@ -81,6 +81,15 @@ type Knobs struct {
// how to dial the destination address. When true, it also makes the DNS forwarder
// how to dial the destination address. When true, it also makes the DNS forwarder
// use UserDial instead of SystemDial when dialing resolvers.
// use UserDial instead of SystemDial when dialing resolvers.
UserDialUseRoutes atomic . Bool
UserDialUseRoutes atomic . Bool
// DisableSplitDNSWhenNoCustomResolvers indicates that the node's DNS manager
// should not adopt a split DNS configuration even though the Config of the
// resolver only contains routes that do not specify custom resolver(s), hence
// all DNS queries can be safely sent to the upstream DNS resolver and the
// node's DNS forwarder doesn't need to handle all DNS traffic.
// This is for now (2024-06-06) an iOS-specific battery life optimization,
// and this knob allows us to disable the optimization remotely if needed.
DisableSplitDNSWhenNoCustomResolvers atomic . Bool
}
}
// UpdateFromNodeAttributes updates k (if non-nil) based on the provided self
// UpdateFromNodeAttributes updates k (if non-nil) based on the provided self
@ -91,22 +100,23 @@ func (k *Knobs) UpdateFromNodeAttributes(capMap tailcfg.NodeCapMap) {
}
}
has := capMap . Contains
has := capMap . Contains
var (
var (
keepFullWG = has ( tailcfg . NodeAttrDebugDisableWGTrim )
keepFullWG = has ( tailcfg . NodeAttrDebugDisableWGTrim )
disableDRPO = has ( tailcfg . NodeAttrDebugDisableDRPO )
disableDRPO = has ( tailcfg . NodeAttrDebugDisableDRPO )
disableUPnP = has ( tailcfg . NodeAttrDisableUPnP )
disableUPnP = has ( tailcfg . NodeAttrDisableUPnP )
randomizeClientPort = has ( tailcfg . NodeAttrRandomizeClientPort )
randomizeClientPort = has ( tailcfg . NodeAttrRandomizeClientPort )
disableDeltaUpdates = has ( tailcfg . NodeAttrDisableDeltaUpdates )
disableDeltaUpdates = has ( tailcfg . NodeAttrDisableDeltaUpdates )
oneCGNAT opt . Bool
oneCGNAT opt . Bool
forceBackgroundSTUN = has ( tailcfg . NodeAttrDebugForceBackgroundSTUN )
forceBackgroundSTUN = has ( tailcfg . NodeAttrDebugForceBackgroundSTUN )
peerMTUEnable = has ( tailcfg . NodeAttrPeerMTUEnable )
peerMTUEnable = has ( tailcfg . NodeAttrPeerMTUEnable )
dnsForwarderDisableTCPRetries = has ( tailcfg . NodeAttrDNSForwarderDisableTCPRetries )
dnsForwarderDisableTCPRetries = has ( tailcfg . NodeAttrDNSForwarderDisableTCPRetries )
silentDisco = has ( tailcfg . NodeAttrSilentDisco )
silentDisco = has ( tailcfg . NodeAttrSilentDisco )
forceIPTables = has ( tailcfg . NodeAttrLinuxMustUseIPTables )
forceIPTables = has ( tailcfg . NodeAttrLinuxMustUseIPTables )
forceNfTables = has ( tailcfg . NodeAttrLinuxMustUseNfTables )
forceNfTables = has ( tailcfg . NodeAttrLinuxMustUseNfTables )
seamlessKeyRenewal = has ( tailcfg . NodeAttrSeamlessKeyRenewal )
seamlessKeyRenewal = has ( tailcfg . NodeAttrSeamlessKeyRenewal )
probeUDPLifetime = has ( tailcfg . NodeAttrProbeUDPLifetime )
probeUDPLifetime = has ( tailcfg . NodeAttrProbeUDPLifetime )
appCStoreRoutes = has ( tailcfg . NodeAttrStoreAppCRoutes )
appCStoreRoutes = has ( tailcfg . NodeAttrStoreAppCRoutes )
userDialUseRoutes = has ( tailcfg . NodeAttrUserDialUseRoutes )
userDialUseRoutes = has ( tailcfg . NodeAttrUserDialUseRoutes )
disableSplitDNSWhenNoCustomResolvers = has ( tailcfg . NodeAttrDisableSplitDNSWhenNoCustomResolvers )
)
)
if has ( tailcfg . NodeAttrOneCGNATEnable ) {
if has ( tailcfg . NodeAttrOneCGNATEnable ) {
@ -131,6 +141,7 @@ func (k *Knobs) UpdateFromNodeAttributes(capMap tailcfg.NodeCapMap) {
k . ProbeUDPLifetime . Store ( probeUDPLifetime )
k . ProbeUDPLifetime . Store ( probeUDPLifetime )
k . AppCStoreRoutes . Store ( appCStoreRoutes )
k . AppCStoreRoutes . Store ( appCStoreRoutes )
k . UserDialUseRoutes . Store ( userDialUseRoutes )
k . UserDialUseRoutes . Store ( userDialUseRoutes )
k . DisableSplitDNSWhenNoCustomResolvers . Store ( disableSplitDNSWhenNoCustomResolvers )
}
}
// AsDebugJSON returns k as something that can be marshalled with json.Marshal
// AsDebugJSON returns k as something that can be marshalled with json.Marshal
@ -140,21 +151,22 @@ func (k *Knobs) AsDebugJSON() map[string]any {
return nil
return nil
}
}
return map [ string ] any {
return map [ string ] any {
"DisableUPnP" : k . DisableUPnP . Load ( ) ,
"DisableUPnP" : k . DisableUPnP . Load ( ) ,
"DisableDRPO" : k . DisableDRPO . Load ( ) ,
"DisableDRPO" : k . DisableDRPO . Load ( ) ,
"KeepFullWGConfig" : k . KeepFullWGConfig . Load ( ) ,
"KeepFullWGConfig" : k . KeepFullWGConfig . Load ( ) ,
"RandomizeClientPort" : k . RandomizeClientPort . Load ( ) ,
"RandomizeClientPort" : k . RandomizeClientPort . Load ( ) ,
"OneCGNAT" : k . OneCGNAT . Load ( ) ,
"OneCGNAT" : k . OneCGNAT . Load ( ) ,
"ForceBackgroundSTUN" : k . ForceBackgroundSTUN . Load ( ) ,
"ForceBackgroundSTUN" : k . ForceBackgroundSTUN . Load ( ) ,
"DisableDeltaUpdates" : k . DisableDeltaUpdates . Load ( ) ,
"DisableDeltaUpdates" : k . DisableDeltaUpdates . Load ( ) ,
"PeerMTUEnable" : k . PeerMTUEnable . Load ( ) ,
"PeerMTUEnable" : k . PeerMTUEnable . Load ( ) ,
"DisableDNSForwarderTCPRetries" : k . DisableDNSForwarderTCPRetries . Load ( ) ,
"DisableDNSForwarderTCPRetries" : k . DisableDNSForwarderTCPRetries . Load ( ) ,
"SilentDisco" : k . SilentDisco . Load ( ) ,
"SilentDisco" : k . SilentDisco . Load ( ) ,
"LinuxForceIPTables" : k . LinuxForceIPTables . Load ( ) ,
"LinuxForceIPTables" : k . LinuxForceIPTables . Load ( ) ,
"LinuxForceNfTables" : k . LinuxForceNfTables . Load ( ) ,
"LinuxForceNfTables" : k . LinuxForceNfTables . Load ( ) ,
"SeamlessKeyRenewal" : k . SeamlessKeyRenewal . Load ( ) ,
"SeamlessKeyRenewal" : k . SeamlessKeyRenewal . Load ( ) ,
"ProbeUDPLifetime" : k . ProbeUDPLifetime . Load ( ) ,
"ProbeUDPLifetime" : k . ProbeUDPLifetime . Load ( ) ,
"AppCStoreRoutes" : k . AppCStoreRoutes . Load ( ) ,
"AppCStoreRoutes" : k . AppCStoreRoutes . Load ( ) ,
"UserDialUseRoutes" : k . UserDialUseRoutes . Load ( ) ,
"UserDialUseRoutes" : k . UserDialUseRoutes . Load ( ) ,
"DisableSplitDNSWhenNoCustomResolvers" : k . DisableSplitDNSWhenNoCustomResolvers . Load ( ) ,
}
}
}
}