Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 23 additions & 58 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ moq-mux = { version = "0.5", path = "rs/moq-mux" }
moq-native = { version = "0.15", path = "rs/moq-native", default-features = false }
moq-net = { version = "0.1", path = "rs/moq-net" }
moq-token = { version = "0.6", path = "rs/moq-token" }
qmux = { version = "0.0.7", default-features = false }
qmux = { version = "0.1.0", default-features = false }

serde = { version = "1", features = ["derive"] }
tokio = "1.48"
Expand Down
5 changes: 2 additions & 3 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion js/net/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"release": "bun ../common/release.ts"
},
"dependencies": {
"@moq/qmux": "^0.0.6",
"@moq/qmux": "^0.1.0",
"@moq/signals": "workspace:*",
"async-mutex": "^0.5.0"
},
Expand Down
10 changes: 9 additions & 1 deletion js/net/src/connection/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,15 @@ async function connectWebSocket(url: URL, delay: number, cancel: Promise<void>):
const active = await Promise.race([cancel, timer.then(() => true)]);
if (!active) return undefined;

const quic = new Session(url);
// qmux 0.1.0 pins a single QMux version per Session. Pick qmux-01 (the
// latest) and offer the application protocols that the spec allows on it:
// moq-transport-18 requires qmux-01, and moq-lite is unconstrained so the
// modern versions all ride here. Older moq-transport drafts (15/16/17)
// need qmux-00 and aren't reachable via this fallback path.
const quic = new Session(url, {
version: "qmux-01",
protocols: [Lite.ALPN_04, Lite.ALPN_03, Lite.ALPN, Ietf.ALPN.DRAFT_18],
});

// Wait for the WebSocket to connect, or for the cancel promise to resolve.
// Close the connection if we lost the race.
Expand Down
21 changes: 9 additions & 12 deletions rs/moq-native/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ impl Default for ClientConfig {
#[derive(Clone)]
pub struct Client {
moq: moq_net::Client,
versions: moq_net::Versions,
backoff: Backoff,
#[cfg(feature = "websocket")]
websocket: super::ClientWebSocket,
Expand Down Expand Up @@ -277,10 +276,8 @@ impl Client {
_ => None,
};

let versions = config.versions();
Ok(Self {
moq: moq_net::Client::new().with_versions(versions.clone()),
versions,
moq: moq_net::Client::new().with_versions(config.versions()),
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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Don't bypass ClientConfig.version on WebSocket paths.

These call sites now advertise moq_net::QMUX_ALPNS unconditionally. That ignores the configured versions() subset for WebSocket, so --client-version moq-lite-02 still offers qmux-01.moq-lite-04, qmux-01.moqt-18, etc., and the server can negotiate one of them before moq_net::Client gets a chance to enforce the subset. Please derive the offered pair list from the configured Versions and reuse that filtered list here.

Also applies to: 392-393, 423-424, 453-454, 472-473

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rs/moq-native/src/client.rs` at line 280, The WebSocket client construction
is advertising the full QMUX_ALPNS instead of honoring the configured Versions
subset; change the call sites that construct moq_net::Client (currently using
moq_net::Client::new().with_versions(config.versions()) and where QMUX_ALPNS is
used) to first derive the offered ALPN/QUIC-version pairs from the configured
Versions (ClientConfig::versions or Versions::... helper) and pass that filtered
list into the WebSocket-path client setup so the same filtered pair list is used
for both normal and WebSocket paths (reuse the filtered list rather than
unconditionally using moq_net::QMUX_ALPNS).

backoff: config.backoff,
#[cfg(feature = "websocket")]
websocket: config.websocket,
Expand Down Expand Up @@ -392,8 +389,8 @@ impl Client {

#[cfg(feature = "websocket")]
{
let alpns = self.versions.alpns();
let ws_handle = crate::websocket::race_handle(&self.websocket, &self.tls, url, &alpns);
let alpns = moq_net::QMUX_ALPNS;
let ws_handle = crate::websocket::race_handle(&self.websocket, &self.tls, url, alpns);

return Ok(tokio::select! {
Ok(quic) = quic_handle => self.moq.connect(quic).await?,
Expand Down Expand Up @@ -423,8 +420,8 @@ impl Client {

#[cfg(feature = "websocket")]
{
let alpns = self.versions.alpns();
let ws_handle = crate::websocket::race_handle(&self.websocket, &self.tls, url, &alpns);
let alpns = moq_net::QMUX_ALPNS;
let ws_handle = crate::websocket::race_handle(&self.websocket, &self.tls, url, alpns);

return Ok(tokio::select! {
Ok(quic) = quic_handle => self.moq.connect(quic).await?,
Expand Down Expand Up @@ -453,8 +450,8 @@ impl Client {

#[cfg(feature = "websocket")]
{
let alpns = self.versions.alpns();
let ws_handle = crate::websocket::race_handle(&self.websocket, &self.tls, url, &alpns);
let alpns = moq_net::QMUX_ALPNS;
let ws_handle = crate::websocket::race_handle(&self.websocket, &self.tls, url, alpns);

return Ok(tokio::select! {
Ok(quic) = quic_handle => self.moq.connect(quic).await?,
Expand All @@ -472,8 +469,8 @@ impl Client {

#[cfg(feature = "websocket")]
{
let alpns = self.versions.alpns();
let session = crate::websocket::connect(&self.websocket, &self.tls, url, &alpns).await?;
let alpns = moq_net::QMUX_ALPNS;
let session = crate::websocket::connect(&self.websocket, &self.tls, url, alpns).await?;
return Ok(self.moq.connect(session).await?);
}

Expand Down
Loading
Loading