You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix a lifetime and re-entrancy bug in the WebRTC WebSys data-channel callbacks.
PollDataChannel previously allowed a queued browser event to invoke a wasm-bindgen closure after its Rust owner had been dropped. Waking the task synchronously from the callback could also re-enter polling while wasm-bindgen still held a mutable borrow of that closure. Either path could panic with closure invoked recursively or after being dropped.
Keep the RTCDataChannel and its registered closures in a shared owner, remove the handlers before the final owner is released, and defer waker notifications until after the JavaScript callback returns.
Browser-to-browser WebRTC relay transfer testing: the wasm-bindgen callback exception no longer occurs and file transfer completes.
The 8 KiB framing behavior encountered during the same investigation is intentionally out of scope and is tracked in #6557.
No standalone automated regression test was added because reproducing the stale browser-event timing requires an actual browser WebRTC runtime. No user-facing documentation change is needed. I have not added a changelog entry for this internal correctness fix; happy to add one if maintainers prefer it.
Change checklist
I have performed a self-review of my own code
I have made corresponding changes to the documentation
I have added tests that prove my fix is effective or that my feature works
A changelog entry has been made in the appropriate crates
For validation, besides the wasm check, I reproduced the failure and verified this fix with a browser-to-browser WebRTC relay transfer in SwarmDrop (which embeds libp2p-webrtc-websys). The prior closure invoked recursively or after being dropped exception no longer occurs and the transfer completes. For a reviewer who wants to reproduce the integration flow manually, the public test page is: https://swarm-apps.github.io/SwarmDrop/try/
I also looked at adding an upstream regression test. The existing interop-tests WebRTC Direct path provides a browser-to-native ping harness, but this bug depends on a queued RTCDataChannel event arriving after the final Rust stream owner has been dropped; I have not found a deterministic way to force that browser scheduling boundary in the current harness. I would be happy to extend the preferred browser test setup if you have a recommendation, or add a focused test seam if you would prefer that over the end-to-end validation record.
yexiyue
added a commit
to yexiyue/rust-libp2p
that referenced
this pull request
Jul 25, 2026
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
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
Fix a lifetime and re-entrancy bug in the WebRTC WebSys data-channel callbacks.
PollDataChannelpreviously allowed a queued browser event to invoke a wasm-bindgen closure after its Rust owner had been dropped. Waking the task synchronously from the callback could also re-enter polling while wasm-bindgen still held a mutable borrow of that closure. Either path could panic withclosure invoked recursively or after being dropped.Keep the
RTCDataChanneland its registered closures in a shared owner, remove the handlers before the final owner is released, and defer waker notifications until after the JavaScript callback returns.Fixes #6551.
AI Assistance Disclosure
Tools used (required — write
noneif no AI was used): Codex (GPT-5)Attestation (required):
Notes & open questions
Validation performed:
cargo fmt --check -p libp2p-webrtc-websyscargo check -p libp2p-webrtc-websys --target wasm32-unknown-unknownThe 8 KiB framing behavior encountered during the same investigation is intentionally out of scope and is tracked in #6557.
No standalone automated regression test was added because reproducing the stale browser-event timing requires an actual browser WebRTC runtime. No user-facing documentation change is needed. I have not added a changelog entry for this internal correctness fix; happy to add one if maintainers prefer it.
Change checklist