Applies to v1.0.x. This document is the source of truth for “what works,
what is partial, and what is intentionally not implemented” in the current
release line. It is updated on every minor release.
See also: CHANGELOG.md, api_stability.md,
reports/interop_status.md.
If you are evaluating QuicX for production use, jump straight to the
Known limitations summary
at the end of this document — it lists every “red line” you need to know.
| Symbol | Meaning |
|---|
| ✅ | Fully implemented, covered by unit tests, used in examples |
| 🟡 | Partially implemented — works in the common path; see notes for caveats |
| 🧪 | Implemented but considered experimental — API or behavior may change |
| ❌ | Not implemented in this release |
| 🚫 | Out of scope for this project |
| Feature | Status | Notes |
|---|
QUIC v1 (0x00000001, RFC 9000) | ✅ | Default |
QUIC v2 (0x6b3343cf, RFC 9369) | ✅ | Selectable per connection |
| Version negotiation packet | ✅ | Server side |
| Forced version downgrade resistance | ✅ | Per RFC 9000 §6 |
| Feature | Status | Notes |
|---|
| TLS 1.3 via BoringSSL | ✅ | |
| 1-RTT handshake | ✅ | |
| 0-RTT handshake (early data) | ✅ | Replay protection per RFC 9001 §9 |
| Session ticket caching | ✅ | In-memory; persistence is the application’s responsibility |
SSLKEYLOGFILE for Wireshark | ✅ | |
| Retry packet (anti-amplification) | ✅ | RetryPolicy::NEVER / SELECTIVE / ALWAYS |
| Address validation token | ✅ | Including stateless retry token |
| Certificate verification | ✅ | Server cert verification on the client |
| Custom verifier callback | ✅ | Via QuicClientConfig |
| Client certificate (mTLS) | 🟡 | Code paths exist, lightly tested in unit tests, no end-to-end example |
| Feature | Status | Notes |
|---|
| Multi-connection management on a single UDP socket | ✅ | |
Graceful CONNECTION_CLOSE (transport + application) | ✅ | |
| Stateless reset | ✅ | |
| Idle timeout | ✅ | Negotiated via transport parameters |
PING frame for keep-alive | ✅ | |
| Feature | Status | Notes |
|---|
| Bidirectional streams | ✅ | |
| Unidirectional streams | ✅ | |
| Stream-level flow control | ✅ | |
| Connection-level flow control | ✅ | |
STREAM_DATA_BLOCKED / DATA_BLOCKED | ✅ | Emitted and handled |
MAX_STREAMS and STREAMS_BLOCKED | ✅ | |
RESET_STREAM / STOP_SENDING | ✅ | |
| Feature | Status | Notes |
|---|
| BBR v1 | ✅ | |
| BBR v2 | ✅ | |
| BBR v3 | 🧪 | Implemented; tuning is preliminary, expect changes |
| CUBIC | ✅ | |
| Reno | ✅ | |
| Pluggable congestion controller (factory) | ✅ | Per-connection selection |
| Packet pacing | ✅ | |
| ACK-based loss detection (RFC 9002) | ✅ | |
| PTO (Probe Timeout) | ✅ | |
| Per-encryption-level retransmission tracking | ✅ | |
| ECN marking and feedback | 🟡 | Optional, off by default; not all simulator peers exercise this |
| Feature | Status | Notes |
|---|
| Active client migration | ✅ | |
| NAT rebinding detection | ✅ | |
Path validation (PATH_CHALLENGE / PATH_RESPONSE) | ✅ | |
| Connection ID rotation during migration | ✅ | RFC 9000 §9.5: after a successful migration the local DCID is rotated to the next remote CID and the peer is asked to retire the old one; locally we honour §19.16 single-seq retire and §19.15 batch retire (retire_prior_to), then auto-replenish the local pool. Verified by interop self-test (connectionmigration / rebind-port / rebind-addr all PASS). |
Server-initiated NEW_CONNECTION_ID rotation | ✅ | Issued during handshake; auto-replenished after migration / retire to keep active_connection_id_limit saturated |
RETIRE_CONNECTION_ID handling | ✅ | |
| Feature | Status | Notes |
|---|
| Key update (RFC 9001 §6) | ✅ | Optional, automatic |
HANDSHAKE_DONE frame | ✅ | |
NEW_TOKEN frame | ✅ | |
Multipath QUIC (draft-ietf-quic-multipath) | ❌ | Not implemented |
| DATAGRAM frame (RFC 9221) | ❌ | Not implemented |
ACK Frequency extension (draft-ietf-quic-ack-frequency) | ❌ | Not implemented |
Reliable stream reset (draft-ietf-quic-reliable-stream-reset) | ❌ | Not implemented |
| Greasing (RFC 8701) | 🟡 | Frame type greasing yes; transport parameter greasing partial |
| Feature | Status | Notes |
|---|
| HTTP/3 framing (DATA / HEADERS / SETTINGS / GOAWAY / etc.) | ✅ | |
| Request streams | ✅ | |
| Response streams | ✅ | |
| Control stream | ✅ | |
GOAWAY graceful shutdown | ✅ | |
SETTINGS exchange | ✅ | |
| Reserved stream type ignoring | ✅ | |
| Feature | Status | Notes |
|---|
| Static table | ✅ | |
| Dynamic table (encoder + decoder) | ✅ | |
| Huffman encoding / decoding | ✅ | |
| Encoder stream | ✅ | |
| Decoder stream | ✅ | |
| Insert count and stream blocking | ✅ | |
| Feature | Status | Notes |
|---|
Path parameter routing (/users/:id) | ✅ | |
Wildcard routing (/static/*) | ✅ | |
| Per-method handler registration | ✅ | All standard verbs |
| Before / After middleware chains | ✅ | Per-method |
Server push (PUSH_PROMISE) | ✅ | |
Streaming request body via IAsyncServerHandler | ✅ | |
| Trailers | 🟡 | Encoder support exists; routing-level convenience API is minimal |
1xx informational responses (Early Hints) | ❌ | |
| Feature | Status | Notes |
|---|
| Synchronous-style request / response | ✅ | |
Streaming response body via IAsyncClientHandler | ✅ | |
| Push promise accept / reject callback | ✅ | |
| Connection pooling across hosts | 🟡 | Per-host single-connection reuse; multi-host pool is application-side |
| Method | Status |
|---|
| GET / HEAD / POST / PUT / DELETE | ✅ |
| OPTIONS / TRACE / PATCH | ✅ |
| CONNECT | ✅ |
CONNECT-UDP (RFC 9298 / MASQUE) | ❌ |
| Extended CONNECT for WebTransport | ❌ |
| Feature | Status | Notes |
|---|
HTTP/1.1 → HTTP/3 Alt-Svc advertisement | ✅ | src/upgrade |
| Negotiation example | ✅ | example/upgrade_h3 |
| HTTP/2 → HTTP/3 fallback | 🚫 | Out of scope (no HTTP/2 server in QuicX) |
| Feature | Status | Notes |
|---|
| Built-in metrics registry | ✅ | UDP / QUIC / HTTP/3 / congestion / TLS / migration / retry / memory |
| Metrics HTTP endpoint | ✅ | Optional, configured via Http3ServerConfig::metrics_ |
| QLog (RFC 9254) | ✅ | Build with -DQUICX_ENABLE_QLOG=ON |
| Levelled logging | ✅ | |
| OpenTelemetry export | ❌ | Application can bridge from the metrics registry |
Platform support is what the build system targets. Routine CI for all
three platforms is not yet in place (planned for a later release); today the
matrix is “developer validated, no continuous coverage”.
| Platform | Build | Runtime | Notes |
|---|
| Linux x86_64 (gcc 9+, clang 10+) | ✅ | ✅ | Primary development platform |
| Linux aarch64 | 🟡 | 🟡 | Should build; not regularly tested |
| macOS x86_64 / arm64 | ✅ | ✅ | Build code path under src/common/network/macos |
| Windows x86_64 (MSVC 2019+) | ✅ | 🟡 | Build code path under src/common/network/windows; less smoke time than Linux |
| FreeBSD / OpenBSD | ❌ | ❌ | Not attempted |
| 32-bit targets | 🚫 | 🚫 | Out of scope |
| Toolchain | Status | Notes |
|---|
| GCC 9+ | ✅ | C++17 |
| Clang 10+ | ✅ | Including ASan / UBSan / TSan / libFuzzer |
| MSVC 2019+ | 🟡 | Builds; CI coverage missing |
| Apple Clang | ✅ | |
| System | Status | Notes |
|---|
| CMake ≥ 3.16 | ✅ | Primary |
| Bazel | 🟡 | BUILD.bazel files exist; less battle-tested than CMake |
| Makefile | 🚫 | Not provided |
| Tool | Status | Notes |
|---|
| AddressSanitizer | ✅ | Clean on quicx_utest |
| UndefinedBehaviorSanitizer | ✅ | Clean on quicx_utest |
| ThreadSanitizer | ✅ | Clean on quicx_utest |
| MemorySanitizer | 🟡 | Requires instrumented BoringSSL; not part of routine validation |
| libFuzzer (frame / packet / qpack / varint) | ✅ | -DENABLE_FUZZING=ON, smoke clean |
| Valgrind | 🟡 | Works for short runs; not part of CI |
The interop matrix is regenerated per release. The current detailed report is
reports/interop_status.md.
Summary for v1.0.0 (24 scenarios × 17 peers, 90.60% pass rate):
handshake / transfer scenarios: pass broadly against mainstream peers
(quinn, msquic, ngtcp2, neqo, lsquic, picoquic, quic-go, mvfst, aioquic, …).
- A few peers have known issues documented in
quic_interop_sim_issues.md.
- Advanced scenarios (
multiconnect, resumption, keyupdate, chacha20,
retry, zerortt, http3, versionnegotiation, ecn,
connectionmigration, … 24 in total) — see the interop status document for
the per-pair grid.
- No Multipath / DATAGRAM / ACK Frequency — applications needing these
should wait for a future release.
- Cross-platform CI is missing — Windows and macOS are developer-tested
but not continuously verified.
- No ABI stability — the public C++ API follows SemVer since 1.0
(patch and minor releases preserve source compatibility); binary (ABI)
stability is not promised, so always rebuild against the QuicX version
you link — see
api_stability.md.
- No SLA on security response time beyond the best-effort targets in
SECURITY.md.
- mTLS, Trailers, connection pooling have working code but limited
end-to-end validation.
- v1.0.0 (released) — the public C++ API follows SemVer from this
release onward; 24-scenario × 17-peer interop matrix at a 90.60% pass
rate.
- For what’s next, see
../../../CHANGELOG.md and
interop_status.md.