control/controlclient: add Debug field to NetworkMap

As part of disabling background STUN packets when idle, we want an
emergency override switch to turn it back on, in case it interacts
poorly in the wild. We'll send that via control, but we'll want to
plumb it down to magicsock via NetworkMap.

Updates tailscale/corp#320

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2020-06-25 10:47:33 -07:00 committed by Brad Fitzpatrick
parent 0071888a17
commit b8edb7a5e9
3 changed files with 71 additions and 23 deletions

View File

@ -620,6 +620,7 @@ func (c *Direct) PollNetMap(ctx context.Context, maxPolls int, cb func(*NetworkM
Hostinfo: resp.Node.Hostinfo,
PacketFilter: c.parsePacketFilter(resp.PacketFilter),
DERPMap: lastDERPMap,
Debug: resp.Debug,
}
for _, profile := range resp.UserProfiles {
nm.UserProfiles[profile.ID] = profile

View File

@ -39,6 +39,9 @@ type NetworkMap struct {
// between updates and should not be modified.
DERPMap *tailcfg.DERPMap
// Debug knobs from control server for debug or feature gating.
Debug *tailcfg.Debug
// ACLs
User tailcfg.UserID
@ -70,9 +73,17 @@ func (nm NetworkMap) String() string {
func (nm *NetworkMap) Concise() string {
buf := new(strings.Builder)
fmt.Fprintf(buf, "netmap: self: %v auth=%v :%v %v\n",
nm.NodeKey.ShortString(), nm.MachineStatus,
nm.LocalPort, nm.Addresses)
fmt.Fprintf(buf, "netmap: self: %v auth=%v",
nm.NodeKey.ShortString(), nm.MachineStatus)
if nm.LocalPort != 0 {
fmt.Fprintf(buf, " port=%v", nm.LocalPort)
}
if nm.Debug != nil {
j, _ := json.Marshal(nm.Debug)
fmt.Fprintf(buf, " debug=%s", j)
}
fmt.Fprintf(buf, " %v", nm.Addresses)
buf.WriteByte('\n')
for _, p := range nm.Peers {
aip := make([]string, len(p.AllowedIPs))
for i, a := range p.AllowedIPs {

View File

@ -11,26 +11,62 @@
)
func TestNetworkMapConcise(t *testing.T) {
nm := &NetworkMap{
Peers: []*tailcfg.Node{
{
Name: "foo",
Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
},
{
Name: "bar",
Endpoints: []string{"10.2.0.100:12", "10.1.0.100:12345"},
},
},
nodekey := func(b byte) (ret tailcfg.NodeKey) {
for i := range ret {
ret[i] = b
}
return
}
var got string
n := int(testing.AllocsPerRun(1000, func() {
got = nm.Concise()
}))
t.Logf("Allocs = %d", n)
want := "netmap: self: [AAAAA] auth=machine-unknown :0 []\n" +
" [AAAAA] : 192.168.0.100:12 192.168.0.100:12354\n [AAAAA] : 10.2.0.100:12 10.1.0.100:12345\n"
if got != want {
t.Errorf("Wrong output\n Got: %q\nWant: %q\n## Got (unescaped):\n%s\n## Want (unescaped):\n%s\n", got, want, got, want)
for _, tt := range []struct {
name string
nm *NetworkMap
want string
}{
{
name: "basic",
nm: &NetworkMap{
NodeKey: nodekey(1),
Peers: []*tailcfg.Node{
{
Key: nodekey(2),
DERP: "127.3.3.40:2",
Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"},
},
{
Key: nodekey(3),
DERP: "127.3.3.40:4",
Endpoints: []string{"10.2.0.100:12", "10.1.0.100:12345"},
},
},
},
want: "netmap: self: [AQEBA] auth=machine-unknown []\n [AgICA] D2 : 192.168.0.100:12 192.168.0.100:12354\n [AwMDA] D4 : 10.2.0.100:12 10.1.0.100:12345\n",
},
{
name: "debug_non_nil",
nm: &NetworkMap{
NodeKey: nodekey(1),
Debug: &tailcfg.Debug{},
},
want: "netmap: self: [AQEBA] auth=machine-unknown debug={} []\n",
},
{
name: "debug_values",
nm: &NetworkMap{
NodeKey: nodekey(1),
Debug: &tailcfg.Debug{LogHeapPprof: true},
},
want: "netmap: self: [AQEBA] auth=machine-unknown debug={\"LogHeapPprof\":true} []\n",
},
} {
t.Run(tt.name, func(t *testing.T) {
var got string
n := int(testing.AllocsPerRun(1000, func() {
got = tt.nm.Concise()
}))
t.Logf("Allocs = %d", n)
if got != tt.want {
t.Errorf("Wrong output\n Got: %q\nWant: %q\n## Got (unescaped):\n%s\n## Want (unescaped):\n%s\n", got, tt.want, got, tt.want)
}
})
}
}