mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 21:27:31 +00:00
net/dns/resolver, control/controlknobs, tailcfg: use UserDial instead of SystemDial to dial DNS servers
Now that tsdial.Dialer.UserDial has been updated to honor the configured routes and dial external network addresses without going through Tailscale, while also being able to dial a node/subnet router on the tailnet, we can start using UserDial to forward DNS requests. This is primarily needed for DNS over TCP when forwarding requests to internal DNS servers, but we also update getKnownDoHClientForProvider to use it. Updates tailscale/corp#18725 Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
@@ -391,20 +391,8 @@ func (f *forwarder) getKnownDoHClientForProvider(urlBase string) (c *http.Client
|
||||
if err != nil {
|
||||
return nil, false
|
||||
}
|
||||
// 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{
|
||||
|
||||
dialer := dnscache.Dialer(f.getDialerType(), &dnscache.Resolver{
|
||||
SingleHost: dohURL.Hostname(),
|
||||
SingleHostStaticResult: allIPs,
|
||||
Logf: f.logf,
|
||||
@@ -699,6 +687,23 @@ func (f *forwarder) sendUDP(ctx context.Context, fq *forwardQuery, rr resolverAn
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (f *forwarder) getDialerType() dnscache.DialContextFunc {
|
||||
if f.controlKnobs != nil && f.controlKnobs.UserDialUseRoutes.Load() {
|
||||
// It is safe to use UserDial as it dials external servers without going through Tailscale
|
||||
// and closes connections on interface change in the same way as SystemDial does,
|
||||
// thus preventing DNS resolution issues when switching between WiFi and cellular,
|
||||
// but can also dial an internal DNS server on the Tailnet or via a subnet router.
|
||||
//
|
||||
// TODO(nickkhyl): Update tsdial.Dialer to reuse the bart.Table we create in net/tstun.Wrapper
|
||||
// to avoid having two bart tables in memory, especially on iOS. Once that's done,
|
||||
// we can get rid of the nodeAttr/control knob and always use UserDial for DNS.
|
||||
//
|
||||
// See https://github.com/tailscale/tailscale/issues/12027.
|
||||
return f.dialer.UserDial
|
||||
}
|
||||
return f.dialer.SystemDial
|
||||
}
|
||||
|
||||
func (f *forwarder) sendTCP(ctx context.Context, fq *forwardQuery, rr resolverAndDelay) (ret []byte, err error) {
|
||||
ipp, ok := rr.name.IPPort()
|
||||
if !ok {
|
||||
@@ -717,7 +722,7 @@ func (f *forwarder) sendTCP(ctx context.Context, fq *forwardQuery, rr resolverAn
|
||||
ctx, cancel := context.WithTimeout(ctx, tcpQueryTimeout)
|
||||
defer cancel()
|
||||
|
||||
conn, err := f.dialer.SystemDial(ctx, tcpFam, ipp.String())
|
||||
conn, err := f.getDialerType()(ctx, tcpFam, ipp.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Reference in New Issue
Block a user