天天看點

[譯] QUIC Wire Layout Specification - Packet Types and Formats | QUIC協定标準中文翻譯(2) 包類型和格式

歡迎通路我的個人網站擷取更佳閱讀排版體驗: [譯] QUIC Wire Layout Specification - Packet Types and Formats | QUIC協定标準中文翻譯(2) 包類型和格式 | yoko blog (https://pengrl.com/p/48146/)

目錄

  • 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位元組大小的公共標頭開始。公共標頭的協定格式定義如下:

--- 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_REACHED

CONNECTIONC_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:

公共标志的處理流程圖如下:

--- 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位元組大小的服務端支援的版本:

--- 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]):

--- 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 文檔

繼續閱讀