feat(webrtc): track WebRTC-Direct STUN listener + v1/v2 (specs#715) after UdpMux
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 624
- Forks
- 256
- Avg merge
- 1d 34m
- Merged PRs (30d)
- 47
Description
Status (2026-09-14)
libp2p/specs#715 MERGED (2026-09-11, merge 78e75c6 by @johannamoran). WebRTC-Direct v2 is on specs master (webrtc-direct.md, r2 / Candidate Recommendation). Approvals: @lidel, @seetadev, @tabcat.
v1 STUN-dispatch listener + v1 dialer on main via #1449 (merge 1d0876da; stack #1446–#1448).
v2 flow + framing/SCTP fix on main via #1459 (merge 1ba536d3, 2026-09-03). Listener accepts libp2p+webrtc+v2/; dialer opt-in webrtc_direct_dial_version=2.
Default path: spec STUN on a shared UDP port. HTTP POST /sdp is opt-in (enable_sdp_http_harness=True) for py↔py experiments only.
Interop (#1471 + #1495): pinned go-libp2p v0.49 harness in CI. py ↔ go v1 and v2 both directions green. #1470 closed.
Docs (#1513, merged 82f23996, 2026-09-09): STUN vs /sdp harness; v1 vs v2 dial guidance. Closes #1511.
Dialer default still webrtc_direct_dial_version=1. Docs / config comments said to flip to v2 once specs#715 lands — that follow-up is now due (refresh "unmerged" wording too).
Still open on this issue: flip dialer default to v2; true ICE-Lite (#1512 / PR #1532 — open); optional UdpMux upstream; js-libp2p interop when #3480 is ready.
Summary
Tracking issue for a spec-aligned /webrtc-direct listener that demuxes concurrent inbound dials on one advertised UDP port via STUN, including WebRTC-Direct v1 and v2 version-prefix dispatch per libp2p/specs#715 (merged; v2 text live on specs master).
v1 (#1449), v2 (#1459), go interop (#1471 + #1495), and docs (#1513) are on main. ICE-Lite follow-up: #1532.
Built on the ICE-mux primitive (#1397 / spike #1352). Umbrella: #546. Earlier scaffolding (#1309) is superseded for node-to-node by the spec STUN path.
Background
WebRTC-Direct v1 and v2 are no-signaling transports. The listener reconstructs the dialer's offer from the inbound STUN connectivity check:
- Read
USERNAME=server_ufrag:client_ufrag - Dispatch on version prefix (
libp2p+webrtc+v1/vslibp2p+webrtc+v2/) - For v2: recover
client_pwdby strippinglibp2p+webrtc+v2/fromserver_ufrag, then set the server's own ICE ufrag/pwd toserver_ufragbefore answering (critical for ICE)
v2 exists because Chromium is removing SDP ICE-credential munging (libp2p/specs#672). Spec PR libp2p/specs#715 is merged (2026-09-11); Go reference support has landed (go-libp2p#3520); JS is in progress (js-libp2p#3480).
Internal note / roadmap: downloads/AI-PR-REVIEWS/1309/WebRTC_NewSpecs.md (local maintainer doc; refreshed 2026-09-14).
Prerequisites
- Spike: aiortc / aioice ICE mux + STUN USERNAME exposure — #1352
- In-tree
UdpMuxshared-port demux — #1397 - (Optional follow-up) Upstream
UdpMuxto aioice / pin tested aioice versions
Scope (checklist)
Listener (server) — primary
- Wire
UdpMuxintolistener.py(spec path default; HTTP/sdpharness opt-in — #1449) - First-contact path via
set_unknown_stun_handler: parseUSERNAME, validate both ufrag halves, reject malformed input - Version dispatch — v1 + v2 + reject path (#1459):
-
libp2p+webrtc+v1/→ v1 flow -
libp2p+webrtc+v2/→ v2 flow — #1459 - unknown / missing prefix → reject
-
- Infer dialer offer from STUN; go → py inbound completes (#1495; closes #1470)
- ICE Lite / DTLS roles per spec — partial on
main(#1512 / #1532):- DTLS server /
setup:passiveon listener answer - True ICE-Lite controlled agent (aioice has no native local lite mode; #1532 in review)
- DTLS server /
-
register_addrafter ICE nomination; rate-limit unknown-STUN handling
Dialer / SDP seam
- v1 dialer:
make_v1_credential+build_synthetic_answer - v2 dialer: opt-in via
webrtc_direct_dial_version=2— #1459 - Flip dialer default to v2 now that specs#715 is merged; refresh README / package docs that still say "while specs#715 is unmerged"
- Document that browser dial requires v2 once NoSdpMangleUfrag ships widely — #1513
Interop and docs
- Interop tests against go-libp2p (#1471 + #1495) — py ↔ go v1+v2; js-libp2p when ready still open
- Module / README distinguish experimental HTTP harness vs spec STUN listener (#1513)
- README/docs: v1 (migration) vs v2 (recommended) — #1513
- Track libp2p/specs#715 merge — done 2026-09-11; still need dialer-default flip + link refresh as above
Non-goals (for this issue)
- Full production WebRTC private-to-private (
/webrtcvia relay) polish — see #773 / umbrella #546 - Replacing aiortc entirely (Path B from #1352) unless mux/credential gaps force it
References
| Resource | Link |
|---|---|
| Spec (webrtc-direct v2) | libp2p/specs#715 — merged 2026-09-11 (78e75c6); live on master |
| Merged stack (v1 listener + dialer) | #1449 (+ #1446–#1448) |
| v2 flow (merged) | #1459 — merged 2026-09-03 |
| go-libp2p interop + inbound fix | #1471, #1495 (closes #1470) |
| Docs (STUN vs harness, v1/v2) | #1513 — merged 2026-09-09 (closes #1511) |
| True ICE-Lite | #1512 / #1532 — open |
| Chrome munging issue | libp2p/specs#672 |
| Umbrella | #546 |
| Scaffolding | #1309 |
| UdpMux PR | #1397 |
| Go v2 | libp2p/go-libp2p#3520 — merged |
| JS v2 | libp2p/js-libp2p#3480 — open |
Suggested sequencing
- Merge #1397 (
UdpMux). - STUN-dispatch listener v1 + v1 dialer — #1449.
- v2 listener/dialer — #1459.
- Go interop + go → py inbound — #1471, #1495.
- Docs — #1513.
- specs#715 merge — 2026-09-11.
- Flip dialer default to v2 + refresh stale "unmerged" docs.
- True ICE-Lite (#1532); js interop when ready; then claim browser-dial support.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the WebRTC-Direct dialer configuration and the README/package documentation mentioned in the issue; confirm where webrtc_direct_dial_version defaults to v1 and where the stale specs#715 wording remains. Update the default and documentation, then run the existing WebRTC-Direct interoperability tests to verify v2 behavior. True ICE-Lite and JavaScript interop are separate follow-ups already in progress.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- audio-video-rtc, networking
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100