Add some logging

This commit is contained in:
Owen
2026-07-06 17:51:49 -04:00
parent f356aed39b
commit 4c600bab15
3 changed files with 20 additions and 9 deletions

View File

@@ -177,11 +177,13 @@ func (m *SystemDNSMonitor) applyCandidates(raw []string) {
m.mu.Lock()
if dnsSlicesEqual(m.lastRaw, raw) {
m.mu.Unlock()
logger.Debug("System DNS candidates unchanged, skipping health check: %v", raw)
return
}
m.lastRaw = raw
m.mu.Unlock()
logger.Debug("System DNS candidates changed, health-checking: %v", raw)
validated := filterUnreachable(raw)
if len(validated) == 0 {
logger.Warn("None of the detected DNS servers answered a health-check query, keeping previous value: %v", raw)
@@ -201,8 +203,8 @@ func (m *SystemDNSMonitor) applyCandidates(raw []string) {
}
}
// dnsServerReachable is a seam for tests; production code always uses probeDNSServer.
var dnsServerReachable = probeDNSServer
// dnsServerReachable is a seam for tests; production code always uses probeDNSServerErr.
var dnsServerReachable = probeDNSServerErr
// filterUnreachable validates that each candidate server actually answers a
// DNS query before it's trusted, rather than statically guessing from the
@@ -215,12 +217,13 @@ func filterUnreachable(servers []string) []string {
}
reachable := make([]bool, len(servers))
errs := make([]error, len(servers))
var wg sync.WaitGroup
for i, server := range servers {
wg.Add(1)
go func(i int, server string) {
defer wg.Done()
reachable[i] = dnsServerReachable(server)
reachable[i], errs[i] = dnsServerReachable(server)
}(i, server)
}
wg.Wait()
@@ -230,22 +233,23 @@ func filterUnreachable(servers []string) []string {
if reachable[i] {
result = append(result, server)
} else {
logger.Debug("Discarding DNS server %s: failed health check", server)
logger.Debug("Discarding DNS server %s: failed health check: %v", server, errs[i])
}
}
return result
}
// probeDNSServer sends a minimal root NS query to confirm a candidate server
// probeDNSServerErr sends a minimal root NS query to confirm a candidate server
// actually answers, without depending on any specific external hostname being
// reachable (which could itself be blocked/filtered independently of whether
// the resolver works).
func probeDNSServer(server string) bool {
// the resolver works). The returned error is kept (rather than just a bool) so
// callers can log why a candidate was rejected (unreachable route, timeout, etc.).
func probeDNSServerErr(server string) (bool, error) {
client := &dns.Client{Timeout: dnsHealthCheckTimeout}
msg := new(dns.Msg)
msg.SetQuestion(".", dns.TypeNS)
_, _, err := client.Exchange(msg, server)
return err == nil
return err == nil, err
}
// dnsSlicesEqual reports whether two server lists are equal regardless of order.

View File

@@ -12,7 +12,7 @@ import (
func stubReachable(t *testing.T, fn func(server string) bool) {
t.Helper()
orig := dnsServerReachable
dnsServerReachable = fn
dnsServerReachable = func(server string) (bool, error) { return fn(server), nil }
t.Cleanup(func() { dnsServerReachable = orig })
}

View File

@@ -404,6 +404,9 @@ func (o *Olm) StartTunnel(config TunnelConfig) {
// with whatever DNS the host network is currently using.
upstreamFromConfig := len(config.UpstreamDNS) > 0 &&
!(len(config.UpstreamDNS) == 1 && config.UpstreamDNS[0] == "8.8.8.8:53")
if upstreamFromConfig {
logger.Info("UpstreamDNS is statically configured (%v); automatic system DNS detection will only update PublicDNS, DNS forwarding will keep using the configured value even if it becomes unreachable on a new network", config.UpstreamDNS)
}
// Start the system DNS monitor. The callback fires synchronously once with
// the initial values so that PublicDNS (and optionally UpstreamDNS) are
@@ -433,6 +436,8 @@ func (o *Olm) StartTunnel(config TunnelConfig) {
if o.dnsProxy != nil {
o.dnsProxy.SetUpstreamDNS(servers)
}
} else {
logger.Debug("Not updating UpstreamDNS: statically configured to %v", config.UpstreamDNS)
}
})
o.dnsMonitor.Start(o.olmCtx)
@@ -897,6 +902,7 @@ func (o *Olm) SetPostures(data map[string]any) {
// changes. The list is applied through the same exclude-IP filtering and
// change detection as the internally-polled SystemDNSMonitor.
func (o *Olm) SetSystemDNS(servers []string) {
logger.Info("SetSystemDNS called with: %v", servers)
if o.dnsMonitor == nil {
// StartTunnel hasn't created the monitor yet (mobile platforms may push a
// value the moment they start observing, before the tunnel goroutine has
@@ -905,6 +911,7 @@ func (o *Olm) SetSystemDNS(servers []string) {
o.pendingSystemDNSMu.Lock()
o.pendingSystemDNS = servers
o.pendingSystemDNSMu.Unlock()
logger.Debug("dnsMonitor not yet started, queued SetSystemDNS value")
return
}
o.dnsMonitor.ReportExternal(servers)