Skip to content

QuicX Support Matrix

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.


SymbolMeaning
✅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

FeatureStatusNotes
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
FeatureStatusNotes
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
FeatureStatusNotes
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✅
FeatureStatusNotes
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✅
FeatureStatusNotes
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
FeatureStatusNotes
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✅
FeatureStatusNotes
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

FeatureStatusNotes
HTTP/3 framing (DATA / HEADERS / SETTINGS / GOAWAY / etc.)✅
Request streams✅
Response streams✅
Control stream✅
GOAWAY graceful shutdown✅
SETTINGS exchange✅
Reserved stream type ignoring✅
FeatureStatusNotes
Static table✅
Dynamic table (encoder + decoder)✅
Huffman encoding / decoding✅
Encoder stream✅
Decoder stream✅
Insert count and stream blocking✅
FeatureStatusNotes
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)❌
FeatureStatusNotes
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
MethodStatus
GET / HEAD / POST / PUT / DELETE✅
OPTIONS / TRACE / PATCH✅
CONNECT✅
CONNECT-UDP (RFC 9298 / MASQUE)❌
Extended CONNECT for WebTransport❌

FeatureStatusNotes
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)

FeatureStatusNotes
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”.

PlatformBuildRuntimeNotes
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

ToolchainStatusNotes
GCC 9+✅C++17
Clang 10+✅Including ASan / UBSan / TSan / libFuzzer
MSVC 2019+🟡Builds; CI coverage missing
Apple Clang✅

SystemStatusNotes
CMake ≥ 3.16✅Primary
Bazel🟡BUILD.bazel files exist; less battle-tested than CMake
Makefile🚫Not provided

ToolStatusNotes
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.

Known limitations summary (read this before adopting)

Section titled “Known limitations summary (read this before adopting)”
  1. No Multipath / DATAGRAM / ACK Frequency — applications needing these should wait for a future release.
  2. Cross-platform CI is missing — Windows and macOS are developer-tested but not continuously verified.
  3. 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.
  4. No SLA on security response time beyond the best-effort targets in SECURITY.md.
  5. 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.