Futures-based QUIC implementation in Rust

Overview

Documentation Crates.io Build status codecov Chat Chat License: MIT License: Apache 2.0

Pure-rust QUIC protocol implementation

Quinn is a pure-rust, future-based implementation of the QUIC transport protocol undergoing standardization by the IETF. This library is at draft 32.

Features

  • Simultaneous client/server operation
  • Ordered and unordered stream reads for improved performance
  • Works on stable Rust, tested on Linux, macOS and Windows
  • Pluggable cryptography, with a standard implementation backed by rustls and ring
  • Application-layer datagrams for small, unreliable messages
  • Future-based async API
  • Experimental HTTP over QUIC
  • The minimum supported Rust version is 1.45.0

Overview

  • quinn: High-level async API based on tokio, see for usage. This will be used by most developers. (Basic benchmarks are included.)
  • quinn-proto: Deterministic state machine of the protocol which performs no I/O internally and is suitable for use with custom event loops (and potentially a C or C++ API).
  • quinn-h3: Contains an implementation of HTTP-3 and QPACK. It is split internally in a deterministic state machine and a tokio-based high-level async API.
  • bench: Benchmarks without any framework.
  • interop: Tooling that helps to run interoperability tests.
  • fuzz: Fuzz tests.

Getting Started

Examples

$ cargo run --example server ./
$ cargo run --example client https://localhost:4433/Cargo.toml

This launches an HTTP 0.9 server on the loopback address serving the current working directory, with the client fetching ./Cargo.toml. By default, the server generates a self-signed certificate and stores it to disk, where the client will automatically find and trust it.

Links

Usage Notes

Click to show the notes

Buffers

A Quinn endpoint corresponds to a single UDP socket, no matter how many connections are in use. Handling high aggregate data rates on a single endpoint can require a larger UDP buffer than is configured by default in most environments. If you observe erratic latency and/or throughput over a stable network link, consider increasing the buffer sizes used. For example, you could adjust the SO_SNDBUF and SO_RCVBUF options of the UDP socket to be used before passing it in to Quinn. Note that some platforms (e.g. Linux) require elevated privileges or modified system configuration for a process to increase its UDP buffer sizes.

Certificates

By default, Quinn clients validate the cryptographic identity of servers they connect to. This prevents an active, on-path attacker from intercepting messages, but requires trusting some certificate authority. For many purposes, this can be accomplished by using certificates from Let's Encrypt for servers, and relying on the default configuration for clients.

For some cases, including peer-to-peer, trust-on-first-use, deliberately insecure applications, or any case where servers are not identified by domain name, this isn't practical. Arbitrary certificate validation logic can be implemented by enabling the dangerous_configuration feature of rustls and constructing a Quinn ClientConfig with an overridden certificate verifier by hand.

When operating your own certificate authority doesn't make sense, rcgen can be used to generate self-signed certificates on demand. To support trust-on-first-use, servers that automatically generate self-signed certificates should write their generated certificate to persistent storage and reuse it on future runs.

Contribution

All feedback welcome. Feel free to file bugs, requests for documentation and any other feedback to the issue tracker.

The quinn-proto test suite uses simulated IO for reproducibility and to avoid long sleeps in certain timing-sensitive tests. If the SSLKEYLOGFILE environment variable is set, the tests will emit UDP packets for inspection using external protocol analyzers like Wireshark, and NSS-compatible key logs for the client side of each connection will be written to the path specified in the variable.

The minimum supported Rust version for published releases of our crates will always be at least 6 months old at the time of release.

Authors

  • Dirkjan Ochtman - Project owner & founder
  • Benjamin Saunders - Project owner & founder
  • Jean-Christophe Begue - Project collaborator, author of the HTTP/3 Implementation
Issues
  • Invalid assumption about SocketAddrV{4,6} layout

    Invalid assumption about SocketAddrV{4,6} layout

    It looks like we're assuming that std::net::Ipv4 matches the libc sockaddr_in (same for IPv6), for example in https://github.com/quinn-rs/quinn/blob/main/quinn/src/platform/unix.rs#L357. However, the standard library never guaranteed this, and in fact is looking at changing this in https://github.com/rust-lang/rust/pull/78802. We should fix our usage.

    bug 
    opened by djc 32
  • New release

    New release

    This blocks libp2p-quic.

    opened by DemiMarie 28
  • Intermittent timeout with git master

    Intermittent timeout with git master

    Logs at https://gist.github.com/DemiMarie-parity/c83746d3f95f94861a446207f58e0752

    opened by Demi-Marie 26
  • Allow read_handshake to return keys.

    Allow read_handshake to return keys.

    This allows quinn-noise to work.

    opened by dvc94ch 25
  • Do not return `ReadError::Blocked` when reading from a stream in a closed connection

    Do not return `ReadError::Blocked` when reading from a stream in a closed connection

    Currently, reading from a stream in a closed connection can sometimes return Blocked, which makes no sense.

    opened by Demi-Marie 25
  • (Pie in the sky) Supporting Noise as the cryptographic protocol

    (Pie in the sky) Supporting Noise as the cryptographic protocol

    We have an internal abstraction over the cryptographic protocol used called the crypto::Session. (Note that this trait is currently private, so you'd have to make this public to start work. We'd be happy to merge that, but would likely prefer doing so when something materializes that actually uses that.)

    Currently we have a single implementation for rustls. In QUIC v1, only TLS 1.3 is officially supported, so supporting something else is technically outside of the spec and can thus probably only be made to work between two consenting endpoints.

    If we wanted to support Noise, that would likely start by writing an implementation of this thread that is based on Noise. I think there are some crates that implement (parts of) Noise -- snow probably makes for a good start.

    There was a 2018 attempt at integrating Noise support into a much earlier version of Quinn. Quinn looks basically nothing like it did at the time, but maybe there are still useful bits to look at there.

    If you want to work on this, we're usually available for questions on our Gitter channel -- just commenting in this issue should also work fine.

    help wanted 
    opened by djc 24
  • Allow connection to return peer certificates

    Allow connection to return peer certificates

    Experiment on implement libp2p-tls.

    But it need peer's certificates. I see rustls has get_peer_certificates func on Session trait. Consider add it to crypto::Session in quinn-proto and Connection in quinn.

    opened by zeroqn 21
  • Update `tokio`, `futures` and `bytes`.

    Update `tokio`, `futures` and `bytes`.

    Old postI had to put `tracing` to `0.1.9` until https://github.com/tokio-rs/mio/pull/1170 is resolved.

    Also https://github.com/carllerche/string/pull/17 and https://github.com/carllerche/string/pull/18 need to pass, but there are probably workarounds for those. This is also an option: https://github.com/carllerche/string/pull/20.

    Examples and tests aren't done yet, ~~I'm still trying to get the server <-> client example to work~~.

    Any help is appreciated!

    This updates the following:

    • tokio: 0.2.0-alpha.6 -> 0.2.2
    • futures: 0.3.0-alpha.18 -> 0.3.1
    • bytes: 0.4.7 -> 0.5.2
    • string: 0.2 -> master
    • http: a3a8fcb213bc456e0b7a42cf0e2bd57afa49851b -> 43dffa1eb79f6801e5e07f3338fa56191dc454bb

    Tests, examples and benchmarks are minimally changed to keep the PR small.

    opened by daxpedda 21
  • Relation between Connection and IncomingStreams

    Relation between Connection and IncomingStreams

    On a successful connection in either direction (i.e., either actively via connect or passively via listen) I get two things eventually - one Connection and one IncomingStreams. As a user i expect these to be related at some level since they denote a connection to the peer. However it seems that closing the connection does nothing for the IncomingStreams.

    Details:

    1. I get a Connection and IncomingStreams from a peer while I'm listening
    2. Something happens and I decide I don't want this peer any more
    3. I get the Connection object and do Connection::close(...).
    4. Nothing happens to the IncomingStreams - it continue to stay indefinitely with tokio event loop - I would have expected it to resolve to completion/failure at this point and destroy itself.
    5. Remote peer still tries to send something to us on their connection to us (Which is still alive for them) by trying to open a new stream to us. The peer keeps getting "ConnectionAborted - closed by remote peer" error which is fine and expected.

    So the IncomingStreams stream (and possibly any other stream obtained from it which the remote hasn't shutdown/closed/destroyed yet - though I haven't checked this part) uselessly remains unresolved with tokio. I have to now keep extra knowledge about closing these streams when I close the Connection to the peer.

    Wouldn't the better/expected design be that when I close Connection (or drop/destroy it) all the related stuff resolve into an error (or anything, but resolve) to gracefully collect all resources ?

    opened by ustulation 20
  • Ack improvements

    Ack improvements

    This change contains a first set of improvements to ACK handling, on the way to sending ACKs more efficiently.

    In these changes the number of ACKs is actually not yet reduced, and the previous strategies are kept. It however introduces some refactorings and prerequesites for adding ACK delay successfully:

    1. The ACK state is moved into a separate struct
    2. ACK delay is reported to peers, in order not to disturb RTT calculations in case ACK delay is applied
    3. Pending ACKs are sent with CONNECTION_CLOSE frames
    opened by Matthias247 2
  • Fails to build on FreeBSD

    Fails to build on FreeBSD

    Regressed by b681c654124d (usize) and 1bc75aa01486 (in_pktinfo)

    $ pkg install rust
    $ rustc -vV
    rustc 1.52.1
    binary: rustc
    commit-hash: unknown
    commit-date: unknown
    host: x86_64-unknown-freebsd
    release: 1.52.1
    LLVM version: 12.0.0
    
    $ cargo build
    [...]
    error[E0422]: cannot find struct, variant or union type `in_pktinfo` in crate `libc`
       --> quinn/src/platform/unix.rs:387:41
        |
    387 |                       let pktinfo = libc::in_pktinfo {
        |                                           ^^^^^^^^^^ help: a struct with a similar name exists: `in6_pktinfo`
        |
       ::: ../libc-0.2.97/src/unix/bsd/freebsdlike/mod.rs:82:1
        |
    82  | / s! {
    83  | |     pub struct in_addr {
    84  | |         pub s_addr: ::in_addr_t,
    85  | |     }
    ...   |
    346 | |     }
    347 | | }
        | |_- similarly named struct `in6_pktinfo` defined here
    
    error[E0425]: cannot find value `IP_PKTINFO` in crate `libc`
       --> quinn/src/platform/unix.rs:394:58
        |
    394 |                     encoder.push(libc::IPPROTO_IP, libc::IP_PKTINFO, pktinfo);
        |                                                          ^^^^^^^^^^ help: a constant with a similar name exists: `IPV6_PKTINFO`
        |
       ::: ../libc-0.2.97/src/unix/bsd/freebsdlike/mod.rs:919:1
        |
    919 | pub const IPV6_PKTINFO: ::c_int = 46;
        | ------------------------------------- similarly named constant `IPV6_PKTINFO` defined here
    
    error[E0531]: cannot find unit struct, unit variant or constant `IP_PKTINFO` in crate `libc`
       --> quinn/src/platform/unix.rs:454:38
        |
    454 |             (libc::IPPROTO_IP, libc::IP_PKTINFO) => unsafe {
        |                                      ^^^^^^^^^^ help: a constant with a similar name exists: `IPV6_PKTINFO`
        |
       ::: ../libc-0.2.97/src/unix/bsd/freebsdlike/mod.rs:919:1
        |
    919 | pub const IPV6_PKTINFO: ::c_int = 46;
        | ------------------------------------- similarly named constant `IPV6_PKTINFO` defined here
    
    error[E0412]: cannot find type `in_pktinfo` in crate `libc`
       --> quinn/src/platform/unix.rs:455:52
        |
    455 |                   let pktinfo = cmsg::decode::<libc::in_pktinfo>(cmsg);
        |                                                      ^^^^^^^^^^ help: a struct with a similar name exists: `in6_pktinfo`
        |
       ::: ../libc-0.2.97/src/unix/bsd/freebsdlike/mod.rs:82:1
        |
    82  | / s! {
    83  | |     pub struct in_addr {
    84  | |         pub s_addr: ::in_addr_t,
    85  | |     }
    ...   |
    346 | |     }
    347 | | }
        | |_- similarly named struct `in6_pktinfo` defined here
    
    error[E0308]: mismatched types
       --> quinn/src/platform/unix.rs:287:17
        |
    287 |                 bufs.len().min(BATCH_SIZE) as libc::c_uint,
        |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `u32`
        |
    help: you can convert a `u32` to a `usize` and panic if the converted value doesn't fit
        |
    287 |                 (bufs.len().min(BATCH_SIZE) as libc::c_uint).try_into().unwrap(),
        |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    error: aborting due to 5 previous errors
    
    Some errors have detailed explanations: E0308, E0412, E0422, E0425, E0531.
    For more information about an error, try `rustc --explain E0308`.
    error: could not compile `quinn`
    
    opened by jbeich 5
  • Support QUICv1

    Support QUICv1

    RFC 9000 is out. It specifies QUIC version 1.

    I couldn't find an issue for support of this version, and from reading the source code, it looked like it wasn't yet supported: https://github.com/quinn-rs/quinn/blob/7f1aa1ead3dc02f32e0f2be9afbe9b6ac65bfbcb/quinn-proto/src/lib.rs#L151-L153

    opened by heinrich5991 3
  • connect  quic go server wrong

    connect quic go server wrong

    I have a quic server with quic-go. server and client work in go. then I run client with quinn is wrong ,report this error failed to connect: aborted by peer: the cryptographic handshake failed: error 120 , I have load client cert pem format.

    opened by bipo123 1
  • Unbounded queues might lead to excessive memory usage

    Unbounded queues might lead to excessive memory usage

    The endpoint and per connection logic is running on individual tokio tasks. To communicate between those tasks, unbounded futures::channel::mpsc channels are used. In specific there are 2 channels:

    • One which carries endpoint events (e.g. received datagrams) from the endpoint to the connection task
    • Another one which carries connection events (e.g. produced datagrams) to the endpoint task

    The fact that these channels are unbounded raises the question on what exactly will happen if one of the tasks is producing data faster than the other task can consume it. The question probably became more important recently due to adding additional fairness between tasks: Since the endpoint task will yield more often, the connection task might have more chances to enqueue new data that can't be sent right away.

    The usual problems with this design are unbounded memory growth - and that as soon as the queue reached a certain size the components mostly work on outdated/non-interesting data, latencies will be terrible and reliability too.

    Let's briefly look at each side individually:

    Endpoint task -> Connection task

    This queue is used for forwarding received datagrams. In the connection task all received datagrams are currently immediately processed. As long as single-threaded runtime is used, the queue is not really unbounded since no new datagrams won't be enqueued by the endpoint as long as the connection is working on the existing ones. Instead if more datagrams would be enqueued in the UDP socket, they would get dropped there.

    I think this is ok for the moment.

    Connection task -> Endpoint task

    The connection produces datagrams whenever it is deemed ok by the congestion controller, and will enqueue them on the endpoint for transmission. I think this queue can get problematic in some situations. E.g. when either the connection task gets scheduled often enough between endpoint task iterations that it produces more datagrams than the endpoint can send in one iteration, or if multiple connections all have data to send.

    I don't really think that letting the endpoint task perform writes until the queue is drained would be the right solution - it would again lead to long times where the stack doesn't process either peer data (ACKs) or user data.

    I can at the moment see a variety of ways to improve this:

    1. The simplest: Use a bounded channel between the components and try_send. If the queue is full because the endpoint can't keep up, the packet will get dropped and the congestion controller will deal with it. Downsides:
      1. We spend all the CPU time for producing a packet (it's expensive!), and then just drop it
      2. Might not scale will in a scenario where an endpoint is serving a high amount of connections. There doesn't seem any fairness regarding which packets will get dropped (although one could claim random == fair?).
    2. Build some reservation system where connections can only produce packets if endpoint capacity is available. Examples:
      1. Add a single async semaphore to the connection -> endpoint channel, and let the connection try to acquire MAX_TRANSMIT_DATAGRAMS before trying to produce packets and submitting them. The permits will get released once the endpoint is done with transmissing packets. If the semaphore is fair, then all connections should be able to produce batches of packets in order.
      2. Do the same, but with one async semaphore per connection. This essentially builds a per-virtual-channel limit even though there is only one real channel. Seems a bit easier to understand since it essentially limits the amount of outgoing datagrams a single connection can have in-flight. But doesn't really limit the overall amount of outgoing packets queued in the endpoint or channel (matters more for a really high amount of connections)
    3. Restructure the whole quinn module to merge connection and endpoint tasks, and to only call poll_transmit on connections if there is really capacity to transmit packets left. That also allows the endpoint module to implement fairness between connections. This might be computationally cheaper than everything else. But it would be a huge refactoring endeavour.
    opened by Matthias247 4
  • Prevent sending of ACK-only packets

    Prevent sending of ACK-only packets

    The priority-based send state implementation had an issue where if returned self.can_send() == true even if no data was available for sending. This condition lead the poll_transmit method to initiate a transmission which passed the ACK-only check since it assumed there was stream data to send. However when trying to write stream frames no actual stream data could be written.

    The reason for this was that the can_send() condition only checked for the length of the binary heap. However the length of this one was only reduced in write_stream_frames() when the level was inspected the next time, and not after data of one level was actually written.

    This change fixes that, and drops the unused levels immediately after data was written. There is on exception however: If only one level is left, it is kept around and reused for future transmits to avoid deallocating and reallocating the transmit queue continuously. However the can_send check was updated to account for the empty level.

    I also added some additional debug asserts which cross-checks if an operation which announced to write more than just ACKs still ended up only writing ACKs. That should make it easier to determine similar issues in the future.

    Ack only transmissions in benchmark before change: 1462

    Ack only transmissions in benchmark after change: 45

    opened by Matthias247 0
  • Disable GSO after encountering EIO on send

    Disable GSO after encountering EIO on send

    Fixes #1128.

    I couldn't find a way to isolate the changes to just endpoint.rs or the UDP platform code. I'm not super happy with the global state, but I think getting rid of it would require moving UdpCapabilities into memory explicitly shared between the EndpointInner and ConnectionInner structures, which can be pursued separately.

    opened by Ralith 0
  • Fall back to disabling GSO after encountering an I/O error

    Fall back to disabling GSO after encountering an I/O error

    A report from @lu-zero revealed that Linux can erroneously advertise GSO support on systems where adapter support for GSO support (ethtool -k <interface> |grep generic-segmentation-offload) is mixed. This manifests as EIO errors from sendmmsg when the UDP_SEGMENT cmsg is set. For compatibility, when GSO is enabled, we should handle the first EIO by disabling GSO support.

    enhancement 
    opened by Ralith 0
  • Congestion window grows without bound when CPU-bound

    Congestion window grows without bound when CPU-bound

    If throughput is limited by CPU resources, then every non-app-limited transmit will, once ACKed, cause the congestion window to grow. If CPU resources abruptly increase (e.g. due to reduced contention from other tasks and/or processes) then we risk flooding the link. The congestion controller interface/implementation should be modified such that success with N in-flight bytes is interpreted as license to grow the congestion window by at most a constant multiple of N.

    bug 
    opened by Ralith 1
  • feat(cca): cubic

    feat(cca): cubic

    mostly copied from quiche, modified to fit here

    still working out the best way to get a ref to the current RTT inside the CCA

    Relates to #693

    opened by FrankSpitulski 3
Releases(0.7.0)
  • 0.7.0(Mar 2, 2021)

    We are happy to announce the release of 0.7.0 of Quinn, our pure-Rust implementation of the QUIC protocol, the next generation TCP replacement protocol currently being standardized at the IETF.

    After 10 months of development since the release of 0.6.0, we finally have a new release which upgrades the protocol to drafts 29 through 32. It has additionally received many performance improvements (especially on Linux), is much more robust, provides a number of new APIs to inspect connection state, and traits that can be used to customize behavior. Our quinn crate has been updated to depend on tokio 1.

    The focus of our HTTP/3 implementation work has shifted to the h3 crate.

    Important changes:

    • Update to Tokio 1, rustls 0.19 and bytes 1 (#873, with fixes in #995 thanks to @geieredgar)
    • Update to draft 29 with support for draft 32 (#812, #879)
    • Adopted 1.45 as the minimum supported Rust version for now (#985, #988)
    • Substantial performance improvements (many contributed by @Matthias247)
    • Work towards support for Generic Send Offload on Linux (#960 and #1024, thanks to @Matthias247)

    Functional improvements:

    • Zero-copy read and write APIs (#1013, thanks to @Matthias247, and #952)
    • Pluggable congestion control and congestion controller bugfixes (#759)
    • Add support for exporting keying material (#850, thanks to @kwantam)
    • Support customized connection ID generation (#851 and #925, thanks to @liwenjieQu)
    • Implement packet pacing support (#852, thanks to @DemiMarie)
    • Proactive connection ID rotation (#860, thanks to @liwenjieQu)
    • Add connection-level statistics (#884, #957, #973, #974; thanks to @Matthias247)
    • Expose access to round-trip time estimate (#889, thanks to @jamadazi)
    • Improve fairness on stream transmissions (#949, thanks to @Matthias247)
    • Accept certificates in PEM format (#829, thanks to @SSebo)
    • Encrypt Retry tokens (#833, thanks to @kansi)
    • Use the incoming IP address for sending outgoing packets (#967, thanks to @Matthias247)
    • Update datagram extension to support one-way semantics (#757)
    • Reduce connection task wake-ups while reading (#992, thanks to @geieredgar)
    • Improve defragmentation algorithm to reduce overhead (#1000, thanks to @geieredgar)

    Bug fixes:

    • Remove unsound assumptions about IP address layout (#987, thanks to @est31)
    • Separate ECN counters per packet space (#798)
    • Reject connections on ALPN failure (#779)
    • Deduplicate buffers when switching to unordered mode (#1014, thanks to @geieredgar)
    • Return UnknownStream from Connection::reset for closed/reset streams (#778)
    • Proactively discard data on stopped streams (#777)
    • Fix socket options on iOS (#849, thanks to @SSebo)
    • Stop issuing redundant flow control credit (#758)
    • Don't block application writes on congestion (#710)

    Other improvements:

    • Initial implementation of fuzz testing (#831 and #855, thanks to @jafow)
    • Expose some quinn-proto APIs in quinn (#809, thanks to @SoftwareSheriff)
    • Reexport ReadUnordered (#837, thanks to @Imberflur)
    • Implement Debug for TlsSession and SessionKind (#843, thanks to @imp)
    • Don't try to run code coverage on PRs (#824, thanks to @DemiMarie)

    Documentation improvements:

    • Initial version of a Quinn book (#866 and many follow-ups, thanks to @TimonPost)
    • README improvements including a new logo (#866, thanks to @TimonPost)
    • Add more high-level docs for quinn-proto Connections (#926, thanks to @infinity0)
    • Add usage documentation for server example (#732, thanks to @jesselucas)
    • Fix up documentation links (#816, thanks to @alexander-jackson)
    • Add documentation links to improve navigation (#826, thanks to @alexander-jackson)
    • Fix typo in the documentation (#847 thanks to @DelusionalOptimist and #932 thanks to @lu-zero)

    Quinn has been proven to function well in real-world scenarios, so if you're interested in QUIC, now would be a good time to start testing. The QUIC v1 spec is stabilizing; we expect it will be published as an RFC within the next month.

    While we don't always have large amounts of pre-defined good first issues setup due to the fast moving development, we're also always happy to mentor new contributors, independent of their prior level of Rust experience! We tend to respond to issues and PRs pretty quickly, and we have an active Gitter channel. Additionally @djc can now offer commercial support for Quinn, contact him for more details.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.1(Apr 4, 2020)

    quinn 0.6.1 is a maintenance release with a number of significant bug fixes:

    • Fix initial data limit for remotely initiated bidirectional streams (fixes #694)
    • Fix bug that retired active CID on duplicate NEW_CONNECTION_ID (fixes #689)
    • Fix issuing of excess CIDs
    • Fix busy-hang when tokio and proto disagree on timer expiry

    Anyone using the 0.6.0 release is advised to upgrade to this release. Thanks to @DemiMarie-parity and @SriRamanujam for providing detailed bug reports and working with us on reproduction and testing!

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0(Mar 12, 2020)

    We are happy to announce the release of 0.6.0 of Quinn, our pure-Rust implementation of the QUIC protocol, the next generation TCP replacement protocol currently being standardized at the IETF.

    After 4 months of development since the release of 0.5.0 (and several bugfix releases), we have a new release which upgrades the protocol to draft-27. It has additionally received many robustness improvements, smaller bug fixes, improved documentation and API refinements. Much of this work was triggered by the work at Parity to extend libp2p with QUIC support based on quinn-proto -- thanks to @DemiMarie-parity.

    While our quinn-h3 implementation of HTTP 3 has not yet been released to crates.io, it has also undergone significant improvements in this release cycle, focusing in particular on improving interoperability with other implementations.

    High level overview:

    • Improved API for inspecting crypto session (TLS) negotiated data (thanks to @kim)
    • Make rustls dependency optional at the quinn level
    • Refined APIs for datagrams (draft extension)
    • Cleaned up clippy warnings throughout all crates
    • Many bug fixes and improved robustness
    • Much improved documentation, particularly for the quinn-proto crate

    Thanks to @DemiMarie-parity, @alecmocatta and @lionel1704 for their contributions.

    Quinn has been proven to function well in real-world scenarios, so if you're interested in QUIC, now would be a good time to start testing. The QUIC v1 spec is stabilizing; we expect it will be published as an RFC in the next 6 months.

    While we don't always have large amounts of pre-defined good first issues setup due to the fast moving development, we're also always happy to mentor new contributors, independent of their prior level of Rust experience! We tend to respond to issues and PRs pretty quickly, and we have an active Gitter channel.

    Source code(tar.gz)
    Source code(zip)
  • quinn-0.5.3(Feb 1, 2020)

  • quinn-0.5.1(Dec 9, 2019)

    quinn 0.5.1 is a quick maintenance release to solve a single bug:

    • Wake up the connection after a datagram send completes (#553, backported in #554)

    This is only relevant if you're using the datagram extension (new in 0.5).

    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Dec 3, 2019)

    We are happy to announce the release of 0.5.0 of Quinn, our pure-Rust implementation of the QUIC protocol, the next generation TCP replacement protocol currently being standardized at the IETF.

    After 3 months of development since the release of 0.4.0, Quinn has been upgraded to the latest draft (draft 24) protocols and has been migrated to std::future::Futures and tokio 0.2. Quinn 0.5.0 is a highly conformant implementation of the latest QUIC draft, according to the interoperability testing data maintained by implementers participating in the QUIC working group.

    • Implemented preliminary support for the (draft) datagram extension
    • Migrated from slog to tracing
    • Improved documentation
    • Many smaller bug fixes and refactoring to improve Quinn's internals

    Thanks to @jean-airoldie, @NULLx76, @TimonPost, @DemiMarie-parity and @daxpedda for their contributions.

    Quinn has been proven to function well in real-world scenarios, so if you're interested in QUIC, now would be a good time to start testing. The QUIC v1 spec is stabilizing and we expect it will be published as an RFC in the next 6 months.

    While we don't always have large amounts of pre-defined good first issues setup due to the fast moving development, we're also always happy to mentor new contributors, independent of their prior level of Rust experience! We tend to respond to issues and PRs pretty quickly, and we have an active Gitter channel.

    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Sep 9, 2019)

    We are happy to announce the release of 0.4.0 of Quinn, our pure-Rust implementation of the QUIC protocol, the next generation TCP replacement protocol currently being standardized at the IETF.

    After 5 months of development since the release of 0.3.0, Quinn has been upgraded to the latest draft (draft 22) protocols. We have created a trait-based abstraction over our use of rustls and ring, so that it will be possible to use Quinn with any TLS implementation implementing these traits, or even alternative non-standard cryptographic protocols. Quinn 0.4.0 is a highly conformant implementation of the latest QUIC draft, according to the interoperability testing data maintained by implementers participating in the QUIC working group.

    • A number of improvements to the high-level API to improve usability
    • Make it possible to build lower-level quinn-proto crate without rustls/ring
    • Moved CI to Azure, which means we now test Windows in addition to Linux and macOS
    • Implement coalescing of outgoing packets, reducing handshake overhead
    • Allow connection migration to be disabled
    • Improved documentation
    • Many smaller bug fixes and refactoring to improve Quinn's internals

    Note that we plan to merge our branch using std::future::Future and async/await oriented interfaces soon after this release is published, since support for this syntax is stabilizing soon. Therefore, the next release will be designed for use with async and await; we will consider pushing out maintenance releases for 0.4 using "old" futures if there is demand.

    Quinn has been proven to function well in real-world scenarios, so if you're interested in QUIC, now would be a good time to start testing. The QUIC v1 spec is stabilizing and we expect it will be published as an RFC in the next 6 months.

    While we don't always have large amounts of pre-defined good first issues setup due to the fast moving development, we're also always happy to mentor new contributors, independent of their prior level of Rust experience! We tend to respond to issues and PRs pretty quickly, and we have an active Gitter channel.

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Apr 18, 2019)

    We are happy to announce the release of 0.3.0 of Quinn, our pure-Rust implementation of the QUIC protocol, the next generation TCP replacement protocol currently being standardized at the IETF.

    After 3 months of development since the release of 0.2.0, 0.3.0 is starting to see some real-world use. Quinn 0.3.0 is a highly conformant implementations of the latest QUIC draft (draft 19), according to the interoperability testing data maintained by implementers participating in the QUIC working group.

    • High-level API types are now Send and Sync for use on multi-threaded runtimes
    • Extensive refactoring to make the code more maintainable and approachable
    • Improved documentation for low-level quinn-proto crate
    • Updated protocol support to draft 19
    • 0-RTT data exchange is now supported
    • Fixed some QUIC-specific issues in rustls (thanks to @ctz for reviewing)
    • QPACK and partial HTTP 3 support has been implemented, but is unreleased for now
    • Work started to abstract the use of rustls to enable use of other TLS implementations
    • Initial benchmarks show 1+ Gbps, with lots of low-hanging optimization fruit still left
    • Example code for different use cases (thanks to @povilasb)
    • Worked around a networking regression (login only) in macOS 10.14

    At this point, we expect the high-level API to only change in minor ways and Quinn has been proven to function well in real-world scenarios (see below), so if you're interested in QUIC, now would be a good time to start testing. The QUIC v1 spec is scheduled to be published as an RFC some time this summer.

    We're grateful for the work @ustulation, @nbaksalyar and @povilasb from @MaidSafe have contributed to this release. @MaidSafe has replaced their internally developed UDP-based protocol with QUIC and Quinn, and in the process contributed a number of bugfixes, added examples and tests. Thanks also to @newpavlov for their contributions. We're happy that @stammw joined the Quinn team as main author of our unreleased quinn-h3 crate.

    While we don't always have large amounts of pre-defined good first issues setup due to the fast moving development, we're also always happy to mentor new contributors, independent of their prior level of Rust experience! We tend to respond to issues and PRs pretty quickly, and we have an active Gitter channel.

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Jan 21, 2019)

    We (@djc and @Ralith) are happy to announce the release of 0.2.0 of Quinn, our pure-Rust implementation of the QUIC protocol, the next generation TCP replacement protocol currently being standardized at the IETF.

    After 3 months of development since the release of 0.1.0, 0.2.0 is much more complete. First and foremost, Quinn 0.2.0 is among the most conformant implementations of the latest QUIC draft (draft 17), according to the interoperability testing data maintained by implementers participating in the QUIC working group. It now supports:

    • Stateless retries
    • Explicit congestion notification (only Linux support so far -- contributions welcome!)
    • Connection migration

    These features are currently being worked on:

    • 0-RTT data has largely been implemented but still needs tweaking of the API
    • HTTP 3 support has been started and is being worked on by our awesome contributor @stammw

    We've worked to make Quinn even more modular. It consists of the quinn-proto crate, which contains deterministic protocol logic without touching any I/O APIs, and a quinn crate which leverages tokio to deliver a high-level asynchronous API. (Additionally, we maintain an experimental branch with async/await support.)

    We're also grateful for the work @imp, @est31, @psiphi75, and @kryptan have contributed to this release. While we don't always have large amounts of pre-defined good first issues setup due to the fast moving development, we're always happy to mentor new contributors, independent of their prior level of Rust experience!

    Finally, we would like to thank the community for their support. To support this release, we've contributed work to libc, tokio, rustls and ring. We'd also like to call out @est31's new rcgen crate, which makes self-signed certificate support easier to use. Quinn would not be possible without the support of the Rust ecosystem.

    We're excited to see what's coming for QUIC and Quinn in 2019.

    Source code(tar.gz)
    Source code(zip)
Futures-based QUIC implementation in Rust

Pure-rust QUIC protocol implementation Quinn is a pure-rust, future-based implementation of the QUIC transport protocol undergoing standardization by

null 1.6k Jun 13, 2021
Futures implementation for JSON-RPC

futures-jsonrpc Futures + JSON-RPC A lightweight remote procedure call protocol. It is designed to be simple! And, with futures, even more flexible! T

Victor Lopes 14 Jan 10, 2021
neqo — an Implementation of QUIC written in Rust

Neqo, an Implementation of QUIC written in Rust To run test HTTP/3 programs (neqo-client and neqo-server): cargo build ./target/debug/neqo-server [::]

Mozilla 1.2k Jun 15, 2021
Network simulation in Rust

netsim - A Rust library for network simulation and testing (currently linux-only). netsim is a crate for simulating networks for the sake of testing n

Andrew Cann 83 Jun 3, 2021
Actor framework for Rust.

Actix Actor framework for Rust Documentation User Guide API Documentation API Documentation (master branch) Features Async and sync actors Actor commu

Actix 6.4k Jun 11, 2021
Docker daemon API in Rust

Bollard: an asynchronous rust client library for the docker API Bollard leverages the latest Hyper and Tokio improvements for an asynchronous API cont

Niel Drummond 204 May 20, 2021
The gRPC library for Rust built on C Core library and futures

gRPC-rs gRPC-rs is a Rust wrapper of gRPC Core. gRPC is a high performance, open source universal RPC framework that puts mobile and HTTP/2 first. Sta

TiKV Project 1.4k Jun 12, 2021
Backroll is a pure Rust implementation of GGPO rollback networking library.

backroll-rs Backroll is a pure Rust implementation of GGPO rollback networking library. Development Status This is still in an untested alpha stage. A

Hourai Teahouse 80 Jun 13, 2021
A working demo of RustDesk server implementation

A working demo of RustDesk server implementation This is a super simple working demo implementation with only one relay connection allowed, without NA

RustDesk 34 Jun 12, 2021
The Rust Implementation of libp2p networking stack.

Central repository for work on libp2p This repository is the central place for Rust development of the libp2p spec. Warning: While we are trying our b

libp2p 1.8k Jun 13, 2021
Cross-platform, low level networking using the Rust programming language.

libpnet Linux ∪ OS X Build Status: Windows Build Status: Discussion and support: #libpnet on freenode / #rust-networking on irc.mozilla.org / #rust on

null 1.4k Jun 11, 2021
A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...

Tokio A runtime for writing reliable, asynchronous, and slim applications with the Rust programming language. It is: Fast: Tokio's zero-cost abstracti

Tokio 12.3k Jun 14, 2021
BLEZ - Asynchronous Bluetooth Low Energy on Linux for Rust

BLEZ - Asynchronous Bluetooth Low Energy on Linux for Rust This library provides an asynchronous, fully featured interface to the Bluetooth Low Energy

Sebastian Urban 35 Jun 13, 2021
A µTP (Micro/uTorrent Transport Library) library implemented in Rust

rust-utp A Micro Transport Protocol library implemented in Rust. API documentation Overview The Micro Transport Protocol is a reliable transport proto

Ricardo Martins 118 May 29, 2021