net/dns: retry forwarder requests over TCP

We weren't correctly retrying truncated requests to an upstream DNS
server with TCP. Instead, we'd return a truncated request to the user,
even if the user was querying us over TCP and thus able to handle a
large response.

Also, add an envknob and controlknob to allow users/us to disable this
behaviour if it turns out to be buggy ( DNS ).

Updates #9264

Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ifb04b563839a9614c0ba03e9c564e8924c1a2bfd
This commit is contained in:
Andrew Dunham
2023-09-07 16:27:50 -04:00
parent 098d110746
commit 530aaa52f1
13 changed files with 448 additions and 49 deletions

View File

@@ -48,6 +48,10 @@ type Knobs struct {
// PeerMTUEnable is whether the node should do peer path MTU discovery.
PeerMTUEnable atomic.Bool
// DisableDNSForwarderTCPRetries is whether the DNS forwarder should
// skip retrying truncated queries over TCP.
DisableDNSForwarderTCPRetries atomic.Bool
}
// UpdateFromNodeAttributes updates k (if non-nil) based on the provided self
@@ -61,14 +65,15 @@ func (k *Knobs) UpdateFromNodeAttributes(selfNodeAttrs []tailcfg.NodeCapability,
return ok || slices.Contains(selfNodeAttrs, attr)
}
var (
keepFullWG = has(tailcfg.NodeAttrDebugDisableWGTrim)
disableDRPO = has(tailcfg.NodeAttrDebugDisableDRPO)
disableUPnP = has(tailcfg.NodeAttrDisableUPnP)
randomizeClientPort = has(tailcfg.NodeAttrRandomizeClientPort)
disableDeltaUpdates = has(tailcfg.NodeAttrDisableDeltaUpdates)
oneCGNAT opt.Bool
forceBackgroundSTUN = has(tailcfg.NodeAttrDebugForceBackgroundSTUN)
peerMTUEnable = has(tailcfg.NodeAttrPeerMTUEnable)
keepFullWG = has(tailcfg.NodeAttrDebugDisableWGTrim)
disableDRPO = has(tailcfg.NodeAttrDebugDisableDRPO)
disableUPnP = has(tailcfg.NodeAttrDisableUPnP)
randomizeClientPort = has(tailcfg.NodeAttrRandomizeClientPort)
disableDeltaUpdates = has(tailcfg.NodeAttrDisableDeltaUpdates)
oneCGNAT opt.Bool
forceBackgroundSTUN = has(tailcfg.NodeAttrDebugForceBackgroundSTUN)
peerMTUEnable = has(tailcfg.NodeAttrPeerMTUEnable)
dnsForwarderDisableTCPRetries = has(tailcfg.NodeAttrDNSForwarderDisableTCPRetries)
)
if has(tailcfg.NodeAttrOneCGNATEnable) {
@@ -85,6 +90,7 @@ func (k *Knobs) UpdateFromNodeAttributes(selfNodeAttrs []tailcfg.NodeCapability,
k.ForceBackgroundSTUN.Store(forceBackgroundSTUN)
k.DisableDeltaUpdates.Store(disableDeltaUpdates)
k.PeerMTUEnable.Store(peerMTUEnable)
k.DisableDNSForwarderTCPRetries.Store(dnsForwarderDisableTCPRetries)
}
// AsDebugJSON returns k as something that can be marshalled with json.Marshal
@@ -94,13 +100,14 @@ func (k *Knobs) AsDebugJSON() map[string]any {
return nil
}
return map[string]any{
"DisableUPnP": k.DisableUPnP.Load(),
"DisableDRPO": k.DisableDRPO.Load(),
"KeepFullWGConfig": k.KeepFullWGConfig.Load(),
"RandomizeClientPort": k.RandomizeClientPort.Load(),
"OneCGNAT": k.OneCGNAT.Load(),
"ForceBackgroundSTUN": k.ForceBackgroundSTUN.Load(),
"DisableDeltaUpdates": k.DisableDeltaUpdates.Load(),
"PeerMTUEnable": k.PeerMTUEnable.Load(),
"DisableUPnP": k.DisableUPnP.Load(),
"DisableDRPO": k.DisableDRPO.Load(),
"KeepFullWGConfig": k.KeepFullWGConfig.Load(),
"RandomizeClientPort": k.RandomizeClientPort.Load(),
"OneCGNAT": k.OneCGNAT.Load(),
"ForceBackgroundSTUN": k.ForceBackgroundSTUN.Load(),
"DisableDeltaUpdates": k.DisableDeltaUpdates.Load(),
"PeerMTUEnable": k.PeerMTUEnable.Load(),
"DisableDNSForwarderTCPRetries": k.DisableDNSForwarderTCPRetries.Load(),
}
}