Skip to content

fix(quic): let an oversized datagram step aside behind control frames - #6521

Merged
kixelated merged 1 commit into
mainfrom
fix/quic-oversized-datagram-probe
Oct 23, 2026
Merged

kixelated merged 1 commit into
mainfrom
fix/quic-oversized-datagram-probe

Conversation

@kixelated

Copy link
Copy Markdown
Collaborator

Problem

A loss probe is clamped to min_mtu. When the head of the send schedule is a DATAGRAM that fits the path MTU but not the probe, write_frames stepped it aside only if the packet was still empty. A PING or IMMEDIATE_ACK already in the probe counted as "not empty", so the probe ended with no STREAM data even though a stream was queued behind the datagram.

That tiny probe (36 bytes in the fuzz case) became the GSO segment size. moq-dev/moq#6279 ended the batch there to stop the resulting MIN_PACKET_SPACE assertion, but the short probe itself was the bug.

Change

  • write_frames: a datagram that does not fit the room left ends the packet only when it would fit an empty one. If it can't fit even an empty packet of this size, it steps aside for what fits behind it, whatever control frames are already in the packet.
  • a_clamped_packet_sends_what_fits now puts a PING ahead of the clamped packet. It fails without the fix.
  • The GSO guard stays, with a simpler comment. A datagram that barely fits an empty packet still ends one holding a PING, by design (a_datagram_behind_control_frames_ends_the_packet), so a short first packet with streams queued is still reachable. The new tail_loss_probe_ended_short_ends_the_gso_batch test reproduces that through poll_transmit and hits the debug_assert without the guard. The committed fuzz input stopped reaching this path after moq-dev/moq#5878.

Dropped: making the GSO re-check size-aware in place of the guard. A 40 to 86 byte first packet leaves room for a STREAM frame, so a size-aware re-check would pass it, but the allocation still needs MIN_PACKET_SPACE (87 bytes). The guard already guarantees room for a frame.

Tests

  • just check: lint, compile, and 1521 Rust tests pass.
  • Both new assertions fail with the fix or the guard reverted.

Impact

No public API or wire change. Consumer: every moq-quic connection that sends DATAGRAMs larger than min_mtu alongside streams.

The quinn-proto counterpart is quinn-rs/quinn#2949. quinn writes datagrams before streams, so it never hits the step-aside case; only the guard applies there.

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

A loss probe is clamped to min_mtu. When a queued DATAGRAM fit the path MTU
but not the probe, write_frames stepped it aside only if the packet was still
empty, so a PING or IMMEDIATE_ACK made it end the probe with no STREAM data,
leaving a tiny first datagram that GSO then repeated. Step aside whenever the
datagram cannot fit even an empty packet of this size.

Also simplify the GSO minimum-segment comment and pin that guard with a test,
since the committed fuzz input no longer reaches it.

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

coderabbitai Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 13 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6d06cee8-b5c3-4a44-be53-6a7f950b879f
📥 Commits

Reviewing files that changed from the base of the PR and between ab2e35d and ac78210.

📒 Files selected for processing: 4
  • rs/moq-quic/src/connection/mod.rs
  • rs/moq-quic/src/connection/streams/saturated.rs
  • rs/moq-quic/src/connection/streams/state.rs
  • rs/moq-quic/src/tests/mod.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 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-23T06:28:12.382564Z ac78210 PR opened
ℹ️ 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.

@kixelated

Copy link
Copy Markdown
Collaborator Author

Merging. The maintainer chose /quest-merge. CI is green, the current head has a non-Grok review, and quest check passes against main.

(Written by Claude Opus 5.5)

@kixelated
kixelated added this pull request to the merge queue Oct 23, 2026
Merged via the queue into main with commit 14db566 Oct 23, 2026
9 checks passed
@kixelated
kixelated deleted the fix/quic-oversized-datagram-probe branch October 23, 2026 18:26
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