quic transport rfc

2019-03-29  本文已影响0人  涵仔睡觉

[toc]

2 Stream

2.1 Stream Identifiers

Streams are identified by an unsigned 62-bit integer, referred to as
the Stream ID. Stream IDs are encoded as a variable-length integer. The least significant two bits of the Stream ID
are used to identify the type of stream (unidirectional or
bidirectional) and the initiator of the stream.

The least significant bit (0x1) of the Stream ID identifies the
initiator of the stream. Clients initiate even-numbered streams
(those with the least significant bit set to 0); servers initiate
odd-numbered streams (with the bit set to 1).

The second least significant bit (0x2) of the Stream ID
differentiates between unidirectional streams and bidirectional
streams. Unidirectional streams always have this bit set to 1 and
bidirectional streams have this bit set to 0.

+----------+----------------------------------+

| Low Bits | Stream Type |

+----------+----------------------------------+

| 0x0 | Client-Initiated, Bidirectional |

| 0x1 | Server-Initiated, Bidirectional |

| 0x2 | Client-Initiated, Unidirectional |

| 0x3 | Server-Initiated, Unidirectional |

+----------+----------------------------------+

A QUIC endpoint MUST NOT reuse a Stream ID.

2.2 Stream Concurrency

QUIC allows for an arbitrary number of streams to operate
concurrently. An endpoint limits the number of concurrently active
incoming streams by limiting the maximum stream ID.

The maximum stream ID is specific to each endpoint and applies only
to the peer that receives the setting.

A receiver MUST ignore any MAX_STREAM_ID frame that does not increase the maximum stream ID.

2.3 Sending and Receiving Data

Endpoints uses streams to send and receive data. Endpoints send
STREAM frames, which encapsulate data for a stream.

2.4 Stream Prioritization

QUIC does not provide frames for exchanging prioritization
information. Instead it relies on receiving priority information
from the application that uses QUIC.

3 Stream States: Life of a Stream

3.1 Send Stream States

The sending part of stream that the endpoint initiates (types 0 and 2
for clients, 1 and 3 for servers) is opened by the application or
application protocol.

image

3.2 Receive Stream States

The receiving part of a stream initiated by a peer (types 1 and 3 for
a client, or 0 and 2 for a server) are created when the first STREAM,
STREAM_BLOCKED, RST_STREAM, or MAX_STREAM_DATA (bidirectional only,
see below) is received for that stream.

image

3.3 Permitted Frame Types

The sender of a stream sends just three frame types that affect the
state of a stream at either sender or receiver: STREAM, STREAM_BLOCKED, and RST_STREAM.

The receiver of a stream sends MAX_STREAM_DATA and STOP_SENDING frames.

3.4 Bidirectional Stream States

image

3.5 Solicited State Transitions

If an endpoint is no longer interested in the data it is receiving on
a stream, it MAY send a STOP_SENDING frame identifying that stream to
prompt closure of the stream in the opposite direction. This
typically indicates that the receiving application is no longer
reading data it receives from the stream, but is not a guarantee that
incoming data will be ignored.

4 Flow Control

A receiver advertises the number of octets it is prepared
to receive on a given stream and for the entire connection. This
leads to two levels of flow control in QUIC:

A data receiver sends MAX_STREAM_DATA or MAX_DATA frames to the
sender to advertise additional credit.

4.1 Handling of Stream Cancellation

the RST_STREAM frame (Section 19.2) includes the
largest offset of data sent on the stream. On receiving a RST_STREAM
frame, a receiver definitively knows how many bytes were sent on that
stream before the RST_STREAM frame, and the receiver MUST use the
final offset to account for all bytes sent on the stream in its
connection level flow controller.

4.2 Data Limit Increments

A receiver MAY use an autotuning mechanism to tune the frequency and
amount that it increases data limits based on a round-trip time
estimate and the rate at which the receiving application consumes
data, similar to common TCP implementations.

4.3 Stream Final Offset

The final offset is the count of the number of octets that are
transmitted on a stream. For a stream that is reset, the final
offset is carried explicitly in a RST_STREAM frame. Otherwise, the
final offset is the offset of the end of the data carried in a STREAM
frame marked with a FIN flag, or 0 in the case of incoming
unidirectional streams.

4.4 Flow Control for Cryptographic Handshake

QUIC relies on the cryptographic protocol
implementation to avoid excessive buffering of data.

4.5 Stream Limit Increment

An endpoint limits the number of concurrently active incoming streams
by limiting the maximum stream ID.

An initial value is set in the transport parameters and is subsequently increased by MAX_STREAM_ID frames.

5 Connections

A QUIC connection is a single conversation between two QUIC endpoints.

QUIC’s connection establishment combines version
negotiation with the cryptographic and transport handshakes to reduce
connection establishment latency.

5.1 Connection ID

Each connection possesses a set of connection identifiers, or
connection IDs, each of which can be identify the connection.Connection IDs are independently selected by endpoints; each endpoint
selects the connection IDs that its peer uses.

5.1.1 Issuing Connection IDs

Each Connection ID has an associated sequence number to assist in
deduplicating messages. The sequence number of
the initial connection ID is 0. If the preferred_address transport
parameter is sent, the sequence number of the supplied connection ID
is 1.

Additional connection IDs are communicated to the peer using
NEW_CONNECTION_ID frames. The sequence number on
each newly-issued connection ID MUST increase by 1.

5.1.2 Consuming and Retiring Connection IDs

An endpoint can change the connection ID it uses for a peer to
another available one at any time during the connection.

An endpoint maintains a set of connection IDs received from its peer,
any of which it can use when sending packets. When the endpoint
wishes to remove a connection ID from use, it sends a
RETIRE_CONNECTION_ID frame to its peer, indicating that the peer
might bring a new connection ID into circulation using the
NEW_CONNECTION_ID frame.

As discussed in Section 9.5, each connection ID MUST be used on
packets sent from only one local address. An endpoint that migrates
away from a local address SHOULD retire all connection IDs used on
that address once it no longer plans to use that address.

5.2 Matching Packets to Connections

Incoming packets are classified on receipt. Packets can either be
associated with an existing connection, or - for servers -
potentially create a new connection.

5.2.1 Client Packet Handling

Valid packets sent to clients always include a Destination Connection
ID that matches a value the client selects. Clients that choose to
receive zero-length connection IDs can use the address/port tuple to
identify a connection. Packets that don’t match an existing
connection are discarded.

5.2.2 Server Packet Handling

6 Version Negotiation

Version negotiation ensures that client and server agree to a QUIC
version that is mutually supported.

image

6.1 Sending Version Negotiation Packets

If the version selected by the client is not acceptable to the
server, the server responds with a Version Negotiation packet. This includes a list of versions that the server will accept.

6.2 Handling Version Negotiation Packets

The client selects an acceptable protocol version from the list
provided by the server. The client then attempts to create a connection using that version.

The client MUST use the long header format and include its selected
version on all packets until it has 1-RTT keys and it has received a
packet from the server which is not a Version Negotiation packet.

6.3 Using Reserved Versions

7 Cryptographic and Transport Handshake

QUIC relies on a combined cryptographic and transport handshake to
minimize connection establishment latency.

7.1 Example Handshake Flows

image
image

7.2 Negotiating Connection IDs

During the handshake, packets with the long header are
used to establish the connection ID that each endpoint uses. Each
endpoint uses the Source Connection ID field to specify the
connection ID that is used in the Destination Connection ID field of
packets being sent to them. Upon receiving a packet, each endpoint
sets the Destination Connection ID it sends to match the value of the
Source Connection ID that they receive.

7.3 Transport Parameters

During connection establishment, both endpoints make authenticated
declarations of their transport parameters. These declarations are
made unilaterally by each endpoint. Endpoints are required to comply
with the restrictions implied by these parameters; the description of
each parameter includes rules for its handling.

7.3.1 Values of Transport Parameters for 0-RTT

A client that attempts to send 0-RTT data MUST remember the transport
parameters used by the server. The transport parameters that the
server advertises during connection establishment apply to all
connections that are resumed using the keying material established
during that handshake.

7.3.2 New Transport Parameters

New transport parameters can be used to negotiate new protocol behavior.

7.3.3 Version Negotiation Validation

To protect against QUIC version downgrade attacks, the transport parameters include three fields that encode version information. These parameters are used to retroactively authenticate the choice of version.

8 Address Validation

Address validation is used by QUIC to avoid being used for a traffic
amplification attack.

8.1 Address Validation During Connection Establishment

Connection establishment implicitly provides address validation for
both endpoints. In particular, receipt of a packet protected with
Handshake keys confirms that the client received the Initial packet
from the server. Once the server has successfully processed a
Handshake packet from the client, it can consider the client address
to have been validated.

8.1.1 Address Validation using Retry Packets

QUIC uses token-based address validation during connection
establishment.

Upon receiving the client’s Initial packet, the server can request address validation by sending a Retry packet containing a token. This token is repeated by the client in an Initial packet after it receives the Retry packet. In response to receiving a token in an Initial packet, a server can either abort the connection or permit it to proceed.

image

8.1.2 Address Validation for Future Connections

A server MAY provide clients with an address validation token during
one connection that can be used on a subsequent connection.

The server uses the NEW_TOKEN frame to provide the
client with an address validation token that can be used to validate
future connections. The client may then use this token to validate
future connections by including it in the Initial packet’s header.

8.1.3 Address Validation Token Integrity

An address validation token MUST be difficult to guess. Including a
large enough random value in the token would be sufficient, but this
depends on the server remembering the value it sends to clients.

A token could include information about the claimed client address (IP
and port), a timestamp, and any other supplementary information the
server will need to validate the token in the future.

8.2 Path Validation

Path validation is used during connection migration by the migrating endpoint to verify reachability of a peer from a new local address.

Path validation can be used at any time by either endpoint.

8.3 Initiating Path Validation

To initiate path validation, an endpoint sends a PATH_CHALLENGE frame
containing a random payload on the path to be validated.

8.4 Path Validation Responses

On receiving a PATH_CHALLENGE frame, an endpoint MUST respond
immediately by echoing the data contained in the PATH_CHALLENGE frame
in a PATH_RESPONSE frame.

8.5 Successful Path Validation

A new address is considered valid when a PATH_RESPONSE frame is
received containing data that was sent in a previous PATH_CHALLENGE.

For path validation to be successful, a PATH_RESPONSE frame MUST be
received from the same remote address to which the corresponding
PATH_CHALLENGE was sent.

8.6 Failed Path Validation

Path validation only fails when the endpoint attempting to validate
the path abandons its attempt to validate the path.

9 Connection Migration

9.1 Probing a New Path

An endpoint MAY probe for peer reachability from a new local address
using path validation prior to migrating the connection to the new local address.

9.2 Initiating Connection Migration

A migrating endpoint can send to its peer
knowing that the peer is willing to receive at the peer’s current
address. Thus an endpoint can migrate to a new local address without
first validating the peer’s address.

9.3 Responding to Connection Migration

Receiving a packet from a new peer address containing a non-probing
frame indicates that the peer has migrated to that address.
In response to such a packet, an endpoint MUST start sending
subsequent packets to the new peer address and MUST initiate path
validation to verify the peer’s ownership of the unvalidated address.

9.3.1 Handling Address Spoofing by a Peer

An endpoint is required to validate a
peer’s new address to confirm the peer’s possession of the new
address. Until a peer’s address is deemed valid, an endpoint MUST
limit the rate at which it sends data to this address. The endpoint
MUST NOT send more than a minimum congestion window’s worth of data
per estimated round-trip time.

9.3.2 Handling Address Spoofing by an On-path Attacker

An on-path attacker could cause a spurious connection migration by
copying and forwarding a packet with a spoofed address such that it
arrives before the original packet. The packet with the spoofed
address will be seen to come from a migrating connection, and the
original packet will be seen as a duplicate and dropped.

To protect the connection from failing due to such a spurious
migration, an endpoint MUST revert to using the last validated peer
address when validation of a new peer address fails.

9.4 Loss Detection and Congestion Control

The capacity available on the new path might not be the same as the
old path. Packets sent on the old path SHOULD NOT contribute to
congestion control or RTT estimation for the new path.

A sender can make exceptions for probe packets so that their loss detection is
independent and does not unduly cause the congestion controller to
reduce its sending rate. An endpoint might set a separate timer when
a PATH_CHALLENGE is sent, which is cancelled when the corresponding
PATH_RESPONSE is received. If the timer fires before the
PATH_RESPONSE is received, the endpoint might send a new
PATH_CHALLENGE, and restart the timer for a longer period of time.

9.5 Privacy Implications of Connection Migration

An endpoint that moves between networks might not wish to have their
activity correlated by any entity other than their peer, so different
connection IDs are used when sending from different local addresses,
as discussed in Section 5.1. For this to be effective endpoints need
to ensure that connections IDs they provide cannot be linked by any
other entity.

The goal here is to ensure that packets
sent on different paths cannot be correlated. To fulfill this
privacy requirement, endpoints that initiate migration and use
connection IDs with length greater than zero SHOULD provide their
peers with new connection IDs before migration.

9.6 Server’s Preferred Address

QUIC allows servers to accept connections on one IP address and
attempt to transfer these connections to a more preferred address
shortly after the handshake.

9.6.1 Communicating A Preferred Address

A server conveys a preferred address by including the
preferred_address transport parameter in the TLS handshake.
Once the handshake is finished, the client SHOULD initiate path
validation of the server’s preferred address using
the connection ID provided in the preferred_address transport parameter.

9.6.2 Responding to Connection Migration

A server might receive a packet addressed to its preferred IP address
at any time after it accepts a connection. If this packet contains a
PATH_CHALLENGE frame, the server sends a PATH_RESPONSE frame.

The server SHOULD also initiate path validation of the client using
its preferred address and the address from which it received the
client probe.

9.6.3 Interaction of Client Migration and Preferred Address

A client might need to perform a connection migration before it has
migrated to the server’s preferred address. In this case, the client
SHOULD perform path validation to both the original and preferred
server address from the client’s new address concurrently.

If path validation of the server’s preferred address succeeds, the
client MUST abandon validation of the original address and migrate to
using the server’s preferred address. If path validation of the
server’s preferred address fails but validation of the server’s
original address succeeds, the client MAY migrate to its new address
and continue sending to the server’s original address.

10. Connection Termination

Connections should remain open until they become idle for a prenegotiated period of time. A QUIC connection, once established, can
be terminated in one of three ways:

10.1 Closing and Draining Connection States

The closing and draining connection states exist to ensure that connections close cleanly and that delayed or reordered packets are properly discarded.

10.2 Idle Timeout

If the idle timeout is enabled, a connection that remains idle for
longer than the advertised idle timeout is closed.

10.3 Immediate Close

An endpoint sends a closing frame (CONNECTION_CLOSE or
APPLICATION_CLOSE) to terminate the connection immediately. Any
closing frame causes all streams to immediately become closed; open
streams can be assumed to be implicitly reset.

10.4 Stateless Reset

A stateless reset is provided as an option of last resort for an
endpoint that does not have access to the state of a connection.

image

10.4.1 Detecting a Stateless Reset

An endpoint detects a potential stateless reset when a packet with a
short header either cannot be decrypted or is marked as a duplicate
packet.

The endpoint then compares the last 16 octets of the packet
with the Stateless Reset Token provided by its peer.
If these values are identical, the endpoint MUST enter the draining
period and not send any further packets on this connection. If the
comparison fails, the packet can be discarded.

10.4.2 Calculating a Stateless Reset Token

The stateless reset token MUST be difficult to guess. In order to create a Stateless Reset Token, an endpoint could randomly generate a secret for every connection that it creates.

A single static key can be used across all connections to the same
endpoint by generating the proof using a second iteration of a
preimage-resistant function that takes a static key and the
connection ID chosen by the endpoint as input. An
endpoint could use HMAC (for example, HMAC(static_key,
connection_id)) or HKDF (for example, using the static key
as input keying material, with the connection ID as salt). The
output of this function is truncated to 16 octets to produce the
Stateless Reset Token for that connection.

10.4.3 Looping

A Stateless Reset might trigger the sending of a Stateless Reset in response, which could lead to infinite exchanges.

An endpoint MUST ensure that every Stateless Reset that it sends is
smaller than the packet which triggered it, unless it maintains state
sufficient to prevent looping. In the event of a loop, this results
in packets eventually being too small to trigger a response.

11 Error Handling

An endpoint that detects an error SHOULD signal the existence of that
error to its peer.

Both transport-level and application-level errors can affect an entire connection, while only application-level errors can be isolated to a single stream.

11.1 Connection Errors

Errors that result in the connection being unusable, such as an
obvious violation of protocol semantics or corruption of state that
affects an entire connection, MUST be signaled using a
CONNECTION_CLOSE or APPLICATION_CLOSE frame.

11.2 Stream Errors

If an application-level error affects a single stream, but otherwise leaves the connection in a recoverable state, the endpoint can send a RST_STREAM frame with an appropriate error code to terminate just the affected stream. RST_STREAM MUST be instigated by the application and MUST carry an application error code.

12 Packets and Frames

QUIC endpoints communicate by exchanging packets. Packets are carried in UDP datagrams and have confidentiality and integrity protection.

12.1 Protected Packets

All QUIC packets except Version Negotiation and Retry packets use authenticated encryption with additional data (AEAD) to provide confidentiality and integrity protection.

12.2 Coalescing Packets

A sender can coalesce multiple QUIC packets into one UDP datagram.

Every QUIC packet that is coalesced into a single UDP datagram is
separate and complete. Though the values of some fields in the
packet header might be redundant, no fields are omitted. Retry packets, Version Negotiation packets, and packets with a short header cannot be followed by other packets in the same UDP datagram.

12.3 Packet Numbers

The packet number is an integer in the range 0 to 2^62-1.

This number is used in determining the cryptographic nonce for packet protection. Each endpoint maintains a separate packet number for sending and receiving.

12.4 Frames and Frame Types

QUIC payloads MUST contain at least one frame, and MAY contain
multiple frames and multiple frame types.


image image image

13 Packetization and Reliability

A sender can minimize per-packet bandwidth and computational costs by
bundling as many frames as possible within a QUIC packet. A sender
MAY wait for a short period of time to bundle multiple frames before
sending a packet that is not maximally packed, to avoid sending out
large numbers of small packets.

13.1 Packet Processing and Acknowledgment

A packet MUST NOT be acknowledged until packet protection has been successfully removed and all frames contained in the packet have been processed.

13.1.1 Sending ACK Frames

To avoid creating an indefinite feedback loop, an endpoint MUST NOT
send an ACK frame in response to a packet containing only ACK or
PADDING frames, even if there are packet gaps which precede the
received packet. The endpoint MUST however acknowledge packets
containing only ACK or PADDING frames when sending ACK frames in
response to other packets.

13.1.2 ACK Frames and Packet Protection

ACK frames MUST only be carried in a packet that has the same packet
number space as the packet being ACKed.

13.2 Retransmission of Information

In general, information is sent again when a packet containing that information is determined to be lost and sending ceases when a packet containing that information is acknowledged.

13.3 Explicit Congestion Notification(ECN)

QUIC endpoints use Explicit Congestion Notification (ECN) to detect and respond to network congestion.

ECN allows a network node to indicate congestion in the network by setting a codepoint in the IP header of a packet instead of dropping it.

在TCP连接上使用ECN是可选的;对于要使用的ECN,必须在连接建立时通过在SYN和SYN-ACK段中包含合适的选项来协商它。原则上应该可以将ECN与UDP之上的协议一起使用。但是,UDP要求应用程序执行拥塞控制,并且当前的网络API不允许访问ECN位。

ECN使用IPv4或IPv6标头中DiffServ字段的两个最低有效(最右)位来编码四个不同的代码点:

当两个端点都支持ECN时,它们使用ECT(0)或ECT(1)标记其数据包。如果分组遍历正在经历拥塞的活动队列管理(AQM)队列(例如,使用随机早期检测(RED)的队列)并且相应的路由器支持ECN,则它可以将代码点改变为CE而不是丢弃分组。该行为被称为“标记”,其目的是通知接收端点即将发生的拥塞。在接收端点处,该拥塞指示由上层协议(传输层)处理 协议)并且需要回送到发送节点以便发信号以降低其传输速率。

13.3.1 ECN Counters

On receiving a packet with an ECT(ECN Capable Transport) or CE(Congestion Experienced) codepoint, an endpoint that can access the IP ECN codepoints increases the corresponding ECT(0), ECT(1), or CE count, and includes these counters in subsequent ACK frames

13.3.2 ECN Verification

Each endpoint independently verifies and enables use of ECN by
setting the IP header ECN codepoint to ECN Capable Transport (ECT)
for the path from it to the other peer.

To verify both that a path supports ECN and the peer can provide ECN
feedback, an endpoint MUST set the ECT(0) codepoint in the IP header
of all outgoing packets.

14 Packet Size

The QUIC packet size includes the QUIC header and integrity check,
but not the UDP or IP header.

14.1 Path Maximum Transmission Unit

The Path Maximum Transmission Unit (PMTU) is the maximum size of the
entire IP header, UDP header, and UDP payload. The UDP payload
includes the QUIC packet header, protected payload, and any
authentication fields.

Endpoints MAY use PMTU Discovery for detecting the PMTU, setting the PMTU appropriately, and storing the result of previous PMTU determinations. In the absence of these mechanisms, QUIC endpoints SHOULD NOT send IP packets larger than 1280 octets.

14.1.1 IPv4 PMTU Discovery

Endpoints that implement PMTUD in IPv4:

14.2 Special Considerations for Packetization Layer PMTU Discovery

15 Versions

QUIC versions are identified using a 32-bit unsigned number.

16 Variable-Length Integer Encoding

QUIC packets and frames commonly use a variable-length encoding for
non-negative integer values. This encoding ensures that smaller
integer values need fewer octets to encode.

The QUIC variable-length integer encoding reserves the two most
significant bits of the first octet to encode the base 2 logarithm of
the integer encoding length in octets. The integer value is encoded
on the remaining bits, in network byte order.

image

17 Packet Formats

All numeric values are encoded in network byte order (that is, bigendian) and all field sizes are in bits.

17.1 Packet Number Encoding and Decoding

The number of bits required to represent the packet number is first reduced by including only a variable number of the least significant bits of the packet number.

image

The size of the packet number encoding is at least one more than the base 2 logarithm of the number of contiguous unacknowledged packet numbers, including the new packet.

Recovering the full packet number is necessary to successfully remove packet protection. Once packet number protection is removed, the packet number is decoded by finding the packet number value that is closest to the next expected packet. The next expected packet is the highest received packet number plus one.

17.2 Long Header Packet

Long headers are used for packets that are sent prior to the
completion of version negotiation and establishment of 1-RTT keys.

image image

The header form, type, connection ID lengths octet, destination and source connection IDs, and version fields of a long header packet are version-independent. The packet number and values for packet types defined in Table 6 are version-specific.

17.3 Short Header Packet

The short header can be used after the version and 1-RTT keys are
negotiated.

image

The header form and connection ID field of a short header packet are
version-independent. The remaining fields are specific to the
selected QUIC version.

17.4 Version Negotiation Packet

The Version Negotiation packet is a response to a client packet that
contains a version that is not supported by the server, and is only
sent by servers.

image

A Version Negotiation packet cannot be explicitly acknowledged in an ACK frame by a client. Receiving another Initial packet implicitly acknowledges a Version Negotiation packet. A Version Negotiation packet consumes an entire UDP datagram.

17.5 Initial Packet

image

The client and server use the Initial packet type for any packet that
contains an initial cryptographic handshake message.

A server sends its first Initial packet in response to a client
Initial. A server may send multiple Initial packets.

The payload of an Initial packet includes a CRYPTO frame (or frames)
containing a cryptographic handshake message, ACK frames, or both.
PADDING and CONNECTION_CLOSE frames are also permitted.

17.5.1 Starting Packet Numbers

The first Initial packet sent by either endpoint contains a packet
number of 0. The packet number MUST increase monotonically
thereafter.

17.5.2 0-RTT Packet Numbers

A client only receives acknowledgments for its 0-RTT packets once the handshake is complete. Consequently, a server might expect 0-RTT packets to start with a packet number of 0.

A client SHOULD instead generate a fresh cryptographic handshake
message and start packet numbers from 0. This ensures that new 0-RTT
packets will not use the same keys, avoiding any risk of key and
nonce reuse; this also prevents 0-RTT packets from previous handshake
attempts from being accepted as part of the connection.

17.6 Handshake Packet

A Handshake packet is used to carry acknowledgments and cryptographic handshake messages from the server and client.

17.7 Retry Packet

A Retry packet carries an address validation token created by the server. It is used by a server that wishes to perform a stateless retry.

image

18 Transport Parameter Encoding

QUIC encodes transport parameters into a sequence of octets, which
are then included in the cryptographic handshake.

uint32 QuicVersion;
enum {
    initial_max_stream_data_bidi_local(0),
    initial_max_data(1),
    initial_max_bidi_streams(2),
    idle_timeout(3),
    preferred_address(4),
    max_packet_size(5),
    stateless_reset_token(6),
    ack_delay_exponent(7),
    initial_max_uni_streams(8),
    disable_migration(9),
    initial_max_stream_data_bidi_remote(10),
    initial_max_stream_data_uni(11),
    max_ack_delay(12),
    original_connection_id(13),
    (65535)
} TransportParameterId;

struct {
    TransportParameterId parameter;
    opaque value<0..2^16-1>;
} TransportParameter;

struct {
    select (Handshake.msg_type) {
        case client_hello:
            QuicVersion initial_version;
        case encrypted_extensions:
            QuicVersion negotiated_version;
            QuicVersion supported_versions<4..2^8-4>;
    };
    TransportParameter parameters<0..2^16-1>;
} TransportParameters;

struct {
    enum { IPv4(4), IPv6(6), (15) } ipVersion;
    opaque ipAddress<4..2^8-1>;
    uint16 port;
    opaque connectionId<0..18>;
    opaque statelessResetToken[16];
} PreferredAddress;

Figure 15: Definition of TransportParameters

19 Frame Types and Formats

Packets contain one or more frames.

19.1 PADDING Frame

The PADDING frame (type=0x00) has no semantic value. PADDING frames
can be used to increase the size of a packet.

19.2 RST_STREAM Frame

An endpoint may use a RST_STREAM frame (type=0x01) to abruptly
terminate a stream.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Stream ID (i) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Application Error Code (16) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Final Offset (i) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.3 CONNECTION_CLOSE frame

An endpoint sends a CONNECTION_CLOSE frame (type=0x02) to notify its
peer that the connection is being closed. CONNECTION_CLOSE is used
to signal errors at the QUIC layer, or the absence of errors (with
the NO_ERROR code).

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       Error Code (16)       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Frame Type (i) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   Reason Phrase Length (i) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Reason Phrase (*) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.4 APPLICATION_CLOSE frame

An APPLICATION_CLOSE frame (type=0x03) is used to signal an error
with the protocol that uses QUIC.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       Error Code (16)       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   Reason Phrase Length (i)                 ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Reason Phrase (*)                    ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.5 MAX_DATA Frame

The MAX_DATA frame (type=0x04) is used in flow control to inform the
peer of the maximum amount of data that can be sent on the connection
as a whole.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Maximum Data (i)                    ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.6 MAX_STREAM_DATA Frame

The MAX_STREAM_DATA frame (type=0x05) is used in flow control to
inform a peer of the maximum amount of data that can be sent on a
stream.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Stream ID (i)                        ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Maximum Stream Data (i)                  ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.7 MAX_STREAM_ID Frame

The MAX_STREAM_ID frame (type=0x06) informs the peer of the maximum
stream ID that they are permitted to open.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Maximum Stream ID (i)                  ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.8 PING Frame

Endpoints can use PING frames (type=0x07) to verify that their peers are still alive or to check reachability to the peer. The PING frame contains no additional fields. The receiver of a PING frame simply needs to acknowledge the packet containing this frame.

19.9 BLOCKED Frame

A sender SHOULD send a BLOCKED frame (type=0x08) when it wishes to send data, but is unable to due to connection-level flow control. BLOCKED frames can be used as input to tuning of flow control algorithms.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Offset (i)                       ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.10 STREAM_BLOCKED Frame

A sender SHOULD send a STREAM_BLOCKED frame (type=0x09) when it
wishes to send data, but is unable to due to stream-level flow
control.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Stream ID (i)                     ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Offset (i)                       ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.11 STREAM_ID_BLOCKED Frame

A sender SHOULD send a STREAM_ID_BLOCKED frame (type=0x0a) when it
wishes to open a stream, but is unable to due to the maximum stream
ID limit set by its peer.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Stream ID (i)                     ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.12 NEW_CONNECTION_ID Frame

An endpoint sends a NEW_CONNECTION_ID frame (type=0x0b) to provide
its peer with alternative connection IDs that can be used to break
linkability when migrating connections.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length (8)    |           Sequence Number (i)               ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   Connection ID (32..144)                   ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+               Stateless Reset Token (128)                     +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.13 RETIRE_CONNECTION_ID Frame

An endpoint sends a RETIRE_CONNECTION_ID frame (type=0x1b) to
indicate that it will no longer use a connection ID that was issued
by its peer. Sending a RETIRE_CONNECTION_ID frame also serves as a
request to the peer to send additional connection IDs for future use. New connection IDs can be delivered to a peer using the NEW_CONNECTION_ID frame.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Sequence Number (i)                     ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.14 STOP_SENDING Frame

An endpoint may use a STOP_SENDING frame (type=0x0c) to communicate that incoming data is being discarded on receipt at application request. This signals a peer to abruptly terminate transmission on a stream.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Stream ID (i)                     ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Application Error Code (16) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.15 ACK Frame

Receivers send ACK frames (types 0x1a and 0x1b) to inform senders of
packets they have received and processed. The ACK frame contains one
or more ACK Blocks. ACK Blocks are ranges of acknowledged packets.
If the frame type is 0x1b, ACK frames also contain the sum of ECN
marks received on the connection up until this point.

It is expected that a sender will reuse the same packet number across
different packet number spaces. ACK frames only acknowledge the
packet numbers that were transmitted by the sender in the same packet
number space of the packet that the ACK was received in.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                   Largest Acknowledged (i)                  ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       ACK Delay (i)                         ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    ACK Block Count (i)                      ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       ACK Blocks (*)                        ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       [ECN Section]                         ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.15.1 ACK Block Section

The ACK Block Section consists of alternating Gap and ACK Block
fields in descending packet number order.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       First ACK Block (i)                   ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Gap (i)                          ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Additional ACK Block (i)                 ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Gap (i)                          ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Additional ACK Block (i)                 ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                             ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Gap (i)                          ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Additional ACK Block (i)                 ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.15.2 ECN section

The ECN section should only be parsed when the ACK frame type byte is
0x1b.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     ECT(0) Count (i)                        ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     ECT(1) Count (i)                        ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     ECN-CE Count (i)                        ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.16 PATH_CHALLENGE Frame

Endpoints can use PATH_CHALLENGE frames (type=0x0e) to check reachability to the peer and for path validation during connection migration.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                            Data (8)                           +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.17 PATH_RESPONSE Frame

The PATH_RESPONSE frame (type=0x0f) is sent in response to a PATH_CHALLENGE frame.

19.18 NEW_TOKEN frame

A server sends a NEW_TOKEN frame (type=0x19) to provide the client a token to send in the header of an Initial packet for a future connection.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       Token Length (i)                      ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Token (*)                         ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.19 STREAM Frames

STREAM frames implicitly create a stream and carry stream data. The STREAM frame takes the form 0b00010XXX (or the set of values from 0x10 to 0x17).

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Stream ID (i)                        ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        [Offset (i)]                         ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        [Length (i)]                         ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Stream Data (*)                      ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.20 CRYPTO Frame

The CRYPTO frame (type=0x18) is used to transmit cryptographic handshake messages. It can be sent in all packet types.

0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Offset (i)                          ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Length (i)                          ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Crypto Data (*)                      ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

19.21 Extension Frames

An extension to QUIC that wishes to use a new type of frame MUST
first ensure that a peer is able to understand the frame. An
endpoint can use a transport parameter to signal its willingness to
receive one or more extension frame types with the one transport
parameter.

20 Transport Error Codes

QUIC error codes are 16-bit unsigned integers.

20.1 Application Protocol Error Codes

Application protocol error codes are 16-bit unsigned integers, but the management of application error codes are left to application protocols. Application protocol error codes are used for the RST_STREAM and APPLICATION_CLOSE frames. QUIC reserves the error code with a value of 0 to mean STOPPING.

上一篇下一篇

猜你喜欢

热点阅读