[译] QUIC Wire Layout Specification - Packet Types and Formats | QUIC协议标准中文翻译(2) 包类型和格式

目录

  • QUIC Public Packet Header | QUIC公共包头
    • Public Flags | 公共标志位
    • Connection ID | 连接ID
    • QUIC Version | QUIC版本
    • Packet Number | 包序号
  • Speical Packets | 特殊包
    • Version Negotiation Packet | 版本协商包
    • Public Reset Packet | 公共重置包
  • Regular Packets | 常规包

Packet Types and Formats | 包类型和格式

QUIC has Special Packets and Regular Packets. There are two types of Special Packets: Version Negotiation Packets and Public Reset Packets, and regular packets containing frames.

QUIC有两种包,特殊包和常规包。特殊包又包含两种类型:版本协商包和公共重置包。常规包包含一帧或者多帧。

All QUIC packets should be sized to fit within the path’s MTU to avoid IP fragmentation. Path MTU discovery is a work in progress, and the current QUIC implementation uses a 1350-byte maximum QUIC packet size for IPv6, 1370 for IPv4. Both sizes are without IP and UDP overhead.

所有的QUIC包必须调整大小来适应链路上MTU的大小以避免IP层切片。链路MTU探测还在开发中,目前QUIC的实现是使用1350字节作为IPv6的最大QUIC包大小,IPv4则是1370字节。这里说的限制不包含IP包头和UDP包头的大小。

QUIC Public Packet Header | QUIC公共包头

All QUIC packets on the wire begin with a public header sized between 1 and 51 bytes. The wire format for the public header is as follows:

所有的QUIC包都以一个1到51字节大小的公共包头开始。公共包头的协议格式定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
--- src
0 1 2 3 4 8
+--------+--------+--------+--------+--------+--- ---+
| Public | Connection ID (64) ... | ->
|Flags(8)| (optional) |
+--------+--------+--------+--------+--------+--- ---+

9 10 11 12
+--------+--------+--------+--------+
| QUIC Version (32) | ->
| (optional) |
+--------+--------+--------+--------+


13 14 15 16 17 18 19 20
+--------+--------+--------+--------+--------+--------+--------+--------+
| Diversification Nonce | ->
| (optional) |
+--------+--------+--------+--------+--------+--------+--------+--------+

21 22 23 24 25 26 27 28
+--------+--------+--------+--------+--------+--------+--------+--------+
| Diversification Nonce Continued | ->
| (optional) |
+--------+--------+--------+--------+--------+--------+--------+--------+

29 30 31 32 33 34 35 36
+--------+--------+--------+--------+--------+--------+--------+--------+
| Diversification Nonce Continued | ->
| (optional) |
+--------+--------+--------+--------+--------+--------+--------+--------+

37 38 39 40 41 42 43 44
+--------+--------+--------+--------+--------+--------+--------+--------+
| Diversification Nonce Continued | ->
| (optional) |
+--------+--------+--------+--------+--------+--------+--------+--------+


45 46 47 48 49 50
+--------+--------+--------+--------+--------+--------+
| Packet Number (8, 16, 32, or 48) |
| (variable length) |
+--------+--------+--------+--------+--------+--------+

---

The payload may include various type-dependent header bytes as described below.
The fields in the public header are the following:

负载可能包含各种类型相关的包头描述。
公共包头中的字段含义如下:

Public Flags | 公共标志位

  • 0x01 = PUBLIC_FLAG_VERSION. Interpretation of this flag depends on whether the packet is sent by the server or the client. When sent by the client, setting it indicates that the header contains a QUIC Version (see below). This bit must be set by a client in all packets until confirmation from the server arrives agreeing to the proposed version is received by the client. A server indicates agreement on a version by sending packets without setting this bit. When this bit is set by the server, the packet is a Version Negotiation Packet. Version Negotiation is described in more detail later.
  • 0x02 = PUBLIC_FLAG_RESET. Set to indicate that the packet is a Public Reset packet.
  • 0x04 = Indicates the presence of a 32 byte diversification nonce in the header.
  • 0x08 = Indicates the full 8 byte Connection ID is present in the packet. This must be set in all packets until negotiated to a different value for a given direction (e.g., client may request fewer bytes of the Connection ID be presented).
  • Two bits at 0x30 indicate the number of low-order-bytes of the packet number that are present in each packet. The bits are only used for Frame Packets. For Public Reset and Version Negotiation Packets (sent by the server) which don’t have a packet number, these bits are not used and must be set to 0. Within this 2 bit mask:
    • 0x30 indicates that 6 bytes of the packet number is present
    • 0x20 indicates that 4 bytes of the packet number is present
    • 0x10 indicates that 2 bytes of the packet number is present
    • 0x00 indicates that 1 byte of the packet number is present
  • 0x40 is reserved for multipath use.
  • 0x80 is currently unused, and must be set to 0.
  • 0x01 = PUBLIC_FLAG_VERSION。如何解析该标志取决于这个包是服务端发送的还是客户端发送的。如果是服务端发送,设置为1标识包头中包含QUIC版本(见下面内容)。直到客户端收到服务端发送的关于同意客户端所提议的版本的确认之前,客户端发送的所有包都必须设置为1。服务端发送包时如果设置为0标识服务器同意了版本。如果服务端设置为1,标识这个一个版本协商包。版本协商包后面有更详细的描述。
  • 0x02 = PUBLIC_FLAG_SET。设置为1标识这是一个公共重置包。
  • 0x04 标识包头中存在一个32字节的多样化现时字段。
  • 0x08 标识当前包中包含8字节的连接ID。所有包都必须设置为1直到在一个指定方向上协商了另一个值(比如,连接ID不存在时可以使用更少的字节)
  • 0x30 这2bit标识包序号字段所使用的大小。这2bit只在帧数据包时使用。对于没有包序号的公共重置包和服务器发送的版本协商包,这2bit没有被使用而且必须设置为0。这2bit对应值的含义:
    • 0x30 标识包序号字段为6字节
    • 0x20 标识包序号字段为4字节
    • 0x10 标识包序号字段为2字节
    • 0x00 标识包序号字段为1字节
  • 0x40 保留给多路径使用。
  • 0x80 目前没有被使用,必须设置为0。

Connection ID | 连接ID

This is an unsigned 64 bit statistically random number selected by the client that is the identifier of the connection. Because QUIC connections are designed to remain established even if the client roams, the IP 4-tuple (source IP, source port, destination IP, destination port) may be insufficient to identify the connection. For each transmission direction, when the 4-tuple is sufficient to identify the connection, the connection ID may be omitted.

客户端选定的无符号64位随机数用于唯一标识连接。因为QUIC连接被设计为即使客户端网络发生变化了依然保持连接的建立,IP四元组(源IP,源端口,目的IP,目的端口)可能不足以标识连接。如果任一的传输方向,如果四元组足以唯一标识连接,连接ID可以被忽略。

QUIC Version | QUIC版本

A 32 bit opaque tag that represents the version of the QUIC protocol. Only present if the public flags contain FLAG_VERSION (i.e public_flags & FLAG_VERSION !=0). A client may set this flag, and include EXACTLY one proposed version, as well as including arbitrary data (conforming to that version). A server may set this flag when the client-proposed version was unsupported, and may then provide a list (0 or more) of acceptable versions, but MUST not include any data after the version(s). Examples of version values in recent experimental versions include “Q025” which corresponds to byte 9 containing ‘Q”, byte 10 containing ‘0”, etc. [See list of changes in various versions listed at the end of this document.]

32位不透明标签用于标识QUIC协议的版本。只有在公共标志包含FLAG_VERSION时存在(比如 public_flags & FLAG_VERSION ! = 0)。客户端可以设置这个标志为1,并且包含一个提议的版本,并且包含任意的数据(用于确认这个版本)。当客户端所提议的版本不支持时,服务端可以设置这个标志为1,并且提供可接受版本的列表(0或者多个),但是在版本之后必须不能再包含其他数据。举例,当前体验版本的版本值为”Q025”,那么第9个字节为’Q’,第10个字节为’0’。[本文档末尾有版本不同版本的修改内容列表]

Packet Number | 包序号

The lower 8, 16, 32, or 48 bits of the packet number, based on which FLAG_?BYTE_SEQUENCE_NUMBER flag is set in the public flags. Each Regular Packet (as opposed to the Special public reset and version negotiation packets) is assigned a packet number by the sender. The first packet sent by an endpoint shall have a packet number of 1, and each subsequent packet shall have a packet number one larger than that of the previous packet.

包序号低位的8或16或32或48bit,具体是低位的几bit取决于公共包头中对应标志的设置。发送端给每个常规包(特殊公共重置包、版本协商包则不需要)分配一个包序号。每端发送的第一个包的包序号应该为1,之后的包的包序号在前一个包的基础上加1。

The lower 64 bits of the packet number is used as part of a cryptographic nonce; therefore, a QUIC endpoint must not send a packet with a packet number that cannot be represented in 64 bits. If a QUIC endpoint transmits a packet with a packet number of (2^64-1), that packet must include a CONNECTION_CLOSE frame with an error code of QUIC_SEQUENCE_NUMBER_LIMIT_REACHED, and the endpoint must not transmit any additional packets.

包序号的低位64bit用来作为加密随机数的一部分,所以,QUIC的端不应该发送包序号不能用64bit表示的包。如果一个QUIC端发送了一个包序号为(2^64-1)的包,那么这个包必须包含一个错误码为QUIC_SEQUENCE_NUMBER_LIMIT_REACHEDCONNECTIONC_LOSE帧,并且这个QUIC端不应该再返送任何其它数据。

At most the lower 48 bits of a packet number are transmitted. To enable unambiguous reconstruction of the packet number by the receiver, a QUIC endpoint must not transmit a packet whose packet number is larger by (2^(bitlength-2)) than the largest packet number for which an acknowledgement is known to have been transmitted by the receiver. Therefore, there must never be more than (2^46) packets in flight.

传输时最多传输包序号的低位48bit。为了接收端能明确的解析包序号,QUIC端不应该发送包序号比接收端发出的ack序号大于(2^(bitlength-2))的包。所以,不应该出现多于(2^46)个包在传输。

Any truncated packet number shall be inferred to have the value closest to the one more than the largest known packet number of the endpoint which transmitted the packet that originally contained the truncated packet number. The transmitted portion of the packet number matches the lowest bits of the inferred value.

任何被截断的包序号应该被推断为最接近目前已知道最大包序号加一的包序号。包序号的传输部分和最低位被推断的值相匹配。

A Public Flags processing flowchart follows:

公共标志的处理流程图如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
--- src
Check the public flags in public header
|
|
V
+--------------+
| Public Reset | YES
| flag set? |---------------> Public Reset Packet
+--------------+
|
| NO
V
+------------+ +-------------+
| Version | YES | Packet sent | YES
| flag set? |--------->| by server? |--------> Version Negotiation
+------------+ +-------------+ Packet
| |
| NO | NO
V V
Regular Packet Regular Packet with
QUIC Version present in header
---

Speical Packets | 特殊包

Version Negotiation Packet | 版本协商包

A version negotiation packet is only sent by the server. Version Negotiation packets begin with an 8-bit public flags and 64-bit Connection ID. The public flags must set PUBLIC_FLAG_VERSION and indicate the 64-bit Connection ID. The rest of the Version Negotiation packet is a list of 4-byte versions which the server supports:

版本协商包只会由服务端发送。版本协商包以一个8bit的公共标志和64bit的连接ID开始。公共标志必须设置PUBLIC_FLAG_VERSION并且指明64bit的连接ID。版本协商包的剩余部分是一个列表,列表的每一项为4字节大小的服务端支持的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
--- src
0 1 2 3 4 5 6 7 8
+--------+--------+--------+--------+--------+--------+--------+--------+--------+
| Public | Connection ID (64) | ->
|Flags(8)| |
+--------+--------+--------+--------+--------+--------+--------+--------+--------+

9 10 11 12 13 14 15 16 17
+--------+--------+--------+--------+--------+--------+--------+--------+---...--+
| 1st QUIC version supported | 2nd QUIC version supported | ...
| by server (32) | by server (32) |
+--------+--------+--------+--------+--------+--------+--------+--------+---...--+

---

Public Reset Packet | 公共重置包

A Public Reset packet begins with an 8-bit public flags and 64-bit Connection ID. The public flags must set PUBLIC_FLAG_RESET and indicate the 64-bit Connection ID. The rest of the Public Reset packet is encoded as if it were a crypto handshake message of the tag PRST (see [QUIC-CRYPTO]):

公共重置包以一个8bit的公共标志和64bit的连接ID开始。公共标志必须设置PUBLIC_FLAG_RESET并且指明64bit的连接ID。公共重置包的剩余部分被编码为一个PRST标签的加密握手消息(参见 [QUIC-CRYPTO]):

1
2
3
4
5
6
7
8
9
10
11
12
13
--- src
0 1 2 3 4 8
+--------+--------+--------+--------+--------+-- --+
| Public | Connection ID (64) ... | ->
|Flags(8)| |
+--------+--------+--------+--------+--------+-- --+

9 10 11 12 13 14
+--------+--------+--------+--------+--------+--------+---
| Quic Tag (32) | Tag value map ... ->
| (PRST) | (variable length)
+--------+--------+--------+--------+--------+--------+---
---

Tag value map: The tag value map contains the following tag-values:

  • RNON (public reset nonce proof) - a 64-bit unsigned integer. Mandatory.
  • RSEQ (rejected packet number) - a 64-bit packet number. Mandatory.
  • CADR (client address) - the observed client IP address and port number. This is currently for debugging purposes only and hence is optional.

标签表: 包含了以下标签值:

  • RNON(公共重置临时证明) - 64bit无符号整型。必须的。
  • RSEQ(拒绝的包序号) - 64bit包序号。必须的。
  • CADR(客户端地址) - 观察到的客户端IP地址和端口。现在用于调试,所以是可选的。

(TODO: Public Reset packet should include authenticated (destination) server IP/port.)

(TODO:Public Reset packet应该包含目的服务器的IP和端口。)

Regular Packets | 常规包

Regular Packets are authenticated and encrypted. The Public Header is authenticated but not encrypted, and the rest of the packet starting with the first frame is encrypted. Immediately following the Public Header, Regular Packets contain AEAD (authenticated encryption and associated data) data. This data must be decrypted in order for the contents to be interpreted. After decryption, the plaintext consists of a sequence of frames.

常规包被认证和加密。公共包头被认证但是没有加密,包从第一个帧开始的剩余部分被加密。紧跟着公共包头,常规包包含AEAD(认证加密相关数据)数据。这些数据必须解密为可被解析的内容。解密之后,原始内容包含了一系列的帧。

(TODO: Document the inputs to encryption and decryption and describe trial decryption.)

(TODO:将加解密的输入输出文档化并描述解密过程。)

英文原文链接

QUIC Wire Layout Specification - Google 文档

原文链接: https://pengrl.com/p/48146/
原文出处: yoko blog (https://pengrl.com)
原文作者: yoko (https://github.com/q191201771)
版权声明: 本文欢迎任何形式转载,转载时完整保留本声明信息(包含原文链接、原文出处、原文作者、版权声明)即可。本文后续所有修改都会第一时间在原始地址更新。

fccxy

0%