mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-27 10:01:28 +02:00
[client] pqkem: don't let the responder's delayed update revert the PSK
The responder configures WireGuard with endpoint=nil first, then a delayed update (scheduleDelayedUpdate) applies the real endpoint after fallbackDelay. It captured the preshared key at schedule time and re-applied it. With the post-quantum exchange the PSK can change within that window (a fresher PSK derived and applied via SetPresharedKey), so re-applying the captured one reverted WireGuard to a key the remote peer no longer used — a mismatch that stalled the handshake until the WGWatcher timeout forced a retry (~30s). Pass a nil PSK in the delayed update so it only sets the endpoint and leaves the current PSK in place; the latest SetPresharedKey wins.
This commit is contained in:
@@ -88,7 +88,7 @@ func (e *EndpointUpdater) configureAsResponder(addr *net.UDPAddr, presharedKey *
|
||||
var ctx context.Context
|
||||
ctx, e.cancelFunc = context.WithCancel(context.Background())
|
||||
e.updateWg.Add(1)
|
||||
go e.scheduleDelayedUpdate(ctx, addr, presharedKey)
|
||||
go e.scheduleDelayedUpdate(ctx, addr)
|
||||
|
||||
if err := e.updateWireGuardPeer(nil, presharedKey); err != nil {
|
||||
e.waitForCloseTheDelayedUpdate()
|
||||
@@ -107,8 +107,14 @@ func (e *EndpointUpdater) waitForCloseTheDelayedUpdate() {
|
||||
e.updateWg.Wait()
|
||||
}
|
||||
|
||||
// scheduleDelayedUpdate waits for the fallback period before updating the endpoint
|
||||
func (e *EndpointUpdater) scheduleDelayedUpdate(ctx context.Context, addr *net.UDPAddr, presharedKey *wgtypes.Key) {
|
||||
// scheduleDelayedUpdate waits for the fallback period, then sets the responder's real
|
||||
// endpoint. It deliberately passes a nil preshared key so it only updates the endpoint
|
||||
// and leaves the current PSK untouched: the PSK captured when this was scheduled may be
|
||||
// stale by now (e.g. the post-quantum bootstrap derived a fresher PSK within the
|
||||
// fallback window, applied via SetPresharedKey), and re-applying the captured one would
|
||||
// revert WireGuard to a key the remote peer no longer uses — a mismatch that stalls the
|
||||
// handshake until the next retry.
|
||||
func (e *EndpointUpdater) scheduleDelayedUpdate(ctx context.Context, addr *net.UDPAddr) {
|
||||
defer e.updateWg.Done()
|
||||
t := time.NewTimer(fallbackDelay)
|
||||
defer t.Stop()
|
||||
@@ -117,7 +123,7 @@ func (e *EndpointUpdater) scheduleDelayedUpdate(ctx context.Context, addr *net.U
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-t.C:
|
||||
if err := e.updateWireGuardPeer(addr, presharedKey); err != nil {
|
||||
if err := e.updateWireGuardPeer(addr, nil); err != nil {
|
||||
e.log.Errorf("failed to update WireGuard peer, address: %s, error: %v", addr, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user