elixir_quic — experimental QUIC v1 library
This repository contains an incremental Elixir QUIC implementation and its revision 3 design. Independent certificate handshakes, Retry, single-fault packet impairment and certificate/ALPN rejection pass in both roles against aioquic 1.2.0. Full protocol lifecycle and product acceptance remain incomplete. The Phase 1 reliable-stream implementation uses the exact Hex dependency ex_ssl 0.7.2, whose packaged production source matches the accepted G-S commit f1327e0bb7fb2093b8dc2b07e72b26233a739963. See the Phase 1 acceptance record for current gates, exact evidence and limitations.
The project has three mandatory goals: JA3/JA4 observation of visible QUIC ClientHello data, measured profile-controlled client behavior, and opt-in integration with the Abyss UDP server. It is not a client-only plan.
Start here
Use CODEX-START.md in the actual ex_quic workspace. The first execution slice implements M0–M1: engineering/dependency contracts, wire codecs and Initial/Retry protection with tests. It does not claim that UDP networking is complete.
| Document | Purpose |
|---|---|
| Phase 1 plan / Consumer API / I/O contract | Reliable streams, public handles, admission outcomes and integration ownership |
| Implementation plan | Ordered M0–M6 tasks, dependencies and concrete exit gates |
| Architecture / Detailed design | Functional core, runtime ownership, routing, sending and resource constraints |
| Actual TLS contract | Existing public SSL.QUIC API, action order and limitations |
| Fingerprint design | Observation, matching, simulation and fidelity evidence |
| Abyss integration | Opt-in pre-handler dispatch and shared-socket lifecycle |
| Testing / PRD | Requirements, independent oracles and experimental release acceptance |
| ex_ssl review | F1 closure and honest scope of current verification |
| Revision changes / Sources | Supersession rules and pinned evidence |
Dependency and status
SSL.QUIC and SSL.Fingerprint are real upstream APIs at the reviewed pin, not work to invent in ex_quic. The dependency is now resolved from Hex; its immutable source comparison and lockfile checksums are recorded in the TLS contract. See implementation progress and runtime evidence and independent peer evidence and M3-C through M3-E acceptance for implemented surfaces and remaining gates; design documents also include future modules.
The upstream formatter finding is closed and the inspected supported-runtime compiler/test and TLS-reference jobs pass. Current known upstream limitations, historical macOS TCP integration failures and the absence of a whole-library security audit remain explicit in the review document.
Adopting this package
The Hex package and OTP application are elixir_quic / :elixir_quic.
The GitHub repository remains gsmlg-dev/ex_quic; the public module namespace is Quic.
Starting with the first Hex release, depend on:
{:elixir_quic, "~> 0.3.0"}
Consumers moving from the Git dependency must replace their :ex_quic
dependency/application entry with :elixir_quic, including application config
or release configuration that names the old app. Rename calls and aliases from
QUIC / QUIC.* to Quic / Quic.*; function names and arguments are unchanged.
The unrelated Hex package named ex_quic is not this library.
Copy/adapt these documents into the workspace while preserving local code and user changes. Replace active v1/v2 planning instructions; move older revisions to an explicitly historical archive rather than leaving conflicting prerequisites. Do not create a remote repository or modify ex_ssl/Abyss during the initial scoped task.
Local tests cover codecs, packet protection, inspection, recovery, and both-role UDP certificate handshakes. These self-connection tests are not independent interoperability or security certification. The full product gate requires observer + measured client profiles + Abyss termination; HTTP/3/QPACK and additional TLS features remain separate work.
Application ALPN and unreliable datagrams
Profiles accept application ALPN, for example
Quic.Profile.compile(:ordered, alpn: ["h3"]); the default remains ex-quic.
Negotiating h3 does not implement HTTP/3 or QPACK. Consumers own those protocols.
RFC 9221 DATAGRAM support is opt-in per endpoint with
datagram: [max_frame_size: 1200, max_items: 64, max_buffer_bytes: 65_536].
Use Quic.send_datagram/3 and Quic.read_datagrams/3 with a public connection
handle. DATAGRAM payloads are unreliable, message-oriented, congestion-controlled,
and never retransmitted after loss. See the consumer contract
for negotiation, size limits, bounded queues and admission semantics.
Publishing
The manual Release GitHub Actions workflow validates the source, builds the
Hex package, pushes the verified version commit/tag, publishes it with
mix hex.publish package --yes, and creates a GitHub release with the package
attached. A failed publication can be resumed with the same version and branch;
the existing tag is reused, and an existing Hex version is accepted only when
its checksum matches the built archive.
Configure the repository or organization Actions secret HEX_API_KEY with Hex
publish permission for elixir_quic before dispatching. Missing credentials fail
before any version commit, tag or publication. HexDocs publication is separate;
this workflow publishes the package only.
Dispatch with the intended new version and git_ref=main. Existing v0.2.1
and earlier tags remain source-only releases; this change does not republish them.
Validate packaging locally without publishing:
mix hex.build --output _build/elixir_quic.tar
License
MIT. See LICENSE. Copied test-only TLS fixtures retain their upstream
Apache-2.0 license in test/fixtures/tls/LICENSE and are excluded from the Hex package.