control/controlclient: handle errors in rememberLastNetmapUpdator (#19112)

If errors occured, the updater could end up deadlocked.

Closing the done channel rather than adding to it, fixes a deadlock in
the corp tests.

Updates #19111

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit is contained in:
Claus Lensbøl
2026-03-24 20:36:34 -04:00
committed by GitHub
parent bb59942df2
commit 9a4a2db0fc
2 changed files with 11 additions and 5 deletions

View File

@@ -865,15 +865,21 @@ type rememberLastNetmapUpdater struct {
func (nu *rememberLastNetmapUpdater) UpdateFullNetmap(nm *netmap.NetworkMap) {
nu.last = nm
nu.done <- nil
select {
case nu.done <- nil:
default:
}
}
// FetchNetMapForTest fetches the netmap once.
func (c *Direct) FetchNetMapForTest(ctx context.Context) (*netmap.NetworkMap, error) {
var nu rememberLastNetmapUpdater
nu.done = make(chan any)
nu.done = make(chan any, 1)
err := c.sendMapRequest(ctx, false, &nu)
if err == nil && nu.last == nil {
if err != nil {
return nil, err
}
if nu.last == nil {
return nil, errors.New("[unexpected] sendMapRequest success without callback")
}
<-nu.done
@@ -1290,7 +1296,7 @@ func NetmapFromMapResponseForDebug(ctx context.Context, pr persist.PersistView,
return nil, errors.New("PersistView invalid")
}
nu := &rememberLastNetmapUpdater{done: make(chan any)}
nu := &rememberLastNetmapUpdater{done: make(chan any, 1)}
sess := newMapSession(pr.PrivateNodeKey(), nu, nil)
defer sess.Close()

View File

@@ -669,7 +669,7 @@ func TestUpdateDiscoForNode(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
nu := &rememberLastNetmapUpdater{
done: make(chan any),
done: make(chan any, 1),
}
ms := newTestMapSession(t, nu)