1. Overview (概述)
QUIC是一个安全的通用传输协议。本文档定义了QUIC版本1,它符合[QUIC-INVARIANTS]中定义的QUIC版本无关属性 (Version-Independent Properties)。
QUIC是一个面向连接的协议 (Connection-Oriented Protocol),在客户端和服务器之间创建有状态的交互。
QUIC握手结合了加密参数和传输参数的协商。QUIC集成了TLS握手[TLS13],尽管使用了定制的帧格式来保护数据包。TLS和QUIC的集成在[QUIC-TLS]中有更详细的描述。握手的结构设计允许尽快交换应用数据。这包括客户端立即发送数据(0-RTT)的选项,这需要某种形式的先前通信或配置来启用。
端点在QUIC中通过交换QUIC数据包 (QUIC Packets) 进行通信。大多数数据包包含帧 (Frames),帧在端点之间传输控制信息和应用数据。QUIC对每个数据包的全部内容进行身份验证,并尽可能加密每个数据包的大部分内容。QUIC数据包承载在UDP数据报[UDP]中,以更好地便于在现有系统和网络中部署。
应用协议通过流 (Streams) 在QUIC连接上交换信息,流是有序的字节序列 (Ordered Sequences of Bytes)。可以创建两种类型的流:双向流 (Bidirectional Streams),允许两个端点发送数据;和单向流 (Unidirectional Streams),只允许单个端点发送数据。使用基于信用的方案 (Credit-Based Scheme) 来限制流的创建和可以发送的数据量。
QUIC提供必要的反馈来实现可靠传输 (Reliable Delivery) 和拥塞控制 (Congestion Control)。[QUIC-RECOVERY]第6节描述了检测和恢复数据丢失的算法。QUIC依赖拥塞控制来避免网络拥塞。[QUIC-RECOVERY]第7节描述了一个示例性的拥塞控制算法。
QUIC连接不严格绑定到单个网络路径。连接迁移 (Connection Migration) 使用连接标识符 (Connection Identifiers) 允许连接转移到新的网络路径。在此版本的QUIC中,只有客户端能够迁移。这种设计还允许连接在网络拓扑或地址映射发生变化后继续存在,例如可能由NAT重新绑定 (NAT Rebinding) 引起的变化。
一旦建立,连接终止提供了多个选项。应用程序可以管理优雅的关闭 (Graceful Shutdown),端点可以协商超时周期,错误可以导致立即拆除连接,并且无状态机制提供了在一个端点丢失状态后终止连接的方法。
1.1. Document Structure (文档结构)
本文档描述了核心QUIC协议,其结构如下:
流 (Streams) - QUIC提供的基本服务抽象
- 第2节: 描述与流相关的核心概念
- 第3节: 提供流状态的参考模型
- 第4节: 概述流量控制的操作
连接 (Connections) - QUIC端点通信的上下文
- 第5节: 描述与连接相关的核心概念
- 第6节: 描述版本协商 (Version Negotiation)
- 第7节: 详细说明建立连接的过程
- 第8节: 描述地址验证和关键的拒绝服务攻击缓解措施
- 第9节: 描述端点如何将连接迁移到新的网络路径
- 第10节: 列出终止打开连接的选项
- 第11节: 提供流和连接错误处理的指导
数据包和帧 (Packets and Frames) - QUIC用于通信的基本单元
- 第12节: 描述与数据包和帧相关的概念
- 第13节: 定义数据传输、重传和确认的模型
- 第14节: 指定管理承载QUIC数据包的数据报大小的规则
编码细节 (Encoding Details) - QUIC协议元素的编码详细信息
- 第15节: 版本 (Versions)
- 第16节: 整数编码 (Integer Encoding)
- 第17节: 数据包头部 (Packet Headers)
- 第18节: 传输参数 (Transport Parameters)
- 第19节: 帧 (Frames)
- 第20节: 错误 (Errors)
配套文档
配套文档描述了QUIC的丢包检测和拥塞控制[QUIC-RECOVERY],以及TLS和其他加密机制的使用[QUIC-TLS]。
本文档定义了QUIC版本1,它符合[QUIC-INVARIANTS]中的协议不变量。
引用说明:
- 引用QUIC版本1时,请引用本文档
- 引用QUIC有限的版本无关属性集时,可以引用[QUIC-INVARIANTS]
1.2. Terms and Definitions (术语和定义)
本文档中的关键词"MUST"、"MUST NOT"、"REQUIRED"、"SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"NOT RECOMMENDED"、"MAY"和"OPTIONAL"应按照BCP 14 [RFC2119] [RFC8174]中的描述进行解释,当且仅当它们以全大写形式出现时,如此处所示。
本文档中常用的术语描述如下:
核心术语
QUIC 本文档描述的传输协议。QUIC是一个名称,而不是首字母缩写。
Endpoint (端点) 可以通过生成、接收和处理QUIC数据包来参与QUIC连接的实体。QUIC中只有两种类型的端点:客户端 (Client) 和服务器 (Server)。
Client (客户端) 发起QUIC连接的端点。
Server (服务器) 接受QUIC连接的端点。
QUIC Packet (QUIC数据包) 可以封装在UDP数据报中的完整可处理的QUIC单元。一个或多个QUIC数据包可以封装在单个UDP数据报中。
Ack-eliciting Packet (引发确认的数据包) 包含ACK、PADDING和CONNECTION_CLOSE以外的帧的QUIC数据包。这些数据包会导致接收方发送确认;参见第13.2.1节。
Frame (帧) 结构化协议信息的单元。有多种帧类型,每种类型携带不同的信息。帧包含在QUIC数据包中。
Address (地址) 在不加限定的情况下使用时,指代表网络路径一端的IP版本、IP地址和UDP端口号的元组。
Connection ID (连接标识符) 用于在端点标识QUIC连接的标识符。每个端点为其对等方选择一个或多个连接ID,以包含在发送到该端点的数据包中。此值对对等方是不透明的。
Stream (流) QUIC连接中的单向或双向有序字节通道。QUIC连接可以承载多个同时进行的流。
Application (应用程序) 使用QUIC发送和接收数据的实体。
协议层次术语
本文档使用术语"QUIC数据包"、"UDP数据报"和"IP数据包"来指代各自协议的单元。也就是说,一个或多个QUIC数据包可以封装在一个UDP数据报中,而UDP数据报又封装在一个IP数据包中。
+------------------+
| IP Packet |
| +--------------+|
| | UDP Datagram ||
| | +----------+ ||
| | |QUIC Pkt 1| ||
| | +----------+ ||
| | +----------+ ||
| | |QUIC Pkt 2| ||
| | +----------+ ||
| +--------------+|
+------------------+
1.3. Notational Conventions (符号约定)
本文档中的数据包和帧图使用自定义格式。此格式的目的是总结而非定义协议元素。文字部分定义了结构的完整语义和细节。
字段表示规则
复杂字段首先命名,然后跟随一对匹配的大括号包围的字段列表。此列表中的每个字段用逗号分隔。
单个字段包括长度信息,以及关于固定值、可选性或重复性的说明。单个字段使用以下符号约定,所有长度以位 (Bits) 为单位:
x (A)
表示x的长度为A位
x (i)
表示x保存使用第16节中描述的可变长度编码的整数值
x (A..B)
表示x的长度可以是从A到B的任何长度;可以省略A以表示最小为零位,可以省略B以表示没有设定上限;此格式的值始终在字节边界结束
x (L) = C
表示x具有固定值C;x的长度由L描述,L可以使用上述任何长度形式
x (L) = C..D
表示x的值在C到D的范围内(包括C和D),长度由L描述,如上所示
[x (L)]
表示x是可选的,长度为L
x (L) ...
表示x重复零次或多次,每个实例的长度为L
字节序和位顺序
本文档使用网络字节序 (Network Byte Order,即大端序 Big Endian) 值。字段从每个字节的高位开始放置。
按照惯例,单个字段通过使用复杂字段的名称来引用复杂字段。
示例结构
图1提供了一个示例:
Example Structure {
One-bit Field (1),
7-bit Field with Fixed Value (7) = 61,
Field with Variable-Length Integer (i),
Arbitrary-Length Field (..),
Variable-Length Field (8..24),
Field With Minimum Length (16..),
Field With Maximum Length (..128),
[Optional Field (64)],
Repeated Field (8) ...,
}
图1: 示例格式
当在文字中引用单个比特字段时,可以通过使用携带该字段的字节的值(字段值已设置)来澄清该字段的位置。例如,值0x80可用于引用字节最高有效位中的单比特字段,例如图1中的One-bit Field。
💡 核心概念总结
QUIC的三大支柱
-
流 (Streams) - 应用数据的逻辑通道
- 双向流和单向流
- 流级别的流量控制
- 多路复用,无队头阻塞
-
连接 (Connections) - 端点间的有状态交互
- 基于连接ID,而非IP地址
- 支持连接迁移
- 集成TLS 1.3握手
-
数据包和帧 (Packets & Frames) - 传输的基本单元
- 基于UDP
- 数据包级别的加密和认证
- 灵活的帧类型设计
QUIC vs TCP+TLS
| 特性 | QUIC | TCP+TLS |
|---|---|---|
| 握手 | 1-RTT (0-RTT可选) | 2-3 RTT |
| 多路复用 | 原生支持 | 需要HTTP/2 |
| 队头阻塞 | 流级别独立 | 字节流级别阻塞 |
| 连接迁移 | ✅ | ❌ |
| 加密 | 强制 | 可选 |
| 部署 | 用户空间,快速迭代 | 内核空间,升级慢 |
下一章: 2. Streams (流) - 深入了解QUIC的流抽象