Repository navigation
quest(m1): plan fuzz crypto, richer sim workloads, and a relay drill flake #5785
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c6e704a
d885295
e3659cc
ec9de84
238c2f4
ef4677e
cf8b3cd
7806b98
fc2f0e7
cad3113
6dceb40
746287f
b857d1c
da666c6
08a07b1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When 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. | ||
|
coderabbitai[bot] marked this conversation as resolved.
Resolved
|
||
| 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When migration changes an endpoint address while an accepted DATAGRAM is queued or in flight, 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]. | ||
| 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 plannedconnectiontarget inquest/m1/quic/coverage/fuzz.mdstill 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 👍 / 👎.
There was a problem hiding this comment.
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)