From 6c82cebe57d3c71c731d33255bcf203954f5f04d Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 18 Nov 2021 15:52:21 -0800 Subject: [PATCH] health: add a health state for net/dns.OSConfigurator. Lets the systemd-resolved OSConfigurator report health changes for out of band config resyncs. Updates #3327 Signed-off-by: David Anderson --- health/health.go | 9 +++++++++ net/dns/manager.go | 4 ++++ net/dns/resolved.go | 5 +++++ 3 files changed, 18 insertions(+) diff --git a/health/health.go b/health/health.go index 3a93779a0..5c004b589 100644 --- a/health/health.go +++ b/health/health.go @@ -58,6 +58,9 @@ const ( // SysDNS is the name of the net/dns subsystem. SysDNS = Subsystem("dns") + // SysDNSOS is the name of the net/dns OSConfigurator subsystem. + SysDNSOS = Subsystem("dns-os") + // SysNetworkCategory is the name of the subsystem that sets // the Windows network adapter's "category" (public, private, domain). // If it's unhealthy, the Windows firewall rules won't match. @@ -101,6 +104,12 @@ func SetDNSHealth(err error) { set(SysDNS, err) } // DNSHealth returns the net/dns.Manager error state. func DNSHealth() error { return get(SysDNS) } +// SetDNSOSHealth sets the state of the net/dns.OSConfigurator +func SetDNSOSHealth(err error) { set(SysDNSOS, err) } + +// DNSOSHealth returns the net/dns.OSConfigurator error state. +func DNSOSHealth() error { return get(SysDNSOS) } + // SetNetworkCategoryHealth sets the state of setting the network adaptor's category. // This only applies on Windows. func SetNetworkCategoryHealth(err error) { set(SysNetworkCategory, err) } diff --git a/net/dns/manager.go b/net/dns/manager.go index e3c2feba5..86b7e5301 100644 --- a/net/dns/manager.go +++ b/net/dns/manager.go @@ -10,6 +10,7 @@ import ( "time" "inet.af/netaddr" + "tailscale.com/health" "tailscale.com/net/dns/resolver" "tailscale.com/net/tsaddr" "tailscale.com/types/dnstype" @@ -68,8 +69,10 @@ func (m *Manager) Set(cfg Config) error { return err } if err := m.os.SetDNS(ocfg); err != nil { + health.SetDNSOSHealth(err) return err } + health.SetDNSOSHealth(nil) return nil } @@ -159,6 +162,7 @@ func (m *Manager) compileConfig(cfg Config) (rcfg resolver.Config, ocfg OSConfig if !m.os.SupportsSplitDNS() || isWindows { bcfg, err := m.os.GetBaseConfig() if err != nil { + health.SetDNSOSHealth(err) return resolver.Config{}, OSConfig{}, err } var defaultRoutes []dnstype.Resolver diff --git a/net/dns/resolved.go b/net/dns/resolved.go index b83c7628d..76fe55967 100644 --- a/net/dns/resolved.go +++ b/net/dns/resolved.go @@ -18,6 +18,7 @@ import ( "github.com/godbus/dbus/v5" "golang.org/x/sys/unix" "inet.af/netaddr" + "tailscale.com/health" "tailscale.com/types/logger" "tailscale.com/util/dnsname" ) @@ -171,6 +172,10 @@ func (m *resolvedManager) resync(ctx context.Context, signals chan *dbus.Signal) m.logf("systemd-resolved restarted, syncing DNS config") m.mu.Lock() err := m.syncLocked(ctx) + // Set health while holding the lock, because this will + // graciously serialize the resync's health outcome with a + // concurrent SetDNS call. + health.SetDNSOSHealth(err) m.mu.Unlock() if err != nil { m.logf("failed to configure systemd-resolved: %v", err)