Repository navigation
Conversation
Reserve an unused ACK ID under the registration lock in both clients. Extract matching ACKs without stale indices and release the registry lock before invoking callbacks. Add deterministic, network-free regression tests.
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.
Problem
Both clients choose an ACK ID using
thread_rng().gen_range(0..999)withoutchecking outstanding requests. Two pending requests can therefore share an ID.
In the asynchronous client,
handle_ackrecords matching vector indices andthen removes them in ascending order. Earlier removals invalidate later
indices: pending IDs
[7, 8, 7]produce indices[0, 2], and removing index 2after index 0 panics with
removal index (is 2) should be < len (is 2).The receive task stops, so subsequent events stop reaching the application.
The synchronous client on main already removes one matching entry safely and
calls its callback outside the mutex. It does not have that index-removal
panic, but collisions can still associate a reply with the wrong request and
leave another request with the same ID outstanding.
Change
occupied IDs and wrapping from i32::MAX to zero.
concurrent callers (including cloned clients) cannot reserve the same ID.
callbacks. Timeout checks and text/binary payload handling are preserved.
wraparound, removing duplicate ACKs, preserving unrelated requests, and
ignoring an already handled ID. Both clients call the tested registry
functions in production; no socket, process, network, or mock implementation
of the registry is involved.
This is scoped to outstanding ACK IDs. It does not change timeout cleanup,
reconnection, or failed-send cleanup, and makes no claim about late replies
after an ID has been retired.
Reproduction
The panic follows directly from
handle_ack(see Problem above); the addedregression tests cover it and pass with this change:
Validation
Following CONTRIBUTING.md and the Makefile's feature settings:
Results: 4/4 ACK regressions with all features, 2/2 synchronous regressions
without async, 7/7 engineio packet tests and 6/6 socketio packet tests. Build,
clippy and formatting passed. Clippy reports 76 engineio and 75 socketio
warnings on both clean upstream main and the patched tree; warnings were not
promoted to errors because the upstream Makefile does not do so.
The network integration suite (
make test-all, which starts Docker servers)was not run. Callback lock release was reviewed in the production code rather
than exercised with a connected client.