Module std::net::quic

QUIC transport for internode messaging.

Provides multiplexed, bidirectional byte streams over QUIC/UDP connections. QUIC connections carry multiple independent streams so that head-of-line blocking never stalls unrelated traffic — ideal for actor supervisor chains and distributed messaging between Hew nodes.

Architecture

 ┌──────────────────────────────────────────────────────────┐
QUICEndpoint
 │  bound to a local UDP address (client or server)         │
 │                                                          │
 │  ┌─────────────────────────────────────────────────┐    │
 │  │ QUICConnection  (one per remote peer)            │    │
 │  │  ┌──────────────┐  ┌──────────────┐             │    │
 │  │  │ QUICStream   │  │ QUICStream   │  …          │    │
 │  │  │ (send/recv)  │  │ (send/recv)  │             │    │
 │  │  └──────────────┘  └──────────────┘             │    │
 │  └─────────────────────────────────────────────────┘    │
 └──────────────────────────────────────────────────────────┘

Examples

Server

import std::net::quic;

fn main() {
    let ep = quic.new_server(":4433");
    let conn = ep.accept();
    let stream = conn.accept_stream();
    let data = stream.recv();
    match stream.send(data) {
        Ok(_) => {},
        Err(err) => panic(err),
    }
    match stream.finish() {
        Ok(_) => {},
        Err(err) => panic(err),
    }
    stream.close();
    // Drain connection events so the peer has received all in-flight data
    // before the connection is torn down. Calling conn.disconnect() before
    // both the stream-closed (kind=3) and peer-disconnected (kind=1)
    // events arrive can race delivery on the wire. Across separate
    // processes the exact order is not guaranteed.
    let ev1 = conn.on_event(); ev1.free();
    let ev2 = conn.on_event(); ev2.free();
    match conn.disconnect() {
        Ok(_) => {},
        Err(err) => panic(err),
    }
    ep.close();
}

Client

import std::net::quic;

fn main() {
    let ep = quic.new_client();
    let conn = ep.connect("127.0.0.1:4433", "localhost");
    let stream = conn.open_stream();
    match stream.send(b"hello quic") {
        Ok(_) => {},
        Err(err) => panic(err),
    }
    let reply = stream.recv();
    match stream.finish() {
        Ok(_) => {},
        Err(err) => panic(err),
    }
    // Drain to EOF before closing.  Without this recv() the local close
    // can race the server's final STREAM_FIN frame and the reply may be
    // lost in transit.
    let eof = stream.recv();
    stream.close();
    match conn.disconnect() {
        Ok(_) => {},
        Err(err) => panic(err),
    }
    ep.close();
}

Contents

Functions

Function new_client

pub fn new_client() -> QUICEndpoint

Create a QUIC client endpoint bound to an ephemeral local port.

The endpoint is configured with a permissive TLS verifier suitable for development. Pass TLS configuration explicitly for production use.

Examples

let ep = quic.new_client();
let conn = ep.connect("node2.example.com:4433", "node2.example.com");

Function new_client_with_ca

pub fn new_client_with_ca(ca_pem: string) -> QUICEndpoint

Create a QUIC client endpoint that trusts the given CA bundle.

ca_pem must contain one or more PEM-encoded certificates.

Function new_server

pub fn new_server(addr: string) -> QUICEndpoint

Bind a QUIC server endpoint on addr.

addr uses "host:port" or ":port" notation. A self-signed certificate is generated automatically for development use.

Examples

let ep = quic.new_server(":4433");
let conn = ep.accept();

Function new_server_with_tls

pub fn new_server_with_tls(addr: string, cert_pem: string, key_pem: string) -> QUICEndpoint

Bind a QUIC server endpoint on addr with explicit TLS material.

cert_pem may contain a PEM-encoded certificate chain; key_pem must contain the matching PEM-encoded private key.

Function last_error

pub fn last_error() -> string

Return the last constructor/setup error observed on this thread.

Failed calls to new_client*() and new_server*() update this string. Successful constructors clear it.

Function endpoint_observe

pub fn endpoint_observe(ep: QUICEndpoint) -> QUICEndpointObservation

Return a non-destructive snapshot of endpoint state.

Reads the local address, cumulative accepted-connection count, and last error string from the endpoint without closing or mutating it. The returned QUICEndpointObservation is a plain value struct and does not need to be freed. Call this at any time to poll endpoint health or inspect which address the runtime bound.

Function connection_observe

pub fn connection_observe(conn: QUICConnection) -> QUICConnectionObservation

Return a non-destructive snapshot of connection state.

Reads both endpoint addresses, stream counts, round-trip time, byte counters, closed flag, and last error string in a single call. The returned QUICConnectionObservation is a plain value struct. rtt_ms is the smoothed RTT in milliseconds as reported by the QUIC stack; it is 0 until the handshake completes. last_error is empty when the connection is healthy.

Function connection_disconnect

pub fn connection_disconnect(conn: QUICConnection) -> Result<(), fs.IoError>

Initiate a graceful QUIC connection shutdown.

Sends a CONNECTION_CLOSE frame to the peer and releases the connection handle. Returns Ok(()) on success. On failure, returns Err(IoError::Other(0)); inspect conn.observe().last_error for the QUIC-level error string because QUIC errors carry no OS errno. After calling connection_disconnect, the connection handle must not be used again.

Function stream_observe

pub fn stream_observe(stream: QUICStream) -> QUICStreamObservation

Return a non-destructive snapshot of stream state.

Reads cumulative byte counts, send/receive close flags, and the last error string. The returned QUICStreamObservation is a plain value struct. send_closed is true after stream_finish or stream_stop completes; recv_closed is true when the peer has finished sending. last_error is empty while the stream is healthy.

Function stream_send

pub fn stream_send(strm: QUICStream, data: bytes) -> Result<(), fs.IoError>

Write a byte slice to a QUIC stream.

Sends data as a single STREAM frame sequence. Blocks until the data is accepted by the QUIC stack (not until it is acknowledged by the peer). Returns Ok(()) on success. On failure, returns Err(IoError::Other(0)); inspect strm.observe().last_error for the QUIC-level error string. Does not close the send side — call stream_finish when all data has been written.

Function stream_send_timeout

pub fn stream_send_timeout(strm: QUICStream, data: bytes, deadline_ms: i64) -> Result<(), fs.IoError>

Send bytes on a QUIC stream with a per-call deadline.

deadline_ms <= 0 disables the deadline. Returns Err(IoError::TimedOut(0)) on deadline expiry, Err(IoError::Other(0)) on transport error.

Function stream_recv_timeout

pub fn stream_recv_timeout(strm: QUICStream, deadline_ms: i64) -> Result<bytes, fs.IoError>

Receive bytes from a QUIC stream with a per-call deadline.

deadline_ms <= 0 disables the deadline. Returns Err(IoError::TimedOut(0)) on deadline expiry. On success returns the bytes (may be empty for EOF).

Function stream_finish

pub fn stream_finish(strm: QUICStream) -> Result<(), fs.IoError>

Signal the end of the send side of a QUIC stream.

Sends a FIN to the peer, indicating no more data will be written. The stream remains open for receiving until the peer also closes their send side (or until stream_stop is called). Returns Ok(()) on success. On failure, returns Err(IoError::Other(0)); inspect strm.observe().last_error for the QUIC-level error string.

Function stream_stop

pub fn stream_stop(strm: QUICStream, error_code: i64) -> Result<(), fs.IoError>

Abruptly cancel a QUIC stream with an application error code.

Sends a RESET_STREAM frame to the peer, discarding any unsent data. error_code is a QUIC application-layer error code (0–2^62-1; the QUIC protocol mandates 62-bit codes and i64 is a 64-bit i64 so no narrowing occurs). Use this when the stream must be abandoned rather than gracefully finished. Returns Ok(()) on success. On failure, returns Err(IoError::Other(0)); inspect strm.observe().last_error for the QUIC-level error string.

Function stream_send_string

pub fn stream_send_string(strm: QUICStream, msg: string) -> Result<(), fs.IoError>

Send a UTF-8 string on a QUIC stream.

Converts msg to bytes using the runtime string helper, then delegates to the underlying hew_quic_stream_send FFI.

Function stream_recv_string

pub fn stream_recv_string(strm: QUICStream) -> string

Receive a UTF-8 string from a QUIC stream.

Delegates to hew_quic_stream_recv and converts the resulting bytes to a string using the runtime string helper.

Types

Struct QUICEndpoint

A QUIC endpoint bound to a local UDP address.

An endpoint can operate as a client (dial outgoing connections) or as a server (accept incoming connections), or both simultaneously.

Created by quic.new_client() or quic.new_server(addr). Must be released with close().

Struct QUICConnection

An established QUIC connection to a remote peer.

A connection multiplexes many independent streams over a single UDP path. Obtained from endpoint.connect() (client) or endpoint.accept() (server). Must be released with disconnect().

Struct QUICStream

A bidirectional QUIC stream within a connection.

Streams are independent of each other: a slow receiver on one stream does not delay data arriving on another stream of the same connection.

Obtained from conn.open_stream() or conn.accept_stream(). Finish the send side with finish() when no more data will be sent; the receive side drains naturally.

Struct QUICEvent

An observed QUIC event emitted by an endpoint or connection.

Used by the blocking event API to react to queued connection and channel events. Pair this with observe() for non-destructive snapshots.

Struct QUICEndpointObservation

Non-destructive endpoint observation.

Fields

local_addr: string
accepted_connections: i64
last_error: string

Struct QUICConnectionObservation

Non-destructive connection observation.

Fields

local_addr: string
peer_addr: string
opened_streams: i64
accepted_streams: i64
rtt_ms: i64
bytes_sent: i64
bytes_received: i64
closed: bool
last_error: string

Struct QUICStreamObservation

Non-destructive stream observation.

Fields

bytes_sent: i64
bytes_received: i64
send_closed: bool
recv_closed: bool
last_error: string

Traits

Trait QUICEndpointMethods

Methods available on a QUICEndpoint.

Methods

fn connect(self: Self, addr: string, server_name: string) -> QUICConnection

Dial a remote QUIC server.

addr is a "host:port" address; server_name is the TLS SNI name used to verify the server's certificate.

Returns an established QUICConnection or a zero-value on failure.

fn accept(self: Self) -> QUICConnection

Block until a remote peer opens an incoming connection (server side).

Returns an established QUICConnection or a zero-value on failure.

fn close(self: Self)

Close the endpoint and release all associated resources.

fn on_event(self: Self) -> QUICEvent

Block until the next queued QUIC event on this endpoint.

Events are recorded by successful connect() and accept() calls and by connection failures observed by the runtime.

fn observe(self: Self) -> QUICEndpointObservation

Return a non-destructive snapshot of endpoint state.

Trait QUICConnectionMethods

Methods available on a QUICConnection.

Methods

fn open_stream(self: Self) -> QUICStream

Open a new bidirectional stream on this connection.

Returns a QUICStream or a zero-value on failure.

fn accept_stream(self: Self) -> QUICStream

Block until the remote peer opens an incoming stream.

Returns a QUICStream or a zero-value on failure.

fn disconnect(self: Self) -> Result<(), fs.IoError>

Gracefully close this connection and release its resources.

Returns Ok(()) on success or Err(fs.IoError) on failure.

fn on_event(self: Self) -> QUICEvent

Block until the next queued QUIC event on this connection.

Events are recorded when streams open, when the peer disconnects, and when stream operations fail.

fn observe(self: Self) -> QUICConnectionObservation

Return a non-destructive snapshot of connection state and telemetry.

Trait QUICStreamMethods

Methods available on a QUICStream.

Methods

fn send(self: Self, data: bytes) -> Result<(), fs.IoError>

Send raw bytes on this stream.

Returns Ok(()) on success or Err(fs.IoError) on failure.

fn recv(self: Self) -> bytes

Block until data arrives and return the received bytes.

Returns an empty buffer on stream close or error.

fn recv_timeout(self: Self, deadline_ms: i64) -> Result<bytes, fs.IoError>

Receive bytes with a per-call deadline.

deadline_ms <= 0 disables the deadline. On deadline expiry returns Err(IoError::TimedOut(0)). On stream EOF returns Ok(empty).

fn send_timeout(self: Self, data: bytes, deadline_ms: i64) -> Result<(), fs.IoError>

Send bytes with a per-call deadline.

deadline_ms <= 0 disables the deadline. On deadline expiry returns Err(IoError::TimedOut(0)).

fn finish(self: Self) -> Result<(), fs.IoError>

Signal that no more data will be sent on this stream.

The receive side of the remote peer will see EOF after all buffered data has been delivered. This does not release the local stream handle; call close() when you are finished with the stream. Returns Ok(()) on success or Err(fs.IoError) on failure.

fn stop(self: Self, error_code: i64) -> Result<(), fs.IoError>

Abruptly stop this stream with an application-defined error code.

Unlike finish, pending data is discarded. Call close() afterwards to release the local stream handle. Returns Ok(()) on success or Err(fs.IoError) on failure.

fn close(self: Self)

Release the local stream handle.

Call finish() first if you want the peer to observe a graceful EOF.

fn send_string(self: Self, msg: string) -> Result<(), fs.IoError>

Send a UTF-8 string on this stream.

Convenience wrapper around send that converts msg to bytes first. Returns Ok(()) on success or Err(fs.IoError) on failure.

fn recv_string(self: Self) -> string

Block until data arrives and return it as a UTF-8 string.

Convenience wrapper around recv that converts the received bytes to a string. Returns an empty string on stream close or error.

fn observe(self: Self) -> QUICStreamObservation

Return a non-destructive snapshot of stream state.

Trait QUICEventMethods

Methods available on a QUICEvent.

Methods

fn kind(self: Self) -> i32

Return the event kind as an integer.

Event kinds: 0 — connected, 1 — disconnected, 2 — stream opened, 3 — stream closed, −1 — error.

fn free(self: Self)

Release the event and its resources.