Skip to content

Commit 25663b1

Browse files
committed
tailcfg: remove most Debug fields, move bulk to nodeAttrs [capver 70]
Now a nodeAttr: ForceBackgroundSTUN, DERPRoute, TrimWGConfig, DisableSubnetsIfPAC, DisableUPnP. Kept support for, but also now a NodeAttr: RandomizeClientPort. Removed: SetForceBackgroundSTUN, SetRandomizeClientPort (both never used, sadly... never got around to them. But nodeAttrs are better anyway), EnableSilentDisco (will be a nodeAttr later when that effort resumes). Updates tailscale#8923 Signed-off-by: Brad Fitzpatrick <[email protected]>
1 parent e92adfe commit 25663b1

File tree

10 files changed

+82
-180
lines changed

10 files changed

+82
-180
lines changed

control/controlclient/direct.go

+29-20
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ import (
2222
"os"
2323
"reflect"
2424
"runtime"
25+
"slices"
2526
"strings"
2627
"sync"
28+
"sync/atomic"
2729
"time"
2830

2931
"go4.org/mem"
@@ -41,14 +43,12 @@ import (
4143
"tailscale.com/net/tlsdial"
4244
"tailscale.com/net/tsdial"
4345
"tailscale.com/net/tshttpproxy"
44-
"tailscale.com/syncs"
4546
"tailscale.com/tailcfg"
4647
"tailscale.com/tka"
4748
"tailscale.com/tstime"
4849
"tailscale.com/types/key"
4950
"tailscale.com/types/logger"
5051
"tailscale.com/types/netmap"
51-
"tailscale.com/types/opt"
5252
"tailscale.com/types/persist"
5353
"tailscale.com/types/ptr"
5454
"tailscale.com/types/tkatype"
@@ -1084,8 +1084,6 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap
10841084
}
10851085

10861086
hasDebug := resp.Debug != nil
1087-
// being conservative here, if Debug not present set to False
1088-
controlknobs.SetDisableUPnP(hasDebug && resp.Debug.DisableUPnP.EqualBool(true))
10891087
if hasDebug {
10901088
if code := resp.Debug.Exit; code != nil {
10911089
c.logf("exiting process with status %v per controlplane", *code)
@@ -1102,17 +1100,21 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap
11021100
}
11031101
}
11041102

1103+
// For responses that mutate the self node, check for updated nodeAttrs.
1104+
if resp.Node != nil {
1105+
caps := resp.Node.Capabilities
1106+
controlknobs.SetDisableUPnP(slices.Contains(caps, tailcfg.NodeAttrDisableUPnP))
1107+
controlDisableDRPO.Store(slices.Contains(caps, tailcfg.NodeAttrDebugDisableDRPO))
1108+
controlKeepFullWGConfig.Store(slices.Contains(caps, tailcfg.NodeAttrDebugDisableWGTrim))
1109+
controlRandomizeClientPort.Store(slices.Contains(caps, tailcfg.NodeAttrRandomizeClientPort))
1110+
}
1111+
11051112
nm := sess.netmapForResponse(&resp)
11061113
if nm.SelfNode == nil {
11071114
c.logf("MapResponse lacked node")
11081115
return errors.New("MapResponse lacked node")
11091116
}
11101117

1111-
if d := nm.Debug; d != nil {
1112-
controlUseDERPRoute.Store(d.DERPRoute)
1113-
controlTrimWGConfig.Store(d.TrimWGConfig)
1114-
}
1115-
11161118
if DevKnob.StripEndpoints() {
11171119
for _, p := range resp.Peers {
11181120
p.Endpoints = nil
@@ -1315,22 +1317,29 @@ func initDevKnob() devKnobs {
13151317

13161318
var clock tstime.Clock = tstime.StdClock{}
13171319

1318-
// opt.Bool configs from control.
1320+
// config from control.
13191321
var (
1320-
controlUseDERPRoute syncs.AtomicValue[opt.Bool]
1321-
controlTrimWGConfig syncs.AtomicValue[opt.Bool]
1322+
controlDisableDRPO atomic.Bool
1323+
controlKeepFullWGConfig atomic.Bool
1324+
controlRandomizeClientPort atomic.Bool
13221325
)
13231326

1324-
// DERPRouteFlag reports the last reported value from control for whether
1325-
// DERP route optimization (Issue 150) should be enabled.
1326-
func DERPRouteFlag() opt.Bool {
1327-
return controlUseDERPRoute.Load()
1327+
// DisableDRPO reports whether control says to disable the
1328+
// DERP route optimization (Issue 150).
1329+
func DisableDRPO() bool {
1330+
return controlDisableDRPO.Load()
1331+
}
1332+
1333+
// KeepFullWGConfig reports whether control says we should disable the lazy
1334+
// wireguard programming and instead give it the full netmap always.
1335+
func KeepFullWGConfig() bool {
1336+
return controlKeepFullWGConfig.Load()
13281337
}
13291338

1330-
// TrimWGConfig reports the last reported value from control for whether
1331-
// we should do lazy wireguard configuration.
1332-
func TrimWGConfig() opt.Bool {
1333-
return controlTrimWGConfig.Load()
1339+
// RandomizeClientPort reports whether control says we should randomize
1340+
// the client port.
1341+
func RandomizeClientPort() bool {
1342+
return controlRandomizeClientPort.Load()
13341343
}
13351344

13361345
// ipForwardingBroken reports whether the system's IP forwarding is disabled

control/controlclient/map.go

-18
Original file line numberDiff line numberDiff line change
@@ -147,24 +147,12 @@ func (ms *mapSession) netmapForResponse(resp *tailcfg.MapResponse) *netmap.Netwo
147147

148148
debug := resp.Debug
149149
if debug != nil {
150-
if debug.RandomizeClientPort {
151-
debug.SetRandomizeClientPort.Set(true)
152-
}
153-
if debug.ForceBackgroundSTUN {
154-
debug.SetForceBackgroundSTUN.Set(true)
155-
}
156150
copyDebugOptBools(&ms.stickyDebug, debug)
157151
} else if ms.stickyDebug != (tailcfg.Debug{}) {
158152
debug = new(tailcfg.Debug)
159153
}
160154
if debug != nil {
161155
copyDebugOptBools(debug, &ms.stickyDebug)
162-
if !debug.ForceBackgroundSTUN {
163-
debug.ForceBackgroundSTUN, _ = ms.stickyDebug.SetForceBackgroundSTUN.Get()
164-
}
165-
if !debug.RandomizeClientPort {
166-
debug.RandomizeClientPort, _ = ms.stickyDebug.SetRandomizeClientPort.Get()
167-
}
168156
}
169157

170158
nm := &netmap.NetworkMap{
@@ -420,11 +408,5 @@ func copyDebugOptBools(dst, src *tailcfg.Debug) {
420408
*v = s
421409
}
422410
}
423-
copy(&dst.DERPRoute, src.DERPRoute)
424-
copy(&dst.DisableSubnetsIfPAC, src.DisableSubnetsIfPAC)
425-
copy(&dst.DisableUPnP, src.DisableUPnP)
426411
copy(&dst.OneCGNATRoute, src.OneCGNATRoute)
427-
copy(&dst.SetForceBackgroundSTUN, src.SetForceBackgroundSTUN)
428-
copy(&dst.SetRandomizeClientPort, src.SetRandomizeClientPort)
429-
copy(&dst.TrimWGConfig, src.TrimWGConfig)
430412
}

control/controlclient/map_test.go

+3-73
Original file line numberDiff line numberDiff line change
@@ -472,11 +472,10 @@ func TestNetmapForResponse(t *testing.T) {
472472

473473
// TestDeltaDebug tests that tailcfg.Debug values can be omitted in MapResponses
474474
// entirely or have their opt.Bool values unspecified between MapResponses in a
475-
// session and that should mean no change. (as of capver 37). But two Debug
476-
// fields existed prior to capver 37 that weren't opt.Bool; we test that we both
475+
// session and that should mean no change. (as of capver 37). But one Debug
476+
// field existed prior to capver 37 that wasn't opt.Bool; we test that we both
477477
// still accept the non-opt.Bool form from control for RandomizeClientPort and
478-
// ForceBackgroundSTUN and also accept the new form, keeping the old form in
479-
// sync.
478+
// also accept the new form, keeping the old form in sync.
480479
func TestDeltaDebug(t *testing.T) {
481480
type step struct {
482481
got *tailcfg.Debug
@@ -493,44 +492,6 @@ func TestDeltaDebug(t *testing.T) {
493492
{nil, nil},
494493
},
495494
},
496-
{
497-
name: "sticky-with-old-style-randomize-client-port",
498-
steps: []step{
499-
{
500-
&tailcfg.Debug{RandomizeClientPort: true},
501-
&tailcfg.Debug{
502-
RandomizeClientPort: true,
503-
SetRandomizeClientPort: "true",
504-
},
505-
},
506-
{
507-
nil, // not sent by server
508-
&tailcfg.Debug{
509-
RandomizeClientPort: true,
510-
SetRandomizeClientPort: "true",
511-
},
512-
},
513-
},
514-
},
515-
{
516-
name: "sticky-with-new-style-randomize-client-port",
517-
steps: []step{
518-
{
519-
&tailcfg.Debug{SetRandomizeClientPort: "true"},
520-
&tailcfg.Debug{
521-
RandomizeClientPort: true,
522-
SetRandomizeClientPort: "true",
523-
},
524-
},
525-
{
526-
nil, // not sent by server
527-
&tailcfg.Debug{
528-
RandomizeClientPort: true,
529-
SetRandomizeClientPort: "true",
530-
},
531-
},
532-
},
533-
},
534495
{
535496
name: "opt-bool-sticky-changing-over-time",
536497
steps: []step{
@@ -554,37 +515,6 @@ func TestDeltaDebug(t *testing.T) {
554515
},
555516
},
556517
},
557-
{
558-
name: "legacy-ForceBackgroundSTUN",
559-
steps: []step{
560-
{
561-
&tailcfg.Debug{ForceBackgroundSTUN: true},
562-
&tailcfg.Debug{ForceBackgroundSTUN: true, SetForceBackgroundSTUN: "true"},
563-
},
564-
},
565-
},
566-
{
567-
name: "opt-bool-SetForceBackgroundSTUN",
568-
steps: []step{
569-
{
570-
&tailcfg.Debug{SetForceBackgroundSTUN: "true"},
571-
&tailcfg.Debug{ForceBackgroundSTUN: true, SetForceBackgroundSTUN: "true"},
572-
},
573-
},
574-
},
575-
{
576-
name: "server-reset-to-default",
577-
steps: []step{
578-
{
579-
&tailcfg.Debug{SetForceBackgroundSTUN: "true"},
580-
&tailcfg.Debug{ForceBackgroundSTUN: true, SetForceBackgroundSTUN: "true"},
581-
},
582-
{
583-
&tailcfg.Debug{SetForceBackgroundSTUN: "unset"},
584-
&tailcfg.Debug{ForceBackgroundSTUN: false, SetForceBackgroundSTUN: "unset"},
585-
},
586-
},
587-
},
588518
}
589519
for _, tt := range tests {
590520
t.Run(tt.name, func(t *testing.T) {

ipn/ipnlocal/local.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -2987,7 +2987,7 @@ func (b *LocalBackend) authReconfig() {
29872987
prefs := b.pm.CurrentPrefs()
29882988
nm := b.netMap
29892989
hasPAC := b.prevIfState.HasPAC()
2990-
disableSubnetsIfPAC := nm != nil && nm.Debug != nil && nm.Debug.DisableSubnetsIfPAC.EqualBool(true)
2990+
disableSubnetsIfPAC := hasCapability(nm, tailcfg.NodeAttrDisableSubnetsIfPAC)
29912991
b.mu.Unlock()
29922992

29932993
if blocked {

tailcfg/tailcfg.go

+32-49
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ type CapabilityVersion int
107107
// - 67: 2023-07-25: Client understands PeerCapMap
108108
// - 68: 2023-08-09: Client has dedicated updateRoutine; MapRequest.Stream true means ignore Hostinfo+Endpoints
109109
// - 69: 2023-08-16: removed Debug.LogHeap* + GoroutineDumpURL; added c2n /debug/logheap
110-
const CurrentCapabilityVersion CapabilityVersion = 69
110+
// - 70: 2023-08-16: removed most Debug fields; added NodeAttrDisable*, NodeAttrDebug* instead
111+
const CurrentCapabilityVersion CapabilityVersion = 70
111112

112113
type StableID string
113114

@@ -1750,35 +1751,6 @@ type ControlIPCandidate struct {
17501751
//
17511752
// TODO(bradfitz): start migrating the imperative ones to c2n requests.
17521753
type Debug struct {
1753-
// ForceBackgroundSTUN controls whether magicsock should
1754-
// always do its background STUN queries (see magicsock's
1755-
// periodicReSTUN), regardless of inactivity.
1756-
ForceBackgroundSTUN bool `json:",omitempty"`
1757-
1758-
// SetForceBackgroundSTUN controls whether magicsock should always do its
1759-
// background STUN queries (see magicsock's periodicReSTUN), regardless of
1760-
// inactivity.
1761-
//
1762-
// As of capver 37, this field is the preferred field for control to set on
1763-
// the wire and ForceBackgroundSTUN is only used within the code as the
1764-
// current map session value. But ForceBackgroundSTUN can still be used too.
1765-
SetForceBackgroundSTUN opt.Bool `json:",omitempty"`
1766-
1767-
// DERPRoute controls whether the DERP reverse path
1768-
// optimization (see Issue 150) should be enabled or
1769-
// disabled. The environment variable in magicsock is the
1770-
// highest priority (if set), then this (if set), then the
1771-
// binary default value.
1772-
DERPRoute opt.Bool `json:",omitempty"`
1773-
1774-
// TrimWGConfig controls whether Tailscale does lazy, on-demand
1775-
// wireguard configuration of peers.
1776-
TrimWGConfig opt.Bool `json:",omitempty"`
1777-
1778-
// DisableSubnetsIfPAC controls whether subnet routers should be
1779-
// disabled if WPAD is present on the network.
1780-
DisableSubnetsIfPAC opt.Bool `json:",omitempty"`
1781-
17821754
// SleepSeconds requests that the client sleep for the
17831755
// provided number of seconds.
17841756
// The client can (and should) limit the value (such as 5
@@ -1788,35 +1760,18 @@ type Debug struct {
17881760
// RandomizeClientPort is whether magicsock should UDP bind to
17891761
// :0 to get a random local port, ignoring any configured
17901762
// fixed port.
1791-
RandomizeClientPort bool `json:",omitempty"`
1792-
1793-
// SetRandomizeClientPort is whether magicsock should UDP bind to :0 to get
1794-
// a random local port, ignoring any configured fixed port.
17951763
//
1796-
// As of capver 37, this field is the preferred field for control to set on
1797-
// the wire and RandomizeClientPort is only used within the code as the
1798-
// current map session value. But RandomizeClientPort can still be used too.
1799-
SetRandomizeClientPort opt.Bool `json:",omitempty"`
1764+
// Deprecated: use NodeAttrRandomizeClientPort instead.
1765+
RandomizeClientPort bool `json:",omitempty"`
18001766

18011767
// OneCGNATRoute controls whether the client should prefer to make one
18021768
// big CGNAT /10 route rather than a /32 per peer.
18031769
OneCGNATRoute opt.Bool `json:",omitempty"`
18041770

1805-
// DisableUPnP is whether the client will attempt to perform a UPnP portmapping.
1806-
// By default, we want to enable it to see if it works on more clients.
1807-
//
1808-
// If UPnP catastrophically fails for people, this should be set to True to kill
1809-
// new attempts at UPnP connections.
1810-
DisableUPnP opt.Bool `json:",omitempty"`
1811-
18121771
// DisableLogTail disables the logtail package. Once disabled it can't be
18131772
// re-enabled for the lifetime of the process.
18141773
DisableLogTail bool `json:",omitempty"`
18151774

1816-
// EnableSilentDisco disables the use of heartBeatTimer in magicsock and attempts to
1817-
// handle disco silently. See issue #540 for details.
1818-
EnableSilentDisco bool `json:",omitempty"`
1819-
18201775
// Exit optionally specifies that the client should os.Exit
18211776
// with this code.
18221777
Exit *int `json:",omitempty"`
@@ -2003,6 +1958,34 @@ const (
20031958
NodeAttrFunnel = "funnel"
20041959
// NodeAttrSSHAggregator grants the ability for a node to collect SSH sessions.
20051960
NodeAttrSSHAggregator = "ssh-aggregator"
1961+
1962+
// NodeAttrDebugForceBackgroundSTUN forces a node to always do background
1963+
// STUN queries regardless of inactivity.
1964+
NodeAttrDebugForceBackgroundSTUN = "debug-always-stun"
1965+
1966+
// NodeAttrDebugDisableWGTrim disables the lazy WireGuard configuration,
1967+
// always giving WireGuard the full netmap, even for idle peers.
1968+
NodeAttrDebugDisableWGTrim = "debug-no-wg-trim"
1969+
1970+
// NodeAttrDebugDisableDRPO disables the DERP Return Path Optimization.
1971+
// See Issue 150.
1972+
NodeAttrDebugDisableDRPO = "debug-disable-drpo"
1973+
1974+
// NodeAttrDisableSubnetsIfPAC controls whether subnet routers should be
1975+
// disabled if WPAD is present on the network.
1976+
NodeAttrDisableSubnetsIfPAC = "debug-disable-subnets-if-pac"
1977+
1978+
// NodeAttrDisableUPnP makes the client not perform a UPnP portmapping.
1979+
// By default, we want to enable it to see if it works on more clients.
1980+
//
1981+
// If UPnP catastrophically fails for people, this should be set kill
1982+
// new attempts at UPnP connections.
1983+
NodeAttrDisableUPnP = "debug-disable-upnp"
1984+
1985+
// NodeAttrRandomizeClientPort makes magicsock UDP bind to
1986+
// :0 to get a random local port, ignoring any configured
1987+
// fixed port.
1988+
NodeAttrRandomizeClientPort = "randomize-client-port"
20061989
)
20071990

20081991
// SetDNSRequest is a request to add a DNS record.

tstest/integration/testcontrol/testcontrol.go

+4-5
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,8 @@ func (s *Server) MapResponse(req *tailcfg.MapRequest) (res *tailcfg.MapResponse,
814814
// node key rotated away (once test server supports that)
815815
return nil, nil
816816
}
817+
node.Capabilities = append(node.Capabilities, tailcfg.NodeAttrDisableUPnP)
818+
817819
user, _ := s.getUser(nk)
818820
t := time.Date(2020, 8, 3, 0, 0, 0, 1, time.UTC)
819821
dns := s.DNSConfig
@@ -830,11 +832,8 @@ func (s *Server) MapResponse(req *tailcfg.MapRequest) (res *tailcfg.MapResponse,
830832
Domain: string(user.Domain),
831833
CollectServices: "true",
832834
PacketFilter: packetFilterWithIngressCaps(),
833-
Debug: &tailcfg.Debug{
834-
DisableUPnP: "true",
835-
},
836-
DNSConfig: dns,
837-
ControlTime: &t,
835+
DNSConfig: dns,
836+
ControlTime: &t,
838837
}
839838

840839
s.mu.Lock()

0 commit comments

Comments
 (0)