mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 21:27:31 +00:00
tailcfg, control/controlclient: make Debug settings sticky in a map session [capver 37]
Fixes #4843 Change-Id: I3accfd91be474ac745cb47f5d6e866c37d5c5d2d Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
8e821d7aa8
commit
4ee64681ad
@@ -16,6 +16,8 @@ import (
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/netmap"
|
||||
"tailscale.com/types/opt"
|
||||
"tailscale.com/util/must"
|
||||
)
|
||||
|
||||
func TestUndeltaPeers(t *testing.T) {
|
||||
@@ -449,3 +451,152 @@ func TestNetmapForResponse(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestDeltaDebug tests that tailcfg.Debug values can be omitted in MapResposnes
|
||||
// entirely or have their opt.Bool values unspecified between MapResponses in a
|
||||
// session and that should mean no change. (as of capver 37). But two Debug
|
||||
// fields existed prior to capver 37 that weren't opt.Bool; we test that we both
|
||||
// still accept the non-opt.Bool form from control for RandomizeClientPort and
|
||||
// ForceBackgroundSTUN and also accept the new form, keeping the old form in
|
||||
// sync.
|
||||
func TestDeltaDebug(t *testing.T) {
|
||||
type step struct {
|
||||
got *tailcfg.Debug
|
||||
want *tailcfg.Debug
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
steps []step
|
||||
}{
|
||||
{
|
||||
name: "nothing-to-nothing",
|
||||
steps: []step{
|
||||
{nil, nil},
|
||||
{nil, nil},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sticky-with-old-style-randomize-client-port",
|
||||
steps: []step{
|
||||
{
|
||||
&tailcfg.Debug{RandomizeClientPort: true},
|
||||
&tailcfg.Debug{
|
||||
RandomizeClientPort: true,
|
||||
SetRandomizeClientPort: "true",
|
||||
},
|
||||
},
|
||||
{
|
||||
nil, // not sent by server
|
||||
&tailcfg.Debug{
|
||||
RandomizeClientPort: true,
|
||||
SetRandomizeClientPort: "true",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sticky-with-new-style-randomize-client-port",
|
||||
steps: []step{
|
||||
{
|
||||
&tailcfg.Debug{SetRandomizeClientPort: "true"},
|
||||
&tailcfg.Debug{
|
||||
RandomizeClientPort: true,
|
||||
SetRandomizeClientPort: "true",
|
||||
},
|
||||
},
|
||||
{
|
||||
nil, // not sent by server
|
||||
&tailcfg.Debug{
|
||||
RandomizeClientPort: true,
|
||||
SetRandomizeClientPort: "true",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "opt-bool-sticky-changing-over-time",
|
||||
steps: []step{
|
||||
{nil, nil},
|
||||
{nil, nil},
|
||||
{
|
||||
&tailcfg.Debug{OneCGNATRoute: "true"},
|
||||
&tailcfg.Debug{OneCGNATRoute: "true"},
|
||||
},
|
||||
{
|
||||
nil,
|
||||
&tailcfg.Debug{OneCGNATRoute: "true"},
|
||||
},
|
||||
{
|
||||
&tailcfg.Debug{OneCGNATRoute: "false"},
|
||||
&tailcfg.Debug{OneCGNATRoute: "false"},
|
||||
},
|
||||
{
|
||||
nil,
|
||||
&tailcfg.Debug{OneCGNATRoute: "false"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "legacy-ForceBackgroundSTUN",
|
||||
steps: []step{
|
||||
{
|
||||
&tailcfg.Debug{ForceBackgroundSTUN: true},
|
||||
&tailcfg.Debug{ForceBackgroundSTUN: true, SetForceBackgroundSTUN: "true"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "opt-bool-SetForceBackgroundSTUN",
|
||||
steps: []step{
|
||||
{
|
||||
&tailcfg.Debug{SetForceBackgroundSTUN: "true"},
|
||||
&tailcfg.Debug{ForceBackgroundSTUN: true, SetForceBackgroundSTUN: "true"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "server-reset-to-default",
|
||||
steps: []step{
|
||||
{
|
||||
&tailcfg.Debug{SetForceBackgroundSTUN: "true"},
|
||||
&tailcfg.Debug{ForceBackgroundSTUN: true, SetForceBackgroundSTUN: "true"},
|
||||
},
|
||||
{
|
||||
&tailcfg.Debug{SetForceBackgroundSTUN: "unset"},
|
||||
&tailcfg.Debug{ForceBackgroundSTUN: false, SetForceBackgroundSTUN: "unset"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
ms := newTestMapSession(t)
|
||||
for stepi, s := range tt.steps {
|
||||
nm := ms.netmapForResponse(&tailcfg.MapResponse{Debug: s.got})
|
||||
if !reflect.DeepEqual(nm.Debug, s.want) {
|
||||
t.Errorf("unexpected result at step index %v; got: %s", stepi, must.Get(json.Marshal(nm.Debug)))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that copyDebugOptBools doesn't missing any opt.Bools.
|
||||
func TestCopyDebugOptBools(t *testing.T) {
|
||||
rt := reflect.TypeOf(tailcfg.Debug{})
|
||||
for i := 0; i < rt.NumField(); i++ {
|
||||
sf := rt.Field(i)
|
||||
if sf.Type != reflect.TypeOf(opt.Bool("")) {
|
||||
continue
|
||||
}
|
||||
var src, dst tailcfg.Debug
|
||||
reflect.ValueOf(&src).Elem().Field(i).Set(reflect.ValueOf(opt.Bool("true")))
|
||||
if src == (tailcfg.Debug{}) {
|
||||
t.Fatalf("failed to set field %v", sf.Name)
|
||||
}
|
||||
copyDebugOptBools(&dst, &src)
|
||||
if src != dst {
|
||||
t.Fatalf("copyDebugOptBools didn't copy field %v", sf.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user