quiche 0.1.0-alpha2
-----BEGIN PGP SIGNATURE-----

iQJKBAABCgA0FiEEBsId305pBx+F583DbwzL4CFiRygFAlxJ6EkWHGFsZXNzYW5k
cm9AZ2hlZGluaS5tZQAKCRBvDMvgIWJHKGadD/wMGdwOOfDKD/1VgPAqUxNNWXlF
Ekt++Y1zBau0lIwxmZWWXF/a68FqzAQgzV9wUv1s5xiQRsRyMX6jZH9EfQHl22cA
vC6R/zW8gHzu8CQWqjlTkCHHQLbojy0HOq7K63xbFPWXxA7NNfFq5u+od7DNdr12
nKUazdShS6ZPNrSJ3Pe3d/mGngQhiUafgbXGyns9VJcOBetVv+2u2atY3HEAXEvV
YDTE0EoOoOkrQ/6Akz+D6EDDSky84/aJEA4UCax3gZtaBP7YqABAVc07m0fZVTCY
SG7dOKGiWu/XfcwGyH6hlsMfKYmJeUeJ8dG0lE4ydKL3CUhoo8npnD5y12+WmDWx
upGKlqbsNoj6NN6gPCyhcyjeeIBHxZG9vaOjFjzlKCWB7rpygGypZkD/M1z3mtcr
SKduBmwaUl4YgdlMhJ5TT8l5kga3mLgQkDcQioko0S1LBWmBKzVoVJDXCcTeNsCz
nksisYS0ibLkaNpTpLETPL7zWk9xLuxl+1O9c+zVN4mzmqeluumJ56mpaa6zjQpE
Oe/4ftXFf+nUNQ3z+NJBD7KRS1JHb4RuVlvBJM8yZcbexRcr3x+OQNcT/oc4ndQk
cOHLy0L4J/5gdtFhG5TYPQ2Z9OkFDlUvK+kKMapMHEfKI83TrKEwhupiPH59w0e8
+g4JK99h0nOsGmcpzw==
=yDAu
-----END PGP SIGNATURE-----
0.1.0-alpha2
1 file changed
tree: 7669912d48d630c36a160e843ba65fb874d411ab
  1. .gitignore
  2. .gitmodules
  3. .travis.yml
  4. CODEOWNERS
  5. COPYING
  6. Cargo.toml
  7. README.md
  8. deps/
  9. examples/
  10. include/
  11. quiche.svg
  12. src/
README.md

quiche

crates.io build license

quiche is an implementation of the QUIC transport protocol 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.

A live QUIC server based on quiche is available at https://quic.tech:4433/ to be used for experimentation.

Note that it is very experimental and unstable software, and many features are still in development.

For more information on how quiche came about and some insights into its design you can read a post on Cloudflare's (where this library is used in production) blog that goes into some more detail.

Status

  • [x] QUIC draft-17
  • [x] Version Negotiation
  • [x] TLS 1.3 handshake (using BoringSSL)
  • [x] Stream API
  • [x] Flow control
  • [x] Connection close
  • [x] Loss detection and recovery
  • [x] Congestion control
  • [ ] Key update
  • [x] Stateless retry
  • [x] Unidirectional streams
  • [ ] Session resumption
  • [ ] 0-RTT
  • [ ] Stateless reset
  • [ ] Connection migration

Getting Started

The first step in establishing a QUIC connection using quiche is creating a configuration object:

let config = quiche::Config::new(quiche::VERSION_DRAFT17).unwrap();

This is shared among multiple connections and can be used to configure a QUIC endpoint.

Now a connection can be created, for clients the connect() utility function can be used, while accept() is for servers:

// Client connection.
let conn = quiche::connect(Some(&server_name), &scid, &mut config).unwrap();

// Server connection.
let conn = quiche::accept(&scid, None, &mut config).unwrap();

Using the connection's recv() method the application can process incoming packets from the network that belong to that connection:

let read = socket.recv(&mut buf).unwrap();

let read = match conn.recv(&mut buf[..read]) {
    Ok(v)  => v,

    Err(quiche::Error::Done) => {
        // Done reading.
        # return;
    },

    Err(e) => {
        // An error occurred, handle it.
        # return;
    },
};

Outgoing packet are generated using the connection's send() method instead:

let write = match conn.send(&mut out) {
    Ok(v) => v,

    Err(quiche::Error::Done) => {
        // Done writing.
        # return;
    },

    Err(e) => {
        // An error occurred, handle it.
        # return;
    },
};

socket.send(&out[..write]).unwrap();

When packets are sent, the application is responsible for maintainig 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, do something.
conn.on_timeout();

let write = match conn.send(&mut out) {
    Ok(v) => v,

    Err(quiche::Error::Done) => {
        // Done writing.
        # return;
    },

    Err(e) => {
        // An error occurred, handle it.
        # return;
    },
};

socket.send(&out[..write]).unwrap();

After some back and forth, the connection will complete its handshake and will be ready for sending or receiving application data:

if conn.is_established() {
    // Handshake completed, send some data on stream 0.
    conn.stream_send(0, b"hello", true);
}

Have a look at the examples/ directory for more complete examples on how to use the quiche API, including examples on how to use quiche in C/C++ applications (see below for more information).

Calling quiche from C/C++

quiche exposes a thin C API on top of the Rust API that can be used to more easily integrate quiche into C/C++ applications (as well as in other languages that allow calling C APIs via some form of FFI). The C API follows the same design of the Rust one, modulo the constraints imposed by the C language itself.

When running cargo build, a static library called libquiche.a will be built automatically alongside the Rust one. This is fully stand-alone and can be linked directly into C/C++ applications.

Building

The first step after cloning the git repo is updating the git submodules:

 $ git submodule update --init

You can now build quiche using cargo:

 $ cargo build --examples

As well as run its tests:

 $ cargo test

Note that BoringSSL, used to implement QUIC's cryptographic handshake based on TLS, needs to be built and linked to quiche. This is done automatically when building quiche using cargo, but requires the cmake and go commands to be available during the build process.

In alternative you can use your own custom build of BoringSSL by configuring the BoringSSL directory with the QUICHE_BSSL_PATH environment variable:

 $ QUICHE_BSSL_PATH="/path/to/boringssl" cargo build --examples

Copyright

Copyright (C) 2018, Cloudflare, Inc.

Copyright (C) 2018, Alessandro Ghedini

See COPYING for the license.