Abstract

The protocol aims to replace TCP and TLS with a more efficient, secure, and flexible alternative. It wants to do this by:

  1. Reduced Connection Establishment Time: By overlapping the connection setup and encryption key negotiation, QUIC minimizes the latency involved in starting a secure connection.
  2. Enhanced Security: QUIC prevents metadata leakage by encrypting more of the transport headers and systematically applying GREASE to maintain protocol flexibility and extensibility.
  3. Avoiding Ossification: The design of QUIC includes mechanisms to resist ossification, ensuring the protocol remains adaptable and extendable. Published Protocol Invariants, Pervasive Encryption of Headers, GREASE

It also adds:

  • Stream Multiplexing: Unlike TCP, which allows a single bidirectional stream per connection, QUIC enables multiple independent streams over a single connection, enhancing data flow management and efficiency.
  • Reliability and Congestion Control: Inherits core TCP functionalities like reliability, ordering, and congestion control, but implemented over UDP.
  • Protocol Layering: QUIC operates above UDP and combines features traditionally provided by TCP and TLS, including transport and security aspects, and elements from HTTP.

The standard adopts TCP Reno congestion control, however in practice systems tend to use TCP BBR or TCP Cubic congestion control.

General Structure

Connection Establishment in QUIC

  • Two-Phase Process: Like TCP, QUIC operates in two main phases - the handshake phase and the data transfer phase.

  • Handshake Phase:

    • Initial Packet: The handshake starts with the client sending an Initial packet (equivalent to TCP’s SYN). This packet includes a QUIC CRYPTO frame carrying a TLS ClientHello message, initiating both the QUIC connection and the TLS handshake. It may also include a optional Token

      • Server can refuse the initial connection attempt, and send a Retry packet containing a Token.
      • Client must then retry the connection, providing the Token in its Initial packet
        • Can be used to prevent connection spoofing
    • Server Response: The server responds with its own Initial packet (akin to TCP’s SYN-ACK), which includes a CRYPTO frame with a TLS ServerHello. This is followed by a QUIC Handshake packet, which contains the data necessary for completing the TLS authentication and any QUIC-specific extensions.

    • Completion: The client then sends another UDP datagram containing an Initial Packet, a Handshake Packet, and a 1-RTT packet. This datagram includes acknowledgments and the TLS Finished message, completing the handshake and starting data transfer.

  • Data Transfer in QUIC:

    • Short Header Packets: After the handshake, QUIC uses short header packets for data transfer. These packets are simpler and designed for efficiency, carrying encrypted and authenticated data.

    • QUIC Streams:

      • Multiple data streams can be sent over a single QUIC connection, allowing simultaneous data flows independent of each other.
      • STREAM frames within QUIC packets carry data for these streams, with each frame containing stream identifiers and offset data to manage stream integrity and order.

QUIC Frames

QUIC packets contain an encrypted sequence of frames

We’ve moved from trying to convey important data in our headers which we will never be able to modify again, to conveying data in these frames, which we can add and remove from. As you can see, therefore our Headers are shorter because of this.

CRYPTO frames are used to carry [[TLS (Transport Layer Security)] ] messages such as ClientHello and ServerHello

  • STREAM and ACK frames send data and acknowledgements
  • Migration between two network interfaces is supported by PATH_CHALLENGE and PATH_RESPONSE frames
  • Other frames control progress of a QUIC connection
Frame Table Reference:
Type ValueFrame Type Name
0x00PADDING
0x01PING
0x02ACK
0x02 - 0x03ACK
0x04RESET_STREAM
0x05STOP_SENDING
0x06CRYPTO
0x07NEW_TOKEN
0x08 - 0x0FSTREAM
0x10MAX_DATA
0x11MAX_STREAM_DATA
0x12 - 0x13MAX_STREAMS
0x14DATA_BLOCKED
0x15STREAM_DATA_BLOCKED
0x16 - 0x17STREAMS_BLOCKED
0x18NEW_CONNECTION_ID
0x19RETIRE_CONNECTION_ID
0x1APATH_CHALLENGE
0x1BPATH_RESPONSE
0x1C - 0x1DCONNECTION_CLOSE
0x1EHANDSHAKE_DONE

ACK Frame

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Largest Acknowledged (i)              ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
|                            ACK Delay (i)                    ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         ACK Range Count (i)                 ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         First ACK Range (i)                 ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           ACK Ranges (*)                    ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            [ECN Counts]                     ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

QUIC sends acknowledgements of received packets in ACK frames

  • Sent inside a long- or short-header packets; unlike TCP, not part of headers
  • Indicate sequence numbers of QUIC packets that were received, not frames

STREAM Frame

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Stream ID (i)                     ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            [Offset (i)]                     ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            [Length (i)]                     ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Stream Data (*)                    ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Data is sent within STREAM frames, sent within QUIC packets

  • Contain a stream identifier, offset of the data within the stream, data length, and data
  • QUIC provides multiple reliable byte streams within a single connection
    • Data for each stream is delivered reliably and in-order
    • Order is not preserved between streams
    • Avoids head-of-line blocking between streams (but not within) → Lecture 5
  • Finish The Link Here

QUIC Headers

QUIC packets can be Long Header, or Short Header.

Long Header

Long header packets are used to establish QUIC connections

They all start with a common header, followed by packet-type specific data

Four different long-header packet types, denoted by the TT field in the header:

  • Initial – initiates connection, starts TLS handshake, contains CRYPTO frame, Structure
  • 0-RTTidempotent data sent with initial handshake, when resuming a session contains a STREAM frame, Structure
  • Handshake – completes connection establishment, Structure
  • Retry – used to force address validation,
LH General Structure
0                   1                   2                   3 
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+
|1|1|T T|X X X X| 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Version (32)                           | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DCID Len (8)  | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             Destination Connection ID (0..160)              ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SCID Len (8)  | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                Source Connection ID (0..160)                ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
...               Packet-type specific data                   ... 
|                                                               | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
LH *Initial Structure
0                   1                   2                   3 
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+
|1|1| 0 |R R|P P| 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Version (32)                           | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DCID Len (8)  | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                Destination Connection ID (0..160)           ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SCID Len (8)  | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   Source Connection ID (0..160)             ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Token Length (i)                    ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             Token (*)                       ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Length (i)                       ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Packet Number (8..32)                 ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Payload (8..)                     ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
LH *Handshake Structure
0                   1                   2                   3 
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+
|1|1| 2 |R R|P P| 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Version (32)                           | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DCID Len (8)  | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                Destination Connection ID (0..160)           ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SCID Len (8)  | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                  Source Connection ID (0..160)              ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Length (i)                        ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Packet Number (8..32)                   ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Payload (8..)                      ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
LH *0-RTT Structure
0                   1                   2                   3 
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
+-+-+-+-+-+-+-+-+
|1|1| 1 |R R|P P| 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Version (32)                           | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DCID Len (8)  | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                Destination Connection ID (0..160)           ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SCID Len (8)  | 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                  Source Connection ID (0..160)              ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Length (i)                        ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Packet Number (8..32)                   ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Payload (8..)                      ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Short Header

The is one short header packet defined in QUIC:

  • 1-RTT – Used for all packets sent after the TLS handshake is complete
    • The short header is followed by QUIC frames in the enclosing UDP packet
    • Compared to long header, omits information that can be inferred from context

The short header contains a Packet Number field

  • Packet numbers increase by one for each packet sent; ACK frames indicate received packet numbers
    • QUIC packet numbers count packets sent; TCP sequence numbers count bytes of data sent
  • QUIC never retransmits packets – retransmits frames sent in lost packets in new packets, with new packet numbers
    • TCP retransmits lost packet with original sequence number
SH Structure
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
|0|1|S|R|R|K|P P|                                             ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|			   Destination Connection ID (0..160)             ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|			        Packet Number (8/16/24/32)                ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|			        Protected Payload (*)                     ... 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

QUIC Invariants

  • Packets start with a long header or a short header
    • The first bit of long header packets is always 1; they include version number, destination- and source-connection identifiers
    • The first bit of short header packets is always 0; they include a destination connection identifier
    • Connections can arbitrarily switch between long header and short header packets That’s it !

Avoiding Ossification

  • QUIC encrypts as much data as possible
    • Entire packet except invariant fields and the last 7-bits of the first byte is encrypted; entire packet is authenticated
    • Encryption keys for initial handshake packets are derived from connection identifiers
      • Contain ClientHello and ServerHello, which are unencrypted when using TLS over TCP, and don’t need to be encrypted
      • QUIC provides no more security than TLS over TCP, but makes it expensive for middleboxes to read handshake
    • Rest of QUIC connection protected by TLS 1.3 as normal
  • QUIC authenticates all data
    • If a middlebox changes the headers, the change can be detected
  • QUIC makes extensive use of GREASE
    • Every field encrypted or has a value that is unpredictable
      • New connections use randomly chosen connection identifies
      • Clients randomly try to negotiate new version numbers
        • Version numbers matching 0x?a?a?a?a for testing version negotiation – will be rejected by servers
      • Unused header fields given randomly chosen values
    • Goal is that middleboxes can’t make any assumptions about QUIC header values → nothing in the header is predictable
    • Hopefully avoids ossification → nothing to ossify around

Development Background

QUIC started in 2012 as a Google project aimed at enhancing the security and performance of web communications. This project also led to the development of SPDY, which evolved into HTTP/2. Google transferred QUIC to the IETF in 2016, resulting in the formation of a working group to standardize the protocol. After extensive revisions and community input (34 drafts and thousands of pull requests), the final set of RFCs (RFC 8999 to RFC 9002) was published in May 2021.

Reliable Data Transfer With QUIC

QUIC as opposed to TCP, delivers several ordered reliable byte streams within a single connection

  • Each stream is delivered reliably and in-order
  • Order is not preserved between streams within a QUIC connection

QUIC doesn’t preserve message boundaries in streams If >1 stream has data to send, the QUIC sender can choose how to prioritize and deliver frames from each stream

Each QUIC packet has a Packet Number

  • Two packet number spaces
    • Packets sent during initial handshake
    • Packets sent to carry data
  • Within each space, packet number starts at zero, increases by one for each packet sent
    • Counts number of packets sent
    • Different to TCP, where the sequence number records the offset within the byte stream

Each QUIC packet contains one or more frames

  • STREAM frames carry data
  • Each has a stream identifier, and carries the length of the data and its offset from start of stream – closer to TCP sequence number

300

A QUIC receiver sends acknowledgements for packets it receives

  • Unlike TCP, it does not acknowledge sequence numbers within each stream
  • The sender needs to remember what data from each stream was in each packet, to know what parts of each stream have been received
  • ACK Frame Acknowledgements sent as reverse path frames Acknowledgements can be delayed
  • e.g., send acknowledgement after every second packet is received
  • The ACK Delay field measures this delay to allow accurate network RTT calculation Acknowledgements contain ranges
  • e.g., a single ACK Frame can indicate that packets 1-4 and 6-8 were received
    • Like TCP Selective Acknowledgement extension

Retransmission and Loss Recovery

QUIC does not retransmit lost packets

  • Every packet has a unique packet number and is only transmitted once
  • Packets declared lost when at least three later packets have been acknowledged
    • Equivalent to TCP triple duplicate ACK
  • Packets declared lost after timeout – like TCP QUIC retransmits lost data in new packets
  • Packetization of STREAM frames into packets may differ when data retransmitted
  • Data ordering between streams not preserved