wgengine/wglog: stop using netmap.NetworkMap here too

This applies the same treatment from 8f210454dd (netlog) to wglog,
ending use of netmap.NetworkMap and instead getting the canonical data
from LocalBackend/nodeBackend.

This is a dependency to removing the netmap.NetworkMap from
upstream callers, like wgengine.Engine in general.

Updates #12542

Change-Id: Icb5af0799322def048a6f594b49f7d11273f025d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2026-06-23 09:06:37 -07:00
committed by Brad Fitzpatrick
parent 295bf20cfd
commit 988b0905bb
8 changed files with 217 additions and 92 deletions
+20
View File
@@ -646,6 +646,7 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo
e.SetPeerByIPPacketFunc(b.lookupPeerByIP)
e.SetPeerSessionStateFunc(b.onPeerWireGuardState)
e.SetNetLogNodeSource(netLogNodeSource{b})
e.SetWGPeerLookup(b.lookupPeerWireGuardString)
if sys.InitialConfig != nil {
if err := b.initPrefsFromConfig(sys.InitialConfig); err != nil {
@@ -8090,6 +8091,25 @@ func (s netLogNodeSource) NodeByAddr(addr netip.Addr) (_ tailcfg.NodeView, _ tai
// Compile-time assertion that netLogNodeSource implements [netlog.NodeSource].
var _ netlog.NodeSource = netLogNodeSource{}
// lookupPeerWireGuardString returns the Tailscale-conventional short string
// (e.g. "[IMTBr]") for the peer whose wireguard-go-formatted public key
// string is wgString (e.g. "peer(IMTB…r7lM)"), or "", false if no current
// peer matches. It is installed on the engine via [Engine.SetWGPeerLookup]
// in [NewLocalBackend] so that [wglog.Logger] can rewrite peer references
// in wireguard-go log lines without any per-Reconfig denormalization.
func (b *LocalBackend) lookupPeerWireGuardString(wgString string) (tsString string, ok bool) {
nb := b.currentNode()
nid, ok := nb.NodeByWireGuardString(wgString)
if !ok {
return "", false
}
nv, ok := nb.NodeByID(nid)
if !ok {
return "", false
}
return nv.Key().ShortString(), true
}
// ActiveSSHConns returns the number of active SSH connections,
// or 0 if SSH is not linked into the binary or available on the platform.
func (b *LocalBackend) ActiveSSHConns() int {
+34
View File
@@ -116,6 +116,15 @@ type nodeBackend struct {
// It is mutated in place (with mu held) and must not escape the [nodeBackend].
nodeByKey map[key.NodePublic]tailcfg.NodeID
// nodeByWGString indexes wireguard-go's truncated peer-string form
// (see [key.NodePublic.WireGuardGoString]) to node ID. It mirrors
// nodeByKey and lets the wireguard-go log path resolve
// "peer(XXXX…YYYY)" references in O(1), without scanning every
// peer, while still tolerating the fact that the wireguard-go form
// is lossy and can't be inverted to a [key.NodePublic].
// It is mutated in place (with mu held) and must not escape the [nodeBackend].
nodeByWGString map[string]tailcfg.NodeID
// userProfiles is the live set of user profiles, updated incrementally
// by mergeUserProfiles as deltas arrive. It parallels the peers map:
// netMap.UserProfiles is the frozen snapshot from the last full install,
@@ -229,6 +238,16 @@ func (nb *nodeBackend) NodeByKey(k key.NodePublic) (_ tailcfg.NodeID, ok bool) {
return nid, ok
}
// NodeByWireGuardString returns the node ID of the peer whose
// [key.NodePublic.WireGuardGoString] form is s (e.g. "peer(IMTB…r7lM)").
// ok is false if no current peer matches.
func (nb *nodeBackend) NodeByWireGuardString(s string) (_ tailcfg.NodeID, ok bool) {
nb.mu.Lock()
defer nb.mu.Unlock()
nid, ok := nb.nodeByWGString[s]
return nid, ok
}
func (nb *nodeBackend) NodeByID(id tailcfg.NodeID) (_ tailcfg.NodeView, ok bool) {
nb.mu.Lock()
defer nb.mu.Unlock()
@@ -580,18 +599,26 @@ func (nb *nodeBackend) updateNodeByKeyLocked() {
nm := nb.netMap
if nm == nil {
nb.nodeByKey = nil
nb.nodeByWGString = nil
return
}
if nb.nodeByKey == nil {
nb.nodeByKey = map[key.NodePublic]tailcfg.NodeID{}
}
if nb.nodeByWGString == nil {
nb.nodeByWGString = map[string]tailcfg.NodeID{}
}
// First pass, mark everything unwanted.
for k := range nb.nodeByKey {
nb.nodeByKey[k] = 0
}
for k := range nb.nodeByWGString {
nb.nodeByWGString[k] = 0
}
addNode := func(n tailcfg.NodeView) {
nb.nodeByKey[n.Key()] = n.ID()
nb.nodeByWGString[n.Key().WireGuardGoString()] = n.ID()
}
if nm.SelfNode.Valid() {
addNode(nm.SelfNode)
@@ -605,6 +632,11 @@ func (nb *nodeBackend) updateNodeByKeyLocked() {
delete(nb.nodeByKey, k)
}
}
for k, v := range nb.nodeByWGString {
if v == 0 {
delete(nb.nodeByWGString, k)
}
}
}
func (nb *nodeBackend) updatePeersLocked() {
@@ -684,6 +716,7 @@ func (nb *nodeBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo
}
}
mak.Set(&nb.nodeByKey, m.Node.Key(), nid)
mak.Set(&nb.nodeByWGString, m.Node.Key().WireGuardGoString(), nid)
continue
case netmap.NodeMutationRemove:
nid := m.NodeIDBeingMutated()
@@ -694,6 +727,7 @@ func (nb *nodeBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo
}
}
delete(nb.nodeByKey, old.Key())
delete(nb.nodeByWGString, old.Key().WireGuardGoString())
delete(nb.peers, nid)
}
continue
+1
View File
@@ -1986,6 +1986,7 @@ func (e *mockEngine) SetPeerByIPPacketFunc(func(netip.Addr) (_ key.NodePublic, o
func (e *mockEngine) SetPeerSessionStateFunc(func(key.NodePublic, wgengine.PeerWireGuardState)) {
}
func (e *mockEngine) SetNetLogNodeSource(netlog.NodeSource) {}
func (e *mockEngine) SetWGPeerLookup(func(wgString string) (tsString string, ok bool)) {}
func (e *mockEngine) Close() {
e.mu.Lock()