net/dns, health: raise health warning for failing forwarded DNS queries (#12888)

updates tailscale/corp#21823

Misconfigured, broken, or blocked DNS will often present as
"internet is broken'" to the end user.  This  plumbs the health tracker
into the dns manager and forwarder and adds a health warning
with a 5 second delay that is raised on failures in the forwarder and
lowered on successes.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This commit is contained in:
Jonathan Nobels
2024-07-29 13:48:46 -04:00
committed by GitHub
parent 3088c6105e
commit 19b0c8a024
7 changed files with 53 additions and 8 deletions

View File

@ -25,6 +25,7 @@ import (
dns "golang.org/x/net/dns/dnsmessage"
"tailscale.com/control/controlknobs"
"tailscale.com/envknob"
"tailscale.com/health"
"tailscale.com/net/dns/resolvconffile"
"tailscale.com/net/netaddr"
"tailscale.com/net/netmon"
@ -202,6 +203,7 @@ type Resolver struct {
logf logger.Logf
netMon *netmon.Monitor // non-nil
dialer *tsdial.Dialer // non-nil
health *health.Tracker // non-nil
saveConfigForTests func(cfg Config) // used in tests to capture resolver config
// forwarder forwards requests to upstream nameservers.
forwarder *forwarder
@ -224,10 +226,14 @@ type ForwardLinkSelector interface {
}
// New returns a new resolver.
func New(logf logger.Logf, linkSel ForwardLinkSelector, dialer *tsdial.Dialer, knobs *controlknobs.Knobs) *Resolver {
// dialer and health must be non-nil.
func New(logf logger.Logf, linkSel ForwardLinkSelector, dialer *tsdial.Dialer, health *health.Tracker, knobs *controlknobs.Knobs) *Resolver {
if dialer == nil {
panic("nil Dialer")
}
if health == nil {
panic("nil health")
}
netMon := dialer.NetMon()
if netMon == nil {
logf("nil netMon")
@ -239,8 +245,9 @@ func New(logf logger.Logf, linkSel ForwardLinkSelector, dialer *tsdial.Dialer, k
hostToIP: map[dnsname.FQDN][]netip.Addr{},
ipToHost: map[netip.Addr]dnsname.FQDN{},
dialer: dialer,
health: health,
}
r.forwarder = newForwarder(r.logf, netMon, linkSel, dialer, knobs)
r.forwarder = newForwarder(r.logf, netMon, linkSel, dialer, health, knobs)
return r
}