[译] QUIC Wire Layout Specificati
欢迎访问我的个人网站获取更佳阅读体验:[译] QUIC Wire Layout Specification - QUIC Transport Parameters & Handshake Protocol Requirements | QUIC协议标准中文翻译(5) 传输参数以及握手协议必需条件 | yoko blog
(https://pengrl.com/p/45849/)
目录
- QUIC Transport Parameters | QUIC传输参数
- Required Parameters | 必须参数
- Optional Parameters | 可选参数
- QuicErrorCodes | QUIC错误码
- Priority | 优先级
- HTTP/2 Layering over QUIC | 基于QUIC的HTTP/2
- Stream Management
- HTTP/2 Header Compression
- Parsing HTTP/2 Headers
- QUIC Negotiation in HTTP
- Handshake Protocol Requirements | 握手协议必需条件
- Connection Establishment in 0-RTT | 0-RTT建立连接
- Source Address Spoofing Defense | 源地址欺骗防御
- Opaque Source Address Tokens | 不透明的源地址令牌
- Transport Parameter Negotiation | 传输参数协商
- Certificate Compression | 证书压缩
- Server Config Update | 服务端配置升级
- Recent Changes By Version
- Contributors
- Acknowledgments
QUIC Transport Parameters | QUIC传输参数
The handshake is responsible for negotiating a variety of transport parameters for a QUIC connection.
握手负责为QUIC连接协商一系列的传输参数。
Required Parameters | 必须参数
- SFCW - Stream Flow Control Window. The size in bytes of the stream level flow control window.
- CFCW - Connection Flow Control Window. The size in bytes of the connection level flow control window.
- SFCW - 流层面流量控制窗口大小。单位为字节。
- CFCW - 连接层面流量控制窗口大小。单位字节。
Optional Parameters | 可选参数
- SRBF - Socket receive buffer size in bytes. The peer may want to limit their max CWND to something similar to the socket receive buffer if they fear the peer may sometimes be delayed in reading packets from kernel’s socket buffer. Defaults to 256kbytes and has a minimum value of 16kbytes.
- TCID - Connection ID truncation. Indicates support for truncated Connection IDs. If sent by a peer, indicates the connection IDs sent to the peer should be truncated to 0 bytes. Useful for cases when a client ephemeral port is only used for a single connection.
- COPT - Connection Options are a repeated tag field. The field contains any connection options being requested by the client or server. These are typically used for experimentation and will evolve over time. Example use cases include changing congestion control algorithms and parameters such as initial window.
- SRBF - socket接收缓冲区大小,单位字节。对端可能限制它的最大拥塞窗口大小类似于socket接收缓冲区大小,以避免对端从内核socket缓冲区读取数据有时可能会延时。默认值为256kbytes,最小值为16kbytes。
- TCID - 去除连接ID。标识支持去除连接ID。如果一端发送了,标识发往该端的连接ID字段需要去除。当客户端的临时端口只用于一个连接时有用。
- COPT - 连接选项是多个tag字段。字段包含了客户端或服务端所要求的连接选项。这些选项通常用于实验并且以后可能会变化。使用场景举例,包括改变拥塞控制算法和初始化窗口的参数。
QuicErrorCodes | QUIC错误码
The number to code mappings for QuicErrorCodes are currently defined in the Chromium source code in src/net/quic/quic_protocol.h. (TODO: hardcode numbers and add them here)
对应错误码的错误数值目前被定义在Chromium的源码中,源码文件为 src/net/quic/quic_protocol.h(TODO:将硬编码的错误数值添加至此)
- QUIC_NO_ERROR: There was no error. This is not valid for RST_STREAM frames or CONNECTION_CLOSE frames
- QUIC_STREAM_DATA_AFTER_TERMINATION: There were data frames after the a fin or reset.
- QUIC_SERVER_ERROR_PROCESSING_STREAM: There was some server error which halted stream processing.
- QUIC_MULTIPLE_TERMINATION_OFFSETS: The sender received two mismatching fin or reset offsets for a single stream.
- QUIC_BAD_APPLICATION_PAYLOAD: The sender received bad application data.
- QUIC_INVALID_PACKET_HEADER: The sender received a malformed packet header.
- QUIC_INVALID_FRAME_DATA: The sender received an frame data. The more detailed error codes below are prefered where possible.
- QUIC_INVALID_FEC_DATA: FEC data is malformed.
- QUIC_INVALID_RST_STREAM_DATA: Stream rst data is malformed
- QUIC_INVALID_CONNECTION_CLOSE_DATA: Connection close data is malformed.
- QUIC_INVALID_ACK_DATA: Ack data is malformed.
- QUIC_DECRYPTION_FAILURE: There was an error decrypting.
- QUIC_ENCRYPTION_FAILURE: There was an error encrypting.
- QUIC_PACKET_TOO_LARGE: The packet exceeded MaxPacketSize.
- QUIC_PACKET_FOR_NONEXISTENT_STREAM: Data was sent for a stream which did not exist.
- QUIC_CLIENT_GOING_AWAY: The client is going away (browser close, etc.)
- QUIC_SERVER_GOING_AWAY: The server is going away (restart etc.)
- QUIC_INVALID_STREAM_ID: A stream ID was invalid.
- QUIC_TOO_MANY_OPEN_STREAMS: Too many streams already open.
- QUIC_CONNECTION_TIMED_OUT: We hit our pre-negotiated (or default) timeout
- QUIC_CRYPTO_TAGS_OUT_OF_ORDER: Handshake message contained out of order tags.
- QUIC_CRYPTO_TOO_MANY_ENTRIES: Handshake message contained too many entries.
- QUIC_CRYPTO_INVALID_VALUE_LENGTH: Handshake message contained an invalid value length.
- QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE: A crypto message was received after the handshake was complete.
- QUIC_INVALID_CRYPTO_MESSAGE_TYPE: A crypto message was received with an illegal message tag.
- QUIC_SEQUENCE_NUMBER_LIMIT_REACHED: Transmitting an additional packet would cause a packet number to be reused.
Priority | 优先级
(TODO: implement)
QUIC will use the HTTP/2 prioritization mechanism. Roughly, a stream may be dependent on another stream. In this situation, the "parent" stream should effectively starve the "child" stream. In addition, parent streams have an explicit priority. Parent streams should not starve other parent streams, but should make progress proportional to their relative priority.
(TODO:实现)
QUIC将使用HTTP/2的优先级机制。粗略的说,一个流可能依赖另一个流。在这种情况,父类流可能会饿死子类流。此外,父类流拥有显式的优先级。父类流不应该饿死其他父类流,但是应该根据它们的相对优先级来调整进度。
HTTP/2 Layering over QUIC | 基于QUIC的HTTP/2
Since QUIC integrates various HTTP/2 mechanisms with transport mechanisms, QUIC implements a number of features that are also specified in HTTP/2. As a result, QUIC allows HTTP/2 mechanisms to be replaced by QUIC's implementation, reducing complexity in the HTTP/2 protocol. This section briefly describes how HTTP/2 semantics can be offered over a QUIC implementation.
Stream Management
When HTTP/2 headers and data are sent over QUIC, the QUIC layer handles most of the stream management. HTTP/2 Stream IDs are replaced by QUIC Stream IDs. HTTP/2 does not need to do any explicit stream framing when using QUIC---data sent over a QUIC stream simply consists of HTTP/2 headers or body. Requests and responses are considered complete when the QUIC stream is closed in the corresponding direction.
Stream flow control is handled by QUIC, and does not need to be re-implemented in HTTP/2. QUIC's flow controller replaces the two levels of poorly matched flow controllers in current HTTP/2 deployments---one at the HTTP/2 level, and the other at the TCP level.
HTTP/2 Header Compression
QUIC implements HPACK header compression for HTTP/2 [RFC7541], which unfortunately introduces some Head-of-Line blocking since HTTP/2 header blocks must be decompressed in the order they were compressed.
Since streams may be processed in arbitrary order at a receiver, strict ordering across headers is enforced by sending all headers on a dedicated headers stream, with Stream ID 3. An HTTP/2 receiver using QUIC would thus process data from a stream only after receiving the corresponding header on the headers stream.
Future work will tweak the compressor and decompressor in QUIC so that the compressed output does not depend on unacked previous compressed state. This could be done, perhaps, by creating "checkpoints" of HPACK state which are updated when headers have been acked. When compressing headers QUIC would only compress relative to the previous "checkpoint".
Parsing HTTP/2 Headers
Bytes sent on the dedicated headers stream are simply HTTP/2 HEADERS frames. The exact layout of these frames is described in Section 6.2 of [RFC7540].
QUIC Negotiation in HTTP
The Alternate-Protocol header is used to negotiate use of QUIC on future HTTP requests. To specify QUIC as an alternate protocol available on port 123, a server uses:
--- src
"Alternate-Protocol: 123:quic"
---
When a client receives a Alternate-Protocol header advertising QUIC, it can then attempt to use QUIC for future secure connections on that domain. Since middleboxes and/or firewalls can block QUIC and/or UDP communication, a client should implement a graceful fallback to TCP when QUIC reachability is broken.
Note that the server may reply with multiple field values or a comma-separated field value for Alternate-Protocol to indicate the various transports it supports.
A server can also send a header to notify that QUIC should not be used on this domain. If it sends the alternate-protocol-required header, the client should remember to not use QUIC on that domain in future, and not do any UDP probing to see if QUIC is available.
Handshake Protocol Requirements | 握手协议必需条件
QUIC provides a dedicated stream (Stream ID 1) to be used for performing a combined connection and security handshake, but the details of this handshake protocol are out of this document's scope. However, QUIC does impose a number of requirements on any such handshake protocol. The following list of requirements documents properties of the current prototype handshake which should be provided by any future handshake protocol.
QUIC提供了一个专用的流(流ID为1)用于处理连接和安全性握手,但是握手协议的细节超出了本文档的范围。然而,对于任何QUIC的握手协议来说,QUIC确实强制了一系列的必需条件。接下来的必需条件列表是目前握手的原型,将来的握手协议也需遵守这些条件。
Connection Establishment in 0-RTT | 0-RTT建立连接
The QUIC handshake protocol manages to successfully achieve 0-RTT for most connections, and is critical to QUIC's latency improvements.
QUIC握手协议设法为大部分连接成功达到0-RTT的目标,改善QUIC的时延是首要目标。
Source Address Spoofing Defense | 源地址欺骗防御
TCP verifies the client’s address by burning a round trip on the SYN, SYN_ACK exchange. QUIC uses a source address token delivered by the server in a previous connection.
TCP通过一次往返的SYN,SYN_ACK交换信息来验证客户端的地址。QUIC使用一个服务端在上一个连接发送的源地址token。
Opaque Source Address Tokens | 不透明的源地址令牌
QUIC servers store a number of pieces of data in the source address token, for use on a subsequent connection from the same client. This includes recently used source addresses, measured bandwidth to the client, and server-designated connection IDs (for Stateless REJs). An alternative handshake protocol’s analog of a source address token needs to be (i) opaque at the client, and (ii) large enough to permit these bits of information to be stored. Alternatively, the handshake protocol should have a different method to store this information at the client.
QUIC服务端在源地址令牌中保存了一系列的数据,为同一个客户端的后续连接所使用。包含了最近使用的源地址,与该客户端间测量过的带宽,以及服务端指定的连接ID(为了无状态的REJ)。一个可替代的握手协议必须提供相似的源地址令牌,满足以下条件:(i) 对于客户端是透明的 (ii) 足够大以允许存储这些信息。或者,握手协议需有其他方法在客户端存储这些信息。
Transport Parameter Negotiation | 传输参数协商
In addition to negotiating crypto parameters, the QUIC handshake also negotiates QUIC and HTTP/2 level parameters, including max open QUIC streams and other QUIC connection options.
作为加密参数协商的补充,QUIC握手需协商QUIC和HTTP/2层面的参数,包括最大打开QUIC流数量以及其他QUIC连接选项。
Certificate Compression | 证书压缩
The QUIC handshake compresses certificates so that an REJ, including the common Google certificate chain, is able to fit into two 1350 byte packets. This helps to reduce the amplification attack footprint of QUIC without reducing 0-RTT rate.
QUIC握手需压缩证书,这样,一个REJ,包含公共google证书链条,可以放进两个1350字节的包中。这有助于降低QUIC的签名攻击而不需要降低0-RTT的比例。
Server Config Update | 服务端配置升级
QUIC uses a Server Config Update (SCUP) message to refresh the source-address token (STK) and server config mid-connection, extending the period over which 0-RTT connections can be established by the client.
QUIC使用一个服务端配置升级(SCUP)消息来刷新源地址令牌(STK)以及服务端配置中间连接,延长客户端可以建立0-RTT连接的时间。
Recent Changes By Version
- Q009: added priority as the first 4 bytes on spdy streams.
- Q010: renumber the various frame types
- Q011: shrunk the fnv128 hash on NULL encrypted packets from 16 bytes to 12 bytes.
- Q012: optimize the ack frame format to reduce the size and better handle ranges of nacks, which should make truncated acks virtually impossible. Also adding an explicit flag for truncated acks and moving the ack outside of the connection close frame.
- Q013: Compressed headers for all data streams are serialized into a reserved stream. This ensures serialized handling of headers, independent of stream cancellation notification.
- Q014: Added WINDOW_UPDATE and BLOCKED frames, no behavioral change.
- Q015: Removes the accumulated_number_of_lost_packets field from the TCP and inter arrival congestion feedback frames and adds an explicit list of recovered packets to the ack frame.
- Q016: Breaks out the sent_info field from the ACK frame into a new STOP_WAITING frame.
- Changed GUID to Connection ID
- Q017: Adds stream level flow control
- Q018: Added a PING frame
- Q019: Adds session/connection level flow control
- Q020: Allow endpoints to set different stream/session flow control windows
- Q021: Crypto and headers streams are flow controlled (at stream level)
- Q023: Ack frames include packet timestamps
- Q024: HTTP/2-style header compression
- Q025: HTTP/2-style header keys. Removal of error_details from the RST_STREAM frame.
- Q026: Token binding, adds expected leaf cert (XLCT) tag to client hello
- Q027: Adds a nonce to the server hello
- Q029: Server and client honor QUIC_STREAM_NO_ERROR on early response
- Q030: Add server side support of certificate transparency.
- Q031: Adds a SHA256 hash of the serialized client hello messages to crypto proof.
- Q032: FEC related fields are removed from wire format.
- Q033: Adds an optional diversification nonce to packet headers, and eliminates the 2 byte and 4 byte connection ID length public flags.
- Q034: Removes entropy and private flags and changes the ack frame from nack ranges to ack ranges and removes truncated acks.
- Q035: Allows each endpoint to independently set maximum number of supported incoming streams using the MIDS ("Maximum Incoming Dynamic Streams") tag instead of the older MSPC ("Maximum Streams Per Connection") tag.
- Q036: Adds support for inducing head-of-line blocking between streams via the new FHOL tag in the handshake.
Contributors
This protocol is the outcome of work by many engineers, not just the authors of this document. The design and rationale behind QUIC draw significantly from work by Jim Roskind. In alphabetical order, the contributors to the project are: Britt Cyr, Jeremy Dorfman, Ryan Hamilton, Jana Iyengar, Fedor Kouranov, Charles Krasic, Jo Kulik, Adam Langley, Jim Roskind, Robbie Shade, Satyam Shekhar, Cherie Shi, Ian Swett, Raman Tenneti, Victor Vasiliev, Antonio Vicente, Patrik Westin, Alyssa Wilk, Dale Worley, Fan Yang, Dan Zhang, Daniel Ziegler.
Acknowledgments
Special thanks are due to the following for helping shape QUIC and its deployment: Chris Bentzel, Misha Efimov, Roberto Peon, Alistair Riddoch, Siddharth Vijayakrishnan, and Assar Westerlund. QUIC has also benefited immensely from discussions with folks in private conversations and public ones on the proto-quic@chromium.org mailing list.