mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-27 23:09:08 +01: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
|
var ctx context.Context
|
||||||
ctx, e.cancelFunc = context.WithCancel(context.Background())
|
ctx, e.cancelFunc = context.WithCancel(context.Background())
|
||||||
e.updateWg.Add(1)
|
e.updateWg.Add(1)
|
||||||
go e.scheduleDelayedUpdate(ctx, addr, presharedKey)
|
go e.scheduleDelayedUpdate(ctx, addr)
|
||||||
|
|
||||||
if err := e.updateWireGuardPeer(nil, presharedKey); err != nil {
|
if err := e.updateWireGuardPeer(nil, presharedKey); err != nil {
|
||||||
e.waitForCloseTheDelayedUpdate()
|
e.waitForCloseTheDelayedUpdate()
|
||||||
@@ -107,8 +107,14 @@ func (e *EndpointUpdater) waitForCloseTheDelayedUpdate() {
|
|||||||
e.updateWg.Wait()
|
e.updateWg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// scheduleDelayedUpdate waits for the fallback period before updating the endpoint
|
// scheduleDelayedUpdate waits for the fallback period, then sets the responder's real
|
||||||
func (e *EndpointUpdater) scheduleDelayedUpdate(ctx context.Context, addr *net.UDPAddr, presharedKey *wgtypes.Key) {
|
// 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()
|
defer e.updateWg.Done()
|
||||||
t := time.NewTimer(fallbackDelay)
|
t := time.NewTimer(fallbackDelay)
|
||||||
defer t.Stop()
|
defer t.Stop()
|
||||||
@@ -117,7 +123,7 @@ func (e *EndpointUpdater) scheduleDelayedUpdate(ctx context.Context, addr *net.U
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case <-t.C:
|
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)
|
e.log.Errorf("failed to update WireGuard peer, address: %s, error: %v", addr, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user