mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-02 11:39:06 +02:00
[client] Create the WireGuard peer before the peer becomes routable
Split peer setup into a prepare and a start phase. AddPeerConn now only registers the conn in the peer store and, in lazy mode, arms the wake endpoint (creating the WireGuard peer) without starting any event source. The peer is then registered in the status recorder, and StartPeerConn starts the activity listener, opens the connection or applies HA activation afterwards. This closes the cold-start race where the route watcher, reacting to the freshly registered idle peer, pushed routed allowed IPs before the WireGuard peer existed: the update_only add was silently dropped while the allowed-IP refcounter recorded the prefix as installed, so nothing retried and traffic to the routed subnet stayed black-holed until the peer was woken by other means. Packets arriving on the armed wake endpoint before the listener starts queue in the socket buffer, and no status write can land before the recorder entry exists because no event source runs in between.
This commit is contained in:
@@ -1771,16 +1771,20 @@ func (e *Engine) addNewPeer(peerConfig *mgmProto.RemotePeerConfig) error {
|
||||
return fmt.Errorf("create peer connection: %w", err)
|
||||
}
|
||||
|
||||
// Order matters: the WireGuard peer must exist before the peer becomes visible in the
|
||||
// status recorder, and event sources may start only after the recorder registration.
|
||||
if exists := e.connMgr.AddPeerConn(peerKey, conn); exists {
|
||||
conn.Close()
|
||||
return fmt.Errorf("peer already exists: %s", peerKey)
|
||||
}
|
||||
|
||||
peerV4, peerV6 := overlayAddrsFromAllowedIPs(peerConfig.GetAllowedIps(), e.wgInterface.Address().IPv6Net)
|
||||
err = e.statusRecorder.AddPeer(peerKey, peerConfig.Fqdn, addrToString(peerV4), addrToString(peerV6))
|
||||
if err != nil {
|
||||
log.Warnf("error adding peer %s to status recorder, got error: %v", peerKey, err)
|
||||
}
|
||||
|
||||
if exists := e.connMgr.AddPeerConn(e.ctx, peerKey, conn); exists {
|
||||
conn.Close()
|
||||
return fmt.Errorf("peer already exists: %s", peerKey)
|
||||
}
|
||||
e.connMgr.StartPeerConn(e.ctx, peerKey)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user