control/controlclient: send optional ConnectionHandleForTest with map requests (#15904)

This handle can be used in tests and debugging to identify the specific
client connection.

Updates tailscale/corp#28368

Change-Id: I48cc573fc0bcf018c66a18e67ad6c4f248fb760c

Signed-off-by: Brian Palmer <brianp@tailscale.com>
This commit is contained in:
Brian Palmer 2025-05-07 12:57:56 -06:00 committed by GitHub
parent fd263adc1b
commit f5cc657e13
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 37 additions and 20 deletions

View File

@ -95,15 +95,16 @@ type Direct struct {
sfGroup singleflight.Group[struct{}, *NoiseClient] // protects noiseClient creation.
noiseClient *NoiseClient
persist persist.PersistView
authKey string
tryingNewKey key.NodePrivate
expiry time.Time // or zero value if none/unknown
hostinfo *tailcfg.Hostinfo // always non-nil
netinfo *tailcfg.NetInfo
endpoints []tailcfg.Endpoint
tkaHead string
lastPingURL string // last PingRequest.URL received, for dup suppression
persist persist.PersistView
authKey string
tryingNewKey key.NodePrivate
expiry time.Time // or zero value if none/unknown
hostinfo *tailcfg.Hostinfo // always non-nil
netinfo *tailcfg.NetInfo
endpoints []tailcfg.Endpoint
tkaHead string
lastPingURL string // last PingRequest.URL received, for dup suppression
connectionHandleForTest string // sent in MapRequest.ConnectionHandleForTest
}
// Observer is implemented by users of the control client (such as LocalBackend)
@ -403,6 +404,14 @@ func (c *Direct) SetTKAHead(tkaHead string) bool {
return true
}
// SetConnectionHandleForTest stores a new MapRequest.ConnectionHandleForTest
// value for the next update.
func (c *Direct) SetConnectionHandleForTest(handle string) {
c.mu.Lock()
defer c.mu.Unlock()
c.connectionHandleForTest = handle
}
func (c *Direct) GetPersist() persist.PersistView {
c.mu.Lock()
defer c.mu.Unlock()
@ -851,6 +860,7 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap
serverNoiseKey := c.serverNoiseKey
hi := c.hostInfoLocked()
backendLogID := hi.BackendLogID
connectionHandleForTest := c.connectionHandleForTest
var epStrs []string
var eps []netip.AddrPort
var epTypes []tailcfg.EndpointType
@ -891,17 +901,18 @@ func (c *Direct) sendMapRequest(ctx context.Context, isStreaming bool, nu Netmap
nodeKey := persist.PublicNodeKey()
request := &tailcfg.MapRequest{
Version: tailcfg.CurrentCapabilityVersion,
KeepAlive: true,
NodeKey: nodeKey,
DiscoKey: c.discoPubKey,
Endpoints: eps,
EndpointTypes: epTypes,
Stream: isStreaming,
Hostinfo: hi,
DebugFlags: c.debugFlags,
OmitPeers: nu == nil,
TKAHead: c.tkaHead,
Version: tailcfg.CurrentCapabilityVersion,
KeepAlive: true,
NodeKey: nodeKey,
DiscoKey: c.discoPubKey,
Endpoints: eps,
EndpointTypes: epTypes,
Stream: isStreaming,
Hostinfo: hi,
DebugFlags: c.debugFlags,
OmitPeers: nu == nil,
TKAHead: c.tkaHead,
ConnectionHandleForTest: connectionHandleForTest,
}
var extraDebugFlags []string
if hi != nil && c.netMon != nil && !c.skipIPForwardingCheck &&

View File

@ -1413,6 +1413,12 @@ type MapRequest struct {
// * "warn-router-unhealthy": client's Router implementation is
// having problems.
DebugFlags []string `json:",omitempty"`
// ConnectionHandleForTest, if non-empty, is an opaque string sent by the client that
// identifies this specific connection to the server. The server may choose to
// use this handle to identify the connection for debugging or testing
// purposes. It has no semantic meaning.
ConnectionHandleForTest string `json:",omitempty"`
}
// PortRange represents a range of UDP or TCP port numbers.