Repository navigation
Conversation
Collaborator
|
isn't this a dup of #201 but with way more code changes? |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
A failed explicit UDP rebind leaves the socket closed without setting
is_brokenor waking idle I/O. Subsequent I/O cannot recover. Simply setting the flag still exposes rebind errors to async receive callers, which can permanently stop a QUIC endpoint driver before the address becomes usable again.Keep recovery in netwatch: mark failed rebinds broken, wake pending I/O, and retry with backoff from 100 ms to a 5 s cap. Async I/O remains pending; nonblocking sends return
WouldBlockduring recovery. A socket-owned timer wakes both send and receive waiters, with no spawned retry task. Explicitclose()cancels recovery and leaves the socket closed. An explicit rebind bypasses the delay so a new network change can trigger an immediate attempt.All poll-based I/O uses the same recovery path.
UdpSender::poll_sendacquires its socket read guard after polling writable readiness, so a rebind never attempts a write lock while that guard is held.Related: #200, #201, and n0-computer/iroh#4558. This follows the request on the iroh PR to put recovery and regression tests in the UDP wrapper. It addresses both the retry-state defect and the concern about unbounded rebind frequency.
API Changes
No new public API. During failed-rebind recovery, async I/O waits and nonblocking sends return
WouldBlock. Explicitrebind()still returns the original bind error.close()cancels automatic recovery.Validation
cargo test --locked -p netwatch --lib: 21 passed on macOS.cargo clippy -p netwatch --all-targetscompletes with the existingunused_asyncwarning ininterfaces/bsd.rs:40;-D warningsfails on that unchanged warning.Reproducible iroh integration tests (iroh 1.1.0, no iroh-side production changes): validation branch. Run
cargo test --locked -p iroh --lib failed_rebind; all three pass with the netwatch backport pinned in that branch.Notes & open questions
Retries continue at the capped interval until recovery or explicit close. Prepared with Codex at the author's request; human review remains pending. This PR does not establish the trigger of any historical production outage.
Change checklist
cargo makepasses locally (targeted checks above).