diff --git a/control/controlclient/map.go b/control/controlclient/map.go index 4c58ae8af..c8cbdbce5 100644 --- a/control/controlclient/map.go +++ b/control/controlclient/map.go @@ -408,10 +408,9 @@ type updateStats struct { // removeUnwantedDiscoUpdates goes over the patchified updates and reject items // where the node is offline and has last been seen before the recorded last seen. func (ms *mapSession) removeUnwantedDiscoUpdates(resp *tailcfg.MapResponse) { - existingMap := ms.netmap() - if existingMap == nil { - return - } + ms.peersMu.RLock() + defer ms.peersMu.RUnlock() + acceptedDiscoUpdates := resp.PeersChangedPatch[:0] for _, change := range resp.PeersChangedPatch { @@ -430,14 +429,13 @@ func (ms *mapSession) removeUnwantedDiscoUpdates(resp *tailcfg.MapResponse) { continue } - peerIdx := existingMap.PeerIndexByNodeID(change.NodeID) + existingNode, ok := ms.peers[change.NodeID] // Accept if: // - Cannot find the peer, don't have enough data - if peerIdx < 0 { + if !ok { acceptedDiscoUpdates = append(acceptedDiscoUpdates, change) continue } - existingNode := existingMap.Peers[peerIdx] // Accept if: // - lastSeen moved forward in time. @@ -456,13 +454,12 @@ func (ms *mapSession) removeUnwantedDiscoUpdates(resp *tailcfg.MapResponse) { // local netmap has a newer key learned via TSMP, overwrite the update with the // key from TSMP. func (ms *mapSession) removeUnwantedDiscoUpdatesFromFullNetmapUpdate(resp *tailcfg.MapResponse) { + ms.peersMu.RLock() + defer ms.peersMu.RUnlock() + if len(resp.Peers) == 0 { return } - existingMap := ms.netmap() - if existingMap == nil { - return - } for _, peer := range resp.Peers { if peer.DiscoKey.IsZero() { continue @@ -470,14 +467,13 @@ func (ms *mapSession) removeUnwantedDiscoUpdatesFromFullNetmapUpdate(resp *tailc // Accept if: // - peer is new - peerIdx := existingMap.PeerIndexByNodeID(peer.ID) - if peerIdx < 0 { + existingNode, ok := ms.peers[peer.ID] + if !ok { continue } // Accept if: // - disco key has not changed - existingNode := existingMap.Peers[peerIdx] if existingNode.DiscoKey() == peer.DiscoKey { continue } diff --git a/control/controlclient/map_test.go b/control/controlclient/map_test.go index 5eee931f3..f057345d9 100644 --- a/control/controlclient/map_test.go +++ b/control/controlclient/map_test.go @@ -696,13 +696,12 @@ func TestUpdateDiscoForNode(t *testing.T) { ms.updateDiscoForNode(node.ID, node.Key, newKey.Public(), tt.updateLastSeen, tt.updateOnline) <-nu.done - nm := ms.netmap() - peerIdx := nm.PeerIndexByNodeID(node.ID) - if peerIdx == -1 { + peer, ok := ms.peers[node.ID] + if !ok { t.Fatal("node not found") } - updated := nm.Peers[peerIdx].DiscoKey().Compare(newKey.Public()) == 0 + updated := peer.DiscoKey().Compare(newKey.Public()) == 0 if updated != tt.wantUpdate { t.Fatalf("Disco key update: %t, wanted update: %t", updated, tt.wantUpdate) }