A year after the release of 0.10.0 of Quinn, our popular community-oriented pure-Rust implementation of QUIC, we have a slew of improvements. The highlights are an upgrade to rustls 0.23 and ring 0.17 (which unfortunately got delayed by incompatibilities introduced in the rustls 0.22), a new API to triage incoming connections and a number of performance improvements. The quinn-udp crate has seen a lot of improvements, including much improved Windows support.
We've recently started an OpenCollective account which we hope commercial organizations relying on Quinn will donate to in order to support ongoing development and maintenance of the project. Since the previous major release, we've also started a Discord channel which has become the preferred (synchronous/ephemeral) communication channel for the project.
This release supports Rust 1.66 and newer.
Thanks to all contributors on behalf of the Quinn team, @Ralith and @djc!
Notable changes
- Update rustls to 0.23 and ring to 0.17 by @djc in #1715
- Allow app to accept/reject/retry before handshake begins by @gretchenfrage in #1752
- Implement acknowledgement frequency by @aochagavia in #1553
- Replace rustls-native-certs with rustls-platform-verifier by @Ralith in #1734
- Support
smol
runtime by @al8n in #1719
Performance
- Transmit directly from connection tasks by @Ralith in #1729
- #729: proto: write outgoing packets to caller-supplied memory by @lmpn in #1697
- udp: add support for ECN, local addrs, GSO, and GRO on Windows by @stormshield-damiend in #1701
- Don't allocate an endpoint response buffer for every driver wakeup by @Ralith in #1730
- Defer initial packet payload decryption until after accept by @Ralith in #1804
- Perform early first-packet validation before decryption by @Ralith in #1789
- Allocate Incoming response buffers as needed by @Ralith in #1811
- Match GSO segment size to the first datagram, not the MTU by @Ralith in #1837
Features
- preferred address by @devsnek in #1816
- add Connection::send_datagram_wait by @devsnek in #1740
- Look up the time through trait Runtime by @Ralith in #1839
- Make SendStream::finish synchronous by @Ralith in #1840
Fixes
- Use boxed AsyncUdpSocket when creating abstract endpoint by @tthebst in #1595
- fix: Make new_with_abstract public again by @tthebst in #1596
- Preserve the tracing span in the EndpointDriver task by @flub in #1616
- Mitigate optimistic ACK attacks by @Ralith in #1613
- set may_fragment based on whether setting IP_DONTFRAG fails with ENOPROTOOPT. by @jieliangma in #1626
- udp: don't log EMSGSIZE errors by @Ralith in #1635
- Propagate current tracing span to spawned connection drivers by @Ralith in #1632
- proto: Fix double-boxing of congestion::ControllerFactory by @Ralith in #1641
- proto: don't panic when draining an unknown connection by @Ralith in #1645
- Require explicit timestamp for Endpoint::connect(), Rust 1.72 by @djc in #1649
- Add missing export for proto::AckFrequencyConfig. by @stormshield-damiend in #1651
- silent an info message related to ack frequency. by @stormshield-damiend in #1652
- Generalize UdpStats::transmits to ios by @Ralith in #1655
- Send ACK_FREQUENCY frames intelligently rather than spamming IMMEDIATE_ACK by @Ralith in #1656
- Pass byte read count to FinishEarly by @rom1v in #1666
- Fix ACK frequency extension corner case by @Ralith in #1672
- Yield protocol violation for packets without frames by @djc in #1693
- Make
quinn-proto::{Connection, Endpoint}
deterministic by @michael-yxchen in #1691 - proto: add a way to configure the minimum MTU change needed to stop the binary search used during the MTU discovery phase. by @stormshield-damiend in #1702
- Validate 0-RTT frames based on packet type, not handshake progress by @Ralith in #1722
- proto: yield transport error for Initial packets with no CRYPTO by @djc in #1721
- Send path validation responses to the correct remote by @Ralith in #1746
- fix(quinn-udp): use TOS for IPv4-mapped IPv6 dst addrs by @mxinden in #1765
- Improve reliability of Close delivery during handshakes by @Ralith in #1767
- Don't double-count buffer consumption in close length checks by @Ralith in #1768
- Improve behavior when only one peer sends ACK-eliciting packets by @Ralith in #1761
- Fix constant of frame_type IMMEDIATE_ACK by @nemethf in #1774
- Bound memory use in RETIRE_CONNECTION_ID frame queue by @Ralith in #1787
- Add missing transport parameter validation checks by @Ralith in #1791
- Rate-limit stateless resets by @Ralith in #1794
- Use the correct MTU for prev_path by @nemethf in #1776
- Break linkability on client-side after planned migration by @nemethf in #1800
- Allow packets with impossible CIDs to be ignored rather than reset by @Ralith in #1796
- Make
quinn_proto::Connection
andquinn_proto::Endpoint
implSync
by @Pixelstormer in #1769 - Refuse incoming/forbid outgoing connections after endpoint is closed by @Ralith in #1829
- Socket rebind: drain old socket by @nemethf in #1801
- Accept connections with unrecognized address validation tokens by @Ralith in #1790
- Fix race condition between 0-RTT and Incoming by @gretchenfrage in #1821
- Fix minor datagram send bugs by @Ralith in #1836
Miscellaneous
- Perform a key update early in a connection's lifetime by @Ralith in #1614
- Fix some typos by @striezel in #1570
- Update actions/checkout in GitHub Actions workflows to v3 by @striezel in #1571
- Allow compilation with
--cfg fuzzing
but not--features=arbitrary
by @smoelius in #1574 - Docs: Use fullchain.pem in the certbot example by @DontBreakAlex in #1577
- Extend Dependabot configuration to keep GitHub Actions up to date by @striezel in #1580
- Replace unmaintained actions-rs/* actions in CI workflows by @striezel in #1579
- Miscellaneous cleanup by @Ralith in #1581
- Update obsolete doc comment by @Ralith in #1582
- Update rcgen requirement from 0.10.0 to 0.11.1 by @dependabot in #1590
- Update README.md to say "see examples for usage" with link by @kettle11 in #1594
- Reexport rustls types by @jonatanzeidler in #1600
- Update docs for UDP fragmentation configuration support by @Ralith in #1599
- Fold UdpState into AsyncUdpSocket by @Ralith in #1612
- Bump Swatinem/rust-cache from 1 to 2 by @dependabot in #1623
- Privatize TransportParameters::default() by @Ralith in #1627
- udp: simplify socket state initialization by @djc in #1629
- udp: use set_socket_option_supported() wrapper by @djc in #1633
- Add docs for RecvMeta by @flub in #1634
- Deflake ACK tests by @Ralith in #1639
- Replace Gitter link with Discord by @djc in #1643
- Minor bulk benchmark improvements by @Ralith in #1657
- Bump actions/checkout from 3 to 4 by @dependabot in #1658
- Implement
Debug
forIdleTimeout
. by @vvvviiv in #1690 - Update async-io requirement from 1.6 to 2.0 by @dependabot in #1696
- ensure LICENSE files are present in all published crates by @decathorpe in #1698
- Update docs for
Connection::accept_bi()
andConnection::open_bi()
by @rickvanprim in #1708 - Bump vmactions/freebsd-vm from 0 to 1 by @dependabot in #1709
- Run FreeBSD workflow on Ubuntu by @djc in #1710
- Update windows-sys requirement from 0.48.0 to 0.52.0 by @dependabot in #1711
- Remove "max_tlps" configuration variable by @link2xt in #1713
- Test UDP layer in isolation by @Ralith in #1731
- udp: use io::Result<> where possible by @stormshield-damiend in #1736
- udp: Expand crate documentation by @Ralith in #1741
- Document two more commonly-observed mistakes in
RecvStream
use by @Ralith in #1743 - Fix parsing of IPV6 URLs in client example by @gretchenfrage in #1745
- build(deps): bump codecov/codecov-action from 3 to 4 by @dependabot in #1753
- Document cancel-safety of stream I/O operations by @Ralith in #1764
- Maintain in-flight counters separately per path by @Ralith in #1777
- Enable packet info and related flags for quinn-udp on Android by @conectado in #1758
- Expose SendStream::poll_write and poll_finish methods by @jean-airoldie in #1783
- Expose RecvStream::poll_read & poll_read_chunk by @jean-airoldie in #1784
- Enable
ios
for the same os_type checks asmacos
by @jamilbk in #1788 - Tweak comment alignment for transport parameter validation by @djc in #1793
- refactor(endpoint): use array::from_fn instead of unsafe MaybeUninit by @mxinden in #1806
- Remove duplicates of header fields from Incoming by @Ralith in #1805
- Update MSRV to 1.66 by @Ralith in #1810
- proto: add forgotten field to Debug for TransportConfig by @Ralith in #1642
- build(deps): bump peaceiris/actions-mdbook from 1 to 2 by @dependabot in #1825
- build(deps): bump peaceiris/actions-gh-pages from 3 to 4 by @dependabot in #1824
- perf: change throughput units from MiB/s into Mb/s. by @stormshield-damiend in #1827
- ci: pass codecov token explicitly by @djc in #1830
- quinn: allow rebinding an abstract socket by @djc in #1831
- Remove badges from metadata by @djc in #1833
- Add references to OpenCollective by @djc in #1834
- proto: take advantage of rustls::quic::Suite being Copy by @djc in #1844
- Apply clippy suggestions from Rust 1.78 by @djc in #1843
- Check compilation without default features in CI by @djc in #1845