mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
fix MacOS nameserver detection, fix not installed errors for commands
copy fix get valid ifaces in nameservers_bsd nameservers on MacOS can be found in resolv.conf reliably nameservers on MacOS can be found in resolv.conf reliably exclude local IPs from MacOS resolve conf check use scutil for MacOS, simplify reinit logic to prevent duplicate calls add more dns server fetching options never skip OS resolver in IsDown check split dsb and darwin nameserver methods, add delay for setting DNS on interface on network change. increase delay to 5s but only on MacOS
This commit is contained in:
@@ -43,6 +43,20 @@ func initLogCmd() *cobra.Command {
|
||||
checkHasElevatedPrivilege()
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
p := &prog{router: router.New(&cfg, false)}
|
||||
s, _ := newService(p, svcConfig)
|
||||
|
||||
status, err := s.Status()
|
||||
if errors.Is(err, service.ErrNotInstalled) {
|
||||
mainLog.Load().Warn().Msg("service not installed")
|
||||
return
|
||||
}
|
||||
if status == service.StatusStopped {
|
||||
mainLog.Load().Warn().Msg("service is not running")
|
||||
return
|
||||
}
|
||||
|
||||
dir, err := socketDir()
|
||||
if err != nil {
|
||||
mainLog.Load().Fatal().Err(err).Msg("failed to find ctrld home dir")
|
||||
@@ -82,6 +96,20 @@ func initLogCmd() *cobra.Command {
|
||||
checkHasElevatedPrivilege()
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
p := &prog{router: router.New(&cfg, false)}
|
||||
s, _ := newService(p, svcConfig)
|
||||
|
||||
status, err := s.Status()
|
||||
if errors.Is(err, service.ErrNotInstalled) {
|
||||
mainLog.Load().Warn().Msg("service not installed")
|
||||
return
|
||||
}
|
||||
if status == service.StatusStopped {
|
||||
mainLog.Load().Warn().Msg("service is not running")
|
||||
return
|
||||
}
|
||||
|
||||
dir, err := socketDir()
|
||||
if err != nil {
|
||||
mainLog.Load().Fatal().Err(err).Msg("failed to find ctrld home dir")
|
||||
@@ -765,6 +793,20 @@ func initReloadCmd(restartCmd *cobra.Command) *cobra.Command {
|
||||
Short: "Reload the ctrld service",
|
||||
Args: cobra.NoArgs,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
p := &prog{router: router.New(&cfg, false)}
|
||||
s, _ := newService(p, svcConfig)
|
||||
|
||||
status, err := s.Status()
|
||||
if errors.Is(err, service.ErrNotInstalled) {
|
||||
mainLog.Load().Warn().Msg("service not installed")
|
||||
return
|
||||
}
|
||||
if status == service.StatusStopped {
|
||||
mainLog.Load().Warn().Msg("service is not running")
|
||||
return
|
||||
}
|
||||
|
||||
dir, err := socketDir()
|
||||
if err != nil {
|
||||
mainLog.Load().Fatal().Err(err).Msg("failed to find ctrld home dir")
|
||||
@@ -1045,6 +1087,20 @@ func initClientsCmd() *cobra.Command {
|
||||
checkHasElevatedPrivilege()
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
p := &prog{router: router.New(&cfg, false)}
|
||||
s, _ := newService(p, svcConfig)
|
||||
|
||||
status, err := s.Status()
|
||||
if errors.Is(err, service.ErrNotInstalled) {
|
||||
mainLog.Load().Warn().Msg("service not installed")
|
||||
return
|
||||
}
|
||||
if status == service.StatusStopped {
|
||||
mainLog.Load().Warn().Msg("service is not running")
|
||||
return
|
||||
}
|
||||
|
||||
dir, err := socketDir()
|
||||
if err != nil {
|
||||
mainLog.Load().Fatal().Err(err).Msg("failed to find ctrld home dir")
|
||||
|
||||
@@ -585,10 +585,14 @@ func (p *prog) proxy(ctx context.Context, req *proxyRequest) *proxyResponse {
|
||||
continue
|
||||
}
|
||||
if p.um.isDown(upstreams[n]) {
|
||||
logger.
|
||||
Bool("is_os_resolver", upstreams[n] == upstreamOS)
|
||||
ctrld.Log(ctx, logger, "Upstream is down")
|
||||
continue
|
||||
// never skip the OS resolver, since we usually query this resolver when we
|
||||
// have no other upstreams to query
|
||||
if upstreams[n] != upstreamOS {
|
||||
logger.
|
||||
Bool("is_os_resolver", upstreams[n] == upstreamOS)
|
||||
ctrld.Log(ctx, logger, "Upstream is down")
|
||||
continue
|
||||
}
|
||||
}
|
||||
answer := resolve(n, upstreamConfig, req.msg)
|
||||
if answer == nil {
|
||||
@@ -1231,67 +1235,43 @@ func resolveInternalDomainTestQuery(ctx context.Context, domain string, m *dns.M
|
||||
func (p *prog) reinitializeOSResolver(networkChange bool) {
|
||||
// Cancel any existing operations
|
||||
p.resetCtxMu.Lock()
|
||||
if p.resetCancel != nil {
|
||||
p.resetCancel()
|
||||
}
|
||||
|
||||
// Create new context for this operation
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
p.resetCtx = ctx
|
||||
p.resetCancel = cancel
|
||||
p.resetCtxMu.Unlock()
|
||||
|
||||
// Ensure cleanup
|
||||
defer cancel()
|
||||
defer p.resetCtxMu.Unlock()
|
||||
|
||||
p.leakingQueryReset.Store(true)
|
||||
defer p.leakingQueryReset.Store(false)
|
||||
|
||||
defer func() {
|
||||
// start leaking queries immediately
|
||||
if networkChange {
|
||||
// set all upstreams to failed and provide to performLeakingQuery
|
||||
failedUpstreams := make(map[string]*ctrld.UpstreamConfig)
|
||||
for _, upstream := range p.cfg.Upstream {
|
||||
failedUpstreams[upstream.Name] = upstream
|
||||
}
|
||||
go p.performLeakingQuery(failedUpstreams, "all")
|
||||
mainLog.Load().Debug().Msg("attempting to reset DNS")
|
||||
p.resetDNS()
|
||||
mainLog.Load().Debug().Msg("DNS reset completed")
|
||||
|
||||
mainLog.Load().Debug().Msg("initializing OS resolver")
|
||||
ns := ctrld.InitializeOsResolver()
|
||||
mainLog.Load().Warn().Msgf("re-initialized OS resolver with nameservers: %v", ns)
|
||||
|
||||
// start leaking queries immediately// start leaking queries immediately
|
||||
if networkChange {
|
||||
// set all upstreams to failed and provide to performLeakingQuery
|
||||
failedUpstreams := make(map[string]*ctrld.UpstreamConfig)
|
||||
for _, upstream := range p.cfg.Upstream {
|
||||
failedUpstreams[upstream.Name] = upstream
|
||||
}
|
||||
go p.performLeakingQuery(failedUpstreams, "all")
|
||||
|
||||
if err := FlushDNSCache(); err != nil {
|
||||
mainLog.Load().Warn().Err(err).Msg("failed to flush DNS cache")
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
mainLog.Load().Debug().Msg("DNS reset cancelled by new network change")
|
||||
return
|
||||
default:
|
||||
mainLog.Load().Debug().Msg("attempting to reset DNS")
|
||||
p.resetDNS()
|
||||
mainLog.Load().Debug().Msg("DNS reset completed")
|
||||
if runtime.GOOS == "darwin" {
|
||||
// delay putting back the ctrld listener to allow for captive portal to trigger
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
mainLog.Load().Debug().Msg("DNS reset cancelled by new network change")
|
||||
return
|
||||
default:
|
||||
mainLog.Load().Debug().Msg("initializing OS resolver")
|
||||
ns := ctrld.InitializeOsResolver()
|
||||
mainLog.Load().Warn().Msgf("re-initialized OS resolver with nameservers: %v", ns)
|
||||
}
|
||||
mainLog.Load().Debug().Msg("setting DNS configuration")
|
||||
p.setDNS()
|
||||
mainLog.Load().Debug().Msg("DNS configuration set successfully")
|
||||
p.logInterfacesState()
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
mainLog.Load().Debug().Msg("DNS reset cancelled by new network change")
|
||||
return
|
||||
default:
|
||||
mainLog.Load().Debug().Msg("setting DNS configuration")
|
||||
p.setDNS()
|
||||
mainLog.Load().Debug().Msg("DNS configuration set successfully")
|
||||
p.logInterfacesState()
|
||||
}
|
||||
}
|
||||
|
||||
// FlushDNSCache flushes the DNS cache on macOS.
|
||||
|
||||
@@ -20,9 +20,9 @@ const (
|
||||
logWriterSmallSize = 1024 * 1024 * 1 // 1 MB
|
||||
logWriterInitialSize = 32 * 1024 // 32 KB
|
||||
logSentInterval = time.Minute
|
||||
logStartEndMarker = "\n\n=== START_END ===\n\n"
|
||||
logStartEndMarker = "\n\n=== INIT_END ===\n\n"
|
||||
logLogEndMarker = "\n\n=== LOG_END ===\n\n"
|
||||
logWarnEndMarker = "\n\n=== WARN END ===\n\n"
|
||||
logWarnEndMarker = "\n\n=== WARN_END ===\n\n"
|
||||
)
|
||||
|
||||
type logViewResponse struct {
|
||||
|
||||
@@ -123,9 +123,7 @@ type prog struct {
|
||||
leakingQueryRunning map[string]bool
|
||||
leakingQueryReset atomic.Bool
|
||||
|
||||
resetCtx context.Context
|
||||
resetCancel context.CancelFunc
|
||||
resetCtxMu sync.Mutex
|
||||
resetCtxMu sync.Mutex
|
||||
|
||||
started chan struct{}
|
||||
onStartedDone chan struct{}
|
||||
|
||||
Reference in New Issue
Block a user