macula_quic (macula v8.0.1)
View SourceMacula QUIC transport — Quinn-based Rust NIF.
Provides QUIC listener, connection, and stream operations backed by Quinn (Rust). Listeners bind to specific IP addresses, enabling per-identity IPv6 binding for virtual relay identities.
Active-mode messages delivered to owning process: {quic, Data, StreamRef, Flags} — stream data {quic, new_conn, ConnRef, Info} — new connection accepted {quic, new_stream, StreamRef, Props} — new stream accepted {quic, peer_send_shutdown, StreamRef, undefined} {quic, stream_closed, StreamRef, Flags} {quic, shutdown, Handle, Reason}
Summary
Functions
Accept stream with options and timeout (for macula_dist).
Start accepting connections on a listener. Delivers {quic, new_conn, ConnRef, Info} to the calling process.
Start accepting streams on a connection. Delivers {quic, new_stream, StreamRef, #{conn => ConnRef}} to the owning process.
Send data asynchronously.
Async shutdown connection.
Async shutdown stream.
Generic close — tries stream, then connection, then listener.
Close a connection.
Close a listener.
Close a stream.
Connect to a remote QUIC server. Host is a hostname or IP-string; validation depends on verify / verify_pubkey opts.
Transfer ownership of a handle to another process. Works with both stream and connection handles.
Generate a self-signed X.509 cert from an Ed25519 keypair. Returns {ok, {CertPem, KeyPem}} as PEM-encoded binaries suitable for handing to macula_quic:listen/3 via cert / key opts (after writing to disk). The cert wraps the identity's macula pubkey; no CA chain required. Used by station listeners running pubkey-anchored peering and by macula-net transport bring-up.
Get connection stats. NOT IMPLEMENTED — answers {error, not_implemented}.
Hand off a stream to another process (for macula_dist).
Complete TLS handshake. With Quinn, handshake completes during accept — this is a no-op for compat.
Listen on a port or {Address, Port} tuple.
Listen on a specific bind address and port. BindAddr is a binary: "0.0.0.0", "192.168.1.1", "2600:3c0e::100", etc.
Path MTU as discovered by Quinn's DPLPMTUD on this connection. Returns {ok, Bytes} once the path MTU has been established; {error, no_path_mtu} early in the connection lifecycle (before the first probe lands) or if the peer disabled datagrams. Phase 4.2.
Open a new bidirectional stream.
Open stream with options map (for macula_dist).
Get remote address of a connection.
Send data on a stream (blocking).
Set active mode on a stream handle.
Functions
Accept stream with options and timeout (for macula_dist).
Start accepting connections on a listener. Delivers {quic, new_conn, ConnRef, Info} to the calling process.
Start accepting streams on a connection. Delivers {quic, new_stream, StreamRef, #{conn => ConnRef}} to the owning process.
Send data asynchronously.
Async shutdown connection.
Async shutdown stream.
-spec close(reference()) -> ok.
Generic close — tries stream, then connection, then listener.
-spec close_connection(reference()) -> ok.
Close a connection.
-spec close_listener(reference()) -> ok.
Close a listener.
-spec close_stream(reference()) -> ok.
Close a stream.
-spec connect(Host, inet:port_number(), list(), timeout()) -> {ok, reference()} | {error, term()} when Host :: binary() | string().
Connect to a remote QUIC server. Host is a hostname or IP-string; validation depends on verify / verify_pubkey opts.
Trust modes (most to least authenticated):
{verify_pubkey, Pin}— pin the leaf cert's Ed25519 SPKI toPin(32 bytes). No CA chain. Overridesverify.{verify, webpki}— webpki roots + hostname check (Let's Encrypt-anchored station certs). THE DEFAULT since 5.0.0; before that the default wasnone.{verify, none}— skip all server-cert verification. Development / self-signed labs only; a network MITM can impersonate the peer. Must now be opted into explicitly, and every such dial logs a warning.
Transfer ownership of a handle to another process. Works with both stream and connection handles.
-spec generate_self_signed_cert(Pubkey :: binary(), Privkey :: binary(), Sans :: [binary() | string()]) -> {ok, {CertPem :: binary(), KeyPem :: binary()}} | {error, term()}.
Generate a self-signed X.509 cert from an Ed25519 keypair. Returns {ok, {CertPem, KeyPem}} as PEM-encoded binaries suitable for handing to macula_quic:listen/3 via cert / key opts (after writing to disk). The cert wraps the identity's macula pubkey; no CA chain required. Used by station listeners running pubkey-anchored peering and by macula-net transport bring-up.
Get connection stats. NOT IMPLEMENTED — answers {error, not_implemented}.
⚠ This used to answer {ok, [{S, 0} || S <- Stats]} — plausible, well-formed, permanently zero — and excuse itself with "zeroed values are harmless (dist_util only uses these for liveness signals)". That is precisely the use a hardcoded zero destroys. A counter that always reads zero makes "nothing is moving" indistinguishable from "nobody implemented the counter", so any liveness check built on it is green forever and its author cannot tell.
That is not hypothetical. On 2026-08-13 station-it-milan received every packet sent to it, answered none for thirty hours, and every signal derived from the BEAM read healthy. Anyone reaching for a send-side counter to catch that would have found this one, and it would have lied. Failing loudly is the only honest answer until the NIF surfaces the real thing.
Quinn HAS the numbers: quinn::Connection::stats() carries udp_tx{datagrams,bytes}, udp_rx{...} and path{rtt,lost_packets,black_holes_detected}, and nif_max_datagram_size already calls stats() and discards all but path.current_mtu. Surfacing the rest is an extension of a working function — see macula-station plans/PLAN_WIRE_LIVENESS_TRIPWIRE.md commit 5.
The sole consumer, macula_dist:quic_getstat/1, already has an {error, _} -> {ok, 0, 0, 0} branch, so this changes no behaviour there. It changes what the next caller is told.
Hand off a stream to another process (for macula_dist).
Complete TLS handshake. With Quinn, handshake completes during accept — this is a no-op for compat.
-spec listen(inet:port_number() | {string() | binary(), inet:port_number()}, list()) -> {ok, reference()} | {error, term()}.
Listen on a port or {Address, Port} tuple.
-spec listen(binary() | string(), inet:port_number(), list()) -> {ok, reference()} | {error, term()}.
Listen on a specific bind address and port. BindAddr is a binary: "0.0.0.0", "192.168.1.1", "2600:3c0e::100", etc.
-spec max_datagram_size(reference()) -> {ok, pos_integer()} | {error, term()}.
Path MTU as discovered by Quinn's DPLPMTUD on this connection. Returns {ok, Bytes} once the path MTU has been established; {error, no_path_mtu} early in the connection lifecycle (before the first probe lands) or if the peer disabled datagrams. Phase 4.2.
Open a new bidirectional stream.
Open stream with options map (for macula_dist).
-spec peername(reference()) -> {ok, {string(), inet:port_number()}} | {error, term()}.
Get remote address of a connection.
Send data on a stream (blocking).
Set active mode on a stream handle.