https://datatracker.ietf.org/doc/draft-ietf-quic-transport/?include_text=1
https://blog.csdn.net/hunter___/article/details/88786666
1. Introduction
QUIC is a multiplexed and secure general-purpose transport protocol
that provides:
o Stream multiplexing
o Stream and connection-level flow control
o Low-latency connection establishment
Iyengar & Thomson Expires July 27, 2019 [Page 5]
Internet-Draft QUIC Transport Protocol January 2019
o Connection migration and resilience to NAT rebinding
o Authenticated and encrypted header and payload
QUIC uses UDP as a substrate to avoid requiring changes to legacy
client operating systems and middleboxes. QUIC authenticates all of
its headers and encrypts most of the data it exchanges, including its
signaling, to avoid incurring a dependency on middleboxes.
1.1. Document Structure
This document describes the core QUIC protocol and is structured as
follows.
o Streams are the basic service abstraction that QUIC provides.
* Section 2 describes core concepts related to streams,
* Section 3 provides a reference model for stream states, and
* Section 4 outlines the operation of flow control.
o Connections are the context in which QUIC endpoints communicate.
* Section 5 describes core concepts related to connections,
* Section 6 describes version negotiation,
* Section 7 details the process for establishing connections,
* Section 8 specifies critical denial of service mitigation
mechanisms,
* Section 9 describes how endpoints migrate a connection to a new
network path,
* Section 10 lists the options for terminating an open
connection, and
* Section 11 provides general guidance for error handling.
o Packets and frames are the basic unit used by QUIC to communicate.
* Section 12 describes concepts related to packets and frames,
* Section 13 defines models for the transmission, retransmission,
and acknowledgement of data, and
Iyengar & Thomson Expires July 27, 2019 [Page 6]
Internet-Draft QUIC Transport Protocol January 2019
* Section 14 specifies rules for managing the size of packets.
o Finally, encoding details of QUIC protocol elements are described
in:
* Section 15 (Versions),
* Section 16 (Integer Encoding),
* Section 17 (Packet Headers),
* Section 18 (Transport Parameters),
* Section 19 (Frames), and
* Section 20 (Errors).
Accompanying documents describe QUIC's loss detection and congestion
control [QUIC-RECOVERY], and the use of TLS for key negotiation
[QUIC-TLS].
This document defines QUIC version 1, which conforms to the protocol
invariants in [QUIC-INVARIANTS].
1.2. Terms and Definitions
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in BCP
14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
Commonly used terms in the document are described below.
QUIC: The transport protocol described by this document. QUIC is a
name, not an acronym.
QUIC packet: The smallest unit of QUIC that can be encapsulated in a
UDP datagram. Multiple QUIC packets can be encapsulated in a
single UDP datagram.
Endpoint: An entity that can participate in a QUIC connection by
generating, receiving, and processing QUIC packets. There are
only two types of endpoint in QUIC: client and server.
Client: The endpoint initiating a QUIC connection.
Server: The endpoint accepting incoming QUIC connections.
Iyengar & Thomson Expires July 27, 2019 [Page 7]
Internet-Draft QUIC Transport Protocol January 2019
Connection ID: An opaque identifier that is used to identify a QUIC
connection at an endpoint. Each endpoint sets a value for its
peer to include in packets sent towards the endpoint.
Stream: A unidirectional or bidirectional channel of ordered bytes
within a QUIC connection. A QUIC connection can carry multiple
simultaneous streams.
Application: An entity that uses QUIC to send and receive data.
1.3. Notational Conventions
Packet and frame diagrams in this document use the format described
in Section 3.1 of [RFC2360], with the following additional
conventions:
[x]: Indicates that x is optional
x (A): Indicates that x is A bits long
x (A/B/C) ...: Indicates that x is one of A, B, or C bits long
x (i) ...: Indicates that x uses the variable-length encoding in
Section 16
x (*) ...: Indicates that x is variable-length
2. Streams
Streams in QUIC provide a lightweight, ordered byte-stream
abstraction to an application. An alternative view of QUIC streams
is as an elastic "message" abstraction.
Streams can be created by sending data. Other processes associated
with stream management - ending, cancelling, and managing flow
control - are all designed to impose minimal overheads. For
instance, a single STREAM frame (Section 19.8) can open, carry data
for, and close a stream. Streams can also be long-lived and can last
the entire duration of a connection.
Streams can be created by either endpoint, can concurrently send data
interleaved with other streams, and can be cancelled. Any stream can
be initiated by either endpoint. QUIC does not provide any means of
ensuring ordering between bytes on different streams.
QUIC allows for an arbitrary number of streams to operate
concurrently and for an arbitrary amount of data to be sent on any
Iyengar & Thomson Expires July 27, 2019 [Page 8]
Internet-Draft QUIC Transport Protocol January 2019
stream, subject to flow control constraints (see Section 4) and
stream limits.
2.1. Stream Types and Identifiers
Streams can be unidirectional or bidirectional. Unidirectional
streams carry data in one direction: from the initiator of the stream
to its peer. Bidirectional streams allow for data to be sent in both
directions.
Streams are identified within a connection by a numeric value,
referred to as the stream ID. Stream IDs are unique to a stream. A
QUIC endpoint MUST NOT reuse a stream ID within a connection. Stream
IDs are encoded as variable-length integers (see Section 16).
The least significant bit (0x1) of the stream ID identifies the
initiator of the stream. Client-initiated streams have even-numbered
stream IDs (with the bit set to 0), and server-initiated streams have
odd-numbered stream IDs (with the bit set to 1).
The second least significant bit (0x2) of the stream ID distinguishes
between bidirectional streams (with the bit set to 0) and
unidirectional streams (with the bit set to 1).
The least significant two bits from a stream ID therefore identify a
stream as one of four types, as summarized in Table 1.
+------+----------------------------------+
| Bits | Stream Type |
+------+----------------------------------+
| 0x0 | Client-Initiated, Bidirectional |
| | |
| 0x1 | Server-Initiated, Bidirectional |
| | |
| 0x2 | Client-Initiated, Unidirectional |
| | |
| 0x3 | Server-Initiated, Unidirectional |
+------+----------------------------------+
Table 1: Stream ID Types
Within each type, streams are created with numerically increasing
stream IDs. A stream ID that is used out of order results in all
streams of that type with lower-numbered stream IDs also being
opened.
The first bidirectional stream opened by the client has a stream ID
of 0.
Iyengar & Thomson Expires July 27, 2019 [Page 9]
Internet-Draft QUIC Transport Protocol January 2019
2.2. Sending and Receiving Data
STREAM frames (Section 19.8) encapsulate data sent by an application.
An endpoint uses the Stream ID and Offset fields in STREAM frames to
place data in order.
Endpoints MUST be able to deliver stream data to an application as an
ordered byte-stream. Delivering an ordered byte-stream requires that
an endpoint buffer any data that is received out of order, up to the
advertised flow control limit.
QUIC makes no specific allowances for delivery of stream data out of
order. However, implementations MAY choose to offer the ability to
deliver data out of order to a receiving application.
An endpoint could receive data for a stream at the same stream offset
multiple times. Data that has already been received can be
discarded. The data at a given offset MUST NOT change if it is sent
multiple times; an endpoint MAY treat receipt of different data at
the same offset within a stream as a connection error of type
PROTOCOL_VIOLATION.
Streams are an ordered byte-stream abstraction with no other
structure that is visible to QUIC. STREAM frame boundaries are not
expected to be preserved when data is transmitted, when data is
retransmitted after packet loss, or when data is delivered to the
application at a receiver.
An endpoint MUST NOT send data on any stream without ensuring that it
is within the flow control limits set by its peer. Flow control is
described in detail in Section 4.
2.3. Stream Prioritization
Stream multiplexing can have a significant effect on application
performance if resources allocated to streams are correctly
prioritized.
QUIC does not provide frames for exchanging prioritization
information. Instead it relies on receiving priority information
from the application that uses QUIC.
A QUIC implementation SHOULD provide ways in which an application can
indicate the relative priority of streams. When deciding which
streams to dedicate resources to, the implementation SHOULD use the
information provided by the application.
Iyengar & Thomson Expires July 27, 2019 [Page 10]
Internet-Draft QUIC Transport Protocol January 2019
3. Stream States
This section describes streams in terms of their send or receive
components. Two state machines are described: one for the streams on
which an endpoint transmits data (Section 3.1), and another for
streams on which an endpoint receives data (Section 3.2).
Unidirectional streams use the applicable state machine directly.
Bidirectional streams use both state machines. For the most part,
the use of these state machines is the same whether the stream is
unidirectional or bidirectional. The conditions for opening a stream
are slightly more complex for a bidirectional stream because the
opening of either send or receive sides causes the stream to open in
both directions.
An endpoint MUST open streams of the same type in increasing order of
stream ID.
Note: These states are largely informative. This document uses
stream states to describe rules for when and how different types
of frames can be sent and the reactions that are expected when
different types of frames are received. Though these state
machines are intended to be useful in implementing QUIC, these
states aren't intended to constrain implementations. An
implementation can define a different state machine as long as its
behavior is consistent with an implementation that implements
these states.
3.1. Sending Stream States
Figure 1 shows the states for the part of a stream that sends data to
a peer.
Iyengar & Thomson Expires July 27, 2019 [Page 11]
Internet-Draft QUIC Transport Protocol January 2019
o
| Create Stream (Sending)
| Peer Creates Bidirectional Stream
v
+-------+
| Ready | Send RESET_STREAM
| |-----------------------.
+-------+ |
| |
| Send STREAM / |
| STREAM_DATA_BLOCKED |
| |
| Peer Creates |
| Bidirectional Stream |
v |
+-------+ |
| Send | Send RESET_STREAM |
| |---------------------->|
+-------+ |
| |
| Send STREAM + FIN |
v v
+-------+ +-------+
| Data | Send RESET_STREAM | Reset |
| Sent |------------------>| Sent |
+-------+ +-------+
| |
| Recv All ACKs | Recv ACK
v v
+-------+ +-------+
| Data | | Reset |
| Recvd | | Recvd |
+-------+ +-------+
Figure 1: States for Sending Parts of Streams
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. The
"Ready" state represents a newly created stream that is able to
accept data from the application. Stream data might be buffered in
this state in preparation for sending.
Sending the first STREAM or STREAM_DATA_BLOCKED frame causes a
sending part of a stream to enter the "Send" state. An
implementation might choose to defer allocating a stream ID to a
stream until it sends the first frame and enters this state, which
can allow for better stream prioritization.
Iyengar & Thomson Expires July 27, 2019 [Page 12]
Internet-Draft QUIC Transport Protocol January 2019
The sending part of a bidirectional stream initiated by a peer (type
0 for a server, type 1 for a client) enters the "Ready" state then
immediately transitions to the "Send" state if the receiving part
enters the "Recv" state (Section 3.2).
In the "Send" state, an endpoint transmits - and retransmits as
necessary - stream data in STREAM frames. The endpoint respects the
flow control limits set by its peer, and continues to accept and
process MAX_STREAM_DATA frames. An endpoint in the "Send" state
generates STREAM_DATA_BLOCKED frames if it is blocked from sending by
stream or connection flow control limits Section 4.1.
After the application indicates that all stream data has been sent
and a STREAM frame containing the FIN bit is sent, the sending part
of the stream enters the "Data Sent" state. From this state, the
endpoint only retransmits stream data as necessary. The endpoint
does not need to check flow control limits or send
STREAM_DATA_BLOCKED frames for a stream in this state.
MAX_STREAM_DATA frames might be received until the peer receives the
final stream offset. The endpoint can safely ignore any
MAX_STREAM_DATA frames it receives from its peer for a stream in this
state.
Once all stream data has been successfully acknowledged, the sending
part of the stream enters the "Data Recvd" state, which is a terminal
state.
From any of the "Ready", "Send", or "Data Sent" states, an
application can signal that it wishes to abandon transmission of
stream data. Alternatively, an endpoint might receive a STOP_SENDING
frame from its peer. In either case, the endpoint sends a
RESET_STREAM frame, which causes the stream to enter the "Reset Sent"
state.
An endpoint MAY send a RESET_STREAM as the first frame that mentions
a stream; this causes the sending part of that stream to open and
then immediately transition to the "Reset Sent" state.
Once a packet containing a RESET_STREAM has been acknowledged, the
sending part of the stream enters the "Reset Recvd" state, which is a
terminal state.
3.2. Receiving Stream States
Figure 2 shows the states for the part of a stream that receives data
from a peer. The states for a receiving part of a stream mirror only
some of the states of the sending part of the stream at the peer.
The receiving part of a stream does not track states on the sending
Iyengar & Thomson Expires July 27, 2019 [Page 13]
Internet-Draft QUIC Transport Protocol January 2019
part that cannot be observed, such as the "Ready" state. Instead,
the receiving part of a stream tracks the delivery of data to the
application, some of which cannot be observed by the sender.
o
| Recv STREAM / STREAM_DATA_BLOCKED / RESET_STREAM
| Create Bidirectional Stream (Sending)
| Recv MAX_STREAM_DATA / STOP_SENDING (Bidirectional)
| Create Higher-Numbered Stream
v
+-------+
| Recv | Recv RESET_STREAM
| |-----------------------.
+-------+ |
| |
| Recv STREAM + FIN |
v |
+-------+ |
| Size | Recv RESET_STREAM |
| Known |---------------------->|
+-------+ |
| |
| Recv All Data |
v v
+-------+ Recv RESET_STREAM +-------+
| Data |--- (optional) --->| Reset |
| Recvd | Recv All Data | Recvd |
+-------+<-- (optional) ----+-------+
| |
| App Read All Data | App Read RST
v v
+-------+ +-------+
| Data | | Reset |
| Read | | Read |
+-------+ +-------+
Figure 2: States for Receiving Parts of Streams
The receiving part of a stream initiated by a peer (types 1 and 3 for
a client, or 0 and 2 for a server) is created when the first STREAM,
STREAM_DATA_BLOCKED, or RESET_STREAM is received for that stream.
For bidirectional streams initiated by a peer, receipt of a
MAX_STREAM_DATA or STOP_SENDING frame for the sending part of the
stream also creates the receiving part. The initial state for the
receiving part of stream is "Recv".
Iyengar & Thomson Expires July 27, 2019 [Page 14]
Internet-Draft QUIC Transport Protocol January 2019
The receiving part of a stream enters the "Recv" state when the
sending part of a bidirectional stream initiated by the endpoint
(type 0 for a client, type 1 for a server) enters the "Ready" state.
An endpoint opens a bidirectional stream when a MAX_STREAM_DATA or
STOP_SENDING frame is received from the peer for that stream.
Receiving a MAX_STREAM_DATA frame for an unopened stream indicates
that the remote peer has opened the stream and is providing flow
control credit. Receiving a STOP_SENDING frame for an unopened
stream indicates that the remote peer no longer wishes to receive
data on this stream. Either frame might arrive before a STREAM or
STREAM_DATA_BLOCKED frame if packets are lost or reordered.
Before creating a stream, all streams of the same type with lower-
numbered stream IDs MUST be created. This ensures that the creation
order for streams is consistent on both endpoints.
In the "Recv" state, the endpoint receives STREAM and
STREAM_DATA_BLOCKED frames. Incoming data is buffered and can be
reassembled into the correct order for delivery to the application.
As data is consumed by the application and buffer space becomes
available, the endpoint sends MAX_STREAM_DATA frames to allow the
peer to send more data.
When a STREAM frame with a FIN bit is received, the final size of the
stream is known (see Section 4.4). The receiving part of the stream
then enters the "Size Known" state. In this state, the endpoint no
longer needs to send MAX_STREAM_DATA frames, it only receives any
retransmissions of stream data.
Once all data for the stream has been received, the receiving part
enters the "Data Recvd" state. This might happen as a result of
receiving the same STREAM frame that causes the transition to "Size
Known". In this state, the endpoint has all stream data. Any STREAM
or STREAM_DATA_BLOCKED frames it receives for the stream can be
discarded.
The "Data Recvd" state persists until stream data has been delivered
to the application. Once stream data has been delivered, the stream
enters the "Data Read" state, which is a terminal state.
Receiving a RESET_STREAM frame in the "Recv" or "Size Known" states
causes the stream to enter the "Reset Recvd" state. This might cause
the delivery of stream data to the application to be interrupted.
It is possible that all stream data is received when a RESET_STREAM
is received (that is, from the "Data Recvd" state). Similarly, it is
possible for remaining stream data to arrive after receiving a
Iyengar & Thomson Expires July 27, 2019 [Page 15]
Internet-Draft QUIC Transport Protocol January 2019
RESET_STREAM frame (the "Reset Recvd" state). An implementation is
free to manage this situation as it chooses. Sending RESET_STREAM
means that an endpoint cannot guarantee delivery of stream data;
however there is no requirement that stream data not be delivered if
a RESET_STREAM is received. An implementation MAY interrupt delivery
of stream data, discard any data that was not consumed, and signal
the receipt of the RESET_STREAM immediately. Alternatively, the
RESET_STREAM signal might be suppressed or withheld if stream data is
completely received and is buffered to be read by the application.
In the latter case, the receiving part of the stream transitions from
"Reset Recvd" to "Data Recvd".
Once the application has been delivered the signal indicating that
the stream was reset, the receiving part of the stream transitions to
the "Reset Read" state, which is a terminal state.
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
(Section 19.8), STREAM_DATA_BLOCKED (Section 19.13), and RESET_STREAM
(Section 19.4).
A sender MUST NOT send any of these frames from a terminal state
("Data Recvd" or "Reset Recvd"). A sender MUST NOT send STREAM or
STREAM_DATA_BLOCKED after sending a RESET_STREAM; that is, in the
terminal states and in the "Reset Sent" state. A receiver could
receive any of these three frames in any state, due to the
possibility of delayed delivery of packets carrying them.
The receiver of a stream sends MAX_STREAM_DATA (Section 19.10) and
STOP_SENDING frames (Section 19.5).
The receiver only sends MAX_STREAM_DATA in the "Recv" state. A
receiver can send STOP_SENDING in any state where it has not received
a RESET_STREAM frame; that is states other than "Reset Recvd" or
"Reset Read". However there is little value in sending a
STOP_SENDING frame in the "Data Recvd" state, since all stream data
has been received. A sender could receive either of these two frames
in any state as a result of delayed delivery of packets.
3.4. Bidirectional Stream States
A bidirectional stream is composed of sending and receiving parts.
Implementations may represent states of the bidirectional stream as
composites of sending and receiving stream states. The simplest
model presents the stream as "open" when either sending or receiving
Iyengar & Thomson Expires July 27, 2019 [Page 16]
Internet-Draft QUIC Transport Protocol January 2019
parts are in a non-terminal state and "closed" when both sending and
receiving streams are in terminal states.
Table 2 shows a more complex mapping of bidirectional stream states
that loosely correspond to the stream states in HTTP/2 [HTTP2]. This
shows that multiple states on sending or receiving parts of streams
are mapped to the same composite state. Note that this is just one
possibility for such a mapping; this mapping requires that data is
acknowledged before the transition to a "closed" or "half-closed"
state.
+-----------------------+---------------------+---------------------+
| Sending Part | Receiving Part | Composite State |
+-----------------------+---------------------+---------------------+
| No Stream/Ready | No Stream/Recv *1 | idle |
| | | |
| Ready/Send/Data Sent | Recv/Size Known | open |
| | | |
| Ready/Send/Data Sent | Data Recvd/Data | half-closed |
| | Read | (remote) |
| | | |
| Ready/Send/Data Sent | Reset Recvd/Reset | half-closed |
| | Read | (remote) |
| | | |
| Data Recvd | Recv/Size Known | half-closed (local) |
| | | |
| Reset Sent/Reset | Recv/Size Known | half-closed (local) |
| Recvd | | |
| | | |
| Reset Sent/Reset | Data Recvd/Data | closed |
| Recvd | Read | |
| | | |
| Reset Sent/Reset | Reset Recvd/Reset | closed |
| Recvd | Read | |
| | | |
| Data Recvd | Data Recvd/Data | closed |
| | Read | |
| | | |
| Data Recvd | Reset Recvd/Reset | closed |
| | Read | |
+-----------------------+---------------------+---------------------+
Table 2: Possible Mapping of Stream States to HTTP/2
Note (*1): A stream is considered "idle" if it has not yet been
created, or if the receiving part of the stream is in the "Recv"
state without yet having received any frames.
Iyengar & Thomson Expires July 27, 2019 [Page 17]
Internet-Draft QUIC Transport Protocol January 2019
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 it is not a guarantee
that incoming data will be ignored.
STREAM frames received after sending STOP_SENDING are still counted
toward connection and stream flow control, even though these frames
will be discarded upon receipt.
A STOP_SENDING frame requests that the receiving endpoint send a
RESET_STREAM frame. An endpoint that receives a STOP_SENDING frame
MUST send a RESET_STREAM frame if the stream is in the Ready or Send
state. If the stream is in the Data Sent state and any outstanding
data is declared lost, an endpoint SHOULD send a RESET_STREAM frame
in lieu of a retransmission.
An endpoint SHOULD copy the error code from the STOP_SENDING frame to
the RESET_STREAM frame it sends, but MAY use any application error
code. The endpoint that sends a STOP_SENDING frame MAY ignore the
error code carried in any RESET_STREAM frame it receives.
If the STOP_SENDING frame is received on a stream that is already in
the "Data Sent" state, an endpoint that wishes to cease
retransmission of previously-sent STREAM frames on that stream MUST
first send a RESET_STREAM frame.
STOP_SENDING SHOULD only be sent for a stream that has not been reset
by the peer. STOP_SENDING is most useful for streams in the "Recv"
or "Size Known" states.
An endpoint is expected to send another STOP_SENDING frame if a
packet containing a previous STOP_SENDING is lost. However, once
either all stream data or a RESET_STREAM frame has been received for
the stream - that is, the stream is in any state other than "Recv" or
"Size Known" - sending a STOP_SENDING frame is unnecessary.
An endpoint that wishes to terminate both directions of a
bidirectional stream can terminate one direction by sending a
RESET_STREAM, and it can encourage prompt termination in the opposite
direction by sending a STOP_SENDING frame.
Iyengar & Thomson Expires July 27, 2019 [Page 18]
Internet-Draft QUIC Transport Protocol January 2019