跳到主要内容

17. 数据包格式

17. 数据包格式 (Packet Formats)

所有数值均以网络字节序 (即大端序) 编码, 所有字段大小均以 bit 为单位. 字段值使用十六进制表示法描述.

17.1 Packet Number 编码和解码

Packet number 是 0 到 2^62-1 范围内的整数 (第 12.3 节). 当 packet number 出现在数据包中时, 它会被编码为 1 到 4 字节. 通过仅包含 packet number 的最低有效位, 可以减少表示 packet number 所需的 bit 数.

编码后的 packet number 按 [QUIC-TLS] 第 5.4 节所述受到保护.

发送方 MUST 使用一种 packet number 大小, 使其可表示的范围大于最大已确认 packet number 与正在发送的 packet number 之间差值的两倍. 这样, 接收该数据包的对端就能正确解码 packet number, 除非该数据包在传输中被延迟, 导致它在许多编号更高的数据包已经被接收之后才到达.

因此, packet number 编码的大小至少比连续未确认 packet number 数量 (包括新数据包) 的以 2 为底的对数多 1.

17.2 Long Header 数据包

Long header 用于在 1-RTT key 建立之前发送的数据包. 一旦 1-RTT key 可用, 发送方就切换为使用 short header 发送数据包 (第 17.3 节). long 形式允许特殊数据包, 例如 Version Negotiation packet, 以这种统一的固定长度数据包格式表示.

带有 long header 的数据包通过 Header Form bit 被设置为 1 来识别.

17.2.1 Version Negotiation Packet

Version Negotiation packet 本质上不特定于某个版本. 客户端收到该数据包时, 会根据 Version field 的值为 0 将其识别为 Version Negotiation packet.

17.2.2 Initial Packet

Initial packet 使用 type 值为 0x00 的 long header. 它携带客户端和服务器为执行密钥交换而发送的首批 CRYPTO frames, 并在任一方向上携带 ACK frames.

17.2.3 0-RTT

0-RTT packet 使用 type 值为 0x01 的 long header. 0-RTT packet 的 packet number space (第 12.3 节) 为 ApplicationData.

17.2.4 Handshake Packet

Handshake packet 使用 type 值为 0x02 的 long header. 它用于携带来自服务器和客户端的加密握手消息和确认.

17.2.5 Retry Packet

Retry packet 使用 type 值为 0x03 的 long packet header. 它携带服务器创建的地址验证 token. 希望执行 retry 的服务器会使用它 (参见第 8.1 节).

17.3 Short Header 数据包

此版本的 QUIC 定义了一个使用 short packet header 的单一数据包类型.

17.3.1 1-RTT Packet

1-RTT packet 使用 short packet header. 它在版本和 1-RTT key 协商完成后使用.

17.4 延迟 Spin Bit

延迟 spin bit 位于 short header 的 bit 0x20, 它允许从网络路径上的观察点进行被动延迟监测. spin bit 只存在于 short packet header 中, 因为可以通过观察握手来测量连接的初始 RTT. 因此, spin bit 在版本协商和连接建立完成后可用.