歡迎訪問個人我的網站獲取更好的閱讀排版體驗: [譯] QUIC Wire Layout Specification - Frame Types and Formats | QUIC協議標準中文翻譯(4) 幀類型和格式 | yoko blog (https://pengrl.com/p/47156/)express
QUIC Frame Packets are populated by frames. which have a Frame Type byte, which itself has a type-dependent interpretation, followed by type-dependent frame header fields. All frames are contained within single QUIC Packets and no frame can span across a QUIC Packet boundary.windows
QUIC的幀類型包由一個或多個幀組成。幀有一個字節大小的幀類型,有本身的類型解釋,後面跟着該幀類型的字段。一個或多個幀只能包含在一個QUIC包中,沒有幀能夠跨越多個QUIC包。session
There are two interpretations for the Frame Type byte, resulting in two frame types: Special Frame Types, and Regular Frame Types. Special Frame Types encode both a Frame Type and corresponding flags all in the Frame Type byte, while Regular Frame Types use the Frame Type byte simply.app
一共有兩種幀類型:特殊幀類型和常規幀類型,它們的解析是不同的。特殊幀類型在幀類型的字節中同時編碼了幀類型和相應的標誌位,而常規幀的幀類型字節只用來標識類型。less
Currently defined Special Frame Types are:ide
當前定義的特殊幀類型有:網站
--- src +------------------+-----------------------------+ | Type-field value | Control Frame-type | +------------------+-----------------------------+ | 1fdooossB | STREAM | | 01ntllmmB | ACK | | 001xxxxxB | CONGESTION_FEEDBACK | +------------------+-----------------------------+ ---
Currently defined Regular Frame Types are:ui
當前定義的常規幀類型有:this
--- src +------------------+-----------------------------+ | Type-field value | Control Frame-type | +------------------+-----------------------------+ | 00000000B (0x00) | PADDING | | 00000001B (0x01) | RST_STREAM | | 00000010B (0x02) | CONNECTION_CLOSE | | 00000011B (0x03) | GOAWAY | | 00000100B (0x04) | WINDOW_UPDATE | | 00000101B (0x05) | BLOCKED | | 00000110B (0x06) | STOP_WAITING | | 00000111B (0x07) | PING | +------------------+-----------------------------+ ---
The STREAM frame is used to both implicitly create a stream and to send data on it, and is as follows:google
流類型幀用於隱式建立流和在流上發送數據,格式爲:
--- src 0 1 … SLEN +--------+--------+--------+--------+--------+ |Type (8)| Stream ID (8, 16, 24, or 32 bits) | | | (Variable length SLEN bytes) | +--------+--------+--------+--------+--------+ SLEN+1 SLEN+2 … SLEN+OLEN +--------+--------+--------+--------+--------+--------+--------+--------+ | Offset (0, 16, 24, 32, 40, 48, 56, or 64 bits) (variable length) | | (Variable length: OLEN bytes) | +--------+--------+--------+--------+--------+--------+--------+--------+ SLEN+OLEN+1 SLEN+OLEN+2 +-------------+-------------+ | Data length (0 or 16 bits)| | Optional(maybe 0 bytes) | +------------+--------------+ ---
The fields in the STREAM frame header are as follows:
- Frame Type: The Frame Type byte is an 8-bit value containing various flags (1fdooossB):
- The leftmost bit must be set to 1 indicating that this is a STREAM frame.
- The 'f' bit is the FIN bit. When set to 1, this bit indicates the sender is done sending on this stream and wishes to "half-close" (described in more detail later.)
- which is described in more detail later in this document.
- The 'd' bit indicates whether a Data Length is present in the STREAM header. When set to 0, this field indicates that the STREAM frame extends to the end of the Packet.
- The next three 'ooo' bits encode the length of the Offset header field as 0, 16, 24, 32, 40, 48, 56, or 64 bits long.
- The next two 'ss' bits encode the length of the Stream ID header field as 8, 16, 24, or 32 bits long.
- Stream ID: A variable-sized unsigned ID unique to this stream.
- Offset: A variable-sized unsigned number specifying the byte offset in the stream for this block of data.
- Data length: An optional 16-bit unsigned number specifying the length of the data in this stream frame. The option to omit the length should only be used when the packet is a "full-sized" Packet, to avoid the risk of corruption via padding.
流類型幀的頭部字段含義以下:
A stream frame must always have either non-zero data length or the FIN bit set.
流類型幀必須是非0大小的數據長度或者設置了Fin標誌。
The ACK frame is sent to inform the peer which packets have been received, as well as which packets are still considered missing by the receiver (the contents of missing packets may need to be resent). The ack frame contains between 1 and 256 ack blocks. Ack blocks are ranges of acknowledged packets, similar to TCP’s SACK blocks, but QUIC has no equivalent of TCP’s cumulative ack point, because packets are retransmitted with new sequence numbers.
發送ACK幀用於通知對端哪些包已經被接收,換句話說,通知對端哪些包接收端沒有收到(丟失包的內容可能須要從新發送)。ACK幀包含了1到256個ack塊。ack塊是已確認的包的區間,相似於TCP的SACK的塊,可是不一樣於TCP的不可撤銷的ack,由於QUIC重傳時使用了新的包序號。
To limit the ACK blocks to the ones that haven't yet been received by the peer, the peer periodically sends STOP_WAITING frames that signal the receiver to stop acking packets below a specified sequence number, raising the "least unacked" packet number at the receiver. A sender of an ACK frame thus reports only those ACK blocks between the received least unacked and the reported largest observed packet numbers. It is recommended for the sender to send the most recent largest acked packet it has received in an ack as the stop waiting frame’s least unacked value.
爲了限制對於那些對端尚未接收到的ACK的塊,數據發送端週期性發送STOP_WAITING
幀來通知接收端中止ack小於一個指定序號的包。使得接收端產生一個"最小還沒ack"的包序號。因而ACK幀的發送者值須要報告那些最小還沒ack與收到的最大序號之間的ACK塊。建議ACK幀的發送者在ACK幀中發送最近最大已ack的包,就像STOP_WAITING
幀的最小還沒ack同樣。
Unlike TCP SACKs, QUIC ACK blocks are irrevocable, so once a packet is acked, even if it does not appear in a future ack frame, it is assumed to be acked.
不一樣於TCP的SACK,QUIC的ACK塊是不可撤銷的,若是一個包被ack了,那麼即便它再也不出如今以後的ACK幀中,依然認爲它已經被ack了。
As a replacement for QUIC’s deprecated entropy, the sender can intentionally skip packet numbers to introduce entropy into the connection. The sender must always close the connection if an unsent packet number is acked, so this mechanism automatically defeats any potential attackers. The ack format is efficient at expressing blocks of missing packets, so this has a low cost to the receiver and sender and efficiently provides up to 8 bits of entropy on demand, rather than incurring the constant overhead and achieving 8 bits of entropy. The 8 bits is the longest gap between ack ranges the ack format can efficiently express.
做爲QUIC已棄用的熵信息的替代方案,發送端能夠有意的跳過包序號來將熵信息注入鏈接中。發送端若是收到一個沒有發送過的包序號對應的ack,應該關閉這個鏈接,這個機制能夠自動預防任何潛在的攻擊者。ack用於表示丟失包的塊的格式是高效的。
Section Offsets
0: Start of the ack frame.
T: Byte offset of the start of the timestamp section.
A: Byte offset of the start of the ack block section.
N: Length in bytes of the largest acked.
各區域偏移
0: ack幀的開始
T: 時間區域的偏移
A: ack塊區域的偏移
N: 最大ack的長度
--- src 0 1 => N N+1 => A(aka N + 3) +---------+-------------------------------------------------+--------+--------+ | Type | Largest Acked | Largest Acked | | (8) | (8, 16, 32, or 48 bits, determined by ll) | Delta Time (16) | |01nullmm | | | +---------+-------------------------------------------------+--------+--------+ A A + 1 ==> A + N +--------+----------------------------------------+ | Number | First Ack | |Blocks-1| Block Length | | (opt) |(8, 16, 32 or 48 bits, determined by mm)| +--------+----------------------------------------+ A + N + 1 A + N + 2 ==> T(aka A + 2N + 1) +------------+-------------------------------------------------+ | Gap to next| Ack Block Length | | Block (8) | (8, 16, 32, or 48 bits, determined by mm) | | (Repeats) | (repeats Number Ranges times) | +------------+-------------------------------------------------+ T T+1 T+2 (Repeated Num Timestamps) +----------+--------+---------------------+ ... --------+------------------+ | Num | Delta | Time Since | | Delta | Time | |Timestamps|Largest | Largest Acked | |Largest | Since Previous | | (8) | Acked | (32 bits) | | Acked |Timestamp(16 bits)| +----------+--------+---------------------+ +--------+------------------+ ---
The fields in the ACK frame are as follows:
- Frame Type: The Frame Type byte is an 8-bit value containing various flags (01nullmmB).
- The first two bits must be set to 01 indicating that this is an ACK frame.
- The 'n' bit indicates whether the frame has more than 1 ack range.
- The 'u' bit is unused.
- The two 'll' bits encode the length of the Largest Observed field as 1, 2, 4, or 6 bytes long.
- The two 'mm' bits encode the length of the Missing Packet Sequence Number Delta field as 1, 2, 4, or 6 bytes long.
- Largest Acked: A variable-sized unsigned value representing the largest packet number the peer has observed.
- Largest Acked Delta Time: A 16-bit unsigned float with 11 explicit bits of mantissa and 5 bits of explicit exponent, specifying the time elapsed in microseconds from when largest acked was received until this Ack frame was sent. The bit format is loosely modeled after IEEE 754. For example, 1 microsecond is represented as 0x1, which has an exponent of zero, presented in the 5 high order bits, and mantissa of 1, presented in the 11 low order bits. When the explicit exponent is greater than zero, an implicit high-order 12th bit of 1 is assumed in the mantissa. For example, a floating value of 0x800 has an explicit exponent of 1, as well as an explicit mantissa of 0, but then has an effective mantissa of 4096 (12th bit is assumed to be 1). Additionally, the actual exponent is one-less than the explicit exponent, and the value represents 4096 microseconds. Any values larger than the representable range are clamped to 0xFFFF.
- Ack Block Section:
- Num Blocks: An optional 8-bit unsigned value specifying one less than the number of ack blocks. Only present if the 'n' flag bit is 1.
- Ack block length: A variable-sized packet number delta. For the first missing packet range, the ack block starts at largest acked. For the first ack block, the length of the ack block is 1 + this value. For subsequent ack blocks, it is the length of the ack block. For non-first blocks, a value of 0 indicates more than 256 packets in a row were lost.
- Gap to next block: An 8-bit unsigned value specifying the number of packets between ack blocks.
- Timestamp Section:
- Num Timestamp: An 8-bit unsigned value specifying the number of timestamps that are included in this ack frame. There will be this many pairs of <packet number, timestamp> following in the timestamps.
- Delta Largest Observed: An 8-bit unsigned value specifying the packet number delta from the first timestamp to the largest observed. Therefore, the packet number is the largest observed minus the delta largest observed.
- First Timestamp: A 32-bit unsigned value specifying the time delta in microseconds, from the beginning of the connection of the arrival of the packet specified by Largest Observed minus Delta Largest Observed.
- Delta Largest Observed (Repeated): (Same as above.)
- Time Since Previous Timestamp (Repeated): A 16-bit unsigned value specifying delta from the previous timestamp. It is encoded in the same format as the Ack Delay Time.
ACK幀中的字段含義以下:
Largest Observed
字段的長度,能夠是1,2,4,6字節Missing Packet Sequence Number Delta
字段的長度,能夠是1,2,4,6字節The STOP_WAITING frame is sent to inform the peer that it should not continue to wait for packets with packet numbers lower than a specified value. The packet number is encoded in 1, 2, 4 or 6 bytes, using the same coding length as is specified for the packet number for the enclosing packet's header (specified in the QUIC Frame Packet's Public Flags field.) The frame is as follows:
發送中止等待幀來通知對端再也不等待小於指定包序號的包。包序號能夠被編碼爲1,2,4,6字節。編碼方式和QUIC幀類型包的公共標誌中包序號字段同樣。幀格式以下:
--- src 0 1 2 3 4 5 6 +--------+--------+--------+--------+--------+-------+-------+ |Type (8)| Least unacked delta (8, 16, 32, or 48 bits) | | | (variable length) | +--------+--------+--------+--------+--------+--------+------+ ---
The fields in the STOP_WAITING frame are as follows:
- Frame Type: The Frame Type byte is an 8-bit value that must be set to 0x06 indicating that this is a STOP_WAITING frame.
- Least Unacked Delta: A variable length packet number delta with the same length as the packet header's packet number. Subtract it from the header's packet number to determine the least unacked. The resulting least unacked is the smallest packet number of any packet for which the sender is still awaiting an ack. If the receiver is missing any packets smaller than this value, the receiver should consider those packets to be irrecoverably lost.
中止等待幀的字段含義以下:
The WINDOW_UPDATE frame is used to inform the peer of an increase in an endpoint's flow control receive window. The stream ID can be 0, indicating this WINDOW_UPDATE applies to the connection level flow control window, or > 0 indicating that the specified stream should increase its flow control window. The frame is as follows:
窗口更新幀用來告知對端本端的一次流量控制接收窗口的增加。流ID爲0時標識這個窗口更新幀做用於鏈接層面的流量控制窗口,> 0
標識一個指定的流須要增加它的流量控制窗口。這個幀以下定義:
An absolute byte offset is specified, and the receiver of a WINDOW_UPDATE frame may only send up to that number of bytes on the specified stream. Violating flow control by sending further bytes will result in the receiving endpoint closing the connection.
指定一個絕對的字節偏移,窗口更新幀的接收端可能在指定的流上最多發送指定的字節。違反流量控制發送更多的數據會致使數據接收端關閉這個鏈接。
On receipt of multiple WINDOW_UPDATE frames for a specific stream ID, it is only necessary to keep track of the maximum byte offset.
若是一個流上收到了多個窗口更新幀,只須要關注最大的字節偏移。
Both stream and session windows start with a default value of 16 KB, but this is typically increased during the handshake. To do this, an endpoint should negotiate the SFCW (Stream Flow Control Window) and CFCW (Connection/Session Flow Control Window) parameters in the handshake. The value associated with each tag should be the number of bytes for initial stream window and initial connection window respectively.
流和鏈接的窗口開始的默認值是16KB,可是通常會在握手階段增加。爲了達到這個效果,一端須要在握手階段協商SFCW(流上的流量控制窗口)和CFCW(鏈接/會話上的流量控制窗口)參數。流層面和鏈接層面的初始窗口大小需分開指定。
幀格式以下:
--- src 0 1 4 5 12 +--------+--------+-- ... --+-------+--------+-- ... --+-------+ |Type(8) | Stream ID (32 bits) | Byte offset (64 bits) | +--------+--------+-- ... --+-------+--------+-- ... --+-------+ ---
The fields in the WINDOW_UPDATE frame are as follows:
- Frame Type: The Frame Type byte is an 8-bit value that must be set to 0x04 indicating that this is a WINDOW_UPDATE frame.
- Stream ID: ID of the stream whose flow control windows is being updated, or 0 to specify the connection-level flow control window.
- Byte offset: A 64-bit unsigned integer indicating the absolute byte offset of data which can be sent on the given stream. In the case of connection level flow control, the cumulative number of bytes which can be sent on all currently open streams.
窗口更新幀的字段含義以下:
The BLOCKED frame is used to indicate to the remote endpoint that this endpoint is ready to send data (and has data to send), but is currently flow control blocked. This is a purely informational frame, which is extremely useful for debugging purposes. A receiver of a BLOCKED frame should simply discard it (after possibly printing a helpful log message). The frame is as follows:
阻塞信息幀用來通知對端本端已經準備好發送數據(而且有數據須要發送),可是當前被流量控制所阻塞。這是一個對調試極其有用的純信息幀。阻塞信息幀的接收者應該簡單的把這個幀丟棄掉(好比再打印一條有用的日誌信息以後)。幀格式以下:
--- src 0 1 2 3 4 +--------+--------+--------+--------+--------+ |Type(8) | Stream ID (32 bits) | +--------+--------+--------+--------+--------+ ---
The fields in the BLOCKED frame are as follows:
Frame Type: The Frame Type byte is an 8-bit value that must be set to 0x05 indicating that this is a BLOCKED frame.
Stream ID: A 32-bit unsigned number indicating the stream which is flow control blocked. A non-zero Stream ID field specifies the stream that is flow control blocked. When zero, the Stream ID field indicates that the connection is flow control blocked at the connection level.
阻塞信息幀中的字段含義以下:
The CONGESTION_FEEDBACK frame is an experimental frame currently not used. It is intended to provide extra congestion feedback information outside the scope of the standard ack frame. A CONGESTION_FEEDBACK frame must have the first three bits of the Frame Type set to 001. The last 5 bits of the Frame Type field are reserved for future use.
擁塞反饋幀時一個實驗性質的幀當前沒有被使用。目的是在標準的ack幀範圍以外提供額外的擁塞反饋信息。擁塞反饋幀的幀類型的頭3bit必須設置爲001,後5bit保留用於將來使用。
The PADDING frame pads a packet with 0x00 bytes. When this frame is encountered, the rest of the packet is expected to be padding bytes. The frame contains 0x00 bytes and extends to the end of the QUIC packet. A PADDING frame only has a Frame Type field, and must have the 8-bit Frame Type field set to 0x00.
填充幀在包中填充一個0x00字節。當遇到了填充幀,該包的剩餘部分都是填充幀。填充幀包含0x00的字節,而且填充在QUIC包的末尾。填充幀只有一個8bit大小設置爲0x00的幀類型的字段。
The RST_STREAM frame allows for abnormal termination of a stream. When sent by the creator of a stream, it indicates the creator wishes to cancel the stream. When sent by the receiver of a stream, it indicates an error or that the receiver did not want to accept the stream, so the stream should be closed. The frame is as follows:
流重置幀用於異常關閉一個流。當由流建立者發送時,標識了建立者但願取消這個流。當由流接收端發送,標識了一個錯誤或者接收端不但願接受這個流,因此這個流應該被關閉。這個幀的格式以下:
--- src 0 1 4 5 12 8 16 +-------+--------+-- ... ----+--------+-- ... ------+-------+-- ... ------+ |Type(8)| StreamID (32 bits) | Byte offset (64 bits)| Error code (32 bits)| +-------+--------+-- ... ----+--------+-- ... ------+-------+-- ... ------+ ---
The fields in a RST_STREAM frame are as follows:
Frame type: The Frame Type is an 8-bit value that must be set to 0x01 specifying that this is a RST_STREAM frame.
Stream ID: The 32-bit Stream ID of the stream being terminated.
Byte offset: A 64-bit unsigned integer indicating the absolute byte offset of the end of data for this stream.
Error code: A 32-bit QuicErrorCode which indicates why the stream is being closed. QuicErrorCodes are listed later in this document.
流重置幀的字段含義以下:
The PING frame can be used by an endpoint to verify that a peer is still alive. The PING frame contains no payload. The receiver of a PING frame simply needs to ACK the packet containing this frame. The PING frame should be used to keep a connection alive when a stream is open. The default is to do this after 15 seconds of quiescence, which is much shorter than most NATs time out. A PING frame only has a Frame Type field, and must have the 8-bit Frame Type field set to 0x07.
PING幀用於驗證對端是否還存活。PING沒有負載信息。PING幀的接收端須要返回這個包的確認包。當流被打開時,PING幀須要用來保證鏈接活躍。默認靜止15秒後發送,這比大部分NAT超時的時間要短得多。PING幀只有幀類型字段,8bit的幀類型必須設置爲0x07。
The CONNECTION_CLOSE frame allows for notification that the connection is being closed. If there are streams in flight, those streams are all implicitly closed when the connection is closed. (Ideally, a GOAWAY frame would be sent with enough time that all streams are torn down.) The frame is as follows:
鏈接關閉幀用於通知鏈接被關閉。若是還有流在傳輸,全部這些流都被隱式關閉(理論上,一個GOAWAY幀能夠被髮送以留有足夠時間用於關閉全部流)。幀格式以下:
--- src 0 1 4 5 6 7 +--------+--------+-- ... -----+--------+--------+--------+----- ... |Type(8) | Error code (32 bits)| Reason phrase | Reason phrase | | | length (16 bits)|(variable length) +--------+--------+-- ... -----+--------+--------+--------+----- ... ---
The fields of a CONNECTION_CLOSE frame are as follows:
Frame Type: An 8-bit value that must be set to 0x02 specifying that this is a CONNECTION_CLOSE frame.
Error Code: A 32-bit field containing the QuicErrorCode which indicates the reason for closing this connection.
Reason Phrase Length: A 16-bit unsigned number specifying the length of the reason phrase. This may be zero if the sender chooses to not give details beyond the QuicErrorCode.
Reason Phrase: An optional human-readable explanation for why the connection was closed.
鏈接關閉幀的字段含義以下:
幀類型: 8bit,必須設置爲0x02
錯誤碼: 32bit,標識關閉連接緣由的錯誤碼
描述信息長度: 16bit無符號數,標識描述信息的長度。能夠爲0若是發送端認爲在錯誤碼之上不須要給出更詳細的信息
描述信息: 可選字段,可讀字符串用於解釋鏈接關閉的緣由
QUIC Wire Layout Specification - Google 文檔
本文做者: yoko
本文連接: http://www.pengrl.com/p/47156/ 版權聲明: 本博客全部文章除特別聲明外,均採用 CC BY-NC-SA 3.0 許可協議。轉載請註明出處!