Files
gluetun/internal/dns/run.go
2025-11-17 19:16:32 +00:00

104 lines
2.0 KiB
Go

package dns
import (
"context"
"errors"
"github.com/qdm12/dns/v2/pkg/nameserver"
"github.com/qdm12/gluetun/internal/constants"
)
func (l *Loop) Run(ctx context.Context, done chan<- struct{}) {
defer close(done)
var err error
l.localResolvers, err = nameserver.GetPrivateDNSServers()
if err != nil {
l.logger.Error("getting private DNS servers: " + err.Error())
return
}
const fallback = false
l.useUnencryptedDNS(fallback)
select {
case <-l.start:
case <-ctx.Done():
return
}
for ctx.Err() == nil {
// Upper scope variables for the DNS forwarder server only
// Their values are to be used if DOT=off
var runError <-chan error
for {
var err error
runError, err = l.setupServer(ctx)
if err == nil {
l.backoffTime = defaultBackoffTime
l.logger.Info("ready")
break
}
l.signalOrSetStatus(constants.Crashed)
if ctx.Err() != nil {
return
}
if !errors.Is(err, errUpdateBlockLists) {
const fallback = true
l.useUnencryptedDNS(fallback)
}
l.logAndWait(ctx, err)
}
l.signalOrSetStatus(constants.Running)
const fallback = false
l.useUnencryptedDNS(fallback)
l.userTrigger = false
exitLoop := l.runWait(ctx, runError)
if exitLoop {
return
}
}
}
func (l *Loop) runWait(ctx context.Context, runError <-chan error) (exitLoop bool) {
for {
select {
case <-ctx.Done():
l.stopServer()
// TODO revert OS and Go nameserver when exiting
return true
case <-l.stop:
l.userTrigger = true
l.logger.Info("stopping")
const fallback = false
l.useUnencryptedDNS(fallback)
l.stopServer()
l.stopped <- struct{}{}
case <-l.start:
l.userTrigger = true
l.logger.Info("starting")
return false
case err := <-runError: // unexpected error
l.statusManager.SetStatus(constants.Crashed)
const fallback = true
l.useUnencryptedDNS(fallback)
l.logAndWait(ctx, err)
return false
}
}
}
func (l *Loop) stopServer() {
stopErr := l.server.Stop()
if stopErr != nil {
l.logger.Error("stopping server: " + stopErr.Error())
}
}