Draft: draft-ietf-quic-qpack

Commentary: I was planning to make only two changes here , but there were a few editorial itches I needed to scratch , so this does : ACK Blocks to ACK Ranges the First ACK Range field to the top level the ECN Section to ECN Counters and adds a description of that field the field names more consistently ( s / Gaps / Gap fields/ and so forth ) figure and list intros more consistent 
 From Once an ACK frame has been acknowledged , the packets it acknowledges SHOULD NOT be acknowledged again . I think that the advice here is that ranges are dropped when all ACKs for all packets in that range have been acknowledged . Or something along those lines . Maybe : Though that seems clumsy . Better words would be appreciated . 
 Maybe " Endpoints SHOULD not acknowledge packets for which it has already received acknowledgement of acknowledgements , except where this would create unnecessary gaps in the encoded ACK frame . " Not ideal , I know/ 
 I think this is connected to in an interesting way . The question that arises is if one MUST include all ACK state between highest received , and the lower PN that needs to be  ( as it is newly arrived due to reordering ) . An alternative would be to explicitly allow GAPs for packets that has been received and where the reception 's ACKs has been ACKed . But , I guess that results in interesting bookkeeping chores in the implementations . 
 Agreed the wording is too strong . Take a look at PR 
 Just a few more nits , but looks good . Commit once you 've addressed those .
Paragraph (version A):
The maximum size of the dynamic table can be modified by the encoder,
subject to a decoder-controlled limit (see configuration and size-
update).  The initial maximum size is determined by the corresponding
setting when HTTP requests or responses are first permitted to be
sent.  For clients using 0-RTT data in HTTP/3, the table size is the
remembered value of the setting, even if the server later specifies a
larger maximum in its SETTINGS frame.  For HTTP/3 servers and HTTP/3
clients when 0-RTT is not attempted or is rejected, the initial
maximum table size is the value of the setting in the peer's SETTINGS
frame.
Paragraph (version A):
The encoder decides how to update the dynamic table and as such can
control how much memory is used by the dynamic table.  To limit the
memory requirements of the decoder, the dynamic table size is
strictly bounded.
Paragraph (version A):
The decoder determines the maximum size that the encoder is permitted
to use for the dynamic table.  In HTTP/3, this value is determined by
the SETTINGS_HEADER_TABLE_SIZE setting (see configuration).
Paragraph (version A):
An encoder can choose to use less capacity than this maximum size
(see size-update), but the chosen size MUST stay lower than or equal
to the maximum set by the decoder.  Whenever the maximum size for the
dynamic table is reduced, entries are evicted from the end of the
dynamic table until the size of the dynamic table is less than or
equal to the maximum size.
Paragraph (version A):
This mechanism can be used to completely clear entries from the
dynamic table by setting a maximum size of 0, which can subsequently
be restored.
Paragraph (version A):
MaxTableSize is the maximum size of the dynamic table as specified by
the decoder (see maximum-table-size).
Paragraph (version B):
Whenever the maximum size for the dynamic table is reduced by the
encoder, entries are evicted from the end of the dynamic table until
the size of the dynamic table is less than or equal to the new
maximum size.  This mechanism can be used to completely clear entries
from the dynamic table by setting a maxiumum size of 0, which can
subsequently be restored.
Paragraph (version B):
The encoder decides how to update the dynamic table size and as such
can control how much memory is used by the dynamic table.  To limit
the memory requirements of the decoder, the dynamic table size is
strictly bounded.  The decoder determines the maximum size that the
encoder is permitted to set for the dynamic table.  In HTTP/3, this
value is determined by the SETTINGS_HEADER_TABLE_SIZE setting (see
configuration).  The encoder MUST not set a dynamic table size that
exceeds this maximum, but it can choose to use a lower dynamic table
size (see size-update).
Paragraph (version B):
The initial maximum size is determined by the corresponding setting
when HTTP requests or responses are first permitted to be sent.  For
clients using 0-RTT data in HTTP/3, the table size is the remembered
value of the setting, even if the server later specifies a larger
maximum in its SETTINGS frame.  For HTTP/3 servers and HTTP/3 clients
when 0-RTT is not attempted or is rejected, the initial maximum table
size is the value of the setting in the peer's SETTINGS frame.
Paragraph (version A):
The new maximum size MUST be lower than or equal to the limit
determined by the protocol using QPACK.  A value that exceeds this
limit MUST be treated as a connection error of type
"HTTP_QPACK_ENCODER_STREAM_ERROR".  In HTTP/3, this limit is the
value of the SETTINGS_HEADER_TABLE_SIZE parameter (see configuration)
received from the decoder.
Paragraph (version B):
The new maximum size MUST be lower than or equal to the limit
described in maximum-table-size.  In HTTP/3, this limit is the value
of the SETTINGS_HEADER_TABLE_SIZE parameter (see configuration)
received from the decoder.  The decoder MUST treat a value that
exceeds this limit as a connection error of type
"HTTP_QPACK_ENCODER_STREAM_ERROR".
Paragraph (version A):
A stream that is reset might have multiple outstanding header blocks
with dynamic table references.  When an endpoint receives a stream
reset before the end of a stream, it generates a Stream Cancellation
instruction on the decoder stream.  Similarly, when an endpoint
abandons reading of a stream it needs to signal this using the Stream
Cancellation instruction.  This signals to the encoder that all
references to the dynamic table on that stream are no longer
outstanding.  A decoder with a maximum dynamic table size equal to
zero MAY omit sending Stream Cancellations, because the encoder
cannot have any dynamic table references.
Paragraph (version B):
A stream that is reset might have multiple outstanding header blocks
with dynamic table references.  When an endpoint receives a stream
reset before the end of a stream, it generates a Stream Cancellation
instruction on the decoder stream.  Similarly, when an endpoint
abandons reading of a stream it needs to signal this using the Stream
Cancellation instruction.  This signals to the encoder that all
references to the dynamic table on that stream are no longer
outstanding.  A decoder with a maximum dynamic table size equal to
zero (see maximum-table-size) MAY omit sending Stream Cancellations,
because the encoder cannot have any dynamic table references.
Paragraph (version B):
"MaxTableSize" is the maximum size of the dynamic table as specified
by the decoder (see maximum-table-size).
Paragraph (version A):
The CANCEL_PUSH frame (type=0x3) is used to request cancellation of a
server push prior to the push stream being created.  The CANCEL_PUSH
frame identifies a server push by Push ID (see frame-push-promise),
encoded as a variable-length integer.
Paragraph (version B):
The CANCEL_PUSH frame (type=0x3) is used to request cancellation of a
server push prior to the push stream being received.  The CANCEL_PUSH
frame identifies a server push by Push ID (see frame-push-promise),
encoded as a variable-length integer.
Paragraph (version A):
In order to quickly complete the handshake and avoid spurious
retransmissions due to crypto retransmission timeouts, crypto packets
SHOULD use a very short ack delay, such as 1ms.  ACK frames MAY be
sent immediately when the crypto stack indicates all data for that
encryption level has been received.
Paragraph (version B):
In order to quickly complete the handshake and avoid spurious
retransmissions due to crypto retransmission timeouts, crypto packets
SHOULD use a very short ack delay, such as 1ms.  ACK frames MAY be
sent immediately when the crypto stack indicates all data for that
packet number space has been received.
Paragraph (version A):
The packet is unacknowledged, ack-eliciting, and was sent prior to
an acknowledged packet.
Paragraph (version B):
The packet is unacknowledged, in-flight, and was sent prior to an
acknowledged packet.
Paragraph (version A):
Implementers MAY experiment with using other reordering thresholds,
including absolute thresholds, bearing in mind that a lower
multiplier reduces reordering resilience and increases spurious
retransmissions, and a higher multiplier increases loss detection
delay.
Paragraph (version B):
Implementations MAY experiment with absolute thresholds, thresholds
from previous connections, adaptive thresholds, or including RTT
variance.  Smaller thresholds reduce reordering resilience and
increase spurious retransmissions, and larger thresholds increase
loss detection delay.
Paragraph (version B):
As described in Section 17.5.1 of QUIC-TRANSPORT, endpoints stop
sending and receiving Initial packets once they start exchanging
Handshake packets.  At this point, all loss recovery state for the
Initial packet number space is also discarded.  Packets that are in
flight for the packet number space are not declared as either
acknowledged or lost.  After discarding state, new Initial packets
will not be sent.
Paragraph (version B):
When a PTO timer expires, new or previously-sent data may not be
available to send and packets may still be in flight.  A sender can
be blocked from sending new data in the future if packets are left in
flight.  Under these conditions, a sender SHOULD mark any packets
still in flight as lost.  If a sender wishes to establish delivery of
packets still in flight, it MAY send an ack-eliciting packet and re-
arm the PTO timer instead.
Paragraph (version A):
The largest packet number acknowledged in an ACK frame.
Paragraph (version B):
The largest packet number acknowledged in the packet number space
so far.
Paragraph (version A):
DetectLostPackets takes one parameter, largest_acked, which is the
largest acked packet.
Paragraph (version A):
If a threshold number of consecutive PTOs have occurred (pto_count is
more than kPersistentCongestionThreshold, see cc-consts-of-interest),
the network is considered to be experiencing persistent congestion,
and the sender's congestion window MUST be reduced to the minimum
congestion window.
Paragraph (version B):
When an ACK frame is received that establishes loss of all in-flight
packets sent prior to a threshold number of consecutive PTOs
(pto_count is more than kPersistentCongestionThreshold, see cc-
consts-of-interest), the network is considered to be experiencing
persistent congestion, and the sender's congestion window MUST be
reduced to the minimum congestion window (kMinimumWindow).  This
response of collapsing the congestion window on persistent congestion
is functionally similar to a sender's response on a Retransmission
Timeout (RTO) in TCP RFC5681.
Paragraph (version A):
A connection is idle if there are no bytes in flight and there is no
pending ack-eliciting data to send.  This can occur when the
connection is application limited or after a probe timeout.  In order
to limit the size of bursts sent into the network, the behavior when
restarting from idle depends upon whether pacing is used.
Paragraph (version A):
If the sender uses pacing, the connection should limit the initial
burst of packets to no more than the initial congestion window and
subsequent packets SHOULD be paced.  The congestion window does not
change while the connection is idle.
Paragraph (version A):
A sender that does not use pacing SHOULD reset its congestion window
to the minimum of the current congestion window and the initial
congestion window.  This recommendation is based on Section 4.1 of
RFC5681.
Paragraph (version B):
A sender becomes idle if it ceases to send data and has no bytes in
flight.  A sender's congestion window MUST NOT increase while it is
idle.
Paragraph (version B):
When sending data after becoming idle, a sender MUST reset its
congestion window to the initial congestion window (see Section 4.1
of RFC5681), unless it paces the sending of packets.  A sender MAY
retain its congestion window if it paces the sending of any packets
in excess of the initial congestion window.
Paragraph (version B):
A sender MAY implement alternate mechanisms to update its congestion
window after idle periods, such as those proposed for TCP in RFC7661.
Paragraph (version B):
When keys for an packet number space are discarded, any packets sent
with those keys are removed from the count of bytes in flight.  No
loss events will occur any in-flight packets from that space, as a
result of discarding loss recovery state (see discard-initial).  Note
that it is expected that keys are discarded after those packets would
be declared lost, but Initial secrets are destroyed earlier.
Paragraph (version A):
Number of consecutive PTOs after which network is considered to be
experiencing persistent congestion.  The rationale for this
threshold is to enable a sender to use initial PTOs for aggressive
probing, similar to Tail Loss Probe (TLP) in TCP TLP RACK.  Once
the number of consecutive PTOs reaches this threshold - that is,
persistent congestion is established - the sender responds by
collapsing its congestion window to kMinimumWindow, similar to a
Retransmission Timeout (RTO) in TCP RFC5681.  The RECOMMENDED
value for kPersistentCongestionThreshold is 2, which is equivalent
to having two TLPs before an RTO in TCP.
Paragraph (version B):
Number of consecutive PTOs required for persistent congestion to
be established.  The rationale for this threshold is to enable a
sender to use initial PTOs for aggressive probing, as TCP does
with Tail Loss Probe (TLP) TLP RACK, before establishing
persistent congestion, as TCP does with a Retransmission Timeout
(RTO) RFC5681.  The RECOMMENDED value for
kPersistentCongestionThreshold is 2, which is equivalent to having
two TLPs before an RTO in TCP.
Paragraph (version A):
After QUIC moves to a new encryption level, packet protection keys
for previous encryption levels can be discarded.  This occurs several
times during the handshake, as well as when keys are updated (see
key-update).
Paragraph (version B):
After QUIC moves to a new encryption level, packet protection keys
for previous encryption levels can be discarded.  This occurs several
times during the handshake, as well as when keys are updated (see
key-update).  Initial packet protection keys are treated specially,
see discard-initial.
Paragraph (version A):
After all CRYPTO frames for a given encryption level have been sent
and all expected CRYPTO frames received, and all the corresponding
acknowledgments have been received or sent, an endpoint starts a
timer.  For 0-RTT keys, which do not carry CRYPTO frames, this timer
starts when the first packets protected with 1-RTT are sent or
received.  To limit the effect of packet loss around a change in
keys, endpoints MUST retain packet protection keys for that
encryption level for at least three times the current Retransmission
Timeout (RTO) interval as defined in QUIC-RECOVERY.  Retaining keys
for this interval allows packets containing CRYPTO or ACK frames at
that encryption level to be sent if packets are determined to be lost
or new packets require acknowledgment.
Paragraph (version B):
After all CRYPTO frames for a given encryption level have been sent
and all expected CRYPTO frames received, and all the corresponding
acknowledgments have been received or sent, an endpoint starts a
timer.  For 0-RTT keys, which do not carry CRYPTO frames, this timer
starts when the first packets protected with 1-RTT are sent or
received.  To limit the effect of packet loss around a change in
keys, endpoints MUST retain packet protection keys for that
encryption level for at least three times the current Probe Timeout
(PTO) interval as defined in QUIC-RECOVERY.  Retaining keys for this
interval allows packets containing CRYPTO or ACK frames at that
encryption level to be sent if packets are determined to be lost or
new packets require acknowledgment.
Paragraph (version B):
Packets protected with Initial secrets (initial-secrets) are not
authenticated, meaning that an attacker could spoof packets with the
intent to disrupt a connection.  To limit these attacks, Initial
packet protection keys can be discarded more aggressively than other
keys.
Paragraph (version B):
The successful use of Handshake packets indicates that no more
Initial packets need to be exchanged, as these keys can only be
produced after receiving all CRYPTO frames from Initial packets.
Thus, a client MUST discard Initial keys when it first sends a
Handshake packet and a server MUST discard Initial keys when it first
successfully processes a Handshake packet.  Endpoints MUST NOT send
Initial packets after this point.
Paragraph (version B):
This results in abandoning loss recovery state for the Initial
encryption level and ignoring any outstanding Initial packets.
Paragraph (version A):
The current encryption level secret and the label "quic key" are
input to the KDF to produce the AEAD key; the label "quic iv" is used
to derive the IV, see aead.  The packet number protection key uses
the "quic hp" label, see header-protect).  Using these labels
provides key separation between QUIC and TLS, see key-diversity.
Paragraph (version B):
The current encryption level secret and the label "quic key" are
input to the KDF to produce the AEAD key; the label "quic iv" is used
to derive the IV, see aead.  The header protection key uses the "quic
hp" label, see header-protect).  Using these labels provides key
separation between QUIC and TLS, see key-diversity.
Paragraph (version A):
The key and IV for the packet are computed as described in
protection-keys.  The nonce, N, is formed by combining the packet
protection IV with the packet number.  The 64 bits of the
reconstructed QUIC packet number in network byte order are left-
padded with zeros to the size of the IV.  The exclusive OR of the
padded packet number and the IV forms the AEAD nonce.
Paragraph (version B):
The key and IV for the packet are computed as described in
protection-keys.  The nonce, N, is formed by combining the packet
protection IV with the packet number.  The 62 bits of the
reconstructed QUIC packet number in network byte order are left-
padded with zeros to the size of the IV.  The exclusive OR of the
padded packet number and the IV forms the AEAD nonce.
Paragraph (version A):
The input plaintext, P, for the AEAD is the content of the QUIC frame
following the header, as described in QUIC-TRANSPORT.
Paragraph (version B):
The input plaintext, P, for the AEAD is the payload of the QUIC
packet, as described in QUIC-TRANSPORT.
Paragraph (version B):
The same header protection key is used for the duration of the
connection, with the value not changing after a key update (see key-
update).  This allows header protection to be used to protect the key
phase.
Paragraph (version A):
A receiving endpoint detects an update when the KEY_PHASE bit does
not match what it is expecting.  It creates a new secret (see
Section 7.2 of TLS13) and the corresponding read key and IV using the
KDF function provided by TLS.
Paragraph (version B):
A receiving endpoint detects an update when the KEY_PHASE bit does
not match what it is expecting.  It creates a new secret (see
Section 7.2 of TLS13) and the corresponding read key and IV using the
KDF function provided by TLS.  The header protection key is not
updated.
Paragraph (version A):
An endpoint SHOULD retain old keys for a short period to allow it to
decrypt packets with smaller packet numbers than the packet that
triggered the key update.  This allows an endpoint to consume packets
that are reordered around the transition between keys.  Packets with
higher packet numbers always use the updated keys and MUST NOT be
decrypted with old keys.
Paragraph (version A):
Keys and their corresponding secrets SHOULD be discarded when an
endpoint has received all packets with packet numbers lower than the
lowest packet number used for the new key.  An endpoint might discard
keys if it determines that the length of the delay to affected
packets is excessive.
Paragraph (version B):
An endpoint SHOULD retain old keys for a period of no more than three
times the Probe Timeout (PTO, see QUIC-RECOVERY).  After this period,
old keys and their corresponding secrets SHOULD be discarded.
Retaining keys allow endpoints to process packets that were sent with
old keys and delayed in the network.  Packets with higher packet
numbers always use the updated keys and MUST NOT be decrypted with
old keys.
Paragraph (version A):
TLS uses Application Layer Protocol Negotiation (ALPN) RFC7301 to
select an application protocol.  The application-layer protocol MAY
restrict the QUIC versions that it can operate over.  Servers MUST
select an application protocol compatible with the QUIC version that
the client has selected.
Paragraph (version A):
If the server cannot select a compatible combination of application
protocol and QUIC version, it MUST abort the connection.  A client
MUST abort a connection if the server picks an incompatible
combination of QUIC version and ALPN identifier.
Paragraph (version B):
QUIC requires that the cryptographic handshake provide authenticated
protocol negotiation.  TLS uses Application Layer Protocol
Negotiation (ALPN) RFC7301 to select an application protocol.  Unless
another mechanism is used for agreeing on an application protocol,
endpoints MUST use ALPN for this purpose.
Paragraph (version B):
An application-layer protocol MAY restrict the QUIC versions that it
can operate over.  Servers MUST select an application protocol
compatible with the QUIC version that the client has selected.  If
the server cannot select a compatible combination of application
protocol and QUIC version, it MUST abort the connection.  A client
MUST abort a connection if the server picks an incompatible
combination of QUIC version and ALPN identifier.
Paragraph (version A):
To preserve this separation, a new version of QUIC SHOULD define new
labels for key derivation for packet protection key and IV, plus the
packet number protection keys.
Paragraph (version B):
To preserve this separation, a new version of QUIC SHOULD define new
labels for key derivation for packet protection key and IV, plus the
header protection keys.
Paragraph (version A):
Sending the first STREAM or STREAM_DATA_BLOCKED frame causes a send
stream to enter the "Send" state.  An implementation might choose to
defer allocating a stream ID to a send stream until it sends the
first frame and enters this state, which can allow for better stream
prioritization.
Paragraph (version B):
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.
Paragraph (version A):
After the application indicates that all stream data has been sent
and a STREAM frame containing the FIN bit is sent, the send 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
send 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.
Paragraph (version A):
Once all stream data has been successfully acknowledged, the send
stream enters the "Data Recvd" state, which is a terminal state.
Paragraph (version B):
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.
Paragraph (version B):
Once all stream data has been successfully acknowledged, the sending
part of the stream enters the "Data Recvd" state, which is a terminal
state.
Paragraph (version A):
An endpoint MAY send a RESET_STREAM as the first frame on a send
stream; this causes the send stream to open and then immediately
transition to the "Reset Sent" state.
Paragraph (version A):
Once a packet containing a RESET_STREAM has been acknowledged, the
send stream enters the "Reset Recvd" state, which is a terminal
state.
Paragraph (version A):
fig-stream-recv-states shows the states for the part of a stream that
receives data from a peer.  The states for a receive stream mirror
only some of the states of the send stream at the peer.  A receive
stream does not track states on the send stream that cannot be
observed, such as the "Ready" state.  Instead, receive streams track
the delivery of data to the application, some of which cannot be
observed by the sender.
Paragraph (version A):
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 a
receive stream is "Recv".
Paragraph (version A):
The receive 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.
Paragraph (version B):
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.
Paragraph (version B):
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.
Paragraph (version B):
fig-stream-recv-states 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 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.
Paragraph (version B):
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".
Paragraph (version B):
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.
Paragraph (version A):
When a STREAM frame with a FIN bit is received, the final offset is
known (see final-offset).  The receive stream 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.
Paragraph (version A):
Once all data for the stream has been received, the receive stream
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.
Paragraph (version B):
When a STREAM frame with a FIN bit is received, the final offset is
known (see final-offset).  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.
Paragraph (version B):
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.
Paragraph (version A):
In the latter case, the receive stream transitions from "Reset Recvd"
to "Data Recvd".
Paragraph (version A):
Once the application has been delivered the signal indicating that
the receive stream was reset, the receive stream transitions to the
"Reset Read" state, which is a terminal state.
Paragraph (version B):
In the latter case, the receiving part of the stream transitions from
"Reset Recvd" to "Data Recvd".
Paragraph (version B):
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.
Paragraph (version A):
A bidirectional stream is composed of a send stream and a receive
stream.  Implementations may represent states of the bidirectional
stream as composites of send and receive stream states.  The simplest
model presents the stream as "open" when either send or receive
stream is in a non-terminal state and "closed" when both send and
receive streams are in a terminal state.
Paragraph (version A):
stream-bidi-mapping 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 send or receive 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.
Paragraph (version A):
A stream is considered "idle" if it has not yet been created, or
if the receive stream is in the "Recv" state without yet having
received any frames.
Paragraph (version B):
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
parts are in a non-terminal state and "closed" when both sending and
receiving streams are in terminal states.
Paragraph (version B):
stream-bidi-mapping 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.
Paragraph (version B):
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.
Paragraph (version A):
If the STOP_SENDING frame is received on a send 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.
Paragraph (version A):
STOP_SENDING SHOULD only be sent for a receive stream that has not
been reset.  STOP_SENDING is most useful for streams in the "Recv" or
"Size Known" states.
Paragraph (version B):
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.
Paragraph (version B):
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.
Paragraph (version A):
A receiver MAY use an autotuning mechanism to tune the frequency and
amount of advertised additional credit based on a round-trip time
estimate and the rate at which the receiving application consumes
data, similar to common TCP implementations.
Paragraph (version B):
A receiver can use an autotuning mechanism to tune the frequency and
amount of advertised additional credit based on a round-trip time
estimate and the rate at which the receiving application consumes
data, similar to common TCP implementations.  As an optimization,
sending frames related to flow control only when there are other
frames to send or when a peer is blocked ensures that flow control
doesn't cause extra packets to be sent.
Paragraph (version A):
The final offset is the count of the number of bytes that are
transmitted on a stream.  For a stream that is reset, the final
offset is carried explicitly in a RESET_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.
Paragraph (version A):
An endpoint will know the final offset for a stream when the receive
stream enters the "Size Known" or "Reset Recvd" state (stream-
states).
Paragraph (version B):
The final offset is the count of the number of bytes that are
transmitted on a stream.  For a stream that is reset, the final
offset is carried explicitly in a RESET_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.
Paragraph (version B):
An endpoint will know the final offset for a stream when the
receiving part of the stream enters the "Size Known" or "Reset Recvd"
state (stream-states).
Paragraph (version A):
If the Destination Connection ID is zero length and the packet
matches the address/port tuple of a connection where the host did not
require connection IDs, QUIC processes the packet as part of that
connection.  Endpoints MUST drop packets with zero-length Destination
Connection ID fields if they do not correspond to a single
connection.
Paragraph (version B):
If the Destination Connection ID is zero length and the packet
matches the address/port tuple of a connection where the host did not
require connection IDs, QUIC processes the packet as part of that
connection.  Endpoints SHOULD either reject connection attempts that
use the same addresses as existing connections, or use a non-zero-
length Destination Connection ID so that packets can be correctly
attributed to connections.
Paragraph (version A):
In order to prevent a handshake deadlock as a result of the server
being unable to send, clients SHOULD send a packet upon a handshake
timeout, as described in QUIC-RECOVERY.  If the client has no data to
retransmit and does not have Handshake keys, it SHOULD send an
Initial packet in a UDP datagram of at least 1200 bytes.  If the
client has Handshake keys, it SHOULD send a Handshake packet.
Paragraph (version B):
Packet loss, in particular loss of a Handshake packet from the
server, can cause a situation in which the server cannot send when
the client has no data to send and the anti-amplification limit is
reached.  In order to avoid this causing a handshake deadlock,
clients SHOULD send a packet upon a handshake timeout, as described
in QUIC-RECOVERY.  If the client has no data to retransmit and does
not have Handshake keys, it SHOULD send an Initial packet in a UDP
datagram of at least 1200 bytes.  If the client has Handshake keys,
it SHOULD send a Handshake packet.
Paragraph (version A):
Unlike the token that is created for a Retry packet, there might be
some time between when the token is created and when the token is
subsequently used.  Thus, a resumption token SHOULD include an
expiration time.  The server MAY include either an explicit
expiration time or an issued timestamp and dynamically calculate the
expiration time.  It is also unlikely that the client port number is
the same on two different connections; validating the port is
therefore unlikely to be successful.
Paragraph (version A):
A resumption token SHOULD be constructed to be easily distinguishable
from tokens that are sent in Retry packets as they are carried in the
same field.
Paragraph (version B):
Unlike the token that is created for a Retry packet, there might be
some time between when the token is created and when the token is
subsequently used.  Thus, a token SHOULD include an expiration time.
The server MAY include either an explicit expiration time or an
issued timestamp and dynamically calculate the expiration time.  It
is also unlikely that the client port number is the same on two
different connections; validating the port is therefore unlikely to
be successful.
Paragraph (version B):
A token SHOULD be constructed to be easily distinguishable from
tokens that are sent in Retry packets as they are carried in the same
field.
Paragraph (version A):
A token allows a server to correlate activity between the connection
where the token was issued and any connection where it is used.
Clients that want to break continuity of identity with a server MAY
discard tokens provided using the NEW_TOKEN frame.  Tokens obtained
in Retry packets MUST NOT be discarded.
Paragraph (version B):
A token allows a server to correlate activity between the connection
where the token was issued and any connection where it is used.
Clients that want to break continuity of identity with a server MAY
discard tokens provided using the NEW_TOKEN frame.  A token obtained
in a Retry packet MUST be used immediately during the connection
attempt and cannot be used in subsequent connection attempts.
Paragraph (version A):
In a stateless design, a server can use encrypted and authenticated
tokens to pass information to clients that the server can later
recover and use to validate a client address.  Tokens are not
integrated into the cryptographic handshake and so they are not
authenticated.  For instance, a client might be able to reuse a
token.  To avoid attacks that exploit this property, a server can
limit its use of tokens to only the information needed validate
client addresses.
Paragraph (version B):
In a stateless design, a server can use encrypted and authenticated
tokens to pass information to clients that the server can later
recover and use to validate a client address.  Tokens are not
integrated into the cryptographic handshake and so they are not
authenticated.  For instance, a client might be able to reuse a
token.  To avoid attacks that exploit this property, a server can
limit its use of tokens to only the information needed to validate
client addresses.
Paragraph (version A):
Path validation tests that packets can be both sent to and received
from a peer on the path.  Importantly, it validates that the packets
received from the migrating endpoint do not carry a spoofed source
address.
Paragraph (version B):
Path validation tests that packets (PATH_CHALLENGE) can be both sent
to and received (PATH_RESPONSE) from a peer on the path.
Importantly, it validates that the packets received from the
migrating endpoint do not carry a spoofed source address.
Paragraph (version A):
The endpoint MUST use fresh random data in every PATH_CHALLENGE frame
so that it can associate the peer's response with the causative
PATH_CHALLENGE.
Paragraph (version A):
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.  However, because a PATH_CHALLENGE might be
sent from a spoofed address, an endpoint MUST limit the rate at which
it sends PATH_RESPONSE frames and MAY silently discard PATH_CHALLENGE
frames that would cause it to respond at a higher rate.
Paragraph (version B):
The endpoint MUST use unpredictable data in every PATH_CHALLENGE
frame so that it can associate the peer's response with the
corresponding PATH_CHALLENGE.
Paragraph (version B):
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.
Paragraph (version A):
A new address is considered valid when a PATH_RESPONSE frame is
received containing data that was sent in a previous PATH_CHALLENGE.
Receipt of an acknowledgment for a packet containing a PATH_CHALLENGE
frame is not adequate validation, since the acknowledgment can be
spoofed by a malicious peer.
Paragraph (version A):
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.  If a PATH_RESPONSE frame is received from a
different remote address than the one to which the PATH_CHALLENGE was
sent, path validation is considered to have failed, even if the data
matches that sent in the PATH_CHALLENGE.
Paragraph (version A):
Additionally, the PATH_RESPONSE frame MUST be received on the same
local address from which the corresponding PATH_CHALLENGE was sent.
An endpoint considers the path to be valid when a PATH_RESPONSE frame
is received on the same path with the same payload as the
PATH_CHALLENGE frame.
Paragraph (version A):
If a PATH_RESPONSE frame is received on a different local address
than the one from which the PATH_CHALLENGE was sent, path validation
is not considered to be successful, even if the data matches the
PATH_CHALLENGE.  This doesn't result in path validation failure, as
it might be a result of a forwarded packet (see off-path-forward) or
misrouting.
Paragraph (version B):
It contains the data that was sent in a previous PATH_CHALLENGE.
Receipt of an acknowledgment for a packet containing a
PATH_CHALLENGE frame is not adequate validation, since the
acknowledgment can be spoofed by a malicious peer.
Paragraph (version B):
It was sent from the same remote address to which the
corresponding PATH_CHALLENGE was sent.  If a PATH_RESPONSE frame
is received from a different remote address than the one to which
the PATH_CHALLENGE was sent, path validation is considered to have
failed, even if the data matches that sent in the PATH_CHALLENGE.
Paragraph (version B):
It was received on the same local address from which the
corresponding PATH_CHALLENGE was sent.
Paragraph (version B):
Note that receipt on a different local address does not result in
path validation failure, as it might be a result of a forwarded
packet (see off-path-forward) or misrouting.  It is possible that a
valid PATH_RESPONSE might be received in the future.
Paragraph (version A):
Endpoints SHOULD abandon path validation based on a timer.  When
setting this timer, implementations are cautioned that the new path
could have a longer round-trip time than the original.  A value of
three times the current Retransmittion Timeout (RTO) as defined in
QUIC-RECOVERY is RECOMMENDED.
Paragraph (version A):
This eliminates the use of the connection ID for linking activity
from the same connection on different networks.  Protection of packet
numbers ensures that packet numbers cannot be used to correlate
activity.  This does not prevent other properties of packets, such as
timing and size, from being used to correlate activity.
Paragraph (version B):
This eliminates the use of the connection ID for linking activity
from the same connection on different networks.  Header protection
ensures that packet numbers cannot be used to correlate activity.
This does not prevent other properties of packets, such as timing and
size, from being used to correlate activity.
Paragraph (version A):
The closing and draining connection states exist to ensure that
connections close cleanly and that delayed or reordered packets are
properly discarded.  These states SHOULD persist for three times the
current Retransmission Timeout (RTO) interval as defined in QUIC-
RECOVERY.
Paragraph (version B):
The closing and draining connection states exist to ensure that
connections close cleanly and that delayed or reordered packets are
properly discarded.  These states SHOULD persist for three times the
current Probe Timeout (PTO) interval as defined in QUIC-RECOVERY.
Paragraph (version A):
An endpoint could receive packets from a new source address,
indicating a client connection migration (migration), while in the
closing period.  An endpoint in the closing state MUST strictly limit
the number of packets it sends to this new address until the address
is validated (see migrate-validate).  A server in the closing state
MAY instead choose to discard packets received from a new source
address.
Paragraph (version B):
While in the closing period, an endpoint could receive packets from a
new source address, indicating a client connection migration
(migration).  An endpoint in the closing state MUST strictly limit
the number of packets it sends to this new address until the address
is validated (see migrate-validate).  A server in the closing state
MAY instead choose to discard packets received from a new source
address.
Paragraph (version A):
The value for an idle timeout can be asymmetric.  The value
advertised by an endpoint is only used to determine whether the
connection is live at that endpoint.  An endpoint that sends packets
near the end of the idle timeout period of a peer risks having those
packets discarded if its peer enters the draining state before the
packets arrive.  If a peer could timeout within an RTO (see
Section 5.3.3 of QUIC-RECOVERY), it is advisable to test for liveness
before sending any data that cannot be retried safely.
Paragraph (version B):
The value for an idle timeout can be asymmetric.  The value
advertised by an endpoint is only used to determine whether the
connection is live at that endpoint.  An endpoint that sends packets
near the end of the idle timeout period of a peer risks having those
packets discarded if its peer enters the draining state before the
packets arrive.  If a peer could timeout within an Probe Timeout
(PTO, see Section 5.3.3 of QUIC-RECOVERY), it is advisable to test
for liveness before sending any data that cannot be retried safely.
Paragraph (version A):
Allowing retransmission of a packet contradicts other advice in
this document that recommends the creation of new packet numbers
for every packet.  Sending new packet numbers is primarily of
advantage to loss recovery and congestion control, which are not
expected to be relevant for a closed connection.  Retransmitting
the final packet requires less state.
Paragraph (version B):
Allowing retransmission of a closing packet contradicts other
advice in this document that recommends the creation of new packet
numbers for every packet.  Sending new packet numbers is primarily
of advantage to loss recovery and congestion control, which are
not expected to be relevant for a closed connection.
Retransmitting the final packet requires less state.
Paragraph (version A):
A stateless reset uses an entire UDP datagram, starting with the
first two bits of the packet header.  The remainder of the first byte
and an arbitrary number of random bytes following it are set to
unpredictable values.  The last 16 bytes of the datagram contain a
Stateless Reset Token.
Paragraph (version A):
A stateless reset will be interpreted by a recipient as a packet with
a short header.  For the packet to appear as valid, the Random Bits
field needs to include at least 182 bits of random or unpredictable
values (or 24 bytes, less the two fixed bits).  This is intended to
allow for a destination connection ID of the maximum length
permitted, with a minimal packet number, and payload.  The Stateless
Reset Token corresponds to the minimum expansion of the packet
protection AEAD.  More random bytes might be necessary if the
endpoint could have negotiated a packet protection scheme with a
larger minimum AEAD expansion.
Paragraph (version B):
A stateless reset uses an entire UDP datagram, starting with the
first two bits of the packet header.  The remainder of the first byte
and an arbitrary number of bytes following it that are set to
unpredictable values.  The last 16 bytes of the datagram contain a
Stateless Reset Token.
Paragraph (version B):
A stateless reset will be interpreted by a recipient as a packet with
a short header.  For the packet to appear as valid, the Random Bits
field needs to include at least 182 bits of data (or 23 bytes, less
the two fixed bits).  This is intended to allow for a Destination
Connection ID of the maximum length permitted, with a minimal packet
number, and payload.  The Stateless Reset Token corresponds to the
minimum expansion of the packet protection AEAD.  More unpredictable
bytes might be necessary if the endpoint could have negotiated a
packet protection scheme with a larger minimum AEAD expansion.
Paragraph (version A):
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 bytes of the packet
with the Stateless Reset Token provided by its peer, either in a
NEW_CONNECTION_ID frame or the server's transport parameters.  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.
Paragraph (version B):
An endpoint detects a potential stateless reset when a incoming
packet with a short header either cannot be associated with a
connection, cannot be decrypted, or is marked as a duplicate packet.
The endpoint then compares the last 16 bytes of the packet with the
Stateless Reset Token provided by its peer, either in a
NEW_CONNECTION_ID frame or the server's transport parameters.  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.
Paragraph (version A):
The design of a Stateless Reset is such that it is indistinguishable
from a valid packet.  This means that a Stateless Reset might trigger
the sending of a Stateless Reset in response, which could lead to
infinite exchanges.
Paragraph (version B):
The design of a Stateless Reset is such that without knowing the
stateless reset token it is indistinguishable from a valid packet.
For instance, if a server sends a Stateless Reset to another server
it might receive another Stateless Reset in response, which could
lead to an infinite exchange.
Paragraph (version A):
Reducing the size of a Stateless Reset below the recommended minimum
size of 37 bytes could mean that the packet could reveal to an
observer that it is a Stateless Reset.  Conversely, refusing to send
a Stateless Reset in response to a small packet might result in
Stateless Reset not being useful in detecting cases of broken
connections where only very small packets are sent; such failures
might only be detected by other means, such as timers.
Paragraph (version B):
Reducing the size of a Stateless Reset below the recommended minimum
size of 39 bytes could mean that the packet could reveal to an
observer that it is a Stateless Reset.  Conversely, refusing to send
a Stateless Reset in response to a small packet might result in
Stateless Reset not being useful in detecting cases of broken
connections where only very small packets are sent; such failures
might only be detected by other means, such as timers.
Paragraph (version A):
An endpoint can increase the odds that a packet will trigger a
Stateless Reset if it cannot be processed by padding it to at least
38 bytes.
Paragraph (version B):
An endpoint can increase the odds that a packet will trigger a
Stateless Reset if it cannot be processed by padding it to at least
40 bytes.
Paragraph (version A):
All QUIC packets except Version Negotiation and Retry packets use
authenticated encryption with additional data (AEAD) RFC5119 to
provide confidentiality and integrity protection.  Details of packet
protection are found in QUIC-TLS; this section includes an overview
of the process.
Paragraph (version A):
Initial packets are protected using keys that are statically derived.
This packet protection is not effective confidentiality protection,
it only exists to ensure that the sender of the packet is on the
network path.  Any entity that receives the Initial packet from a
client can recover the keys necessary to remove packet protection or
to generate packets that will be successfully authenticated.
Paragraph (version B):
All QUIC packets except Version Negotiation and Retry packets use
authenticated encryption with additional data (AEAD) RFC5116 to
provide confidentiality and integrity protection.  Details of packet
protection are found in QUIC-TLS; this section includes an overview
of the process.
Paragraph (version B):
Initial packets are protected using keys that are statically derived.
This packet protection is not effective confidentiality protection.
Initial protection only exists to ensure that the sender of the
packet is on the network path.  Any entity that receives the Initial
packet from a client can recover the keys necessary to remove packet
protection or to generate packets that will be successfully
authenticated.
Paragraph (version A):
The packet number field contains a packet number, which has
additional confidentiality protection that is applied after packet
protection is applied (see QUIC-TLS for details).  The underlying
packet number increases with each packet sent, see packet-numbers for
details.
Paragraph (version B):
The packet number field contains a packet number, which has
additional confidentiality protection that is applied after packet
protection is applied (see QUIC-TLS for details).  The underlying
packet number increases with each packet sent in a given packet
number space, see packet-numbers for details.
Paragraph (version A):
The packet number is an integer in the range 0 to 2^62-1.  Where
present, packet numbers are encoded as a variable-length integer (see
integer-encoding).  This number is used in determining the
cryptographic nonce for packet protection.  Each endpoint maintains a
separate packet number for sending and receiving.
Paragraph (version B):
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.
Paragraph (version B):
Packet numbers are limited to this range because they need to be
representable in whole in the Largest Acknowledged field of an ACK
frame (frame-ack).  When present in a long or short header however,
packet numbers are reduced and encoded in 1 to 4 bytes, see packet-
encoding).
Paragraph (version A):
The Frame Type field uses a variable length integer encoding (see
integer-encoding) with one exception.  To ensure simple and efficient
implementations of frame parsing, a frame type MUST use the shortest
possible encoding.  Though a two-, four- or eight-byte encoding of
the frame types defined in this document is possible, the Frame Type
field for these frames is encoded on a single byte.  For instance,
though 0x4007 is a legitimate two-byte encoding for a variable-length
integer with a value of 7, PING frames are always encoded as a single
byte with the value 0x07.  An endpoint MAY treat the receipt of a
frame type that uses a longer encoding than necessary as a connection
error of type PROTOCOL_VIOLATION.
Paragraph (version B):
The Frame Type field uses a variable length integer encoding (see
integer-encoding) with one exception.  To ensure simple and efficient
implementations of frame parsing, a frame type MUST use the shortest
possible encoding.  Though a two-, four- or eight-byte encoding of
the frame types defined in this document is possible, the Frame Type
field for these frames is encoded on a single byte.  For instance,
though 0x4007 is a legitimate two-byte encoding for a variable-length
integer with a value of 7, PING frames are always encoded as a single
byte with the value 0x01.  An endpoint MAY treat the receipt of a
frame type that uses a longer encoding than necessary as a connection
error of type PROTOCOL_VIOLATION.
Paragraph (version A):
Data sent in CRYPTO frames is retransmitted according to the rules
in QUIC-RECOVERY, until all data has been acknowledged.
Paragraph (version B):
Data sent in CRYPTO frames is retransmitted according to the rules
in QUIC-RECOVERY, until all data has been acknowledged.  Data in
CRYPTO frames for Initial and Handshake packets is discarded when
keys for the corresponding encryption level are discarded.
Paragraph (version A):
Cancellation of stream transmission, as carried in a RESET_STREAM
frame, is sent until acknowledged or until all stream data is
acknowledged by the peer (that is, either the "Reset Recvd" or
"Data Recvd" state is reached on the send stream).  The content of
a RESET_STREAM frame MUST NOT change when it is sent again.
Paragraph (version A):
Similarly, a request to cancel stream transmission, as encoded in
a STOP_SENDING frame, is sent until the receive stream enters
either a "Data Recvd" or "Reset Recvd" state, see solicited-state-
transitions.
Paragraph (version B):
Cancellation of stream transmission, as carried in a RESET_STREAM
frame, is sent until acknowledged or until all stream data is
acknowledged by the peer (that is, either the "Reset Recvd" or
"Data Recvd" state is reached on the sending part of the stream).
The content of a RESET_STREAM frame MUST NOT change when it is
sent again.
Paragraph (version B):
Similarly, a request to cancel stream transmission, as encoded in
a STOP_SENDING frame, is sent until the receiving part of the
stream enters either a "Data Recvd" or "Reset Recvd" state, see
solicited-state-transitions.
Paragraph (version A):
The current maximum stream data offset is sent in MAX_STREAM_DATA
frames.  Like MAX_DATA, an updated value is sent when the packet
containing the most recent MAX_STREAM_DATA frame for a stream is
lost or when the limit is updated, with care taken to prevent the
frame from being sent too often.  An endpoint SHOULD stop sending
MAX_STREAM_DATA frames when the receive stream enters a "Size
Known" state.
Paragraph (version B):
The current maximum stream data offset is sent in MAX_STREAM_DATA
frames.  Like MAX_DATA, an updated value is sent when the packet
containing the most recent MAX_STREAM_DATA frame for a stream is
lost or when the limit is updated, with care taken to prevent the
frame from being sent too often.  An endpoint SHOULD stop sending
MAX_STREAM_DATA frames when the receiving part of the stream
enters a "Size Known" state.
Paragraph (version A):
Blocked signals are carried in DATA_BLOCKED, STREAM_DATA_BLOCKED,
and STREAMS_BLOCKED frames.  DATA_BLOCKED streams have connection
scope, STREAM_DATA_BLOCKED frames have stream scope, and
STREAMS_BLOCKED frames are scoped to a specific stream type.  New
frames are sent if packets containing the most recent frame for a
scope is lost, but only while the endpoint is blocked on the
corresponding limit.  These frames always include the limit that
is causing blocking at the time that they are transmitted.
Paragraph (version B):
Blocked signals are carried in DATA_BLOCKED, STREAM_DATA_BLOCKED,
and STREAMS_BLOCKED frames.  DATA_BLOCKED frames have connection
scope, STREAM_DATA_BLOCKED frames have stream scope, and
STREAMS_BLOCKED frames are scoped to a specific stream type.  New
frames are sent if packets containing the most recent frame for a
scope is lost, but only while the endpoint is blocked on the
corresponding limit.  These frames always include the limit that
is causing blocking at the time that they are transmitted.
Paragraph (version A):
QUIC endpoints use Explicit Congestion Notification (ECN) RFC3168 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.  Endpoints react to
congestion by reducing their sending rate in response, as described
in QUIC-RECOVERY.
Paragraph (version B):
QUIC endpoints can use Explicit Congestion Notification (ECN) RFC3168
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.  Endpoints react to
congestion by reducing their sending rate in response, as described
in QUIC-RECOVERY.
Paragraph (version A):
On receiving a QUIC packet with an ECT or CE codepoint, an endpoint
that can access the ECN codepoints from the enclosing IP packet
increases the corresponding ECT(0), ECT(1), or CE count, and includes
these counters in subsequent ACK frames (see processing-and-ack and
frame-ack).
Paragraph (version B):
On receiving a QUIC packet with an ECT or CE codepoint, an ECN-
enabled endpoint that can access the ECN codepoints from the
enclosing IP packet increases the corresponding ECT(0), ECT(1), or CE
count, and includes these counts in subsequent ACK frames (see
processing-and-ack and frame-ack).  Note that this requires being
able to read the ECN codepoints from the enclosing IP packet, which
is not possible on all platforms.
Paragraph (version A):
If an endpoint receives a QUIC packet without an ECT or CE codepoint
in the IP packet header, it responds per processing-and-ack with an
ACK frame without increasing any ECN counters.  Similarly, if an
endpoint does not have access to received ECN codepoints, it does not
increase ECN counters.
Paragraph (version B):
If an endpoint receives a QUIC packet without an ECT or CE codepoint
in the IP packet header, it responds per processing-and-ack with an
ACK frame without increasing any ECN counts.  If an endpoint does not
implement ECN support or does not have access to received ECN
codepoints, it does not increase ECN counts.
Paragraph (version A):
Each packet number space maintains separate acknowledgement state and
separate ECN counters.  For example, if one each of an Initial,
0-RTT, Handshake, and 1-RTT QUIC packet are coalesced, the
corresponding counters for the Initial and Handshake packet number
space will be incremented by one and the counters for the 1-RTT
packet number space will be increased by two.
Paragraph (version A):
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.  Even if ECN is not used on
the path to the peer, the endpoint MUST provide feedback about ECN
markings received (if accessible).
Paragraph (version A):
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 RFC8311.
Paragraph (version B):
Each packet number space maintains separate acknowledgement state and
separate ECN counts.  For example, if one each of an Initial, 0-RTT,
Handshake, and 1-RTT QUIC packet are coalesced, the corresponding
counts for the Initial and Handshake packet number space will be
incremented by one and the counts for the 1-RTT packet number space
will be increased by two.
Paragraph (version B):
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.  Even if not setting ECN
codepoints on packets it transmits, the endpoint SHOULD provide
feedback about ECN markings received (if accessible).
Paragraph (version B):
To verify both that a path supports ECN and the peer can provide ECN
feedback, an endpoint sets the ECT(0) codepoint in the IP header of
all outgoing packets RFC8311.
Paragraph (version A):
The increase in ECT(0) and ECT(1) counters MUST be at least the
number of QUIC packets newly acknowledged that were sent with the
corresponding codepoint minus the increase in the CE counter.
This detects network remarking between ECT(0) and ECT(1).
Paragraph (version A):
The total increase in ECT(0), ECT(1), and CE counters reported in
the ACK frame MUST be at least the total number of QUIC packets
newly acknowledged in this ACK frame.  This detects if the network
changes ECT(0), ECT(1) or CE to Not-ECT.
Paragraph (version A):
This validation is only performed if the ACK frame increases the
largest received packet number.  Reordered acknowledgments could have
lower counter values and might not be successfully validated as a
result.
Paragraph (version A):
These counts might be inflated if acknowledgments are never received
for packets that were successfully delivered.  If validation
succeeds, an endpoint MUST increase its expected counter values to
those it receives.
Paragraph (version A):
An endpoint could miss acknowledgements for a packet when ACK frames
are lost.  It is therefore possible for the total increase in ECT(0),
ECT(1), and CE counters to be greater than the number of packets
acknowledged in an ACK frame.  When this happens, the local reference
counts MUST be increased to match the counters in the ACK frame.
Paragraph (version B):
Network devices that corrupt or apply non-standard ECN markings might
result in reduced throughput or other undesirable side-effects.  To
reduce this risk, an endpoint uses the following steps to verify the
counts it receives in an ACK frame.
Paragraph (version B):
The total increase in ECT(0), ECT(1), and CE counts MUST be no
smaller than the total number of QUIC packets sent with an ECT
codepoint that are newly acknowledged in this ACK frame.  This
step detects any network remarking from ECT(0), ECT(1), or CE
codepoints to Not-ECT.
Paragraph (version B):
Any increase in either ECT(0) or ECT(1) counts, plus any increase
in the CE count, MUST be no smaller than the number of packets
sent with the corresponding ECT codepoint that are newly
acknowledged in this ACK frame.  This step detects any erroneous
network remarking from ECT(0) to ECT(1) (or vice versa).
Paragraph (version B):
An endpoint could miss acknowledgements for a packet when ACK frames
are lost.  It is therefore possible for the total increase in ECT(0),
ECT(1), and CE counts to be greater than the number of packets
acknowledged in an ACK frame.  When this happens, and if verification
succeeds, the local reference counts MUST be increased to match the
counts in the ACK frame.
Paragraph (version B):
Processing counts out of order can result in verification failure.
An endpoint SHOULD NOT perform this verification if the ACK frame is
received in a packet with packet number lower than a previously
received ACK frame.  Verifying based on ACK frames that arrive out of
order can result in disabling ECN unnecessarily.
Paragraph (version A):
If an endpoint sets ECT codepoints on outgoing IP packets and
encounters a retransmission timeout due to the absence of
acknowledgments from the peer (see QUIC-RECOVERY), or if an endpoint
has reason to believe that an element on the network path might be
corrupting ECN codepoints, the endpoint MAY cease setting ECT
codepoints in subsequent packets.  Doing so allows the connection to
traverse network elements that drop IP packets with ECT or CE
markings or corrupt ECN codepoints in the IP header.
Paragraph (version A):
Clients MUST ensure they send the first Initial packet in a UDP
datagram that is at least 1200 bytes.  The payload of a UDP datagram
carrying the Initial packet MUST be expanded to at least 1200 bytes,
by adding PADDING frames to the Initial packet and/or by combining
the Initial packet with a 0-RTT packet (see packet-coalesce).
Sending a UDP datagram of this size ensures that the network path
supports a reasonable Maximum Transmission Unit (MTU), and helps
reduce the amplitude of amplification attacks caused by server
responses toward an unverified client address, see address-
validation.
Paragraph (version B):
If an endpoint sets ECT codepoints on outgoing IP packets and
encounters a retransmission timeout due to the absence of
acknowledgments from the peer (see QUIC-RECOVERY), or if an endpoint
has reason to believe that an element on the network path might be
corrupting ECN codepoints, the endpoint MAY cease setting ECT
codepoints in subsequent packets.  Doing so allows the connection to
be resilient to network elements that corrupt ECN codepoints in the
IP header or drop packets with ECT or CE codepoints in the IP header.
Paragraph (version B):
Clients MUST ensure they send the first Initial packet in a single IP
packet.  Similarly, the first Initial packet sent after receiving a
Retry packet MUST be sent in a single IP packet.
Paragraph (version B):
The payload of a UDP datagram carrying the first Initial packet MUST
be expanded to at least 1200 bytes, by adding PADDING frames to the
Initial packet and/or by combining the Initial packet with a 0-RTT
packet (see packet-coalesce).  Sending a UDP datagram of this size
ensures that the network path supports a reasonable Maximum
Transmission Unit (MTU), and helps reduce the amplitude of
amplification attacks caused by server responses toward an unverified
client address, see address-validation.
Paragraph (version A):
If a QUIC endpoint determines that the PMTU between any pair of local
and remote IP addresses has fallen below the size needed to support
the smallest allowed maximum packet size, it MUST immediately cease
sending QUIC packets on the affected path.  An endpoint MAY terminate
the connection if an alternative path cannot be found.
Paragraph (version B):
If a QUIC endpoint determines that the PMTU between any pair of local
and remote IP addresses has fallen below the size needed to support
the smallest allowed maximum packet size, it MUST immediately cease
sending QUIC packets, except for PMTU probe packets, on the affected
path.  An endpoint MAY terminate the connection if an alternative
path cannot be found.
Paragraph (version A):
PMTU discovery RFC1191 RFC8201 relies on reception of ICMP messages
(e.g., IPv6 Packet Too Big messages) that indicate when a packet is
dropped because it is larger than the local router MTU.  DPLPMTUD can
also optionally use these messages.  This use of ICMP messages is
potentially vulnerable to off-path attacks that successfully guess
the IP address 3-tuple and reduce the PMTU to a bandwidth-inefficient
value.
Paragraph (version A):
QUIC endpoints SHOULD provide validation to protect from off-path
injection of ICMP messages as specified in RFC8201 and Section 5.2 of
RFC8085.  This uses the quoted packet supplied in the payload of an
ICMP message, which, when present, can be used to associate the
message with a corresponding transport connection DPLPMTUD.
Paragraph (version A):
When a randomized source port is used for a QUIC connection, this can
provide some protection from off path attacks that forge ICMP
messages.  The source port in a quoted packet can be checked for UDP
transports RFC8085 such as QUIC.  When used, a stack will only pass
ICMP messages to a QUIC endpoint where the port information in quoted
packet within the ICMP payload matches a port used by QUIC.
Paragraph (version A):
As a part of ICMP validation, QUIC endpoints SHOULD validate that
connection ID information corresponds to an active session.
Paragraph (version B):
PMTU discovery RFC1191 RFC8201 relies on reception of ICMP messages
(e.g., IPv6 Packet Too Big messages) that indicate when a packet is
dropped because it is larger than the local router MTU.  DPLPMTUD can
also optionally use these messages.  This use of ICMP messages is
potentially vulnerable to off-path attacks that successfully guess
the addresses used on the path and reduce the PMTU to a bandwidth-
inefficient value.
Paragraph (version B):
QUIC endpoints SHOULD validate ICMP messages to protect from off-path
injection as specified in RFC8201 and Section 5.2 of RFC8085.  This
validation SHOULD use the quoted packet supplied in the payload of an
ICMP message to associate the message with a corresponding transport
connection DPLPMTUD.
Paragraph (version B):
ICMP message validation MUST include matching IP addresses and UDP
ports RFC8085 and, when possible, connection IDs to an active QUIC
session.
Paragraph (version A):
The endpoint SHOULD ignore all ICMP messages that are not validated
or do not carry sufficient quoted packet payload to perform
validation.  Any reduction in the QUIC maximum packet size MAY be
provisional until QUIC's loss detection algorithm determines that the
quoted packet has actually been lost.
Paragraph (version B):
The endpoint SHOULD ignore all ICMP messages that fail validation.
Paragraph (version B):
An endpoint MUST NOT increase PMTU based on ICMP messages.  Any
reduction in the QUIC maximum packet size MAY be provisional until
QUIC's loss detection algorithm determines that the quoted packet has
actually been lost.
Paragraph (version A):
Packet numbers in long and short packet headers are encoded in 1 to 4
bytes.  The number of bits required to represent the packet number is
reduced by including the least significant bits of the packet number.
Paragraph (version B):
Packet numbers are integers in the range 0 to 2^62-1 (packet-
numbers).  When present in long or short packet headers, they are
encoded in 1 to 4 bytes.  The number of bits required to represent
the packet number is reduced by including the least significant bits
of the packet number.
Paragraph (version A):
The packet number field is 1 to 4 bytes long.  The packet number
has confidentiality protection separate from packet protection, as
described in Section 5.4 of QUIC-TLS.  The length of the packet
number field is encoded in the plaintext packet number.  See
packet-encoding for details.
Paragraph (version B):
The packet number field is 1 to 4 bytes long.  The packet number
has confidentiality protection separate from packet protection, as
described in Section 5.4 of QUIC-TLS.  The length of the packet
number field is encoded in the Packet Number Length bits of byte 0
(see above).
Paragraph (version A):
The first Initial packet sent by either endpoint contains a packet
number of 0.  The packet number MUST increase monotonically
thereafter.  Initial packets are in a different packet number space
to other packets (see packet-numbers).
Paragraph (version B):
A client stops both sending and processing Initial packets when it
sends its first Handshake packet.  A server stops sending and
processing Initial packets when it receives its first Handshake
packet.  Though packets might still be in flight or awaiting
acknowledgment, no further Initial packets need to be exchanged
beyond this point.  Initial packet protection keys are discarded (see
Section 4.10 of QUIC-TLS) along with any loss recovery and congestion
control state (see Sections 5.3.1.2 and 6.9 of QUIC-RECOVERY).
Paragraph (version B):
Any data in CRYPTO frames is discarded - and no longer retransmitted
- when Initial keys are discarded.
Paragraph (version B):
The first Initial packet sent by either endpoint MUST contain a
packet number of 0.  The packet number MUST increase monotonically
thereafter.  Initial packets are in a different packet number space
to other packets (see packet-numbers).
Paragraph (version A):
A Handshake packet uses long headers with a type value of 0x3.  It is
used to carry acknowledgments and cryptographic handshake messages
from the server and client.
Paragraph (version B):
A Handshake packet uses long headers with a type value of 0x2.  It is
used to carry acknowledgments and cryptographic handshake messages
from the server and client.
Paragraph (version A):
The first Handshake packet sent by a server contains a packet number
of 0.  Handshake packets are their own packet number space.  Packet
numbers are incremented normally for other Handshake packets.
Paragraph (version B):
Handshake packets are their own packet number space, and thus the
first Handshake packet sent by a server contains a packet number of
0.
Paragraph (version B):
Like Initial packets (see discard-initial), data in CRYPTO frames at
the Handshake encryption level is discarded - and no longer
retransmitted - when Handshake protection keys are discarded.
Paragraph (version A):
If the client received and processed a Retry packet, it validates
that the original_connection_id transport parameter is present and
correct; otherwise, it validates that the transport parameter is
absent.  A client MUST treat a failed validation as a connection
error of type TRANSPORT_PARAMETER_ERROR.
Paragraph (version B):
If the client received and processed a Retry packet, it MUST validate
that the original_connection_id transport parameter is present and
correct; otherwise, it MUST validate that the transport parameter is
absent.  A client MUST treat a failed validation as a connection
error of type TRANSPORT_PARAMETER_ERROR.
Paragraph (version A):
The idle timeout is a value in seconds that is encoded as an
integer.  If this parameter is absent or zero then the idle
timeout is disabled.
Paragraph (version B):
The idle timeout is a value in seconds that is encoded as an
integer, see (idle-timeout).  If this parameter is absent or zero
then the idle timeout is disabled.
Paragraph (version A):
This parameter is an integer value specifying the initial flow
control limit for unidirectional streams.  This limit applies to
newly created bidirectional streams opened by the endpoint that
receives the transport parameter.  In client transport parameters,
this applies to streams with an identifier with the least
significant two bits set to 0x3; in server transport parameters,
this applies to streams with the least significant two bits set to
0x2.
Paragraph (version B):
This parameter is an integer value specifying the initial flow
control limit for unidirectional streams.  This limit applies to
newly created unidirectional streams opened by the endpoint that
receives the transport parameter.  In client transport parameters,
this applies to streams with an identifier with the least
significant two bits set to 0x3; in server transport parameters,
this applies to streams with the least significant two bits set to
0x2.
Paragraph (version A):
Receivers send ACK frames (types 0x02 and 0x03) to inform senders of
packets they have received and processed.  The ACK frame contains one
or more ACK Ranges.  ACK Ranges identify acknowledged packets.  If
the frame type is 0x03, ACK frames also contain the sum of QUIC
packets with associated ECN marks received on the connection up until
this point.
Paragraph (version B):
Receivers send ACK frames (types 0x02 and 0x03) to inform senders of
packets they have received and processed.  The ACK frame contains one
or more ACK Ranges.  ACK Ranges identify acknowledged packets.  If
the frame type is 0x03, ACK frames also contain the sum of QUIC
packets with associated ECN marks received on the connection up until
this point.  QUIC implementations MUST properly handle both types
and, if they have enabled ECN for packets they send, they SHOULD use
the information in the ECN section to manage their congestion state.
Paragraph (version A):
The three ECN Counters, see ack-ecn-counters.
Paragraph (version B):
The three ECN Counts, see ack-ecn-counts.
Paragraph (version A):
ECN counters are maintained separately for each packet number space.
Paragraph (version B):
ECN counts are maintained separately for each packet number space.
Paragraph (version A):
Receipt of a STOP_SENDING frame is invalid for a locally-initiated
stream that has not yet been created or is in the "Ready" state (see
stream-send-states).  Receiving a STOP_SENDING frame for a locally-
initiated send stream that is "Ready" or not yet created MUST be
treated as a connection error of type PROTOCOL_VIOLATION.  An
endpoint that receives a STOP_SENDING frame for a receive-only stream
MUST terminate the connection with error PROTOCOL_VIOLATION.
Paragraph (version B):
Receipt of a STOP_SENDING frame is invalid for a locally-initiated
stream that has not yet been created or is in the "Ready" state (see
stream-send-states).  Receiving a STOP_SENDING frame for a locally-
initiated stream that is "Ready" or not yet created MUST be treated
as a connection error of type PROTOCOL_VIOLATION.  An endpoint that
receives a STOP_SENDING frame for a receive-only stream MUST
terminate the connection with error PROTOCOL_VIOLATION.
Paragraph (version A):
A server sends a NEW_TOKEN frame (type=0x07) to provide the client a
token to send in the header of an Initial packet for a future
connection.
Paragraph (version B):
A server sends a NEW_TOKEN frame (type=0x07) to provide the client
with a token to send in the header of an Initial packet for a future
connection.
Paragraph (version A):
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^62.
Paragraph (version B):
The first byte in the stream has an offset of 0.  The largest offset
delivered on a stream - the sum of the offset and data length - MUST
be less than 2^62.
Paragraph (version A):
A variable-length integer 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.
Paragraph (version B):
A variable-length integer specifying the length of the reason
phrase in bytes.  Because a CONNECTION_CLOSE frame cannot be split
between packets, any limits on packet size will also limit the
space available for a reason phrase.