From 56d6954e4043bd678a49586eeb593982d58862e9 Mon Sep 17 00:00:00 2001 From: mirjak Date: Fri, 10 Aug 2018 16:40:48 +0200 Subject: [PATCH 1/5] Editorial pass Up to section 6.6.2 --- draft-ietf-quic-transport.md | 198 +++++++++++++++++++---------------- 1 file changed, 110 insertions(+), 88 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index c7637cb495..a726620509 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -131,17 +131,23 @@ QUIC implements techniques learned from experience with TCP, SCTP and other transport protocols. QUIC uses UDP as substrate so as to not require changes to legacy client operating systems and middleboxes to be deployable. QUIC authenticates all of its headers and encrypts most of the data it exchanges, -including its signaling. This allows the protocol to evolve without incurring a -dependency on upgrades to middleboxes. This document describes the core QUIC +including its signaling. This allows the protocol to evolve by minimizing +dependencies on upgrades to middleboxes. This document describes the core QUIC protocol, including the conceptual design, wire format, and mechanisms of the QUIC protocol for connection establishment, stream multiplexing, stream and connection-level flow control, connection migration, and data reliability. -Accompanying documents describe QUIC's loss detection and congestion control -{{QUIC-RECOVERY}}, and the use of TLS 1.3 for key negotiation {{QUIC-TLS}}. +An accompanying document describes QUIC's loss detection and congestion control +{{QUIC-RECOVERY}}. As these are sender-side only mechanisms they can be changed +without negotiating a new QUIC version. This document specifies version +0x00000001 of QUIC which uses TLS1.3 for key negotiation as described in +{{QUIC-TLS}}. Key negotiation and encryption is described in a separate +docuement to make changes to only this part easier in future versions. -QUIC version 1 conforms to the protocol invariants in {{QUIC-INVARIANTS}}. +All versions of QUIC MUST conform to the protocol invariants in +{{QUIC-INVARIANTS}}. +QUIC is a name, not an acronym. # Conventions and Definitions @@ -182,7 +188,15 @@ QUIC packet: : A well-formed UDP payload that can be parsed by a QUIC receiver. -QUIC is a name, not an acronym. +0-RTT: + +: QUIC packets containing application payload data that are encrypted with + a key derived from previous QUIC connection to the same endpoint. + +1-RTT: + +: QUIC packets that are encrypted with keys derived from the QUIC + handshake. ## Notational Conventions @@ -293,8 +307,8 @@ Long headers are used for packets that are sent prior to the completion of version negotiation and establishment of 1-RTT keys. Once both conditions are met, a sender switches to sending packets using the short header ({{short-header}}). The long form allows for special packets - such as the -Version Negotiation packet - to be represented in this uniform fixed-length -packet format. Packets that use the long header contain the following fields: +Version Negotiation packet - to be represented in this uniform packet format. +Packets that use the long header contain the following fields: Header Form: @@ -380,7 +394,8 @@ covers the both the Packet Number and Payload fields, both of which are confidentiality protected and initially of unknown length. The size of the Payload field is learned once the packet number protection is removed. -Senders can sometimes coalesce multiple packets into one UDP datagram. See +The length field is used to enable senders to coalesce multiple long-header +packets and potentially one short-header packet into one UDP datagram. See {{packet-coalesce}} for more details. @@ -466,16 +481,16 @@ Protected Payload: : Packets with a short header always include a 1-RTT protected payload. -The header form and connection ID field of a short header packet are -version-independent. The remaining fields are specific to the selected QUIC -version. See {{QUIC-INVARIANTS}} for details on how packets from different -versions of QUIC are interpreted. +The header form and connection ID field, if present, of a short header packet +areversion-independent. The remaining fields are specific to the selected +QUIC version. See {{QUIC-INVARIANTS}} for details on how packets from +different versions of QUIC are interpreted. ## Version Negotiation Packet {#packet-version} A Version Negotiation packet is inherently not version-specific, and does not -use the long packet header (see {{long-header}}. Upon receipt by a client, it +use the long packet header (see {{long-header}}). Upon receipt by a client, it will appear to be a packet using the long header, but will be identified as a Version Negotiation packet based on the Version field having a value of 0. @@ -736,11 +751,11 @@ the Source Connection ID includes the connection ID that the sender of the packet wishes to use (see {{connection-id}}). The server MUST use consistent Source Connection IDs during the handshake. -On first receiving an Initial or Retry packet from the server, the client uses -the Source Connection ID supplied by the server as the Destination Connection ID -for subsequent packets. Once a client has received an Initial packet from the -server, it MUST discard any packet it receives with a different Source -Connection ID. +On first receiving an Initial or Retry packet from the server, the client MUST +use the Source Connection ID supplied by the server as the Destination +Connection ID for subsequent packets. Once a client has received an Initial +packet from the server, it MUST discard any packet it receives with a different +Source Connection ID. ### Tokens @@ -842,18 +857,21 @@ used to carry acknowledgments and cryptographic handshake messages from the server and client. A server sends its cryptographic handshake in one or more Handshake packets in -response to an Initial packet if it does not send a Retry packet. Once a client -has received a Handshake packet from a server, it uses Handshake packets to send -subsequent cryptographic handshake messages and acknowledgments to the server. +response to an Initial packet (in addition to the server Initial packet) if it +does not send a Retry packet. Once a client has received a Handshake packet +from a server, it uses Handshake packets to send subsequent cryptographic +handshake messages and acknowledgments to the server. The Destination Connection ID field in a Handshake packet contains a connection -ID that is chosen by the recipient of the packet; the Source Connection ID -includes the connection ID that the sender of the packet wishes to use (see -{{connection-id-encoding}}). +ID that is chosen by the other endpoint of this connection as indicated in +Source Connection ID field of the previously received Initial packet from that +endpoint; the Source Connection ID includes the connection ID that the +sender of the packet wishes to use (see {{connection-id-encoding}}). -The first Handshake packet sent by a server contains a packet number of 0. -Handshake packets are their own packet number space. Packet numbers are -incremented normally for other Handshake packets. +The first Handshake packet sent by a server contains a packet number of 0. +Handshake packets are their own packet number space. See section +{{packet-numbers}} on packet number spaces. Packet numbers are incremented +normally for other Handshake packets. Servers MUST NOT send more than three datagrams including Initial and Handshake packets without receiving a packet from a verified source address. Source @@ -873,7 +891,8 @@ static handshake keys or the 0-RTT keys are sent with long headers; all packets protected with 1-RTT keys are sent with short headers. The different packet types explicitly indicate the encryption level and therefore the keys that are used to remove packet protection. 0-RTT and 1-RTT protected packets share a -single packet number space. +single packet number space. Initial and Handshake packets both have their own +packet number space. Packets protected with handshake keys only use packet protection to ensure that the sender of the packet is on the network path. This packet protection is not @@ -889,23 +908,24 @@ Packets protected with 0-RTT keys use a type value of 0x7C. The connection ID fields for a 0-RTT packet MUST match the values used in the Initial packet ({{packet-initial}}). -The client can send 0-RTT packets after receiving an Initial -{{packet-initial}} or Handshake ({{packet-handshake}}) packet, if that +The client can send further 0-RTT packets after receiving an Initial +({{packet-initial}}) or Handshake ({{packet-handshake}}) packet, if that packet does not complete the handshake. Even if the client receives a different connection ID in the Handshake packet, it MUST continue to use the same Destination Connection ID for 0-RTT packets, see {{connection-id-encoding}}. -The version field for protected packets is the current QUIC version. +The version field for protected packets contains the current QUIC version. The packet number field contains a packet number, which has additional confidentiality protection that is applied after packet protection is applied (see {{QUIC-TLS}} for details). The underlying packet number increases with each packet sent, see {{packet-numbers}} for details. -The payload is protected using authenticated encryption. {{QUIC-TLS}} describes -packet protection in detail. After decryption, the plaintext consists of a -sequence of frames, as described in {{frames}}. +The content of 0-RTT and 1-RTT packets is protected using authenticated +encryption. {{QUIC-TLS}}vdescribes packet protection in detail. After +decryption, the plaintext consistsvof a sequence of frames, as described in +{{frames}}. ## Coalescing Packets {#packet-coalesce} @@ -914,14 +934,13 @@ A sender can coalesce multiple QUIC packets (typically a Cryptographic Handshake packet and a Protected packet) into one UDP datagram. This can reduce the number of UDP datagrams needed to send application data during the handshake and immediately afterwards. It is not necessary for senders to coalesce -packets, though failing to do so will require sending a significantly -larger number of datagrams during the handshake. Receivers MUST -be able to process coalesced packets. +packets, though not doing it leads larger number of datagrams during the +handshake. Receivers MUST be able to process coalesced packets. Senders SHOULD coalesce packets in order of increasing encryption levels (Initial, Handshake, 0-RTT, 1-RTT), as this makes it more likely the receiver will be able to process all the packets in a single pass. A packet with a short -header does not include a length, so it will always be the last packet included +header does not include a length, so it can only be the last packet included in a UDP datagram. Senders MUST NOT coalesce QUIC packets with different Destination Connection @@ -932,9 +951,8 @@ datagram. Every QUIC packet that is coalesced into a single UDP datagram is separate and complete. Though the values of some fields in the packet header might be redundant, no fields are omitted. The receiver of coalesced QUIC packets MUST -individually process each QUIC packet and separately acknowledge them, as if -they were received as the payload of different UDP datagrams. If one or more -packets in a datagram cannot be processed yet (because the keys are not yet +individually process each QUIC packet and separately acknowledge them. If one or +more packets in a datagram cannot be processed yet (because the keys are not yet available) or processing fails (decryption failure, unknown type, etc.), the receiver MUST still attempt to process the remaining packets. The skipped packets MAY either be discarded or buffered for later processing, just as if the @@ -996,7 +1014,7 @@ response to connection migration ({{migration}}). NEW_CONNECTION_ID frames The packet number is an integer in the range 0 to 2^62-1. The value is used in determining the cryptographic nonce for packet encryption. Each endpoint -maintains a separate packet number for sending and receiving. +maintains separate packet number spaces for sending and receiving. Packet numbers are divided into 3 spaces in QUIC: @@ -1114,7 +1132,8 @@ Stateless Reset do not contain frames. Protected payloads MUST contain at least one frame, and MAY contain multiple frames and multiple frame types. -Frames MUST fit within a single QUIC packet and MUST NOT span a QUIC packet +Frames MUST fit within a single QUIC packet, and therefore within a single +UDP datagram, and MUST NOT span a QUIC packet boundary. Each frame begins with a Frame Type, indicating its type, followed by additional type-dependent fields: @@ -1184,7 +1203,9 @@ endpoint cannot send a frame of a type that is unknown to its peer. An extension to QUIC that wishes to use a new type of frame MUST first ensure that a peer is able to understand the frame. An endpoint can use a transport parameter to signal its willingness to receive one or more extension frame types -with the one transport parameter. +with the one transport parameter. Otherwise it is assumed that enpoints have +knowledge about which (extension) frame types are supported by the otherwise, e.g. +through out of band negotiation. An IANA registry is used to manage the assignment of frame types, see {{iana-frames}}. @@ -1196,9 +1217,9 @@ A QUIC connection is a single conversation between two QUIC endpoints. QUIC's connection establishment intertwines version negotiation with the cryptographic and transport handshakes to reduce connection establishment latency, as described in {{handshake}}. Once established, a connection may migrate to a -different IP or port at either endpoint, due to NAT rebinding or mobility, as -described in {{migration}}. Finally a connection may be terminated by either -endpoint, as described in {{termination}}. +different IP address and/or port number at either endpoint, due to NAT rebinding +or mobility, as described in {{migration}}. Finally a connection may be terminated +by either endpoint, as described in {{termination}}. ## Connection ID @@ -1207,18 +1228,21 @@ distinguish it from other connections. A connection ID can be either 0 octets in length, or between 4 and 18 octets (inclusive). Connection IDs are selected independently in each direction. -The primary function of a connection ID is to ensure that changes in addressing -at lower protocol layers (UDP, IP, and below) don't cause packets for a QUIC -connection to be delivered to the wrong endpoint. Each endpoint selects -connection IDs using an implementation-specific (and perhaps +The primary function of a connection ID is to ensure packets can still be +assotiated with the right connection at the receiver if changes in sender +addressing at lower protocol layers (UDP, IP, and below) occur. The Connection ID +is visibe to the path to also enable the network to deliver packets for a QUIC +connection to the right endpoint after an address change if load balancing is used. +Each endpoint selects connection IDs using an implementation-specific (and perhaps deployment-specific) method which will allow packets with that connection ID to be routed back to the endpoint and identified by the endpoint upon receipt. A zero-length connection ID MAY be used when the connection ID is not needed for -routing and the address/port tuple of packets is sufficient to associate them to -a connection. An endpoint whose peer has selected a zero-length connection ID -MUST continue to use a zero-length connection ID for the lifetime of the -connection and MUST NOT send packets from any other local address. +routing and the address/port tuple of packets is assumed to be sufficiently stable +to associate them to a connection. An endpoint whose peer has selected a +zero-length connection ID MUST continue to use a zero-length connection ID for the +lifetime of the connection and cannot send packets from any other local address +without breaking the connection. When an endpoint has requested a non-zero-length connection ID, it will issue a series of connection IDs over the lifetime of a connection. The series of @@ -1259,8 +1283,8 @@ Incoming packets are classified on receipt. Packets can either be associated with an existing connection, or - for servers - potentially create a new connection. -Hosts try to associate a packet with an existing connection. If the packet has a -Destination Connection ID corresponding to an existing connection, QUIC +Endpoints try to associate a packet with an existing connection. If the packet +has a Destination Connection ID corresponding to an existing connection, QUIC processes that packet accordingly. Note that more than one connection ID can be associated with a connection; see {{connection-id}}. @@ -1276,7 +1300,7 @@ correspond to a single connection. Valid packets sent to clients always include a Destination Connection ID that matches the value the client selects. Clients that choose to receive zero-length connection IDs can use the address/port tuple to identify a -connection. Packets that don't match an existing connection MAY be discarded. +connection. Packets that do not match an existing connection MAY be discarded. Due to packet reordering or loss, clients might receive packets for a connection that are encrypted with a key it has not yet computed. Clients MAY drop these @@ -1303,25 +1327,24 @@ the packet. Servers SHOULD NOT attempt to decode or decrypt a packet from an unknown version, but instead send a Version Negotiation packet, provided that the packet is sufficiently long. -Servers MUST drop other packets that contain unsupported versions. - -Packets with a supported version, or no version field, are matched to -a connection as described in {{packet-handling}}. If not matched, the -server continues below. +Servers MUST drop packets without sending a Version Negotiation packet when the +received packet contains unsupported versions and is too small +to be an Initial packet for some version supported by the server. -If the packet is an Initial packet fully conforming with the specification, the +If the packet is an Initial packet fully conforming with this specification, the server proceeds with the handshake ({{handshake}}). This commits the server to -the version that the client selected. - -If a server isn't currently accepting any new connections, it SHOULD send a -Handshake packet containing a CONNECTION_CLOSE frame with error code -SERVER_BUSY. +the version that the client selected. If a server isn't currently accepting any +new connections, it SHOULD send a Handshake packet containing a CONNECTION_CLOSE +frame with error code SERVER_BUSY. -If the packet is a 0-RTT packet, the server MAY buffer a limited -number of these packets in anticipation of a late-arriving Initial -Packet. Clients are forbidden from sending Handshake packets prior to +If the packet is a 0-RTT packet with a supported version number, the server MAY +buffer a limited number of these packets in anticipation of a late-arriving +Initial Packet. Clients are forbidden from sending Handshake packets prior to receiving a server response, so servers SHOULD ignore any such packets. +Packets with a supported version, or no version field, are matched to +a connection as described in {{packet-handling}}. + Servers MUST drop incoming packets under all other circumstances. They SHOULD send a Stateless Reset ({{stateless-reset}}) if a connection ID is present in the header. @@ -1329,8 +1352,9 @@ is present in the header. ## Version Negotiation Version negotiation ensures that client and server agree to a QUIC version -that is mutually supported. A server sends a Version Negotiation packet in -response to each packet that might initiate a new connection, see +that is mutually supported independent of the implemented version. A server +can send a Version Negotiation packet in response to each packet that might +initiate a new connection and is sufficiently large, see also {{packet-handling}} for details. The size of the first packet sent by a client will determine whether a server @@ -1363,12 +1387,8 @@ selects an acceptable protocol version from the list provided by the server. The client then attempts to create a connection using that version. Though the contents of the Initial packet the client sends might not change in response to version negotiation, a client MUST increase the packet number it -uses on every packet it sends. Packets MUST continue to use long headers and -MUST include the new negotiated protocol version. - -The client MUST use the long header format and include its selected version on -all packets until it has 1-RTT keys and it has received a packet from the server -which is not a Version Negotiation packet. +uses on every packet it sends. The client MUST use the long header format and +include its selected version on all packets until it has 1-RTT keys. A client MUST NOT change the version it uses unless it is in response to a Version Negotiation packet from the server. Once a client receives a packet @@ -1443,15 +1463,16 @@ that meets the requirements of the cryptographic handshake protocol: client can receive packets that are addressed with the transport address that is claimed by the client (see {{address-validation}}) -The initial CRYPTO frame MUST be sent in a single packet. Any second attempt -that is triggered by address validation MUST also be sent within a single -packet. This avoids having to reassemble a message from multiple packets. +The initial CRYPTO frame MUST be sent in a single QUIC packet and therefore +also within a single UDP datagram. Any second attempt that is triggered by +address validation MUST also be sent within a single packet. This avoids having +to reassemble a message from multiple packets. -The first client packet of the cryptographic handshake protocol MUST fit within +The first client message of the cryptographic handshake protocol MUST fit within a 1232 octet QUIC packet payload. This includes overheads that reduce the space available to the cryptographic handshake protocol. -The CRYPTO frame can be sent in different packet number spaces. CRYPTO frames +The CRYPTO frames can be sent in different packet number spaces. CRYPTO frames in each packet number space carry a separate sequence of handshake data starting from an offset of 0. @@ -1585,7 +1606,8 @@ included in the cryptographic handshake. Once the handshake completes, the transport parameters declared by the peer are available. Each endpoint validates the value provided by its peer. In particular, version negotiation MUST be validated (see {{version-validation}}) before the connection -establishment is considered properly complete. +establishment is considered properly complete. Each transport parameter consists +of an 2-byte parameter ID and an optional parameter value. Definitions for each of the defined transport parameters are included in {{transport-parameter-definitions}}. Any given parameter MUST appear @@ -1661,7 +1683,7 @@ disable_migration (0x0009): : The endpoint does not support connection migration ({{migration}}). Peers MUST NOT send any packets, including probing packets ({{probing}}), from a local address other than that used to perform the handshake. This parameter is a - zero-length value. + zero-length value. Values other than 0 and 1 are invalid. Either peer MAY advertise an initial value for the flow control on each type of stream on which they might receive data. Each of the following transport From 835b1e53d834d5e2960cbc1215a8a73f49106ade Mon Sep 17 00:00:00 2001 From: mirjak Date: Wed, 15 Aug 2018 18:12:42 +0200 Subject: [PATCH 2/5] Full editorial pass --- draft-ietf-quic-transport.md | 325 +++++++++++++++++++---------------- 1 file changed, 176 insertions(+), 149 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index a726620509..5f6ec73528 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1599,7 +1599,12 @@ language from Section 3 of {{!TLS13=I-D.ietf-tls-tls13}}. The `extension_data` field of the quic_transport_parameters extension defined in {{QUIC-TLS}} contains a TransportParameters value. TLS encoding rules are -therefore used to encode the transport parameters. +therefore used to encode the transport parameters. As show in +{{figure-transport-parameters}} TransportParameters consists of either an +indication of the initial version used by the client or the negotiated version +and supported versions provided by the server followed by a list of other +transport parameters that contain a parameter ID and optional value prefixed +by the two bytes length. QUIC encodes transport parameters into a sequence of octets, which are then included in the cryptographic handshake. Once the handshake completes, the @@ -1612,8 +1617,8 @@ of an 2-byte parameter ID and an optional parameter value. Definitions for each of the defined transport parameters are included in {{transport-parameter-definitions}}. Any given parameter MUST appear at most once in a given transport parameters extension. An endpoint MUST -treat receipt of duplicate transport parameters as a connection error of -type TRANSPORT_PARAMETER_ERROR. +treat receipt of duplicate transport parameters or an invalid parameter value +as a connection error of type TRANSPORT_PARAMETER_ERROR. ### Transport Parameter Definitions @@ -1741,11 +1746,11 @@ type TRANSPORT_PARAMETER_ERROR. ### Values of Transport Parameters for 0-RTT {#zerortt-parameters} A client that attempts to send 0-RTT data MUST remember the transport parameters -used by the server. The transport parameters that the server advertises during -connection establishment apply to all connections that are resumed using the -keying material established during that handshake. Remembered transport -parameters apply to the new connection until the handshake completes and new -transport parameters from the server can be provided. +provided by the server in the initial handshake. The transport parameters that +the server advertises during connection establishment apply to all connections +that are resumed using the keying material established during that handshake. +Remembered transport parameters apply to the new connection until the handshake +completes and new transport parameters from the server can be provided. A server can remember the transport parameters that it advertised, or store an integrity-protected copy of the values in the ticket and recover the information @@ -1779,10 +1784,13 @@ for transport parameters cannot be supported. ### New Transport Parameters -New transport parameters can be used to negotiate new protocol behavior. An -endpoint MUST ignore transport parameters that it does not support. Absence of -a transport parameter therefore disables any optional protocol feature that is -negotiated using the parameter. +New transport parameters can be used by the client to negotiate new protocol +behavior. An endpoint MUST ignore transport parameters that it does not support. +Absence of a transport parameter as provided by the server therefore disables +any optional protocol feature that is negotiated using the parameter. A server +cannot negotiation new features but can indicate the support of a new feature +that is ready to be used by the client. Howeverm it cannot assume that the client +understand the parameter and is ready to use that feature. New transport parameters can be registered according to the rules in {{iana-transport-parameters}}. @@ -1790,16 +1798,14 @@ New transport parameters can be registered according to the rules in ### Version Negotiation Validation {#version-validation} -Though the cryptographic handshake has integrity protection, two forms of QUIC -version downgrade are possible. In the first, an attacker replaces the QUIC -version in the Initial packet. In the second, a fake Version Negotiation packet -is sent by an attacker. To protect against these attacks, the transport -parameters include three fields that encode version information. These -parameters are used to retroactively authenticate the choice of version (see -{{version-negotiation}}). - -The cryptographic handshake provides integrity protection for the negotiated -version as part of the transport parameters (see {{transport-parameters}}). As +Theoretically, two forms of QUIC version downgrade are possible. In the first, +an attacker replaces the QUIC version in the Initial packet. In the second, +a fake Version Negotiation packet is sent by an attacker. To protect against +these attacks, the cryptographic handshake provides integrity protection for +the negotiated version as part of the transport parameters. As described in +{{transport-parameters}} the transport parameters include three fields that +encode version information. These parameters are used to retroactively +authenticate the choice of version (see {{version-negotiation}}). As a result, attacks on version negotiation by an attacker can be detected. The client includes the initial_version field in its transport parameters. The @@ -1827,10 +1833,11 @@ QUIC versions that the server supports. The negotiated_version field is the version that is in use. This MUST be set by the server to the value that is on the Initial packet that it accepts (not an -Initial packet that triggers a Retry or Version Negotiation packet). A client -that receives a negotiated_version that does not match the version of QUIC that -is in use MUST terminate the connection with a VERSION_NEGOTIATION_ERROR error -code. +Initial packet that triggers a Retry or Version Negotiation packet). + +A client that receives a negotiated_version that does not match the version of +QUIC that is in use MUST terminate the connection with a +VERSION_NEGOTIATION_ERROR error code. The server includes a list of versions that it would send in any version negotiation packet ({{packet-version}}) in the supported_versions field. The @@ -2007,14 +2014,16 @@ validation - but a server SHOULD limit the data it sends toward an unvalidated address. Successful completion of the cryptographic handshake implicitly provides proof that the client has received packets from the server. -The client should allow for additional Retry packets being sent in +The client SHOULD allow for additional Retry packets being sent in response to Initial packets sent containing a token. There are several situations in which the server might not be able to use the previously generated token to validate the client's address and must send a new -Retry. A reasonable limit to the number of tries the client allows -for, before giving up, is 3. That is, the client MUST echo the -address validation token from a new Retry packet up to 3 times. After -that, it MAY give up on the connection attempt. +Retry. + +A reasonable limit to the number of tries the client allows for, before giving +up, is 3. That is, the client MUST echo the address validation token from a +new Retry packet up to 3 times. After that, it MAY give up on the connection +attempt. ### Address Validation for Future Connections @@ -2037,7 +2046,9 @@ Thus, a resumption token SHOULD include an expiration time. The server MAY include either an explicit expiration time or an issued timestamp and dynamically calculate the expiration time. It is also unlikely that the client port number is the same on two different connections; validating the port is -therefore unlikely to be successful. +therefore unlikely to be successful. It may also be possible that the client's +IP address has changed, there it is also not recommended to validate the IP +address. ### Address Validation Token Integrity {#token-integrity} @@ -2248,7 +2259,7 @@ against potential attacks as described in {{address-spoofing}} and {{on-path-spoofing}}. An endpoint MAY skip validation of a peer address if that address has been seen recently. -An endpoint only changes the address that it sends packets to in response to the +An endpoint MUST only change the address that it sends packets to in response to the highest-numbered non-probing packet. This ensures that an endpoint does not send packets to an old peer address in the case that it receives reordered packets. @@ -2312,20 +2323,20 @@ validation of the address of the spurious migration to be abandoned. ### Loss Detection and Congestion Control {#migration-cc} The capacity available on the new path might not be the same as the old path. -Packets sent on the old path SHOULD NOT contribute to congestion control or RTT -estimation for the new path. - -On confirming a peer's ownership of its new address, an endpoint SHOULD +On confirming a peer's ownership of its new address, an endpoint MUST immediately reset the congestion controller and round-trip time estimator for -the new path. - -An endpoint MUST NOT return to the send rate used for the previous path unless -it is reasonably sure that the previous send rate is valid for the new path. -For instance, a change in the client's port number is likely indicative of a -rebinding in a middlebox and not a complete change in path. This determination -likely depends on heuristics, which could be imperfect; if the new path capacity -is significantly reduced, ultimately this relies on the congestion controller -responding to congestion signals and reducing send rates appropriately. +the new path unless it is reasonably sure that the actually network path did not +change. For instance, a change in the client's port number is likely indicative +of a rebinding in a middlebox and not a complete change in path. This +determination likely depends on heuristics, which could be imperfect; if the new +path capacity is significantly reduced, ultimately this relies on the congestion +controller responding to congestion signals and reducing send rates +appropriately. + +If the congestion controller has been reset this means that packets sent on the +old path do not contribute to congestion controller or RTT estimation for the new +path and an endpoint MUST NOT return to the send rate used for the previous path +but start in slow start instead. There may be apparent reordering at the receiver when an endpoint sends data and probes from/to multiple addresses during the migration period, since the two @@ -2457,14 +2468,15 @@ of three ways: ### Closing and Draining Connection States {#draining} The closing and draining connection states exist to ensure that connections -close cleanly and that delayed or reordered packets are properly discarded. -These states SHOULD persist for three times the current Retransmission Timeout -(RTO) interval as defined in {{QUIC-RECOVERY}}. +close cleanly and that delayed or reordered packets are properly discarded and +do not interfere with future connections on the same 5-tuple. These states +SHOULD persist for three times the current Retransmission Timeout (RTO) +interval as defined in {{QUIC-RECOVERY}}. An endpoint enters a closing period after initiating an immediate close -({{immediate-close}}). While closing, an endpoint MUST NOT send packets unless -they contain a CONNECTION_CLOSE or APPLICATION_CLOSE frame (see -{{immediate-close}} for details). +({{immediate-close}}). In the closing period, an endpoint MUST NOT send +packets unless they only contain a CONNECTION_CLOSE or APPLICATION_CLOSE frame +(see {{immediate-close}} for details). In the closing state, only a packet containing a closing frame can be sent. An endpoint retains only enough information to generate a packet containing a @@ -2582,11 +2594,16 @@ properly continue the connection. An endpoint that wishes to communicate a fatal connection error MUST use a closing frame if it has sufficient state to do so. -To support this process, a token is sent by endpoints. The token is carried in -the NEW_CONNECTION_ID frame sent by either peer, and servers can specify the -stateless_reset_token transport parameter during the handshake (clients cannot -because their transport parameters don't have confidentiality protection). This -value is protected by encryption, so only client and server know this value. +To support this process, a token is sent by the endpoints that can be recovered +or regenerated by the endpoint based on the information available in each packet +even if the connection state was lost. This provides a protect mechanism to +identify Stateless Reset packets from an attacker. + +The token is carried in the NEW_CONNECTION_ID frame sent by either peer, and +servers can specify the stateless_reset_token transport parameter during the +handshake (clients cannot because their transport parameters don't have +confidentiality protection). This value is protected by encryption, so +only client and server know this value. An endpoint that receives packets that it cannot process sends a packet in the following layout: @@ -2795,7 +2812,7 @@ encoding. The PADDING frame (type=0x00) has no semantic value. PADDING frames can be used to increase the size of a packet. Padding can be used to increase an initial client packet to the minimum required size, or to provide protection against -traffic analysis for protected packets. +traffic analysis for protected packets. PADDING frames need to be acknowleged. A PADDING frame has no content. That is, a PADDING frame consists of the single octet that identifies the frame as a PADDING frame. @@ -3437,7 +3454,10 @@ acknowledged again. Because ACK frames are not sent in response to ACK-only packets, a receiver that is only sending ACK frames will only receive acknowledgements for its packets if the sender includes them in packets with non-ACK frames. A sender SHOULD -bundle ACK frames with other frames when possible. +bundle ACK frames with other frames when possible. A receiver that would only +send ACK frames therefore can trigger an ACK from the sender by sending a +frames that needs to be acknowledged. Knowing which ACKs have been received +enables the enpoint to reduce the ACK frame to a minimum. Endpoints can only acknowledge packets sent in a particular packet number space by sending ACK frames in packets from the same packet @@ -3515,7 +3535,7 @@ CE Count: Endpoints can use PATH_CHALLENGE frames (type=0x0e) to check reachability to the peer and for path validation during connection establishment and connection -migration. +migration, see sections {{migrate-validate}} and {{migration}}. PATH_CHALLENGE frames contain an 8-byte payload. @@ -3722,10 +3742,10 @@ FIN bit. A sender bundles one or more frames in a QUIC packet (see {{frames}}). A sender SHOULD minimize per-packet bandwidth and computational costs by -bundling as many frames as possible within a QUIC packet. A sender MAY wait for -a short period of time to bundle multiple frames before sending a packet that is +bundling multiple frames within a QUIC packet. A sender MAY wait for +a short period of time for additional frames before sending a packet that is not maximally packed, to avoid sending out large numbers of small packets. An -implementation may use knowledge about application sending behavior or +implementation MAY use knowledge about application sending behavior or heuristics to determine whether and for how long to wait. This waiting period is an implementation decision, and an implementation should be careful to delay conservatively, since any delay is likely to increase application-visible @@ -3735,11 +3755,11 @@ latency. ## Packet Processing and Acknowledgment {#processing-and-ack} A packet MUST NOT be acknowledged until packet protection has been successfully -removed and all frames contained in the packet have been processed. Any stream -state transitions triggered by the frame MUST have occurred. For STREAM frames, -this means the data has been enqueued in preparation to be received by the -application protocol, but it does not require that data is delivered and -consumed. +removed and all frames contained in the packet have been processed, including +any stream state transitions triggered by the frame, as described in section +{{stream-states}}. For STREAM frames, this means the data has been enqueued +in preparation to be received by the application protocol, but it does not +require that data is delivered and consumed. Once the packet has been fully processed, a receiver acknowledges receipt by sending one or more ACK frames containing the packet number of the received @@ -3763,7 +3783,7 @@ discussed in more detail in {{QUIC-RECOVERY}}. ## Retransmission of Information -QUIC packets that are determined to be lost are not retransmitted whole. The +QUIC packets that are determined to be lost are not retransmitted. The same applies to the frames that are contained within lost packets. Instead, the information that might be carried in frames is sent again in new frames as needed. @@ -3773,13 +3793,15 @@ been lost. In general, information is sent again when a packet containing that information is determined to be lost and sending ceases when a packet containing that information is acknowledged. -* Data sent in CRYPTO frames are retransmitted according to the rules in - {{QUIC-RECOVERY}}, until either all data has been acknowledged or the crypto - state machine implicitly knows that the peer received the data. +* Data sent in CRYPTO frames is retransmitted if detected as lost, e.g. + according to the rules in section 4.3.1 of {{QUIC-RECOVERY}}, until either all + data has been acknowledged or the crypto state machine implicitly knows that the + peer received the data. -* Application data sent in STREAM frames is retransmitted in new STREAM frames - unless the endpoint has sent a RST_STREAM for that stream. Once an endpoint - sends a RST_STREAM frame, no further STREAM frames are needed. +* Application data sent in STREAM frames is retransmitted if detected as lost, + e.g. according to the rules in {{QUIC-RECOVERY}}, in new STREAM frames unless + the endpoint has sent a RST_STREAM for that stream. Once an endpoint sends a + RST_STREAM frame, no further STREAM frames are needed. * The most recent set of acknowledgments are sent in ACK frames. An ACK frame SHOULD contain all unacknowledged acknowledgments, as described in @@ -3830,7 +3852,8 @@ containing that information is acknowledged. * A liveness or path validation check using PATH_CHALLENGE frames is sent periodically until a matching PATH_RESPONSE frame is received or until there is no remaining need for liveness or path validation checking. PATH_CHALLENGE - frames include a different payload each time they are sent. + frames include a different payload each time they are sent and are therefore + not-retransmittable. * Responses to path validation using PATH_RESPONSE frames are sent just once. A new PATH_CHALLENGE frame will be sent if another PATH_RESPONSE frame is @@ -3842,9 +3865,9 @@ containing that information is acknowledged. * PADDING frames contain no information, so lost PADDING frames do not require repair. -Upon detecting losses, a sender MUST take appropriate congestion control action. -The details of loss detection and congestion control are described in -{{QUIC-RECOVERY}}. +A sender MUST control its sending rate if congestion is detected in line with +the requirements of {{?CCPrinciples=RFC2914}}. The details of loss detection +and congestion control are described in {{QUIC-RECOVERY}}. ## Packet Size {#packet-size} @@ -4059,36 +4082,38 @@ Note: data to a peer. ~~~ - o - | Create Stream (Sending) - | Create Bidirectional Stream (Receiving) - v - +-------+ - | Ready | Send RST_STREAM - | |-----------------------. - +-------+ | - | | - | Send STREAM / | - | STREAM_BLOCKED | - v | - +-------+ | - | Send | Send RST_STREAM | - | |---------------------->| - +-------+ | - | | - | Send STREAM + FIN | - v v - +-------+ +-------+ - | Data | Send RST_STREAM | Reset | - | Sent +------------------>| Sent | - +-------+ +-------+ - | | - | Recv All ACKs | Recv ACK - v v - +-------+ +-------+ - | Data | | Reset | - | Recvd | | Recvd | - +-------+ +-------+ + o + | Create Stream (Sending) + | Create Bidirectional Stream (Receiving) + v + +-------+ + | Ready | Send RST_STREAM + | |-----------------------. + +-------+ | + | | + | Send STREAM / | + | STREAM_BLOCKED | + v | + +-------+ | +Send STREAM / .-| | | + STREAM_BLOCKED / | | Send | Send RST_STREAM | +Recv MAX_STREAM_DATA '>| |---------------------->| + +-------+ | + | | + | Send STREAM + FIN / | + | Recv STOP_SENDING | + v v + .-+-------+ +-------+ + Recv STOP_SEDNING | | Data | Send RST_STREAM | Reset | + '>| Sent +------------------>| Sent | + +-------+ +-------+ + | | + | Recv All ACKs | Recv ACK + v v + +-------+ +-------+ + | Data | | Reset | + | Recvd | | Recvd | + +-------+ +-------+ ~~~ {: #fig-stream-send-states title="States for Send Streams"} @@ -4100,7 +4125,7 @@ in preparation for sending. The sending part of a bidirectional stream initiated by a peer (type 0 for a server, type 1 for a client) enters the "Ready" state if the receiving part -enters the "Recv" state. +enters the "Recv" state (see Figure {{fig-stream-recv-states}}). Sending the first STREAM or STREAM_BLOCKED frame causes a send stream to enter the "Send" state. An implementation might choose to defer allocating a Stream @@ -4147,37 +4172,38 @@ instead, receive streams track the delivery of data to the application or application protocol some of which cannot be observed by the sender. ~~~ - o - | Recv STREAM / STREAM_BLOCKED / RST_STREAM - | Create Bidirectional Stream (Sending) - | Recv MAX_STREAM_DATA - | Create Higher-Numbered Stream - v - +-------+ - | Recv | Recv RST_STREAM - | |-----------------------. - +-------+ | - | | - | Recv STREAM + FIN | - v | - +-------+ | - | Size | Recv RST_STREAM | - | Known +---------------------->| - +-------+ | - | | - | Recv All Data | - v v - +-------+ +-------+ - | Data | Recv RST_STREAM | Reset | - | Recvd +<-- (optional) --->| Recvd | - +-------+ +-------+ - | | - | App Read All Data | App Read RST - v v - +-------+ +-------+ - | Data | | Reset | - | Read | | Read | - +-------+ +-------+ + o + | Recv STREAM / STREAM_BLOCKED / RST_STREAM + | Create Bidirectional Stream (Sending) + | Recv MAX_STREAM_DATA + | Create Higher-Numbered Stream + v + +-------+ Send STOP_SENDING + .-| |-------------------------------. +Send | | Recv | | + MAX_STREAM_SIZE '>| | Recv RST_STREAM | + +-------+-----------------------. | + | | | + | Recv STREAM + FIN | | + v | v + +-------+ | +-------+ + | Size | | | Wait | + | Known + Recv RST_STREAM | | STOP | + +-------+---------------------->| +-------+ + | | | + | Recv All Data | | Recv + v v | RST_STREAM + +-------+ +------- | + | Data | Recv RST_STREAM | Reset |<--' + | Recvd +<-- (optional) --->| Recvd | + +-------+ +-------+ + | | + | App Read All Data | App Read RST + v v + +-------+ +-------+ + | Data | | Reset | + | Read | | Read | + +-------+ +-------+ ~~~ {: #fig-stream-recv-states title="States for Receive Streams"} @@ -4422,9 +4448,9 @@ STREAM frames ensures that loss recovery, congestion control, and flow control operate effectively. CRYPTO frames SHOULD be prioritized over other streams prior to the completion -of the cryptographic handshake. This includes the retransmission of the second -flight of client handshake messages, that is, the TLS Finished and any client -authentication messages. +of the cryptographic handshake. In {{QUIC-TLS}} this includes the retransmission +of the second flight of client handshake messages, that is the TLS Finished and +any client authentication messages. STREAM data in frames determined to be lost SHOULD be retransmitted before sending new data, unless application priorities indicate otherwise. @@ -4472,7 +4498,8 @@ with the Stream ID set appropriately. A receiver could use the current offset of data consumed to determine the flow control offset to be advertised. A receiver MAY send MAX_STREAM_DATA frames in multiple packets in order to make sure that the sender receives an update before running out of flow control credit, even if -one of the packets is lost. +one of the packets is lost. As soons as the packet with the MAX_STREAM_DATA +frame is acknowlegded, there is no need to send the same max stream limit agian. Connection flow control is a limit to the total bytes of stream data sent in STREAM frames on all streams. A receiver advertises credit for a connection by @@ -4508,7 +4535,7 @@ stream before the RST_STREAM frame, and the receiver MUST use the final offset to account for all bytes sent on the stream in its connection level flow controller. -### Response to a RST_STREAM +## Response to a RST_STREAM RST_STREAM terminates one direction of a stream abruptly. Whether any action or response can or should be taken on the data already received is an @@ -4517,7 +4544,7 @@ RST_STREAM an endpoint will choose to stop sending data in its own direction. If the sender of a RST_STREAM wishes to explicitly state that no future data will be processed, that endpoint MAY send a STOP_SENDING frame at the same time. -### Data Limit Increments {#fc-credit} +## Data Limit Increments {#fc-credit} This document leaves when and how many bytes to advertise in a MAX_DATA or MAX_STREAM_DATA to implementations, but offers a few considerations. These @@ -4546,7 +4573,7 @@ peer-initiated streams close. A receiver MAY also advance the maximum stream ID based on current activity, system conditions, and other environmental factors. -### Blocking on Flow Control {#blocking} +## Blocking on Flow Control {#blocking} If a sender does not receive a MAX_DATA or MAX_STREAM_DATA frame when it has run out of flow control credit, the sender will be blocked and SHOULD send a BLOCKED @@ -4558,7 +4585,7 @@ entire round trip. For smooth operation of the congestion controller, it is generally considered best to not let the sender go into quiescence if avoidable. To avoid blocking a -sender, and to reasonably account for the possibility of loss, a receiver should +sender, and to reasonably account for the possibility of loss, a receiver SHOULD send a MAX_DATA or MAX_STREAM_DATA frame at least two round trips before it expects the sender to get blocked. From 3f61ebcf4bbe3b40b5998e6cbe6e4041ecfb7174 Mon Sep 17 00:00:00 2001 From: mirjak Date: Wed, 15 Aug 2018 18:21:48 +0200 Subject: [PATCH 3/5] tailing spaces... --- draft-ietf-quic-transport.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 5f6ec73528..5f46606615 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -139,8 +139,8 @@ connection-level flow control, connection migration, and data reliability. An accompanying document describes QUIC's loss detection and congestion control {{QUIC-RECOVERY}}. As these are sender-side only mechanisms they can be changed -without negotiating a new QUIC version. This document specifies version -0x00000001 of QUIC which uses TLS1.3 for key negotiation as described in +without negotiating a new QUIC version. This document specifies version +0x00000001 of QUIC which uses TLS1.3 for key negotiation as described in {{QUIC-TLS}}. Key negotiation and encryption is described in a separate docuement to make changes to only this part easier in future versions. @@ -192,11 +192,11 @@ QUIC packet: : QUIC packets containing application payload data that are encrypted with a key derived from previous QUIC connection to the same endpoint. - + 1-RTT: : QUIC packets that are encrypted with keys derived from the QUIC - handshake. + handshake. ## Notational Conventions @@ -868,7 +868,7 @@ Source Connection ID field of the previously received Initial packet from that endpoint; the Source Connection ID includes the connection ID that the sender of the packet wishes to use (see {{connection-id-encoding}}). -The first Handshake packet sent by a server contains a packet number of 0. +The first Handshake packet sent by a server contains a packet number of 0. Handshake packets are their own packet number space. See section {{packet-numbers}} on packet number spaces. Packet numbers are incremented normally for other Handshake packets. @@ -2018,7 +2018,7 @@ The client SHOULD allow for additional Retry packets being sent in response to Initial packets sent containing a token. There are several situations in which the server might not be able to use the previously generated token to validate the client's address and must send a new -Retry. +Retry. A reasonable limit to the number of tries the client allows for, before giving up, is 3. That is, the client MUST echo the address validation token from a @@ -2812,7 +2812,7 @@ encoding. The PADDING frame (type=0x00) has no semantic value. PADDING frames can be used to increase the size of a packet. Padding can be used to increase an initial client packet to the minimum required size, or to provide protection against -traffic analysis for protected packets. PADDING frames need to be acknowleged. +traffic analysis for protected packets. PADDING frames need to be acknowleged. A PADDING frame has no content. That is, a PADDING frame consists of the single octet that identifies the frame as a PADDING frame. @@ -4089,7 +4089,7 @@ data to a peer. +-------+ | Ready | Send RST_STREAM | |-----------------------. - +-------+ | + +-------+ | | | | Send STREAM / | | STREAM_BLOCKED | @@ -4177,7 +4177,7 @@ application protocol some of which cannot be observed by the sender. | Create Bidirectional Stream (Sending) | Recv MAX_STREAM_DATA | Create Higher-Numbered Stream - v + v +-------+ Send STOP_SENDING .-| |-------------------------------. Send | | Recv | | @@ -4190,8 +4190,8 @@ Send | | Recv | | | Size | | | Wait | | Known + Recv RST_STREAM | | STOP | +-------+---------------------->| +-------+ - | | | - | Recv All Data | | Recv + | | | + | Recv All Data | | Recv v v | RST_STREAM +-------+ +------- | | Data | Recv RST_STREAM | Reset |<--' From dee34a1c9119e79177f013a059a6275a4edd6a1b Mon Sep 17 00:00:00 2001 From: mirjak Date: Wed, 15 Aug 2018 18:24:37 +0200 Subject: [PATCH 4/5] still tailing spaces... --- draft-ietf-quic-transport.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 5f46606615..98169d4d13 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -144,7 +144,7 @@ without negotiating a new QUIC version. This document specifies version {{QUIC-TLS}}. Key negotiation and encryption is described in a separate docuement to make changes to only this part easier in future versions. -All versions of QUIC MUST conform to the protocol invariants in +All versions of QUIC MUST conform to the protocol invariants in {{QUIC-INVARIANTS}}. QUIC is a name, not an acronym. @@ -3756,7 +3756,7 @@ latency. A packet MUST NOT be acknowledged until packet protection has been successfully removed and all frames contained in the packet have been processed, including -any stream state transitions triggered by the frame, as described in section +any stream state transitions triggered by the frame, as described in section {{stream-states}}. For STREAM frames, this means the data has been enqueued in preparation to be received by the application protocol, but it does not require that data is delivered and consumed. From 70e97ec0ef373b71bf55ed56e052d5e9227892ba Mon Sep 17 00:00:00 2001 From: mirjak Date: Thu, 16 Aug 2018 13:41:49 +0200 Subject: [PATCH 5/5] Comments form @ianswett, @nibanks, and @MikeBishop --- draft-ietf-quic-transport.md | 174 ++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 86 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 98169d4d13..7c27e76828 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -138,16 +138,14 @@ QUIC protocol for connection establishment, stream multiplexing, stream and connection-level flow control, connection migration, and data reliability. An accompanying document describes QUIC's loss detection and congestion control -{{QUIC-RECOVERY}}. As these are sender-side only mechanisms they can be changed -without negotiating a new QUIC version. This document specifies version -0x00000001 of QUIC which uses TLS1.3 for key negotiation as described in -{{QUIC-TLS}}. Key negotiation and encryption is described in a separate -docuement to make changes to only this part easier in future versions. +{{QUIC-RECOVERY}}. Each implementation of QUIC will unilaterally select a loss +detection and congestion control strategy. A recommended approach is described +in {{QUIC-RECOVERY}}. This document specifies version 0x00000001 of QUIC which +uses TLS 1.3 for key negotiation as described in {{QUIC-TLS}}. Key negotiation +and encryption is described in a separate docuement to make changes to only +this part easier in future versions. -All versions of QUIC MUST conform to the protocol invariants in -{{QUIC-INVARIANTS}}. - -QUIC is a name, not an acronym. +All versions of QUIC conform to the protocol invariants in {{QUIC-INVARIANTS}}. # Conventions and Definitions @@ -190,14 +188,15 @@ QUIC packet: 0-RTT: -: QUIC packets containing application payload data that are encrypted with - a key derived from previous QUIC connection to the same endpoint. +: QUIC packets encrypted with a key derived from previous QUIC connection + to the same endpoint. 1-RTT: : QUIC packets that are encrypted with keys derived from the QUIC handshake. +QUIC is a name, not an acronym. ## Notational Conventions @@ -394,8 +393,8 @@ covers the both the Packet Number and Payload fields, both of which are confidentiality protected and initially of unknown length. The size of the Payload field is learned once the packet number protection is removed. -The length field is used to enable senders to coalesce multiple long-header -packets and potentially one short-header packet into one UDP datagram. See +The length field enables senders to coalesce multiple long-header packets +and potentially one short-header packet into one UDP datagram. See {{packet-coalesce}} for more details. @@ -481,8 +480,8 @@ Protected Payload: : Packets with a short header always include a 1-RTT protected payload. -The header form and connection ID field, if present, of a short header packet -areversion-independent. The remaining fields are specific to the selected +The header form and connection ID field of a short header packet +are version-independent. The remaining fields are specific to the selected QUIC version. See {{QUIC-INVARIANTS}} for details on how packets from different versions of QUIC are interpreted. @@ -869,8 +868,8 @@ endpoint; the Source Connection ID includes the connection ID that the sender of the packet wishes to use (see {{connection-id-encoding}}). The first Handshake packet sent by a server contains a packet number of 0. -Handshake packets are their own packet number space. See section -{{packet-numbers}} on packet number spaces. Packet numbers are incremented +Handshake packets are their own packet number space. (See {{packet-numbers}} +for more information on packet number spaces.) Packet numbers are incremented normally for other Handshake packets. Servers MUST NOT send more than three datagrams including Initial and Handshake @@ -891,8 +890,8 @@ static handshake keys or the 0-RTT keys are sent with long headers; all packets protected with 1-RTT keys are sent with short headers. The different packet types explicitly indicate the encryption level and therefore the keys that are used to remove packet protection. 0-RTT and 1-RTT protected packets share a -single packet number space. Initial and Handshake packets both have their own -packet number space. +single packet number space, while Initial and Handshake packets each have their +own packet number space. Packets protected with handshake keys only use packet protection to ensure that the sender of the packet is on the network path. This packet protection is not @@ -908,7 +907,7 @@ Packets protected with 0-RTT keys use a type value of 0x7C. The connection ID fields for a 0-RTT packet MUST match the values used in the Initial packet ({{packet-initial}}). -The client can send further 0-RTT packets after receiving an Initial +The client can send additional 0-RTT packets after receiving an Initial ({{packet-initial}}) or Handshake ({{packet-handshake}}) packet, if that packet does not complete the handshake. Even if the client receives a different connection ID in the Handshake packet, it MUST continue to @@ -923,8 +922,8 @@ confidentiality protection that is applied after packet protection is applied each packet sent, see {{packet-numbers}} for details. The content of 0-RTT and 1-RTT packets is protected using authenticated -encryption. {{QUIC-TLS}}vdescribes packet protection in detail. After -decryption, the plaintext consistsvof a sequence of frames, as described in +encryption. {{QUIC-TLS}} describes packet protection in detail. After +decryption, the plaintext consists of a sequence of frames, as described in {{frames}}. @@ -934,7 +933,7 @@ A sender can coalesce multiple QUIC packets (typically a Cryptographic Handshake packet and a Protected packet) into one UDP datagram. This can reduce the number of UDP datagrams needed to send application data during the handshake and immediately afterwards. It is not necessary for senders to coalesce -packets, though not doing it leads larger number of datagrams during the +packets, though not doing so leads to a larger number of datagrams during the handshake. Receivers MUST be able to process coalesced packets. Senders SHOULD coalesce packets in order of increasing encryption levels @@ -1132,10 +1131,10 @@ Stateless Reset do not contain frames. Protected payloads MUST contain at least one frame, and MAY contain multiple frames and multiple frame types. -Frames MUST fit within a single QUIC packet, and therefore within a single -UDP datagram, and MUST NOT span a QUIC packet -boundary. Each frame begins with a Frame Type, indicating its type, followed by -additional type-dependent fields: +QUIC packets cannot span multiple datagrams. Therefore frames must fit within +a single QUIC packet and cannot span a QUIC packet boundary. Each frame begins +with a Frame Type, indicating its type, followed by additional type-dependent +fields: ~~~ 0 1 2 3 @@ -1204,8 +1203,8 @@ An extension to QUIC that wishes to use a new type of frame MUST first ensure that a peer is able to understand the frame. An endpoint can use a transport parameter to signal its willingness to receive one or more extension frame types with the one transport parameter. Otherwise it is assumed that enpoints have -knowledge about which (extension) frame types are supported by the otherwise, e.g. -through out of band negotiation. +knowledge about which (extension) frame types are supported by the otherwise, +e.g. through out of band negotiation. An IANA registry is used to manage the assignment of frame types, see {{iana-frames}}. @@ -1218,8 +1217,8 @@ connection establishment intertwines version negotiation with the cryptographic and transport handshakes to reduce connection establishment latency, as described in {{handshake}}. Once established, a connection may migrate to a different IP address and/or port number at either endpoint, due to NAT rebinding -or mobility, as described in {{migration}}. Finally a connection may be terminated -by either endpoint, as described in {{termination}}. +or mobility, as described in {{migration}}. Finally a connection may be +terminated by either endpoint, as described in {{termination}}. ## Connection ID @@ -1229,20 +1228,20 @@ in length, or between 4 and 18 octets (inclusive). Connection IDs are selected independently in each direction. The primary function of a connection ID is to ensure packets can still be -assotiated with the right connection at the receiver if changes in sender -addressing at lower protocol layers (UDP, IP, and below) occur. The Connection ID -is visibe to the path to also enable the network to deliver packets for a QUIC -connection to the right endpoint after an address change if load balancing is used. -Each endpoint selects connection IDs using an implementation-specific (and perhaps -deployment-specific) method which will allow packets with that connection ID to -be routed back to the endpoint and identified by the endpoint upon receipt. +associated with the correct connection at the receiver if changes in sender +addressing at lower protocol layers (UDP, IP, and below) occur. The Connection +ID is visibe to the path to enable load balancers to deliver packets for a +QUIC connection to the correct endpoint despite address changes. Each endpoint +selects connection IDs using an implementation-specific (and perhaps +deployment-specific) method which will allow packets with that connection ID +to be routed back to the endpoint and identified by the endpoint upon receipt. A zero-length connection ID MAY be used when the connection ID is not needed for -routing and the address/port tuple of packets is assumed to be sufficiently stable -to associate them to a connection. An endpoint whose peer has selected a -zero-length connection ID MUST continue to use a zero-length connection ID for the -lifetime of the connection and cannot send packets from any other local address -without breaking the connection. +routing and the address/port tuple of packets is assumed to be sufficiently +stable to associate them to a connection. An endpoint whose peer has selected a +zero-length connection ID MUST continue to use a zero-length connection ID for +the lifetime of the connection and cannot send packets from any other local +address without breaking the connection. When an endpoint has requested a non-zero-length connection ID, it will issue a series of connection IDs over the lifetime of a connection. The series of @@ -1328,8 +1327,9 @@ unknown version, but instead send a Version Negotiation packet, provided that the packet is sufficiently long. Servers MUST drop packets without sending a Version Negotiation packet when the -received packet contains unsupported versions and is too small -to be an Initial packet for some version supported by the server. +received packet indicates an unsupported versions and is too small +to be the first packet that would create a new connection for some version +supported by the server. If the packet is an Initial packet fully conforming with this specification, the server proceeds with the handshake ({{handshake}}). This commits the server to @@ -1352,9 +1352,9 @@ is present in the header. ## Version Negotiation Version negotiation ensures that client and server agree to a QUIC version -that is mutually supported independent of the implemented version. A server +that is mutually supported, independent of the implemented version. A server can send a Version Negotiation packet in response to each packet that might -initiate a new connection and is sufficiently large, see also +initiate a new connection and is sufficiently large; see {{packet-handling}} for details. The size of the first packet sent by a client will determine whether a server @@ -1599,8 +1599,8 @@ language from Section 3 of {{!TLS13=I-D.ietf-tls-tls13}}. The `extension_data` field of the quic_transport_parameters extension defined in {{QUIC-TLS}} contains a TransportParameters value. TLS encoding rules are -therefore used to encode the transport parameters. As show in -{{figure-transport-parameters}} TransportParameters consists of either an +therefore used to encode the transport parameters. As shown in +{{figure-transport-parameters}}, TransportParameters consists of either an indication of the initial version used by the client or the negotiated version and supported versions provided by the server followed by a list of other transport parameters that contain a parameter ID and optional value prefixed @@ -1612,7 +1612,8 @@ transport parameters declared by the peer are available. Each endpoint validates the value provided by its peer. In particular, version negotiation MUST be validated (see {{version-validation}}) before the connection establishment is considered properly complete. Each transport parameter consists -of an 2-byte parameter ID and an optional parameter value. +of an 2-byte parameter ID and a parameter value, prefixed by a 2-byte length +field for the value field which might be zero. Definitions for each of the defined transport parameters are included in {{transport-parameter-definitions}}. Any given parameter MUST appear @@ -1688,7 +1689,7 @@ disable_migration (0x0009): : The endpoint does not support connection migration ({{migration}}). Peers MUST NOT send any packets, including probing packets ({{probing}}), from a local address other than that used to perform the handshake. This parameter is a - zero-length value. Values other than 0 and 1 are invalid. + zero-length value. Either peer MAY advertise an initial value for the flow control on each type of stream on which they might receive data. Each of the following transport @@ -1746,7 +1747,7 @@ type TRANSPORT_PARAMETER_ERROR. ### Values of Transport Parameters for 0-RTT {#zerortt-parameters} A client that attempts to send 0-RTT data MUST remember the transport parameters -provided by the server in the initial handshake. The transport parameters that +provided by the server in the preivous handshake. The transport parameters that the server advertises during connection establishment apply to all connections that are resumed using the keying material established during that handshake. Remembered transport parameters apply to the new connection until the handshake @@ -1785,12 +1786,12 @@ for transport parameters cannot be supported. ### New Transport Parameters New transport parameters can be used by the client to negotiate new protocol -behavior. An endpoint MUST ignore transport parameters that it does not support. -Absence of a transport parameter as provided by the server therefore disables -any optional protocol feature that is negotiated using the parameter. A server -cannot negotiation new features but can indicate the support of a new feature -that is ready to be used by the client. Howeverm it cannot assume that the client -understand the parameter and is ready to use that feature. +behavior. An endpoint MUST ignore transport parameters that it does not +support. Absence of a transport parameter as provided by the server therefore +disables any optional protocol feature that is negotiated using the parameter. +A server cannot negotiate new features but can indicate the support of a new +feature that is ready to be used by the client. However, it cannot assume that +the client understand the parameter and is ready to use that feature. New transport parameters can be registered according to the rules in {{iana-transport-parameters}}. @@ -1803,7 +1804,7 @@ an attacker replaces the QUIC version in the Initial packet. In the second, a fake Version Negotiation packet is sent by an attacker. To protect against these attacks, the cryptographic handshake provides integrity protection for the negotiated version as part of the transport parameters. As described in -{{transport-parameters}} the transport parameters include three fields that +{{transport-parameters}}, the transport parameters include three fields that encode version information. These parameters are used to retroactively authenticate the choice of version (see {{version-negotiation}}). As a result, attacks on version negotiation by an attacker can be detected. @@ -2046,9 +2047,7 @@ Thus, a resumption token SHOULD include an expiration time. The server MAY include either an explicit expiration time or an issued timestamp and dynamically calculate the expiration time. It is also unlikely that the client port number is the same on two different connections; validating the port is -therefore unlikely to be successful. It may also be possible that the client's -IP address has changed, there it is also not recommended to validate the IP -address. +therefore unlikely to be successful. ### Address Validation Token Integrity {#token-integrity} @@ -2259,9 +2258,10 @@ against potential attacks as described in {{address-spoofing}} and {{on-path-spoofing}}. An endpoint MAY skip validation of a peer address if that address has been seen recently. -An endpoint MUST only change the address that it sends packets to in response to the -highest-numbered non-probing packet. This ensures that an endpoint does not send -packets to an old peer address in the case that it receives reordered packets. +An endpoint MUST only change the address that it sends packets to in response to +the highest-numbered non-probing packet. This ensures that an endpoint does not +send packets to an old peer address in the case that it receives reordered +packets. After changing the address to which it sends non-probing packets, an endpoint could abandon any path validation for other addresses. @@ -2333,10 +2333,10 @@ path capacity is significantly reduced, ultimately this relies on the congestion controller responding to congestion signals and reducing send rates appropriately. -If the congestion controller has been reset this means that packets sent on the -old path do not contribute to congestion controller or RTT estimation for the new -path and an endpoint MUST NOT return to the send rate used for the previous path -but start in slow start instead. +If the congestion controller has been reset packets sent on the old path do not +contribute to congestion controller or RTT estimation for the new path and an +endpoint MUST NOT return to the send rate used for the previous path but start +in slow start instead. There may be apparent reordering at the receiver when an endpoint sends data and probes from/to multiple addresses during the migration period, since the two @@ -2474,7 +2474,7 @@ SHOULD persist for three times the current Retransmission Timeout (RTO) interval as defined in {{QUIC-RECOVERY}}. An endpoint enters a closing period after initiating an immediate close -({{immediate-close}}). In the closing period, an endpoint MUST NOT send +({{immediate-close}}). During the closing period, an endpoint MUST NOT send packets unless they only contain a CONNECTION_CLOSE or APPLICATION_CLOSE frame (see {{immediate-close}} for details). @@ -2812,7 +2812,7 @@ encoding. The PADDING frame (type=0x00) has no semantic value. PADDING frames can be used to increase the size of a packet. Padding can be used to increase an initial client packet to the minimum required size, or to provide protection against -traffic analysis for protected packets. PADDING frames need to be acknowleged. +traffic analysis for protected packets. A PADDING frame has no content. That is, a PADDING frame consists of the single octet that identifies the frame as a PADDING frame. @@ -3455,9 +3455,10 @@ Because ACK frames are not sent in response to ACK-only packets, a receiver that is only sending ACK frames will only receive acknowledgements for its packets if the sender includes them in packets with non-ACK frames. A sender SHOULD bundle ACK frames with other frames when possible. A receiver that would only -send ACK frames therefore can trigger an ACK from the sender by sending a -frames that needs to be acknowledged. Knowing which ACKs have been received -enables the enpoint to reduce the ACK frame to a minimum. +send ACK frames therefore can trigger an acknowledgement from the sender by +sending a packets that contains another frame that would elicit an +acknowledgement. Knowing which packets have been acknowledged enables the +enpoint to reduce the ACK frame size to a minimum. Endpoints can only acknowledge packets sent in a particular packet number space by sending ACK frames in packets from the same packet @@ -3745,7 +3746,7 @@ A sender SHOULD minimize per-packet bandwidth and computational costs by bundling multiple frames within a QUIC packet. A sender MAY wait for a short period of time for additional frames before sending a packet that is not maximally packed, to avoid sending out large numbers of small packets. An -implementation MAY use knowledge about application sending behavior or +implementation can use knowledge about application sending behavior or heuristics to determine whether and for how long to wait. This waiting period is an implementation decision, and an implementation should be careful to delay conservatively, since any delay is likely to increase application-visible @@ -3756,7 +3757,7 @@ latency. A packet MUST NOT be acknowledged until packet protection has been successfully removed and all frames contained in the packet have been processed, including -any stream state transitions triggered by the frame, as described in section +any stream state transitions triggered by the frame, as described in {{stream-states}}. For STREAM frames, this means the data has been enqueued in preparation to be received by the application protocol, but it does not require that data is delivered and consumed. @@ -3795,13 +3796,14 @@ containing that information is acknowledged. * Data sent in CRYPTO frames is retransmitted if detected as lost, e.g. according to the rules in section 4.3.1 of {{QUIC-RECOVERY}}, until either all - data has been acknowledged or the crypto state machine implicitly knows that the - peer received the data. + data has been acknowledged or the crypto state machine implicitly knows that + the peer received the data. * Application data sent in STREAM frames is retransmitted if detected as lost, - e.g. according to the rules in {{QUIC-RECOVERY}}, in new STREAM frames unless - the endpoint has sent a RST_STREAM for that stream. Once an endpoint sends a - RST_STREAM frame, no further STREAM frames are needed. + e.g. according to the rules in {{QUIC-RECOVERY}}. New STREAM frames containing + the lost data are generated, unless the endpoint has sent a RST_STREAM for that + stream. Once an endpoint sends a RST_STREAM frame, no further STREAM frames are + needed. * The most recent set of acknowledgments are sent in ACK frames. An ACK frame SHOULD contain all unacknowledged acknowledgments, as described in @@ -4104,7 +4106,7 @@ Recv MAX_STREAM_DATA '>| |---------------------->| | Recv STOP_SENDING | v v .-+-------+ +-------+ - Recv STOP_SEDNING | | Data | Send RST_STREAM | Reset | + Recv STOP_SENDING | | Data | Send RST_STREAM | Reset | '>| Sent +------------------>| Sent | +-------+ +-------+ | | @@ -4125,7 +4127,7 @@ in preparation for sending. The sending part of a bidirectional stream initiated by a peer (type 0 for a server, type 1 for a client) enters the "Ready" state if the receiving part -enters the "Recv" state (see Figure {{fig-stream-recv-states}}). +enters the "Recv" state (see {{fig-stream-recv-states}}). Sending the first STREAM or STREAM_BLOCKED frame causes a send stream to enter the "Send" state. An implementation might choose to defer allocating a Stream @@ -4448,9 +4450,9 @@ STREAM frames ensures that loss recovery, congestion control, and flow control operate effectively. CRYPTO frames SHOULD be prioritized over other streams prior to the completion -of the cryptographic handshake. In {{QUIC-TLS}} this includes the retransmission -of the second flight of client handshake messages, that is the TLS Finished and -any client authentication messages. +of the cryptographic handshake. In {{QUIC-TLS}} this includes the +retransmission of the second flight of client handshake messages, that is, the +TLS Finished and any client authentication messages. STREAM data in frames determined to be lost SHOULD be retransmitted before sending new data, unless application priorities indicate otherwise.