mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-11 13:18:53 +00:00
tailcfg: add NodeCapMap
Like PeerCapMap, add a field to `tailcfg.Node` which provides a map of Capability to raw JSON messages which are deferred to be parsed later by the application code which cares about the specific capabilities. This effectively allows us to prototype new behavior without having to commit to a schema in tailcfg, and it also opens up the possibilities to develop custom behavior in tsnet applications w/o having to plumb through application specific data in the MapResponse. Updates #4217 Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
@@ -187,8 +187,9 @@ func (ms *mapSession) HandleNonKeepAliveMapResponse(ctx context.Context, resp *t
|
||||
if resp.Node != nil {
|
||||
if DevKnob.StripCaps() {
|
||||
resp.Node.Capabilities = nil
|
||||
resp.Node.CapMap = nil
|
||||
}
|
||||
ms.controlKnobs.UpdateFromNodeAttributes(resp.Node.Capabilities)
|
||||
ms.controlKnobs.UpdateFromNodeAttributes(resp.Node.Capabilities, resp.Node.CapMap)
|
||||
}
|
||||
|
||||
// Call Node.InitDisplayNames on any changed nodes.
|
||||
@@ -324,6 +325,7 @@ var (
|
||||
patchLastSeen = clientmetric.NewCounter("controlclient_patch_lastseen")
|
||||
patchKeyExpiry = clientmetric.NewCounter("controlclient_patch_keyexpiry")
|
||||
patchCapabilities = clientmetric.NewCounter("controlclient_patch_capabilities")
|
||||
patchCapMap = clientmetric.NewCounter("controlclient_patch_capmap")
|
||||
patchKeySignature = clientmetric.NewCounter("controlclient_patch_keysig")
|
||||
|
||||
patchifiedPeer = clientmetric.NewCounter("controlclient_patchified_peer")
|
||||
@@ -452,6 +454,10 @@ func (ms *mapSession) updatePeersStateFromResponse(resp *tailcfg.MapResponse) (s
|
||||
mut.KeySignature = v
|
||||
patchKeySignature.Add(1)
|
||||
}
|
||||
if v := pc.CapMap; v != nil {
|
||||
mut.CapMap = v
|
||||
patchCapMap.Add(1)
|
||||
}
|
||||
*vp = mut.View()
|
||||
}
|
||||
|
||||
@@ -647,6 +653,10 @@ func peerChangeDiff(was tailcfg.NodeView, n *tailcfg.Node) (_ *tailcfg.PeerChang
|
||||
if was.Cap() != n.Cap {
|
||||
pc().Cap = n.Cap
|
||||
}
|
||||
case "CapMap":
|
||||
if n.CapMap != nil {
|
||||
pc().CapMap = n.CapMap
|
||||
}
|
||||
case "Tags":
|
||||
if !views.SliceEqual(was.Tags(), views.SliceOf(n.Tags)) {
|
||||
return nil, false
|
||||
|
@@ -6,6 +6,7 @@
|
||||
package controlknobs
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"sync/atomic"
|
||||
|
||||
"tailscale.com/syncs"
|
||||
@@ -48,39 +49,30 @@ type Knobs struct {
|
||||
|
||||
// UpdateFromNodeAttributes updates k (if non-nil) based on the provided self
|
||||
// node attributes (Node.Capabilities).
|
||||
func (k *Knobs) UpdateFromNodeAttributes(selfNodeAttrs []tailcfg.NodeCapability) {
|
||||
func (k *Knobs) UpdateFromNodeAttributes(selfNodeAttrs []tailcfg.NodeCapability, capMap tailcfg.NodeCapMap) {
|
||||
if k == nil {
|
||||
return
|
||||
}
|
||||
var (
|
||||
keepFullWG bool
|
||||
disableDRPO bool
|
||||
disableUPnP bool
|
||||
randomizeClientPort bool
|
||||
disableDeltaUpdates bool
|
||||
oneCGNAT opt.Bool
|
||||
forceBackgroundSTUN bool
|
||||
)
|
||||
for _, attr := range selfNodeAttrs {
|
||||
switch attr {
|
||||
case tailcfg.NodeAttrDebugDisableWGTrim:
|
||||
keepFullWG = true
|
||||
case tailcfg.NodeAttrDebugDisableDRPO:
|
||||
disableDRPO = true
|
||||
case tailcfg.NodeAttrDisableUPnP:
|
||||
disableUPnP = true
|
||||
case tailcfg.NodeAttrRandomizeClientPort:
|
||||
randomizeClientPort = true
|
||||
case tailcfg.NodeAttrOneCGNATEnable:
|
||||
oneCGNAT.Set(true)
|
||||
case tailcfg.NodeAttrOneCGNATDisable:
|
||||
oneCGNAT.Set(false)
|
||||
case tailcfg.NodeAttrDebugForceBackgroundSTUN:
|
||||
forceBackgroundSTUN = true
|
||||
case tailcfg.NodeAttrDisableDeltaUpdates:
|
||||
disableDeltaUpdates = true
|
||||
}
|
||||
has := func(attr tailcfg.NodeCapability) bool {
|
||||
_, ok := capMap[attr]
|
||||
return ok || slices.Contains(selfNodeAttrs, attr)
|
||||
}
|
||||
var (
|
||||
keepFullWG = has(tailcfg.NodeAttrDebugDisableWGTrim)
|
||||
disableDRPO = has(tailcfg.NodeAttrDebugDisableDRPO)
|
||||
disableUPnP = has(tailcfg.NodeAttrDisableUPnP)
|
||||
randomizeClientPort = has(tailcfg.NodeAttrRandomizeClientPort)
|
||||
disableDeltaUpdates = has(tailcfg.NodeAttrDisableDeltaUpdates)
|
||||
oneCGNAT opt.Bool
|
||||
forceBackgroundSTUN = has(tailcfg.NodeAttrDebugForceBackgroundSTUN)
|
||||
)
|
||||
|
||||
if has(tailcfg.NodeAttrOneCGNATEnable) {
|
||||
oneCGNAT.Set(true)
|
||||
} else if has(tailcfg.NodeAttrOneCGNATDisable) {
|
||||
oneCGNAT.Set(false)
|
||||
}
|
||||
|
||||
k.KeepFullWGConfig.Store(keepFullWG)
|
||||
k.DisableDRPO.Store(disableDRPO)
|
||||
k.DisableUPnP.Store(disableUPnP)
|
||||
|
Reference in New Issue
Block a user