Skip to content

fix(net): backport repeated unknown SETUP option handling - #5222

Merged
kixelated merged 6 commits into
releasefrom
quest/m1/release-backports/setup-repeat
Oct 11, 2026
Merged

kixelated merged 6 commits into
releasefrom
quest/m1/release-backports/setup-repeat

Conversation

@kixelated

@kixelated kixelated commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Release rejects repeated unknown SETUP options that peers are allowed to send. Knownness also depends on the draft: retired MAX_REQUEST_ID is unknown from draft 17, and the MoQ Cluster HOP_ID and RELAY_COST options are unknown before draft 17 (cluster::supported).

Approach

Backport the SETUP decoder portion of #4927 in Rust and JavaScript. Keep duplicate rejection for recognized options, but allow unknown options to repeat while decoding and size-checking their values. One draft-aware predicate (Rust ParameterVarInt::defined, JS definedSetupOption) decides knownness: MAX_REQUEST_ID is unique only in drafts 14-16, HOP_ID/RELAY_COST only from draft 17, and the other named options on every draft.

Impact

  • No public API or ABI change.
  • Accept already-valid IETF messages; no framing, enum assignment or version negotiation change. No MoQ Lite wire change.
  • Release base is preserved. No package version bump or release.

Alternatives

Use the narrow decoder backport rather than importing main's codec refactor or unrelated GROUP_ORDER tightening. No compatibility shim is needed.

Validation

A table test in each language repeats every named varint option, IMPLEMENTATION, and GREASE/unknown ids on drafts 14-22 and asserts Duplicate exactly where the draft defines the option. Forcing HOP_ID/RELAY_COST back to always-known fails it on drafts 14-16 in both languages. The final Rust suite passes 5,073 tests, plus 387 and 132 transport feature tests. Full release-scoped Nix just check and just test interop --all pass.

Interop negotiates Lite; explicit draft-specific raw-wire regressions establish the IETF behavior.

Follow-ups

Main quest cleanup remains gated in #5231 until all six backports land. Main's newer decoder still treats every named option as known on every draft (including MAX_REQUEST_ID and the cluster options), so it needs the same draft-aware predicate in its own PR; it is not imported into this release backport.

(Written by GPT-6 Astra, updated by Claude Opus 5.5)

kixelated and others added 2 commits October 10, 2026 09:22
Co-Authored-By: GPT-6 <noreply@openai.com>
Co-Authored-By: GPT-6 <noreply@openai.com>
Co-Authored-By: GPT-6 <noreply@openai.com>
@kixelated
kixelated marked this pull request as ready for review October 10, 2026 22:54

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: 69ab205

No actionable correctness findings in the full three-file diff. The scoped SETUP backport looks appropriate: both implementations allow unknown repeats while preserving duplicate rejection for recognized options and consuming each repeated value. The regressions cover unknown odd/even kinds and GREASE across drafts 14–22, plus known duplicates and truncated unknown values on drafts 17–22.

Public API and wire encoding are unchanged; decoder acceptance is broadened as intended. Keeping the unrelated GROUP_ORDER work out of this release backport is the simpler approach.

Verification limits: static GitHub review of the diff and surrounding decoder/setup code only; I did not run tests. Check, Test, WASM, macOS, and Windows CI were still running when checked.

(Written by OpenAI)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 69ab205e58

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread rs/moq-net/src/ietf/parameters.rs Outdated
hash_map::Entry::Vacant(entry) => entry.insert(u64::decode(&mut r, version)?),
};
// Unknown SETUP options may repeat, but their values must still decode.
if !matches!(kind, ParameterVarInt::Unknown(_)) && vars.contains_key(&kind) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Classify setup options by negotiated draft

For draft 17 and later, MaxRequestId is no longer a recognized SETUP option, as documented on its enum variant, but this check treats every named variant as known regardless of version. A peer sending option 2 twice in a draft 17-22 SETUP is therefore still rejected with Duplicate instead of having the now-unknown option ignored; make knownness version-dependent and mirror that logic in JS's KNOWN_SETUP_OPTIONS.

AGENTS.md reference: rs/moq-net/AGENTS.md:L5-L5

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-11T15:58:44.079195Z e7c2651 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Co-Authored-By: GPT-6 Astra <noreply@openai.com>
@kixelated
kixelated marked this pull request as draft October 11, 2026 04:57
Co-Authored-By: GPT-6 Astra <noreply@openai.com>
@kixelated
kixelated marked this pull request as ready for review October 11, 2026 05:42

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: ed7441b

No new actionable findings. The retired MAX_REQUEST_ID issue raised in the independent Codex review is fixed in both implementations: option 2 may repeat only in the draft-17+ branch, while drafts 14–16 retain duplicate rejection. The new raw-wire tests cover both sides of that boundary across all supported drafts.

The narrow, version-specific correction is appropriate for this release backport; no broader codec refactor is needed. Public API and wire encoding remain unchanged.

Verification limits: static review of the meaningful delta and surrounding decoders, accounting for the release merge. I did not run tests; current-head CI is still in progress.

(Written by OpenAI)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ed7441b71e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread rs/moq-net/src/ietf/parameters.rs Outdated
Comment on lines +86 to +87
if !matches!(kind, ParameterVarInt::Unknown(_)) && vars.contains_key(&kind) {
return Err(DecodeError::Duplicate);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat legacy cluster options as unknown

Fresh evidence beyond the earlier MAX_REQUEST_ID report is cluster::supported in rs/moq-net/src/ietf/cluster.rs:51-55, which explicitly excludes drafts 14-16. On those drafts, repeated numeric HOP_ID or RELAY_COST options are therefore unknown and must be ignored, but converting them to named enum variants here causes the second occurrence to return Duplicate; the equivalent KNOWN_SETUP_OPTIONS check in JS has the same problem. Make recognizedness depend on both the option and negotiated draft.

AGENTS.md reference: rs/moq-net/AGENTS.md:L5-L5

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in e7c2651: one draft-aware predicate (Rust ParameterVarInt::defined, JS definedSetupOption) now treats HOP_ID/RELAY_COST as unknown on drafts 14-16 and MAX_REQUEST_ID as unknown from 17. SOLICIT and HIDDEN ride every draft, so they stay unique everywhere. A table test covers every named option on drafts 14-22 in both languages.

(Written by Claude Opus 5.5)

HOP_ID and RELAY_COST are only negotiated on draft-17+, so on drafts 14-16 they are unknown options and may repeat, just like MAX_REQUEST_ID from draft-17 on. Replace the per-branch special cases with one draft-aware predicate in Rust and JS, and cover every named option on every draft.

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

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Automated review by review (OpenAI)

Reviewed commit: e7c2651

No new actionable correctness findings in the one-commit delta since ed7441b. The independent legacy-cluster finding is fixed: HOP_ID and RELAY_COST may repeat on drafts 14–16, matching cluster negotiation, while remaining unique from draft 17. The prior MAX_REQUEST_ID fix is preserved. SOLICIT and HIDDEN remain recognized on every supported draft, consistent with their setup consumers.

Centralizing draft-aware knownness is simpler than accumulating decoder-branch exceptions and fits this release backport. The table regressions cover all named varint options, IMPLEMENTATION, and unknown/GREASE IDs across drafts 14–22; they do not cover every named byte option as the description currently claims.

Verification limits: static GitHub review of the delta, decoder context, and extension version gates. I did not run tests or independently verify the reported validation results.

(Written by OpenAI)

@kixelated

Copy link
Copy Markdown
Collaborator Author

Merge summary for e7c2651:

  • Addressed the open Codex P2: SETUP option knownness is now one draft-aware predicate (Rust ParameterVarInt::defined, JS definedSetupOption). MAX_REQUEST_ID is unique only on drafts 14-16, HOP_ID/RELAY_COST only on draft 17+ (matching cluster::supported), and SOLICIT, HIDDEN, and the core options on every draft. Unknown and GREASE ids may repeat everywhere but must still decode.
  • Replaced the per-case tests with a table test in each language over drafts 14-22; it fails in both languages if the cluster options are treated as always-known.
  • Release-scoped just check and CI pass; OpenAI reviewed this head with no findings and Codex gave it a thumbs-up.
  • Follow-up, not in this PR: main's decoder still treats every named SETUP option as known on every draft, so it needs the same draft-aware predicate.

(Written by Claude Opus 5.5)

@kixelated
kixelated merged commit 8921d70 into release Oct 11, 2026
9 checks passed
@kixelated
kixelated deleted the quest/m1/release-backports/setup-repeat branch October 11, 2026 16:17
@moq-bot moq-bot Bot mentioned this pull request Oct 11, 2026
@moq-bot moq-bot Bot mentioned this pull request Oct 11, 2026
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