mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-09-04 13:36:35 +02:00
cmd/cli: ensure goroutines that check DNS terminated
So changes to DNS after ctrld stopped won't be reverted by the goroutine itself. The problem happens rarely on darwin, because networksetup command won't propagate config to /etc/resolv.conf if there is no changes between multiple running.
This commit is contained in:
@@ -1333,6 +1333,10 @@ func run(appCallback *AppCallback, stopCh chan struct{}) {
|
|||||||
|
|
||||||
close(waitCh)
|
close(waitCh)
|
||||||
<-stopCh
|
<-stopCh
|
||||||
|
|
||||||
|
// Wait goroutines which watches/manipulates DNS settings terminated,
|
||||||
|
// ensuring that changes to DNS since here won't be reverted.
|
||||||
|
p.dnsWg.Wait()
|
||||||
for _, f := range p.onStopped {
|
for _, f := range p.onStopped {
|
||||||
f()
|
f()
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-3
@@ -78,6 +78,7 @@ type prog struct {
|
|||||||
csSetDnsDone chan struct{}
|
csSetDnsDone chan struct{}
|
||||||
csSetDnsOk bool
|
csSetDnsOk bool
|
||||||
dnsWatchDogOnce sync.Once
|
dnsWatchDogOnce sync.Once
|
||||||
|
dnsWg sync.WaitGroup
|
||||||
|
|
||||||
cfg *ctrld.Config
|
cfg *ctrld.Config
|
||||||
localUpstreams []string
|
localUpstreams []string
|
||||||
@@ -596,7 +597,11 @@ func (p *prog) setDNS() {
|
|||||||
for i := range nameservers {
|
for i := range nameservers {
|
||||||
servers[i] = netip.MustParseAddr(nameservers[i])
|
servers[i] = netip.MustParseAddr(nameservers[i])
|
||||||
}
|
}
|
||||||
go watchResolvConf(netIface, servers, setResolvConf)
|
p.dnsWg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer p.dnsWg.Done()
|
||||||
|
p.watchResolvConf(netIface, servers, setResolvConf)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
if allIfaces {
|
if allIfaces {
|
||||||
withEachPhysicalInterfaces(netIface.Name, "set DNS", func(i *net.Interface) error {
|
withEachPhysicalInterfaces(netIface.Name, "set DNS", func(i *net.Interface) error {
|
||||||
@@ -604,7 +609,11 @@ func (p *prog) setDNS() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if p.dnsWatchdogEnabled() {
|
if p.dnsWatchdogEnabled() {
|
||||||
go p.dnsWatchdog(netIface, nameservers, allIfaces)
|
p.dnsWg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer p.dnsWg.Done()
|
||||||
|
p.dnsWatchdog(netIface, nameservers, allIfaces)
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,7 +648,12 @@ func (p *prog) dnsWatchdog(iface *net.Interface, nameservers []string, allIfaces
|
|||||||
slices.Sort(ns)
|
slices.Sort(ns)
|
||||||
ticker := time.NewTicker(p.dnsWatchdogDuration())
|
ticker := time.NewTicker(p.dnsWatchdogDuration())
|
||||||
logger := mainLog.Load().With().Str("iface", iface.Name).Logger()
|
logger := mainLog.Load().With().Str("iface", iface.Name).Logger()
|
||||||
for range ticker.C {
|
for {
|
||||||
|
select {
|
||||||
|
case <-p.stopCh:
|
||||||
|
mainLog.Load().Debug().Msg("stop dns watchdog")
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
if dnsChanged(iface, ns) {
|
if dnsChanged(iface, ns) {
|
||||||
logger.Debug().Msg("DNS settings were changed, re-applying settings")
|
logger.Debug().Msg("DNS settings were changed, re-applying settings")
|
||||||
if err := setDNS(iface, ns); err != nil {
|
if err := setDNS(iface, ns); err != nil {
|
||||||
@@ -659,6 +673,7 @@ func (p *prog) dnsWatchdog(iface *net.Interface, nameservers []string, allIfaces
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
// watchResolvConf watches any changes to /etc/resolv.conf file,
|
// watchResolvConf watches any changes to /etc/resolv.conf file,
|
||||||
// and reverting to the original config set by ctrld.
|
// and reverting to the original config set by ctrld.
|
||||||
func watchResolvConf(iface *net.Interface, ns []netip.Addr, setDnsFn func(iface *net.Interface, ns []netip.Addr) error) {
|
func (p *prog) watchResolvConf(iface *net.Interface, ns []netip.Addr, setDnsFn func(iface *net.Interface, ns []netip.Addr) error) {
|
||||||
resolvConfPath := "/etc/resolv.conf"
|
resolvConfPath := "/etc/resolv.conf"
|
||||||
// Evaluating symbolics link to watch the target file that /etc/resolv.conf point to.
|
// Evaluating symbolics link to watch the target file that /etc/resolv.conf point to.
|
||||||
if rp, _ := filepath.EvalSymlinks(resolvConfPath); rp != "" {
|
if rp, _ := filepath.EvalSymlinks(resolvConfPath); rp != "" {
|
||||||
@@ -34,6 +34,9 @@ func watchResolvConf(iface *net.Interface, ns []netip.Addr, setDnsFn func(iface
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
case <-p.stopCh:
|
||||||
|
mainLog.Load().Debug().Msgf("stopping watcher for %s", resolvConfPath)
|
||||||
|
return
|
||||||
case event, ok := <-watcher.Events:
|
case event, ok := <-watcher.Events:
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user