Skip to content

daemon: path watchdog resets on rekey-giveup — faster T2 desync recovery#415

Merged
TeoSlayer merged 1 commit into
mainfrom
fix/pathwatch-rekey-giveup-fast-reset
Jul 22, 2026
Merged

daemon: path watchdog resets on rekey-giveup — faster T2 desync recovery#415
TeoSlayer merged 1 commit into
mainfrom
fix/pathwatch-rekey-giveup-fast-reset

Conversation

@TeoSlayer

Copy link
Copy Markdown
Collaborator

The 2026-07-20 director probe's worst finding (T2): after a session-key desync, replies arrive undecryptable and are silently dropped ('no reply'), and plain rekey-retransmit can't recover (resends to a stale endpoint). The path watchdog's resetPeerPath can (fresh resolve + punch) but only fired after ~85s of inbound silence. This wires the unambiguous rekey-gave-up signal as a fast reset trigger — recovery drops from ~85s to one ~10s tick, with the reset cooldown preventing storms. Directly targets the intermittent no-reply that makes MOM/agents feel like 'Pilot stopped working'. 🤖 Generated with Claude Code

… T2 recovery)

The 2026-07-20 director probe (T2) documented the worst reliability
failure: after a session-key desync, peers exchange 'encrypted packet
but no key' + 'rekey retransmit gave up after maxRekeyAttempts' in a
loop, and specialist replies arrive undecryptable and are dropped —
nothing surfaces to the caller (a silent 'no reply'). Plain
rekey-retransmit can't recover it: it resends the key exchange to the
same stale cached endpoint. The per-peer path watchdog CAN (resetPeerPath
re-resolves a fresh endpoint + re-punches), but only fired after the ~85s
inbound-silence probe budget.

Wire the rekey-gave-up state (keyexchange.PeerInRekeyGaveUp) as a fast
reset trigger in pathWatchPeer: a gave-up peer is an unambiguous dead
session, so reset it on the current ~10s tick instead of waiting out the
probe budget. Still honours the post-reset cooldown so a genuinely
offline peer can't cause a reset storm. Cuts T2 recovery from ~85s to
one tick.

Test: TestPathWatchRekeyGaveUpResetsImmediately (resets on gave-up before
the probe budget; cooldown suppresses a second reset). pkg/daemon +
keyexchange green under -race.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@TeoSlayer
TeoSlayer merged commit c57923e into main Jul 22, 2026
14 checks passed
TeoSlayer added a commit that referenced this pull request Jul 22, 2026
…fied live) (#416)

#415 tried to recover the T2 desync by polling the rekey-gave-up state
from the path watchdog. A LIVE test (2026-07-22) proved it never fired:
a desynced peer has no usable key, so it is not Ready, so ReadyPeerIDs()
— the set the watchdog scans — excludes it entirely. 0 firings across
dozens of real give-ups. (The unit test passed only because it injected
a Ready peer + gave-up state, a combination that can't occur.)

Correct fix: event-driven. Add an onGaveUp hook fired from the keyexchange
retransmit loop at the exact give-up site, wired through the tunnel to a
daemon handler (onRekeyGaveUp) that runs resetPeerPath — the only thing
that recovers a desync, because it re-resolves a FRESH endpoint and
re-punches (plain rekey-retransmit just resends to the same stale cached
endpoint forever). Per-peer 30s cooldown prevents a persistently-offline
peer from storming resolves; reset runs async (registry I/O) off the
rekey loop goroutine.

Reverts #415's ineffective path-watchdog poll. Verified LIVE on a real
NAT'd laptop: give-up -> full path reset (fresh resolve + punch + PILA)
in ~1.2s, reproduced across peers 17461 and 16392, vs the prior
indefinite silent-drop. This is the 'no reply on whatever' fix.

Tests: TestOnRekeyGaveUpResetsWithCooldown (hook resets + cooldown
suppresses a second give-up). pkg/daemon + keyexchange green under -race.

Co-authored-by: Teodor Calin <teodor@vulturelabs.io>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants