glquic
QUIC connections, listeners and streams, built on erlang_quic.
Each connection sends its events, including those of all its streams, as
messages to the process that owns it: the process that connected, or the
one a listener’s handler returned, until ownership is transferred with
transfer_connection. Receive them with receive, or add them to a
selector with select.
import glquic
pub fn main() {
let options = glquic.client_options(alpn: ["echo"])
let assert Ok(connection) =
glquic.connect(to: "localhost", on: 4433, with: options, timeout: 5000)
let assert Ok(stream) = glquic.open_stream(connection)
let assert Ok(Nil) = glquic.send_and_finish(stream, <<"Hello, Joe!">>)
let assert Ok(glquic.Data(data: <<"Hello, Joe!">>, ..)) = glquic.receive(5000)
}
Types
A local or remote socket address.
pub type Address {
Address(host: String, port: Int)
}
Constructors
-
Address(host: String, port: Int)
Why a connection closed.
pub type CloseReason {
ClosedLocally(error_code: Int)
ClosedByPeer(error_code: Int)
PeerTransportError(error_code: Int, reason: String)
IdleTimeout
CertificateInvalid(reason: String)
NoApplicationProtocol
OtherReason(reason: String)
}
Constructors
-
ClosedLocally(error_code: Int)This side closed the connection with an application error code.
-
ClosedByPeer(error_code: Int)The peer closed the connection with an application error code.
-
PeerTransportError(error_code: Int, reason: String)The peer closed the connection with a transport or TLS error code, for example when no application protocol (ALPN) matched.
-
IdleTimeoutNothing was received within the idle timeout.
-
CertificateInvalid(reason: String)The peer’s certificate could not be verified.
-
NoApplicationProtocolThe server accepted none of the client’s application protocols (ALPN).
-
OtherReason(reason: String)A reason not covered by the other variants, formatted as Erlang.
A QUIC connection to a peer.
pub type Connection
Errors returned by QUIC operations.
pub type Error {
Timeout
Closed
HandshakeFailed(reason: CloseReason)
NotConnected
UnknownStream
StreamClosed
StreamLimitReached
SendQueueFull
DatagramsNotSupported
DatagramTooLarge
CongestionLimited
AddressInUse
NotFound
CertificateError(String)
Other(String)
}
Constructors
-
TimeoutThe operation did not finish in time.
-
ClosedThe connection has closed.
-
HandshakeFailed(reason: CloseReason)The connection closed before its handshake completed.
-
NotConnectedThe connection has not completed its handshake.
-
UnknownStreamThe connection has no stream with this ID.
-
StreamClosedThe stream has already been closed.
-
StreamLimitReachedThe peer does not allow any more streams to be opened yet.
-
SendQueueFullThe connection’s send queue is full and nothing was sent. Try again once it drains, for example after
notify_when_send_ready. -
DatagramsNotSupportedThe peer has not enabled datagrams.
-
DatagramTooLargeThe datagram is larger than the peer accepts.
-
CongestionLimitedThe datagram was dropped by congestion control.
-
AddressInUseThe UDP port is already in use.
-
NotFoundThe listener does not exist.
-
CertificateError(String)A certificate or private key file could not be read.
-
Other(String)An error not covered by the other variants, formatted as Erlang.
An event sent to the owner of a connection.
pub type Event {
Connected(connection: Connection)
NewStream(stream: Stream, unidirectional: Bool)
Data(stream: Stream, data: BitArray, fin: Bool)
StreamReset(stream: Stream, error_code: Int)
StopSending(stream: Stream, error_code: Int)
Datagram(connection: Connection, data: BitArray)
SendReady(connection: Connection)
TransportError(
connection: Connection,
error_code: Int,
reason: String,
)
ConnectionClosed(connection: Connection, reason: CloseReason)
Unknown(message: dynamic.Dynamic)
}
Constructors
-
Connected(connection: Connection)A connection completed its handshake.
-
NewStream(stream: Stream, unidirectional: Bool)The peer opened a stream.
-
Data(stream: Stream, data: BitArray, fin: Bool)Data was received on a stream.
finis true for the last data the peer will send on it. -
StreamReset(stream: Stream, error_code: Int)The peer abruptly stopped sending on a stream.
-
StopSending(stream: Stream, error_code: Int)The peer asked this side to stop sending on a stream.
-
Datagram(connection: Connection, data: BitArray)A datagram was received on a connection.
-
SendReady(connection: Connection)The connection’s send queue has drained after
notify_when_send_ready. -
TransportError( connection: Connection, error_code: Int, reason: String, )A connection hit a transport error.
-
ConnectionClosed(connection: Connection, reason: CloseReason)A connection closed.
-
Unknown(message: dynamic.Dynamic)A
quicmessage this library does not decode.
How a stream gives the peer credit to send more data.
pub type FlowControl {
Automatic
Manual
}
Constructors
-
AutomaticGive credit as data is delivered to the owner, as long as the owner’s mailbox is not backed up.
-
ManualOnly give credit for data returned with
consume.
A stream within a connection, identified by its QUIC stream ID.
pub type Stream {
Stream(connection: Connection, id: Int)
}
Constructors
-
Stream(connection: Connection, id: Int)
Values
pub fn ca_certificate(
options: Options(Client),
path: String,
) -> Options(Client)
Verify the server certificate against the CA certificates in a PEM file.
pub fn client_certificate(
options: Options(Client),
certificate certificate: String,
private_key private_key: String,
) -> Options(Client)
Present a PEM certificate and private key to the server.
pub fn client_options(alpn alpn: List(String)) -> Options(Client)
Options for connecting with the given application protocols (ALPN).
The server certificate is verified against the system certificate store,
or the file set with ca_certificate.
pub fn close(
connection: Connection,
error_code: Int,
) -> Result(Nil, Error)
Close a connection, sending the peer an application error code. The
owner receives ConnectionClosed when it is done.
pub fn close_listener(listener: Listener) -> Result(Nil, Error)
Stop a listener, closing the connections it accepted.
pub fn connect(
to host: String,
on port: Int,
with options: Options(Client),
timeout timeout: Int,
) -> Result(Connection, Error)
Connect to a server, waiting up to timeout milliseconds for the
handshake. The calling process owns the connection.
pub fn consume(stream: Stream, bytes: Int) -> Result(Nil, Error)
Give the peer credit for this many bytes of processed data on a stream
with Manual flow control.
pub fn datagrams(
options: Options(side),
enabled: Bool,
) -> Options(side)
Allow the peer to send datagrams.
pub fn finish(stream: Stream) -> Result(Nil, Error)
Finish sending on a stream. The peer receives the end of the stream after any data already sent.
pub fn idle_timeout(
options: Options(side),
milliseconds: Int,
) -> Options(side)
Close the connection after this many milliseconds without activity. Defaults to 30 seconds.
pub fn insecure_skip_verify(
options: Options(Client),
) -> Options(Client)
Skip verifying the server certificate. Only use this for testing.
pub fn keep_alive_interval(
options: Options(side),
milliseconds: Int,
) -> Options(side)
Send a keep-alive packet after this many milliseconds without activity, at least 5000.
pub fn listen(
on port: Int,
with options: Options(Server),
handler handler: fn(Connection) -> process.Pid,
) -> Result(Listener, Error)
Start listening on a UDP port. Use port 0 to pick any free port, and
listener_address to find out which.
handler is called with each new connection before its handshake, and
returns the process that will own it, for example one it spawns to
handle the connection. It runs in the listener’s process, so it should
return quickly. A connection closes when its owner exits.
pub fn listener_address(
listener: Listener,
) -> Result(Address, Error)
The address a listener is bound to.
pub fn local_address(
connection: Connection,
) -> Result(Address, Error)
The local address of a connection.
pub fn max_peer_bidirectional_streams(
options: Options(side),
count: Int,
) -> Options(side)
How many bidirectional streams the peer may have open at a time. Defaults to 100.
pub fn max_peer_unidirectional_streams(
options: Options(side),
count: Int,
) -> Options(side)
How many unidirectional streams the peer may have open at a time. Defaults to 100.
pub fn negotiated_protocol(
connection: Connection,
) -> Result(String, Error)
The application protocol (ALPN) both sides agreed on.
pub fn notify_when_send_ready(
connection: Connection,
) -> Result(Nil, Error)
Send the owner SendReady once the connection’s send queue has drained,
for example after a send fails with SendQueueFull.
pub fn open_stream(
connection: Connection,
) -> Result(Stream, Error)
Open a bidirectional stream.
pub fn open_unidirectional_stream(
connection: Connection,
) -> Result(Stream, Error)
Open a stream that only this side can send on.
pub fn peer_address(
connection: Connection,
) -> Result(Address, Error)
The remote address of a connection.
pub fn raw_option(
options: Options(side),
name: String,
value: dynamic.Dynamic,
) -> Options(side)
Set an erlang_quic option that has no function of its own. See the
options of quic:connect/4 and quic:start_server/3 for what is
available.
pub fn receive(within timeout: Int) -> Result(Event, Nil)
Wait up to timeout milliseconds for a QUIC event.
pub fn require_client_certificate(
options: Options(Server),
ca_certificate path: String,
) -> Options(Server)
Require clients to present a certificate signed by a CA in a PEM file.
pub fn reset(
stream: Stream,
error_code: Int,
) -> Result(Nil, Error)
Abruptly stop sending on a stream, sending the peer an application error code.
pub fn select(
selector: process.Selector(message),
mapping: fn(Event) -> message,
) -> process.Selector(message)
Add a handler for QUIC events to a selector.
pub fn send_and_finish(
stream: Stream,
data: BitArray,
) -> Result(Nil, Error)
Send data on a stream and finish sending on it.
pub fn send_datagram(
connection: Connection,
data: BitArray,
) -> Result(Nil, Error)
Send an unreliable datagram. The peer must have enabled datagrams.
pub fn server_options(
alpn alpn: List(String),
certificate certificate: String,
private_key private_key: String,
) -> Options(Server)
Options for listening with the given application protocols (ALPN) and a PEM certificate and private key. The certificate file may also hold the rest of its chain.
Client certificates are not requested unless require_client_certificate
is set.
pub fn set_flow_control(
stream: Stream,
mode: FlowControl,
) -> Result(Nil, Error)
Change how a stream gives the peer credit to send more data, for example to apply backpressure while data is processed elsewhere.
pub fn stop_sending(
stream: Stream,
error_code: Int,
) -> Result(Nil, Error)
Ask the peer to stop sending on a stream, with an application error code.
pub fn transfer_connection(
connection: Connection,
to owner: process.Pid,
) -> Result(Nil, Error)
Make another process the owner of a connection, so it receives the
events of the connection and all its streams. A connected connection
sends the new owner Connected.
Events already sent to the old owner stay in its mailbox, so prefer returning the final owner from a listener’s handler.