From 923144668ffdfd7acb011ec99aa6bfe44bec8a81 Mon Sep 17 00:00:00 2001 From: EKR Date: Sat, 1 Jul 2017 12:17:09 -0700 Subject: [PATCH] Re-order the presentation of the various frame types to match the order of the code points. This just makes it a bit cleaner. --- draft-ietf-quic-transport.md | 858 ++++++++++++++++++----------------- 1 file changed, 430 insertions(+), 428 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 498b1a9917..bb386d9ec1 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1482,378 +1482,168 @@ packet. The use of these frames and various frame header bits are described in subsequent sections. -## STREAM Frame {#frame-stream} +## PADDING Frame {#frame-padding} -STREAM frames implicitly create a stream and carry stream data. The type byte -for a STREAM frame contains embedded flags, and is formatted as `11FSSOOD`. -These bits are parsed as follows: +The PADDING frame (type=0x00) has no semantic value. PADDING frames can be used +to increase the size of a packet. Padding can be used to increase an initial +client packet to the minimum required size, or to provide protection against +traffic analysis for protected packets. -* The first two bits must be set to 11, indicating that this is a STREAM frame. +A PADDING frame has no content. That is, a PADDING frame consists of the single +octet that identifies the frame as a PADDING frame. -* `F` is the FIN bit, which is used for stream termination. -* The `SS` bits encode the length of the Stream ID header field. - The values 00, 01, 02, and 03 indicate lengths of 8, 16, 24, and 32 bits - long respectively. +## RST_STREAM Frame {#frame-rst-stream} -* The `OO` bits encode the length of the Offset header field. - The values 00, 01, 02, and 03 indicate lengths of 0, 16, 32, and - 64 bits long respectively. +An endpoint may use a RST_STREAM frame (type=0x01) to abruptly terminate a +stream. -* The `D` bit indicates whether a Data Length field is present in the STREAM - header. When set to 0, this field indicates that the Stream Data field - extends to the end of the packet. When set to 1, this field indicates that - Data Length field contains the length (in bytes) of the Stream Data field. - The option to omit the length should only be used when the packet is a - "full-sized" packet, to avoid the risk of corruption via padding. +After sending a RST_STREAM, an endpoint ceases transmission of STREAM frames on +the identified stream. A receiver of RST_STREAM can discard any data that it +already received on that stream. An endpoint sends a RST_STREAM in response to +a RST_STREAM unless the stream is already closed. -A STREAM frame is shown below. +The RST_STREAM frame is as follows: ~~~ 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 (8/16/24/32) ... +| Stream ID (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Offset (0/16/32/64) ... +| Error Code (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| [Data Length (16)] | Stream Data (*) ... +| | ++ Final Offset (64) + +| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ -{: #stream-format title="STREAM Frame Format"} -The STREAM frame contains the following fields: +The fields are: Stream ID: -: The stream ID of the stream (see {{stream-id}}). - -Offset: - -: A variable-sized unsigned number specifying the byte offset in the stream for - the data in this STREAM frame. When the offset length is 0, the offset is 0. - The first byte in the stream has an offset of 0. The largest offset delivered - on a stream - the sum of the re-constructed offset and data length - MUST be - less than 2^64. - -Data Length: - -: An optional 16-bit unsigned number specifying the length of the Stream Data - field in this STREAM frame. This field is present when the `D` bit is set to - 1. - -Stream Data: - -: The bytes from the designated stream to be delivered. +: The 32-bit Stream ID of the stream being terminated. -A stream frame's payload MUST NOT be empty, unless the FIN bit is set. When the -FIN flag is sent on an empty STREAM frame, the offset in the STREAM frame MUST -be one greater than the last data byte sent on this stream. +Error code: -Stream multiplexing is achieved by interleaving STREAM frames from multiple -streams into one or more QUIC packets. A single QUIC packet can include -multiple STREAM frames from one or more streams. +: A 32-bit error code which indicates why the stream is being closed. -Implementation note: One of the benefits of QUIC is avoidance of head-of-line -blocking across multiple streams. When a packet loss occurs, only streams with -data in that packet are blocked waiting for a retransmission to be received, -while other streams can continue making progress. Note that when data from -multiple streams is bundled into a single QUIC packet, loss of that packet -blocks all those streams from making progress. An implementation is therefore -advised to bundle as few streams as necessary in outgoing packets without losing -transmission efficiency to underfilled packets. +Final offset: +: A 64-bit unsigned integer indicating the absolute byte offset of the end of + data written on this stream by the RST_STREAM sender. -## ACK Frame {#frame-ack} -Receivers send ACK frames to inform senders which packets they have received and -processed, as well as which packets are considered missing. The ACK frame -contains between 1 and 256 ACK blocks. ACK blocks are ranges of acknowledged -packets. +## CONNECTION_CLOSE frame {#frame-connection-close} -To limit ACK blocks to those that have not yet been received by the sender, the -receiver SHOULD track which ACK frames have been acknowledged by its peer. Once -an ACK frame has been acknowledged, the packets it acknowledges SHOULD not be -acknowledged again. +An endpoint sends a CONNECTION_CLOSE frame (type=0x02) to notify its peer that +the connection is being closed. If there are open streams that haven't been +explicitly closed, they are implicitly closed when the connection is closed. +(Ideally, a GOAWAY frame would be sent with enough time that all streams are +torn down.) The frame is as follows: -A receiver that is only sending ACK frames will not receive acknowledgments for -its packets. Sending an occasional MAX_DATA or MAX_STREAM_DATA frame as data is -received will ensure that acknowledgements are generated by a peer. Otherwise, -an endpoint MAY send a PING frame once per RTT to solicit an acknowledgment. +~~~ + 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 (32) | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Reason Phrase Length (16) | [Reason Phrase (*)] ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +~~~ -To limit receiver state or the size of ACK frames, a receiver MAY limit the -number of ACK blocks it sends. A receiver can do this even without receiving -acknowledgment of its ACK frames, with the knowledge this could cause the sender -to unnecessarily retransmit some data. When this is necessary, the receiver -SHOULD acknowledge newly received packets and stop acknowledging packets -received in the past. +The fields of a CONNECTION_CLOSE frame are as follows: -Unlike TCP SACKs, QUIC ACK blocks are irrevocable. Once a packet has -been acknowledged, even if it does not appear in a future ACK frame, -it remains acknowledged. +Error Code: -QUIC ACK frames contain a timestamp section with up to 255 timestamps. -Timestamps enable better congestion control, but are not required for correct -loss recovery, and old timestamps are less valuable, so it is not guaranteed -every timestamp will be received by the sender. A receiver SHOULD send a -timestamp exactly once for each received packet containing retransmittable -frames. A receiver MAY send timestamps for non-retransmittable packets. -A receiver MUST not send timestamps in unprotected packets. +: A 32-bit error code which indicates the reason for closing this connection. -A sender MAY intentionally skip packet numbers to introduce entropy into the -connection, to avoid opportunistic acknowledgement attacks. The sender SHOULD -close the connection if an unsent packet number is acknowledged. The format of -the ACK frame is efficient at expressing blocks of missing packets; skipping -packet numbers between 1 and 255 effectively provides up to 8 bits of efficient -entropy on demand, which should be adequate protection against most -opportunistic acknowledgement attacks. +Reason Phrase Length: -The type byte for a ACK frame contains embedded flags, and is formatted as -`101NLLMM`. These bits are parsed as follows: +: A 16-bit unsigned number specifying the length of the reason phrase in bytes. + Note that a CONNECTION_CLOSE frame cannot be split between packets, so in + practice any limits on packet size will also limit the space available for a + reason phrase. -* The first three bits must be set to 101 indicating that this is an ACK frame. +Reason Phrase: -* The `N` bit indicates whether the frame contains a Num Blocks field. +: A human-readable explanation for why the connection was closed. This can be + zero length if the sender chooses to not give details beyond the Error Code. + This SHOULD be a UTF-8 encoded string {{!RFC3629}}. -* The two `LL` bits encode the length of the Largest Acknowledged field. - The values 00, 01, 02, and 03 indicate lengths of 8, 16, 32, and 64 - bits respectively. -* The two `MM` bits encode the length of the ACK Block Length fields. - The values 00, 01, 02, and 03 indicate lengths of 8, 16, 32, and 64 - bits respectively. +## GOAWAY Frame {#frame-goaway} -An ACK frame is shown below. +An endpoint uses a GOAWAY frame (type=0x03) to initiate a graceful shutdown of a +connection. The endpoints will continue to use any active streams, but the +sender of the GOAWAY will not initiate or accept any additional streams beyond +those indicated. The GOAWAY frame is as follows: ~~~ 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -|[Num Blocks(8)]| NumTS (8) | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Largest Acknowledged (8/16/32/64) ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| ACK Delay (16) | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| ACK Block Section (*) ... +| Largest Client Stream ID (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Timestamp Section (*) ... +| Largest Server Stream ID (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ -{: #ack-format title="ACK Frame Format"} - -The fields in the ACK frame are as follows: -Num Blocks (opt): - -: An optional 8-bit unsigned value specifying the number of additional ACK - blocks (besides the required First ACK Block) in this ACK frame. Only present - if the 'N' flag bit is 1. - -Num Timestamps: - -: An unsigned 8-bit number specifying the total number of pairs in the Timestamp Section. +The fields of a GOAWAY frame are: -Largest Acknowledged: +Largest Client Stream ID: -: A variable-sized unsigned value representing the largest packet number the - peer is acknowledging in this packet (typically the largest that the peer has - seen thus far.) +: The highest-numbered, client-initiated stream on which the endpoint sending + the GOAWAY frame either sent data, or received and delivered data. All + higher-numbered, client-initiated streams (that is, odd-numbered streams) are + implicitly reset by sending or receiving the GOAWAY frame. -ACK Delay: +Largest Server Stream ID: -: The time from when the largest acknowledged packet, as indicated in the - Largest Acknowledged field, was received by this peer to when this ACK was - sent. +: The highest-numbered, server-initiated stream on which the endpoint sending + the GOAWAY frame either sent data, or received and delivered data. All + higher-numbered, server-initiated streams (that is, even-numbered streams) are + implicitly reset by sending or receiving the GOAWAY frame. -ACK Block Section: +A GOAWAY frame indicates that any application layer actions on streams with +higher numbers than those indicated can be safely retried because no data was +exchanged. An endpoint MUST set the value of the Largest Client or Server +Stream ID to be at least as high as the highest-numbered stream on which it +either sent data or received and delivered data to the application protocol that +uses QUIC. -: Contains one or more blocks of packet numbers which have been successfully - received, see {{ack-block-section}}. +An endpoint MAY choose a larger stream identifier if it wishes to allow for a +number of streams to be created. This is especially valuable for peer-initiated +streams where packets creating new streams could be in transit; using a larger +stream number allows those streams to complete. -Timestamp Section: +In addition to initiating a graceful shutdown of a connection, GOAWAY MAY be +sent immediately prior to sending a CONNECTION_CLOSE frame that is sent as a +result of detecting a fatal error. Higher-numbered streams than those indicated +in the GOAWAY frame can then be retried. -: Contains zero or more timestamps reporting transit delay of received packets. - See {{timestamp-section}}. +## MAX_DATA Frame {#frame-max-data} -### ACK Block Section {#ack-block-section} +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. -The ACK Block Section contains between one and 256 blocks of packet numbers -which have been successfully received. If the Num Blocks field is absent, only -the First ACK Block length is present in this section. Otherwise, the Num Blocks -field indicates how many additional blocks follow the First ACK Block Length -field. +The frame is as follows: ~~~ 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 Length (8/16/32/64) ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| [Gap 1 (8)] | [ACK Block 1 Length (8/16/32/64)] ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| [Gap 2 (8)] | [ACK Block 2 Length (8/16/32/64)] ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| [Gap N (8)] | [ACK Block N Length (8/16/32/64)] ... +| | ++ Maximum Data (64) + +| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ -{: #ack-block-format title="ACK Block Section"} -The fields in the ACK Block Section are: - -First ACK Block Length: +The fields in the MAX_DATA frame are as follows: -: An unsigned packet number delta that indicates the number of contiguous - additional packets being acknowledged starting at the Largest Acknowledged. - -Gap To Next Block (opt, repeated): - -: An unsigned number specifying the number of contiguous missing packets from - the end of the previous ACK block to the start of the next. Repeated "Num - Blocks" times. - -ACK Block Length (opt, repeated): - -: An unsigned packet number delta that indicates the number of contiguous - packets being acknowledged starting after the end of the previous gap. - Repeated "Num Blocks" times. - - -### Timestamp Section {#timestamp-section} - -The Timestamp Section contains between zero and 255 measurements of packet -receive times relative to the beginning of the 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 -+-+-+-+-+-+-+-+-+ -| [Delta LA (8)]| -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| [First Timestamp (32)] | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -|[Delta LA 1(8)]| [Time Since Previous 1 (16)] | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -|[Delta LA 2(8)]| [Time Since Previous 2 (16)] | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -|[Delta LA N(8)]| [Time Since Previous N (16)] | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -~~~ -{: #timestamp-format title="Timestamp Section"} - -The fields in the Timestamp Section are: - -Delta Largest Acknowledged (opt): - -: An optional 8-bit unsigned packet number delta specifying the delta between - the largest acknowledged and the first packet whose timestamp is being - reported. In other words, this first packet number may be computed as - (Largest Acknowledged - Delta Largest Acknowledged.) - -First Timestamp (opt): - -: An optional 32-bit unsigned value specifying the time delta in microseconds, - from the beginning of the connection to the arrival of the packet indicated by - Delta Largest Acknowledged. - -Delta Largest Acked 1..N (opt, repeated): - -: This field has the same semantics and format as "Delta Largest Acknowledged". - Repeated "Num Timestamps - 1" times. - -Time Since Previous Timestamp 1..N(opt, repeated): - -: An optional 16-bit unsigned value specifying time delta from the previous - reported timestamp. It is encoded in the same format as the ACK Delay. - Repeated "Num Timestamps - 1" times. - -The timestamp section lists packet receipt timestamps ordered by timestamp. - - -#### Time Format - -DISCUSS_AND_REPLACE: Perhaps make this format simpler. - -The time format used in the ACK frame above is a 16-bit unsigned float with 11 -explicit bits of mantissa and 5 bits of explicit exponent, specifying time in -microseconds. The bit format is loosely modeled after IEEE 754. For example, 1 -microsecond is represented as 0x1, which has an exponent of zero, presented in -the 5 high order bits, and mantissa of 1, presented in the 11 low order bits. -When the explicit exponent is greater than zero, an implicit high-order 12th bit -of 1 is assumed in the mantissa. For example, a floating value of 0x800 has an -explicit exponent of 1, as well as an explicit mantissa of 0, but then has an -effective mantissa of 4096 (12th bit is assumed to be 1). Additionally, the -actual exponent is one-less than the explicit exponent, and the value represents -4096 microseconds. Any values larger than the representable range are clamped -to 0xFFFF. - - -### ACK Frames and Packet Protection - -ACK frames that acknowledge protected packets MUST be carried in a packet that -has an equivalent or greater level of packet protection. - -Packets that are protected with 1-RTT keys MUST be acknowledged in packets that -are also protected with 1-RTT keys. - -A packet that is not protected and claims to acknowledge a packet number that -was sent with packet protection is not valid. An unprotected packet that -carries acknowledgments for protected packets MUST be discarded in its entirety. - -Packets that a client sends with 0-RTT packet protection MUST be acknowledged by -the server in packets protected by 1-RTT keys. This can mean that the client is -unable to use these acknowledgments if the server cryptographic handshake -messages are delayed or lost. Note that the same limitation applies to other -data sent by the server protected by the 1-RTT keys. - -Unprotected packets, such as those that carry the initial cryptographic -handshake messages, MAY be acknowledged in unprotected packets. Unprotected -packets are vulnerable to falsification or modification. Unprotected packets -can be acknowledged along with protected packets in a protected packet. - -An endpoint SHOULD acknowledge packets containing cryptographic handshake -messages in the next unprotected packet that it sends, unless it is able to -acknowledge those packets in later packets protected by 1-RTT keys. At the -completion of the cryptographic handshake, both peers send unprotected packets -containing cryptographic handshake messages followed by packets protected by -1-RTT keys. An endpoint SHOULD acknowledge the unprotected packets that complete -the cryptographic handshake in a protected packet, because its peer is -guaranteed to have access to 1-RTT packet protection keys. - -For instance, a server acknowledges a TLS ClientHello in the packet that carries -the TLS ServerHello; similarly, a client can acknowledge a TLS HelloRetryRequest -in the packet containing a second TLS ClientHello. The complete set of server -handshake messages (TLS ServerHello through to Finished) might be acknowledged -by a client in protected packets, because it is certain that the server is able -to decipher the packet. - - -## MAX_DATA Frame {#frame-max-data} - -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. - -The frame is as follows: - -~~~ - 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 (64) + -| | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -~~~ - -The fields in the MAX_DATA frame are as follows: - -Maximum Data: +Maximum Data: : A 64-bit unsigned integer indicating the maximum amount of data that can be sent on the entire connection, in units of 1024 octets. That is, the updated @@ -1944,6 +1734,16 @@ than it has sent, unless this is a result of a change in the initial limits (see {{zerortt-parameters}}). +## PING frame {#frame-ping} + +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. The PING frame SHOULD be used to keep a connection +alive when a stream is open. The default is to send a PING frame after 15 +seconds of quiescence. A PING frame has no additional fields. + + ## BLOCKED Frame {#frame-blocked} A sender sends a BLOCKED frame (type=0x08) when it wishes to send data, but is @@ -1990,69 +1790,6 @@ stream, but is unable to due to the maximum stream ID limit. The STREAM_ID_NEEDED frame does not contain a payload. -## RST_STREAM Frame {#frame-rst-stream} - -An endpoint may use a RST_STREAM frame (type=0x01) to abruptly terminate a -stream. - -After sending a RST_STREAM, an endpoint ceases transmission of STREAM frames on -the identified stream. A receiver of RST_STREAM can discard any data that it -already received on that stream. An endpoint sends a RST_STREAM in response to -a RST_STREAM unless the stream is already closed. - -The RST_STREAM frame is as follows: - -~~~ - 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 (32) | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Error Code (32) | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| | -+ Final Offset (64) + -| | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -~~~ - -The fields are: - -Stream ID: - -: The 32-bit Stream ID of the stream being terminated. - -Error code: - -: A 32-bit error code which indicates why the stream is being closed. - -Final offset: - -: A 64-bit unsigned integer indicating the absolute byte offset of the end of - data written on this stream by the RST_STREAM sender. - - -## PADDING Frame {#frame-padding} - -The PADDING frame (type=0x00) has no semantic value. PADDING frames can be used -to increase the size of a packet. Padding can be used to increase an initial -client packet to the minimum required size, or to provide protection against -traffic analysis for protected packets. - -A PADDING frame has no content. That is, a PADDING frame consists of the single -octet that identifies the frame as a PADDING frame. - - -## PING frame {#frame-ping} - -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. The PING frame SHOULD be used to keep a connection -alive when a stream is open. The default is to send a PING frame after 15 -seconds of quiescence. A PING frame has no additional fields. - - ## NEW_CONNECTION_ID Frame {#frame-new-connection-id} A server sends a NEW_CONNECTION_ID to provide the client with alternative @@ -2089,93 +1826,358 @@ Connection ID: : A 64-bit connection ID. -## CONNECTION_CLOSE frame {#frame-connection-close} - -An endpoint sends a CONNECTION_CLOSE frame (type=0x02) to notify its peer that -the connection is being closed. If there are open streams that haven't been -explicitly closed, they are implicitly closed when the connection is closed. -(Ideally, a GOAWAY frame would be sent with enough time that all streams are -torn down.) The frame is as follows: +## ACK Frame {#frame-ack} -~~~ - 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 (32) | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Reason Phrase Length (16) | [Reason Phrase (*)] ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -~~~ +Receivers send ACK frames to inform senders which packets they have received and +processed, as well as which packets are considered missing. The ACK frame +contains between 1 and 256 ACK blocks. ACK blocks are ranges of acknowledged +packets. -The fields of a CONNECTION_CLOSE frame are as follows: +To limit ACK blocks to those that have not yet been received by the sender, the +receiver SHOULD track which ACK frames have been acknowledged by its peer. Once +an ACK frame has been acknowledged, the packets it acknowledges SHOULD not be +acknowledged again. -Error Code: +A receiver that is only sending ACK frames will not receive acknowledgments for +its packets. Sending an occasional MAX_DATA or MAX_STREAM_DATA frame as data is +received will ensure that acknowledgements are generated by a peer. Otherwise, +an endpoint MAY send a PING frame once per RTT to solicit an acknowledgment. -: A 32-bit error code which indicates the reason for closing this connection. +To limit receiver state or the size of ACK frames, a receiver MAY limit the +number of ACK blocks it sends. A receiver can do this even without receiving +acknowledgment of its ACK frames, with the knowledge this could cause the sender +to unnecessarily retransmit some data. When this is necessary, the receiver +SHOULD acknowledge newly received packets and stop acknowledging packets +received in the past. -Reason Phrase Length: +Unlike TCP SACKs, QUIC ACK blocks are irrevocable. Once a packet has +been acknowledged, even if it does not appear in a future ACK frame, +it remains acknowledged. -: A 16-bit unsigned number specifying the length of the reason phrase in bytes. - Note that a CONNECTION_CLOSE frame cannot be split between packets, so in - practice any limits on packet size will also limit the space available for a - reason phrase. +QUIC ACK frames contain a timestamp section with up to 255 timestamps. +Timestamps enable better congestion control, but are not required for correct +loss recovery, and old timestamps are less valuable, so it is not guaranteed +every timestamp will be received by the sender. A receiver SHOULD send a +timestamp exactly once for each received packet containing retransmittable +frames. A receiver MAY send timestamps for non-retransmittable packets. +A receiver MUST not send timestamps in unprotected packets. -Reason Phrase: +A sender MAY intentionally skip packet numbers to introduce entropy into the +connection, to avoid opportunistic acknowledgement attacks. The sender SHOULD +close the connection if an unsent packet number is acknowledged. The format of +the ACK frame is efficient at expressing blocks of missing packets; skipping +packet numbers between 1 and 255 effectively provides up to 8 bits of efficient +entropy on demand, which should be adequate protection against most +opportunistic acknowledgement attacks. -: A human-readable explanation for why the connection was closed. This can be - zero length if the sender chooses to not give details beyond the Error Code. - This SHOULD be a UTF-8 encoded string {{!RFC3629}}. +The type byte for a ACK frame contains embedded flags, and is formatted as +`101NLLMM`. These bits are parsed as follows: +* The first three bits must be set to 101 indicating that this is an ACK frame. -## GOAWAY Frame {#frame-goaway} +* The `N` bit indicates whether the frame contains a Num Blocks field. -An endpoint uses a GOAWAY frame (type=0x03) to initiate a graceful shutdown of a -connection. The endpoints will continue to use any active streams, but the -sender of the GOAWAY will not initiate or accept any additional streams beyond -those indicated. The GOAWAY frame is as follows: +* The two `LL` bits encode the length of the Largest Acknowledged field. + The values 00, 01, 02, and 03 indicate lengths of 8, 16, 32, and 64 + bits respectively. + +* The two `MM` bits encode the length of the ACK Block Length fields. + The values 00, 01, 02, and 03 indicate lengths of 8, 16, 32, and 64 + bits respectively. + +An ACK frame is shown below. ~~~ 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 Client Stream ID (32) | +|[Num Blocks(8)]| NumTS (8) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Largest Server Stream ID (32) | +| Largest Acknowledged (8/16/32/64) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| ACK Delay (16) | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| ACK Block Section (*) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Timestamp Section (*) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ +{: #ack-format title="ACK Frame Format"} -The fields of a GOAWAY frame are: +The fields in the ACK frame are as follows: -Largest Client Stream ID: +Num Blocks (opt): -: The highest-numbered, client-initiated stream on which the endpoint sending - the GOAWAY frame either sent data, or received and delivered data. All - higher-numbered, client-initiated streams (that is, odd-numbered streams) are - implicitly reset by sending or receiving the GOAWAY frame. +: An optional 8-bit unsigned value specifying the number of additional ACK + blocks (besides the required First ACK Block) in this ACK frame. Only present + if the 'N' flag bit is 1. -Largest Server Stream ID: +Num Timestamps: -: The highest-numbered, server-initiated stream on which the endpoint sending - the GOAWAY frame either sent data, or received and delivered data. All - higher-numbered, server-initiated streams (that is, even-numbered streams) are - implicitly reset by sending or receiving the GOAWAY frame. +: An unsigned 8-bit number specifying the total number of pairs in the Timestamp Section. -A GOAWAY frame indicates that any application layer actions on streams with -higher numbers than those indicated can be safely retried because no data was -exchanged. An endpoint MUST set the value of the Largest Client or Server -Stream ID to be at least as high as the highest-numbered stream on which it -either sent data or received and delivered data to the application protocol that -uses QUIC. +Largest Acknowledged: + +: A variable-sized unsigned value representing the largest packet number the + peer is acknowledging in this packet (typically the largest that the peer has + seen thus far.) + +ACK Delay: + +: The time from when the largest acknowledged packet, as indicated in the + Largest Acknowledged field, was received by this peer to when this ACK was + sent. + +ACK Block Section: + +: Contains one or more blocks of packet numbers which have been successfully + received, see {{ack-block-section}}. + +Timestamp Section: + +: Contains zero or more timestamps reporting transit delay of received packets. + See {{timestamp-section}}. + + +### ACK Block Section {#ack-block-section} + +The ACK Block Section contains between one and 256 blocks of packet numbers +which have been successfully received. If the Num Blocks field is absent, only +the First ACK Block length is present in this section. Otherwise, the Num Blocks +field indicates how many additional blocks follow the First ACK Block Length +field. + +~~~ + 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 Length (8/16/32/64) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| [Gap 1 (8)] | [ACK Block 1 Length (8/16/32/64)] ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| [Gap 2 (8)] | [ACK Block 2 Length (8/16/32/64)] ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| [Gap N (8)] | [ACK Block N Length (8/16/32/64)] ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +~~~ +{: #ack-block-format title="ACK Block Section"} + +The fields in the ACK Block Section are: + +First ACK Block Length: + +: An unsigned packet number delta that indicates the number of contiguous + additional packets being acknowledged starting at the Largest Acknowledged. + +Gap To Next Block (opt, repeated): + +: An unsigned number specifying the number of contiguous missing packets from + the end of the previous ACK block to the start of the next. Repeated "Num + Blocks" times. + +ACK Block Length (opt, repeated): + +: An unsigned packet number delta that indicates the number of contiguous + packets being acknowledged starting after the end of the previous gap. + Repeated "Num Blocks" times. + + +### Timestamp Section {#timestamp-section} + +The Timestamp Section contains between zero and 255 measurements of packet +receive times relative to the beginning of the 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 ++-+-+-+-+-+-+-+-+ +| [Delta LA (8)]| ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| [First Timestamp (32)] | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|[Delta LA 1(8)]| [Time Since Previous 1 (16)] | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|[Delta LA 2(8)]| [Time Since Previous 2 (16)] | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +|[Delta LA N(8)]| [Time Since Previous N (16)] | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +~~~ +{: #timestamp-format title="Timestamp Section"} + +The fields in the Timestamp Section are: + +Delta Largest Acknowledged (opt): + +: An optional 8-bit unsigned packet number delta specifying the delta between + the largest acknowledged and the first packet whose timestamp is being + reported. In other words, this first packet number may be computed as + (Largest Acknowledged - Delta Largest Acknowledged.) + +First Timestamp (opt): + +: An optional 32-bit unsigned value specifying the time delta in microseconds, + from the beginning of the connection to the arrival of the packet indicated by + Delta Largest Acknowledged. + +Delta Largest Acked 1..N (opt, repeated): + +: This field has the same semantics and format as "Delta Largest Acknowledged". + Repeated "Num Timestamps - 1" times. + +Time Since Previous Timestamp 1..N(opt, repeated): + +: An optional 16-bit unsigned value specifying time delta from the previous + reported timestamp. It is encoded in the same format as the ACK Delay. + Repeated "Num Timestamps - 1" times. + +The timestamp section lists packet receipt timestamps ordered by timestamp. + + +## STREAM Frame {#frame-stream} + +STREAM frames implicitly create a stream and carry stream data. The type byte +for a STREAM frame contains embedded flags, and is formatted as `11FSSOOD`. +These bits are parsed as follows: + +* The first two bits must be set to 11, indicating that this is a STREAM frame. + +* `F` is the FIN bit, which is used for stream termination. + +* The `SS` bits encode the length of the Stream ID header field. + The values 00, 01, 02, and 03 indicate lengths of 8, 16, 24, and 32 bits + long respectively. + +* The `OO` bits encode the length of the Offset header field. + The values 00, 01, 02, and 03 indicate lengths of 0, 16, 32, and + 64 bits long respectively. + +* The `D` bit indicates whether a Data Length field is present in the STREAM + header. When set to 0, this field indicates that the Stream Data field + extends to the end of the packet. When set to 1, this field indicates that + Data Length field contains the length (in bytes) of the Stream Data field. + The option to omit the length should only be used when the packet is a + "full-sized" packet, to avoid the risk of corruption via padding. + +A STREAM frame is shown below. + +~~~ + 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 (8/16/24/32) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Offset (0/16/32/64) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| [Data Length (16)] | Stream Data (*) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +~~~ +{: #stream-format title="STREAM Frame Format"} + +The STREAM frame contains the following fields: + +Stream ID: + +: The stream ID of the stream (see {{stream-id}}). + +Offset: + +: A variable-sized unsigned number specifying the byte offset in the stream for + the data in this STREAM frame. When the offset length is 0, the offset is 0. + The first byte in the stream has an offset of 0. The largest offset delivered + on a stream - the sum of the re-constructed offset and data length - MUST be + less than 2^64. + +Data Length: + +: An optional 16-bit unsigned number specifying the length of the Stream Data + field in this STREAM frame. This field is present when the `D` bit is set to + 1. + +Stream Data: + +: The bytes from the designated stream to be delivered. + +A stream frame's payload MUST NOT be empty, unless the FIN bit is set. When the +FIN flag is sent on an empty STREAM frame, the offset in the STREAM frame MUST +be one greater than the last data byte sent on this stream. + +Stream multiplexing is achieved by interleaving STREAM frames from multiple +streams into one or more QUIC packets. A single QUIC packet can include +multiple STREAM frames from one or more streams. + +Implementation note: One of the benefits of QUIC is avoidance of head-of-line +blocking across multiple streams. When a packet loss occurs, only streams with +data in that packet are blocked waiting for a retransmission to be received, +while other streams can continue making progress. Note that when data from +multiple streams is bundled into a single QUIC packet, loss of that packet +blocks all those streams from making progress. An implementation is therefore +advised to bundle as few streams as necessary in outgoing packets without losing +transmission efficiency to underfilled packets. + + +#### Time Format + +DISCUSS_AND_REPLACE: Perhaps make this format simpler. + +The time format used in the ACK frame above is a 16-bit unsigned float with 11 +explicit bits of mantissa and 5 bits of explicit exponent, specifying time in +microseconds. The bit format is loosely modeled after IEEE 754. For example, 1 +microsecond is represented as 0x1, which has an exponent of zero, presented in +the 5 high order bits, and mantissa of 1, presented in the 11 low order bits. +When the explicit exponent is greater than zero, an implicit high-order 12th bit +of 1 is assumed in the mantissa. For example, a floating value of 0x800 has an +explicit exponent of 1, as well as an explicit mantissa of 0, but then has an +effective mantissa of 4096 (12th bit is assumed to be 1). Additionally, the +actual exponent is one-less than the explicit exponent, and the value represents +4096 microseconds. Any values larger than the representable range are clamped +to 0xFFFF. + + +### ACK Frames and Packet Protection + +ACK frames that acknowledge protected packets MUST be carried in a packet that +has an equivalent or greater level of packet protection. + +Packets that are protected with 1-RTT keys MUST be acknowledged in packets that +are also protected with 1-RTT keys. + +A packet that is not protected and claims to acknowledge a packet number that +was sent with packet protection is not valid. An unprotected packet that +carries acknowledgments for protected packets MUST be discarded in its entirety. + +Packets that a client sends with 0-RTT packet protection MUST be acknowledged by +the server in packets protected by 1-RTT keys. This can mean that the client is +unable to use these acknowledgments if the server cryptographic handshake +messages are delayed or lost. Note that the same limitation applies to other +data sent by the server protected by the 1-RTT keys. + +Unprotected packets, such as those that carry the initial cryptographic +handshake messages, MAY be acknowledged in unprotected packets. Unprotected +packets are vulnerable to falsification or modification. Unprotected packets +can be acknowledged along with protected packets in a protected packet. + +An endpoint SHOULD acknowledge packets containing cryptographic handshake +messages in the next unprotected packet that it sends, unless it is able to +acknowledge those packets in later packets protected by 1-RTT keys. At the +completion of the cryptographic handshake, both peers send unprotected packets +containing cryptographic handshake messages followed by packets protected by +1-RTT keys. An endpoint SHOULD acknowledge the unprotected packets that complete +the cryptographic handshake in a protected packet, because its peer is +guaranteed to have access to 1-RTT packet protection keys. + +For instance, a server acknowledges a TLS ClientHello in the packet that carries +the TLS ServerHello; similarly, a client can acknowledge a TLS HelloRetryRequest +in the packet containing a second TLS ClientHello. The complete set of server +handshake messages (TLS ServerHello through to Finished) might be acknowledged +by a client in protected packets, because it is certain that the server is able +to decipher the packet. -An endpoint MAY choose a larger stream identifier if it wishes to allow for a -number of streams to be created. This is especially valuable for peer-initiated -streams where packets creating new streams could be in transit; using a larger -stream number allows those streams to complete. -In addition to initiating a graceful shutdown of a connection, GOAWAY MAY be -sent immediately prior to sending a CONNECTION_CLOSE frame that is sent as a -result of detecting a fatal error. Higher-numbered streams than those indicated -in the GOAWAY frame can then be retried. # Packetization and Reliability {#packetization}