mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-09-29 13:51:51 +02:00
cmd/cli: add DNS watchdog on Darwin/Windows
Once per minute, ctrld will check if DNS settings was changed or not. If yes, re-applying the proper settings for system interfaces. For now, this is only applied when deactivation_pin was set.
This commit is contained in:
1 parent
56f9c72569
commit
e6ad39b070
1 file changed
+60
-9
+60
-9
@@ -12,11 +12,13 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/kardianos/service"
|
"github.com/kardianos/service"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
@@ -38,6 +40,7 @@ const (
|
|||||||
upstreamPrefix = "upstream."
|
upstreamPrefix = "upstream."
|
||||||
upstreamOS = upstreamPrefix + "os"
|
upstreamOS = upstreamPrefix + "os"
|
||||||
upstreamPrivate = upstreamPrefix + "private"
|
upstreamPrivate = upstreamPrefix + "private"
|
||||||
|
dnsWatchdogInterval = time.Minute
|
||||||
)
|
)
|
||||||
|
|
||||||
// ControlSocketName returns name for control unix socket.
|
// ControlSocketName returns name for control unix socket.
|
||||||
@@ -62,15 +65,16 @@ var svcConfig = &service.Config{
|
|||||||
var useSystemdResolved = false
|
var useSystemdResolved = false
|
||||||
|
|
||||||
type prog struct {
|
type prog struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
waitCh chan struct{}
|
waitCh chan struct{}
|
||||||
stopCh chan struct{}
|
stopCh chan struct{}
|
||||||
reloadCh chan struct{} // For Windows.
|
reloadCh chan struct{} // For Windows.
|
||||||
reloadDoneCh chan struct{}
|
reloadDoneCh chan struct{}
|
||||||
logConn net.Conn
|
logConn net.Conn
|
||||||
cs *controlServer
|
cs *controlServer
|
||||||
csSetDnsDone chan struct{}
|
csSetDnsDone chan struct{}
|
||||||
csSetDnsOk bool
|
csSetDnsOk bool
|
||||||
|
dnsWatchDogOnce sync.Once
|
||||||
|
|
||||||
cfg *ctrld.Config
|
cfg *ctrld.Config
|
||||||
localUpstreams []string
|
localUpstreams []string
|
||||||
@@ -517,6 +521,45 @@ func (p *prog) setDNS() {
|
|||||||
return setDnsIgnoreUnusableInterface(i, nameservers)
|
return setDnsIgnoreUnusableInterface(i, nameservers)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
go p.dnsWatchdog(netIface, nameservers, allIfaces)
|
||||||
|
}
|
||||||
|
|
||||||
|
// dnsWatchdog watches for DNS changes on Darwin and Windows then re-applying ctrld's settings.
|
||||||
|
// This is only works when deactivation pin set.
|
||||||
|
func (p *prog) dnsWatchdog(iface *net.Interface, nameservers []string, allIfaces bool) {
|
||||||
|
switch runtime.GOOS {
|
||||||
|
case "darwin", "windows":
|
||||||
|
default:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if deactivationPinNotSet() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.dnsWatchDogOnce.Do(func() {
|
||||||
|
mainLog.Load().Debug().Msg("start DNS settings watchdog")
|
||||||
|
ns := nameservers
|
||||||
|
slices.Sort(ns)
|
||||||
|
ticker := time.NewTicker(dnsWatchdogInterval)
|
||||||
|
logger := mainLog.Load().With().Str("iface", iface.Name).Logger()
|
||||||
|
for range ticker.C {
|
||||||
|
if dnsChanged(iface, ns) {
|
||||||
|
logger.Debug().Msg("DNS settings were changed, re-applying settings")
|
||||||
|
if err := setDNS(iface, ns); err != nil {
|
||||||
|
mainLog.Load().Error().Err(err).Str("iface", iface.Name).Msgf("could not re-apply DNS settings")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if allIfaces {
|
||||||
|
withEachPhysicalInterfaces(iface.Name, "re-applying DNS", func(i *net.Interface) error {
|
||||||
|
if dnsChanged(i, ns) {
|
||||||
|
if err := setDnsIgnoreUnusableInterface(i, nameservers); err != nil {
|
||||||
|
mainLog.Load().Error().Err(err).Str("iface", i.Name).Msgf("could not re-apply DNS settings")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *prog) resetDNS() {
|
func (p *prog) resetDNS() {
|
||||||
@@ -806,3 +849,11 @@ func savedStaticNameservers(iface *net.Interface) []string {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dnsChanged reports whether DNS settings for given interface was changed.
|
||||||
|
// The caller must sort the nameservers before calling this function.
|
||||||
|
func dnsChanged(iface *net.Interface, nameservers []string) bool {
|
||||||
|
curNameservers := currentDNS(iface)
|
||||||
|
slices.Sort(curNameservers)
|
||||||
|
return !slices.Equal(curNameservers, nameservers)
|
||||||
|
}
|
||||||
Reference in new issue
Block a user