[−][src]Crate quiche
🥧 Savoury implementation of the QUIC transport protocol and HTTP/3.
quiche is an implementation of the QUIC transport protocol and HTTP/3 as specified by the IETF. It provides a low level API for processing QUIC packets and handling connection state. The application is responsible for providing I/O (e.g. sockets handling) as well as an event loop with support for timers.
Connection setup
The first step in establishing a QUIC connection using quiche is creating a configuration object:
let config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
This is shared among multiple connections and can be used to configure a QUIC endpoint.
On the client-side the connect()
utility function can be used to create
a new connection, while accept()
is for servers:
// Client connection. let conn = quiche::connect(Some(&server_name), &scid, &mut config)?; // Server connection. let conn = quiche::accept(&scid, None, &mut config)?;
Handling incoming packets
Using the connection's recv()
method the application can process
incoming packets that belong to that connection from the network:
loop { let read = socket.recv(&mut buf).unwrap(); let read = match conn.recv(&mut buf[..read]) { Ok(v) => v, Err(quiche::Error::Done) => { // Done reading. break; }, Err(e) => { // An error occurred, handle it. break; }, }; }
Generating outgoing packets
Outgoing packet are generated using the connection's send()
method
instead:
loop { let write = match conn.send(&mut out) { Ok(v) => v, Err(quiche::Error::Done) => { // Done writing. break; }, Err(e) => { // An error occurred, handle it. break; }, }; socket.send(&out[..write]).unwrap(); }
When packets are sent, the application is responsible for maintaining a
timer to react to time-based connection events. The timer expiration can be
obtained using the connection's timeout()
method.
let timeout = conn.timeout();
The application is responsible for providing a timer implementation, which
can be specific to the operating system or networking framework used. When
a timer expires, the connection's on_timeout()
method should be called,
after which additional packets might need to be sent on the network:
// Timeout expired, handle it. conn.on_timeout(); // Send more packets as needed after timeout. loop { let write = match conn.send(&mut out) { Ok(v) => v, Err(quiche::Error::Done) => { // Done writing. break; }, Err(e) => { // An error occurred, handle it. break; }, }; socket.send(&out[..write]).unwrap(); }
Sending and receiving stream data
After some back and forth, the connection will complete its handshake and will be ready for sending or receiving application data.
Data can be sent on a stream by using the stream_send()
method:
if conn.is_established() { // Handshake completed, send some data on stream 0. conn.stream_send(0, b"hello", true)?; }
The application can check whether there are any readable streams by using
the connection's readable()
method, which returns an iterator over all
the streams that have outstanding data to read.
The stream_recv()
method can then be used to retrieve the application
data from the readable stream:
if conn.is_established() { // Iterate over readable streams. for stream_id in conn.readable() { // Stream is readable, read until there's no more data. while let Ok((read, fin)) = conn.stream_recv(stream_id, &mut buf) { println!("Got {} bytes on stream {}", read, stream_id); } } }
HTTP/3
The quiche HTTP/3 module provides a high level API for sending and receiving HTTP requests and responses on top of the QUIC transport protocol.
Modules
h3 | HTTP/3 wire protocol and QPACK implementation. |
Structs
Config | Stores configuration shared between multiple connections. |
Connection | A QUIC connection. |
Header | A QUIC packet's header. |
Stats | Statistics about the connection. |
StreamIter | An iterator over QUIC streams. |
Enums
Error | A QUIC error. |
Shutdown | The stream's side to shutdown. |
Type | QUIC packet type. |
Constants
MAX_CONN_ID_LEN | The maximum length of a connection ID. |
MIN_CLIENT_INITIAL_LEN | The minimum length of Initial packets sent by a client. |
PROTOCOL_VERSION | The current QUIC wire version. |
Functions
accept | Creates a new server-side connection. |
connect | Creates a new client-side connection. |
negotiate_version | Writes a version negotiation packet. |
retry | Writes a stateless retry packet. |
version_is_supported | Returns true if the given protocol version is supported. |
Type Definitions
Result | A specialized |