Skip to content

feat(moq-webrtc)!: remove peer-to-peer and the relay's STUN responder - #8771

Merged
kixelated merged 6 commits into
mainfrom
remove-p2p
Nov 15, 2026
Merged

kixelated merged 6 commits into
mainfrom
remove-p2p

Conversation

@kixelated

@kixelated kixelated commented Nov 14, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

moq-dev/moq keeps what a large live-media platform uses. Peer-to-peer
routing, with browsers and native nodes forwarding for each other, moves
to a downstream product that re-plans it there (maintainer decision
2026-11-14). Git history keeps the code for a later port.

Removed:

  • moq-webrtc's p2p module and feature (MoQ over a data channel, host
    candidates per interface, mDNS .local resolution) and the ICE agent's
    STUN Binding client and trickle events, which only it used.
  • The vendored sctp-proto and str0m's data channels (about 25k lines),
    which only the data-channel transport used. WHIP/WHEP keep str0m, dimpl,
    and the is ICE agent.
  • The private @moq/p2p package, test/p2p, its interop CI step, and
    its nightly bench.
  • moq-relay's public STUN responder: the stun feature, the [stun]
    config, --stun-bind / MOQ_STUN_BIND, the moq_relay::stun module,
    and its moq_relay_stun_* metrics.
  • The stun-types dependency, and if-addrs from the workspace. mdns-sd
    stays for LAN cluster discovery.
  • The P2P, browser mesh, and WHIP-without-SCTP quests.

Impact

Public API: moq-webrtc loses the p2p feature and module; moq-relay
loses the stun feature, its config section, flag, env var, module, and
metrics. None of it was ever released: origin/release ships moq-rtc
with no data-channel transport and moq-relay 0.17.16 with no STUN
responder, so no MIGRATE.md entries are needed.

Migration: a relay config with [stun], --stun-bind, or
MOQ_STUN_BIND must drop it, and an application that listed the relay
as a STUN server points ICE at a dedicated STUN server instead. Users of
moq_webrtc::p2p or @moq/p2p stay on an earlier commit or port the
code from history.

Wire: a WHIP or WHEP offer's m=application (data channel) section is
now answered rejected (port 0, left out of BUNDLE) instead of accepted
with an SCTP association nobody read. Audio and video negotiate as
before. moq-lite and moq-transport are unchanged.

Decisions

Taken while the maintainer was away, for review:

  • moq-tokio's Client::connect_with, Listener::accept_with, and the qmux established-elsewhere path, built for P2P, stay: they are the hook Kixel's port would use, and removing them breaks moq-tokio (rejected: deleting them now).
  • The vendored SCTP goes too, since WHIP/WHEP never used data channels (rejected: keeping it behind a feature, the old webrtc-sctp-feature quest).

Validation

  • just check in the dev shell passes after merging main (Rust lint and tests, JS, gh, quest, nix).
  • moq-webrtc: 1,268 tests pass, including the WHIP/WHEP Opus round trip and a new test that a data-channel offer is answered rejected while its audio is accepted.
  • Review found that an offer with its data channel first left every ICE candidate on the rejected line; candidates now go on the first accepted BUNDLE line, and candidates_skip_a_rejected_first_line covers it (it fails without the fix).
  • The real moq-relay binary refuses --stun-bind with a usage error and a [stun] config with "unknown field stun".
  • quest check: 484 documents ok.

Follow-ups

None. The P2P quests now live in kixel.ai's quest/m3/p2p/ (kixel-ai/kixel.ai#98). Expect a small conflict with moq-dev/moq#8756, which deletes quest/m3/mesh/ and quest/m5/mesh-ice.md that this edits.

Models

Size: L
Implementer: Claude Code, claude-opus-5-5, unknown effort

🤖 Generated with Claude Code

(Written by Opus 5.5)

Review

Rewritten by quest review after each round.

  • Head: a2b9216

  • Base: origin/main at 2f328ef

  • Risk: high, it changes .github/workflows/interop.yml, which is always high, as are 1 more of its paths: workflows run with the repository's secrets and decide what merges and ships

  • Classified: high by the always-high paths

  • Reviewer: Codex, gpt-6.1-sol, xhigh effort

  • Session: 01a1dbcf-f22d-7393-9760-0d1d2cc98f16, round 4

  • Score: 10/10, The update only merges main, and the merge resolutions preserve the reviewed removals while retaining upstream additions without new issues found by code inspection.

  • Rounds: 4; first round 1 (medium 1); findings 1 (medium 1): fixed 1, refuted 0, open 0

  • Findings: none

kixelated and others added 2 commits November 14, 2026 12:29
moq-dev/moq keeps what a large live-media platform uses. Peer-to-peer
routing, with browsers and native nodes forwarding for each other, moves
to a downstream product that re-plans it there (maintainer decision
2026-11-14). Git history keeps the code for a later port.

Removed:
- moq-webrtc's `p2p` module and feature (MoQ over a data channel, host
  candidates per interface, mDNS `.local` resolution) and the ICE agent's
  STUN Binding client and trickle events, which only it used.
- The vendored sctp-proto and str0m's data channels (about 25k lines),
  which only the data-channel transport used. WHIP/WHEP keep str0m, dimpl,
  and the `is` ICE agent.
- The private `@moq/p2p` package, `test/p2p`, its interop CI step, and
  its nightly bench.
- moq-relay's public STUN responder: the `stun` feature, the `[stun]`
  config, `--stun-bind` / `MOQ_STUN_BIND`, the `moq_relay::stun` module,
  and its `moq_relay_stun_*` metrics.
- The stun-types dependency, and if-addrs from the workspace. mdns-sd
  stays for LAN cluster discovery.
- The P2P, browser mesh, and WHIP-without-SCTP quests.

Public API: moq-webrtc loses the `p2p` feature and module; moq-relay
loses the `stun` feature, its config section, flag, env var, module, and
metrics. None of it was ever released: `origin/release` ships moq-rtc
with no data-channel transport and moq-relay 0.17.16 with no STUN
responder, so no MIGRATE.md entries are needed.

Migration: a relay config with `[stun]`, `--stun-bind`, or
`MOQ_STUN_BIND` must drop it, and an application that listed the relay
as a STUN server points ICE at a dedicated STUN server instead. Users of
`moq_webrtc::p2p` or `@moq/p2p` stay on an earlier commit or port the
code from history.

Wire: a WHIP or WHEP offer's `m=application` (data channel) section is
now answered rejected (port 0, left out of BUNDLE) instead of accepted
with an SCTP association nobody read. Audio and video negotiate as
before. moq-lite and moq-transport are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Rejecting m=application moves the WHIP/WHEP answer's ICE candidates onto a rejected line whenever the offer lists its data channel first. Details inline.

Reviewed changes

I read every non-vendored change line by line and skimmed the deleted vendored and test code for anything that crossed into the kept paths.

  • moq-webrtc p2p and SCTP removed. The p2p module and feature, vendored sctp_proto, and str0m's channel/sctp modules are gone. str0m's SdpApi loses add_channel* and SNAP, and poll_output stops looping for SCTP.
  • The ICE agent drops its STUN client. Agent::next now returns str0m::Event directly. Phase::Held and the gathering hold are gone, so the deadline starts at started.
  • Offered data channels are answered rejected. The app m-line is emitted as disabled: true (port 0) and left out of BUNDLE. A new test covers an offer whose data channel comes after its audio.
  • moq-relay's STUN responder removed. The stun feature, [stun], --stun-bind, and moq_relay_stun_* metrics are gone. MOQ_STUN_BIND now falls under the existing rule that refuses unknown MOQ_* variables at startup.
  • JS, CI, and docs cleanup. @moq/p2p, test/p2p, the interop step, the nightly benches, the select.sh feature, the OSS-scanner build, and the threat model are updated. A grep outside quest/ finds no stale references. origin/release ships no moq-tokio or moq-cli webrtc feature, so dropping that upgrade.md note is safe.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using claude-opus-5-5 | 𝕏

kixelated and others added 3 commits November 14, 2026 13:00
An offer that puts its data channel first had every candidate on the
rejected line, which is out of the BUNDLE group.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	rs/moq-relay/src/settings.rs
pullfrog[bot]
pullfrog Bot previously approved these changes Nov 14, 2026

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found. The fix for the earlier candidate-placement finding is correct.

Reviewed changes

This pass covers the two commits pushed since the last Pullfrog review at c947a7d.

  • Moved answer candidates to the first accepted m-line. as_sdp now builds every line with media_attributes(false). After pending.apply_to (which can flip disabled), it splices the Candidate attributes onto the first non-disabled line, at the same position in the attribute list as before, and falls back to index 0 when no line is accepted. This also covers a rejected audio or video line at index 0.
  • Added candidates_skip_a_rejected_first_line. The test sends an offer whose m=application comes first. It checks that the rejected line carries no candidate and the accepted audio line does.
  • Applied rustfmt. Whitespace changes only.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

pullfrog[bot]
pullfrog Bot previously approved these changes Nov 14, 2026

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found. The only change since the last review is a merge of main, and it resolves cleanly.

Reviewed changes

This pass covers the merge pushed since the last Pullfrog review at cb327ea.

  • Merged main into the branch. On main, #8747 deleted rs/moq-relay/src/settings.rs, and the settings registry now comes from Config through config::registry(). The PR's deletion of the Stun settings struct therefore drops out of the diff. Removing Config::stun alone is enough to remove [stun], --stun-bind, and MOQ_STUN_BIND. A grep outside quest/ finds no remaining feature = "stun", MOQ_STUN, stun-bind, or p2p references. Discard::Stun in internal.rs is the uring demux drop counter. It is unrelated to this PR and stays.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@kixelated
kixelated added this pull request to the merge queue Nov 14, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Nov 14, 2026
@moq-bot

moq-bot Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

quest land watch: the merge queue removed this pull request at e9f4ca1 because it conflicts with main (merge_conflict).

The land fixer works on it in the background, and the watcher re-enqueues it at the back of the queue once it is fixed or judged flaky, or hands it back here with what it needs.

(written by quest land watch)

@moq-bot

moq-bot Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

codex, gpt-6.1-sol, medium effort land fixer note:

The failure log reports:

Line 5: CONFLICT (content): Merge conflict in bun.lock
Line 9: Automatic merge failed; fix conflicts and then commit the result.

Merged base and rebuilt bun.lock from base using nix develop --no-write-lock-file --command bun install. The resulting lockfile preserves base’s OBS workspace and removes only the two P2P workspaces removed by this PR. Repair commit: 70aa93e0798a60210b0394354cd0ff3173848f72 on pr-8771.

Ran nix develop --no-write-lock-file --command just ci base. All other selected checks passed, including Rust lint/build, all 13,736 Rust tests, JavaScript build/type checks and tests, audio replays, generated Cargo/Nix consistency, formatters, and workflow tooling tests. The gate failed because: ci: flake's NixOS VM tests need KVM, but /dev/kvm is missing; run them on a KVM host, as CI does. Rerun the complete gate on a KVM host to validate the repair.

(written by codex, gpt-6.1-sol, medium effort)

@moq-bot

moq-bot Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

codex, gpt-6.1-sol, medium effort land fixer: Merged base and rebuilt bun.lock mechanically, but &#96;nix develop --no-write-lock-file --command just ci base&#96; failed: ci: flake's NixOS VM tests need KVM, but /dev/kvm is missing; run them on a KVM hos. Recommendation: Retain repair commit 70aa93e0798a60210b0394354cd0ff3173848f72 on pr-8771 and rerun just ci base in the merged tree dev shell on a KVM host before landing.

CONFLICT (content): Merge conflict in bun.lock
Auto-merging nix/Cargo.nix
Auto-merging package.json
Auto-merging quest/m3/mesh/README.md
Automatic merge failed; fix conflicts and then commit the result.

(written by codex, gpt-6.1-sol, medium effort)

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found. The only change since the last review is another merge of main, and it resolves cleanly.

Reviewed changes

This pass covers the merge pushed since the last Pullfrog review at e9f4ca1.

  • Merged main into the branch. The range-diff shows only shifted context in bun.lock, where main added the @moq/obs workspace and typescript 7.0.2, and in quest/m3/mesh/README.md, where main edited the Related list this PR also touches. None of the PR's own edits changed, and the earlier candidate-placement fix in vendor/str0m/change/sdp.rs is unchanged.

Pullfrog  | View workflow run | Using claude-opus-5-5 | 𝕏

@kixelated
kixelated added this pull request to the merge queue Nov 14, 2026
Merged via the queue into main with commit 1ed1b35 Nov 15, 2026
7 checks passed
@kixelated
kixelated deleted the remove-p2p branch November 15, 2026 00:33
kixelated added a commit that referenced this pull request Nov 15, 2026
Conflicts: main removed the relay's STUN responder (#8771), so the handoff no
longer carries a STUN socket (Role::Stun and Sockets::udp go too).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Nov 15, 2026
Main dropped TCP sockets (#8772) and peer-to-peer (#8771). The track socket's
messages, main's new tests, and the interop socket clients now key each message's
group, since a socket track is scale-less. A lite-07 test helper stamps its frame
with its group's key, as the first frame's absolute delta must.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated added a commit that referenced this pull request Nov 15, 2026
…om the media and gateway crates

moq-audio's aac, bus, and aec, moq-ffi's audio and video, moq-rtmp's tls, and
moq-quic's mux always compile, and moq-video's dmabuf compiles on Linux. v4l2
joins the defaults of moq-video, moq-transcode, and moq-cli beside vaapi and
nvidia. moq-webrtc's p2p already went with #8771.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant