lx: early rebind and wake nudge for provably dead sessions (sing-box-lx SPEC 041 v2)

The v1 give-up rebind heals a dead 5-tuple only at ~90s, while users probe
within the first seconds after device wake. Two new triggers over the same
action and shared debounce window:

- early: >=3 unanswered initiations against a provably dead session (no live
  keypair, or last handshake older than RejectAfterTime) rebind at ~15s from
  the retry branch; a live session keeps byte-for-byte upstream behaviour;
- nudge: public Device.RebindIfSessionStale() lets the consumer report a
  device wake-up and heal stale peers immediately, without traffic demand.

The whole mechanism now lives in device/lx_giveup_rebind.go (moved from
device.go to keep the upstream file delta minimal); the rebind log line
carries the trigger label.
This commit is contained in:
Leadaxe 2026-08-02 01:40:01 +03:00
parent c4e0bcf768
commit 3909adbf87
5 changed files with 444 additions and 60 deletions

View file

@ -111,6 +111,13 @@ func expiredRetransmitHandshake(peer *Peer) {
peer.timers.handshakeAttempts.Add(1)
peer.device.log.Verbosef("%s - Handshake did not complete after %d seconds, retrying (try %d)", peer, int(RekeyTimeout.Seconds()), peer.timers.handshakeAttempts.Load()+1)
/* lx: SPEC 041 v2 early self-heal: >=3 unanswered initiations against
* a provably dead session (no live keypair, or last handshake older
* than RejectAfterTime) prove the 5-tuple dead without waiting out the
* full cycle. Rebind now (debounced with the give-up trigger below);
* the retry cycle itself continues untouched. */
peer.device.maybeEarlyGiveUpRebind(peer)
/* We clear the endpoint address src address, in case this is the cause of trouble. */
peer.markEndpointSrcForClearing()