diff --git a/net/dns/resolver/forwarder.go b/net/dns/resolver/forwarder.go index 26bc6148c..884e53321 100644 --- a/net/dns/resolver/forwarder.go +++ b/net/dns/resolver/forwarder.go @@ -28,7 +28,6 @@ import ( "tailscale.com/net/dnscache" "tailscale.com/net/neterror" "tailscale.com/net/netmon" - "tailscale.com/net/netns" "tailscale.com/net/sockstats" "tailscale.com/net/tsdial" "tailscale.com/types/dnstype" @@ -394,8 +393,20 @@ func (f *forwarder) getKnownDoHClientForProvider(urlBase string) (c *http.Client if err != nil { return nil, false } - nsDialer := netns.NewDialer(f.logf, f.netMon) - dialer := dnscache.Dialer(nsDialer.DialContext, &dnscache.Resolver{ + // NOTE: use f.dialer.SystemDial so we close connections on a link + // change; on mobile devices when switching between WiFi and cellular, + // we need to ensure we don't retain a connection on the old interface + // or we can block DNS resolution. + // + // NOTE: if we ever support arbitrary user-defined DoH providers, this + // isn't sufficient; we'd need a dialer that dial a DoH server on the + // internet, without going through Tailscale (as SystemDial does), but + // also can dial a node on the tailnet (e.g. a PiHole). + // + // As of the time of writing (2024-02-11), this isn't a problem because + // we only support a restricted set of public DoH providers that aren't + // on a user's tailnet. + dialer := dnscache.Dialer(f.dialer.SystemDial, &dnscache.Resolver{ SingleHost: dohURL.Hostname(), SingleHostStaticResult: allIPs, Logf: f.logf,