Skip to content
Merged
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
2 changes: 2 additions & 0 deletions quest/m1/quic/coverage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ and the harness defaults to Cubic while production runs BBR3.
## Required

- [Characterization tests](/quest/m1/quic/coverage/characterize.md) - golden scheduling order, and every uncovered frame, reset, limit, and endpoint path, on today's harness
- [Plaintext fuzz crypto](/quest/m1/quic/coverage/fuzz-crypto.md) - a fuzz-only plaintext session so the connection target skips TLS and its injected packets decrypt
- [Richer simulation workloads](/quest/m1/quic/coverage/sim-workloads.md) - resets, bidi streams, datagrams, and migration in the random workloads, each with its own invariant
- [Pin benchmark cores](/quest/m1/quic/coverage/bench-pin.md) - local base/head comparisons run on one core type on hybrid CPUs

## Related
Expand Down
27 changes: 27 additions & 0 deletions quest/m1/quic/coverage/fuzz-crypto.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# [S] Plaintext crypto for fuzzing

## Goal

A plaintext crypto session in `moq-quic`'s hidden `fuzz` module (no TLS
handshake, no packet protection) lets the `connection` fuzz target skip the
per-input TLS cost and decrypt the packets it injects, so fuzzing reaches the
frame layer at far higher throughput. It never ships in a non-test build.

## Plan

Decided 2026-10-16 with the maintainer:

- One implementation, in the hidden `fuzz` feature module. The Criterion
benchmarks enable `--features fuzz`, as moq-net's already do, and replace
their bench-local no-op protection (`NoProtection*` in
`rs/moq-quic/benches/common/mod.rs`, ported from quinn `perf`'s
`noprotection.rs`) with it.
- The `connection` target switches to it, so injected and mutated packets
decrypt instead of being dropped at the AEAD. Today it runs about 64
inputs/s, almost all spent in the handshake.
Comment on lines +19 to +21

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 Exclude injected frames from the write-integrity oracle

When a mutated inbound packet happens to encode a valid STREAM frame, the new no-op AEAD will admit bytes that were not written through the connected Pair. The planned connection target in quest/m1/quic/coverage/fuzz.md still asserts that all delivered bytes match what was written, so such a valid fuzz input will be minimized as a regression even though the transport behaved correctly. Split raw-packet operations from that byte-integrity oracle, or account for successfully injected frames, before switching the target to this crypto.

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.

Agreed. cf8b3cd scopes the delivered-bytes check to streams no injected frame touched, once injected packets decrypt; the no-panic check still covers every input.

(Written by Claude Opus 5.5)

Comment on lines +19 to +21

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 Account for corrupted packets in the integrity oracle

When Op::Corrupt flips a byte in a queued STREAM payload, the planned no-op packet protection admits that alteration, but read still asserts that every delivered byte matches the sender's record, producing a false fuzzing regression. Fresh evidence in the landed target is the mutation at rs/moq-quic/src/fuzz/connection.rs:602-608 followed by the byte assertion at rs/moq-quic/src/fuzz/connection.rs:713-723; excluding only streams touched by Inject does not cover this path, so corrupted packets must also be tracked or separated from the integrity oracle.

Useful? React with 👍 / 👎.

- Once packets decrypt, an injected or corrupted packet can carry valid
STREAM or DATAGRAM frames, so the target's integrity checks (stream bytes
match what was written, `check_datagram` matches what was sent) exclude
the streams and datagrams those packets touch; no-panic still covers every
input.
- Not a debug transport: nothing outside the `fuzz` feature can name it.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
32 changes: 32 additions & 0 deletions quest/m1/quic/coverage/sim-workloads.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# [M] Richer simulation workloads

## Goal

The seeded simulation's random workloads in `rs/moq-quic/src/tests/sim.rs`
also exercise the paths the QUIC rewrites cut, each with its own invariant,
so a refactor that breaks one fails a replayable seed:

- **Resets**: RESET_STREAM and RESET_STREAM_AT mid-transfer. The reader
sees an unmodified prefix of what was written, then the reset code. The
prefix covers at least the reliable size for RESET_STREAM_AT and may be
any length for RESET_STREAM, since bytes already read stay read. Stream
and connection credit come back.
- **Stops**: STOP_SENDING mid-transfer. The sender observes the code
through `SendStream::stopped` or `WriteError::Stopped`, the stopped
reader sees nothing further, and credit comes back.
- **Bidirectional streams**: both sides write on the same streams, and every
byte arrives once and in order in each direction.
- **Datagrams** interleaved with streams: each arrives at most once and
unmodified, and datagrams never stall stream progress. On a lossless link
with buffers sized for the workload, every datagram arrives, so dropping
them all fails.
- **Migration**: NAT rebinding and active migration mid-workload. The
connection survives and every delivery invariant still holds.
Comment on lines +23 to +24

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 Exempt migration-time datagrams from exact delivery

When migration changes an endpoint address while an accepted DATAGRAM is queued or in flight, Pair::drive_server discards packets whose destination is the old address (rs/moq-quic/src/tests/util.rs:177-200), and QUIC DATAGRAMs are unreliable and are not retransmitted. Thus even a lossless-link migration case can legitimately miss that datagram, while “every delivery invariant” applies the exact-delivery assertion from the previous bullet and turns a valid migration into a failing seed. Either quiesce datagrams before rebinding or exempt migration-transition datagrams from the exact-delivery oracle.

Useful? React with 👍 / 👎.


## Plan

Decided 2026-10-16 with the maintainer. Reuse the workload generator and
invariant checks from the seeded simulation, under the same PR budget (64
fixed cases) and nightly sweep (`just rs quic-sim`). If migration needs
address changes that `Pair`'s `Link`s cannot express, add the smallest
harness hook for it here; flag it on the PR if that pushes past [M].
1 change: 1 addition & 0 deletions quest/m1/test-flakes-2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Public API: none. Wire: none.
- [Update after finish](/quest/m1/test-flakes-2/update-after-finish.md) - a subscribe update racing a publisher's finish ends the track cleanly in JS and Rust, not with the write's error
- [Auth refresh mocks time](/quest/m1/test-flakes-2/auth-refresh-mock-time.md) - moq-relay's auth refresh and fixed-lease tests measure a grant's life on one mocked clock
- [uring teardown close](/quest/m1/test-flakes-2/uring-teardown-close.md) - moq-uring's published-close teardown test holds under load, fixed at its cause
- [Relay burst drill](/quest/m1/test-flakes-2/relay-burst-impaired.md) - the impaired transport-peer burst drill never aborts its subscription while the link is up
- [WASM IETF read](/quest/m1/test-flakes-2/wasm-ietf-read.md) - the WASM suite's IETF read case reads whole groups on a loaded runner, fixed at the burst or the assertion as the evidence says
- [BBR marking seed](/quest/m1/test-flakes-2/bbr-marking-seed.md) - the BBR marking test seeds its probe schedule, replays a failing seed, and its rare drop is fixed at the cause

Expand Down
25 changes: 25 additions & 0 deletions quest/m1/test-flakes-2/relay-burst-impaired.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# [S] The relay burst drill holds on an impaired peer link

## Goal

The `bursts_cross_a_transport_peer::impaired` drill
(`rs/moq-relay/tests/drills.rs`) passes reliably, fixed at its cause. It
still proves that bursts cross a relay peer link over an impaired transport
without the subscription aborting while the link is up.

## Plan

Seen 2026-10-16 on the io_uring job for #5772 (run 38974661047, head
1c1055c): the subscription aborted with "internal error" at the drill's
`Err(err) => panic!("the subscription aborted: {err}")` arm, which is
reached only when the route is not flapping. A rerun passed. The PR touched
only the dev shell, so the drill ran only because every crate was retested.

Decided 2026-10-16 (maintainer): a child of this questline, m1. Reproduce it
first, on the io_uring lane under load. Then find which layer produces the
"internal error": an abort that reaches a subscriber while its peer link is
up is a product bug unless the drill's impairment legitimately cut the link,
in which case the drill must classify that as a flap. Never widen a timeout
or add a retry.

Public API: none expected. Wire: none.