SPECIFICATION: https://www.rfc-editor.org/rfc/rfc9000 SECTION: [Stream Types and Identifiers](#section-2.1) TEXT[!MUST,implementation,test]: A QUIC TEXT[!MUST,implementation,test]: endpoint MUST NOT reuse a stream ID within a connection. SECTION: [Sending and Receiving Data](#section-2.2) TEXT[!MUST,implementation,test]: Endpoints MUST be able to deliver stream data to an application as an TEXT[!MUST,implementation,test]: ordered byte stream. TEXT[!MAY]: However, TEXT[!MAY,implementation,test]: implementations MAY choose to offer the ability to TEXT[!MAY,implementation,test]: deliver data out of order to a receiving application. TEXT[!MUST,implementation,test]: The data at a given offset MUST NOT change if it is sent TEXT[!MUST,implementation,test]: multiple times TEXT[!MUST,exception]: ; an endpoint MAY treat receipt of different data at TEXT[!MUST,exception]: the same offset within a stream as a connection error of type TEXT[!MUST,exception]: PROTOCOL_VIOLATION. TEXT[!MUST,implementation,test]: An endpoint MUST NOT send data on any stream without ensuring that it TEXT[!MUST,implementation,test]: is within the flow control limits set by its peer. SECTION: [Stream Prioritization](#section-2.3) TEXT[!SHOULD,implementation,test]: A QUIC implementation SHOULD provide ways in which an application can TEXT[!SHOULD,implementation,test]: indicate the relative priority of streams. SECTION: [Sending Stream States](#section-3.1) TEXT[!MAY,exception]: An endpoint MAY send a RESET_STREAM as the first frame that mentions TEXT[!MAY,exception]: a stream; this causes the sending part of that stream to open and TEXT[!MAY,exception]: then immediately transition to the "Reset Sent" state. SECTION: [Receiving Stream States](#section-3.2) TEXT[!MUST,implementation,test]: Before a stream is created, all streams of the same type with lower- TEXT[!MUST,implementation,test]: numbered stream IDs MUST be created. TEXT[!MAY,exception]: An TEXT[!MAY,exception]: implementation MAY interrupt delivery of stream data, discard any TEXT[!MAY,exception]: data that was not consumed, and signal the receipt of the TEXT[!MAY,exception]: RESET_STREAM. SECTION: [Permitted Frame Types](#section-3.3) TEXT[!MUST,implementation,test]: A sender MUST NOT send any of these frames from a terminal state TEXT[!MUST,implementation,test]: ("Data Recvd" or "Reset Recvd"). TEXT[!MUST,implementation,test]: A sender MUST NOT send a STREAM or TEXT[!MUST,implementation,test]: STREAM_DATA_BLOCKED frame for a stream in the "Reset Sent" state or TEXT[!MUST,implementation,test]: any terminal state -- that is, after sending a RESET_STREAM frame. TEXT[!MAY,exception]: A receiver MAY send a STOP_SENDING frame in any state where it has TEXT[!MAY,exception]: not received a RESET_STREAM frame -- that is, states other than TEXT[!MAY,exception]: "Reset Recvd" or "Reset Read". SECTION: [Solicited State Transitions](#section-3.5) TEXT[!SHOULD,implementation,test]: If the stream is in the "Recv" or "Size Known" state, the transport TEXT[!SHOULD,implementation,test]: SHOULD signal this by sending a STOP_SENDING frame to prompt closure TEXT[!SHOULD,implementation,test]: of the stream in the opposite direction. TEXT[!MUST,implementation,test]: An endpoint that receives a STOP_SENDING frame TEXT[!MUST,implementation,test]: MUST send a RESET_STREAM frame if the stream is in the "Ready" or TEXT[!MUST,implementation,test]: "Send" state. TEXT[!MAY,exception]: If the stream is in the "Data Sent" state, the TEXT[!MAY,exception]: endpoint MAY defer sending the RESET_STREAM frame until the packets TEXT[!MAY,exception]: containing outstanding data are acknowledged or declared lost. TEXT[!SHOULD,implementation,test]: If TEXT[!SHOULD,implementation,test]: any outstanding data is declared lost, the endpoint SHOULD send a TEXT[!SHOULD,implementation,test]: RESET_STREAM frame instead of retransmitting the data. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD copy the error code from the STOP_SENDING frame to TEXT[!SHOULD,implementation,test]: the RESET_STREAM frame it sends, but it can use any application error TEXT[!SHOULD,implementation,test]: code. TEXT[!MAY,exception]: An endpoint that sends a STOP_SENDING frame MAY ignore the TEXT[!MAY,exception]: error code in any RESET_STREAM frames subsequently received for that TEXT[!MAY,exception]: stream. TEXT[!SHOULD,implementation,test]: STOP_SENDING SHOULD only be sent for a stream that has not been reset TEXT[!SHOULD,implementation,test]: by the peer. SECTION: [Flow Control](#section-4) TEXT[!SHOULD,implementation]: To avoid excessive buffering at multiple layers, QUIC implementations TEXT[!SHOULD,implementation]: SHOULD provide an interface for the cryptographic protocol TEXT[!SHOULD,implementation]: implementation to communicate its buffering limits. SECTION: [Data Flow Control](#section-4.1) TEXT[!MUST,implementation,test]: Senders MUST NOT send data in excess of either limit. TEXT[!MUST,implementation,test]: A receiver MUST close the connection with an error of type TEXT[!MUST,implementation,test]: FLOW_CONTROL_ERROR if the sender violates the advertised connection TEXT[!MUST,implementation,test]: or stream data limits; see Section 11 for details on error handling. TEXT[!MUST,implementation,test]: A sender MUST ignore any MAX_STREAM_DATA or MAX_DATA frames that do TEXT[!MUST,implementation,test]: not increase flow control limits. TEXT[!SHOULD,implementation,test]: A sender SHOULD send a TEXT[!SHOULD,implementation,test]: STREAM_DATA_BLOCKED or DATA_BLOCKED frame to indicate to the receiver TEXT[!SHOULD,implementation,test]: that it has data to write but is blocked by flow control limits. TEXT[!SHOULD,implementation,test]: To keep the TEXT[!SHOULD,implementation,test]: connection from closing, a sender that is flow control limited SHOULD TEXT[!SHOULD,implementation,test]: periodically send a STREAM_DATA_BLOCKED or DATA_BLOCKED frame when it TEXT[!SHOULD,implementation,test]: has no ack-eliciting packets in flight. SECTION: [Increasing Flow Control Limits](#section-4.2) TEXT[!MAY,implementation]: To avoid blocking a sender, a receiver MAY send a MAX_STREAM_DATA or TEXT[!MAY,implementation]: MAX_DATA frame multiple times within a round trip or send it early TEXT[!MAY,implementation]: enough to allow time for loss of the frame and subsequent recovery. TEXT[!MUST,implementation,test]: Therefore, a receiver MUST NOT wait for a TEXT[!MUST,implementation,test]: STREAM_DATA_BLOCKED or DATA_BLOCKED frame before sending a TEXT[!MUST,implementation,test]: MAX_STREAM_DATA or MAX_DATA frame; doing so could result in the TEXT[!MUST,implementation,test]: sender being blocked for the rest of the connection. SECTION: [Handling Stream Cancellation](#section-4.4) TEXT[!MUST,implementation,test]: Both endpoints MUST maintain flow control state TEXT[!MUST,implementation,test]: for the stream in the unterminated direction until that direction TEXT[!MUST,implementation,test]: enters a terminal state. SECTION: [Stream Final Size](#section-4.5) TEXT[!MUST,implementation,test]: The receiver MUST use the final size of the stream to TEXT[!MUST,implementation,test]: account for all bytes sent on the stream in its connection-level flow TEXT[!MUST,implementation,test]: controller. TEXT[!MUST,implementation,test]: An endpoint MUST NOT send data on a stream at or beyond the final TEXT[!MUST,implementation,test]: size. TEXT[implementation,test]: Once a final size for a stream is known, it cannot change. TEXT[!SHOULD,implementation,test]: If a TEXT[!SHOULD,implementation,test]: RESET_STREAM or STREAM frame is received indicating a change in the TEXT[!SHOULD,implementation,test]: final size for the stream, an endpoint SHOULD respond with an error TEXT[!SHOULD,implementation,test]: of type FINAL_SIZE_ERROR; see Section 11 for details on error TEXT[!SHOULD,implementation,test]: handling. TEXT[!SHOULD,implementation,test]: A receiver SHOULD treat receipt of data at or beyond the TEXT[!SHOULD,implementation,test]: final size as an error of type FINAL_SIZE_ERROR, even after a stream TEXT[!SHOULD,implementation,test]: is closed. SECTION: [Controlling Concurrency](#section-4.6) TEXT[!MUST,implementation,test]: If either is received, the connection MUST be closed TEXT[!MUST,implementation,test]: immediately with a connection error of type TRANSPORT_PARAMETER_ERROR TEXT[!MUST,implementation,test]: if the offending value was received in a transport parameter or of TEXT[!MUST,implementation,test]: type FRAME_ENCODING_ERROR if it was received in a frame; see TEXT[!MUST,implementation,test]: Section 10.2. TEXT[!MUST,implementation,test]: Endpoints MUST NOT exceed the limit set by their peer. TEXT[!MUST,implementation,test]: An endpoint TEXT[!MUST,implementation,test]: that receives a frame with a stream ID exceeding the limit it has TEXT[!MUST,implementation,test]: sent MUST treat this as a connection error of type TEXT[!MUST,implementation,test]: STREAM_LIMIT_ERROR; see Section 11 for details on error handling. TEXT[!MUST,implementation,test]: MAX_STREAMS frames TEXT[!MUST,implementation,test]: that do not increase the stream limit MUST be ignored. TEXT[test]: Implementations might choose TEXT[test]: to increase limits as streams are closed, to keep the number of TEXT[test]: streams available to peers roughly consistent. TEXT[!SHOULD,implementation,test]: An endpoint that is unable to open a new stream due to the peer's TEXT[!SHOULD,implementation,test]: limits SHOULD send a STREAMS_BLOCKED frame (Section 19.14). TEXT[!MUST,implementation,test]: An endpoint MUST NOT wait TEXT[!MUST,implementation,test]: to receive this signal before advertising additional credit, since TEXT[!MUST,implementation,test]: doing so will mean that the peer will be blocked for at least an TEXT[!MUST,implementation,test]: entire round trip, and potentially indefinitely if the peer chooses TEXT[!MUST,implementation,test]: not to send STREAMS_BLOCKED frames. SECTION: [Connection ID](#section-5.1) TEXT[!MUST,implementation]: Connection IDs MUST NOT contain any information that can be used by TEXT[!MUST,implementation]: an external observer (that is, one that does not cooperate with the TEXT[!MUST,implementation]: issuer) to correlate them with other connection IDs for the same TEXT[!MUST,implementation]: connection. TEXT[!MUST,implementation,test]: As a trivial example, this means the same connection ID TEXT[!MUST,implementation,test]: MUST NOT be issued more than once on the same connection. TEXT[!MUST,implementation]: An TEXT[!MUST,implementation]: endpoint MUST NOT use the same IP address and port for multiple TEXT[!MUST,implementation]: concurrent connections with zero-length connection IDs, unless it is TEXT[!MUST,implementation]: certain that those protocol features are not in use. SECTION: [Issuing Connection IDs](#section-5.1.1) TEXT[test]: If the preferred_address transport TEXT[test]: parameter is sent, the sequence number of the supplied connection ID TEXT[test]: is 1. TEXT[!MUST,implementation,test]: The sequence number on TEXT[!MUST,implementation,test]: each newly issued connection ID MUST increase by 1. TEXT[!MUST,implementation,test]: When an endpoint issues a connection ID, it MUST accept packets that TEXT[!MUST,implementation,test]: carry this connection ID for the duration of the connection or until TEXT[!MUST,implementation,test]: its peer invalidates the connection ID via a RETIRE_CONNECTION_ID TEXT[!MUST,implementation,test]: frame (Section 19.16). TEXT[!SHOULD,implementation,test]: An endpoint SHOULD ensure that its peer has a sufficient number of TEXT[!SHOULD,implementation,test]: available and unused connection IDs. TEXT[!MUST,implementation,test]: An endpoint MUST NOT TEXT[!MUST,implementation,test]: provide more connection IDs than the peer's limit. TEXT[!MAY,implementation,test]: An endpoint MAY TEXT[!MAY,implementation,test]: send connection IDs that temporarily exceed a peer's limit if the TEXT[!MAY,implementation,test]: NEW_CONNECTION_ID frame also requires the retirement of any excess, TEXT[!MAY,implementation,test]: by including a sufficiently large value in the Retire Prior To field. TEXT[!MUST,implementation,test]: After processing a NEW_CONNECTION_ID frame and TEXT[!MUST,implementation,test]: adding and retiring active connection IDs, if the number of active TEXT[!MUST,implementation,test]: connection IDs exceeds the value advertised in its TEXT[!MUST,implementation,test]: active_connection_id_limit transport parameter, an endpoint MUST TEXT[!MUST,implementation,test]: close the connection with an error of type CONNECTION_ID_LIMIT_ERROR. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD supply a new connection ID when the peer retires a TEXT[!SHOULD,implementation,test]: connection ID. TEXT[!MAY,implementation,test]: If an endpoint provided fewer connection IDs than the TEXT[!MAY,implementation,test]: peer's active_connection_id_limit, it MAY supply a new connection ID TEXT[!MAY,implementation,test]: when it receives a packet with a previously unused connection ID. TEXT[!MAY,implementation]: An TEXT[!MAY,implementation]: endpoint MAY limit the total number of connection IDs issued for each TEXT[!MAY,implementation]: connection to avoid the risk of running out of connection IDs; see TEXT[!MAY,implementation]: Section 10.3.2. TEXT[!MAY,implementation]: An endpoint MAY also limit the issuance of TEXT[!MAY,implementation]: connection IDs to reduce the amount of per-path state it maintains, TEXT[!MAY,implementation]: such as path validation status, as its peer might interact with it TEXT[!MAY,implementation]: over as many paths as there are issued connection IDs. TEXT[!SHOULD,implementation,test]: An endpoint that initiates migration and requires non-zero-length TEXT[!SHOULD,implementation,test]: connection IDs SHOULD ensure that the pool of connection IDs TEXT[!SHOULD,implementation,test]: available to its peer allows the peer to use a new connection ID on TEXT[!SHOULD,implementation,test]: migration, as the peer will be unable to respond if the pool is TEXT[!SHOULD,implementation,test]: exhausted. TEXT[test]: An endpoint that selects a zero-length connection ID during the TEXT[test]: handshake cannot issue a new connection ID. SECTION: [Consuming and Retiring Connection IDs](#section-5.1.2) TEXT[!SHOULD,implementation,test]: Endpoints SHOULD retire connection IDs when TEXT[!SHOULD,implementation,test]: they are no longer actively using either the local or destination TEXT[!SHOULD,implementation,test]: address for which the connection ID was used. TEXT[implementation]: An endpoint might need to stop accepting previously issued connection TEXT[implementation]: IDs in certain circumstances. Such an endpoint can cause its peer to TEXT[implementation]: retire connection IDs by sending a NEW_CONNECTION_ID frame with an TEXT[implementation]: increased Retire Prior To field. TEXT[!SHOULD,implementation,test]: The endpoint SHOULD continue to TEXT[!SHOULD,implementation,test]: accept the previously issued connection IDs until they are retired by TEXT[!SHOULD,implementation,test]: the peer. TEXT[!MAY,implementation]: If the endpoint can no longer process the indicated TEXT[!MAY,implementation]: connection IDs, it MAY close the connection. TEXT[!MUST,implementation,test]: Upon receipt of an increased Retire Prior To field, the peer MUST TEXT[!MUST,implementation,test]: stop using the corresponding connection IDs and retire them with TEXT[!MUST,implementation,test]: RETIRE_CONNECTION_ID frames before adding the newly provided TEXT[!MUST,implementation,test]: connection ID to the set of active connection IDs. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD limit the number of connection IDs it has retired TEXT[!SHOULD,implementation,test]: locally for which RETIRE_CONNECTION_ID frames have not yet been TEXT[!SHOULD,implementation,test]: acknowledged. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD allow for sending and tracking a TEXT[!SHOULD,implementation,test]: number of RETIRE_CONNECTION_ID frames of at least twice the value of TEXT[!SHOULD,implementation,test]: the active_connection_id_limit transport parameter. TEXT[!MUST,implementation,test]: An endpoint MUST TEXT[!MUST,implementation,test]: NOT forget a connection ID without retiring it, though it MAY choose TEXT[!MUST,implementation,test]: to treat having connection IDs in need of retirement that exceed this TEXT[!MUST,implementation,test]: limit as a connection error of type CONNECTION_ID_LIMIT_ERROR. TEXT[!SHOULD,implementation,test]: Endpoints SHOULD NOT issue updates of the Retire Prior To field TEXT[!SHOULD,implementation,test]: before receiving RETIRE_CONNECTION_ID frames that retire all TEXT[!SHOULD,implementation,test]: connection IDs indicated by the previous Retire Prior To value. SECTION: [Matching Packets to Connections](#section-5.2) TEXT[!MAY,implementation]: Invalid packets that lack strong integrity protection, such as TEXT[!MAY,implementation]: Initial, Retry, or Version Negotiation, MAY be discarded. TEXT[!MUST,implementation,test]: An TEXT[!MUST,implementation,test]: endpoint MUST generate a connection error if processing the contents TEXT[!MUST,implementation,test]: of these packets prior to discovering an error, or fully revert any TEXT[!MUST,implementation,test]: changes made during that processing. SECTION: [Client Packet Handling](#section-5.2.1) TEXT[!MAY,implementation]: The client MAY drop these packets, or it MAY buffer them in TEXT[!MAY,implementation]: anticipation of later packets that allow it to compute the key. TEXT[!MUST,implementation]: If a client receives a packet that uses a different version than it TEXT[!MUST,implementation]: initially selected, it MUST discard that packet. SECTION: [Server Packet Handling](#section-5.2.2) TEXT[!SHOULD,implementation,test]: If a server receives a packet that indicates an unsupported version TEXT[!SHOULD,implementation,test]: and if the packet is large enough to initiate a new connection for TEXT[!SHOULD,implementation,test]: any supported version, the server SHOULD send a Version Negotiation TEXT[!SHOULD,implementation,test]: packet as described in Section 6.1. TEXT[!MAY,implementation]: A server MAY limit the number of TEXT[!MAY,implementation]: packets to which it responds with a Version Negotiation packet. TEXT[!MUST,implementation,test]: Servers MUST drop smaller packets that specify unsupported versions. TEXT[!SHOULD,implementation,test]: Servers SHOULD respond with a Version TEXT[!SHOULD,implementation,test]: Negotiation packet, provided that the datagram is sufficiently long. TEXT[!SHOULD,implementation,test]: If a server refuses to accept a new connection, it SHOULD send an TEXT[!SHOULD,implementation,test]: Initial packet containing a CONNECTION_CLOSE frame with error code TEXT[!SHOULD,implementation,test]: CONNECTION_REFUSED. TEXT[!MAY,implementation,test]: If the packet is a 0-RTT packet, the server MAY buffer a limited TEXT[!MAY,implementation,test]: number of these packets in anticipation of a late-arriving Initial TEXT[!MAY,implementation,test]: packet. TEXT[!SHOULD,implementation,test]: Clients are not able to send Handshake packets prior to TEXT[!SHOULD,implementation,test]: receiving a server response, so servers SHOULD ignore any such TEXT[!SHOULD,implementation,test]: packets. TEXT[!MUST,implementation,test]: Servers MUST drop incoming packets under all other circumstances. SECTION: [Considerations for Simple Load Balancers](#section-5.2.3) TEXT[!SHOULD,exception]: A server in a deployment that does not implement a solution to TEXT[!SHOULD,exception]: maintain connection continuity when the client address changes SHOULD TEXT[!SHOULD,exception]: indicate that migration is not supported by using the TEXT[!SHOULD,exception]: disable_active_migration transport parameter. TEXT[!MUST,exception]: Server deployments that use this simple form of load balancing MUST TEXT[!MUST,exception]: avoid the creation of a stateless reset oracle; see Section 21.11. SECTION: [Version Negotiation](#section-6) TEXT[!SHOULD,implementation]: Clients that support TEXT[!SHOULD,implementation]: multiple QUIC versions SHOULD ensure that the first UDP datagram they TEXT[!SHOULD,implementation]: send is sized to the largest of the minimum datagram sizes from all TEXT[!SHOULD,implementation]: versions they support, using PADDING frames (Section 19.1) as TEXT[!SHOULD,implementation]: necessary. SECTION: [Sending Version Negotiation Packets](#section-6.1) TEXT[!MUST,implementation,test]: An endpoint MUST NOT send a Version Negotiation packet TEXT[!MUST,implementation,test]: in response to receiving a Version Negotiation packet. TEXT[!MAY,implementation]: A server MAY limit the number of Version Negotiation packets it TEXT[!MAY,implementation]: sends. SECTION: [Handling Version Negotiation Packets](#section-6.2) TEXT[!MUST,implementation,test]: A client that supports only this version of QUIC MUST abandon the TEXT[!MUST,implementation,test]: current connection attempt if it receives a Version Negotiation TEXT[!MUST,implementation,test]: packet, with the following two exceptions. TEXT[!MUST,implementation,test]: A client MUST discard any TEXT[!MUST,implementation,test]: Version Negotiation packet if it has received and successfully TEXT[!MUST,implementation,test]: processed any other packet, including an earlier Version Negotiation TEXT[!MUST,implementation,test]: packet. TEXT[!MUST,implementation,test]: A client MUST discard a Version Negotiation packet that TEXT[!MUST,implementation,test]: lists the QUIC version selected by the client. SECTION: [Using Reserved Versions](#section-6.3) TEXT[!MAY,implementation]: Endpoints MAY add reserved versions to any field where unknown or TEXT[!MAY,implementation]: unsupported versions are ignored to test that a peer correctly TEXT[!MAY,implementation]: ignores the value. TEXT[!MAY,implementation,test]: Endpoints MAY send packets with a reserved version to test that a TEXT[!MAY,implementation,test]: peer correctly discards the packet. SECTION: [Cryptographic and Transport Handshake](#section-7) TEXT[!MUST,implementation,test]: The cryptographic handshake MUST TEXT[!MUST,implementation,test]: provide the following properties: TEXT[!MUST,implementation,test]: Endpoints MUST explicitly negotiate an application protocol. SECTION: [Negotiating Connection IDs](#section-7.2) TEXT[!MUST,implementation,test]: This Destination Connection ID MUST be at least 8 bytes in TEXT[!MUST,implementation,test]: length. TEXT[!MUST,implementation,test]: Until a packet is received from the server, the client MUST TEXT[!MUST,implementation,test]: use the same Destination Connection ID value on all packets in this TEXT[!MUST,implementation,test]: connection. TEXT[implementation]: The Destination Connection ID field from the first Initial packet TEXT[implementation]: sent by a client is used to determine packet protection keys for TEXT[implementation]: Initial packets. TEXT[!MUST,implementation,test]: Once a TEXT[!MUST,implementation,test]: client has received a valid Initial packet from the server, it MUST TEXT[!MUST,implementation,test]: discard any subsequent packet it receives on that connection with a TEXT[!MUST,implementation,test]: different Source Connection ID. TEXT[!MUST,implementation,test]: A client MUST change the Destination Connection ID it uses for TEXT[!MUST,implementation,test]: sending packets in response to only the first received Initial or TEXT[!MUST,implementation,test]: Retry packet. TEXT[!MUST,implementation,test]: A server MUST set the Destination Connection ID it TEXT[!MUST,implementation,test]: uses for sending packets based on the first received Initial packet. TEXT[!MUST,implementation]: Any further changes to the Destination Connection ID are only TEXT[!MUST,implementation]: permitted if the values are taken from NEW_CONNECTION_ID frames; TEXT[!MUST,implementation,test]: if TEXT[!MUST,implementation,test]: subsequent Initial packets include a different Source Connection ID, TEXT[!MUST,implementation,test]: they MUST be discarded. SECTION: [Authenticating Connection IDs](#section-7.3) TEXT[!MUST,implementation,test]: The values provided by a peer for these transport parameters MUST TEXT[!MUST,implementation,test]: match the values that an endpoint used in the Destination and Source TEXT[!MUST,implementation,test]: Connection ID fields of Initial packets that it sent (and received, TEXT[!MUST,implementation,test]: for servers). TEXT[!MUST,implementation,test]: Endpoints MUST validate that received transport TEXT[!MUST,implementation,test]: parameters match received connection ID values. TEXT[!MUST,implementation,test]: An endpoint MUST treat the absence of the TEXT[!MUST,implementation,test]: initial_source_connection_id transport parameter from either endpoint TEXT[!MUST,implementation,test]: or the absence of the original_destination_connection_id transport TEXT[!MUST,implementation,test]: parameter from the server as a connection error of type TEXT[!MUST,implementation,test]: TRANSPORT_PARAMETER_ERROR. TEXT[!MUST,implementation,test]: An endpoint MUST treat the following as a connection error of type TEXT[!MUST,implementation,test]: TRANSPORT_PARAMETER_ERROR or PROTOCOL_VIOLATION: SECTION: [Transport Parameters](#section-7.4) TEXT[!MUST,implementation,test]: An endpoint MUST treat receipt of a transport parameter with an TEXT[!MUST,implementation,test]: invalid value as a connection error of type TEXT[!MUST,implementation,test]: TRANSPORT_PARAMETER_ERROR. TEXT[!MUST,implementation,test]: An endpoint MUST NOT send a parameter more than once in a given TEXT[!MUST,implementation,test]: transport parameters extension. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD treat receipt of TEXT[!SHOULD,implementation,test]: duplicate transport parameters as a connection error of type TEXT[!SHOULD,implementation,test]: TRANSPORT_PARAMETER_ERROR. SECTION: [Values of Transport Parameters for 0-RTT](#section-7.4.1) TEXT[!MUST,exception]: The definition of a new transport parameter (Section 7.4.2) MUST TEXT[!MUST,exception]: specify whether storing the transport parameter for 0-RTT is TEXT[!MUST,exception]: mandatory, optional, or prohibited. TEXT[!MUST,implementation,test]: A client MUST NOT use remembered values for the following parameters: TEXT[!MUST,implementation,test]: ack_delay_exponent, max_ack_delay, initial_source_connection_id, TEXT[!MUST,implementation,test]: original_destination_connection_id, preferred_address, TEXT[!MUST,implementation,test]: retry_source_connection_id, and stateless_reset_token. TEXT[!MUST,implementation,test]: The client TEXT[!MUST,implementation,test]: MUST use the server's new values in the handshake instead; if the TEXT[!MUST,implementation,test]: server does not provide new values, the default values are used. TEXT[!MUST,implementation,test]: A client that attempts to send 0-RTT data MUST remember all other TEXT[!MUST,implementation,test]: transport parameters used by the server that it is able to process. TEXT[!MUST,implementation,test]: If 0-RTT data is accepted by the server, the server MUST NOT reduce TEXT[!MUST,implementation,test]: any limits or alter any values that might be violated by the client TEXT[!MUST,implementation,test]: with its 0-RTT data. TEXT[!MUST,implementation,test]: In particular, a server that accepts 0-RTT data TEXT[!MUST,implementation,test]: MUST NOT set values for the following parameters (Section 18.2) that TEXT[!MUST,implementation,test]: are smaller than the remembered values of the parameters. TEXT[!SHOULD,implementation,test]: The applicable TEXT[!SHOULD,implementation,test]: subset of transport parameters that permit the sending of application TEXT[!SHOULD,implementation,test]: data SHOULD be set to non-zero values for 0-RTT. TEXT[!MAY,implementation]: A server MAY store and recover the previously sent values of the TEXT[!MAY,implementation]: max_idle_timeout, max_udp_payload_size, and disable_active_migration TEXT[!MAY,implementation]: parameters and reject 0-RTT if it selects smaller values. TEXT[!MUST,implementation,test]: A server MUST reject 0-RTT data if the restored values for transport TEXT[!MUST,implementation,test]: parameters cannot be supported. TEXT[!MUST,implementation,test]: When sending frames in 0-RTT packets, a client MUST only use TEXT[!MUST,implementation,test]: remembered transport parameters; importantly, it MUST NOT use updated TEXT[!MUST,implementation,test]: values that it learns from the server's updated transport parameters TEXT[!MUST,implementation,test]: or from frames received in 1-RTT packets. TEXT[!MAY]: server MAY treat the use of updated transport parameters in 0-RTT as TEXT[!MAY]: a connection error of type PROTOCOL_VIOLATION. SECTION: [New Transport Parameters](#section-7.4.2) TEXT[!MUST,implementation,test]: An endpoint MUST ignore transport parameters that it does TEXT[!MUST,implementation,test]: not support. SECTION: [Cryptographic Message Buffering](#section-7.5) TEXT[!MUST,implementation,test]: Implementations MUST support buffering at least 4096 bytes of data TEXT[!MUST,implementation,test]: received in out-of-order CRYPTO frames. TEXT[!MAY]: Endpoints MAY choose to TEXT[!MAY]: allow more data to be buffered during the handshake. TEXT[!MUST,implementation,test]: If an endpoint does not expand its buffer, it MUST close TEXT[!MUST,implementation,test]: the connection with a CRYPTO_BUFFER_EXCEEDED error code. TEXT[!MAY,implementation]: Once the handshake completes, if an endpoint is unable to buffer all TEXT[!MAY,implementation]: data in a CRYPTO frame, it MAY discard that CRYPTO frame and all TEXT[!MAY,implementation]: CRYPTO frames received in the future, or it MAY close the connection TEXT[!MAY,implementation]: with a CRYPTO_BUFFER_EXCEEDED error code. TEXT[!MUST,implementation,test]: Packets containing TEXT[!MUST,implementation,test]: discarded CRYPTO frames MUST be acknowledged because the packet has TEXT[!MUST,implementation,test]: been received and processed by the transport even though the CRYPTO TEXT[!MUST,implementation,test]: frame was discarded. SECTION: [Address Validation](#section-8) TEXT[!MUST,implementation,test]: Therefore, after receiving packets from an address that is TEXT[!MUST,implementation,test]: not yet validated, an endpoint MUST limit the amount of data it sends TEXT[!MUST,implementation,test]: to the unvalidated address to three times the amount of data received TEXT[!MUST,implementation,test]: from that address. SECTION: [Address Validation during Connection Establishment](#section-8.1) TEXT[!MAY]: Additionally, an endpoint MAY consider the peer address validated if TEXT[!MAY]: the peer uses a connection ID chosen by the endpoint and the TEXT[!MAY]: connection ID contains at least 64 bits of entropy. TEXT[!MUST,implementation,test]: Prior to validating the client address, servers MUST NOT send more TEXT[!MUST,implementation,test]: than three times as many bytes as the number of bytes they have TEXT[!MUST,implementation,test]: received. TEXT[!MUST,implementation,test]: For the purposes of TEXT[!MUST,implementation,test]: avoiding amplification prior to address validation, servers MUST TEXT[!MUST,implementation,test]: count all of the payload bytes received in datagrams that are TEXT[!MUST,implementation,test]: uniquely attributed to a single connection. TEXT[!MUST,implementation,test]: Clients MUST ensure that UDP datagrams containing Initial packets TEXT[!MUST,implementation,test]: have UDP payloads of at least 1200 bytes, adding PADDING frames as TEXT[!MUST,implementation,test]: necessary. TEXT[!MUST,implementation,test]: To TEXT[!MUST,implementation,test]: prevent this deadlock, clients MUST send a packet on a Probe Timeout TEXT[!MUST,implementation,test]: (PTO); see Section 6.2 of [QUIC-RECOVERY]. TEXT[!MUST,implementation,test]: Specifically, the client TEXT[!MUST,implementation,test]: MUST send an Initial packet in a UDP datagram that contains at least TEXT[!MUST,implementation,test]: 1200 bytes if it does not have Handshake keys, and otherwise send a TEXT[!MUST,implementation,test]: Handshake packet. SECTION: [Token Construction](#section-8.1.1) TEXT[!MUST,implementation,test]: A token sent in a NEW_TOKEN frame or a Retry packet MUST be TEXT[!MUST,implementation,test]: constructed in a way that allows the server to identify how it was TEXT[!MUST,implementation,test]: provided to a client. SECTION: [Address Validation Using Retry Packets](#section-8.1.2) TEXT[!MUST,implementation,test]: This token MUST be repeated by the client in all TEXT[!MUST,implementation,test]: Initial packets it sends for that connection after it receives the TEXT[!MUST,implementation,test]: Retry packet. TEXT[!SHOULD,implementation]: Instead, the TEXT[!SHOULD,implementation]: server SHOULD immediately close (Section 10.2) the connection with an TEXT[!SHOULD,implementation]: INVALID_TOKEN error. SECTION: [Address Validation for Future Connections](#section-8.1.3) TEXT[!MAY,implementation]: A server MAY provide clients with an address validation token during TEXT[!MAY,implementation]: one connection that can be used on a subsequent connection. TEXT[!MUST,implementation,test]: The client TEXT[!MUST,implementation,test]: MUST include the token in all Initial packets it sends, unless a TEXT[!MUST,implementation,test]: Retry replaces the token with a newer one. TEXT[!MUST,implementation,test]: The client MUST NOT use TEXT[!MUST,implementation,test]: the token provided in a Retry for future connections. TEXT[!MAY]: Servers MAY TEXT[!MAY]: discard any Initial packet that does not carry the expected token. TEXT[!SHOULD,implementation,test]: Thus, a token SHOULD have an TEXT[!SHOULD,implementation,test]: expiration time, which could be either an explicit expiration time or TEXT[!SHOULD,implementation,test]: an issued timestamp that can be used to dynamically calculate the TEXT[!SHOULD,implementation,test]: expiration time. TEXT[!MUST,implementation,test]: A token issued with NEW_TOKEN MUST NOT include information that would TEXT[!MUST,implementation,test]: allow values to be linked by an observer to the connection on which TEXT[!MUST,implementation,test]: it was issued. TEXT[!MUST,implementation,test]: A server MUST ensure that every NEW_TOKEN frame it sends TEXT[!MUST,implementation,test]: is unique across all clients, with the exception of those sent to TEXT[!MUST,implementation,test]: repair losses of previously sent NEW_TOKEN frames. TEXT[!MAY,implementation]: Information that TEXT[!MAY,implementation]: allows the server to distinguish between tokens from Retry and TEXT[!MAY,implementation]: NEW_TOKEN MAY be accessible to entities other than the server. TEXT[!SHOULD,implementation,test]: When connecting to a server for TEXT[!SHOULD,implementation,test]: which the client retains an applicable and unused token, it SHOULD TEXT[!SHOULD,implementation,test]: include that token in the Token field of its Initial packet. TEXT[!MUST,implementation,test]: A client MUST NOT include TEXT[!MUST,implementation,test]: a token that is not applicable to the server that it is connecting TEXT[!MUST,implementation,test]: to, unless the client has the knowledge that the server that issued TEXT[!MUST,implementation,test]: the token and the server the client is connecting to are jointly TEXT[!MUST,implementation,test]: managing the tokens. TEXT[!MAY,implementation,test]: A client MAY use a token from any previous TEXT[!MAY,implementation,test]: connection to that server. TEXT[!MUST,implementation,test]: In comparison, a TEXT[!MUST,implementation,test]: token obtained in a Retry packet MUST be used immediately during the TEXT[!MUST,implementation,test]: connection attempt and cannot be used in subsequent connection TEXT[!MUST,implementation,test]: attempts. TEXT[!SHOULD,implementation,test]: A client SHOULD NOT reuse a token from a NEW_TOKEN frame for TEXT[!SHOULD,implementation,test]: different connection attempts. TEXT[!MUST,implementation,test]: When a server receives an Initial packet with an address validation TEXT[!MUST,implementation,test]: token, it MUST attempt to validate the token, unless it has already TEXT[!MUST,implementation,test]: completed address validation. TEXT[!SHOULD,implementation]: If the token is invalid, then the TEXT[!SHOULD,implementation]: server SHOULD proceed as if the client did not have a validated TEXT[!SHOULD,implementation]: address, including potentially sending a Retry packet. TEXT[!SHOULD,implementation,test]: If the validation succeeds, the server SHOULD then allow TEXT[!SHOULD,implementation,test]: the handshake to proceed. TEXT[!MAY,implementation]: Clients MAY use tokens obtained on one connection for any connection TEXT[!MAY,implementation]: attempt using the same version. SECTION: [Address Validation Token Integrity](#section-8.1.4) TEXT[!MUST,implementation,test]: An address validation token MUST be difficult to guess. TEXT[!MUST,implementation,test]: For this design to work, TEXT[!MUST,implementation,test]: the token MUST be covered by integrity protection against TEXT[!MUST,implementation,test]: modification or falsification by clients. TEXT[!SHOULD,implementation,test]: Tokens TEXT[!SHOULD,implementation,test]: sent in Retry packets SHOULD include information that allows the TEXT[!SHOULD,implementation,test]: server to verify that the source IP address and port in client TEXT[!SHOULD,implementation,test]: packets remain constant. TEXT[!MUST,implementation,test]: Tokens sent in NEW_TOKEN frames MUST include information that allows TEXT[!MUST,implementation,test]: the server to verify that the client IP address has not changed from TEXT[!MUST,implementation,test]: when the token was issued. TEXT[!MUST,implementation,test]: If the client IP address has changed, the TEXT[!MUST,implementation,test]: server MUST adhere to the anti-amplification limit; see Section 8. TEXT[!MUST,implementation,test]: To protect against such attacks, servers MUST ensure that TEXT[!MUST,implementation,test]: replay of tokens is prevented or limited. TEXT[!SHOULD,implementation,test]: Servers SHOULD ensure that TEXT[!SHOULD,implementation,test]: tokens sent in Retry packets are only accepted for a short time, as TEXT[!SHOULD,implementation,test]: they are returned immediately by clients. TEXT[!SHOULD,implementation,test]: Tokens that are provided TEXT[!SHOULD,implementation,test]: in NEW_TOKEN frames (Section 19.7) need to be valid for longer but TEXT[!SHOULD,implementation,test]: SHOULD NOT be accepted multiple times. TEXT[!MAY,implementation]: Servers are encouraged to TEXT[!MAY,implementation]: allow tokens to be used only once, if possible; tokens MAY include TEXT[!MAY,implementation]: additional information about clients to further narrow applicability TEXT[!MAY,implementation]: or reuse. SECTION: [Path Validation](#section-8.2) TEXT[!MAY,test]: An endpoint MAY include other frames with the PATH_CHALLENGE and TEXT[!MAY,test]: PATH_RESPONSE frames used for path validation. SECTION: [Initiating Path Validation](#section-8.2.1) TEXT[!MAY,implementation]: An endpoint MAY send multiple PATH_CHALLENGE frames to guard against TEXT[!MAY,implementation]: packet loss. TEXT[!SHOULD,implementation,test]: However, an endpoint SHOULD NOT send multiple TEXT[!SHOULD,implementation,test]: PATH_CHALLENGE frames in a single packet. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD NOT probe a new path with packets containing a TEXT[!SHOULD,implementation,test]: PATH_CHALLENGE frame more frequently than it would send an Initial TEXT[!SHOULD,implementation,test]: packet. TEXT[!MUST,implementation,test]: The endpoint MUST use unpredictable data in every PATH_CHALLENGE TEXT[!MUST,implementation,test]: frame so that it can associate the peer's response with the TEXT[!MUST,implementation,test]: corresponding PATH_CHALLENGE. TEXT[!MUST,implementation,test]: An endpoint MUST expand datagrams that contain a PATH_CHALLENGE frame TEXT[!MUST,implementation,test]: to at least the smallest allowed maximum datagram size of 1200 bytes, TEXT[!MUST,implementation,test]: unless the anti-amplification limit for the path does not permit TEXT[!MUST,implementation,test]: sending a datagram of this size. TEXT[!MUST,implementation,test]: To ensure that the path MTU is large enough, the endpoint TEXT[!MUST,implementation,test]: MUST perform a second path validation by sending a PATH_CHALLENGE TEXT[!MUST,implementation,test]: frame in a datagram of at least 1200 bytes. TEXT[!MUST,implementation,test]: Unlike other cases where datagrams are expanded, endpoints MUST NOT TEXT[!MUST,implementation,test]: discard datagrams that appear to be too small when they contain TEXT[!MUST,implementation,test]: PATH_CHALLENGE or PATH_RESPONSE. SECTION: [Path Validation Responses](#section-8.2.2) TEXT[!MUST,implementation,test]: On receiving a PATH_CHALLENGE frame, an endpoint MUST respond by TEXT[!MUST,implementation,test]: echoing the data contained in the PATH_CHALLENGE frame in a TEXT[!MUST,implementation,test]: PATH_RESPONSE frame. TEXT[!MUST,implementation,test]: An endpoint MUST NOT delay transmission of a TEXT[!MUST,implementation,test]: packet containing a PATH_RESPONSE frame unless constrained by TEXT[!MUST,implementation,test]: congestion control. TEXT[!MUST,implementation,test]: A PATH_RESPONSE frame MUST be sent on the network path where the TEXT[!MUST,implementation,test]: PATH_CHALLENGE frame was received. TEXT[!MUST,implementation,test]: This requirement MUST NOT be enforced by the endpoint that initiates TEXT[!MUST,implementation,test]: path validation, as that would enable an attack on migration; see TEXT[!MUST,implementation,test]: Section 9.3.3. TEXT[!MUST,implementation,test]: An endpoint MUST expand datagrams that contain a PATH_RESPONSE frame TEXT[!MUST,implementation,test]: to at least the smallest allowed maximum datagram size of 1200 bytes. TEXT[!MUST,implementation,test]: However, an endpoint MUST NOT expand the TEXT[!MUST,implementation,test]: datagram containing the PATH_RESPONSE if the resulting data exceeds TEXT[!MUST,implementation,test]: the anti-amplification limit. TEXT[!MUST,implementation,test]: An endpoint MUST NOT send more than one PATH_RESPONSE frame in TEXT[!MUST,implementation,test]: response to one PATH_CHALLENGE frame; see Section 13.3. SECTION: [Successful Path Validation](#section-8.2.3) TEXT[!MUST,implementation,test]: However, the endpoint MUST initiate TEXT[!MUST,implementation,test]: another path validation with an expanded datagram to verify that the TEXT[!MUST,implementation,test]: path supports the required MTU. SECTION: [Failed Path Validation](#section-8.2.4) TEXT[!SHOULD,implementation,test]: Endpoints SHOULD abandon path validation based on a timer. TEXT[!SHOULD,implementation,test]: A value of TEXT[!SHOULD,implementation,test]: three times the larger of the current PTO or the PTO for the new path TEXT[!SHOULD,implementation,test]: (using kInitialRtt, as defined in [QUIC-RECOVERY]) is RECOMMENDED. TEXT[!MAY,implementation]: An endpoint TEXT[!MAY,implementation]: that has no valid network path to its peer MAY signal this using the TEXT[!MAY,implementation]: NO_VIABLE_PATH connection error, noting that this is only possible if TEXT[!MAY,implementation]: the network path exists but does not support the required MTU TEXT[!MAY,implementation]: (Section 14). SECTION: [Connection Migration](#section-9) TEXT[!MUST,implementation,test]: An endpoint MUST NOT initiate TEXT[!MUST,implementation,test]: connection migration before the handshake is confirmed, as defined in TEXT[!MUST,implementation,test]: Section 4.1.2 of [QUIC-TLS]. TEXT[!MUST,implementation,test]: If the peer sent the disable_active_migration transport parameter, an TEXT[!MUST,implementation,test]: endpoint also MUST NOT send packets (including probing packets; see TEXT[!MUST,implementation,test]: Section 9.1) from a different local address to the address the peer TEXT[!MUST,implementation,test]: used during the handshake, unless the endpoint has acted on a TEXT[!MUST,implementation,test]: preferred_address transport parameter from the peer. TEXT[!MUST,implementation,test]: If the peer TEXT[!MUST,implementation,test]: violates this requirement, the endpoint MUST either drop the incoming TEXT[!MUST,implementation,test]: packets on that path without generating a Stateless Reset or proceed TEXT[!MUST,implementation,test]: with path validation and allow the peer to migrate. TEXT[!MUST,implementation,test]: An endpoint MUST TEXT[!MUST,implementation,test]: perform path validation (Section 8.2) if it detects any change to a TEXT[!MUST,implementation,test]: peer's address, unless it has previously validated that address. TEXT[!MAY,implementation]: When an endpoint has no validated path on which to send packets, it TEXT[!MAY,implementation]: MAY discard connection state. TEXT[!MAY]: An endpoint capable of connection TEXT[!MAY]: migration MAY wait for a new path to become available before TEXT[!MAY]: discarding connection state. TEXT[!MUST,implementation]: If a client receives TEXT[!MUST,implementation]: packets from an unknown server address, the client MUST discard these TEXT[!MUST,implementation]: packets. SECTION: [Probing a New Path](#section-9.1) TEXT[!MAY,implementation]: An endpoint MAY probe for peer reachability from a new local address TEXT[!MAY,implementation]: using path validation (Section 8.2) prior to migrating the connection TEXT[!MAY,implementation]: to the new local address. TEXT[test]: PATH_CHALLENGE, PATH_RESPONSE, NEW_CONNECTION_ID, and PADDING frames TEXT[test]: are "probing frames", and all other frames are "non-probing frames". SECTION: [Initiating Connection Migration](#section-9.2) TEXT[!MAY]: An endpoint MAY defer path TEXT[!MAY]: validation until after a peer sends the next non-probing frame to its TEXT[!MAY]: new address. SECTION: [Responding to Connection Migration](#section-9.3) TEXT[!MUST,implementation,test]: If the recipient permits the migration, it MUST send subsequent TEXT[!MUST,implementation,test]: packets to the new peer address TEXT[!MUST,implementation,test]: and MUST initiate path validation TEXT[!MUST,implementation,test]: (Section 8.2) to verify the peer's ownership of the address if TEXT[!MUST,implementation,test]: validation is not already underway. TEXT[implementation]: An endpoint only changes the address to which it sends packets in TEXT[implementation]: response to the highest-numbered non-probing packet. TEXT[!MUST,implementation,test]: An endpoint MAY send data to an unvalidated peer address, but it MUST TEXT[!MUST,implementation,test]: protect against potential attacks as described in Sections 9.3.1 and TEXT[!MUST,implementation,test]: 9.3.2. TEXT[!MAY]: An endpoint MAY skip validation of a peer address if that TEXT[!MAY]: address has been seen recently. TEXT[!SHOULD,implementation,test]: After verifying a new client address, the server SHOULD send new TEXT[!SHOULD,implementation,test]: address validation tokens (Section 8) to the client. SECTION: [On-Path Address Spoofing](#section-9.3.2) TEXT[!MUST,implementation,test]: To protect the connection from failing due to such a spurious TEXT[!MUST,implementation,test]: migration, an endpoint MUST revert to using the last validated peer TEXT[!MUST,implementation,test]: address when validation of a new peer address fails. TEXT[!MUST,implementation,test]: If an endpoint has no state about the last validated peer address, it TEXT[!MUST,implementation,test]: MUST close the connection silently by discarding all connection TEXT[!MUST,implementation,test]: state. TEXT[!MAY,implementation]: For instance, an endpoint MAY send a Stateless Reset in TEXT[!MAY,implementation]: response to any further incoming packets. SECTION: [Off-Path Packet Forwarding](#section-9.3.3) TEXT[!MUST,implementation,test]: In response to an apparent migration, endpoints MUST validate the TEXT[!MUST,implementation,test]: previously active path using a PATH_CHALLENGE frame. TEXT[!SHOULD,implementation,test]: An endpoint that receives a PATH_CHALLENGE on an active path SHOULD TEXT[!SHOULD,implementation,test]: send a non-probing packet in response. SECTION: [Loss Detection and Congestion Control](#section-9.4) TEXT[!MUST,implementation,test]: Packets sent on the old path MUST NOT contribute to TEXT[!MUST,implementation,test]: congestion control or RTT estimation for the new path. TEXT[!MUST,implementation,test]: On confirming a peer's ownership of its new address, an endpoint MUST TEXT[!MUST,implementation,test]: immediately reset the congestion controller and round-trip time TEXT[!MUST,implementation,test]: estimator for the new path to initial values (see Appendices A.3 and TEXT[!MUST,implementation,test]: B.3 of [QUIC-RECOVERY]) unless the only change in the peer's address TEXT[!MUST,implementation,test]: is its port number. TEXT[!MAY]: Because port-only changes are commonly the TEXT[!MAY]: result of NAT rebinding or other middlebox activity, the endpoint MAY TEXT[!MAY]: instead retain its congestion control state and round-trip estimate TEXT[!MAY]: in those cases instead of reverting to initial values. TEXT[!MUST,implementation,test]: This timer SHOULD be set as described in Section 6.2.1 of TEXT[!MUST,implementation,test]: [QUIC-RECOVERY] and MUST NOT be more aggressive. SECTION: [Privacy Implications of Connection Migration](#section-9.5) TEXT[!MAY,implementation]: At any time, endpoints MAY change the Destination Connection ID they TEXT[!MAY,implementation]: transmit with to a value that has not been used on another path. TEXT[!MUST,implementation,test]: An endpoint MUST NOT reuse a connection ID when sending from more TEXT[!MUST,implementation,test]: than one local address -- for example, when initiating connection TEXT[!MUST,implementation,test]: migration as described in Section 9.2 or when probing a new network TEXT[!MUST,implementation,test]: path as described in Section 9.1. TEXT[!MUST,implementation,test]: Similarly, an endpoint MUST NOT reuse a connection ID when sending to TEXT[!MUST,implementation,test]: more than one destination address. TEXT[!MAY,implementation]: Due to network changes outside TEXT[!MAY,implementation]: the control of its peer, an endpoint might receive packets from a new TEXT[!MAY,implementation]: source address with the same Destination Connection ID field value, TEXT[!MAY,implementation]: in which case it MAY continue to use the current connection ID with TEXT[!MAY,implementation]: the new remote address while still sending from the same local TEXT[!MAY,implementation]: address. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD NOT initiate migration with a peer that has TEXT[!SHOULD,implementation,test]: requested a zero-length connection ID, because traffic over the new TEXT[!SHOULD,implementation,test]: path might be trivially linkable to traffic over the old one. TEXT[!SHOULD,implementation]: Changing address TEXT[!SHOULD,implementation]: can cause a peer to reset its congestion control state (see TEXT[!SHOULD,implementation]: Section 9.4), so addresses SHOULD only be changed infrequently. TEXT[!SHOULD,implementation,test]: To ensure that migration is possible and TEXT[!SHOULD,implementation,test]: packets sent on different paths cannot be correlated, endpoints TEXT[!SHOULD,implementation,test]: SHOULD provide new connection IDs before peers migrate; see TEXT[!SHOULD,implementation,test]: Section 5.1.1. SECTION: [Server's Preferred Address](#section-9.6) TEXT[!SHOULD,implementation]: If a TEXT[!SHOULD,implementation]: client receives packets from a new server address when the client has TEXT[!SHOULD,implementation]: not initiated a migration to that address, the client SHOULD discard TEXT[!SHOULD,implementation]: these packets. SECTION: [Communicating a Preferred Address](#section-9.6.1) TEXT[!MAY,implementation]: Servers MAY communicate a preferred address of each address family TEXT[!MAY,implementation]: (IPv4 and IPv6) to allow clients to pick the one most suited to their TEXT[!MAY,implementation]: network attachment. TEXT[!SHOULD,implementation,test]: Once the handshake is confirmed, the client SHOULD select one of the TEXT[!SHOULD,implementation,test]: two addresses provided by the server and initiate path validation TEXT[!SHOULD,implementation,test]: (see Section 8.2). TEXT[!SHOULD,implementation,test]: As soon as path validation succeeds, the client SHOULD begin sending TEXT[!SHOULD,implementation,test]: all future packets to the new server address using the new connection TEXT[!SHOULD,implementation,test]: ID and discontinue use of the old server address. TEXT[!MUST,implementation,test]: If path validation TEXT[!MUST,implementation,test]: fails, the client MUST continue sending all future packets to the TEXT[!MUST,implementation,test]: server's original IP address. SECTION: [Migration to a Preferred Address](#section-9.6.2) TEXT[!MUST,implementation,test]: A client that migrates to a preferred address MUST validate the TEXT[!MUST,implementation,test]: address it chooses before migrating; see Section 21.5.3. TEXT[!MUST,implementation]: The server MUST send non- TEXT[!MUST,implementation]: probing packets from its original address until it receives a non- TEXT[!MUST,implementation]: probing packet from the client at its preferred address and until the TEXT[!MUST,implementation]: server has validated the new path. TEXT[!MUST,implementation,test]: The server MUST probe on the path toward the client from its TEXT[!MUST,implementation,test]: preferred address. TEXT[!SHOULD,implementation,test]: The server SHOULD drop TEXT[!SHOULD,implementation,test]: newer packets for this connection that are received on the old IP TEXT[!SHOULD,implementation,test]: address. TEXT[!MAY]: The server MAY continue to process delayed packets that are TEXT[!MAY]: received on the old IP address. TEXT[!MUST,implementation]: A client MUST NOT use these for other connections, TEXT[!MUST,implementation]: including connections that are resumed from the current connection. SECTION: [Interaction of Client Migration and Preferred Address](#section-9.6.3) TEXT[!SHOULD,implementation,test]: In this case, the client TEXT[!SHOULD,implementation,test]: SHOULD perform path validation to both the original and preferred TEXT[!SHOULD,implementation,test]: server address from the client's new address concurrently. TEXT[!MUST,implementation,test]: If path validation of the server's preferred address succeeds, the TEXT[!MUST,implementation,test]: client MUST abandon validation of the original address and migrate to TEXT[!MUST,implementation,test]: using the server's preferred address. TEXT[!MAY,test]: If path validation of the TEXT[!MAY,test]: server's preferred address fails but validation of the server's TEXT[!MAY,test]: original address succeeds, the client MAY migrate to its new address TEXT[!MAY,test]: and continue sending to the server's original address. TEXT[!MUST]: If packets received at the server's preferred address have a TEXT[!MUST]: different source address than observed from the client during the TEXT[!MUST]: handshake, the server MUST protect against potential attacks as TEXT[!MUST]: described in Sections 9.3.1 and 9.3.2. TEXT[!SHOULD,implementation,test]: Servers SHOULD initiate path validation to the client's new address TEXT[!SHOULD,implementation,test]: upon receiving a probe packet from a different address; see TEXT[!SHOULD,implementation,test]: Section 8. TEXT[!SHOULD,implementation,test]: A client that migrates to a new address SHOULD use a preferred TEXT[!SHOULD,implementation,test]: address from the same address family for the server. TEXT[!MAY,implementation]: This TEXT[!MAY,implementation]: connection ID is provided to ensure that the client has a connection TEXT[!MAY,implementation]: ID available for migration, but the client MAY use this connection ID TEXT[!MAY,implementation]: on any path. SECTION: [Use of IPv6 Flow Label and Migration](#section-9.7) TEXT[!SHOULD,implementation,test]: Endpoints that send data using IPv6 SHOULD apply an IPv6 flow label TEXT[!SHOULD,implementation,test]: in compliance with [RFC6437], unless the local API does not allow TEXT[!SHOULD,implementation,test]: setting IPv6 flow labels. TEXT[!MUST,implementation]: The flow label generation MUST be designed to minimize the chances of TEXT[!MUST,implementation]: linkability with a previously used flow label, as a stable flow label TEXT[!MUST,implementation]: would enable correlating activity on multiple paths; see Section 9.5. SECTION: [Connection Termination](#section-10) TEXT[!MAY,implementation]: An endpoint MAY discard connection state if it does not have a TEXT[!MAY,implementation]: validated path on which it can send packets; see Section 8.2. SECTION: [Idle Timeout](#section-10.1) TEXT[implementation,test]: If a max_idle_timeout is specified by either endpoint in its TEXT[implementation,test]: transport parameters (Section 18.2), the connection is silently TEXT[implementation,test]: closed and its state is discarded when it remains idle for longer TEXT[implementation,test]: than the minimum of the max_idle_timeout value advertised by both TEXT[implementation,test]: endpoints. TEXT[implementation,test]: An endpoint restarts its idle timer when a packet from its peer is TEXT[implementation,test]: received and processed successfully. TEXT[implementation,test]: An endpoint also restarts its TEXT[implementation,test]: idle timer when sending an ack-eliciting packet if no other ack- TEXT[implementation,test]: eliciting packets have been sent since last receiving and processing TEXT[implementation,test]: a packet. TEXT[!MUST,implementation,test]: To avoid excessively small idle timeout periods, endpoints MUST TEXT[!MUST,implementation,test]: increase the idle timeout period to be at least three times the TEXT[!MUST,implementation,test]: current Probe Timeout (PTO). SECTION: [Deferring Idle Timeout](#section-10.1.2) TEXT[!SHOULD,exception]: Application protocols that use QUIC SHOULD provide guidance on when TEXT[!SHOULD,exception]: deferring an idle timeout is appropriate. SECTION: [Immediate Close](#section-10.2) TEXT[implementation]: The closing and draining connection states exist to ensure that TEXT[implementation]: connections close cleanly and that delayed or reordered packets are TEXT[implementation]: properly discarded. TEXT[!SHOULD,implementation,test]: These states SHOULD persist for at least three TEXT[!SHOULD,implementation,test]: times the current PTO interval as defined in [QUIC-RECOVERY]. TEXT[!MAY]: Endpoints that have some alternative means to ensure that late- TEXT[!MAY]: arriving packets do not induce a response, such as those that are TEXT[!MAY]: able to close the UDP socket, MAY end these states earlier to allow TEXT[!MAY]: for faster resource recovery. TEXT[!SHOULD,implementation,test]: Servers that retain an open socket for TEXT[!SHOULD,implementation,test]: accepting new connections SHOULD NOT end the closing or draining TEXT[!SHOULD,implementation,test]: state early. TEXT[!SHOULD,implementation,test]: Once its closing or draining state ends, an endpoint SHOULD discard TEXT[!SHOULD,implementation,test]: all connection state. TEXT[!MAY,implementation]: The endpoint MAY send a Stateless Reset in TEXT[!MAY,implementation]: response to any further incoming packets belonging to this TEXT[!MAY,implementation]: connection. SECTION: [Closing Connection State](#section-10.2.1) TEXT[!SHOULD,implementation,test]: An endpoint SHOULD limit the rate at which it generates packets in TEXT[!SHOULD,implementation,test]: the closing state. TEXT[!MAY]: An endpoint's selected connection ID and the QUIC version are TEXT[!MAY]: sufficient information to identify packets for a closing connection; TEXT[!MAY]: the endpoint MAY discard all other connection state. TEXT[!MAY]: An TEXT[!MAY]: endpoint MAY retain packet protection keys for incoming packets to TEXT[!MAY]: allow it to read and process a CONNECTION_CLOSE frame. TEXT[!MAY]: An endpoint MAY drop packet protection keys when entering the closing TEXT[!MAY]: state and send a packet containing a CONNECTION_CLOSE frame in TEXT[!MAY]: response to any UDP datagram that is received. TEXT[!MUST,implementation,test]: To avoid being used for an amplification attack, TEXT[!MUST,implementation,test]: such endpoints MUST limit the cumulative size of packets it sends to TEXT[!MUST,implementation,test]: three times the cumulative size of the packets that are received and TEXT[!MUST,implementation,test]: attributed to the connection. TEXT[!MAY]: To minimize the state that an endpoint TEXT[!MAY]: maintains for a closing connection, endpoints MAY send the exact same TEXT[!MAY]: packet in response to any received packet. TEXT[!MUST,implementation,test]: An endpoint in the closing state MUST either discard TEXT[!MUST,implementation,test]: packets received from an unvalidated address or limit the cumulative TEXT[!MUST,implementation,test]: size of packets it sends to an unvalidated address to three times the TEXT[!MUST,implementation,test]: size of packets it receives from that address. SECTION: [Draining Connection State](#section-10.2.2) TEXT[!MUST,implementation,test]: While otherwise identical to the closing state, an TEXT[!MUST,implementation,test]: endpoint in the draining state MUST NOT send any packets. TEXT[!MAY]: An endpoint that receives a CONNECTION_CLOSE frame MAY send a single TEXT[!MAY]: packet containing a CONNECTION_CLOSE frame before entering the TEXT[!MAY]: draining state, using a NO_ERROR code if appropriate. TEXT[!MUST,implementation,test]: An endpoint TEXT[!MUST,implementation,test]: MUST NOT send further packets. TEXT[!MAY]: An endpoint MAY enter the draining state from the closing state if it TEXT[!MAY]: receives a CONNECTION_CLOSE frame, which indicates that the peer is TEXT[!MAY]: also closing or draining. SECTION: [Immediate Close during the Handshake](#section-10.2.3) TEXT[!MUST,implementation,test]: After the handshake is confirmed (see TEXT[!MUST,implementation,test]: Section 4.1.2 of [QUIC-TLS]), an endpoint MUST send any TEXT[!MUST,implementation,test]: CONNECTION_CLOSE frames in a 1-RTT packet. TEXT[!MAY,implementation]: However, prior to TEXT[!MAY,implementation]: confirming the handshake, it is possible that more advanced packet TEXT[!MAY,implementation]: protection keys are not available to the peer, so another TEXT[!MAY,implementation]: CONNECTION_CLOSE frame MAY be sent in a packet that uses a lower TEXT[!MAY,implementation]: packet protection level. TEXT[!SHOULD,implementation,test]: Under these TEXT[!SHOULD,implementation,test]: circumstances, a server SHOULD send a CONNECTION_CLOSE frame in TEXT[!SHOULD,implementation,test]: both Handshake and Initial packets to ensure that at least one of TEXT[!SHOULD,implementation,test]: them is processable by the client. TEXT[!SHOULD,implementation,test]: * Prior to confirming the handshake, a peer might be unable to TEXT[!SHOULD,implementation,test]: process 1-RTT packets, so an endpoint SHOULD send a TEXT[!SHOULD,implementation,test]: CONNECTION_CLOSE frame in both Handshake and 1-RTT packets. TEXT[!SHOULD,implementation,test]: server SHOULD also send a CONNECTION_CLOSE frame in an Initial TEXT[!SHOULD,implementation,test]: packet. TEXT[!MUST,implementation,test]: A CONNECTION_CLOSE of type 0x1d MUST be replaced by a TEXT[!MUST,implementation,test]: CONNECTION_CLOSE of type 0x1c when sending the frame in Initial or TEXT[!MUST,implementation,test]: Handshake packets. TEXT[!MUST,implementation,test]: Endpoints MUST clear the value of the TEXT[!MUST,implementation,test]: Reason Phrase field and SHOULD use the APPLICATION_ERROR code when TEXT[!MUST,implementation,test]: converting to a CONNECTION_CLOSE of type 0x1c. TEXT[!MAY,implementation]: For this TEXT[!MAY,implementation]: reason, endpoints MAY discard packets rather than immediately close TEXT[!MAY,implementation]: if errors are detected in packets that lack authentication. SECTION: [Stateless Reset](#section-10.3) TEXT[!MAY,implementation]: An TEXT[!MAY,implementation]: endpoint MAY send a Stateless Reset in response to receiving a packet TEXT[!MAY,implementation]: that it cannot associate with an active connection. TEXT[!MUST,implementation,test]: An endpoint that wishes to communicate a fatal TEXT[!MUST,implementation,test]: connection error MUST use a CONNECTION_CLOSE frame if it is able. TEXT[!SHOULD,implementation,test]: The remainder of the first byte TEXT[!SHOULD,implementation,test]: and an arbitrary number of bytes following it are set to values that TEXT[!SHOULD,implementation,test]: SHOULD be indistinguishable from random. TEXT[!SHOULD,implementation,test]: To achieve that end, TEXT[!SHOULD,implementation,test]: the endpoint SHOULD ensure that all packets it sends are at least 22 TEXT[!SHOULD,implementation,test]: bytes longer than the minimum connection ID length that it requests TEXT[!SHOULD,implementation,test]: the peer to include in its packets, adding PADDING frames as TEXT[!SHOULD,implementation,test]: necessary. TEXT[!SHOULD,implementation,test]: An TEXT[!SHOULD,implementation,test]: endpoint that sends a Stateless Reset in response to a packet that is TEXT[!SHOULD,implementation,test]: 43 bytes or shorter SHOULD send a Stateless Reset that is one byte TEXT[!SHOULD,implementation,test]: shorter than the packet it responds to. TEXT[!MUST,implementation,test]: An endpoint MUST NOT send a Stateless Reset that is three times or TEXT[!MUST,implementation,test]: more larger than the packet it receives to avoid being used for TEXT[!MUST,implementation,test]: amplification. TEXT[!MUST,implementation,test]: Endpoints MUST discard packets that are too small to be valid QUIC TEXT[!MUST,implementation,test]: packets. TEXT[!MUST,implementation,test]: Endpoints MUST send Stateless Resets formatted as a packet with a TEXT[!MUST,implementation,test]: short header. TEXT[!MUST,implementation,test]: However, endpoints MUST treat any packet ending in a TEXT[!MUST,implementation,test]: valid stateless reset token as a Stateless Reset, as other QUIC TEXT[!MUST,implementation,test]: versions might allow the use of a long header. TEXT[!MAY]: An endpoint MAY send a Stateless Reset in response to a packet with a TEXT[!MAY]: long header. SECTION: [Detecting a Stateless Reset](#section-10.3.1) TEXT[!MAY,implementation]: Endpoints MAY skip this check if any packet from a datagram is TEXT[!MAY,implementation]: successfully processed. TEXT[!MUST,implementation,test]: However, the comparison MUST be performed TEXT[!MUST,implementation,test]: when the first packet in an incoming datagram either cannot be TEXT[!MUST,implementation,test]: associated with a connection or cannot be decrypted. TEXT[!MUST,implementation,test]: An endpoint MUST NOT check for any stateless reset tokens associated TEXT[!MUST,implementation,test]: with connection IDs it has not used or for connection IDs that have TEXT[!MUST,implementation,test]: been retired. TEXT[!MUST,implementation,test]: When comparing a datagram to stateless reset token values, endpoints TEXT[!MUST,implementation,test]: MUST perform the comparison without leaking information about the TEXT[!MUST,implementation,test]: value of the token. TEXT[!MUST,implementation,test]: If the last 16 bytes of the datagram are identical in value to a TEXT[!MUST,implementation,test]: stateless reset token, the endpoint MUST enter the draining period TEXT[!MUST,implementation,test]: and not send any further packets on this connection. SECTION: [Calculating a Stateless Reset Token](#section-10.3.2) TEXT[!MUST,implementation,test]: The stateless reset token MUST be difficult to guess. TEXT[!MUST,implementation,test]: An endpoint that uses this design MUST TEXT[!MUST,implementation,test]: either use the same connection ID length for all connections or TEXT[!MUST,implementation,test]: encode the length of the connection ID such that it can be recovered TEXT[!MUST,implementation,test]: without state. TEXT[!MUST,exception]: This method for TEXT[!MUST,exception]: choosing the stateless reset token means that the combination of TEXT[!MUST,exception]: connection ID and static key MUST NOT be used for another connection. TEXT[!MUST,exception]: A connection ID from a connection TEXT[!MUST,exception]: that is reset by revealing the stateless reset token MUST NOT be TEXT[!MUST,exception]: reused for new connections at nodes that share a static key. TEXT[!MUST,implementation,test]: The same stateless reset token MUST NOT be used for multiple TEXT[!MUST,implementation,test]: connection IDs. TEXT[!MAY,implementation]: Endpoints are not required to compare new values TEXT[!MAY,implementation]: against all previous values, but a duplicate value MAY be treated as TEXT[!MAY,implementation]: a connection error of type PROTOCOL_VIOLATION. SECTION: [Looping](#section-10.3.3) TEXT[!MUST,implementation,test]: An endpoint MUST ensure that every Stateless Reset that it sends is TEXT[!MUST,implementation,test]: smaller than the packet that triggered it, unless it maintains state TEXT[!MUST,implementation,test]: sufficient to prevent looping. SECTION: [Error Handling](#section-11) TEXT[!SHOULD,implementation,test]: An endpoint that detects an error SHOULD signal the existence of that TEXT[!SHOULD,implementation,test]: error to its peer. TEXT[!SHOULD,implementation,test]: The most appropriate error code (Section 20) SHOULD be included in TEXT[!SHOULD,implementation,test]: the frame that signals the error. TEXT[!MAY,implementation]: In particular, an endpoint MAY use any applicable error TEXT[!MAY,implementation]: code when it detects an error condition; a generic error code (such TEXT[!MAY,implementation]: as PROTOCOL_VIOLATION or INTERNAL_ERROR) can always be used in place TEXT[!MAY,implementation]: of specific error codes. TEXT[!MUST,implementation,test]: stateless reset MUST NOT be used by an endpoint that has the state TEXT[!MUST,implementation,test]: necessary to send a frame on the connection. SECTION: [Connection Errors](#section-11.1) TEXT[!MUST,implementation,test]: Errors that result in the connection being unusable, such as an TEXT[!MUST,implementation,test]: obvious violation of protocol semantics or corruption of state that TEXT[!MUST,implementation,test]: affects an entire connection, MUST be signaled using a TEXT[!MUST,implementation,test]: CONNECTION_CLOSE frame (Section 19.19). TEXT[!SHOULD,implementation,test]: An TEXT[!SHOULD,implementation,test]: endpoint SHOULD be prepared to retransmit a packet containing a TEXT[!SHOULD,implementation,test]: CONNECTION_CLOSE frame if it receives more packets on a terminated TEXT[!SHOULD,implementation,test]: connection. TEXT[!MAY,implementation]: As the AEAD for Initial packets does not provide strong TEXT[!MAY,implementation]: authentication, an endpoint MAY discard an invalid Initial packet. SECTION: [Stream Errors](#section-11.2) TEXT[!MUST,implementation,test]: RESET_STREAM MUST only be instigated by the TEXT[!MUST,implementation,test]: application protocol that uses QUIC. TEXT[!SHOULD,exception]: Application protocols SHOULD define rules for handling streams that TEXT[!SHOULD,exception]: are prematurely canceled by either endpoint. SECTION: [Coalescing Packets](#section-12.2) TEXT[!MUST,implementation,test]: Receivers MUST be able to TEXT[!MUST,implementation,test]: process coalesced packets. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD include multiple frames in a single packet if they TEXT[!SHOULD,implementation,test]: are to be sent at the same encryption level, instead of coalescing TEXT[!SHOULD,implementation,test]: multiple packets at the same encryption level. TEXT[!MAY,implementation]: Receivers MAY route based on the information in the first packet TEXT[!MAY,implementation]: contained in a UDP datagram. TEXT[!MUST,implementation,test]: Senders MUST NOT coalesce QUIC packets TEXT[!MUST,implementation,test]: with different connection IDs into a single UDP datagram. TEXT[!SHOULD,implementation,test]: Receivers TEXT[!SHOULD,implementation,test]: SHOULD ignore any subsequent packets with a different Destination TEXT[!SHOULD,implementation,test]: Connection ID than the first packet in the datagram. TEXT[!MUST,implementation,test]: The receiver of coalesced QUIC packets MUST TEXT[!MUST,implementation,test]: individually process each QUIC packet and separately acknowledge TEXT[!MUST,implementation,test]: them, as if they were received as the payload of different UDP TEXT[!MUST,implementation,test]: datagrams. TEXT[!MUST,implementation,test]: For example, if decryption fails (because the keys are TEXT[!MUST,implementation,test]: not available or for any other reason), the receiver MAY either TEXT[!MUST,implementation,test]: discard or buffer the packet for later processing and MUST attempt to TEXT[!MUST,implementation,test]: process the remaining packets. SECTION: [Packet Numbers](#section-12.3) TEXT[!MUST,implementation,test]: Subsequent packets sent in the same packet TEXT[!MUST,implementation,test]: number space MUST increase the packet number by at least one. TEXT[!MUST,implementation,test]: A QUIC endpoint MUST NOT reuse a packet number within the same packet TEXT[!MUST,implementation,test]: number space in one connection. TEXT[!MUST,implementation,test]: If the packet number for sending TEXT[!MUST,implementation,test]: reaches 2^62-1, the sender MUST close the connection without sending TEXT[!MUST,implementation,test]: a CONNECTION_CLOSE frame or any further packets; an endpoint MAY send TEXT[!MUST,implementation,test]: a Stateless Reset (Section 10.3) in response to further packets that TEXT[!MUST,implementation,test]: it receives. TEXT[!MUST,implementation,test]: A receiver MUST discard a newly unprotected packet unless it is TEXT[!MUST,implementation,test]: certain that it has not processed another packet with the same packet TEXT[!MUST,implementation,test]: number from the same packet number space. TEXT[!MUST,implementation,test]: Duplicate suppression MUST TEXT[!MUST,implementation,test]: happen after removing packet protection for the reasons described in TEXT[!MUST,implementation,test]: Section 9.5 of [QUIC-TLS]. SECTION: [Frames and Frame Types](#section-12.4) TEXT[!MUST,implementation,test]: The payload of a packet that contains frames MUST contain at least TEXT[!MUST,implementation,test]: one frame, and MAY contain multiple frames and multiple frame types. TEXT[!MUST,implementation,test]: An endpoint MUST treat receipt of a packet containing no frames as a TEXT[!MUST,implementation,test]: connection error of type PROTOCOL_VIOLATION. TEXT[!MUST,implementation,test]: An endpoint MUST treat TEXT[!MUST,implementation,test]: receipt of a frame in a packet type that is not permitted as a TEXT[!MUST,implementation,test]: connection error of type PROTOCOL_VIOLATION. TEXT[!MUST,implementation,test]: An endpoint MUST treat the receipt of a frame of unknown type as a TEXT[!MUST,implementation,test]: connection error of type FRAME_ENCODING_ERROR. TEXT[!MUST,implementation,test]: To ensure simple and efficient TEXT[!MUST,implementation,test]: implementations of frame parsing, a frame type MUST use the shortest TEXT[!MUST,implementation,test]: possible encoding. TEXT[!MAY]: An endpoint MAY treat the TEXT[!MAY]: receipt of a frame type that uses a longer encoding than necessary as TEXT[!MAY]: a connection error of type PROTOCOL_VIOLATION. SECTION: [Frames and Number Spaces](#section-12.5) TEXT[!MAY,implementation]: * PADDING, PING, and CRYPTO frames MAY appear in any packet number TEXT[!MAY,implementation]: space. TEXT[!MAY,implementation]: * CONNECTION_CLOSE frames signaling errors at the QUIC layer (type TEXT[!MAY,implementation]: 0x1c) MAY appear in any packet number space. TEXT[!MUST,implementation,test]: CONNECTION_CLOSE TEXT[!MUST,implementation,test]: frames signaling application errors (type 0x1d) MUST only appear TEXT[!MUST,implementation,test]: in the application data packet number space. TEXT[!MAY,implementation]: * ACK frames MAY appear in any packet number space but can only TEXT[!MAY,implementation]: acknowledge packets that appeared in that packet number space. TEXT[!MUST,implementation,test]: * All other frame types MUST only be sent in the application data TEXT[!MUST,implementation,test]: packet number space. TEXT[!MAY,implementation]: A server MAY treat receipt TEXT[!MAY,implementation]: of these frames in 0-RTT packets as a connection error of type TEXT[!MAY,implementation]: PROTOCOL_VIOLATION. SECTION: [Packetization and Reliability](#section-13) TEXT[!MAY]: A sender TEXT[!MAY]: MAY wait for a short period of time to collect multiple frames before TEXT[!MAY]: sending a packet that is not maximally packed, to avoid sending out TEXT[!MAY]: large numbers of small packets. TEXT[!MAY]: An implementation MAY use knowledge TEXT[!MAY]: about application sending behavior or heuristics to determine whether TEXT[!MAY]: and for how long to wait. SECTION: [Packet Processing](#section-13.1) TEXT[!MUST,implementation,test]: A packet MUST NOT be acknowledged until packet protection has been TEXT[!MUST,implementation,test]: successfully removed and all frames contained in the packet have been TEXT[!MUST,implementation,test]: processed. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD treat receipt of an acknowledgment for a packet it TEXT[!SHOULD,implementation,test]: did not send as a connection error of type PROTOCOL_VIOLATION, if it TEXT[!SHOULD,implementation,test]: is able to detect the condition. SECTION: [Generating Acknowledgments](#section-13.2) TEXT[!SHOULD,implementation,test]: When sending a packet for any reason, an endpoint SHOULD attempt to TEXT[!SHOULD,implementation,test]: include an ACK frame if one has not been sent recently. SECTION: [Sending ACK Frames](#section-13.2.1) TEXT[!MUST,implementation,test]: Every packet SHOULD be acknowledged at least once, and ack-eliciting TEXT[!MUST,implementation,test]: packets MUST be acknowledged at least once within the maximum delay TEXT[!MUST,implementation,test]: an endpoint communicated using the max_ack_delay transport parameter; TEXT[!MUST,implementation,test]: see Section 18.2. TEXT[!MUST,implementation,test]: An endpoint MUST acknowledge all ack-eliciting Initial and Handshake TEXT[!MUST,implementation,test]: packets immediately and all ack-eliciting 0-RTT and 1-RTT packets TEXT[!MUST,implementation,test]: within its advertised max_ack_delay, with the following exception. TEXT[!MUST,implementation,test]: Since packets containing only ACK frames are not congestion TEXT[!MUST,implementation,test]: controlled, an endpoint MUST NOT send more than one such packet in TEXT[!MUST,implementation,test]: response to receiving an ack-eliciting packet. TEXT[!MUST,implementation,test]: An endpoint MUST NOT send a non-ack-eliciting packet in response to a TEXT[!MUST,implementation,test]: non-ack-eliciting packet, even if there are packet gaps that precede TEXT[!MUST,implementation,test]: the received packet. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD TEXT[!SHOULD,implementation,test]: send an ACK frame with other frames when there are new ack-eliciting TEXT[!SHOULD,implementation,test]: packets to acknowledge. TEXT[!MAY,implementation]: When only non-ack-eliciting packets need to TEXT[!MAY,implementation]: be acknowledged, an endpoint MAY choose not to send an ACK frame with TEXT[!MAY,implementation]: outgoing frames until an ack-eliciting packet has been received. TEXT[!MUST,implementation,test]: In TEXT[!MUST,implementation,test]: that case, an endpoint MUST NOT send an ack-eliciting frame in all TEXT[!MUST,implementation,test]: packets that would otherwise be non-ack-eliciting, to avoid an TEXT[!MUST,implementation,test]: infinite feedback loop of acknowledgments. TEXT[!SHOULD,implementation,test]: In order to assist loss detection at the sender, an endpoint SHOULD TEXT[!SHOULD,implementation,test]: generate and send an ACK frame without delay when it receives an ack- TEXT[!SHOULD,implementation,test]: eliciting packet either: TEXT[implementation,test]: * when the received packet has a packet number less than another TEXT[implementation,test]: ack-eliciting packet that has been received, or TEXT[implementation,test]: * when the packet has a packet number larger than the highest- TEXT[implementation,test]: numbered ack-eliciting packet that has been received and there are TEXT[implementation,test]: missing packets between that packet and this packet. TEXT[!SHOULD,implementation,test]: Similarly, packets marked with the ECN Congestion Experienced (CE) TEXT[!SHOULD,implementation,test]: codepoint in the IP header SHOULD be acknowledged immediately, to TEXT[!SHOULD,implementation,test]: reduce the peer's response time to congestion events. SECTION: [Acknowledgment Frequency](#section-13.2.2) TEXT[!SHOULD,implementation,test]: A receiver SHOULD send an ACK frame after receiving at least two ack- TEXT[!SHOULD,implementation,test]: eliciting packets. TEXT[!MAY,implementation]: A receiver MAY process multiple available packets before determining TEXT[!MAY,implementation]: whether to send an ACK frame in response. SECTION: [Managing ACK Ranges](#section-13.2.3) TEXT[!SHOULD,implementation,test]: ACK frames SHOULD always acknowledge the most recently received TEXT[!SHOULD,implementation,test]: packets, and the more out of order the packets are, the more TEXT[!SHOULD,implementation,test]: important it is to send an updated ACK frame quickly, to prevent the TEXT[!SHOULD,implementation,test]: peer from declaring a packet as lost and spuriously retransmitting TEXT[!SHOULD,implementation,test]: the frames it contains. TEXT[!SHOULD,implementation,test]: After receiving TEXT[!SHOULD,implementation,test]: acknowledgments for an ACK frame, the receiver SHOULD stop tracking TEXT[!SHOULD,implementation,test]: those acknowledged ACK Ranges. TEXT[!MAY,implementation]: Receivers MAY also limit ACK TEXT[!MAY,implementation]: frame size further to preserve space for other frames or to limit the TEXT[!MAY,implementation]: capacity that acknowledgments consume. TEXT[!MUST,implementation,test]: A receiver MUST retain an ACK Range unless it can ensure that it will TEXT[!MUST,implementation,test]: not subsequently accept packets with numbers in that range. TEXT[implementation,test]: Maintaining a minimum packet number that increases as ranges are TEXT[implementation,test]: discarded is one way to achieve this with minimal state. TEXT[!MUST,implementation,test]: Receivers can discard all ACK Ranges, but they MUST retain the TEXT[!MUST,implementation,test]: largest packet number that has been successfully processed, as that TEXT[!MUST,implementation,test]: is used to recover packet numbers from subsequent packets; see TEXT[!MUST,implementation,test]: Section 17.1. TEXT[!SHOULD,implementation,test]: A receiver SHOULD include an ACK Range containing the largest TEXT[!SHOULD,implementation,test]: received packet number in every ACK frame. SECTION: [Measuring and Reporting Host Delay](#section-13.2.5) TEXT[!MUST,implementation,test]: An endpoint MUST NOT include delays that it TEXT[!MUST,implementation,test]: does not control when populating the ACK Delay field in an ACK frame. TEXT[!SHOULD,implementation,test]: However, endpoints SHOULD include buffering delays caused by TEXT[!SHOULD,implementation,test]: unavailability of decryption keys, since these delays can be large TEXT[!SHOULD,implementation,test]: and are likely to be non-repeating. TEXT[!SHOULD,implementation,test]: When the measured acknowledgment delay is larger than its TEXT[!SHOULD,implementation,test]: max_ack_delay, an endpoint SHOULD report the measured delay. SECTION: [ACK Frames and Packet Protection](#section-13.2.6) TEXT[!MUST,implementation,test]: ACK frames MUST only be carried in a packet that has the same packet TEXT[!MUST,implementation,test]: number space as the packet being acknowledged; see Section 12.1. TEXT[!MUST,implementation,test]: For TEXT[!MUST,implementation,test]: instance, packets that are protected with 1-RTT keys MUST be TEXT[!MUST,implementation,test]: acknowledged in packets that are also protected with 1-RTT keys. TEXT[!MUST,implementation,test]: Packets that a client sends with 0-RTT packet protection MUST be TEXT[!MUST,implementation,test]: acknowledged by the server in packets protected by 1-RTT keys. SECTION: [PADDING Frames Consume Congestion Window](#section-13.2.7) TEXT[!SHOULD,implementation,test]: To TEXT[!SHOULD,implementation,test]: avoid a deadlock, a sender SHOULD ensure that other frames are sent TEXT[!SHOULD,implementation,test]: periodically in addition to PADDING frames to elicit acknowledgments TEXT[!SHOULD,implementation,test]: from the receiver. SECTION: [Retransmission of Information](#section-13.3) TEXT[!MUST,implementation,test]: The content of a RESET_STREAM frame MUST NOT change when it is TEXT[!MUST,implementation,test]: sent again. TEXT[!SHOULD,implementation,test]: An endpoint SHOULD stop sending TEXT[!SHOULD,implementation,test]: MAX_STREAM_DATA frames when the receiving part of the stream TEXT[!SHOULD,implementation,test]: enters a "Size Known" or "Reset Recvd" state. TEXT[!MUST,implementation,test]: * The HANDSHAKE_DONE frame MUST be retransmitted until it is TEXT[!MUST,implementation,test]: acknowledged. TEXT[!SHOULD,implementation,test]: Endpoints SHOULD prioritize retransmission of data over sending new TEXT[!SHOULD,implementation,test]: data, unless priorities specified by the application indicate TEXT[!SHOULD,implementation,test]: otherwise; see Section 2.3. TEXT[!MUST,implementation,test]: A receiver MUST accept packets containing an TEXT[!MUST,implementation,test]: outdated frame, such as a MAX_DATA frame carrying a smaller maximum TEXT[!MUST,implementation,test]: data value than one found in an older packet. TEXT[!SHOULD,implementation,test]: A sender SHOULD avoid retransmitting information from packets once TEXT[!SHOULD,implementation,test]: they are acknowledged. TEXT[!MUST,implementation,test]: Upon detecting losses, a sender MUST take appropriate congestion TEXT[!MUST,implementation,test]: control action. SECTION: [Reporting ECN Counts](#section-13.4.1) TEXT[!MUST,implementation,test]: Even if an endpoint does not set an ECT field in packets it sends, TEXT[!MUST,implementation,test]: the endpoint MUST provide feedback about ECN markings it receives, if TEXT[!MUST,implementation,test]: these are accessible. SECTION: [ECN Validation](#section-13.4.2) TEXT[!MAY]: Implementations MAY use other methods TEXT[!MAY]: defined in RFCs; see [RFC8311]. SECTION: [Receiving ACK Frames with ECN Counts](#section-13.4.2.1) TEXT[!MUST,implementation,test]: An endpoint MUST NOT fail ECN validation as a result of TEXT[!MUST,implementation,test]: processing an ACK frame that does not increase the largest TEXT[!MUST,implementation,test]: acknowledged packet number. SECTION: [ECN Validation Outcomes](#section-13.4.2.2) TEXT[!MUST,implementation,test]: If validation fails, then the endpoint MUST disable ECN. TEXT[implementation,test]: It stops TEXT[implementation,test]: setting the ECT codepoint in IP packets that it sends, assuming that TEXT[implementation,test]: either the network path or the peer does not support ECN. TEXT[!MAY]: Even if validation fails, an endpoint MAY revalidate ECN for the same TEXT[!MAY]: path at any later time in the connection. TEXT[!MAY,implementation]: Upon successful validation, an endpoint MAY continue to set an ECT TEXT[!MAY,implementation]: codepoint in subsequent packets it sends, with the expectation that TEXT[!MAY,implementation]: the path is ECN capable. TEXT[!MUST,implementation,test]: Network routing and path elements can TEXT[!MUST,implementation,test]: change mid-connection; an endpoint MUST disable ECN if validation TEXT[!MUST,implementation,test]: later fails. SECTION: [Datagram Size](#section-14) TEXT[!MUST,implementation,test]: QUIC MUST NOT be used if the network path cannot support a TEXT[!MUST,implementation,test]: maximum datagram size of at least 1200 bytes. TEXT[!MUST,implementation,test]: UDP datagrams MUST NOT be fragmented at the IP layer. TEXT[!MUST,implementation,test]: In IPv4 TEXT[!MUST,implementation,test]: [IPv4], the Don't Fragment (DF) bit MUST be set if possible, to TEXT[!MUST,implementation,test]: prevent fragmentation on the path. TEXT[!MUST,implementation,test]: Therefore, an endpoint MUST NOT close a connection TEXT[!MUST,implementation,test]: when it receives a datagram that does not meet size constraints; the TEXT[!MUST,implementation,test]: endpoint MAY discard such datagrams. SECTION: [Initial Datagram Size](#section-14.1) TEXT[!MUST,implementation,test]: A client MUST expand the payload of all UDP datagrams carrying TEXT[!MUST,implementation,test]: Initial packets to at least the smallest allowed maximum datagram TEXT[!MUST,implementation,test]: size of 1200 bytes by adding PADDING frames to the Initial packet or TEXT[!MUST,implementation,test]: by coalescing the Initial packet; see Section 12.2. TEXT[!MUST,implementation,test]: Similarly, a server MUST expand the payload of all UDP TEXT[!MUST,implementation,test]: datagrams carrying ack-eliciting Initial packets to at least the TEXT[!MUST,implementation,test]: smallest allowed maximum datagram size of 1200 bytes. TEXT[!MAY,implementation]: Datagrams containing Initial packets MAY exceed 1200 bytes if the TEXT[!MAY,implementation]: sender believes that the network path and peer both support the size TEXT[!MAY,implementation]: that it chooses. TEXT[!MUST,implementation,test]: A server MUST discard an Initial packet that is carried in a UDP TEXT[!MUST,implementation,test]: datagram with a payload that is smaller than the smallest allowed TEXT[!MUST,implementation,test]: maximum datagram size of 1200 bytes. TEXT[!MAY]: A server MAY also immediately TEXT[!MAY]: close the connection by sending a CONNECTION_CLOSE frame with an TEXT[!MAY]: error code of PROTOCOL_VIOLATION; see Section 10.2.3. TEXT[!MUST,implementation,test]: The server MUST also limit the number of bytes it sends before TEXT[!MUST,implementation,test]: validating the address of the client; see Section 8. SECTION: [Path Maximum Transmission Unit](#section-14.2) TEXT[!SHOULD,implementation,test]: An endpoint SHOULD use DPLPMTUD (Section 14.3) or PMTUD TEXT[!SHOULD,implementation,test]: (Section 14.2.1) to determine whether the path to a destination will TEXT[!SHOULD,implementation,test]: support a desired maximum datagram size without fragmentation. TEXT[!SHOULD,implementation,test]: In TEXT[!SHOULD,implementation,test]: the absence of these mechanisms, QUIC endpoints SHOULD NOT send TEXT[!SHOULD,implementation,test]: datagrams larger than the smallest allowed maximum datagram size. TEXT[!SHOULD,implementation,test]: All QUIC TEXT[!SHOULD,implementation,test]: packets that are not sent in a PMTU probe SHOULD be sized to fit TEXT[!SHOULD,implementation,test]: within the maximum datagram size to avoid the datagram being TEXT[!SHOULD,implementation,test]: fragmented or dropped [RFC8085]. TEXT[!MUST,implementation,test]: If a QUIC endpoint determines that the PMTU between any pair of local TEXT[!MUST,implementation,test]: and remote IP addresses cannot support the smallest allowed maximum TEXT[!MUST,implementation,test]: datagram size of 1200 bytes, it MUST immediately cease sending QUIC TEXT[!MUST,implementation,test]: packets, except for those in PMTU probes or those containing TEXT[!MUST,implementation,test]: CONNECTION_CLOSE frames, on the affected path. TEXT[!MAY,implementation]: An endpoint MAY TEXT[!MAY,implementation]: terminate the connection if an alternative path cannot be found. TEXT[!SHOULD,implementation,test]: QUIC implementations that implement any kind of PMTU discovery TEXT[!SHOULD,implementation,test]: therefore SHOULD maintain a maximum datagram size for each TEXT[!SHOULD,implementation,test]: combination of local and remote IP addresses. TEXT[!MAY,implementation]: A QUIC implementation MAY be more conservative in computing the TEXT[!MAY,implementation]: maximum datagram size to allow for unknown tunnel overheads or IP TEXT[!MAY,implementation]: header options/extensions. SECTION: [Handling of ICMP Messages by PMTUD](#section-14.2.1) TEXT[!MUST,implementation,test]: An endpoint MUST ignore an ICMP message that claims the PMTU has TEXT[!MUST,implementation,test]: decreased below QUIC's smallest allowed maximum datagram size. TEXT[!SHOULD,implementation]: QUIC endpoints using PMTUD SHOULD validate ICMP messages to protect TEXT[!SHOULD,implementation]: from packet injection as specified in [RFC8201] and Section 5.2 of TEXT[!SHOULD,implementation]: [RFC8085]. TEXT[!SHOULD,implementation,test]: This validation SHOULD use the quoted packet supplied in TEXT[!SHOULD,implementation,test]: the payload of an ICMP message to associate the message with a TEXT[!SHOULD,implementation,test]: corresponding transport connection (see Section 4.6.1 of [DPLPMTUD]). TEXT[!MUST,implementation]: ICMP message validation MUST include matching IP addresses and UDP TEXT[!MUST,implementation]: ports [RFC8085] and, when possible, connection IDs to an active QUIC TEXT[!MUST,implementation]: session. TEXT[!SHOULD,implementation,test]: The endpoint SHOULD ignore all ICMP messages that fail TEXT[!SHOULD,implementation,test]: validation. TEXT[!MUST,implementation,test]: An endpoint MUST NOT increase the PMTU based on ICMP messages; see TEXT[!MUST,implementation,test]: Item 6 in Section 3 of [DPLPMTUD]. TEXT[!MAY]: Any reduction in QUIC's maximum TEXT[!MAY]: datagram size in response to ICMP messages MAY be provisional until TEXT[!MAY]: QUIC's loss detection algorithm determines that the quoted packet has TEXT[!MAY]: actually been lost. SECTION: [Datagram Packetization Layer PMTU Discovery](#section-14.3) TEXT[!SHOULD,implementation,test]: Endpoints SHOULD set the initial value of BASE_PLPMTU (Section 5.1 of TEXT[!SHOULD,implementation,test]: [DPLPMTUD]) to be consistent with QUIC's smallest allowed maximum TEXT[!SHOULD,implementation,test]: datagram size. SECTION: [Sending QUIC PMTU Probes](#section-14.4) TEXT[!SHOULD,implementation,test]: Loss of TEXT[!SHOULD,implementation,test]: a QUIC packet that is carried in a PMTU probe is therefore not a TEXT[!SHOULD,implementation,test]: reliable indication of congestion and SHOULD NOT trigger a congestion TEXT[!SHOULD,implementation,test]: control reaction; see Item 7 in Section 3 of [DPLPMTUD]. SECTION: [Versions](#section-15) TEXT[!MAY,implementation]: client or server MAY advertise support for any of these reserved TEXT[!MAY,implementation]: versions. TEXT[!MAY,implementation]: Reserved version numbers will never represent a real protocol; a TEXT[!MAY,implementation]: client MAY use one of these version numbers with the expectation that TEXT[!MAY,implementation]: the server will initiate version negotiation; a server MAY advertise TEXT[!MAY,implementation]: support for one of these versions and can expect that clients ignore TEXT[!MAY,implementation]: the value. SECTION: [Packet Number Encoding and Decoding](#section-17.1) TEXT[!MUST,implementation]: Prior to receiving an acknowledgment for a packet number space, the TEXT[!MUST,implementation]: full packet number MUST be included; it is not to be truncated, as TEXT[!MUST,implementation]: described below. TEXT[!MUST,implementation]: After an acknowledgment is received for a packet number space, the TEXT[!MUST,implementation]: sender MUST use a packet number size able to represent more than TEXT[!MUST,implementation]: twice as large a range as the difference between the largest TEXT[!MUST,implementation]: acknowledged packet number and the packet number being sent. TEXT[!SHOULD,implementation]: An endpoint SHOULD TEXT[!SHOULD,implementation]: use a large enough packet number encoding to allow the packet number TEXT[!SHOULD,implementation]: to be recovered even if the packet arrives after packets that are TEXT[!SHOULD,implementation]: sent afterwards. TEXT[implementation,test]: Once header protection is removed, the packet number is decoded by TEXT[implementation,test]: finding the packet number value that is closest to the next expected TEXT[implementation,test]: packet. SECTION: [Long Header Packets](#section-17.2) TEXT[!MUST,implementation,test]: Packets containing a zero TEXT[!MUST,implementation,test]: value for this bit are not valid packets in this version and MUST TEXT[!MUST,implementation,test]: be discarded. TEXT[!MUST,implementation,test]: In QUIC version 1, this value MUST NOT exceed TEXT[!MUST,implementation,test]: 20 bytes. TEXT[!MUST,implementation,test]: Endpoints that receive a version 1 long header with a TEXT[!MUST,implementation,test]: value larger than 20 MUST drop the packet. TEXT[!SHOULD,implementation,test]: In order to properly TEXT[!SHOULD,implementation,test]: form a Version Negotiation packet, servers SHOULD be able to read TEXT[!SHOULD,implementation,test]: longer connection IDs from other QUIC versions. TEXT[!MUST,implementation,test]: The value TEXT[!MUST,implementation,test]: included prior to protection MUST be set to 0. TEXT[!MUST,implementation,test]: An endpoint MUST TEXT[!MUST,implementation,test]: treat receipt of a packet that has a non-zero value for these bits TEXT[!MUST,implementation,test]: after removing both packet and header protection as a connection TEXT[!MUST,implementation,test]: error of type PROTOCOL_VIOLATION. SECTION: [Version Negotiation Packet](#section-17.2.1) TEXT[implementation,test]: The value in the Unused field is set to an arbitrary value by the TEXT[implementation,test]: server. TEXT[!MUST,implementation,test]: Clients MUST ignore the value of this field. TEXT[!SHOULD,implementation,test]: Where QUIC TEXT[!SHOULD,implementation,test]: might be multiplexed with other protocols (see [RFC7983]), servers TEXT[!SHOULD,implementation,test]: SHOULD set the most significant bit of this field (0x40) to 1 so that TEXT[!SHOULD,implementation,test]: Version Negotiation packets appear to have the Fixed Bit field. TEXT[!MUST,implementation,test]: The Version field of a Version Negotiation packet MUST be set to TEXT[!MUST,implementation,test]: 0x00000000. TEXT[!MUST,implementation,test]: The server MUST include the value from the Source Connection ID field TEXT[!MUST,implementation,test]: of the packet it receives in the Destination Connection ID field. TEXT[!MUST,implementation,test]: The value for Source Connection ID MUST be copied from the TEXT[!MUST,implementation,test]: Destination Connection ID of the received packet, which is initially TEXT[!MUST,implementation,test]: randomly selected by a client. TEXT[!MUST,implementation,test]: Version- TEXT[!MUST,implementation,test]: specific rules for the connection ID therefore MUST NOT influence a TEXT[!MUST,implementation,test]: decision about whether to send a Version Negotiation packet. TEXT[!MUST,implementation,test]: A server MUST NOT send more than one Version Negotiation packet in TEXT[!MUST,implementation,test]: response to a single UDP datagram. SECTION: [Initial Packet](#section-17.2.2) TEXT[!MUST,implementation,test]: Initial packets sent by the server MUST set the Token Length field TEXT[!MUST,implementation,test]: to 0; clients that receive an Initial packet with a non-zero Token TEXT[!MUST,implementation,test]: Length field MUST either discard the packet or generate a TEXT[!MUST,implementation,test]: connection error of type PROTOCOL_VIOLATION. TEXT[!MAY,implementation]: A server MAY send multiple Initial packets. SECTION: [0-RTT](#section-17.2.3) TEXT[!SHOULD,implementation,test]: A client SHOULD attempt TEXT[!SHOULD,implementation,test]: to resend data in 0-RTT packets after it sends a new Initial packet. TEXT[!MUST,implementation,test]: New packet numbers MUST be used for any new packets that are sent; as TEXT[!MUST,implementation,test]: described in Section 17.2.5.3, reusing packet numbers could TEXT[!MUST,implementation,test]: compromise packet protection. TEXT[!MUST,implementation,test]: A client MUST NOT send 0-RTT packets once it starts processing 1-RTT TEXT[!MUST,implementation,test]: packets from the server. TEXT[!MUST,implementation,test]: An acknowledgment for a 1-RTT TEXT[!MUST,implementation,test]: packet MUST be carried in a 1-RTT packet. TEXT[!SHOULD,implementation,test]: A server SHOULD treat a violation of remembered limits TEXT[!SHOULD,implementation,test]: (Section 7.4.1) as a connection error of an appropriate type (for TEXT[!SHOULD,implementation,test]: instance, a FLOW_CONTROL_ERROR for exceeding stream data limits). SECTION: [Handshake Packet](#section-17.2.4) TEXT[!MAY,implementation]: Handshake packets MAY contain TEXT[!MAY,implementation]: CONNECTION_CLOSE frames of type 0x1c. TEXT[!MUST,implementation,test]: Endpoints MUST treat receipt TEXT[!MUST,implementation,test]: of Handshake packets with other frames as a connection error of type TEXT[!MUST,implementation,test]: PROTOCOL_VIOLATION. SECTION: [Retry Packet](#section-17.2.5) TEXT[!MUST,implementation,test]: The value in TEXT[!MUST,implementation,test]: the Unused field is set to an arbitrary value by the server; a client TEXT[!MUST,implementation,test]: MUST ignore these bits. SECTION: [Sending a Retry Packet](#section-17.2.5.1) TEXT[!MUST,implementation,test]: This value MUST NOT be equal to the Destination TEXT[!MUST,implementation,test]: Connection ID field of the packet sent by the client. TEXT[!MUST,implementation,test]: A client MUST TEXT[!MUST,implementation,test]: discard a Retry packet that contains a Source Connection ID field TEXT[!MUST,implementation,test]: that is identical to the Destination Connection ID field of its TEXT[!MUST,implementation,test]: Initial packet. TEXT[!MUST,implementation,test]: The client MUST use the value from the Source TEXT[!MUST,implementation,test]: Connection ID field of the Retry packet in the Destination Connection TEXT[!MUST,implementation,test]: ID field of subsequent packets that it sends. TEXT[!MAY,implementation]: A server MAY send Retry packets in response to Initial and 0-RTT TEXT[!MAY,implementation]: packets. TEXT[!MUST,implementation,test]: A server MUST NOT send more than one Retry TEXT[!MUST,implementation,test]: packet in response to a single UDP datagram. SECTION: [Handling a Retry Packet](#section-17.2.5.2) TEXT[!MUST,implementation,test]: A client MUST accept and process at most one Retry packet for each TEXT[!MUST,implementation,test]: connection attempt. TEXT[!MUST,implementation,test]: After the client has received and processed an TEXT[!MUST,implementation,test]: Initial or Retry packet from the server, it MUST discard any TEXT[!MUST,implementation,test]: subsequent Retry packets that it receives. TEXT[!MUST,implementation,test]: Clients MUST discard Retry packets that have a Retry Integrity Tag TEXT[!MUST,implementation,test]: that cannot be validated; see Section 5.8 of [QUIC-TLS]. TEXT[!MUST,implementation,test]: A client TEXT[!MUST,implementation,test]: MUST discard a Retry packet with a zero-length Retry Token field. TEXT[!MUST,implementation,test]: The TEXT[!MUST,implementation,test]: client MUST NOT change the Source Connection ID because the server TEXT[!MUST,implementation,test]: could include the connection ID as part of its token validation TEXT[!MUST,implementation,test]: logic; see Section 8.1.4. SECTION: [Continuing a Handshake after Retry](#section-17.2.5.3) TEXT[!MUST,implementation,test]: A client MUST use the same TEXT[!MUST,implementation,test]: cryptographic handshake message it included in this packet. TEXT[!MAY]: A server TEXT[!MAY]: MAY treat a packet that contains a different cryptographic handshake TEXT[!MAY]: message as a connection error or discard it. TEXT[!MAY,implementation]: A client MAY attempt 0-RTT after receiving a Retry packet by sending TEXT[!MAY,implementation]: 0-RTT packets to the connection ID provided by the server. TEXT[!MUST,test]: A client MUST NOT reset the packet number for any packet number space TEXT[!MUST,test]: after processing a Retry packet. TEXT[!MAY]: A server MAY abort the connection if it TEXT[!MAY]: detects that the client reset the packet number. SECTION: [1-RTT Packet](#section-17.3.1) TEXT[!MUST,implementation,test]: Packets TEXT[!MUST,implementation,test]: containing a zero value for this bit are not valid packets in this TEXT[!MUST,implementation,test]: version and MUST be discarded. TEXT[!MUST,implementation,test]: The value included prior to TEXT[!MUST,implementation,test]: protection MUST be set to 0. TEXT[!MUST,implementation,test]: An endpoint MUST treat receipt of a TEXT[!MUST,implementation,test]: packet that has a non-zero value for these bits, after removing TEXT[!MUST,implementation,test]: both packet and header protection, as a connection error of type TEXT[!MUST,implementation,test]: PROTOCOL_VIOLATION. SECTION: [Latency Spin Bit](#section-17.4) TEXT[!MAY,implementation]: The spin bit is an OPTIONAL feature of this version of QUIC. TEXT[!MUST,implementation,test]: An TEXT[!MUST,implementation,test]: endpoint that does not support this feature MUST disable it, as TEXT[!MUST,implementation,test]: defined below. TEXT[!MUST,implementation,test]: Implementations MUST allow administrators TEXT[!MUST,implementation,test]: of clients and servers to disable the spin bit either globally or on TEXT[!MUST,implementation,test]: a per-connection basis. TEXT[!MUST,implementation,test]: Even when the spin bit is not disabled by TEXT[!MUST,implementation,test]: the administrator, endpoints MUST disable their use of the spin bit TEXT[!MUST,implementation,test]: for a random selection of at least one in every 16 network paths, or TEXT[!MUST,implementation,test]: for one in every 16 connection IDs, in order to ensure that QUIC TEXT[!MUST,implementation,test]: connections that disable the spin bit are commonly observed on the TEXT[!MUST,implementation,test]: network. TEXT[!MUST,implementation,test]: When the spin bit is disabled, endpoints MAY set the spin bit to any TEXT[!MUST,implementation,test]: value and MUST ignore any incoming value. TEXT[!SHOULD,implementation,test]: It is RECOMMENDED that TEXT[!SHOULD,implementation,test]: endpoints set the spin bit to a random value either chosen TEXT[!SHOULD,implementation,test]: independently for each packet or chosen independently for each TEXT[!SHOULD,implementation,test]: connection ID. SECTION: [Transport Parameter Definitions](#section-18.2) TEXT[!MUST,implementation,test]: This transport parameter MUST NOT be sent TEXT[!MUST,implementation,test]: by a client but MAY be sent by a server. TEXT[implementation,test]: Values below 1200 are invalid. TEXT[!SHOULD,implementation]: This value TEXT[!SHOULD,implementation]: SHOULD include the receiver's expected delays in alarms firing. TEXT[implementation,test]: Values of 2^14 or greater are invalid. TEXT[!MUST,implementation,test]: An endpoint that receives this transport TEXT[!MUST,implementation,test]: parameter MUST NOT use a new local address when sending to the TEXT[!MUST,implementation,test]: address that the peer used during the handshake. TEXT[!MAY,implementation]: Servers MAY choose to only send a preferred address TEXT[!MAY,implementation]: of one address family by sending an all-zero address and port TEXT[!MAY,implementation]: (0.0.0.0:0 or [::]:0) for the other family. TEXT[!MUST,implementation,test]: A server TEXT[!MUST,implementation,test]: that chooses a zero-length connection ID MUST NOT provide a TEXT[!MUST,implementation,test]: preferred address. TEXT[!MUST,implementation,test]: Similarly, a server MUST NOT include a zero- TEXT[!MUST,implementation,test]: length connection ID in this transport parameter. TEXT[!MUST,implementation,test]: A client MUST TEXT[!MUST,implementation,test]: treat a violation of these requirements as a connection error of TEXT[!MUST,implementation,test]: type TRANSPORT_PARAMETER_ERROR. TEXT[!MUST,implementation,test]: The value of the TEXT[!MUST,implementation,test]: active_connection_id_limit parameter MUST be at least 2. TEXT[!MUST,implementation,test]: An TEXT[!MUST,implementation,test]: endpoint that receives a value less than 2 MUST close the TEXT[!MUST,implementation,test]: connection with an error of type TRANSPORT_PARAMETER_ERROR. TEXT[!MUST,implementation,test]: A client MUST NOT include any server-only transport parameter: TEXT[!MUST,implementation,test]: original_destination_connection_id, preferred_address, TEXT[!MUST,implementation,test]: retry_source_connection_id, or stateless_reset_token. TEXT[!MUST,implementation,test]: A server MUST TEXT[!MUST,implementation,test]: treat receipt of any of these transport parameters as a connection TEXT[!MUST,implementation,test]: error of type TRANSPORT_PARAMETER_ERROR. SECTION: [ACK Frames](#section-19.3) TEXT[!MUST,implementation,test]: QUIC implementations MUST properly handle both TEXT[!MUST,implementation,test]: types, and, if they have enabled ECN for packets they send, they TEXT[!MUST,implementation,test]: SHOULD use the information in the ECN section to manage their TEXT[!MUST,implementation,test]: congestion state. SECTION: [ACK Ranges](#section-19.3.1) TEXT[!MUST,implementation,test]: If any computed packet number is negative, an endpoint MUST generate TEXT[!MUST,implementation,test]: a connection error of type FRAME_ENCODING_ERROR. SECTION: [RESET_STREAM Frames](#section-19.4) TEXT[!MUST,implementation,test]: An endpoint that receives a RESET_STREAM frame for a send-only stream TEXT[!MUST,implementation,test]: MUST terminate the connection with error STREAM_STATE_ERROR. SECTION: [STOP_SENDING Frames](#section-19.5) TEXT[!MUST,implementation,test]: Receiving a STOP_SENDING frame for a TEXT[!MUST,implementation,test]: locally initiated stream that has not yet been created MUST be TEXT[!MUST,implementation,test]: treated as a connection error of type STREAM_STATE_ERROR. TEXT[!MUST,implementation,test]: An TEXT[!MUST,implementation,test]: endpoint that receives a STOP_SENDING frame for a receive-only stream TEXT[!MUST,implementation,test]: MUST terminate the connection with error STREAM_STATE_ERROR. SECTION: [CRYPTO Frames](#section-19.6) TEXT[!MUST,implementation,test]: Receipt of a frame that exceeds TEXT[!MUST,implementation,test]: this limit MUST be treated as a connection error of type TEXT[!MUST,implementation,test]: FRAME_ENCODING_ERROR or CRYPTO_BUFFER_EXCEEDED. SECTION: [NEW_TOKEN Frames](#section-19.7) TEXT[!MUST,implementation,test]: The token MUST NOT be empty. TEXT[!MUST,implementation,test]: A client MUST treat receipt TEXT[!MUST,implementation,test]: of a NEW_TOKEN frame with an empty Token field as a connection TEXT[!MUST,implementation,test]: error of type FRAME_ENCODING_ERROR. TEXT[!MUST,implementation,test]: Clients MUST NOT send NEW_TOKEN frames. TEXT[!MUST,implementation,test]: A server MUST treat receipt TEXT[!MUST,implementation,test]: of a NEW_TOKEN frame as a connection error of type TEXT[!MUST,implementation,test]: PROTOCOL_VIOLATION. SECTION: [STREAM Frames](#section-19.8) TEXT[!MUST,implementation,test]: An endpoint MUST terminate the connection with error TEXT[!MUST,implementation,test]: STREAM_STATE_ERROR if it receives a STREAM frame for a locally TEXT[!MUST,implementation,test]: initiated stream that has not yet been created, or for a send-only TEXT[!MUST,implementation,test]: stream. TEXT[!MUST,implementation,test]: Receipt of a frame that exceeds this limit TEXT[!MUST,implementation,test]: MUST be treated as a connection error of type FRAME_ENCODING_ERROR or TEXT[!MUST,implementation,test]: FLOW_CONTROL_ERROR. SECTION: [MAX_DATA Frames](#section-19.9) TEXT[!MUST,implementation,test]: The sum of TEXT[!MUST,implementation,test]: the final sizes on all streams -- including streams in terminal TEXT[!MUST,implementation,test]: states -- MUST NOT exceed the value advertised by a receiver. TEXT[!MUST,implementation,test]: An TEXT[!MUST,implementation,test]: endpoint MUST terminate a connection with an error of type TEXT[!MUST,implementation,test]: FLOW_CONTROL_ERROR if it receives more data than the maximum data TEXT[!MUST,implementation,test]: value that it has sent. SECTION: [MAX_STREAM_DATA Frames](#section-19.10) TEXT[!MUST,implementation,test]: Receiving a MAX_STREAM_DATA frame for a locally TEXT[!MUST,implementation,test]: initiated stream that has not yet been created MUST be treated as a TEXT[!MUST,implementation,test]: connection error of type STREAM_STATE_ERROR. TEXT[!MUST,implementation,test]: An endpoint that TEXT[!MUST,implementation,test]: receives a MAX_STREAM_DATA frame for a receive-only stream MUST TEXT[!MUST,implementation,test]: terminate the connection with error STREAM_STATE_ERROR. TEXT[!MUST,implementation,test]: The data sent on a stream MUST NOT exceed the largest maximum stream TEXT[!MUST,implementation,test]: data value advertised by the receiver. TEXT[!MUST,implementation,test]: An endpoint MUST terminate a TEXT[!MUST,implementation,test]: connection with an error of type FLOW_CONTROL_ERROR if it receives TEXT[!MUST,implementation,test]: more data than the largest maximum stream data that it has sent for TEXT[!MUST,implementation,test]: the affected stream. SECTION: [MAX_STREAMS Frames](#section-19.11) TEXT[!MUST,implementation,test]: Receipt of a frame that TEXT[!MUST,implementation,test]: permits opening of a stream larger than this limit MUST be treated TEXT[!MUST,implementation,test]: as a connection error of type FRAME_ENCODING_ERROR. TEXT[!MUST,implementation,test]: MAX_STREAMS frames that do not increase the stream limit MUST be TEXT[!MUST,implementation,test]: ignored. TEXT[!MUST,implementation,test]: An endpoint MUST NOT open more streams than permitted by the current TEXT[!MUST,implementation,test]: stream limit set by its peer. TEXT[!MUST,implementation,test]: An endpoint MUST terminate a connection TEXT[!MUST,implementation,test]: with an error of type STREAM_LIMIT_ERROR if a peer opens more streams TEXT[!MUST,implementation,test]: than was permitted. SECTION: [DATA_BLOCKED Frames](#section-19.12) TEXT[!SHOULD,implementation,test]: A sender SHOULD send a DATA_BLOCKED frame (type=0x14) when it wishes TEXT[!SHOULD,implementation,test]: to send data but is unable to do so due to connection-level flow TEXT[!SHOULD,implementation,test]: control; see Section 4. SECTION: [STREAM_DATA_BLOCKED Frames](#section-19.13) TEXT[!SHOULD,implementation,test]: A sender SHOULD send a STREAM_DATA_BLOCKED frame (type=0x15) when it TEXT[!SHOULD,implementation,test]: wishes to send data but is unable to do so due to stream-level flow TEXT[!SHOULD,implementation,test]: control. TEXT[!MUST,implementation,test]: An endpoint that receives a STREAM_DATA_BLOCKED frame for a send-only TEXT[!MUST,implementation,test]: stream MUST terminate the connection with error STREAM_STATE_ERROR. SECTION: [STREAMS_BLOCKED Frames](#section-19.14) TEXT[!SHOULD,implementation,test]: A sender SHOULD send a STREAMS_BLOCKED frame (type=0x16 or 0x17) when TEXT[!SHOULD,implementation,test]: it wishes to open a stream but is unable to do so due to the maximum TEXT[!SHOULD,implementation,test]: stream limit set by its peer; see Section 19.11. TEXT[!MUST,implementation,test]: Receipt of a frame that encodes a larger TEXT[!MUST,implementation,test]: stream ID MUST be treated as a connection error of type TEXT[!MUST,implementation,test]: STREAM_LIMIT_ERROR or FRAME_ENCODING_ERROR. SECTION: [NEW_CONNECTION_ID Frames](#section-19.15) TEXT[!MUST,implementation,test]: Values less than 1 and greater than 20 are invalid TEXT[!MUST,implementation,test]: and MUST be treated as a connection error of type TEXT[!MUST,implementation,test]: FRAME_ENCODING_ERROR. TEXT[!MUST,implementation,test]: An endpoint MUST NOT send this frame if it currently requires that TEXT[!MUST,implementation,test]: its peer send packets with a zero-length Destination Connection ID. TEXT[!MUST,implementation,test]: An endpoint that is sending packets with a zero-length Destination TEXT[!MUST,implementation,test]: Connection ID MUST treat receipt of a NEW_CONNECTION_ID frame as a TEXT[!MUST,implementation,test]: connection error of type PROTOCOL_VIOLATION. TEXT[!MUST,implementation,test]: Receipt TEXT[!MUST,implementation,test]: of the same frame multiple times MUST NOT be treated as a connection TEXT[!MUST,implementation,test]: error. TEXT[!MAY,implementation]: If an endpoint receives a NEW_CONNECTION_ID frame that repeats a TEXT[!MAY,implementation]: previously issued connection ID with a different Stateless Reset TEXT[!MAY,implementation]: Token field value or a different Sequence Number field value, or if a TEXT[!MAY,implementation]: sequence number is used for different connection IDs, the endpoint TEXT[!MAY,implementation]: MAY treat that receipt as a connection error of type TEXT[!MAY,implementation]: PROTOCOL_VIOLATION. TEXT[!MUST,implementation,test]: The value in the Retire Prior To field TEXT[!MUST,implementation,test]: MUST be less than or equal to the value in the Sequence Number field. TEXT[!MUST,implementation,test]: Receiving a value in the Retire Prior To field that is greater than TEXT[!MUST,implementation,test]: that in the Sequence Number field MUST be treated as a connection TEXT[!MUST,implementation,test]: error of type FRAME_ENCODING_ERROR. TEXT[!MUST,implementation,test]: A receiver TEXT[!MUST,implementation,test]: MUST ignore any Retire Prior To fields that do not increase the TEXT[!MUST,implementation,test]: largest received Retire Prior To value. TEXT[!MUST,implementation,test]: An endpoint that receives a NEW_CONNECTION_ID frame with a sequence TEXT[!MUST,implementation,test]: number smaller than the Retire Prior To field of a previously TEXT[!MUST,implementation,test]: received NEW_CONNECTION_ID frame MUST send a corresponding TEXT[!MUST,implementation,test]: RETIRE_CONNECTION_ID frame that retires the newly received connection TEXT[!MUST,implementation,test]: ID, unless it has already done so for that sequence number. SECTION: [RETIRE_CONNECTION_ID Frames](#section-19.16) TEXT[!MUST,implementation,test]: Receipt of a RETIRE_CONNECTION_ID frame containing a sequence number TEXT[!MUST,implementation,test]: greater than any previously sent to the peer MUST be treated as a TEXT[!MUST,implementation,test]: connection error of type PROTOCOL_VIOLATION. TEXT[!MUST,implementation,test]: The sequence number specified in a RETIRE_CONNECTION_ID frame MUST TEXT[!MUST,implementation,test]: NOT refer to the Destination Connection ID field of the packet in TEXT[!MUST,implementation,test]: which the frame is contained. TEXT[!MAY]: The peer MAY treat this as a TEXT[!MAY]: connection error of type PROTOCOL_VIOLATION. TEXT[!MUST,implementation,test]: An endpoint that provides a zero- TEXT[!MUST,implementation,test]: length connection ID MUST treat receipt of a RETIRE_CONNECTION_ID TEXT[!MUST,implementation,test]: frame as a connection error of type PROTOCOL_VIOLATION. SECTION: [PATH_CHALLENGE Frames](#section-19.17) TEXT[!MUST,implementation,test]: The recipient of this frame MUST generate a PATH_RESPONSE frame TEXT[!MUST,implementation,test]: (Section 19.18) containing the same Data value. SECTION: [PATH_RESPONSE Frames](#section-19.18) TEXT[!MAY]: If the content of a PATH_RESPONSE frame does not match the content of TEXT[!MAY]: a PATH_CHALLENGE frame previously sent by the endpoint, the endpoint TEXT[!MAY]: MAY generate a connection error of type PROTOCOL_VIOLATION. SECTION: [CONNECTION_CLOSE Frames](#section-19.19) TEXT[!SHOULD,implementation,test]: This SHOULD be a UTF-8 encoded TEXT[!SHOULD,implementation,test]: string [RFC3629], though the frame does not carry information, TEXT[!SHOULD,implementation,test]: such as language tags, that would aid comprehension by any entity TEXT[!SHOULD,implementation,test]: other than the one that created the text. SECTION: [HANDSHAKE_DONE Frames](#section-19.20) TEXT[!MUST,implementation,test]: Servers MUST TEXT[!MUST,implementation,test]: NOT send a HANDSHAKE_DONE frame before completing the handshake. TEXT[!MUST,implementation,test]: server MUST treat receipt of a HANDSHAKE_DONE frame as a connection TEXT[!MUST,implementation,test]: error of type PROTOCOL_VIOLATION. SECTION: [Extension Frames](#section-19.21) TEXT[!MUST,implementation,test]: An extension to QUIC that wishes to use a new type of frame MUST TEXT[!MUST,implementation,test]: first ensure that a peer is able to understand the frame. TEXT[!SHOULD,exception]: Such extensions TEXT[!SHOULD,exception]: SHOULD define their interaction with previously defined extensions TEXT[!SHOULD,exception]: modifying the same protocol components. TEXT[!MUST,implementation,test]: Extension frames MUST be congestion controlled and MUST cause an ACK TEXT[!MUST,implementation,test]: frame to be sent. SECTION: [Amplification Attack](#section-21.3) TEXT[!SHOULD,implementation,test]: Servers SHOULD provide mitigations for this attack by limiting the TEXT[!SHOULD,implementation,test]: usage and lifetime of address validation tokens; see Section 8.1.3. SECTION: [Optimistic ACK Attack](#section-21.4) TEXT[!MAY,implementation]: An endpoint MAY skip packet numbers when sending TEXT[!MAY,implementation]: packets to detect this behavior. SECTION: [Request Forgery Attacks](#section-21.5) TEXT[!SHOULD,exception]: QUIC TEXT[!SHOULD,exception]: servers SHOULD NOT be deployed in networks that do not deploy ingress TEXT[!SHOULD,exception]: filtering [BCP38] and also have inadequately secured UDP endpoints. TEXT[!MUST,exception]: Any future extension that allows server migration MUST TEXT[!MUST,exception]: also define countermeasures for forgery attacks. SECTION: [Request Forgery with Preferred Addresses](#section-21.5.3) TEXT[!MUST,implementation,test]: A client MUST NOT send non-probing frames to a preferred address TEXT[!MUST,implementation,test]: prior to validating that address; see Section 8. SECTION: [Generic Request Forgery Countermeasures](#section-21.5.6) TEXT[!MAY,implementation]: Endpoints MAY prevent connection attempts or TEXT[!MAY,implementation]: migration to a loopback address. TEXT[!SHOULD,implementation,test]: Endpoints SHOULD NOT allow TEXT[!SHOULD,implementation,test]: connections or migration to a loopback address if the same service TEXT[!SHOULD,implementation,test]: was previously available at a different interface or if the address TEXT[!SHOULD,implementation,test]: was provided by a service at a non-loopback address. TEXT[!SHOULD,implementation,test]: Endpoints SHOULD NOT refuse to use TEXT[!SHOULD,implementation,test]: an address unless they have specific knowledge about the network TEXT[!SHOULD,implementation,test]: indicating that sending datagrams to unvalidated addresses in a given TEXT[!SHOULD,implementation,test]: range is not safe. TEXT[!MAY]: Endpoints MAY choose to reduce the risk of request forgery by not TEXT[!MAY]: including values from NEW_TOKEN frames in Initial packets or by only TEXT[!MAY]: sending probing frames in packets prior to completing address TEXT[!MAY]: validation. TEXT[!MAY,implementation]: Endpoints MAY TEXT[!MAY,implementation]: choose to avoid sending datagrams to these ports or not send TEXT[!MAY,implementation]: datagrams that match these patterns prior to validating the TEXT[!MAY,implementation]: destination address. TEXT[!MAY]: Endpoints MAY retire connection IDs containing TEXT[!MAY]: patterns known to be problematic without using them. SECTION: [Slowloris Attacks](#section-21.6) TEXT[!SHOULD,exception]: QUIC deployments SHOULD provide mitigations for the Slowloris TEXT[!SHOULD,exception]: attacks, such as increasing the maximum number of clients the server TEXT[!SHOULD,exception]: will allow, limiting the number of connections a single IP address is TEXT[!SHOULD,exception]: allowed to make, imposing restrictions on the minimum transfer speed TEXT[!SHOULD,exception]: a connection is allowed to have, and restricting the length of time TEXT[!SHOULD,exception]: an endpoint is allowed to stay connected. SECTION: [Stream Fragmentation and Reassembly Attacks](#section-21.7) TEXT[!SHOULD,exception]: QUIC deployments SHOULD provide mitigations for stream fragmentation TEXT[!SHOULD,exception]: attacks. SECTION: [Peer Denial of Service](#section-21.9) TEXT[!SHOULD,implementation,test]: While there are legitimate uses for all messages, implementations TEXT[!SHOULD,implementation,test]: SHOULD track cost of processing relative to progress and treat TEXT[!SHOULD,implementation,test]: excessive quantities of any non-productive packets as indicative of TEXT[!SHOULD,implementation,test]: an attack. TEXT[!MAY,implementation,test]: Endpoints MAY respond to this condition with a connection TEXT[!MAY,implementation,test]: error or by dropping packets. SECTION: [Stateless Reset Oracle](#section-21.11) TEXT[!MUST,exception]: To defend TEXT[!MUST,exception]: against this style of denial of service, endpoints that share a TEXT[!MUST,exception]: static key for stateless resets (see Section 10.3.2) MUST be arranged TEXT[!MUST,exception]: so that packets with a given connection ID always arrive at an TEXT[!MUST,exception]: instance that has connection state, unless that connection is no TEXT[!MUST,exception]: longer active. TEXT[!MUST,exception]: More generally, servers MUST NOT generate a stateless reset if a TEXT[!MUST,exception]: connection with the corresponding connection ID could be active on TEXT[!MUST,exception]: any endpoint using the same static key. SECTION: [Version Downgrade](#section-21.12) TEXT[!MUST,exception]: Future TEXT[!MUST,exception]: versions of QUIC that use Version Negotiation packets MUST define a TEXT[!MUST,exception]: mechanism that is robust against version downgrade attacks. SECTION: [Provisional Registrations](#section-22.1.1) TEXT[!MAY,exception]: Provisional registrations MAY omit the Specification and Notes TEXT[!MAY,exception]: fields, plus any additional fields that might be required for a TEXT[!MAY,exception]: permanent registration. SECTION: [Selecting Codepoints](#section-22.1.2) TEXT[!SHOULD,exception]: New requests for codepoints from QUIC registries SHOULD use a TEXT[!SHOULD,exception]: randomly selected codepoint that excludes both existing allocations TEXT[!SHOULD,exception]: and the first unallocated codepoint in the selected space. TEXT[!MAY,exception]: Requests TEXT[!MAY,exception]: for multiple codepoints MAY use a contiguous range. TEXT[!SHOULD,exception]: For codepoints that are encoded in variable-length integers TEXT[!SHOULD,exception]: (Section 16), such as frame types, codepoints that encode to four or TEXT[!SHOULD,exception]: eight bytes (that is, values 2^14 and above) SHOULD be used unless TEXT[!SHOULD,exception]: the usage is especially sensitive to having a longer encoding. TEXT[!MAY,exception]: Applications to register codepoints in QUIC registries MAY include a TEXT[!MAY,exception]: requested codepoint as part of the registration. TEXT[!MUST,exception]: IANA MUST allocate TEXT[!MUST,exception]: the selected codepoint if the codepoint is unassigned and the TEXT[!MUST,exception]: requirements of the registration policy are met. SECTION: [Reclaiming Provisional Codepoints](#section-22.1.3) TEXT[!SHOULD,exception]: This SHOULD be done only for the TEXT[!SHOULD,exception]: codepoints with the earliest recorded date, and entries that have TEXT[!SHOULD,exception]: been updated less than a year prior SHOULD NOT be reclaimed. TEXT[!MUST,exception]: A request to remove a codepoint MUST be reviewed by the designated TEXT[!MUST,exception]: experts. TEXT[!MUST,exception]: The experts MUST attempt to determine whether the codepoint TEXT[!MUST,exception]: is still in use. TEXT[!MUST,exception]: If any use of the codepoints is identified by this search or a TEXT[!MUST,exception]: request to update the registration is made, the codepoint MUST NOT be TEXT[!MUST,exception]: reclaimed. TEXT[!MAY,exception]: If no use of the codepoint was identified and no request was made to TEXT[!MAY,exception]: update the registration, the codepoint MAY be removed from the TEXT[!MAY,exception]: registry. SECTION: [Permanent Registrations](#section-22.1.4) TEXT[!MAY,exception]: The creation of a registry TEXT[!MAY,exception]: MAY specify additional constraints on permanent registrations. TEXT[!MAY,exception]: The creation of a registry MAY identify a range of codepoints where TEXT[!MAY,exception]: registrations are governed by a different registration policy. TEXT[!MUST,exception]: All registrations made by Standards Track publications MUST be TEXT[!MUST,exception]: permanent. SECTION: [QUIC Versions Registry](#section-22.2) TEXT[!MUST,exception]: All codepoints that follow the pattern 0x?a?a?a?a are reserved, MUST TEXT[!MUST,exception]: NOT be assigned by IANA, and MUST NOT appear in the listing of TEXT[!MUST,exception]: assigned values. SECTION: [QUIC Transport Parameters Registry](#section-22.3) TEXT[!MUST,exception]: In addition to the fields listed in Section 22.1.1, permanent TEXT[!MUST,exception]: registrations in this registry MUST include the following field: TEXT[!MUST,exception]: Each value of the form "31 * N + 27" for integer values of N (that TEXT[!MUST,exception]: is, 27, 58, 89, ...) are reserved; these values MUST NOT be assigned TEXT[!MUST,exception]: by IANA and MUST NOT appear in the listing of assigned values. SECTION: [QUIC Frame Types Registry](#section-22.4) TEXT[!MUST,exception]: In addition to the fields listed in Section 22.1.1, permanent TEXT[!MUST,exception]: registrations in this registry MUST include the following field: TEXT[!SHOULD,exception]: In addition to the advice in Section 22.1, specifications for new TEXT[!SHOULD,exception]: permanent registrations SHOULD describe the means by which an TEXT[!SHOULD,exception]: endpoint might determine that it can send the identified type of TEXT[!SHOULD,exception]: frame. SECTION: [QUIC Transport Error Codes Registry](#section-22.5) TEXT[!MUST,exception]: In addition to the fields listed in Section 22.1.1, permanent TEXT[!MUST,exception]: registrations in this registry MUST include the following fields: TEXT[!MAY,exception]: Description: A brief description of the error code semantics, which TEXT[!MAY,exception]: MAY be a summary if a specification reference is provided. SPECIFICATION: https://www.rfc-editor.org/rfc/rfc9001 SECTION: [Carrying TLS Messages](#section-4) TEXT[!MUST,implementation]: If QUIC needs to retransmit that data, it MUST use TEXT[!MUST,implementation]: the same keys even if TLS has already updated to newer keys. TEXT[!SHOULD,todo]: When packets of different types need to be sent, TEXT[!SHOULD,todo]: endpoints SHOULD use coalesced packets to send them in the same UDP TEXT[!SHOULD,todo]: datagram. SECTION: [Handshake Confirmed](#section-4.1.2) TEXT[!MUST,implementation]: The server MUST send a TEXT[!MUST,implementation]: HANDSHAKE_DONE frame as soon as the handshake is complete. TEXT[!MAY,todo]: Additionally, a client MAY consider the handshake to be confirmed TEXT[!MAY,todo]: when it receives an acknowledgment for a 1-RTT packet. SECTION: [Sending and Receiving Handshake Messages](#section-4.1.3) TEXT[!MUST,todo]: * If the packet is from a previously installed encryption level, it TEXT[!MUST,todo]: MUST NOT contain data that extends past the end of previously TEXT[!MUST,todo]: received data in that flow. TEXT[!MUST,todo]: Implementations MUST treat any TEXT[!MUST,todo]: violations of this requirement as a connection error of type TEXT[!MUST,todo]: PROTOCOL_VIOLATION. TEXT[!MUST,todo]: When TLS TEXT[!MUST,todo]: provides keys for a higher encryption level, if there is data from TEXT[!MUST,todo]: a previous encryption level that TLS has not consumed, this MUST TEXT[!MUST,todo]: be treated as a connection error of type PROTOCOL_VIOLATION. TEXT[implementation]: QUIC is responsible for buffering handshake bytes that arrive TEXT[implementation]: out of order or for encryption levels that are not yet ready. SECTION: [Encryption Level Changes](#section-4.1.4) TEXT[!SHOULD,implementation]: While waiting for TLS processing to TEXT[!SHOULD,implementation]: complete, an endpoint SHOULD buffer received packets if they might be TEXT[!SHOULD,implementation]: processed using keys that are not yet available. TEXT[!SHOULD,todo]: An endpoint SHOULD TEXT[!SHOULD,todo]: continue to respond to packets that can be processed during this TEXT[!SHOULD,todo]: time. SECTION: [TLS Version](#section-4.2) TEXT[!MUST,implementation]: Clients MUST NOT offer TLS versions older than 1.3. TEXT[!MUST,implementation]: An endpoint MUST terminate the connection if a TEXT[!MUST,implementation]: version of TLS older than 1.3 is negotiated. SECTION: [ClientHello Size](#section-4.3) TEXT[!MAY,todo]: To TEXT[!MAY,todo]: avoid this, servers MAY use the Retry feature (see Section 8.1 of TEXT[!MAY,todo]: [QUIC-TRANSPORT]) to only buffer partial ClientHello messages from TEXT[!MAY,todo]: clients with a validated address. SECTION: [Peer Authentication](#section-4.4) TEXT[!MUST,implementation]: A client MUST authenticate the identity of the server. TEXT[!MAY,implementation]: A server MAY request that the client authenticate during the TEXT[!MAY,implementation]: handshake. TEXT[!MAY,implementation]: A server MAY refuse a connection if the client is unable TEXT[!MAY,implementation]: to authenticate when requested. TEXT[!MUST,todo]: A server MUST NOT use post-handshake client authentication (as TEXT[!MUST,todo]: defined in Section 4.6.2 of [TLS13]) because the multiplexing offered TEXT[!MUST,todo]: by QUIC prevents clients from correlating the certificate request TEXT[!MUST,todo]: with the application-level event that triggered it (see TEXT[!MUST,todo]: [HTTP2-TLS13]). TEXT[!MUST,todo]: More specifically, servers MUST NOT send post- TEXT[!MUST,todo]: handshake TLS CertificateRequest messages, and clients MUST treat TEXT[!MUST,todo]: receipt of such messages as a connection error of type TEXT[!MUST,todo]: PROTOCOL_VIOLATION. SECTION: [Session Resumption](#section-4.5) TEXT[!SHOULD,todo]: Clients SHOULD NOT reuse tickets as TEXT[!SHOULD,todo]: that allows entities other than the server to correlate connections; TEXT[!SHOULD,todo]: see Appendix C.4 of [TLS13]. SECTION: [Enabling 0-RTT](#section-4.6.1) TEXT[!MUST,test]: Servers MUST NOT send the early_data extension with a TEXT[!MUST,test]: max_early_data_size field set to any value other than 0xffffffff. TEXT[!MUST,todo]: client MUST treat receipt of a NewSessionTicket that contains an TEXT[!MUST,todo]: early_data extension with any other value as a connection error of TEXT[!MUST,todo]: type PROTOCOL_VIOLATION. SECTION: [Accepting and Rejecting 0-RTT](#section-4.6.2) TEXT[!MUST,todo]: When rejecting 0-RTT, a server MUST NOT TEXT[!MUST,todo]: process any 0-RTT packets, even if it could. TEXT[!SHOULD,todo]: When 0-RTT was TEXT[!SHOULD,todo]: rejected, a client SHOULD treat receipt of an acknowledgment for a TEXT[!SHOULD,todo]: 0-RTT packet as a connection error of type PROTOCOL_VIOLATION, if it TEXT[!SHOULD,todo]: is able to detect the condition. TEXT[!MUST,todo]: The client therefore MUST reset the state of all TEXT[!MUST,todo]: streams, including application state bound to those streams. TEXT[!MAY,todo]: A client MAY reattempt 0-RTT if it receives a Retry or Version TEXT[!MAY,todo]: Negotiation packet. SECTION: [HelloRetryRequest](#section-4.7) TEXT[!SHOULD,todo]: Although it is in principle possible to use this feature TEXT[!SHOULD,todo]: for address verification, QUIC implementations SHOULD instead use the TEXT[!SHOULD,todo]: Retry feature; see Section 8.1 of [QUIC-TRANSPORT]. SECTION: [TLS Errors](#section-4.8) TEXT[!MUST,implementation]: As QUIC provides TEXT[!MUST,implementation]: alternative mechanisms for connection termination and the TLS TEXT[!MUST,implementation]: connection is only closed if an error is encountered, a QUIC endpoint TEXT[!MUST,implementation]: MUST treat any alert from TLS as if it were at the "fatal" level. TEXT[!MAY,todo]: Endpoints MAY use a generic TEXT[!MAY,todo]: error code to avoid possibly exposing confidential information. SECTION: [Discarding Unused Keys](#section-4.9) TEXT[!MUST,implementation]: If packets from a lower encryption level contain TEXT[!MUST,implementation]: CRYPTO frames, frames that retransmit that data MUST be sent at the TEXT[!MUST,implementation]: same encryption level. TEXT[!MUST,todo]: Though an endpoint might retain older keys, new data MUST be sent at TEXT[!MUST,todo]: the highest currently available encryption level. TEXT[!MAY,todo]: These packets MAY also include PADDING frames. SECTION: [Discarding Initial Keys](#section-4.9.1) TEXT[!MUST,implementation]: Thus, a client MUST discard Initial keys when it first sends a TEXT[!MUST,implementation]: Handshake packet and a server MUST discard Initial keys when it first TEXT[!MUST,implementation]: successfully processes a Handshake packet. TEXT[!MUST,implementation]: Endpoints MUST NOT send TEXT[!MUST,implementation]: Initial packets after this point. SECTION: [Discarding Handshake Keys](#section-4.9.2) TEXT[!MUST,implementation,test]: An endpoint MUST discard its Handshake keys when the TLS handshake is TEXT[!MUST,implementation,test]: confirmed (Section 4.1.2). SECTION: [Discarding 0-RTT Keys](#section-4.9.3) TEXT[!SHOULD,implementation]: Therefore, a client SHOULD discard 0-RTT keys as soon as it installs TEXT[!SHOULD,implementation]: 1-RTT keys as they have no use after that moment. TEXT[!MAY,implementation]: Additionally, a server MAY discard 0-RTT keys as soon as it receives TEXT[!MAY,implementation]: a 1-RTT packet. TEXT[!MAY,implementation]: Servers MAY temporarily retain TEXT[!MAY,implementation]: 0-RTT keys to allow decrypting reordered packets without requiring TEXT[!MAY,implementation]: their contents to be retransmitted with 1-RTT keys. TEXT[!MUST,implementation]: After receiving TEXT[!MUST,implementation]: a 1-RTT packet, servers MUST discard 0-RTT keys within a short time; TEXT[!MUST,implementation]: the RECOMMENDED time period is three times the Probe Timeout (PTO, TEXT[!MUST,implementation]: see [QUIC-RECOVERY]). TEXT[!MAY,todo]: A server MAY discard 0-RTT keys earlier if it TEXT[!MAY,todo]: determines that it has received all 0-RTT packets, which can be done TEXT[!MAY,todo]: by keeping track of missing packet numbers. SECTION: [Packet Protection Keys](#section-5.1) TEXT[!MUST,todo]: Other versions of TLS MUST provide a similar function in order to be TEXT[!MUST,todo]: used with QUIC. SECTION: [Initial Secrets](#section-5.2) TEXT[!SHOULD,implementation,test]: Future versions of QUIC SHOULD generate a new salt value, thus TEXT[!SHOULD,implementation,test]: ensuring that the keys are different for each version of QUIC. TEXT[!MUST,test]: The HKDF-Expand-Label function defined in TLS 1.3 MUST be used for TEXT[!MUST,test]: Initial packets even where the TLS versions offered do not include TEXT[!MUST,test]: TLS 1.3. SECTION: [AEAD Usage](#section-5.3) TEXT[!MUST,implementation]: A cipher suite MUST NOT be TEXT[!MUST,implementation]: negotiated unless a header protection scheme is defined for the TEXT[!MUST,implementation]: cipher suite. TEXT[!MUST,todo]: An endpoint MUST NOT reject a ClientHello that offers a cipher suite TEXT[!MUST,todo]: that it does not support, or it would be impossible to deploy a new TEXT[!MUST,todo]: cipher suite. TEXT[!MUST,implementation]: An endpoint MUST initiate a key update TEXT[!MUST,implementation]: (Section 6) prior to exceeding any limit set for the AEAD that is in TEXT[!MUST,implementation]: use. SECTION: [Header Protection Application](#section-5.4.1) TEXT[!MUST,implementation]: Before a TLS cipher suite can be used with QUIC, a header protection TEXT[!MUST,implementation]: algorithm MUST be specified for the AEAD used with that cipher suite. SECTION: [Header Protection Sample](#section-5.4.2) TEXT[!MUST,test]: An endpoint MUST discard packets that are not long enough to contain TEXT[!MUST,test]: a complete sample. SECTION: [Receiving Protected Packets](#section-5.5) TEXT[!MUST,implementation]: Once an endpoint successfully receives a packet with a given packet TEXT[!MUST,implementation]: number, it MUST discard all packets in the same packet number space TEXT[!MUST,implementation]: with higher packet numbers if they cannot be successfully unprotected TEXT[!MUST,implementation]: with either the same key, or -- if there is a key update -- a TEXT[!MUST,implementation]: subsequent packet protection key; see Section 6. TEXT[!MUST,implementation]: Similarly, a packet TEXT[!MUST,implementation]: that appears to trigger a key update but cannot be unprotected TEXT[!MUST,implementation]: successfully MUST be discarded. SECTION: [Use of 0-RTT Keys](#section-5.6) TEXT[!MUST,implementation]: A client TEXT[!MUST,implementation]: therefore MUST NOT use 0-RTT for application data unless specifically TEXT[!MUST,implementation]: requested by the application that is in use. TEXT[!MUST,todo]: An application protocol that uses QUIC MUST include a profile that TEXT[!MUST,todo]: defines acceptable use of 0-RTT; otherwise, 0-RTT can only be used to TEXT[!MUST,todo]: carry QUIC frames that do not carry application data. TEXT[!MAY,todo]: A client MAY wish to apply additional restrictions on what data it TEXT[!MAY,todo]: sends prior to the completion of the TLS handshake. TEXT[!SHOULD,todo]: A client SHOULD stop sending 0-RTT data TEXT[!SHOULD,todo]: if it receives an indication that 0-RTT data has been rejected. TEXT[!MUST,implementation]: A server MUST NOT use 0-RTT keys to protect packets; it uses 1-RTT TEXT[!MUST,implementation]: keys to protect acknowledgments of 0-RTT packets. TEXT[!MUST,todo]: A client MUST NOT TEXT[!MUST,todo]: attempt to decrypt 0-RTT packets it receives and instead MUST discard TEXT[!MUST,todo]: them. TEXT[!MUST,implementation]: Once a client has installed 1-RTT keys, it MUST NOT send any more TEXT[!MUST,implementation]: 0-RTT packets. SECTION: [Receiving Out-of-Order Protected Packets](#section-5.7) TEXT[!MUST,todo]: Endpoints in either role MUST NOT decrypt 1-RTT packets from TEXT[!MUST,todo]: their peer prior to completing the handshake. TEXT[!MUST,implementation]: A server MUST NOT process TEXT[!MUST,implementation]: incoming 1-RTT protected packets before the TLS handshake is TEXT[!MUST,implementation]: complete. TEXT[!MAY,implementation]: Received TEXT[!MAY,implementation]: packets protected with 1-RTT keys MAY be stored and later decrypted TEXT[!MAY,implementation]: and used once the handshake is complete. TEXT[!MAY,todo]: The server MAY retain these packets for TEXT[!MAY,todo]: later decryption in anticipation of receiving a ClientHello. TEXT[!MUST,todo]: Even if it has 1-RTT secrets, a client MUST NOT TEXT[!MUST,todo]: process incoming 1-RTT protected packets before the TLS handshake is TEXT[!MUST,todo]: complete. SECTION: [Key Update](#section-6) TEXT[!MAY,implementation]: Once the handshake is confirmed (see Section 4.1.2), an endpoint MAY TEXT[!MAY,implementation]: initiate a key update. TEXT[!MUST,todo]: Endpoints TEXT[!MUST,todo]: MUST NOT send a TLS KeyUpdate message. TEXT[!MUST,todo]: Endpoints MUST treat the TEXT[!MUST,todo]: receipt of a TLS KeyUpdate message as a connection error of type TEXT[!MUST,todo]: 0x010a, equivalent to a fatal TLS alert of unexpected_message; see TEXT[!MUST,todo]: Section 4.8. SECTION: [Initiating a Key Update](#section-6.1) TEXT[!MUST,implementation]: An endpoint MUST NOT initiate a key update prior to having confirmed TEXT[!MUST,implementation]: the handshake (Section 4.1.2). TEXT[!MUST,implementation]: An endpoint MUST NOT initiate a TEXT[!MUST,implementation]: subsequent key update unless it has received an acknowledgment for a TEXT[!MUST,implementation]: packet that was sent protected with keys from the current key phase. TEXT[!MUST,implementation]: An endpoint MUST retain old keys until it has successfully TEXT[!MUST,implementation]: unprotected a packet sent using the new keys. TEXT[!SHOULD,implementation]: An endpoint SHOULD TEXT[!SHOULD,implementation]: retain old keys for some time after unprotecting a packet sent using TEXT[!SHOULD,implementation]: the new keys. SECTION: [Responding to a Key Update](#section-6.2) TEXT[!MUST,implementation]: The endpoint MUST update its TEXT[!MUST,implementation]: send keys to the corresponding key phase in response, as described in TEXT[!MUST,implementation]: Section 6.1. TEXT[!MUST,implementation]: Sending keys MUST be updated before sending an TEXT[!MUST,implementation]: acknowledgment for the packet that was received with updated keys. TEXT[!MAY,implementation]: An endpoint TEXT[!MAY,implementation]: MAY treat such consecutive key updates as a connection error of type TEXT[!MAY,implementation]: KEY_UPDATE_ERROR. TEXT[!MAY,implementation]: An endpoint that receives an acknowledgment that is carried in a TEXT[!MAY,implementation]: packet protected with old keys where any acknowledged packet was TEXT[!MAY,implementation]: protected with newer keys MAY treat that as a connection error of TEXT[!MAY,implementation]: type KEY_UPDATE_ERROR. SECTION: [Timing of Receive Key Generation](#section-6.3) TEXT[!MUST,todo]: Endpoints responding to an apparent key update MUST NOT generate a TEXT[!MUST,todo]: timing side-channel signal that might indicate that the Key Phase bit TEXT[!MUST,todo]: was invalid (see Section 9.5). TEXT[!MAY,implementation]: An endpoint MAY TEXT[!MAY,implementation]: generate new keys as part of packet processing, but this creates a TEXT[!MAY,implementation]: timing signal that could be used by an attacker to learn when key TEXT[!MAY,implementation]: updates happen and thus leak the value of the Key Phase bit. TEXT[!MAY,todo]: For a short period after a key TEXT[!MAY,todo]: update completes, up to the PTO, endpoints MAY defer generation of TEXT[!MAY,todo]: the next set of receive packet protection keys. TEXT[!SHOULD,implementation]: Once generated, the next set of packet protection keys SHOULD be TEXT[!SHOULD,implementation]: retained, even if the packet that was received was subsequently TEXT[!SHOULD,implementation]: discarded. TEXT[!MUST,implementation]: For this reason, endpoints MUST be able to retain two sets of packet TEXT[!MUST,implementation]: protection keys for receiving packets: the current and the next. SECTION: [Sending with Updated Keys](#section-6.4) TEXT[!MUST,todo]: Packets with higher packet numbers MUST be protected with either the TEXT[!MUST,todo]: same or newer packet protection keys than packets with lower packet TEXT[!MUST,todo]: numbers. TEXT[!MUST,todo]: An endpoint that successfully removes protection with old TEXT[!MUST,todo]: keys when newer keys were used for packets with lower packet numbers TEXT[!MUST,todo]: MUST treat this as a connection error of type KEY_UPDATE_ERROR. SECTION: [Receiving with Different Keys](#section-6.5) TEXT[!MAY,todo]: An endpoint MAY allow a period of approximately the Probe Timeout TEXT[!MAY,todo]: (PTO; see [QUIC-RECOVERY]) after promoting the next set of receive TEXT[!MAY,todo]: keys to be current before it creates the subsequent set of packet TEXT[!MAY,todo]: protection keys. TEXT[!MAY,todo]: These updated keys MAY replace the previous keys at TEXT[!MAY,todo]: that time. TEXT[!SHOULD,implementation]: Endpoints SHOULD wait three times TEXT[!SHOULD,implementation]: the PTO before initiating a key update after receiving an TEXT[!SHOULD,implementation]: acknowledgment that confirms that the previous key update was TEXT[!SHOULD,implementation]: received. TEXT[!SHOULD,implementation]: An endpoint SHOULD retain old read keys for no more than three times TEXT[!SHOULD,implementation]: the PTO after having received a packet protected using the new keys. TEXT[!SHOULD,implementation]: After this period, old read keys and their corresponding secrets TEXT[!SHOULD,implementation]: SHOULD be discarded. SECTION: [Limits on AEAD Usage](#section-6.6) TEXT[!MUST,implementation]: Endpoints MUST count the number of encrypted packets for each set of TEXT[!MUST,implementation]: keys. TEXT[!MUST,implementation]: If the total number of encrypted packets with the same key TEXT[!MUST,implementation]: exceeds the confidentiality limit for the selected AEAD, the endpoint TEXT[!MUST,implementation]: MUST stop using those keys. TEXT[!MUST,implementation]: Endpoints MUST initiate a key update TEXT[!MUST,implementation]: before sending more protected packets than the confidentiality limit TEXT[!MUST,implementation]: for the selected AEAD permits. TEXT[!MUST,implementation]: If a key update is not possible or TEXT[!MUST,implementation]: integrity limits are reached, the endpoint MUST stop using the TEXT[!MUST,implementation]: connection and only send stateless resets in response to receiving TEXT[!MUST,implementation]: packets. TEXT[!SHOULD,implementation]: It is RECOMMENDED that endpoints immediately close the TEXT[!SHOULD,implementation]: connection with a connection error of type AEAD_LIMIT_REACHED before TEXT[!SHOULD,implementation]: reaching a state where key updates are not possible. TEXT[!MUST,implementation]: In addition to counting packets sent, endpoints MUST count the number TEXT[!MUST,implementation]: of received packets that fail authentication during the lifetime of a TEXT[!MUST,implementation]: connection. TEXT[!MUST,implementation]: If the total number of received packets that fail TEXT[!MUST,implementation]: authentication within the connection, across all keys, exceeds the TEXT[!MUST,implementation]: integrity limit for the selected AEAD, the endpoint MUST immediately TEXT[!MUST,implementation]: close the connection with a connection error of type TEXT[!MUST,implementation]: AEAD_LIMIT_REACHED and not process any more packets. TEXT[!MAY,todo]: Endpoints that limit the size of packets MAY use higher TEXT[!MAY,todo]: confidentiality and integrity limits; see Appendix B for details. TEXT[!MAY,todo]: Future analyses and specifications MAY relax confidentiality or TEXT[!MAY,todo]: integrity limits for an AEAD. TEXT[!MUST,implementation]: Any TLS cipher suite that is specified for use with QUIC MUST define TEXT[!MUST,implementation]: limits on the use of the associated AEAD function that preserves TEXT[!MUST,implementation]: margins for confidentiality and integrity. TEXT[!MUST,implementation]: That is, limits MUST be TEXT[!MUST,implementation]: specified for the number of packets that can be authenticated and for TEXT[!MUST,implementation]: the number of packets that can fail authentication. SECTION: [Security of Initial Messages](#section-7) TEXT[!SHOULD,todo]: Implementations TEXT[!SHOULD,todo]: SHOULD use caution in relying on any data that is contained in TEXT[!SHOULD,todo]: Initial packets that is not otherwise authenticated. SECTION: [Protocol Negotiation](#section-8.1) TEXT[!MUST,implementation]: Unless another TEXT[!MUST,implementation]: mechanism is used for agreeing on an application protocol, endpoints TEXT[!MUST,implementation]: MUST use ALPN for this purpose. TEXT[!MUST,implementation]: When using ALPN, endpoints MUST immediately close a connection (see TEXT[!MUST,implementation]: Section 10.2 of [QUIC-TRANSPORT]) with a no_application_protocol TLS TEXT[!MUST,implementation]: alert (QUIC error code 0x0178; see Section 4.8) if an application TEXT[!MUST,implementation]: protocol is not negotiated. TEXT[!MUST,todo]: While [ALPN] only specifies that servers TEXT[!MUST,todo]: use this alert, QUIC clients MUST use error 0x0178 to terminate a TEXT[!MUST,todo]: connection when ALPN negotiation fails. TEXT[!MAY,todo]: An application protocol MAY restrict the QUIC versions that it can TEXT[!MAY,todo]: operate over. TEXT[!MUST,implementation]: Servers MUST select an application protocol compatible TEXT[!MUST,implementation]: with the QUIC version that the client has selected. TEXT[!MUST,implementation]: The server MUST TEXT[!MUST,implementation]: treat the inability to select a compatible application protocol as a TEXT[!MUST,implementation]: connection error of type 0x0178 (no_application_protocol). TEXT[!MUST,todo]: Similarly, a client MUST treat the selection of an incompatible TEXT[!MUST,todo]: application protocol by a server as a connection error of type TEXT[!MUST,todo]: 0x0178. SECTION: [QUIC Transport Parameters Extension](#section-8.2) TEXT[test]: The quic_transport_parameters extension is carried in the ClientHello TEXT[test]: and the EncryptedExtensions messages during the handshake. TEXT[!MUST,implementation]: Endpoints TEXT[!MUST,implementation]: MUST send the quic_transport_parameters extension; endpoints that TEXT[!MUST,implementation]: receive ClientHello or EncryptedExtensions messages without the TEXT[!MUST,implementation]: quic_transport_parameters extension MUST close the connection with an TEXT[!MUST,implementation]: error of type 0x016d (equivalent to a fatal TLS missing_extension TEXT[!MUST,implementation]: alert, see Section 4.8). TEXT[!MUST,implementation]: Endpoints MUST NOT send this extension in a TLS connection that does TEXT[!MUST,implementation]: not use QUIC (such as the use of TLS with TCP defined in [TLS13]). TEXT[!MUST,todo]: fatal unsupported_extension alert MUST be sent by an implementation TEXT[!MUST,todo]: that supports this extension if the extension is received when the TEXT[!MUST,todo]: transport is not QUIC. SECTION: [Removing the EndOfEarlyData Message](#section-8.3) TEXT[!MUST,todo]: Clients MUST NOT send the EndOfEarlyData message. TEXT[!MUST,implementation]: A server MUST TEXT[!MUST,implementation]: treat receipt of a CRYPTO frame in a 0-RTT packet as a connection TEXT[!MUST,implementation]: error of type PROTOCOL_VIOLATION. SECTION: [Prohibit TLS Middlebox Compatibility Mode](#section-8.4) TEXT[!MUST,todo]: A client MUST NOT request the use of the TEXT[!MUST,todo]: TLS 1.3 compatibility mode. TEXT[!SHOULD,todo]: A server SHOULD treat the receipt of a TEXT[!SHOULD,todo]: TLS ClientHello with a non-empty legacy_session_id field as a TEXT[!SHOULD,todo]: connection error of type PROTOCOL_VIOLATION. SECTION: [Replay Attacks with 0-RTT](#section-9.2) TEXT[!MUST,todo]: Endpoints MUST implement and use the replay protections described in TEXT[!MUST,todo]: [TLS13], however it is recognized that these protections are TEXT[!MUST,todo]: imperfect. TEXT[!MUST,todo]: These MUST NOT be TEXT[!MUST,todo]: used to communicate application semantics between endpoints; clients TEXT[!MUST,todo]: MUST treat them as opaque values. TEXT[!MUST,todo]: An application TEXT[!MUST,todo]: protocol that uses QUIC MUST describe how the protocol uses 0-RTT and TEXT[!MUST,todo]: the measures that are employed to protect against replay attack. TEXT[!MUST,todo]: QUIC extensions MUST either describe how replay attacks affect their TEXT[!MUST,todo]: operation or prohibit the use of the extension in 0-RTT. TEXT[!MUST,todo]: Application TEXT[!MUST,todo]: protocols MUST either prohibit the use of extensions that carry TEXT[!MUST,todo]: application semantics in 0-RTT or provide replay mitigation TEXT[!MUST,todo]: strategies. SECTION: [Packet Reflection Attack Mitigation](#section-9.3) TEXT[!MUST,todo]: First, the packet TEXT[!MUST,todo]: containing a ClientHello MUST be padded to a minimum size. SECTION: [Header Protection Analysis](#section-9.4) TEXT[!MUST,todo]: Future header protection variants based on this construction MUST use TEXT[!MUST,todo]: a PRF to ensure equivalent security guarantees. SECTION: [Header Protection Timing Side Channels](#section-9.5) TEXT[!MUST,todo]: For authentication to be TEXT[!MUST,todo]: free from side channels, the entire process of header protection TEXT[!MUST,todo]: removal, packet number recovery, and packet protection removal MUST TEXT[!MUST,todo]: be applied together without timing and other side channels. TEXT[!MUST,todo]: For the sending of packets, construction and protection of packet TEXT[!MUST,todo]: payloads and packet numbers MUST be free from side channels that TEXT[!MUST,todo]: would reveal the packet number or its encoded size. TEXT[!SHOULD,implementation]: After TEXT[!SHOULD,implementation]: receiving a key update, an endpoint SHOULD generate and save the next TEXT[!SHOULD,implementation]: set of receive packet protection keys, as described in Section 6.3. SECTION: [Key Diversity](#section-9.6) TEXT[!SHOULD,todo]: To preserve this separation, TEXT[!SHOULD,implementation,test,todo]: a new version of QUIC SHOULD define new TEXT[!SHOULD,implementation,test,todo]: labels for key derivation for packet protection key and IV, plus the TEXT[!SHOULD,implementation,test,todo]: header protection keys. TEXT[!SHOULD,implementation]: New QUIC versions SHOULD define a new salt value used in TEXT[!SHOULD,implementation]: calculating initial secrets. SPECIFICATION: https://www.rfc-editor.org/rfc/rfc9002 SECTION: [Generating RTT Samples](#section-5.1) TEXT[implementation]: An endpoint generates an RTT sample on receiving an ACK frame that TEXT[implementation]: meets the following two conditions: TEXT[implementation]: The RTT sample, latest_rtt, is generated as the time elapsed since TEXT[implementation]: the largest acknowledged packet was sent: TEXT[!SHOULD,implementation]: To avoid generating multiple RTT samples for a single packet, an ACK TEXT[!SHOULD,implementation]: frame SHOULD NOT be used to update RTT estimates if it does not newly TEXT[!SHOULD,implementation]: acknowledge the largest acknowledged packet. TEXT[!MUST,implementation]: An RTT sample MUST NOT be generated on receiving an ACK frame that TEXT[!MUST,implementation]: does not newly acknowledge at least one ack-eliciting packet. SECTION: [Estimating min_rtt](#section-5.2) TEXT[!MUST,implementation,test]: min_rtt MUST be set to the latest_rtt on the first RTT sample. TEXT[!MUST,implementation]: min_rtt MUST be set to the lesser of min_rtt and latest_rtt TEXT[!MUST,implementation]: (Section 5.1) on all other samples. TEXT[!SHOULD,todo]: Endpoints SHOULD set the min_rtt to the newest RTT sample after TEXT[!SHOULD,todo]: persistent congestion is established. TEXT[!MAY,todo]: Endpoints MAY reestablish the min_rtt at other times in the TEXT[!MAY,todo]: connection, such as when traffic volume is low and an acknowledgment TEXT[!MAY,todo]: is received with a low acknowledgment delay. TEXT[!SHOULD,implementation]: Implementations SHOULD TEXT[!SHOULD,implementation]: NOT refresh the min_rtt value too often since the actual minimum RTT TEXT[!SHOULD,implementation]: of the path is not frequently observable. SECTION: [Estimating smoothed_rtt and rttvar](#section-5.3) TEXT[!SHOULD,implementation]: To account for this, the endpoint SHOULD ignore TEXT[!SHOULD,implementation]: max_ack_delay until the handshake is confirmed, as defined in TEXT[!SHOULD,implementation]: Section 4.1.2 of [QUIC-TLS]. TEXT[!MAY,todo]: Therefore, prior to handshake confirmation, an endpoint TEXT[!MAY,todo]: MAY ignore RTT samples if adjusting the RTT sample for acknowledgment TEXT[!MAY,todo]: delay causes the sample to be less than the min_rtt. TEXT[!MAY,todo]: * MAY ignore the acknowledgment delay for Initial packets, since TEXT[!MAY,todo]: these acknowledgments are not delayed by the peer (Section 13.2.1 TEXT[!MAY,todo]: of [QUIC-TRANSPORT]); TEXT[!SHOULD,implementation]: * SHOULD ignore the peer's max_ack_delay until the handshake is TEXT[!SHOULD,implementation]: confirmed; TEXT[!MUST,implementation]: * MUST use the lesser of the acknowledgment delay and the peer's TEXT[!MUST,implementation]: max_ack_delay after the handshake is confirmed; and TEXT[!MUST,implementation]: * MUST NOT subtract the acknowledgment delay from the RTT sample if TEXT[!MUST,implementation]: the resulting value is smaller than the min_rtt. TEXT[!SHOULD,todo]: In such TEXT[!SHOULD,todo]: cases, an endpoint SHOULD subtract such local delays from its RTT TEXT[!SHOULD,todo]: sample until the handshake is confirmed. SECTION: [Acknowledgment-Based Detection](#section-6.1) TEXT[implementation]: A packet is declared lost if it meets all of the following TEXT[implementation]: conditions: TEXT[!MAY,implementation]: Implementations with adaptive time TEXT[!MAY,implementation]: thresholds MAY choose to start with smaller initial reordering TEXT[!MAY,implementation]: thresholds to minimize recovery latency. SECTION: [Packet Threshold](#section-6.1.1) TEXT[!SHOULD,implementation]: The RECOMMENDED initial value for the packet reordering threshold TEXT[!SHOULD,implementation]: (kPacketThreshold) is 3, based on best practices for TCP loss TEXT[!SHOULD,implementation]: detection [RFC5681] [RFC6675]. TEXT[!SHOULD,implementation]: In order to remain similar to TCP, TEXT[!SHOULD,implementation]: implementations SHOULD NOT use a packet threshold less than 3; see TEXT[!SHOULD,implementation]: [RFC5681]. SECTION: [Time Threshold](#section-6.1.2) TEXT[!SHOULD,implementation]: Once a later packet within the same packet number space has been TEXT[!SHOULD,implementation]: acknowledged, an endpoint SHOULD declare an earlier packet lost if it TEXT[!SHOULD,implementation]: was sent a threshold amount of time in the past. TEXT[!MUST,implementation]: To avoid declaring TEXT[!MUST,implementation]: packets as lost too early, this time threshold MUST be set to at TEXT[!MUST,implementation]: least the local timer granularity, as indicated by the kGranularity TEXT[!MUST,implementation]: constant. TEXT[implementation]: The time threshold is: TEXT[implementation]: max(kTimeThreshold * max(smoothed_rtt, latest_rtt), kGranularity) TEXT[!SHOULD,implementation]: If packets sent prior to the largest acknowledged packet cannot yet TEXT[!SHOULD,implementation]: be declared lost, then a timer SHOULD be set for the remaining time. TEXT[!SHOULD,implementation]: The RECOMMENDED time threshold (kTimeThreshold), expressed as an RTT TEXT[!SHOULD,implementation]: multiplier, is 9/8. TEXT[!SHOULD,implementation]: The RECOMMENDED value of the timer granularity TEXT[!SHOULD,implementation]: (kGranularity) is 1 millisecond. TEXT[!MAY,implementation]: Implementations MAY experiment with absolute thresholds, thresholds TEXT[!MAY,implementation]: from previous connections, adaptive thresholds, or the including of TEXT[!MAY,implementation]: RTT variation. SECTION: [Probe Timeout](#section-6.2) TEXT[!MUST,todo]: A PTO timer expiration event does not indicate packet loss and MUST TEXT[!MUST,todo]: NOT cause prior unacknowledged packets to be marked as lost. SECTION: [Computing PTO](#section-6.2.1) TEXT[implementation]: PTO = smoothed_rtt + max(4*rttvar, kGranularity) + max_ack_delay TEXT[implementation]: When the PTO is armed for Initial or Handshake packet number spaces, TEXT[implementation]: the max_ack_delay in the PTO period computation is set to 0 TEXT[!MUST,implementation]: The PTO period MUST be at least kGranularity to avoid the timer TEXT[!MUST,implementation]: expiring immediately. TEXT[!MUST,implementation]: When ack-eliciting packets in multiple packet number spaces are in TEXT[!MUST,implementation]: flight, the timer MUST be set to the earlier value of the Initial and TEXT[!MUST,implementation]: Handshake packet number spaces. TEXT[!MUST,implementation]: An endpoint MUST NOT set its PTO timer for the Application Data TEXT[!MUST,implementation]: packet number space until the handshake is confirmed. TEXT[!SHOULD,todo]: A sender SHOULD restart its PTO timer every time an ack-eliciting TEXT[!SHOULD,todo]: packet is sent or acknowledged, or when Initial or Handshake keys are TEXT[!SHOULD,todo]: discarded (Section 4.9 of [QUIC-TLS]). TEXT[!MUST,implementation]: When a PTO timer expires, the PTO backoff MUST be increased, TEXT[!MUST,implementation]: resulting in the PTO period being set to twice its current value. TEXT[!MUST,implementation]: The PTO timer MUST NOT be set if a timer is set for time threshold TEXT[!MUST,implementation]: loss detection; see Section 6.1.2. SECTION: [Handshakes and New Paths](#section-6.2.2) TEXT[!MAY,todo]: Resumed connections over the same network MAY use the previous TEXT[!MAY,todo]: connection's final smoothed RTT value as the resumed connection's TEXT[!MAY,todo]: initial RTT. TEXT[!SHOULD,implementation,test]: When no previous RTT is available, the initial RTT TEXT[!SHOULD,implementation,test]: SHOULD be set to 333 milliseconds. TEXT[!SHOULD,todo]: A connection MAY use the delay between sending a PATH_CHALLENGE and TEXT[!SHOULD,todo]: receiving a PATH_RESPONSE to set the initial RTT (see kInitialRtt in TEXT[!SHOULD,todo]: Appendix A.2) for a new path, but the delay SHOULD NOT be considered TEXT[!SHOULD,todo]: an RTT sample. TEXT[!MUST,implementation]: When TEXT[!MUST,implementation]: Initial or Handshake keys are discarded, the PTO and loss detection TEXT[!MUST,implementation]: timers MUST be reset, because discarding keys indicates forward TEXT[!MUST,implementation]: progress and the loss detection timer might have been set for a now- TEXT[!MUST,implementation]: discarded packet number space. SECTION: [Before Address Validation](#section-6.2.2.1) TEXT[!MUST,implementation]: If TEXT[!MUST,implementation]: no additional data can be sent, the server's PTO timer MUST NOT be TEXT[!MUST,implementation]: armed until datagrams have been received from the client because TEXT[!MUST,implementation]: packets sent on PTO count against the anti-amplification limit. TEXT[!MUST,todo]: That is, TEXT[!MUST,todo]: the client MUST set the PTO timer if the client has not received an TEXT[!MUST,todo]: acknowledgment for any of its Handshake packets and the handshake is TEXT[!MUST,todo]: not confirmed (see Section 4.1.2 of [QUIC-TLS]), even if there are no TEXT[!MUST,todo]: packets in flight. TEXT[!MUST,implementation]: When the PTO fires, the client MUST send a TEXT[!MUST,implementation]: Handshake packet if it has Handshake keys, otherwise it MUST send an TEXT[!MUST,implementation]: Initial packet in a UDP datagram with a payload of at least 1200 TEXT[!MUST,implementation]: bytes. SECTION: [Speeding up Handshake Completion](#section-6.2.3) TEXT[!MAY,todo]: To speed up handshake completion under these conditions, an endpoint TEXT[!MAY,todo]: MAY, for a limited number of times per connection, send a packet TEXT[!MAY,todo]: containing unacknowledged CRYPTO data earlier than the PTO expiry, TEXT[!MAY,todo]: subject to the address validation limits in Section 8.1 of TEXT[!MAY,todo]: [QUIC-TRANSPORT]. SECTION: [Sending Probe Packets](#section-6.2.4) TEXT[!MUST,implementation]: When a PTO timer expires, a sender MUST send at least one ack- TEXT[!MUST,implementation]: eliciting packet in the packet number space as a probe. TEXT[!MAY,implementation]: An endpoint TEXT[!MAY,implementation]: MAY send up to two full-sized datagrams containing ack-eliciting TEXT[!MAY,implementation]: packets to avoid an expensive consecutive PTO expiration due to a TEXT[!MAY,implementation]: single lost datagram or to transmit data from multiple packet number TEXT[!MAY,implementation]: spaces. TEXT[!MUST,test,todo]: All probe packets sent on a PTO MUST be ack-eliciting. TEXT[!SHOULD,implementation]: In addition to sending data in the packet number space for which the TEXT[!SHOULD,implementation]: timer expired, the sender SHOULD send ack-eliciting packets from TEXT[!SHOULD,implementation]: other packet number spaces with in-flight data, coalescing packets if TEXT[!SHOULD,implementation]: possible. TEXT[!SHOULD,todo]: An endpoint SHOULD include new data in packets that are sent on PTO TEXT[!SHOULD,todo]: expiration. TEXT[!MAY,implementation]: Previously sent data MAY be sent if no new data can be TEXT[!MAY,implementation]: sent. TEXT[!MAY,todo]: Implementations MAY use alternative strategies for determining TEXT[!MAY,todo]: the content of probe packets, including sending new or retransmitted TEXT[!MAY,todo]: data based on the application's priorities. TEXT[!SHOULD,implementation,test]: When there is no data to send, the sender SHOULD send TEXT[!SHOULD,implementation,test]: a PING or other ack-eliciting frame in a single packet, rearming the TEXT[!SHOULD,implementation,test]: PTO timer. TEXT[!MAY,todo]: Alternatively, instead of sending an ack-eliciting packet, the sender TEXT[!MAY,todo]: MAY mark any packets still in flight as lost. SECTION: [Handling Retry Packets](#section-6.3) TEXT[!MAY,todo]: The client MAY compute an RTT estimate to the server as the time TEXT[!MAY,todo]: period from when the first Initial packet was sent to when a Retry or TEXT[!MAY,todo]: a Version Negotiation packet is received. TEXT[!MAY,todo]: The client MAY use this TEXT[!MAY,todo]: value in place of its default for the initial RTT estimate. SECTION: [Discarding Keys and Packet State](#section-6.4) TEXT[!MUST,implementation]: The sender MUST discard all recovery state TEXT[!MUST,implementation]: associated with those packets and MUST remove them from the count of TEXT[!MUST,implementation]: bytes in flight. SECTION: [Congestion Control](#section-7) TEXT[!MUST,todo]: If a sender uses a different controller than that specified in this TEXT[!MUST,todo]: document, the chosen controller MUST conform to the congestion TEXT[!MUST,todo]: control guidelines specified in Section 3.1 of [RFC8085]. TEXT[implementation]: Similar to TCP, packets containing only ACK frames do not count TEXT[implementation]: toward bytes in flight and are not congestion controlled. TEXT[!MAY,todo]: Unlike TEXT[!MAY,todo]: TCP, QUIC can detect the loss of these packets and MAY use that TEXT[!MAY,todo]: information to adjust the congestion controller or the rate of ACK- TEXT[!MAY,todo]: only packets being sent, but this document does not describe a TEXT[!MAY,todo]: mechanism for doing so. TEXT[!MUST,implementation]: An endpoint MUST NOT send a packet if it would cause bytes_in_flight TEXT[!MUST,implementation]: (see Appendix B.2) to be larger than the congestion window, unless TEXT[!MUST,implementation]: the packet is sent on a PTO timer expiration (see Section 6.2) or TEXT[!MUST,implementation]: when entering recovery (see Section 7.3.2). SECTION: [Initial and Minimum Congestion Window](#section-7.2) TEXT[!SHOULD,implementation]: Endpoints SHOULD use an initial congestion TEXT[!SHOULD,implementation]: window of ten times the maximum datagram size (max_datagram_size), TEXT[!SHOULD,implementation]: while limiting the window to the larger of 14,720 bytes or twice the TEXT[!SHOULD,implementation]: maximum datagram size. TEXT[!SHOULD,todo]: If the maximum datagram size changes during the connection, the TEXT[!SHOULD,todo]: initial congestion window SHOULD be recalculated with the new size. TEXT[!SHOULD,todo]: If the maximum datagram size is decreased in order to complete the TEXT[!SHOULD,todo]: handshake, the congestion window SHOULD be set to the new initial TEXT[!SHOULD,todo]: congestion window. TEXT[!SHOULD,implementation]: The RECOMMENDED TEXT[!SHOULD,implementation]: value is 2 * max_datagram_size. SECTION: [Slow Start](#section-7.3.1) TEXT[implementation]: While a sender is in slow start, the congestion window increases by TEXT[implementation]: the number of bytes acknowledged when each acknowledgment is TEXT[implementation]: processed. TEXT[!MUST,implementation]: The sender MUST exit slow start and enter a recovery period when a TEXT[!MUST,implementation]: packet is lost or when the ECN-CE count reported by its peer TEXT[!MUST,implementation]: increases. SECTION: [Recovery](#section-7.3.2) TEXT[implementation]: sender that is already in a recovery period stays in it and does not TEXT[implementation]: reenter it. TEXT[!MUST,implementation]: On entering a recovery period, a sender MUST set the slow start TEXT[!MUST,implementation]: threshold to half the value of the congestion window when loss is TEXT[!MUST,implementation]: detected. TEXT[!MUST,implementation]: The congestion window MUST be set to the reduced value of TEXT[!MUST,implementation]: the slow start threshold before exiting the recovery period. TEXT[!MAY,implementation]: Implementations MAY reduce the congestion window immediately upon TEXT[!MAY,implementation]: entering a recovery period or use other mechanisms, such as TEXT[!MAY,implementation]: Proportional Rate Reduction [PRR], to reduce the congestion window TEXT[!MAY,implementation]: more gradually. SECTION: [Congestion Avoidance](#section-7.3.3) TEXT[!MUST,implementation]: A sender in congestion avoidance uses an Additive Increase TEXT[!MUST,implementation]: Multiplicative Decrease (AIMD) approach that MUST limit the increase TEXT[!MUST,implementation]: to the congestion window to at most one maximum datagram size for TEXT[!MUST,implementation]: each congestion window that is acknowledged. SECTION: [Ignoring Loss of Undecryptable Packets](#section-7.4) TEXT[!MAY,todo]: Endpoints MAY ignore the TEXT[!MAY,todo]: loss of Handshake, 0-RTT, and 1-RTT packets that might have arrived TEXT[!MAY,todo]: before the peer had packet protection keys to process those packets. TEXT[!MUST,todo]: Endpoints MUST NOT ignore the loss of packets that were sent after TEXT[!MUST,todo]: the earliest acknowledged packet in a given packet number space. SECTION: [Probe Timeout](#section-7.5) TEXT[!MUST,implementation]: Probe packets MUST NOT be blocked by the congestion controller. TEXT[!MUST,implementation]: sender MUST however count these packets as being additionally in TEXT[!MUST,implementation]: flight, since these packets add network load without establishing TEXT[!MUST,implementation]: packet loss. SECTION: [Duration](#section-7.6.1) TEXT[!SHOULD,implementation]: The RECOMMENDED value for kPersistentCongestionThreshold is 3, which TEXT[!SHOULD,implementation]: results in behavior that is approximately equivalent to a TCP sender TEXT[!SHOULD,implementation]: declaring an RTO after two TLPs. SECTION: [Establishing Persistent Congestion](#section-7.6.2) TEXT[!MUST,implementation]: These two packets MUST be ack-eliciting, since a receiver is required TEXT[!MUST,implementation]: to acknowledge only ack-eliciting packets within its maximum TEXT[!MUST,implementation]: acknowledgment delay; see Section 13.2 of [QUIC-TRANSPORT]. TEXT[!SHOULD,implementation]: The persistent congestion period SHOULD NOT start until there is at TEXT[!SHOULD,implementation]: least one RTT sample. TEXT[!SHOULD,todo]: Since network congestion is not affected by packet number spaces, TEXT[!SHOULD,todo]: persistent congestion SHOULD consider packets sent across packet TEXT[!SHOULD,todo]: number spaces. TEXT[!MAY,todo]: A sender that does not have state for all packet TEXT[!MAY,todo]: number spaces or an implementation that cannot compare send times TEXT[!MAY,todo]: across packet number spaces MAY use state for just the packet number TEXT[!MAY,todo]: space that was acknowledged. TEXT[!MUST,implementation]: When persistent congestion is declared, the sender's congestion TEXT[!MUST,implementation]: window MUST be reduced to the minimum congestion window TEXT[!MUST,implementation]: (kMinimumWindow), similar to a TCP sender's response on an RTO TEXT[!MUST,implementation]: [RFC5681]. SECTION: [Pacing](#section-7.7) TEXT[!SHOULD,implementation]: A sender SHOULD pace sending of all in-flight packets based on input TEXT[!SHOULD,implementation]: from the congestion controller. TEXT[!MUST,implementation]: Senders MUST either use pacing or limit such bursts. TEXT[!SHOULD,implementation]: Senders SHOULD limit bursts to the initial congestion window; see TEXT[!SHOULD,implementation]: Section 7.2. TEXT[!MAY,todo]: A sender with knowledge that the network path to the TEXT[!MAY,todo]: receiver can absorb larger bursts MAY use a higher limit. TEXT[!SHOULD,implementation]: To avoid delaying their delivery to the peer, packets TEXT[!SHOULD,implementation]: containing only ACK frames SHOULD therefore not be paced. SECTION: [Underutilizing the Congestion Window](#section-7.8) TEXT[!SHOULD,todo]: When this occurs, the congestion window TEXT[!SHOULD,todo]: SHOULD NOT be increased in either slow start or congestion avoidance. TEXT[!SHOULD,todo]: A sender SHOULD NOT consider itself application limited if it TEXT[!SHOULD,todo]: would have fully utilized the congestion window without pacing delay. TEXT[!MAY,todo]: A sender MAY implement alternative mechanisms to update its TEXT[!MAY,todo]: congestion window after periods of underutilization, such as those TEXT[!MAY,todo]: proposed for TCP in [RFC7661]. SPECIFICATION: https://www.rfc-editor.org/rfc/rfc9114 SECTION: [Discovering an HTTP/3 Endpoint](#section-3.1) TEXT[!MUST,todo]: Upon receiving a TEXT[!MUST,todo]: server certificate in the TLS handshake, the client MUST verify that TEXT[!MUST,todo]: the certificate is an acceptable match for the URI's origin server TEXT[!MUST,todo]: using the process described in Section 4.3.4 of [HTTP]. TEXT[!MUST,todo]: If the TEXT[!MUST,todo]: certificate cannot be verified with respect to the URI's origin TEXT[!MUST,todo]: server, the client MUST NOT consider the server authoritative for TEXT[!MUST,todo]: that origin. TEXT[!MAY,todo]: A client MAY attempt access to a resource with an "https" URI by TEXT[!MAY,todo]: resolving the host identifier to an IP address, establishing a QUIC TEXT[!MAY,todo]: connection to that address on the indicated port (including TEXT[!MAY,todo]: validation of the server certificate as described above), and sending TEXT[!MAY,todo]: an HTTP/3 request message targeting the URI to the server over that TEXT[!MAY,todo]: secured connection. TEXT[!SHOULD,todo]: Connectivity problems (e.g., blocking UDP) can result in a failure to TEXT[!SHOULD,todo]: establish a QUIC connection; clients SHOULD attempt to use TCP-based TEXT[!SHOULD,todo]: versions of HTTP in this case. TEXT[!MAY,todo]: Servers MAY serve HTTP/3 on any UDP port; an alternative service TEXT[!MAY,todo]: advertisement always includes an explicit port, and URIs contain TEXT[!MAY,todo]: either an explicit port or a default port associated with the scheme. SECTION: [HTTP Alternative Services](#section-3.1.1) TEXT[!MAY,todo]: On receipt of an Alt-Svc record indicating HTTP/3 support, a client TEXT[!MAY,todo]: MAY attempt to establish a QUIC connection to the indicated host and TEXT[!MAY,todo]: port; if this connection is successful, the client can send HTTP TEXT[!MAY,todo]: requests using the mapping described in this document. SECTION: [Other Schemes](#section-3.1.2) TEXT[!MUST,todo]: Prior to making requests for an origin whose scheme is not "https", TEXT[!MUST,todo]: the client MUST ensure the server is willing to serve that scheme. SECTION: [Connection Establishment](#section-3.2) TEXT[!MAY,todo]: The use TEXT[!MAY,todo]: of other QUIC transport versions with HTTP/3 MAY be defined by future TEXT[!MAY,todo]: specifications. TEXT[!MUST,todo]: HTTP/3 clients MUST support a mechanism to indicate the TEXT[!MUST,todo]: target host to the server during the TLS handshake. TEXT[!MUST,todo]: If the server is TEXT[!MUST,todo]: identified by a domain name ([DNS-TERMS]), clients MUST send the TEXT[!MUST,todo]: Server Name Indication (SNI; [RFC6066]) TLS extension unless an TEXT[!MUST,todo]: alternative mechanism to indicate the target host is used. TEXT[!MAY,todo]: Support for TEXT[!MAY,todo]: other application-layer protocols MAY be offered in the same TEXT[!MAY,todo]: handshake. TEXT[!MUST,implementation]: After the QUIC connection is TEXT[!MUST,implementation]: established, a SETTINGS frame MUST be sent by each endpoint as the TEXT[!MUST,implementation]: initial frame of their respective HTTP control stream. SECTION: [Connection Reuse](#section-3.3) TEXT[!MAY,todo]: Once a connection to a server endpoint exists, this connection MAY be TEXT[!MAY,todo]: reused for requests with multiple different URI authority components. TEXT[!MUST,todo]: To use an existing connection for a new origin, clients MUST validate TEXT[!MUST,todo]: the certificate presented by the server for the new origin server TEXT[!MUST,todo]: using the process described in Section 4.3.4 of [HTTP]. TEXT[!MUST,todo]: If the certificate is not acceptable with regard to the new origin TEXT[!MUST,todo]: for any reason, the connection MUST NOT be reused and a new TEXT[!MUST,todo]: connection SHOULD be established for the new origin. TEXT[!SHOULD,todo]: If the reason TEXT[!SHOULD,todo]: the certificate cannot be verified might apply to other origins TEXT[!SHOULD,todo]: already associated with the connection, the client SHOULD revalidate TEXT[!SHOULD,todo]: the server certificate for those origins. TEXT[!SHOULD,todo]: Clients SHOULD NOT open more than one HTTP/3 connection to a given IP TEXT[!SHOULD,todo]: address and UDP port, where the IP address and port might be derived TEXT[!SHOULD,todo]: from a URI, a selected alternative service ([ALTSVC]), a configured TEXT[!SHOULD,todo]: proxy, or name resolution of any of these. TEXT[!SHOULD,todo]: A client MAY open TEXT[!SHOULD,todo]: multiple HTTP/3 connections to the same IP address and UDP port using TEXT[!SHOULD,todo]: different transport or TLS configurations but SHOULD avoid creating TEXT[!SHOULD,todo]: multiple connections with the same configuration. TEXT[!SHOULD,todo]: When either endpoint chooses to close the HTTP/3 TEXT[!SHOULD,todo]: connection, the terminating endpoint SHOULD first send a GOAWAY frame TEXT[!SHOULD,todo]: (Section 5.2) so that both endpoints can reliably determine whether TEXT[!SHOULD,todo]: previously sent frames have been processed and gracefully complete or TEXT[!SHOULD,todo]: terminate any necessary remaining tasks. SECTION: [HTTP Message Framing](#section-4.1) TEXT[!MUST,implementation]: client MUST send only a single request on a given stream. TEXT[!MUST,todo]: On a given stream, receipt of multiple requests or receipt of an TEXT[!MUST,todo]: additional HTTP response following a final HTTP response MUST be TEXT[!MUST,todo]: treated as malformed. TEXT[!MUST,implementation]: Receipt of an invalid sequence of frames MUST be treated as a TEXT[!MUST,implementation]: connection error of type H3_FRAME_UNEXPECTED. TEXT[!MAY,todo]: A server MAY send one or more PUSH_PROMISE frames before, after, or TEXT[!MAY,todo]: interleaved with the frames of a response message. TEXT[!MUST,implementation]: PUSH_PROMISE frames are not permitted on push streams; TEXT[!MUST,implementation]: a pushed response that includes PUSH_PROMISE frames MUST be treated TEXT[!MUST,implementation]: as a connection error of type H3_FRAME_UNEXPECTED. TEXT[!MAY,implementation]: Frames of unknown types (Section 9), including reserved frames TEXT[!MAY,implementation]: (Section 7.2.8) MAY be sent on a request or push stream before, TEXT[!MAY,implementation]: after, or interleaved with other frames described in this section. TEXT[!MUST,todo]: Transfer codings (see Section 7 of [HTTP/1.1]) are not defined for TEXT[!MUST,todo]: HTTP/3; the Transfer-Encoding header field MUST NOT be used. TEXT[!MAY,implementation]: A response MAY consist of multiple messages when and only when one or TEXT[!MAY,implementation]: more interim responses (1xx; see Section 15.2 of [HTTP]) precede a TEXT[!MAY,implementation]: final response to the same request. TEXT[!MUST,implementation]: After sending a request, a client MUST TEXT[!MUST,implementation]: close the stream for sending. TEXT[!MUST,todo]: Unless using the CONNECT method (see TEXT[!MUST,todo]: Section 4.4), clients MUST NOT make stream closure dependent on TEXT[!MUST,todo]: receiving a response to their request. TEXT[!MUST,implementation]: After sending a final TEXT[!MUST,implementation]: response, the server MUST close the stream for sending. TEXT[!SHOULD,todo]: Because some messages are large or unbounded, endpoints TEXT[!SHOULD,todo]: SHOULD begin processing partial HTTP messages once enough of the TEXT[!SHOULD,todo]: message has been received to make progress. TEXT[!SHOULD,implementation]: If a client-initiated TEXT[!SHOULD,implementation]: stream terminates without enough of the HTTP message to provide a TEXT[!SHOULD,implementation]: complete response, the server SHOULD abort its response stream with TEXT[!SHOULD,implementation]: the error code H3_REQUEST_INCOMPLETE. TEXT[!MAY,todo]: When the server does TEXT[!MAY,todo]: not need to receive the remainder of the request, it MAY abort TEXT[!MAY,todo]: reading the request stream, send a complete response, and cleanly TEXT[!MAY,todo]: close the sending part of the stream. TEXT[!SHOULD,todo]: The error code H3_NO_ERROR TEXT[!SHOULD,todo]: SHOULD be used when requesting that the client stop sending on the TEXT[!SHOULD,todo]: request stream. TEXT[!MUST,todo]: Clients MUST NOT discard complete responses as a TEXT[!MUST,todo]: result of having their request terminated abruptly, though clients TEXT[!MUST,todo]: can always discard responses at their discretion for other reasons. TEXT[!SHOULD,todo]: If the server sends a partial or complete response but does not abort TEXT[!SHOULD,todo]: reading the request, clients SHOULD continue sending the content of TEXT[!SHOULD,todo]: the request and close the stream normally. SECTION: [Request Cancellation and Rejection](#section-4.1.1) TEXT[!MAY,todo]: Once a request stream has been opened, the request MAY be cancelled TEXT[!MAY,todo]: by either endpoint. TEXT[!SHOULD,todo]: When possible, it is RECOMMENDED that servers TEXT[!SHOULD,todo]: send an HTTP response with an appropriate status code rather than TEXT[!SHOULD,todo]: cancelling a request it has already begun processing. TEXT[!SHOULD,todo]: Implementations SHOULD cancel requests by abruptly terminating any TEXT[!SHOULD,todo]: directions of a stream that are still open. TEXT[!SHOULD,todo]: The server SHOULD TEXT[!SHOULD,todo]: abort its response stream with the error code H3_REQUEST_REJECTED. TEXT[!MUST,todo]: Servers MUST NOT use the H3_REQUEST_REJECTED error code for requests TEXT[!MUST,todo]: that were partially or fully processed. TEXT[!SHOULD,todo]: When a server abandons a TEXT[!SHOULD,todo]: response after partial processing, it SHOULD abort its response TEXT[!SHOULD,todo]: stream with the error code H3_REQUEST_CANCELLED. TEXT[!SHOULD,todo]: Client SHOULD use the error code H3_REQUEST_CANCELLED to cancel TEXT[!SHOULD,todo]: requests. TEXT[!MAY,todo]: Upon receipt of this error code, a server MAY abruptly TEXT[!MAY,todo]: terminate the response using the error code H3_REQUEST_REJECTED if no TEXT[!MAY,todo]: processing was performed. TEXT[!MUST,todo]: Clients MUST NOT use the TEXT[!MUST,todo]: H3_REQUEST_REJECTED error code, except when a server has requested TEXT[!MUST,todo]: closure of the request stream with this error code. TEXT[!MAY,todo]: If a stream is cancelled after receiving a complete response, the TEXT[!MAY,todo]: client MAY ignore the cancellation and use the response. TEXT[!SHOULD,todo]: However, if TEXT[!SHOULD,todo]: a stream is cancelled after receiving a partial response, the TEXT[!SHOULD,todo]: response SHOULD NOT be used. TEXT[!SHOULD,todo]: Only idempotent actions such as GET, TEXT[!SHOULD,todo]: PUT, or DELETE can be safely retried; a client SHOULD NOT TEXT[!SHOULD,todo]: automatically retry a request with a non-idempotent method unless it TEXT[!SHOULD,todo]: has some means to know that the request semantics are idempotent TEXT[!SHOULD,todo]: independent of the method or some means to detect that the original TEXT[!SHOULD,todo]: request was never applied. SECTION: [Malformed Requests and Responses](#section-4.1.2) TEXT[!MUST,todo]: Intermediaries that process HTTP requests or responses (i.e., any TEXT[!MUST,todo]: intermediary not acting as a tunnel) MUST NOT forward a malformed TEXT[!MUST,todo]: request or response. TEXT[!MUST,implementation]: Malformed requests or responses that are TEXT[!MUST,implementation]: detected MUST be treated as a stream error of type H3_MESSAGE_ERROR. TEXT[!MAY,todo]: For malformed requests, a server MAY send an HTTP response indicating TEXT[!MAY,todo]: the error prior to closing or resetting the stream. TEXT[!MUST,implementation]: Clients MUST NOT TEXT[!MUST,implementation]: accept a malformed response. SECTION: [HTTP Fields](#section-4.2) TEXT[!MUST,todo]: Characters in field names MUST be TEXT[!MUST,todo]: converted to lowercase prior to their encoding. TEXT[!MUST,implementation,test]: A request or TEXT[!MUST,implementation,test]: response containing uppercase characters in field names MUST be TEXT[!MUST,implementation,test]: treated as malformed. TEXT[!MUST,implementation,test]: An endpoint MUST NOT generate TEXT[!MUST,implementation,test]: an HTTP/3 field section containing connection-specific fields; any TEXT[!MUST,implementation,test]: message containing connection-specific fields MUST be treated as TEXT[!MUST,implementation,test]: malformed. TEXT[!MUST,implementation,test]: The only exception to this is the TE header field, which MAY be TEXT[!MUST,implementation,test]: present in an HTTP/3 request header; when it is, it MUST NOT contain TEXT[!MUST,implementation,test]: any value other than "trailers". TEXT[!MUST,todo]: An intermediary transforming an HTTP/1.x message to HTTP/3 MUST TEXT[!MUST,todo]: remove connection-specific header fields as discussed in TEXT[!MUST,todo]: Section 7.6.1 of [HTTP], or their messages will be treated by other TEXT[!MUST,todo]: HTTP/3 endpoints as malformed. SECTION: [Field Compression](#section-4.2.1) TEXT[!MAY,todo]: To allow for better compression efficiency, the Cookie header field TEXT[!MAY,todo]: ([COOKIES]) MAY be split into separate field lines, each with one or TEXT[!MAY,todo]: more cookie-pairs, before compression. TEXT[!MUST,todo]: If a decompressed field TEXT[!MUST,todo]: section contains multiple cookie field lines, these MUST be TEXT[!MUST,todo]: concatenated into a single byte string using the two-byte delimiter TEXT[!MUST,todo]: of "; " (ASCII 0x3b, 0x20) before being passed into a context other TEXT[!MUST,todo]: than HTTP/2 or HTTP/3, such as an HTTP/1.1 connection, or a generic TEXT[!MUST,todo]: HTTP server application. SECTION: [Header Size Constraints](#section-4.2.2) TEXT[!MAY,implementation]: An HTTP/3 implementation MAY impose a limit on the maximum size of TEXT[!MAY,implementation]: the message header it will accept on an individual HTTP message. TEXT[!SHOULD,implementation]: An implementation that TEXT[!SHOULD,implementation]: has received this parameter SHOULD NOT send an HTTP message header TEXT[!SHOULD,implementation]: that exceeds the indicated size, as the peer will likely refuse to TEXT[!SHOULD,implementation]: process it. SECTION: [HTTP Control Data](#section-4.3) TEXT[!MUST,implementation]: Endpoints MUST NOT TEXT[!MUST,implementation]: generate pseudo-header fields other than those defined in this TEXT[!MUST,implementation]: document. TEXT[!MUST,implementation]: Pseudo-header fields defined for requests MUST NOT appear TEXT[!MUST,implementation]: in responses; pseudo-header fields defined for responses MUST NOT TEXT[!MUST,implementation]: appear in requests. TEXT[!MUST,implementation]: Pseudo-header fields MUST NOT appear in trailer TEXT[!MUST,implementation]: sections. TEXT[!MUST,implementation]: Endpoints MUST treat a request or response that contains TEXT[!MUST,implementation]: undefined or invalid pseudo-header fields as malformed. TEXT[!MUST,implementation]: All pseudo-header fields MUST appear in the header section before TEXT[!MUST,implementation]: regular header fields. TEXT[!MUST,implementation]: Any request or response that contains a TEXT[!MUST,implementation]: pseudo-header field that appears in a header section after a regular TEXT[!MUST,implementation]: header field MUST be treated as malformed. SECTION: [Request Pseudo-Header Fields](#section-4.3.1) TEXT[!MUST,implementation]: The authority MUST NOT include the TEXT[!MUST,implementation]: deprecated userinfo subcomponent for URIs of scheme "http" or TEXT[!MUST,implementation]: "https". TEXT[!MUST,todo]: To ensure that the HTTP/1.1 request line can be reproduced TEXT[!MUST,todo]: accurately, this pseudo-header field MUST be omitted when TEXT[!MUST,todo]: translating from an HTTP/1.1 request that has a request target in TEXT[!MUST,todo]: a method-specific form; see Section 7.1 of [HTTP]. TEXT[!SHOULD,todo]: Clients that TEXT[!SHOULD,todo]: generate HTTP/3 requests directly SHOULD use the :authority TEXT[!SHOULD,todo]: pseudo-header field instead of the Host header field. TEXT[!MUST,todo]: An TEXT[!MUST,todo]: intermediary that converts an HTTP/3 request to HTTP/1.1 MUST TEXT[!MUST,todo]: create a Host field if one is not present in a request by copying TEXT[!MUST,todo]: the value of the :authority pseudo-header field. TEXT[!MUST,implementation]: This pseudo-header field MUST NOT be empty for "http" or "https" TEXT[!MUST,implementation]: URIs; "http" or "https" URIs that do not contain a path component TEXT[!MUST,implementation]: MUST include a value of / (ASCII 0x2f). TEXT[!MUST,implementation]: All HTTP/3 requests MUST include exactly one value for the :method, TEXT[!MUST,implementation]: :scheme, and :path pseudo-header fields, unless the request is a TEXT[!MUST,implementation]: CONNECT request; see Section 4.4. TEXT[!MUST,implementation]: If the :scheme pseudo-header field identifies a scheme that has a TEXT[!MUST,implementation]: mandatory authority component (including "http" and "https"), the TEXT[!MUST,implementation]: request MUST contain either an :authority pseudo-header field or a TEXT[!MUST,implementation]: Host header field. TEXT[!MUST,implementation]: If these fields are present, they MUST NOT be TEXT[!MUST,implementation]: empty. TEXT[!MUST,implementation]: If both fields are present, they MUST contain the same value. TEXT[!MUST,todo]: If the scheme does not have a mandatory authority component and none TEXT[!MUST,todo]: is provided in the request target, the request MUST NOT contain the TEXT[!MUST,todo]: :authority pseudo-header or Host header fields. SECTION: [Response Pseudo-Header Fields](#section-4.3.2) TEXT[!MUST,implementation]: This pseudo- TEXT[!MUST,implementation]: header field MUST be included in all responses; otherwise, the TEXT[!MUST,implementation]: response is malformed (see Section 4.1.2). SECTION: [The CONNECT Method](#section-4.4) TEXT[!MUST,implementation]: A CONNECT request MUST be constructed as follows: TEXT[!MAY,todo]: Extension frames MAY be used if TEXT[!MAY,todo]: specifically permitted by the definition of the extension. TEXT[!MUST,todo]: Receipt TEXT[!MUST,todo]: of any other known frame type MUST be treated as a connection error TEXT[!MUST,todo]: of type H3_FRAME_UNEXPECTED. TEXT[!SHOULD,todo]: TCP connections that remain half closed in a single TEXT[!SHOULD,todo]: direction are not invalid, but are often handled poorly by servers, TEXT[!SHOULD,todo]: so clients SHOULD NOT close a stream for sending while they still TEXT[!SHOULD,todo]: expect to receive data from the target of the CONNECT. TEXT[!MUST,todo]: Correspondingly, if a proxy detects an error with the stream or the TEXT[!MUST,todo]: QUIC connection, it MUST close the TCP connection. TEXT[!MUST,todo]: If the proxy TEXT[!MUST,todo]: detects that the client has reset the stream or aborted reading from TEXT[!MUST,todo]: the stream, it MUST close the TCP connection. TEXT[!SHOULD,todo]: If the stream is reset TEXT[!SHOULD,todo]: or reading is aborted by the client, a proxy SHOULD perform the same TEXT[!SHOULD,todo]: operation on the other direction in order to ensure that both TEXT[!SHOULD,todo]: directions of the stream are cancelled. TEXT[!SHOULD,todo]: In all these cases, if the TEXT[!SHOULD,todo]: underlying TCP implementation permits it, the proxy SHOULD send a TCP TEXT[!SHOULD,todo]: segment with the RST bit set. TEXT[!SHOULD,todo]: Since CONNECT creates a tunnel to an arbitrary server, proxies that TEXT[!SHOULD,todo]: support CONNECT SHOULD restrict its use to a set of known ports or a TEXT[!SHOULD,todo]: list of safe request targets; see Section 9.3.6 of [HTTP] for more TEXT[!SHOULD,todo]: details. SECTION: [Server Push](#section-4.6) TEXT[!SHOULD,todo]: A server SHOULD use push IDs sequentially, beginning from TEXT[!SHOULD,todo]: zero. TEXT[!MUST,implementation]: A client MUST treat receipt of a push stream as a connection TEXT[!MUST,implementation]: error of type H3_ID_ERROR when no MAX_PUSH_ID frame has been sent or TEXT[!MUST,implementation]: when the stream references a push ID that is greater than the maximum TEXT[!MUST,implementation]: push ID. TEXT[!MUST,todo]: When the TEXT[!MUST,todo]: same push ID is promised on multiple request streams, the TEXT[!MUST,todo]: decompressed request field sections MUST contain the same fields in TEXT[!MUST,todo]: the same order, and both the name and the value in each field MUST be TEXT[!MUST,todo]: identical. TEXT[!MAY,todo]: A server MAY push requests that have TEXT[!MAY,todo]: the following properties: TEXT[!MUST,todo]: The server MUST include a value in the :authority pseudo-header field TEXT[!MUST,todo]: for which the server is authoritative. TEXT[!MUST,todo]: If the client has not yet TEXT[!MUST,todo]: validated the connection for the origin indicated by the pushed TEXT[!MUST,todo]: request, it MUST perform the same verification process it would do TEXT[!MUST,todo]: before sending a request for that origin on the connection; see TEXT[!MUST,todo]: Section 3.3. TEXT[!MUST,todo]: If this verification fails, the client MUST NOT TEXT[!MUST,todo]: consider the server authoritative for that origin. TEXT[!SHOULD,todo]: Clients SHOULD send a CANCEL_PUSH frame upon receipt of a TEXT[!SHOULD,todo]: PUSH_PROMISE frame carrying a request that is not cacheable, is not TEXT[!SHOULD,todo]: known to be safe, that indicates the presence of request content, or TEXT[!SHOULD,todo]: for which it does not consider the server authoritative. TEXT[!MUST,todo]: Any TEXT[!MUST,todo]: corresponding responses MUST NOT be used or cached. TEXT[!MAY,todo]: These TEXT[!MAY,todo]: associations do not affect the operation of the protocol, but they TEXT[!MAY,todo]: MAY be considered by user agents when deciding how to use pushed TEXT[!MAY,todo]: resources. TEXT[!SHOULD,todo]: The server SHOULD send PUSH_PROMISE frames TEXT[!SHOULD,todo]: prior to sending HEADERS or DATA frames that reference the promised TEXT[!SHOULD,todo]: responses. TEXT[!SHOULD,todo]: Clients SHOULD abort reading and discard data TEXT[!SHOULD,todo]: already read from push streams if no corresponding PUSH_PROMISE frame TEXT[!SHOULD,todo]: is processed in a reasonable amount of time. TEXT[!MUST,todo]: Pushed responses that are not cacheable MUST NOT be stored by any TEXT[!MUST,todo]: HTTP cache. TEXT[!MAY,todo]: They MAY be made available to the application TEXT[!MAY,todo]: separately. SECTION: [Idle Connections](#section-5.1) TEXT[!SHOULD,todo]: HTTP/3 implementations will need to open a new HTTP/3 TEXT[!SHOULD,todo]: connection for new requests if the existing connection has been idle TEXT[!SHOULD,todo]: for longer than the idle timeout negotiated during the QUIC TEXT[!SHOULD,todo]: handshake, and they SHOULD do so if approaching the idle timeout; see TEXT[!SHOULD,todo]: Section 10.1 of [QUIC-TRANSPORT]. TEXT[!MAY,todo]: A gateway MAY TEXT[!MAY,todo]: maintain connections in anticipation of need rather than incur the TEXT[!MAY,todo]: latency cost of connection establishment to servers. TEXT[!SHOULD,todo]: Servers SHOULD TEXT[!SHOULD,todo]: NOT actively keep connections open. SECTION: [Connection Shutdown](#section-5.2) TEXT[!MAY,todo]: This TEXT[!MAY,todo]: identifier MAY be zero if no requests or pushes were processed. TEXT[!SHOULD,todo]: Upon sending a GOAWAY frame, the endpoint TEXT[!SHOULD,todo]: SHOULD explicitly cancel (see Sections 4.1.1 and 7.2.3) any requests TEXT[!SHOULD,todo]: or pushes that have identifiers greater than or equal to the one TEXT[!SHOULD,todo]: indicated, in order to clean up transport state for the affected TEXT[!SHOULD,todo]: streams. TEXT[!SHOULD,todo]: The endpoint SHOULD continue to do so as more requests or TEXT[!SHOULD,todo]: pushes arrive. TEXT[!MUST,implementation]: Endpoints MUST NOT initiate new requests or promise new pushes on the TEXT[!MUST,implementation]: connection after receipt of a GOAWAY frame from the peer. TEXT[!MAY,todo]: Clients TEXT[!MAY,todo]: MAY establish a new connection to send additional requests. TEXT[!MAY,todo]: Servers MAY reject individual requests on streams below the TEXT[!MAY,todo]: indicated ID if these requests were not processed. TEXT[!SHOULD,todo]: Servers SHOULD send a GOAWAY frame when the closing of a connection TEXT[!SHOULD,todo]: is known in advance, even if the advance notice is small, so that the TEXT[!SHOULD,todo]: remote peer can know whether or not a request has been partially TEXT[!SHOULD,todo]: processed. TEXT[!MUST,implementation]: An endpoint MAY send multiple GOAWAY frames indicating different TEXT[!MUST,implementation]: identifiers, but the identifier in each frame MUST NOT be greater TEXT[!MUST,implementation]: than the identifier in any previous frame, since clients might TEXT[!MUST,implementation]: already have retried unprocessed requests on another HTTP connection. TEXT[!MUST,implementation]: Receiving a GOAWAY containing a larger identifier than previously TEXT[!MUST,implementation]: received MUST be treated as a connection error of type H3_ID_ERROR. TEXT[!MAY,todo]: Like the server, TEXT[!MAY,todo]: the client MAY send subsequent GOAWAY frames so long as the specified TEXT[!MAY,todo]: push ID is no greater than any previously sent value. TEXT[!MAY,todo]: Once all accepted requests and pushes have been processed, the TEXT[!MAY,todo]: endpoint can permit the connection to become idle, or it MAY initiate TEXT[!MAY,todo]: an immediate closure of the connection. TEXT[!SHOULD,todo]: An endpoint that completes a TEXT[!SHOULD,todo]: graceful shutdown SHOULD use the H3_NO_ERROR error code when closing TEXT[!SHOULD,todo]: the connection. SECTION: [Immediate Application Closure](#section-5.3) TEXT[!MAY,todo]: Before closing the connection, a GOAWAY frame MAY be sent to allow TEXT[!MAY,todo]: the client to retry some requests. SECTION: [Transport Closure](#section-5.4) TEXT[!MUST,todo]: If a connection terminates without a GOAWAY frame, clients MUST TEXT[!MUST,todo]: assume that any request that was sent, whether in whole or in part, TEXT[!MUST,todo]: might have been processed. SECTION: [Bidirectional Streams](#section-6.1) TEXT[!SHOULD,todo]: In order to TEXT[!SHOULD,todo]: permit these streams to open, an HTTP/3 server SHOULD configure non- TEXT[!SHOULD,todo]: zero minimum values for the number of permitted streams and the TEXT[!SHOULD,todo]: initial stream flow-control window. TEXT[!SHOULD,todo]: So as to not unnecessarily limit TEXT[!SHOULD,todo]: parallelism, at least 100 request streams SHOULD be permitted at a TEXT[!SHOULD,todo]: time. TEXT[!MUST,implementation]: Clients MUST treat TEXT[!MUST,implementation]: receipt of a server-initiated bidirectional stream as a connection TEXT[!MUST,implementation]: error of type H3_STREAM_CREATION_ERROR unless such an extension has TEXT[!MUST,implementation]: been negotiated. SECTION: [Unidirectional Streams](#section-6.2) TEXT[!MUST,todo]: Therefore, the transport parameters sent by both clients TEXT[!MUST,todo]: and servers MUST allow the peer to create at least three TEXT[!MUST,todo]: unidirectional streams. TEXT[!SHOULD,todo]: These transport parameters SHOULD also TEXT[!SHOULD,todo]: provide at least 1,024 bytes of flow-control credit to each TEXT[!SHOULD,todo]: unidirectional stream. TEXT[!SHOULD,todo]: Endpoints SHOULD create the HTTP control stream as well as the TEXT[!SHOULD,todo]: unidirectional streams required by mandatory extensions (such as the TEXT[!SHOULD,todo]: QPACK encoder and decoder streams) first, and then create additional TEXT[!SHOULD,todo]: streams as allowed by their peer. TEXT[!MUST,implementation]: Recipients of unknown stream types MUST TEXT[!MUST,implementation]: either abort reading of the stream or discard incoming data without TEXT[!MUST,implementation]: further processing. TEXT[!SHOULD,todo]: If reading is aborted, the recipient SHOULD use TEXT[!SHOULD,todo]: the H3_STREAM_CREATION_ERROR error code or a reserved error code TEXT[!SHOULD,todo]: (Section 8.1). TEXT[!MUST,implementation]: The recipient MUST NOT consider unknown stream types TEXT[!MUST,implementation]: to be a connection error of any kind. TEXT[!SHOULD,todo]: As certain stream types can affect connection state, a recipient TEXT[!SHOULD,todo]: SHOULD NOT discard data from incoming unidirectional streams prior to TEXT[!SHOULD,todo]: reading the stream type. TEXT[!MAY,todo]: Implementations MAY send stream types before knowing whether the peer TEXT[!MAY,todo]: supports them. TEXT[!MUST,todo]: However, stream types that could modify the state or TEXT[!MUST,todo]: semantics of existing protocol components, including QPACK or other TEXT[!MUST,todo]: extensions, MUST NOT be sent until the peer is known to support them. TEXT[!MUST,todo]: A receiver MUST tolerate unidirectional streams being TEXT[!MUST,todo]: closed or reset prior to the reception of the unidirectional stream TEXT[!MUST,todo]: header. SECTION: [Control Streams](#section-6.2.1) TEXT[!MUST,implementation]: Each side MUST initiate a single control stream at the beginning of TEXT[!MUST,implementation]: the connection and send its SETTINGS frame as the first frame on this TEXT[!MUST,implementation]: stream. TEXT[!MUST,implementation]: If the first frame of the control stream is any other frame TEXT[!MUST,implementation]: type, this MUST be treated as a connection error of type TEXT[!MUST,implementation]: H3_MISSING_SETTINGS. TEXT[!MUST,implementation]: Only one control stream per peer is permitted; TEXT[!MUST,implementation]: receipt of a second stream claiming to be a control stream MUST be TEXT[!MUST,implementation]: treated as a connection error of type H3_STREAM_CREATION_ERROR. TEXT[!MUST,implementation]: The TEXT[!MUST,implementation]: sender MUST NOT close the control stream, and the receiver MUST NOT TEXT[!MUST,implementation]: request that the sender close the control stream. TEXT[!MUST,implementation]: If either control TEXT[!MUST,implementation]: stream is closed at any point, this MUST be treated as a connection TEXT[!MUST,implementation]: error of type H3_CLOSED_CRITICAL_STREAM. TEXT[!SHOULD,todo]: Because the contents of the control stream are used to manage the TEXT[!SHOULD,todo]: behavior of other streams, endpoints SHOULD provide enough flow- TEXT[!SHOULD,todo]: control credit to keep the peer's control stream from becoming TEXT[!SHOULD,todo]: blocked. SECTION: [Push Streams](#section-6.2.2) TEXT[!MUST,implementation]: Only servers can push; if a server receives a client-initiated push TEXT[!MUST,implementation]: stream, this MUST be treated as a connection error of type TEXT[!MUST,implementation]: H3_STREAM_CREATION_ERROR. TEXT[!SHOULD,todo]: A client SHOULD NOT abort reading on a push stream prior to reading TEXT[!SHOULD,todo]: the push stream header, as this could lead to disagreement between TEXT[!SHOULD,todo]: client and server on which push IDs have already been consumed. TEXT[!MUST,implementation]: Each push ID MUST only be used once in a push stream header. TEXT[!MUST,implementation]: If a TEXT[!MUST,implementation]: client detects that a push stream header includes a push ID that was TEXT[!MUST,implementation]: used in another push stream header, the client MUST treat this as a TEXT[!MUST,implementation]: connection error of type H3_ID_ERROR. SECTION: [Reserved Stream Types](#section-6.2.3) TEXT[!MAY,todo]: They MAY also be TEXT[!MAY,todo]: sent on connections where no data is currently being transferred. TEXT[!MUST,todo]: Endpoints MUST NOT consider these streams to have any meaning upon TEXT[!MUST,todo]: receipt. TEXT[!MAY,todo]: When sending a reserved stream type, TEXT[!MAY,todo]: the implementation MAY either terminate the stream cleanly or reset TEXT[!MAY,todo]: it. TEXT[!SHOULD,todo]: When resetting the stream, either the H3_NO_ERROR error code or TEXT[!SHOULD,todo]: a reserved error code (Section 8.1) SHOULD be used. SECTION: [Frame Layout](#section-7.1) TEXT[!MUST,implementation,test]: Each frame's payload MUST contain exactly the fields identified in TEXT[!MUST,implementation,test]: its description. TEXT[!MUST,implementation,test]: A frame payload that contains additional bytes TEXT[!MUST,implementation,test]: after the identified fields or a frame payload that terminates before TEXT[!MUST,implementation,test]: the end of the identified fields MUST be treated as a connection TEXT[!MUST,implementation,test]: error of type H3_FRAME_ERROR. TEXT[!MUST,todo]: In particular, redundant length TEXT[!MUST,todo]: encodings MUST be verified to be self-consistent; see Section 10.8. TEXT[!MUST,implementation]: When a stream terminates cleanly, if the last frame on the stream was TEXT[!MUST,implementation]: truncated, this MUST be treated as a connection error of type TEXT[!MUST,implementation]: H3_FRAME_ERROR. SECTION: [DATA](#section-7.2.1) TEXT[!MUST,implementation]: DATA frames MUST be associated with an HTTP request or response. TEXT[!MUST,implementation]: If TEXT[!MUST,implementation]: a DATA frame is received on a control stream, the recipient MUST TEXT[!MUST,implementation]: respond with a connection error of type H3_FRAME_UNEXPECTED. SECTION: [HEADERS](#section-7.2.2) TEXT[!MUST,implementation]: If a HEADERS frame is received on a control stream, the recipient TEXT[!MUST,implementation]: MUST respond with a connection error of type H3_FRAME_UNEXPECTED. SECTION: [CANCEL_PUSH](#section-7.2.3) TEXT[!SHOULD,todo]: The server SHOULD TEXT[!SHOULD,todo]: abort sending the resource, but the mechanism to do so depends on the TEXT[!SHOULD,todo]: state of the corresponding push stream. TEXT[!SHOULD,todo]: If the push stream is TEXT[!SHOULD,todo]: open, the server SHOULD abruptly terminate that stream. TEXT[!MAY,todo]: If the push TEXT[!MAY,todo]: stream has already ended, the server MAY still abruptly terminate the TEXT[!MAY,todo]: stream or MAY take no action. TEXT[!SHOULD,todo]: Regardless of TEXT[!SHOULD,todo]: whether a push stream has been opened, a server SHOULD send a TEXT[!SHOULD,todo]: CANCEL_PUSH frame when it determines that promise will not be TEXT[!SHOULD,todo]: fulfilled. TEXT[!SHOULD,todo]: A client SHOULD NOT send a CANCEL_PUSH frame TEXT[!SHOULD,todo]: when it has already received a corresponding push stream. TEXT[!SHOULD,todo]: The TEXT[!SHOULD,todo]: client SHOULD abort reading the stream with an error code of TEXT[!SHOULD,todo]: H3_REQUEST_CANCELLED. TEXT[!MUST,todo]: Receiving a TEXT[!MUST,todo]: CANCEL_PUSH frame on a stream other than the control stream MUST be TEXT[!MUST,todo]: treated as a connection error of type H3_FRAME_UNEXPECTED. TEXT[!MUST,implementation]: If a CANCEL_PUSH frame is received that TEXT[!MUST,implementation]: references a push ID greater than currently allowed on the TEXT[!MUST,implementation]: connection, this MUST be treated as a connection error of type TEXT[!MUST,implementation]: H3_ID_ERROR. TEXT[!MUST,implementation]: If a server receives a CANCEL_PUSH frame for a push TEXT[!MUST,implementation]: ID that has not yet been mentioned by a PUSH_PROMISE frame, this MUST TEXT[!MUST,implementation]: be treated as a connection error of type H3_ID_ERROR. SECTION: [SETTINGS](#section-7.2.4) TEXT[!MUST,implementation]: A SETTINGS frame MUST be sent as the first frame of TEXT[!MUST,implementation]: each control stream (see Section 6.2.1) by each peer, and it MUST NOT TEXT[!MUST,implementation]: be sent subsequently. TEXT[!MUST,implementation]: If an endpoint receives a second SETTINGS TEXT[!MUST,implementation]: frame on the control stream, the endpoint MUST respond with a TEXT[!MUST,implementation]: connection error of type H3_FRAME_UNEXPECTED. TEXT[!MUST,implementation]: SETTINGS frames MUST NOT be sent on any stream other than the control TEXT[!MUST,implementation]: stream. TEXT[!MUST,test]: If an endpoint receives a SETTINGS frame on a different TEXT[!MUST,test]: stream, the endpoint MUST respond with a connection error of type TEXT[!MUST,test]: H3_FRAME_UNEXPECTED. TEXT[!MUST,implementation]: The same setting identifier MUST NOT occur more than once in the TEXT[!MUST,implementation]: SETTINGS frame. TEXT[!MAY,implementation]: A receiver MAY treat the presence of duplicate TEXT[!MAY,implementation]: setting identifiers as a connection error of type H3_SETTINGS_ERROR. TEXT[!MUST,implementation]: An implementation MUST ignore any parameter with an identifier it TEXT[!MUST,implementation]: does not understand. SECTION: [Defined SETTINGS Parameters](#section-7.2.4.1) TEXT[!SHOULD,implementation]: Endpoints SHOULD include at least one such setting in their TEXT[!SHOULD,implementation]: SETTINGS frame. TEXT[!MUST,todo]: Endpoints MUST NOT consider such settings to have TEXT[!MUST,todo]: any meaning upon receipt. TEXT[!MUST,implementation]: These reserved settings MUST NOT be sent, and TEXT[!MUST,implementation]: their receipt MUST be treated as a connection error of type TEXT[!MUST,implementation]: H3_SETTINGS_ERROR. SECTION: [Initialization](#section-7.2.4.2) TEXT[!MUST,implementation]: An HTTP implementation MUST NOT send frames or requests that would be TEXT[!MUST,implementation]: invalid based on its current understanding of the peer's settings. TEXT[!SHOULD,todo]: Each endpoint SHOULD use TEXT[!SHOULD,todo]: these initial values to send messages before the peer's SETTINGS TEXT[!SHOULD,todo]: frame has arrived, as packets carrying the settings can be lost or TEXT[!SHOULD,todo]: delayed. TEXT[!MUST,todo]: Endpoints MUST NOT require any data to be received from TEXT[!MUST,todo]: the peer prior to sending the SETTINGS frame; settings MUST be sent TEXT[!MUST,todo]: as soon as the transport is ready to send data. TEXT[!SHOULD,todo]: Clients SHOULD TEXT[!SHOULD,todo]: NOT wait indefinitely for SETTINGS to arrive before sending requests, TEXT[!SHOULD,todo]: but they SHOULD process received datagrams in order to increase the TEXT[!SHOULD,todo]: likelihood of processing SETTINGS before sending the first request. TEXT[!SHOULD,todo]: Clients TEXT[!SHOULD,todo]: SHOULD store the settings the server provided in the HTTP/3 TEXT[!SHOULD,todo]: connection where resumption information was provided, but they MAY TEXT[!SHOULD,todo]: opt not to store settings in certain cases (e.g., if the session TEXT[!SHOULD,todo]: ticket is received before the SETTINGS frame). TEXT[!MUST,todo]: A client MUST comply TEXT[!MUST,todo]: with stored settings -- or default values if no values are stored -- TEXT[!MUST,todo]: when attempting 0-RTT. TEXT[!MUST,todo]: Once a server has provided new settings, TEXT[!MUST,todo]: clients MUST comply with those values. TEXT[!MUST,todo]: If the TEXT[!MUST,todo]: server cannot determine that the settings remembered by a client are TEXT[!MUST,todo]: compatible with its current settings, it MUST NOT accept 0-RTT data. TEXT[!MAY,todo]: A server MAY accept 0-RTT and subsequently provide different settings TEXT[!MAY,todo]: in its SETTINGS frame. TEXT[!MUST,implementation]: If 0-RTT data is accepted by the server, its TEXT[!MUST,implementation]: SETTINGS frame MUST NOT reduce any limits or alter any values that TEXT[!MUST,implementation]: might be violated by the client with its 0-RTT data. TEXT[!MUST,todo]: The server MUST TEXT[!MUST,todo]: include all settings that differ from their default values. TEXT[!MUST,implementation]: If a TEXT[!MUST,implementation]: server accepts 0-RTT but then sends settings that are not compatible TEXT[!MUST,implementation]: with the previously specified settings, this MUST be treated as a TEXT[!MUST,implementation]: connection error of type H3_SETTINGS_ERROR. TEXT[!MUST,implementation]: If a server accepts TEXT[!MUST,implementation]: 0-RTT but then sends a SETTINGS frame that omits a setting value that TEXT[!MUST,implementation]: the client understands (apart from reserved setting identifiers) that TEXT[!MUST,implementation]: was previously specified to have a non-default value, this MUST be TEXT[!MUST,implementation]: treated as a connection error of type H3_SETTINGS_ERROR. SECTION: [PUSH_PROMISE](#section-7.2.5) TEXT[!MUST,implementation]: A server MUST NOT use a push ID that is larger than the client has TEXT[!MUST,implementation]: provided in a MAX_PUSH_ID frame (Section 7.2.7). TEXT[!MUST,implementation]: A client MUST treat TEXT[!MUST,implementation]: receipt of a PUSH_PROMISE frame that contains a larger push ID than TEXT[!MUST,implementation]: the client has advertised as a connection error of H3_ID_ERROR. TEXT[!MAY,todo]: A server MAY use the same push ID in multiple PUSH_PROMISE frames. TEXT[!MUST,todo]: If so, the decompressed request header sets MUST contain the same TEXT[!MUST,todo]: fields in the same order, and both the name and the value in each TEXT[!MUST,todo]: field MUST be exact matches. TEXT[!SHOULD,todo]: Clients SHOULD compare the request TEXT[!SHOULD,todo]: header sections for resources promised multiple times. TEXT[!MUST,implementation]: If a client TEXT[!MUST,implementation]: receives a push ID that has already been promised and detects a TEXT[!MUST,implementation]: mismatch, it MUST respond with a connection error of type TEXT[!MUST,implementation]: H3_GENERAL_PROTOCOL_ERROR. TEXT[!SHOULD,todo]: If the decompressed field sections match TEXT[!SHOULD,todo]: exactly, the client SHOULD associate the pushed content with each TEXT[!SHOULD,todo]: stream on which a PUSH_PROMISE frame was received. TEXT[!SHOULD,todo]: A server SHOULD TEXT[!SHOULD,todo]: avoid reusing a push ID over a long period. TEXT[!MUST,implementation]: If a PUSH_PROMISE frame is received on the control stream, the client TEXT[!MUST,implementation]: MUST respond with a connection error of type H3_FRAME_UNEXPECTED. TEXT[!MUST,implementation]: A client MUST NOT send a PUSH_PROMISE frame. TEXT[!MUST,implementation]: A server MUST treat the TEXT[!MUST,implementation]: receipt of a PUSH_PROMISE frame as a connection error of type TEXT[!MUST,implementation]: H3_FRAME_UNEXPECTED. SECTION: [GOAWAY](#section-7.2.6) TEXT[!MUST,implementation]: A client MUST treat receipt of a GOAWAY frame containing a stream ID TEXT[!MUST,implementation]: of any other type as a connection error of type H3_ID_ERROR. TEXT[!MUST,implementation]: A client MUST treat a GOAWAY frame on a stream other than TEXT[!MUST,implementation]: the control stream as a connection error of type H3_FRAME_UNEXPECTED. SECTION: [MAX_PUSH_ID](#section-7.2.7) TEXT[!MUST,implementation]: Receipt TEXT[!MUST,implementation]: of a MAX_PUSH_ID frame on any other stream MUST be treated as a TEXT[!MUST,implementation]: connection error of type H3_FRAME_UNEXPECTED. TEXT[!MUST,implementation]: A server MUST NOT send a MAX_PUSH_ID frame. TEXT[!MUST,implementation]: A client MUST treat the TEXT[!MUST,implementation]: receipt of a MAX_PUSH_ID frame as a connection error of type TEXT[!MUST,implementation]: H3_FRAME_UNEXPECTED. TEXT[!MUST,implementation,test]: A MAX_PUSH_ID frame cannot reduce the maximum push TEXT[!MUST,implementation,test]: ID; receipt of a MAX_PUSH_ID frame that contains a smaller value than TEXT[!MUST,implementation,test]: previously received MUST be treated as a connection error of type TEXT[!MUST,implementation,test]: H3_ID_ERROR. SECTION: [Reserved Frame Types](#section-7.2.8) TEXT[!MAY,implementation]: These frames have no semantics, and TEXT[!MAY,implementation]: they MAY be sent on any stream where frames are allowed to be sent. TEXT[!MUST,implementation]: Endpoints MUST TEXT[!MUST,implementation]: NOT consider these frames to have any meaning upon receipt. TEXT[!MUST,implementation]: These frame TEXT[!MUST,implementation]: types MUST NOT be sent, and their receipt MUST be treated as a TEXT[!MUST,implementation]: connection error of type H3_FRAME_UNEXPECTED. SECTION: [Error Handling](#section-8) TEXT[!MAY,todo]: An endpoint MAY choose to treat a stream error as a connection error TEXT[!MAY,todo]: under certain circumstances, closing the entire connection in TEXT[!MAY,todo]: response to a condition on a single stream. TEXT[!MUST,todo]: Because new error codes can be defined without negotiation (see TEXT[!MUST,todo]: Section 9), use of an error code in an unexpected context or receipt TEXT[!MUST,todo]: of an unknown error code MUST be treated as equivalent to TEXT[!MUST,todo]: H3_NO_ERROR. SECTION: [HTTP/3 Error Codes](#section-8.1) TEXT[!SHOULD,todo]: Implementations SHOULD select an error code from this space with some TEXT[!SHOULD,todo]: probability when they would have sent H3_NO_ERROR. SECTION: [Extensions to HTTP/3](#section-9) TEXT[!MUST,implementation]: Implementations MUST ignore unknown or unsupported values in all TEXT[!MUST,implementation]: extensible protocol elements. TEXT[!MUST,todo]: Implementations MUST discard data or TEXT[!MUST,todo]: abort reading on unidirectional streams that have unknown or TEXT[!MUST,todo]: unsupported types. TEXT[!SHOULD,todo]: However, where a known frame type is required to be in TEXT[!SHOULD,todo]: a specific location, such as the SETTINGS frame as the first frame of TEXT[!SHOULD,todo]: the control stream (see Section 6.2.1), an unknown frame type does TEXT[!SHOULD,todo]: not satisfy that requirement and SHOULD be treated as an error. TEXT[!MUST,todo]: Extensions that could change the semantics of existing protocol TEXT[!MUST,todo]: components MUST be negotiated before being used. TEXT[!MUST,todo]: If a setting is used for extension negotiation, the default TEXT[!MUST,todo]: value MUST be defined in such a fashion that the extension is TEXT[!MUST,todo]: disabled if the setting is omitted. SECTION: [Intermediary-Encapsulation Attacks](#section-10.3) TEXT[!MUST,implementation]: Requests or responses containing invalid field names MUST be treated TEXT[!MUST,implementation]: as malformed. TEXT[!MUST,implementation]: Any request or response that contains a TEXT[!MUST,implementation]: character not permitted in a field value MUST be treated as TEXT[!MUST,implementation]: malformed. SECTION: [Cacheability of Pushed Responses](#section-10.4) TEXT[!MUST,todo]: Where multiple tenants share space on the same server, that server TEXT[!MUST,todo]: MUST ensure that tenants are not able to push representations of TEXT[!MUST,todo]: resources that they do not have authority over. SECTION: [Denial-of-Service Considerations](#section-10.5) TEXT[!SHOULD,implementation]: A client that accepts server push SHOULD limit the number TEXT[!SHOULD,implementation]: of push IDs it issues at a time. TEXT[!SHOULD,todo]: Implementations SHOULD track the TEXT[!SHOULD,todo]: use of these features and set limits on their use. TEXT[!MAY,todo]: An endpoint MAY TEXT[!MAY,todo]: treat activity that is suspicious as a connection error of type TEXT[!MAY,todo]: H3_EXCESSIVE_LOAD, but false positives will result in disrupting TEXT[!MAY,todo]: valid connections and requests. SECTION: [Limits on Field Section Size](#section-10.5.1) TEXT[!MAY,todo]: This setting is only advisory, so TEXT[!MAY,todo]: endpoints MAY choose to send field sections that exceed this limit TEXT[!MAY,todo]: and risk having the request or response being treated as malformed. SECTION: [Use of Compression](#section-10.6) TEXT[!MUST,todo]: Implementations communicating on a secure channel MUST NOT compress TEXT[!MUST,todo]: content that includes both confidential and attacker-controlled data TEXT[!MUST,todo]: unless separate compression contexts are used for each source of TEXT[!MUST,todo]: data. TEXT[!MUST,todo]: Compression MUST NOT be used if the source of data cannot be TEXT[!MUST,todo]: reliably determined. SECTION: [Frame Parsing](#section-10.8) TEXT[!MUST,implementation]: An implementation MUST ensure that the length of a TEXT[!MUST,implementation]: frame exactly matches the length of the fields it contains. SECTION: [Early Data](#section-10.9) TEXT[!MUST,todo]: The anti-replay mitigations in [HTTP-REPLAY] MUST be applied when TEXT[!MUST,todo]: using HTTP/3 with 0-RTT. SECTION: [Frame Types](#section-11.2.1) TEXT[!SHOULD,todo]: If an entry is present in TEXT[!SHOULD,todo]: only one registry, every effort SHOULD be made to avoid assigning the TEXT[!SHOULD,todo]: corresponding value to an unrelated operation. TEXT[!MAY,todo]: Expert reviewers MAY TEXT[!MAY,todo]: reject unrelated registrations that would conflict with the same TEXT[!MAY,todo]: value in the corresponding registry. TEXT[!MUST,todo]: In addition to common fields as described in Section 11.2, permanent TEXT[!MUST,todo]: registrations in this registry MUST include the following field: TEXT[!MUST,todo]: Specifications of frame types MUST include a description of the frame TEXT[!MUST,todo]: layout and its semantics, including any parts of the frame that are TEXT[!MUST,todo]: conditionally present. TEXT[!MUST,todo]: Each code of the format 0x1f * N + 0x21 for non-negative integer TEXT[!MUST,todo]: values of N (that is, 0x21, 0x40, ..., through 0x3ffffffffffffffe) TEXT[!MUST,todo]: MUST NOT be assigned by IANA and MUST NOT appear in the listing of TEXT[!MUST,todo]: assigned values. SECTION: [Settings Parameters](#section-11.2.2) TEXT[!SHOULD,todo]: If an entry is present in only one registry, every TEXT[!SHOULD,todo]: effort SHOULD be made to avoid assigning the corresponding value to TEXT[!SHOULD,todo]: an unrelated operation. TEXT[!MAY,todo]: Expert reviewers MAY reject unrelated TEXT[!MAY,todo]: registrations that would conflict with the same value in the TEXT[!MAY,todo]: corresponding registry. TEXT[!MUST,todo]: In addition to common fields as described in Section 11.2, permanent TEXT[!MUST,todo]: registrations in this registry MUST include the following fields: TEXT[!SHOULD,todo]: default SHOULD be the most restrictive possible value. TEXT[!MUST,todo]: Each code of the format 0x1f * N + 0x21 for non-negative integer TEXT[!MUST,todo]: values of N (that is, 0x21, 0x40, ..., through 0x3ffffffffffffffe) TEXT[!MUST,todo]: MUST NOT be assigned by IANA and MUST NOT appear in the listing of TEXT[!MUST,todo]: assigned values. SECTION: [Error Codes](#section-11.2.3) TEXT[!MAY,todo]: Use of values that are registered in the "HTTP/2 Error Code" registry TEXT[!MAY,todo]: is discouraged, and expert reviewers MAY reject such registrations. TEXT[!MUST,todo]: Permanent registrations in TEXT[!MUST,todo]: this registry MUST include the following field: TEXT[!MUST,todo]: Each code of the format 0x1f * N + 0x21 for non-negative integer TEXT[!MUST,todo]: values of N (that is, 0x21, 0x40, ..., through 0x3ffffffffffffffe) TEXT[!MUST,todo]: MUST NOT be assigned by IANA and MUST NOT appear in the listing of TEXT[!MUST,todo]: assigned values. SECTION: [Stream Types](#section-11.2.4) TEXT[!MUST,todo]: In addition to common fields as described in Section 11.2, permanent TEXT[!MUST,todo]: registrations in this registry MUST include the following fields: TEXT[!MUST,todo]: Specifications for permanent registrations MUST include a description TEXT[!MUST,todo]: of the stream type, including the layout and semantics of the stream TEXT[!MUST,todo]: contents. TEXT[!MUST,todo]: Each code of the format 0x1f * N + 0x21 for non-negative integer TEXT[!MUST,todo]: values of N (that is, 0x21, 0x40, ..., through 0x3ffffffffffffffe) TEXT[!MUST,todo]: MUST NOT be assigned by IANA and MUST NOT appear in the listing of TEXT[!MUST,todo]: assigned values. SPECIFICATION: https://www.rfc-editor.org/rfc/rfc9204 SECTION: [Encoder](#section-2.1) TEXT[!MAY,todo]: An encoder MAY insert any entry in the dynamic table it chooses; it TEXT[!MAY,todo]: is not limited to field lines it is compressing. TEXT[!MUST,implementation]: An encoder MUST emit field representations in the order TEXT[!MUST,implementation]: they appear in the input field section. SECTION: [Limits on Dynamic Table Insertions](#section-2.1.1) TEXT[!MUST,implementation]: If the dynamic table does not contain enough room for a new entry TEXT[!MUST,implementation]: without evicting other entries, and the entries that would be evicted TEXT[!MUST,implementation]: are not evictable, the encoder MUST NOT insert that entry into the TEXT[!MUST,implementation]: dynamic table (including duplicates of existing entries). SECTION: [Blocked Streams](#section-2.1.2) TEXT[!MUST,implementation]: An encoder MUST limit the number of streams that could TEXT[!MUST,implementation]: become blocked to the value of SETTINGS_QPACK_BLOCKED_STREAMS at all TEXT[!MUST,implementation]: times. TEXT[!MUST,implementation,test]: If a decoder encounters more blocked streams than it promised TEXT[!MUST,implementation,test]: to support, it MUST treat this as a connection error of type TEXT[!MUST,implementation,test]: QPACK_DECOMPRESSION_FAILED. SECTION: [Avoiding Flow-Control Deadlocks](#section-2.1.3) TEXT[!SHOULD,todo]: To avoid these deadlocks, an encoder SHOULD NOT write an instruction TEXT[!SHOULD,todo]: unless sufficient stream and connection flow-control credit is TEXT[!SHOULD,todo]: available for the entire instruction. SECTION: [Decoder](#section-2.2) TEXT[!MUST,implementation,test]: The decoder MUST emit field lines in the order their representations TEXT[!MUST,implementation,test]: appear in the encoded field section. SECTION: [Blocked Decoding](#section-2.2.1) TEXT[!SHOULD,todo]: While blocked, encoded field section data SHOULD remain in the TEXT[!SHOULD,todo]: blocked stream's flow-control window. TEXT[!MUST,implementation,test]: If it encounters a Required Insert TEXT[!MUST,implementation,test]: Count smaller than expected, it MUST treat this as a connection error TEXT[!MUST,implementation,test]: of type QPACK_DECOMPRESSION_FAILED; see Section 2.2.3. TEXT[!MAY,todo]: If it TEXT[!MAY,todo]: encounters a Required Insert Count larger than expected, it MAY treat TEXT[!MAY,todo]: this as a connection error of type QPACK_DECOMPRESSION_FAILED. SECTION: [Completed Processing of a Field Section](#section-2.2.2.1) TEXT[!MUST,implementation,test]: After the decoder finishes decoding a field section encoded using TEXT[!MUST,implementation,test]: representations containing dynamic table references, it MUST emit a TEXT[!MUST,implementation,test]: Section Acknowledgment instruction (Section 4.4.1). SECTION: [Abandonment of a Stream](#section-2.2.2.2) TEXT[!MAY,todo]: A decoder with a maximum dynamic table TEXT[!MAY,todo]: capacity (Section 3.2.3) equal to zero MAY omit sending Stream TEXT[!MAY,todo]: Cancellations, because the encoder cannot have any dynamic table TEXT[!MAY,todo]: references. SECTION: [Invalid References](#section-2.2.3) TEXT[!MUST,implementation]: If the decoder encounters a reference in a field line representation TEXT[!MUST,implementation]: to a dynamic table entry that has already been evicted or that has an TEXT[!MUST,implementation]: absolute index greater than or equal to the declared Required Insert TEXT[!MUST,implementation]: Count (Section 4.5.1), it MUST treat this as a connection error of TEXT[!MUST,implementation]: type QPACK_DECOMPRESSION_FAILED. TEXT[!MUST,implementation]: If the decoder encounters a reference in an encoder instruction to a TEXT[!MUST,implementation]: dynamic table entry that has already been evicted, it MUST treat this TEXT[!MUST,implementation]: as a connection error of type QPACK_ENCODER_STREAM_ERROR. SECTION: [Static Table](#section-3.1) TEXT[!MUST,test]: When the decoder encounters an invalid static table index in a field TEXT[!MUST,test]: line representation, it MUST treat this as a connection error of type TEXT[!MUST,test]: QPACK_DECOMPRESSION_FAILED. TEXT[!MUST,test]: If this index is received on the encoder TEXT[!MUST,test]: stream, this MUST be treated as a connection error of type TEXT[!MUST,test]: QPACK_ENCODER_STREAM_ERROR. SECTION: [Dynamic Table](#section-3.2) TEXT[!MUST,implementation,test]: Therefore, duplicate entries MUST NOT TEXT[!MUST,implementation,test]: be treated as an error by the decoder. SECTION: [Dynamic Table Capacity and Eviction](#section-3.2.2) TEXT[!MUST,implementation,test]: The TEXT[!MUST,implementation,test]: encoder MUST NOT cause a dynamic table entry to be evicted unless TEXT[!MUST,implementation,test]: that entry is evictable; see Section 2.1.1. TEXT[!MUST,implementation,test]: It is an error if the encoder attempts to add an TEXT[!MUST,implementation,test]: entry that is larger than the dynamic table capacity; the decoder TEXT[!MUST,implementation,test]: MUST treat this as a connection error of type TEXT[!MUST,implementation,test]: QPACK_ENCODER_STREAM_ERROR. SECTION: [Maximum Dynamic Table Capacity](#section-3.2.3) TEXT[!MUST,implementation]: The encoder MUST NOT set a dynamic table capacity that exceeds this TEXT[!MUST,implementation]: maximum, but it can choose to use a lower dynamic table capacity; see TEXT[!MUST,implementation]: Section 4.3.1. TEXT[!MAY,test]: When the client's 0-RTT value of the TEXT[!MAY,test]: SETTING is zero, the server MAY set it to a non-zero value in its TEXT[!MAY,test]: SETTINGS frame. TEXT[!MUST,implementation]: If the remembered value is non-zero, the server MUST TEXT[!MUST,implementation]: send the same non-zero value in its SETTINGS frame. TEXT[!MUST,implementation]: When the maximum table capacity is zero, the encoder MUST NOT insert TEXT[!MUST,implementation]: entries into the dynamic table and MUST NOT send any encoder TEXT[!MUST,implementation]: instructions on the encoder stream. SECTION: [Prefixed Integers](#section-4.1.1) TEXT[!MUST,implementation]: QPACK implementations MUST be able to decode integers up to and TEXT[!MUST,implementation]: including 62 bits long. SECTION: [Encoder and Decoder Streams](#section-4.2) TEXT[!MUST,implementation,test]: Each endpoint TEXT[!MUST,implementation,test]: MUST initiate, at most, one encoder stream and, at most, one decoder TEXT[!MUST,implementation,test]: stream. TEXT[!MUST,implementation,test]: Receipt of a second instance of either stream type MUST be TEXT[!MUST,implementation,test]: treated as a connection error of type H3_STREAM_CREATION_ERROR. TEXT[!MUST,implementation]: The sender MUST NOT close either of these streams, and the receiver TEXT[!MUST,implementation]: MUST NOT request that the sender close either of these streams. TEXT[!MUST,implementation]: Closure of either unidirectional stream type MUST be treated as a TEXT[!MUST,implementation]: connection error of type H3_CLOSED_CRITICAL_STREAM. TEXT[!MAY,todo]: An endpoint MAY avoid creating an encoder stream if it will not be TEXT[!MAY,todo]: used (for example, if its encoder does not wish to use the dynamic TEXT[!MAY,todo]: table or if the maximum size of the dynamic table permitted by the TEXT[!MAY,todo]: peer is zero). TEXT[!MAY,todo]: An endpoint MAY avoid creating a decoder stream if its decoder sets TEXT[!MAY,todo]: the maximum capacity of the dynamic table to zero. TEXT[!MUST,implementation]: An endpoint MUST allow its peer to create an encoder stream and a TEXT[!MUST,implementation]: decoder stream even if the connection's settings prevent their use. SECTION: [Set Dynamic Table Capacity](#section-4.3.1) TEXT[!MUST,implementation,test]: The new capacity MUST be lower than or equal to the limit described TEXT[!MUST,implementation,test]: in Section 3.2.3. TEXT[!MUST,implementation,test]: The decoder MUST treat a new dynamic table capacity TEXT[!MUST,implementation,test]: value that exceeds this limit as a connection error of type TEXT[!MUST,implementation,test]: QPACK_ENCODER_STREAM_ERROR. TEXT[!MUST,implementation,test]: This MUST NOT cause the eviction of entries that TEXT[!MUST,implementation,test]: are not evictable; see Section 2.1.1. SECTION: [Section Acknowledgment](#section-4.4.1) TEXT[!MUST,implementation,test]: If an encoder receives a Section Acknowledgment instruction referring TEXT[!MUST,implementation,test]: to a stream on which every encoded field section with a non-zero TEXT[!MUST,implementation,test]: Required Insert Count has already been acknowledged, this MUST be TEXT[!MUST,implementation,test]: treated as a connection error of type QPACK_DECODER_STREAM_ERROR. SECTION: [Insert Count Increment](#section-4.4.3) TEXT[!MUST,test]: An encoder that receives an Increment field equal to zero, or one TEXT[!MUST,test]: that increases the Known Received Count beyond what the encoder has TEXT[!MUST,test]: sent, MUST treat this as a connection error of type TEXT[!MUST,test]: QPACK_DECODER_STREAM_ERROR. SECTION: [Required Insert Count](#section-4.5.1.1) TEXT[!MUST,implementation,test]: If the decoder encounters a value TEXT[!MUST,implementation,test]: of EncodedInsertCount that could not have been produced by a TEXT[!MUST,implementation,test]: conformant encoder, it MUST treat this as a connection error of type TEXT[!MUST,implementation,test]: QPACK_DECOMPRESSION_FAILED. SECTION: [Base](#section-4.5.1.2) TEXT[!MUST,implementation,test]: The value of Base MUST NOT be negative. TEXT[!MUST,implementation,test]: An endpoint MUST treat a field block TEXT[!MUST,implementation,test]: with a Sign bit of 1 as invalid if the value of Required Insert Count TEXT[!MUST,implementation,test]: is less than or equal to the value of Delta Base. SECTION: [Literal Field Line with Name Reference](#section-4.5.4) TEXT[!MUST,todo]: When TEXT[!MUST,todo]: the 'N' bit is set, the encoded field line MUST always be encoded TEXT[!MUST,todo]: with a literal representation. TEXT[!MUST,todo]: In particular, when a peer sends a TEXT[!MUST,todo]: field line that it received represented as a literal field line with TEXT[!MUST,todo]: the 'N' bit set, it MUST use a literal representation to forward this TEXT[!MUST,todo]: field line. SECTION: [Never-Indexed Literals](#section-7.1.3) TEXT[!MUST,todo]: An intermediary MUST NOT re-encode a value that uses a literal TEXT[!MUST,todo]: representation with the 'N' bit set with another representation that TEXT[!MUST,todo]: would index it. TEXT[!MUST,todo]: If QPACK is used for re-encoding, a literal TEXT[!MUST,todo]: representation with the 'N' bit set MUST be used. TEXT[!MUST,todo]: If HPACK is used TEXT[!MUST,todo]: for re-encoding, the never-indexed literal representation (see TEXT[!MUST,todo]: Section 6.2.3 of [RFC7541]) MUST be used. SECTION: [Implementation Limits](#section-7.4) TEXT[!SHOULD,todo]: These limits SHOULD be large TEXT[!SHOULD,todo]: enough to process the largest individual field the HTTP TEXT[!SHOULD,todo]: implementation can be configured to accept. TEXT[!MUST,implementation]: If an implementation encounters a value larger than it is able to TEXT[!MUST,implementation]: decode, this MUST be treated as a stream error of type TEXT[!MUST,implementation]: QPACK_DECOMPRESSION_FAILED if on a request stream or a connection TEXT[!MUST,implementation]: error of the appropriate type if on the encoder or decoder stream. SPECIFICATION: https://www.rfc-editor.org/rfc/rfc9221 SECTION: [Transport Parameter](#section-3) TEXT[implementation,test]: The max_datagram_frame_size transport parameter is an TEXT[implementation,test]: integer value (represented as a variable-length integer) that TEXT[implementation,test]: represents the maximum size of a DATAGRAM frame (including the frame TEXT[implementation,test]: type, length, and payload) the endpoint is willing to receive, in TEXT[implementation,test]: bytes. TEXT[!MUST,implementation]: An endpoint MUST NOT send DATAGRAM frames until it has received the TEXT[!MUST,implementation]: max_datagram_frame_size transport parameter with a non-zero value TEXT[!MUST,implementation]: during the handshake (or during a previous handshake if 0-RTT is TEXT[!MUST,implementation]: used). TEXT[!MUST,implementation]: An endpoint MUST NOT send DATAGRAM frames that are larger TEXT[!MUST,implementation]: than the max_datagram_frame_size value it has received from its peer. TEXT[!MUST,implementation]: An endpoint that receives a DATAGRAM frame when it has not indicated TEXT[!MUST,implementation]: support via the transport parameter MUST terminate the connection TEXT[!MUST,implementation]: with an error of type PROTOCOL_VIOLATION. TEXT[!MUST,implementation]: Similarly, an endpoint TEXT[!MUST,implementation]: that receives a DATAGRAM frame that is larger than the value it sent TEXT[!MUST,implementation]: in its max_datagram_frame_size transport parameter MUST terminate the TEXT[!MUST,implementation]: connection with an error of type PROTOCOL_VIOLATION. TEXT[!SHOULD,implementation]: For most uses of DATAGRAM frames, it is RECOMMENDED to send a value TEXT[!SHOULD,implementation]: of 65535 in the max_datagram_frame_size transport parameter to TEXT[!SHOULD,implementation]: indicate that this endpoint will accept any DATAGRAM frame that fits TEXT[!SHOULD,implementation]: inside a QUIC packet. TEXT[!MAY,test]: Application TEXT[!MAY,test]: protocols that use DATAGRAM frames MAY choose to only negotiate and TEXT[!MAY,test]: use them in a single direction. TEXT[!MAY,implementation]: When clients use 0-RTT, they MAY store the value of the server's TEXT[!MAY,implementation]: max_datagram_frame_size transport parameter. TEXT[!MUST,todo]: When servers decide TEXT[!MUST,todo]: to accept 0-RTT data, they MUST send a max_datagram_frame_size TEXT[!MUST,todo]: transport parameter greater than or equal to the value they sent to TEXT[!MUST,todo]: the client in the connection where they sent them the TEXT[!MUST,todo]: NewSessionTicket message. TEXT[!MUST,implementation,test]: If a client stores the value of the TEXT[!MUST,implementation,test]: max_datagram_frame_size transport parameter with their 0-RTT state, TEXT[!MUST,implementation,test]: they MUST validate that the new value of the max_datagram_frame_size TEXT[!MUST,implementation,test]: transport parameter sent by the server in the handshake is greater TEXT[!MUST,implementation,test]: than or equal to the stored value; if not, the client MUST terminate TEXT[!MUST,implementation,test]: the connection with error PROTOCOL_VIOLATION. TEXT[!MUST,todo]: Application protocols that use datagrams MUST define how they react TEXT[!MUST,todo]: to the absence of the max_datagram_frame_size transport parameter. SECTION: [Behavior and Usage](#section-5) TEXT[!SHOULD,test]: This frame SHOULD be sent as soon as possible (as determined TEXT[!SHOULD,test]: by factors like congestion control, described below) and MAY be TEXT[!SHOULD,test]: coalesced with other frames. TEXT[!SHOULD,implementation]: When a QUIC endpoint receives a valid DATAGRAM frame, it SHOULD TEXT[!SHOULD,implementation]: deliver the data to the application immediately, as long as it is TEXT[!SHOULD,implementation]: able to process the frame and can store the contents in memory. TEXT[!MUST,implementation]: Like STREAM frames, DATAGRAM frames contain application data and MUST TEXT[!MUST,implementation]: be protected with either 0-RTT or 1-RTT keys. SECTION: [Multiplexing Datagrams](#section-5.1) TEXT[!SHOULD,implementation,test]: QUIC implementations SHOULD present an API to applications to assign TEXT[!SHOULD,implementation,test]: relative priorities to DATAGRAM frames with respect to each other and TEXT[!SHOULD,implementation,test]: to QUIC streams. SECTION: [Acknowledgement Handling](#section-5.2) TEXT[!SHOULD,implementation]: Receivers SHOULD support TEXT[!SHOULD,implementation]: delaying ACK frames (within the limits specified by max_ack_delay) in TEXT[!SHOULD,implementation]: response to receiving packets that only contain DATAGRAM frames, TEXT[!SHOULD,implementation]: since the sender takes no action if these packets are temporarily TEXT[!SHOULD,implementation]: unacknowledged. TEXT[!MAY,todo]: If a sender detects that a packet containing a specific DATAGRAM TEXT[!MAY,todo]: frame might have been lost, the implementation MAY notify the TEXT[!MAY,todo]: application that it believes the datagram was lost. TEXT[!MAY,todo]: Similarly, if a packet containing a DATAGRAM frame is acknowledged, TEXT[!MAY,todo]: the implementation MAY notify the sender application that the TEXT[!MAY,todo]: datagram was successfully transmitted and received. SECTION: [Flow Control](#section-5.3) TEXT[!MAY,todo]: However, since DATAGRAM TEXT[!MAY,todo]: frames are inherently unreliable, they MAY be dropped by the receiver TEXT[!MAY,todo]: if the receiver cannot process them. SECTION: [Congestion Control](#section-5.4) TEXT[!MUST,implementation]: The sender MUST either delay sending the frame until TEXT[!MUST,implementation]: the controller allows it or drop the frame without sending it (at TEXT[!MUST,implementation]: which point it MAY notify the application). SECTION: [Security Considerations](#section-6) TEXT[!MUST,implementation]: All application data TEXT[!MUST,implementation]: transmitted with the DATAGRAM frame, like the STREAM frame, MUST be TEXT[!MUST,implementation]: protected either by 0-RTT or 1-RTT keys. SPECIFICATION: https://www.rfc-editor.org/rfc/rfc9287 SECTION: [The Grease QUIC Bit Transport Parameter](#section-3) TEXT[!MUST,implementation]: The transport parameter is sent with an empty TEXT[!MUST,implementation]: value; an endpoint that understands this transport parameter MUST TEXT[!MUST,implementation]: treat receipt of a non-empty value of the transport parameter as a TEXT[!MUST,implementation]: connection error of type TRANSPORT_PARAMETER_ERROR. TEXT[!MUST,implementation,test]: An endpoint that advertises the grease_quic_bit transport parameter TEXT[!MUST,implementation,test]: MUST accept packets with the QUIC Bit set to a value of 0. SECTION: [Clearing the QUIC Bit](#section-3.1) TEXT[!SHOULD,implementation]: Endpoints that receive the grease_quic_bit transport parameter from a TEXT[!SHOULD,implementation]: peer SHOULD set the QUIC Bit to an unpredictable value unless another TEXT[!SHOULD,implementation]: extension assigns specific meaning to the value of the bit. TEXT[!MAY,todo]: A client MAY also set the QUIC Bit to 0 in Initial, Handshake, or TEXT[!MAY,todo]: 0-RTT packets that are sent prior to receiving transport parameters TEXT[!MAY,todo]: from the server. TEXT[!MUST,implementation]: However, a client MUST NOT set the QUIC Bit to 0 TEXT[!MUST,implementation]: unless the Initial packets it sends include a token provided by the TEXT[!MUST,implementation]: server in a NEW_TOKEN frame (Section 19.7 of [QUIC]), received less TEXT[!MUST,implementation]: than 604800 seconds (7 days) prior on a connection where the server TEXT[!MUST,implementation]: also included the grease_quic_bit transport parameter. TEXT[!MUST,implementation]: A server MUST set the QUIC Bit to 0 only after processing transport TEXT[!MUST,implementation]: parameters from a client. TEXT[!MUST,implementation]: A server MUST NOT remember that a client TEXT[!MUST,implementation]: negotiated the extension in a previous connection and set the QUIC TEXT[!MUST,implementation]: Bit to 0 based on that information. TEXT[!MUST,implementation]: An endpoint MUST NOT set the QUIC Bit to 0 without knowing whether TEXT[!MUST,implementation]: the peer supports the extension. SECTION: [Using the QUIC Bit](#section-3.2) TEXT[!MUST,todo]: Extensions that use the QUIC Bit MUST negotiate their use TEXT[!MUST,todo]: prior to acting on any semantic. SPECIFICATION: https://www.rfc-editor.org/rfc/rfc9368 SECTION: [Definitions](#section-1.2) TEXT[!SHOULD,todo]: Implementations can make this TEXT[!SHOULD,todo]: configurable, and a RECOMMENDED value is one minute. SECTION: [Version Negotiation Mechanism](#section-2) TEXT[!MAY,implementation]: If the server can parse the first flight, it can establish the TEXT[!MAY,implementation]: connection using the client's Chosen Version, or it MAY select any TEXT[!MAY,implementation]: other compatible version, as described in Section 2.3. SECTION: [Incompatible Version Negotiation](#section-2.1) TEXT[!MUST,implementation]: This packet SHALL include each entry TEXT[!MUST,implementation]: from the server's set of Offered Versions (see Section 5) in a TEXT[!MUST,implementation]: Supported Version field. TEXT[!MAY,implementation]: The server MAY add reserved versions (as TEXT[!MAY,implementation]: defined in Section 6.3 of [QUIC]) in Supported Version fields. TEXT[!MUST,implementation]: Upon receiving the Version Negotiation packet, the client SHALL TEXT[!MUST,implementation]: search for a version it supports in the list provided by the server. TEXT[!MUST,implementation]: If it doesn't find one, it SHALL abort the connection attempt. TEXT[!MUST,implementation,test]: Otherwise, it SHALL select a mutually supported version and send a TEXT[!MUST,implementation,test]: new first flight with that version -- this version is now the TEXT[!MUST,implementation,test]: Negotiated Version. TEXT[!MUST,implementation]: Clients TEXT[!MUST,implementation]: MUST NOT send Version Negotiation packets and servers MUST ignore all TEXT[!MUST,implementation]: received Version Negotiation packets. SECTION: [Compatible Versions](#section-2.2) TEXT[!MUST,implementation]: Implementations MUST NOT assume compatibility TEXT[!MUST,implementation]: between versions unless explicitly specified. SECTION: [Compatible Version Negotiation](#section-2.3) TEXT[!MUST,implementation]: In order to perform compatible version negotiation, the server MUST TEXT[!MUST,implementation]: select one of these versions that it (1) supports and (2) knows the TEXT[!MUST,implementation]: client's Chosen Version is compatible with. TEXT[!MUST,implementation]: If the first flight is correctly TEXT[!MUST,implementation]: formatted, then this conversion process cannot fail by definition of TEXT[!MUST,implementation]: the first flight being compatible; if the server is unable to convert TEXT[!MUST,implementation]: the first flight, it MUST abort the handshake. TEXT[!MUST,todo]: If a document specifies that a QUIC version is compatible with TEXT[!MUST,todo]: another, that document MUST specify the mechanism by which clients TEXT[!MUST,todo]: are made aware of the Negotiated Version. TEXT[!SHOULD,todo]: Mutually compatible versions SHOULD use the same mechanism. TEXT[!MUST,todo]: In particular, if the Negotiated Version TEXT[!MUST,todo]: mandates that endpoints perform validations on Handshake packets, TEXT[!MUST,todo]: endpoints MUST also perform such validations on the converted first TEXT[!MUST,todo]: flight. SECTION: [Client Choice of Original Version](#section-2.5) TEXT[!SHOULD,todo]: When the client picks its Original Version, it SHOULD try to avoid TEXT[!SHOULD,todo]: incompatible version negotiation to save a round trip. TEXT[!SHOULD,todo]: Therefore, TEXT[!SHOULD,todo]: the client SHOULD pick an Original Version to maximize the combined TEXT[!SHOULD,todo]: probability that both: SECTION: [Version Information](#section-3) TEXT[!MUST,implementation]: Any version of QUIC that supports this mechanism MUST provide a TEXT[!MUST,implementation]: mechanism to exchange Version Information in both directions during TEXT[!MUST,implementation]: the handshake, such that this data is authenticated. TEXT[implementation]: Version Information { TEXT[implementation]: Chosen Version (32), TEXT[implementation]: Available Versions (32) ..., TEXT[!MUST,implementation]: Note that the TEXT[!MUST,implementation]: version in the Chosen Version field MUST be included in this list TEXT[!MUST,implementation]: to allow the client to communicate the Chosen Version's TEXT[!MUST,implementation]: preference. TEXT[!MAY,implementation]: Note that this preference is only advisory; servers TEXT[!MAY,implementation]: MAY choose to use their own preference instead. TEXT[!MAY,todo]: For the same reason, the TEXT[!MAY,todo]: Available Versions field MAY be empty. TEXT[!MAY,todo]: Clients and servers MAY both include versions following the pattern TEXT[!MAY,todo]: 0x?a?a?a?a in their Available Versions list. SECTION: [Version Downgrade Prevention](#section-4) TEXT[!MUST,implementation,test]: Clients MUST ignore any received Version Negotiation packets that TEXT[!MUST,implementation,test]: contain the Original Version. TEXT[!MUST,implementation,test]: A client that makes a connection TEXT[!MUST,implementation,test]: attempt based on information received from a Version Negotiation TEXT[!MUST,implementation,test]: packet MUST ignore any Version Negotiation packets it receives in TEXT[!MUST,implementation,test]: response to that connection attempt. TEXT[!MUST,implementation]: Both endpoints MUST parse their peer's Version Information during the TEXT[!MUST,implementation]: handshake. TEXT[!MUST,implementation]: If that leads to a parsing failure (for example, if it is TEXT[!MUST,implementation]: too short or if its length is not divisible by four), then the TEXT[!MUST,implementation]: endpoint MUST close the connection; if the connection was using QUIC TEXT[!MUST,implementation]: version 1, that connection closure MUST use a transport error of type TEXT[!MUST,implementation]: TRANSPORT_PARAMETER_ERROR. TEXT[!MUST,implementation,test]: If an endpoint receives a Chosen Version TEXT[!MUST,implementation,test]: equal to zero, or any Available Version equal to zero, it MUST treat TEXT[!MUST,implementation,test]: it as a parsing failure. TEXT[!MUST,implementation]: If a server receives Version Information TEXT[!MUST,implementation]: where the Chosen Version is not included in Available Versions, it TEXT[!MUST,implementation]: MUST treat it as a parsing failure. TEXT[!MUST,implementation]: Every QUIC version that supports version negotiation MUST define a TEXT[!MUST,implementation]: method for closing the connection with a version negotiation error. TEXT[!MUST,implementation]: When the server then processes the client's Version TEXT[!MUST,implementation]: Information, the server MUST validate that the client's Chosen TEXT[!MUST,implementation]: Version matches the version in use for the connection. TEXT[!MUST,implementation]: If the two TEXT[!MUST,implementation]: differ, the server MUST close the connection with a version TEXT[!MUST,implementation]: negotiation error. TEXT[!MUST,implementation]: Subsequently, TEXT[!MUST,implementation]: if the server receives the client's Version Information over QUIC TEXT[!MUST,implementation]: version 1 (as indicated by the Version field of the Long Header TEXT[!MUST,implementation]: packets that carried the transport parameters) and the client's TEXT[!MUST,implementation]: Chosen Version is not set to 0x00000001, the server MUST close the TEXT[!MUST,implementation]: connection with a version negotiation error. TEXT[!MAY,implementation]: Servers MAY complete the handshake even if the Version Information is TEXT[!MAY,implementation]: missing. TEXT[!MUST,implementation]: Clients MUST NOT complete the handshake if they are TEXT[!MUST,implementation]: reacting to a Version Negotiation packet and the Version Information TEXT[!MUST,implementation]: is missing, but MAY do so otherwise. TEXT[!MUST,implementation,test]: If a client receives Version Information where the server's Chosen TEXT[!MUST,implementation,test]: Version was not sent by the client as part of its Available Versions, TEXT[!MUST,implementation,test]: the client MUST close the connection with a version negotiation TEXT[!MUST,implementation,test]: error. TEXT[!MUST,test]: If a client has reacted to a Version Negotiation packet and TEXT[!MUST,test]: the server's Version Information was missing, the client MUST close TEXT[!MUST,test]: the connection with a version negotiation error. TEXT[!MUST,implementation]: If the client received and acted on a Version Negotiation packet, the TEXT[!MUST,implementation]: client MUST validate the server's Available Versions field. TEXT[!MUST,implementation,test]: If the client would have selected a different TEXT[!MUST,implementation,test]: version, the client MUST close the connection with a version TEXT[!MUST,implementation,test]: negotiation error. TEXT[!MUST,implementation]: In particular, if the client reacted to a Version TEXT[!MUST,implementation]: Negotiation packet and the server's Available Versions field is TEXT[!MUST,implementation]: empty, the client MUST close the connection with a version TEXT[!MUST,implementation]: negotiation error. TEXT[!MUST,implementation]: In particular, since the client can be made aware of the TEXT[!MUST,implementation]: Negotiated Version by the QUIC long header version during compatible TEXT[!MUST,implementation]: version negotiation (see Section 2.3), clients MUST validate that the TEXT[!MUST,implementation]: server's Chosen Version is equal to the Negotiated Version; if they TEXT[!MUST,implementation]: do not match, the client MUST close the connection with a version TEXT[!MUST,implementation]: negotiation error. SECTION: [Server Deployments of QUIC](#section-5) TEXT[!SHOULD,todo]: To avoid that, TEXT[!SHOULD,todo]: server operators SHOULD perform a three-step process when they wish TEXT[!SHOULD,todo]: to add or remove support for a version, as described below. SECTION: [Application-Layer Protocol Considerations](#section-6) TEXT[!MUST,todo]: A given ALPN token MUST NOT be used with a new QUIC version that is TEXT[!MUST,todo]: different from the version for which the ALPN token was originally TEXT[!MUST,todo]: defined, unless all the following requirements are met: TEXT[!MUST,implementation]: When incompatible version negotiation is in use, the second TEXT[!MUST,implementation]: connection that is created in response to the received Version TEXT[!MUST,implementation]: Negotiation packet MUST restart its application-layer protocol TEXT[!MUST,implementation]: negotiation process without taking into account the Original Version. SECTION: [Considerations for Future Versions](#section-7) TEXT[!SHOULD,todo]: In order to facilitate the deployment of future versions of QUIC, TEXT[!SHOULD,todo]: designers of future versions SHOULD attempt to design their new TEXT[!SHOULD,todo]: version such that commonly deployed versions are compatible with it. SECTION: [Interaction with Retry](#section-7.1) TEXT[!MUST,todo]: If a future document wishes to define compatibility between two TEXT[!MUST,todo]: versions that support Retry, that document MUST specify how version TEXT[!MUST,todo]: negotiation (both compatible and incompatible) interacts with Retry TEXT[!MUST,todo]: during a handshake that requires both. SECTION: [Interaction with TLS Resumption](#section-7.2) TEXT[!SHOULD,todo]: New versions that also use TEXT[!SHOULD,todo]: TLS 1.3 SHOULD mandate that their session tickets are tightly scoped TEXT[!SHOULD,todo]: to one version of QUIC, i.e., require that clients not use them TEXT[!SHOULD,todo]: across multiple version and that servers validate this client TEXT[!SHOULD,todo]: requirement. SECTION: [Interaction with 0-RTT](#section-7.3) TEXT[!MUST,todo]: If a future document TEXT[!MUST,todo]: wishes to define compatibility between two versions that support TEXT[!MUST,todo]: 0-RTT, that document MUST address the scenario where there are 0-RTT TEXT[!MUST,todo]: packets in the client's first flight. SECTION: [Special Handling for QUIC Version 1](#section-8) TEXT[!MUST,todo]: Because QUIC version 1 was the only QUIC version that was published TEXT[!MUST,todo]: on the IETF Standards Track before this document, it is handled TEXT[!MUST,todo]: specially as follows: if a client is starting a QUIC version 1 TEXT[!MUST,todo]: connection in response to a received Version Negotiation packet and TEXT[!MUST,todo]: the version_information transport parameter is missing from the TEXT[!MUST,todo]: server's transport parameters, then the client SHALL proceed as if TEXT[!MUST,todo]: the server's transport parameters contained a version_information TEXT[!MUST,todo]: transport parameter with a Chosen Version set to 0x00000001 and an TEXT[!MUST,todo]: Available Version list containing exactly one version set to TEXT[!MUST,todo]: 0x00000001. TEXT[!MUST,todo]: Note that implementations that TEXT[!MUST,todo]: wish to use version negotiation to negotiate versions other than QUIC TEXT[!MUST,todo]: version 1 MUST implement the version negotiation mechanism defined in TEXT[!MUST,todo]: this document. SPECIFICATION: https://www.rfc-editor.org/rfc/rfc9369 SECTION: [Differences with QUIC Version 1](#section-3) TEXT[!MUST,implementation,test]: Except for a few differences, QUIC version 2 endpoints MUST implement TEXT[!MUST,implementation,test]: the QUIC version 1 specification as described in [QUIC], [QUIC-TLS], TEXT[!MUST,implementation,test]: and [QUIC-RECOVERY]. SECTION: [Version Negotiation Considerations](#section-4) TEXT[!SHOULD,implementation,test]: As TEXT[!SHOULD,implementation,test]: this mechanism does not currently distinguish between QUIC versions, TEXT[!SHOULD,implementation,test]: HTTP servers SHOULD support multiple versions to reduce the TEXT[!SHOULD,implementation,test]: probability of incompatibility and the cost associated with QUIC TEXT[!SHOULD,implementation,test]: version negotiation or TCP fallback. TEXT[!MUST,implementation]: Any QUIC endpoint that supports QUIC version 2 MUST send, process, TEXT[!MUST,implementation]: and validate the version_information transport parameter specified in TEXT[!MUST,implementation]: [QUIC-VN] to prevent version downgrade attacks. TEXT[!SHOULD,implementation,test]: Endpoints that support both TEXT[!SHOULD,implementation,test]: versions SHOULD support compatible version negotiation to avoid a TEXT[!SHOULD,implementation,test]: round trip. SECTION: [Compatible Negotiation Requirements](#section-4.1) TEXT[!MUST,implementation]: If the server sends a Retry packet, it MUST use the original version. TEXT[!MUST,implementation]: The client TEXT[!MUST,implementation]: MUST NOT use a different version in the subsequent Initial packet TEXT[!MUST,implementation]: that contains the Retry token. TEXT[!MAY,implementation]: The server MAY encode the QUIC TEXT[!MAY,implementation]: version in its Retry token to validate that the client did not switch TEXT[!MAY,implementation]: versions, and drop the packet if it switched, to enforce client TEXT[!MAY,implementation]: compliance. TEXT[!MUST,implementation]: After switching to a negotiated version TEXT[!MUST,implementation]: after a Retry, the server MUST include the relevant transport TEXT[!MUST,implementation]: parameters to validate that the server sent the Retry and the TEXT[!MUST,implementation]: connection IDs used in the exchange, as described in Section 7.3 of TEXT[!MUST,implementation]: [QUIC]. TEXT[implementation]: The server cannot send CRYPTO frames until it has processed the TEXT[implementation]: client's transport parameters. TEXT[!MUST,implementation,test]: The server MUST send all CRYPTO TEXT[!MUST,implementation,test]: frames using the negotiated version. TEXT[implementation]: Before the server is able to process transport parameters from the TEXT[implementation]: client, it might need to respond to Initial packets from the client. TEXT[implementation]: For these packets, the server uses the original version. TEXT[!SHOULD,implementation,test]: Once the client has learned the negotiated version, it SHOULD send TEXT[!SHOULD,implementation,test]: subsequent Initial packets using that version. TEXT[!MUST,todo]: The server MUST NOT TEXT[!MUST,todo]: discard its original version Initial receive keys until it TEXT[!MUST,todo]: successfully processes a Handshake packet with the negotiated TEXT[!MUST,todo]: version. TEXT[!MUST,implementation,test]: Both endpoints MUST send Handshake and 1-RTT packets using the TEXT[!MUST,implementation,test]: negotiated version. TEXT[!MUST,implementation]: An endpoint MUST drop packets using any other TEXT[!MUST,implementation]: version. TEXT[!MUST,todo]: The client MUST NOT send 0-RTT packets using the negotiated version, TEXT[!MUST,todo]: even after processing a packet of that version from the server. SECTION: [TLS Resumption and NEW_TOKEN Tokens](#section-5) TEXT[!MUST,implementation]: Clients MUST NOT use a TEXT[!MUST,implementation]: session ticket or token from a QUIC version 1 connection to initiate TEXT[!MUST,implementation]: a QUIC version 2 connection, and vice versa. TEXT[implementation]: When a connection TEXT[implementation]: includes compatible version negotiation, any issued server tokens are TEXT[implementation]: considered to originate from the negotiated version, not the original TEXT[implementation]: one. TEXT[!MUST,todo]: Servers MUST validate the originating version of any session ticket TEXT[!MUST,todo]: or token and not accept one issued from a different version.