mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
use saved static nameservers stored for the default router interface when doing nameserver discovery
fix bad logger usages patch darwin interface name patch darwin interface name, debugging make resetDNS check for static config on startup, optionally restoring static confiration as needed fix netmon logging
This commit is contained in:
@@ -418,7 +418,8 @@ func run(appCallback *AppCallback, stopCh chan struct{}) {
|
||||
if err := p.router.Cleanup(); err != nil {
|
||||
mainLog.Load().Error().Err(err).Msg("could not cleanup router")
|
||||
}
|
||||
p.resetDNS()
|
||||
// restore static DNS settings or DHCP
|
||||
p.resetDNS(false, true)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1030,7 +1031,8 @@ func uninstall(p *prog, s service.Service) {
|
||||
mainLog.Load().Warn().Err(err).Msg("post uninstallation failed, please check system/service log for details error")
|
||||
return
|
||||
}
|
||||
p.resetDNS()
|
||||
// restore static DNS settings or DHCP
|
||||
p.resetDNS(false, true)
|
||||
|
||||
// if present restore the original DNS settings
|
||||
if netIface, err := netInterface(p.runningIface); err == nil {
|
||||
@@ -1779,12 +1781,14 @@ func resetDnsNoLog(p *prog) {
|
||||
if verbose < 3 {
|
||||
lvl := zerolog.GlobalLevel()
|
||||
zerolog.SetGlobalLevel(zerolog.Disabled)
|
||||
p.resetDNS()
|
||||
// This is startup so interface settings may have changed
|
||||
p.resetDNS(true, true)
|
||||
zerolog.SetGlobalLevel(lvl)
|
||||
return
|
||||
}
|
||||
// For debugging purpose, still emit log.
|
||||
p.resetDNS()
|
||||
// This is startup so interface settings may have changed
|
||||
p.resetDNS(true, true)
|
||||
}
|
||||
|
||||
// resetDnsTask returns a task which perform reset DNS operation.
|
||||
@@ -1806,10 +1810,10 @@ func resetDnsTask(p *prog, s service.Service, isCtrldInstalled bool, ir *ifaceRe
|
||||
}
|
||||
p.runningIface = iface
|
||||
if isCtrldInstalled {
|
||||
mainLog.Load().Debug().Msg("restore system DNS settings")
|
||||
if status, _ := s.Status(); status == service.StatusRunning {
|
||||
mainLog.Load().Fatal().Msg("reset DNS while ctrld still running is not safe")
|
||||
}
|
||||
mainLog.Load().Debug().Msg("Start resetDNS")
|
||||
resetDnsNoLog(p)
|
||||
}
|
||||
iface = oldIface
|
||||
@@ -1868,8 +1872,8 @@ func uninstallInvalidCdUID(p *prog, logger zerolog.Logger, doStop bool) bool {
|
||||
logger.Warn().Err(err).Msg("failed to create new service")
|
||||
return false
|
||||
}
|
||||
|
||||
p.resetDNS()
|
||||
// restore static DNS settings or DHCP
|
||||
p.resetDNS(false, true)
|
||||
|
||||
tasks := []task{{s.Uninstall, true, "Uninstall"}}
|
||||
if doTasks(tasks) {
|
||||
|
||||
@@ -355,7 +355,7 @@ NOTE: running "ctrld start" without any arguments will start already installed c
|
||||
}, false, "Save current DNS"},
|
||||
{func() error {
|
||||
return ConfigureWindowsServiceFailureActions(ctrldServiceName)
|
||||
}, false, "Configure Windows service failure actions"},
|
||||
}, false, "Configure service failure actions"},
|
||||
{s.Start, true, "Start"},
|
||||
{noticeWritingControlDConfig, false, "Notice writing ControlD config"},
|
||||
}
|
||||
@@ -608,7 +608,8 @@ func initStopCmd() *cobra.Command {
|
||||
}
|
||||
if doTasks([]task{{s.Stop, true, "Stop"}}) {
|
||||
p.router.Cleanup()
|
||||
p.resetDNS()
|
||||
// restore static DNS settings or DHCP
|
||||
p.resetDNS(false, true)
|
||||
|
||||
// restore DNS settings
|
||||
if netIface, err := netInterface(p.runningIface); err == nil {
|
||||
@@ -714,7 +715,8 @@ func initRestartCmd() *cobra.Command {
|
||||
{s.Stop, true, "Stop"},
|
||||
{func() error {
|
||||
p.router.Cleanup()
|
||||
p.resetDNS()
|
||||
// restore static DNS settings or DHCP
|
||||
p.resetDNS(false, true)
|
||||
return nil
|
||||
}, false, "Cleanup"},
|
||||
{func() error {
|
||||
@@ -994,13 +996,13 @@ NOTE: Uninstalling will set DNS to values provided by DHCP.`,
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
mainLog.Load().Warn().Err(err).Msg("failed to remove file")
|
||||
mainLog.Load().Warn().Err(err).Msgf("failed to remove file: %s", file)
|
||||
} else {
|
||||
mainLog.Load().Debug().Msgf("file removed: %s", file)
|
||||
}
|
||||
}
|
||||
if err := selfDeleteExe(); err != nil {
|
||||
mainLog.Load().Warn().Err(err).Msg("failed to remove file")
|
||||
mainLog.Load().Warn().Err(err).Msg("failed to delete ctrld binary")
|
||||
} else {
|
||||
if !supportedSelfDelete {
|
||||
mainLog.Load().Debug().Msgf("file removed: %s", bin)
|
||||
@@ -1266,7 +1268,8 @@ func initUpgradeCmd() *cobra.Command {
|
||||
{s.Stop, true, "Stop"},
|
||||
{func() error {
|
||||
p.router.Cleanup()
|
||||
p.resetDNS()
|
||||
// restore static DNS settings or DHCP
|
||||
p.resetDNS(false, true)
|
||||
return nil
|
||||
}, false, "Cleanup"},
|
||||
{func() error {
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
"tailscale.com/net/netmon"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/types/logger"
|
||||
|
||||
"github.com/Control-D-Inc/ctrld"
|
||||
"github.com/Control-D-Inc/ctrld/internal/controld"
|
||||
@@ -1179,7 +1178,10 @@ func FlushDNSCache() error {
|
||||
|
||||
// monitorNetworkChanges starts monitoring for network interface changes
|
||||
func (p *prog) monitorNetworkChanges(ctx context.Context) error {
|
||||
mon, err := netmon.New(logger.WithPrefix(mainLog.Load().Printf, "netmon: "))
|
||||
mon, err := netmon.New(func(format string, args ...any) {
|
||||
// Always fetch the latest logger (and inject the prefix)
|
||||
mainLog.Load().Printf("netmon: "+format, args...)
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating network monitor: %w", err)
|
||||
}
|
||||
@@ -1457,7 +1459,10 @@ func (p *prog) handleRecovery(reason RecoveryReason) {
|
||||
// Immediately remove our DNS settings from the interface.
|
||||
// set recoveryRunning to true to prevent watchdogs from putting the listener back on the interface
|
||||
p.recoveryRunning.Store(true)
|
||||
p.resetDNS()
|
||||
// we do not want to restore any static DNS settings
|
||||
// we must try to get the DHCP values, any static DNS settings
|
||||
// will be appended to nameservers from the saved interface values
|
||||
p.resetDNS(false, false)
|
||||
|
||||
// For an OS failure, reinitialize OS resolver nameservers immediately.
|
||||
if reason == RecoveryReasonOSFailure {
|
||||
|
||||
@@ -268,7 +268,7 @@ func (p *prog) preRun() {
|
||||
if runtime.GOOS == "darwin" {
|
||||
p.onStopped = append(p.onStopped, func() {
|
||||
if !service.Interactive() {
|
||||
p.resetDNS()
|
||||
p.resetDNS(false, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -276,7 +276,7 @@ func (p *prog) preRun() {
|
||||
|
||||
func (p *prog) postRun() {
|
||||
if !service.Interactive() {
|
||||
p.resetDNS()
|
||||
p.resetDNS(false, true)
|
||||
ns := ctrld.InitializeOsResolver(false)
|
||||
mainLog.Load().Debug().Msgf("initialized OS resolver with nameservers: %v", ns)
|
||||
p.setDNS()
|
||||
@@ -809,7 +809,13 @@ func (p *prog) dnsWatchdog(iface *net.Interface, nameservers []string, allIfaces
|
||||
}
|
||||
}
|
||||
|
||||
func (p *prog) resetDNS() {
|
||||
// resetDNS performs a DNS reset on the running interface.
|
||||
// The parameter isStart indicates whether this is being called as part of a start (or restart)
|
||||
// command. When true, we check if the current static DNS configuration already differs from the
|
||||
// service listener (127.0.0.1). If so, we assume that an admin has manually changed the interface's
|
||||
// static DNS settings and we do not override them using the potentially out-of-date saved file.
|
||||
// Otherwise, we restore the saved configuration (if any) or reset to DHCP.
|
||||
func (p *prog) resetDNS(isStart bool, restoreStatic bool) {
|
||||
if p.runningIface == "" {
|
||||
mainLog.Load().Debug().Msg("no running interface, skipping resetDNS")
|
||||
return
|
||||
@@ -822,17 +828,47 @@ func (p *prog) resetDNS() {
|
||||
logger.Error().Err(err).Msg("could not get interface")
|
||||
return
|
||||
}
|
||||
|
||||
if err := restoreNetworkManager(); err != nil {
|
||||
logger.Error().Err(err).Msg("could not restore NetworkManager")
|
||||
return
|
||||
}
|
||||
logger.Debug().Msg("Restoring DNS for interface")
|
||||
if err := resetDNS(netIface); err != nil {
|
||||
logger.Error().Err(err).Msgf("could not reset DNS")
|
||||
return
|
||||
|
||||
// If starting, check the current static DNS configuration.
|
||||
if isStart {
|
||||
current, err := currentStaticDNS(netIface)
|
||||
if err != nil {
|
||||
logger.Warn().Err(err).Msg("unable to obtain current static DNS configuration; proceeding to restore saved config")
|
||||
} else if len(current) > 0 {
|
||||
// If any static DNS value is not our own listener, assume an admin override.
|
||||
hasManualConfig := false
|
||||
for _, ns := range current {
|
||||
if ns != "127.0.0.1" {
|
||||
hasManualConfig = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if hasManualConfig {
|
||||
logger.Debug().Msgf("Detected manual DNS configuration on interface %q: %v; not overriding with saved configuration", netIface.Name, current)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Default logic: if there is a saved static DNS configuration, restore it.
|
||||
saved := savedStaticNameservers(netIface)
|
||||
if len(saved) > 0 && restoreStatic {
|
||||
logger.Debug().Msgf("Restoring interface %q from saved static config: %v", netIface.Name, saved)
|
||||
if err := setDNS(netIface, saved); err != nil {
|
||||
logger.Error().Err(err).Msgf("failed to restore static DNS config on interface %q", netIface.Name)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
logger.Debug().Msgf("No saved static DNS config for interface %q; resetting to DHCP", netIface.Name)
|
||||
if err := resetDNS(netIface); err != nil {
|
||||
logger.Error().Err(err).Msgf("failed to reset DNS to DHCP on interface %q", netIface.Name)
|
||||
return
|
||||
}
|
||||
}
|
||||
logger.Debug().Msg("Restoring DNS successfully")
|
||||
if allIfaces {
|
||||
withEachPhysicalInterfaces(netIface.Name, "reset DNS", resetDnsIgnoreUnusableInterface)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user