feat(quic-interop): alias sim-driven testcases + document unsupported ones

The quic-interop-runner exposes several testcases that drive the same
client logic but vary the network conditions injected by the ns-3 sim.
These don't need new client code on our side — they exercise the
existing handshake / transfer paths under loss / corruption / high-RTT /
cross-traffic, which is exactly the bug-finding signal we want.

Aliases added:
  - transferloss, transfercorruption, longrtt, goodput, crosstraffic
    → transfer (H3 GET against varying sim configs)
  - handshakeloss → handshake

Plan doc now lists every standard testcase and either marks it landed,
aliased, or explicitly unsupported with a written reason — so anyone
returning to this knows what's left and why each gap exists. Unsupported
set covers: versionnegotiation (writer hard-codes V1), resumption /
zerortt (no session ticket / 0-RTT), keyupdate (no KEY_PHASE handling),
retry (parser exists but not wired to feed-loop), rebinding-* (no client
migration), amplificationlimit (server-side), blackhole (inverse test),
ipv6 (UdpSocket v6 path unverified).

https://claude.ai/code/session_01HcvfQq1ttPV9PkRoJb4nyT
This commit is contained in:
Claude
2026-05-06 21:57:52 +00:00
parent 68d0cdf2a2
commit 093a39a3ee
2 changed files with 37 additions and 4 deletions
@@ -66,6 +66,30 @@ Inspect `./logs/<run>/client_qlog/*.qlog` in qvis when something breaks.
- `multiplexing` testcase: same as `transfer` but issues each GET in a
parallel `coroutineScope { async { … } }` so the request streams
genuinely overlap on the wire (what tshark verifies).
- Aliased sim-driven testcases — these reuse the same client code paths;
the runner injects the network condition via the ns-3 sim. Failures
here are exactly the bug-finding signal we want, since they exercise
loss recovery / RTT estimator / congestion behaviour against real peers:
- `transferloss` → transfer (random packet loss)
- `transfercorruption` → transfer (random bit-flip; AEAD AUTH FAIL → drop + retransmit)
- `longrtt` → transfer (emulated high-latency link)
- `goodput` → transfer (throughput floor)
- `crosstraffic` → transfer (competing UDP flows on the same link)
- `handshakeloss` → handshake (loss during handshake — tests CRYPTO retransmit)
## Explicitly unsupported testcases (return 127, runner skips)
| Testcase | Reason |
|---|---|
| `versionnegotiation` | `QuicConnectionWriter` hard-codes `QuicVersion.V1`; needs a configurable initial version + VN-response retry path |
| `resumption` | session ticket parsing + persistence not yet implemented |
| `zerortt` | depends on `resumption` + early-data path |
| `keyupdate` | KEY_PHASE bit handling not yet implemented in 1-RTT |
| `retry` | `RetryPacket` parses but isn't fully wired into the connection feed-loop yet — claiming support without verifying would mask bugs |
| `rebinding-port`, `rebinding-addr` | client-side connection migration (re-bind UDP socket, NEW_CONNECTION_ID rotation) not implemented |
| `amplificationlimit` | server-side test, N/A for client role |
| `blackhole` | inverse test (verifies we *fail* on dead network in bounded time); needs special handling |
| `ipv6` | `UdpSocket` IPv6 path not exercised; risky to claim without testing |
## Phase 1a — landed 2026-05-06
@@ -86,8 +86,9 @@ fun main() {
// Both `handshake` and `chacha20` only require the handshake to
// complete; `chacha20` adds the constraint that we offered only
// ChaCha20-Poly1305 (verified by the runner via tshark on the
// sim's pcap, decrypted using SSLKEYLOGFILE).
"handshake", "chacha20" -> {
// sim's pcap, decrypted using SSLKEYLOGFILE). `handshakeloss`
// is the same client behaviour against a lossy sim.
"handshake", "chacha20", "handshakeloss" -> {
runHandshakeTest(requests, cipherSuites, keyLogPath)
}
@@ -95,8 +96,16 @@ fun main() {
// write each body to $DOWNLOADS/<basename>. `multiplexing`
// additionally requires the requests to be sent in parallel on
// separate streams (the runner verifies via tshark that the
// streams overlap in time).
"transfer", "http3", "multiplexing" -> {
// streams overlap in time). The remaining aliases run the same
// client logic against different sim configurations:
// transferloss — random packet loss
// transfercorruption — random bit-flips (recovery via AEAD AUTH FAIL → drop + retransmit)
// longrtt — emulated high-latency link
// goodput — throughput floor under default sim
// crosstraffic — competing UDP flows on the same link
"transfer", "http3", "multiplexing",
"transferloss", "transfercorruption", "longrtt", "goodput", "crosstraffic",
-> {
if (downloads == null) {
System.err.println("DOWNLOADS env var required for $testcase")
EXIT_FAIL