Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

357 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

SwiftNIO QUIC

A pure-Swift implementation of the QUIC transport protocol, built on SwiftNIO.

Status: early development. The public API is not yet stable and there is no tagged release. See docs/PLAN.md for the roadmap and issue #1 for live per-task status.

Features

A QUIC endpoint, client and server, over SwiftNIO’s UDP datagram channels.

Spec Title Implemented
RFC 8999 Version-Independent Properties of QUIC Header invariants, connection IDs, version negotiation
RFC 9000 QUIC: A UDP-Based Multiplexed and Secure Transport Connections, streams, flow control, address validation, connection migration (§ 9) including server preferred_address, and the § 20 error codes
RFC 9001 Using TLS to Secure QUIC The TLS 1.3 handshake, packet and header protection, 0-RTT resumption, key update
RFC 9002 QUIC Loss Detection and Congestion Control RTT estimation, packet- and time-threshold loss detection, PTO, NewReno, ECN response, pacing
RFC 9221 An Unreliable Datagram Extension to QUIC DATAGRAM frames, with send backpressure and a bounded receive backlog
RFC 9368 Compatible Version Negotiation for QUIC A version-1 first flight upgraded to version 2 inside one handshake
RFC 9369 QUIC Version 2 Version 2, preferred by default
RFC 8899 Packetization Layer Path MTU Discovery DPLPMTUD, which RFC 9000 § 14.3 binds into QUIC to grow datagrams past the 1200-byte floor
draft-ietf-quic-qlog-main-schema-13 qlog: Structured Logging for Network Protocols Event logs written to QLOGDIR, carrying the QUIC event set that draft-ietf-quic-qlog-quic-events-13 defines. Still an Internet-Draft, so the code pins the draft version it cites

docs/specs/TRACEABILITY.md maps each normative section to its implementation and tests.

Beyond the specs:

  • Swift 6 language mode with strict concurrency, and an async/await public API. Streams are bespoke async send, receive, and bidirectional types with inbound backpressure wired to flow control.
  • Sans-I/O core. The state machines take bytes and events in and give bytes and events out. The ChannelHandlers are a thin shell, so protocol logic stays deterministically testable.
  • Cross-platform, everywhere SwiftNIO runs. Dependencies are SwiftNIO, a fork of swift-nio-ssl, swift-crypto, swift-collections, and swift-log.
  • Linux datapath offloads: batched reads (recvmmsg), GRO receive, GSO send, ECN marking, and tunable socket buffers.
  • Tested against the RFCs and other implementations. Roughly 1,100 deterministic unit and integration tests, in-process lossy-link simulators with seeded packet fates, and interop CI against quic-go and ngtcp2 through the QUIC Interop Runner.

QUIC transport only. HTTP/3 and QPACK will live in a separate swift-nio-http3 package that depends on this one.

Known issues

The roadmap tracker (issue #1) carries per-task status. The larger open items:

  • Abuse hardening is a set of point defenses, not full coverage of RFC 9000 § 21. The § 21.5.6, § 21.6, and § 21.9 defenses are in place; the rest is tracked per section in TRACEABILITY.md.
  • Retry tokens and stateless-reset tokens use per-process keys. They do not survive a restart and cannot span a cluster, because neither is derived from a configurable server secret (RFC 9000 § 8.1, § 10.3) (#127).
  • The interop rebind-port and rebind-addr cases fail on more than one pairing, so peer migration after a NAT rebind (RFC 9000 § 9.3) does not yet pass against every implementation (#364).
  • The public API has had no review pass. It carries no DocC yet, and whether to offer a Channel-conforming surface alongside the async types is still an open design question (#337).
  • A server scales to one socket per address. Single-socket dual-stack listening (#201) and SO_REUSEPORT sharding across event loops (#211) are both pending.
  • Two interop cases are not enabled yet: chacha20, which needs the TLS 1.3 cipher pinned (#175), and connectionmigration, which waits on quic-interop-runner#500 (#274).

TLS

QUIC drives the TLS 1.3 handshake directly rather than running it over records. swift-nio-quic uses a fork of swift-nio-ssl at alta/swift-nio-ssl that exposes BoringSSL’s QUIC-TLS interface, and swift-crypto for packet protection. See AGENTS.md and docs/ARCHITECTURE.md for details.

Building

swift build
swift test

Opt-in slow tests

Some tests cost about a minute each and hold several event loop threads and a multi-megabyte transfer, so they are excluded from the default run. Set QUIC_RUN_SLOW_TESTS to a truthy value (1, true, yes, y, or on) to include them:

QUIC_RUN_SLOW_TESTS=1 swift test

This follows SWIFTNIO_RUN_SLOW_TESTS in apple/swift-nio. It currently gates the real-socket NAT rebind cases in RebindLoopbackTests, which drive the rebind-port and rebind-addr interop scenarios through a loopback relay. One cheap case from that suite runs by default.

The in-process simulator has its own large-seed sweeps behind QUIC_SIMULATOR_SWEEP, which predates this convention.

Working on the swift-nio-ssl fork at the same time

The fork is expected to be checked out as a sibling directory at ../swift-nio-ssl. To build against your local checkout instead of the pinned remote commit:

swift package edit swift-nio-ssl --path ../swift-nio-ssl
# … hack on both repos …
swift package unedit swift-nio-ssl

License

Apache License 2.0. See LICENSE.txt and NOTICE.txt.

About

A pure-Swift, RFC 9000 compliant QUIC implementation built on SwiftNIO.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages