diff --git a/control/controlclient/direct.go b/control/controlclient/direct.go index 3ffeaba87..8346b59a7 100644 --- a/control/controlclient/direct.go +++ b/control/controlclient/direct.go @@ -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 diff --git a/control/controlclient/netmap.go b/control/controlclient/netmap.go index 71c00f90c..0556a25e4 100644 --- a/control/controlclient/netmap.go +++ b/control/controlclient/netmap.go @@ -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 { diff --git a/control/controlclient/netmap_test.go b/control/controlclient/netmap_test.go index 93f511b75..d9c23b93c 100644 --- a/control/controlclient/netmap_test.go +++ b/control/controlclient/netmap_test.go @@ -11,26 +11,62 @@ import ( ) func TestNetworkMapConcise(t *testing.T) { - nm := &NetworkMap{ - Peers: []*tailcfg.Node{ - { - Name: "foo", - Endpoints: []string{"192.168.0.100:12", "192.168.0.100:12354"}, + nodekey := func(b byte) (ret tailcfg.NodeKey) { + for i := range ret { + ret[i] = b + } + return + } + 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"}, + }, + }, }, - { - Name: "bar", - 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", }, - } - 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) + { + 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) + } + }) } }