diff --git a/management/server/peer.go b/management/server/peer.go index bb3ac5ff6..208bd944b 100644 --- a/management/server/peer.go +++ b/management/server/peer.go @@ -1066,12 +1066,18 @@ func (am *DefaultAccountManager) SyncPeer(ctx context.Context, sync types.PeerSy metaDiffAffectsPosture := posture.AffectsPosture(ctx, &metaDiff, resPostureChecks) if requiresPeerUpdate(ctx, isStatusChanged, sync.UpdateAccountPeers, ipv6CapabilityChanged, metaDiffAffectsPosture, metaDiff.VersionChanged(), metaDiff.HostnameChanged()) { - // The maps pushed below carry changed content (the peer's version, + // The maps sent out below carry changed content (the peer's version, // hostname, capabilities, or validation state). The serial versions the // distributed map, so it must advance with the content. if err = am.Store.IncrementNetworkSerial(ctx, accountID); err != nil { return nil, nil, nil, 0, fmt.Errorf("increment network serial: %w", err) } + // The map built above predates the increment; rebuild it so the syncing + // peer's own response also carries the advanced serial. + nmap, resPostureChecks, dnsFwdPort, err = am.networkMapController.GetValidatedPeerWithMap(ctx, peerNotValid, accountID, peer.ID) + if err != nil { + return nil, nil, nil, 0, err + } changedPeerIDs := []string{peer.ID} affectedPeerIDs := am.syncPeerAffectedPeers(ctx, accountID, peer.ID, nmap, peerNotValid, metaDiffAffectsPosture) if err = am.networkMapController.OnPeersUpdated(ctx, accountID, changedPeerIDs, affectedPeerIDs); err != nil { @@ -1236,17 +1242,22 @@ func (am *DefaultAccountManager) LoginPeer(ctx context.Context, login types.Peer return nil, nil, nil, false, err } + if shouldUpdatePeers { + // The maps sent out below carry changed peer content. The serial versions + // the distributed map, so it must advance with the content, and before the + // network is loaded for the response so the logging-in peer also sees the + // advanced serial. + if err = am.Store.IncrementNetworkSerial(ctx, accountID); err != nil { + return nil, nil, nil, false, fmt.Errorf("increment network serial: %w", err) + } + } + network, postureChecks, enableSSH, err := getPeerLoginInfo(ctx, am.Store, accountID, peer, !isRequiresApproval) if err != nil { return nil, nil, nil, false, err } if shouldUpdatePeers { - // The maps pushed below carry changed peer content. The serial versions - // the distributed map, so it must advance with the content. - if err = am.Store.IncrementNetworkSerial(ctx, accountID); err != nil { - return nil, nil, nil, false, fmt.Errorf("increment network serial: %w", err) - } changedPeerIDs := []string{peer.ID} affectedPeerIDs := am.resolveAffectedPeersForPeerChanges(ctx, am.Store, accountID, changedPeerIDs) if err = am.networkMapController.OnPeersUpdated(ctx, accountID, changedPeerIDs, affectedPeerIDs); err != nil { diff --git a/management/server/peer_test.go b/management/server/peer_test.go index 1b79449f8..695b7bd0f 100644 --- a/management/server/peer_test.go +++ b/management/server/peer_test.go @@ -2856,7 +2856,7 @@ func TestSyncPeer_PeerUpdateBumpsNetworkSerial(t *testing.T) { newMeta := peer2.Meta newMeta.WtVersion = "0.99.99" - _, _, _, _, err := manager.SyncPeer(context.Background(), types.PeerSync{ + _, nmap, _, _, err := manager.SyncPeer(context.Background(), types.PeerSync{ WireGuardPubKey: peer2.Key, Meta: newMeta, }, peer2.AccountID) @@ -2865,6 +2865,8 @@ func TestSyncPeer_PeerUpdateBumpsNetworkSerial(t *testing.T) { network, err := manager.Store.GetAccountNetwork(context.Background(), store.LockingStrengthNone, account.Id) require.NoError(t, err) assert.Greater(t, network.CurrentSerial(), serialBefore, "a map-relevant meta change should advance the serial") + require.NotNil(t, nmap) + assert.Equal(t, network.CurrentSerial(), nmap.Network.CurrentSerial(), "the syncing peer's own map should carry the advanced serial") }) }