From 299f1bf581886a6d9051d6ac60efc770db5321ab Mon Sep 17 00:00:00 2001 From: Harry Harpham Date: Thu, 12 Feb 2026 16:38:18 -0700 Subject: [PATCH] testcontrol: ensure Server.UpdateNode triggers netmap updates Updating a node on a testcontrol server should trigger netmap updates to all connected streaming clients. This was not the case previous to this change and consequently caused race conditions in tests. It was possible for a test to call UpdateNode and for connected nodes to never see the update propagate. Updates #16340 Fixes #18703 Signed-off-by: Harry Harpham --- tstest/integration/testcontrol/testcontrol.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tstest/integration/testcontrol/testcontrol.go b/tstest/integration/testcontrol/testcontrol.go index 56664ba74..1e2441490 100644 --- a/tstest/integration/testcontrol/testcontrol.go +++ b/tstest/integration/testcontrol/testcontrol.go @@ -1075,9 +1075,7 @@ func sendUpdate(dst chan<- updateType, updateType updateType) bool { } } -func (s *Server) UpdateNode(n *tailcfg.Node) (peersToUpdate []tailcfg.NodeID) { - s.mu.Lock() - defer s.mu.Unlock() +func (s *Server) updateNodeLocked(n *tailcfg.Node) (peersToUpdate []tailcfg.NodeID) { if n.Key.IsZero() { panic("zero nodekey") } @@ -1085,6 +1083,15 @@ func (s *Server) UpdateNode(n *tailcfg.Node) (peersToUpdate []tailcfg.NodeID) { return s.nodeIDsLocked(n.ID) } +// UpdateNode updates or adds the input node, then triggers a netmap update for +// all attached streaming clients. +func (s *Server) UpdateNode(n *tailcfg.Node) { + s.mu.Lock() + defer s.mu.Unlock() + s.updateNodeLocked(n) + s.updateLocked("UpdateNode", s.nodeIDsLocked(0)) +} + func (s *Server) incrInServeMap(delta int) { s.mu.Lock() defer s.mu.Unlock() @@ -1143,7 +1150,9 @@ func (s *Server) serveMap(w http.ResponseWriter, r *http.Request, mkey key.Machi } } } - peersToUpdate = s.UpdateNode(node) + s.mu.Lock() + peersToUpdate = s.updateNodeLocked(node) + s.mu.Unlock() } nodeID := node.ID