d2a10c9e4a
Setup for driving the pure-Kotlin QUIC client against real reference
servers, kicking off the live-interop validation that closes the loop on
the audit cycles.
PermissiveCertificateValidator (commonMain test-only):
Accepts any cert chain and any signature. For local dev servers (picoquic,
quic-go, nests-rs in Docker) where the system trust store would reject the
self-signed cert. Documented as test-only — must never be wired into
production code.
InteropRunner.main (jvmTest):
Standalone runnable that opens a UDP socket, builds a QuicConnection with
PermissiveCertificateValidator, drives the handshake under a configurable
timeout, and reports CONNECTED / HandshakeFailed / Timeout / UdpFailed
with peer transport parameters on success. Exit code 0 on connect, 1 on
any failure mode — wirable into CI.
`quic/scripts/run-picoquic.sh`:
One-line Docker harness that runs Christian Huitema's picoquic reference
server on UDP 4433. Picoquic is the IETF QUIC WG's reference impl and
the most permissive target for a fresh client (clear qlog traces, accepts
a wide range of transport params).
`./gradlew :quic:interop` Gradle task:
Wraps the runner so live-interop is one command:
./gradlew :quic:interop -PinteropHost=127.0.0.1 -PinteropPort=4433
Validated against a non-running server: returns Timeout cleanly with
exit 1 (the failure-path proves the harness wires correctly).
Workflow documented in `quic/scripts/README.md` covering picoquic,
quic-go, aioquic, quiche, and the eventual graduation path to the
quic-interop-runner Docker matrix at https://interop.seemann.io.
Next step: actually run picoquic in Docker and chase whatever real-world
incompatibilities surface. Each will be a focused fix commit.
https://claude.ai/code/session_01EC1tfXfap8k8GyKvrxkxZx
71 lines
2.3 KiB
Markdown
71 lines
2.3 KiB
Markdown
# `:quic` interop harness
|
|
|
|
Scripts and test entry points for driving the pure-Kotlin QUIC client against
|
|
real reference servers.
|
|
|
|
## Quickstart — picoquic
|
|
|
|
```bash
|
|
# Terminal 1: run the picoquic reference server in Docker.
|
|
quic/scripts/run-picoquic.sh -d
|
|
|
|
# Terminal 2: drive our client at it.
|
|
./gradlew :quic:jvmTestClasses
|
|
java -cp "$(./gradlew -q :quic:printTestRuntimeClasspath)" \
|
|
com.vitorpamplona.quic.interop.InteropRunnerKt 127.0.0.1 4433
|
|
```
|
|
|
|
Expected output:
|
|
|
|
```
|
|
== :quic interop runner ==
|
|
target: 127.0.0.1:4433
|
|
timeout: 10s
|
|
|
|
✓ HANDSHAKE COMPLETE
|
|
status: CONNECTED
|
|
negotiated ALPN: h3
|
|
peer transport params: max_data=…, max_streams_bidi=…, …
|
|
```
|
|
|
|
## What this proves
|
|
|
|
- TCP-equivalent UDP connection setup
|
|
- QUIC v1 Initial / Handshake / 1-RTT packet flow with RFC-correct PADDING
|
|
- TLS 1.3 over QUIC with the SHA-256 cipher suites
|
|
- ALPN `h3` negotiation
|
|
- QUIC transport parameters round-trip
|
|
- Header protection (AES-ECB)
|
|
- AEAD payload protection (AES-128-GCM)
|
|
|
|
It does NOT yet prove WebTransport / MoQ — picoquic doesn't speak WT.
|
|
|
|
## Live nests interop
|
|
|
|
For a full WebTransport + MoQ test against the actual Nostr nests server, the
|
|
target is `nostrnests.com:443`:
|
|
|
|
```bash
|
|
java -cp "..." com.vitorpamplona.quic.interop.InteropRunnerKt nostrnests.com 443
|
|
```
|
|
|
|
This goes against the real CA-signed cert, so revert to the default
|
|
`JdkCertificateValidator` (the InteropRunner currently uses
|
|
`PermissiveCertificateValidator` for self-signed dev servers — change the
|
|
constant before pointing at production).
|
|
|
|
## Other reference servers worth trying
|
|
|
|
| Server | Image | Notes |
|
|
|---|---|---|
|
|
| picoquic | `privateoctopus/picoquic` | Most permissive; clear qlog traces |
|
|
| quic-go | `martenseemann/quic-go-interop` | Stable, widest scenario coverage |
|
|
| aioquic | `aiortc/aioquic` | Easy to debug, Python reference |
|
|
| quiche | `cloudflare/quiche` | Production-grade, strict |
|
|
| nests-rs | (local cargo build) | The actual MoQ relay; needs WebTransport |
|
|
|
|
The IETF's [`quic-interop-runner`](https://github.com/quic-interop/quic-interop-runner)
|
|
exposes all of these via a single Docker matrix. Wrapping our client in its
|
|
container contract (`TESTCASE` env, `REQUESTS=` URL list, `/certs` mount) would
|
|
let us join the public matrix at https://interop.seemann.io.
|