- 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
The handshake is responsible for negotiating a variety of transport parameters for a QUIC connection.
- 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 - 连接层面流量控制窗口大小。单位字节。
- 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字段。字段包含了客户端或服务端所要求的连接选项。这些选项通常用于实验并且以后可能会变化。使用场景举例，包括改变拥塞控制算法和初始化窗口的参数。
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)
- 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.
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.
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.
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.
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”.
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].
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:
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.
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.
The QUIC handshake protocol manages to successfully achieve 0-RTT for most connections, and is critical to QUIC’s latency improvements.
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.
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) 足够大以允许存储这些信息。或者，握手协议需有其他方法在客户端存储这些信息。
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.
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 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.
- 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.
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.
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 firstname.lastname@example.org mailing list.