From e15da31e052ab9d8a48fb49feb20c0df61a97d61 Mon Sep 17 00:00:00 2001 From: David Schinazi Date: Mon, 7 Jan 2019 13:30:10 -0800 Subject: [PATCH 001/190] Proposal to make Version Negotiation more like Retry to punt VN to QUICv2 --- draft-ietf-quic-transport.md | 231 ++++++++++++----------------------- 1 file changed, 75 insertions(+), 156 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index fceb18be5c..802e2a90e6 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1086,24 +1086,6 @@ that is mutually supported. A server sends a Version Negotiation packet in response to each packet that might initiate a new connection, see {{packet-handling}} for details. -The first few messages of an exchange between a client attempting to create a -new connection with server is shown in {{fig-vn}}. After version negotiation -completes, connection establishment can proceed, for example as shown in -{{example-handshake-flows}}. - -~~~~ -Client Server - -Packet (v=X) -> - - <- Version Negotiation (supported=Y,Z) - -Packet (v=Y) -> - - <- Packet(s) (v=Y) -~~~~ -{: #fig-vn title="Example Version Negotiation Exchange"} - The size of the first packet sent by a client will determine whether a server sends a Version Negotiation packet. Clients that support multiple QUIC versions SHOULD pad the first packet they send to the largest of the minimum packet sizes @@ -1132,40 +1114,31 @@ expectation that it will eventually receive an Initial packet. ## Handling Version Negotiation Packets {#handle-vn} -When the client receives a Version Negotiation packet, it first checks that the -Destination and Source Connection ID fields match the Source and Destination -Connection ID fields in a packet that the client sent. If this check fails, the -packet MUST be discarded. +How a client reacts to receiving a Version Negotiation packet is left as future +work defined by future versions of QUIC. Future versions of QUIC that define +version negotiation with QUIC version 1 MUST define a mechanism that prevents +version downgrade attacks. -Once the Version Negotiation packet is determined to be valid, the client then -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 -content 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 ({{long-header}}) -and MUST include the new negotiated protocol version. +### Version Negotiation Between Draft Versions -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. +\[\[RFC editor: please remove this section before publication.]] -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 -from the server which is not a Version Negotiation packet, it MUST discard other -Version Negotiation packets on the same connection. Similarly, a client MUST -ignore a Version Negotiation packet if it has already received and acted on a -Version Negotiation packet. +When a draft implementation receives a Version Negotiation packet, it MAY use +it to attempt a new connection with one of the supported versions. -A client MUST ignore a Version Negotiation packet that lists the client's chosen -version. +The client MUST check that Destination Connection ID and Original Destination +Connection ID fields in the Version Negotiation packet match the Source and +Destination Connection ID fields in a packet that the client sent. If this +check fails, the packet MUST be discarded. -A client MAY attempt 0-RTT after receiving a Version Negotiation packet. A -client that sends additional 0-RTT packets MUST NOT reset the packet number to 0 -as a result, see {{retry-0rtt-pn}}. +Once the Version Negotiation packet is determined to be valid, the client then +selects an acceptable protocol version from the list provided by the server. +The client then attempts to create a new connection using that version, and +the Source Connection ID from the Version Negotiation packet as its new +Destination Connection ID. -Version negotiation packets have no cryptographic protection. The result of the -negotiation MUST be revalidated as part of the cryptographic handshake (see -{{version-validation}}). +Note that this mechanism does not protect against downgrade attacks and +MUST NOT be used outside of draft implementations. ## Using Reserved Versions @@ -1214,8 +1187,6 @@ properties: * authenticated values for the transport parameters of the peer (see {{transport-parameters}}) -* authenticated confirmation of version negotiation (see {{version-validation}}) - * authenticated negotiation of an application protocol (TLS uses ALPN {{?RFC7301}} for this purpose) @@ -1242,7 +1213,7 @@ Details of how TLS is integrated with QUIC are provided in {{QUIC-TLS}}, but some examples are provided here. An extension of this exchange to support client address validation is shown in {{validate-retry}}. -Once any version negotiation and address validation exchanges are complete, the +Once any address validation exchanges are complete, the cryptographic handshake is used to agree on cryptographic keys. The cryptographic handshake is carried in Initial ({{packet-initial}}) and Handshake ({{packet-handshake}}) packets. @@ -1372,9 +1343,7 @@ The encoding of the transport parameters is detailed in QUIC includes the encoded transport parameters 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. +available. Each endpoint validates the value provided by its peer. Definitions for each of the defined transport parameters are included in {{transport-parameter-definitions}}. Any given parameter MUST appear at most @@ -1442,76 +1411,6 @@ New transport parameters can be registered according to the rules in {{iana-transport-parameters}}. -### 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-parameter-definitions}}). 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 -initial_version is the version that the client initially attempted to use. If -the server did not send a Version Negotiation packet {{packet-version}}, this -will be identical to the negotiated_version field in the server transport -parameters. - -A server that processes all packets in a stateful fashion can remember how -version negotiation was performed and validate the initial_version value. - -A server that does not maintain state for every packet it receives (i.e., a -stateless server) uses a different process. If the initial_version matches the -version of QUIC that is in use, a stateless server can accept the value. - -If the initial_version is different from the version of QUIC that is in use, a -stateless server MUST check that it would have sent a Version Negotiation packet -if it had received a packet with the indicated initial_version. If a server -would have accepted the version included in the initial_version and the value -differs from the QUIC version that is in use, the server MUST terminate the -connection with a VERSION_NEGOTIATION_ERROR error. - -The server includes both the version of QUIC that is in use and a list of the -QUIC versions that the server supports (see -{{transport-parameter-definitions}}). - -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. - -The server includes a list of versions that it would send in any version -negotiation packet ({{packet-version}}) in the supported_versions field. The -server populates this field even if it did not send a version negotiation -packet. - -The client validates that the negotiated_version is included in the -supported_versions list and - if version negotiation was performed - that it -would have selected the negotiated version. A client MUST terminate the -connection with a VERSION_NEGOTIATION_ERROR error code if the current QUIC -version is not listed in the supported_versions list. A client MUST terminate -with a VERSION_NEGOTIATION_ERROR error code if version negotiation occurred but -it would have selected a different version based on the value of the -supported_versions list. - -When an endpoint accepts multiple QUIC versions, it can potentially interpret -transport parameters as they are defined by any of the QUIC versions it -supports. The version field in the QUIC packet header is authenticated using -transport parameters. The position and the format of the version fields in -transport parameters MUST either be identical across different QUIC versions, or -be unambiguously different to ensure no confusion about their interpretation. -One way that a new format could be introduced is to define a TLS extension with -a different codepoint. - - # Address Validation Address validation is used by QUIC to avoid being used for a traffic @@ -3377,8 +3276,8 @@ Example pseudo-code for packet number decoding can be found in ~~~~~ {: #fig-long-header title="Long Header Packet Format"} -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 +Long headers are used for packets that are sent prior to the 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 @@ -3586,7 +3485,7 @@ The layout of a Version Negotiation packet is: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+ -|1| Unused (7) | +|1|R R R| ODCIL | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Version (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -3596,6 +3495,10 @@ The layout of a Version Negotiation packet is: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Connection ID (0/32..144) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Original Destination Connection ID (0/32..144) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Number of Supported Versions (i) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Supported Version 1 (32) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | [Supported Version 2 (32)] ... @@ -3604,23 +3507,55 @@ The layout of a Version Negotiation packet is: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | [Supported Version N (32)] ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Unused Payload (*) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ {: #version-negotiation-format title="Version Negotiation Packet"} -The value in the Unused field is selected randomly by the server. - The Version field of a Version Negotiation packet MUST be set to 0x00000000. +A Version Negotiation packet contains the following fields: -The server MUST include the value from the Source Connection ID field of the -packet it receives in the Destination Connection ID field. The value for Source -Connection ID MUST be copied from the Destination Connection ID of the received -packet, which is initially randomly selected by a client. Echoing both -connection IDs gives clients some assurance that the server received the packet -and that the Version Negotiation packet was not generated by an off-path -attacker. +Reserved Bits (R): + +: The three bits with a mask of 0x70 of byte 0 are reserved. They MUST be sent + sent as all-zeroes and MUST be ignored upon receipt. + +ODCIL: + +: The four least-significant bits of byte 0 encode the length of the Original + Destination Connection ID field. The length uses the same encoding as the + DCIL and SCIL fields. + +Original Destination Connection ID: + +: The Original Destination Connection ID contains the value of the Destination + Connection ID from the Initial packet that this Version Negotiation packet is + in response to. The length of this field is given in ODCIL. -The remainder of the Version Negotiation packet is a list of 32-bit versions -which the server supports. +Number of Supported Versions: + +: The number of supported versions following this field, encoded as a + variable-length integer ({{integer-encoding}}). This field MUST NOT be zero. + +Supported Versions: + +: A list of 32-bit versions which the server supports. + +Unused Payload: + +: The rest of the packet after the supported versions is currently unused. + It MUST be sent empty and MUST be silently ignored upon reception. This + allows future extensibility of Version Negotiation packets. + + +The server MUST include the value from the Source Connection ID field of the +packet it receives in the Destination Connection ID field. The server includes +a connection ID of its choice in the Source Connection ID field. This value +MUST not be equal to the Destination Connection ID field of the packet sent by +the client. Echoing both connection IDs (source is echoed in destination and +destination is echoed in original destination) gives clients some assurance +that the server received the packet and that the Version Negotiation packet +was not generated by an off-path attacker. A Version Negotiation packet cannot be explicitly acknowledged in an ACK frame by a client. Receiving another Initial packet implicitly acknowledges a Version @@ -3692,8 +3627,7 @@ Token: The client and server use the Initial packet type for any packet that contains an initial cryptographic handshake message. This includes all cases where a new packet containing the initial cryptographic message needs to be created, such as -the packets sent after receiving a Version Negotiation ({{packet-version}}) or -Retry packet ({{packet-retry}}). +the packets sent after receiving a Retry packet ({{packet-retry}}). A server sends its first Initial packet in response to a client Initial. A server may send multiple Initial packets. The cryptographic key exchange could @@ -3752,18 +3686,18 @@ probably right after the example handshake exchanges. --> Packet numbers for 0-RTT protected packets use the same space as 1-RTT protected packets. -After a client receives a Retry or Version Negotiation packet, 0-RTT packets are +After a client receives a Retry packet, 0-RTT packets are likely to have been lost or discarded by the server. A client MAY attempt to resend data in 0-RTT packets after it sends a new Initial packet. A client MUST NOT reset the packet number it uses for 0-RTT packets. The keys used to protect 0-RTT packets will not change as a result of responding to a -Retry or Version Negotiation packet unless the client also regenerates the +Retry packet unless the client also regenerates the cryptographic handshake message. Sending packets with the same packet number in that case is likely to compromise the packet protection for all 0-RTT packets because the same key and nonce could be used to protect different content. -Receiving a Retry or Version Negotiation packet, especially a Retry that changes +Receiving a Retry packet, especially a Retry that changes the connection ID used for subsequent packets, indicates a strong possibility that 0-RTT packets could be lost. A client only receives acknowledgments for its 0-RTT packets once the handshake is complete. Consequently, a server might @@ -3956,14 +3890,6 @@ language from Section 3 of {{!TLS13=RFC8446}}. } TransportParameter; struct { - select (Handshake.msg_type) { - case client_hello: - QuicVersion initial_version; - - case encrypted_extensions: - QuicVersion negotiated_version; - QuicVersion supported_versions<4..2^8-4>; - }; TransportParameter parameters<0..2^16-1>; } TransportParameters; ~~~ @@ -5087,12 +5013,6 @@ TRANSPORT_PARAMETER_ERROR (0x8): an invalid value, was absent even though it is mandatory, was present though it is forbidden, or is otherwise in error. -VERSION_NEGOTIATION_ERROR (0x9): - -: An endpoint received transport parameters that contained version negotiation - parameters that disagreed with the version negotiation that it performed. - This error code indicates a potential version downgrade attack. - PROTOCOL_VIOLATION (0xA): : An endpoint detected an error with protocol compliance that was not covered by @@ -5430,7 +5350,6 @@ from 0xFF00 to 0xFFFF are reserved for Private Use {{!RFC8126}}. | 0x6 | FINAL_OFFSET_ERROR | Change to final stream offset | {{error-codes}} | | 0x7 | FRAME_ENCODING_ERROR | Frame encoding error | {{error-codes}} | | 0x8 | TRANSPORT_PARAMETER_ERROR | Error in transport parameters | {{error-codes}} | -| 0x9 | VERSION_NEGOTIATION_ERROR | Version negotiation failure | {{error-codes}} | | 0xA | PROTOCOL_VIOLATION | Generic protocol violation | {{error-codes}} | | 0xC | INVALID_MIGRATION | Violated disabled migration | {{error-codes}} | {: #iana-error-table title="Initial QUIC Transport Error Codes Entries"} From 0551486736d4883882372488f30bf3e295542990 Mon Sep 17 00:00:00 2001 From: David Schinazi Date: Mon, 7 Jan 2019 13:50:41 -0800 Subject: [PATCH 002/190] remove more text --- draft-ietf-quic-transport.md | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 802e2a90e6..8822d87ab5 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1148,11 +1148,7 @@ unsupported versions. To help ensure this, a server SHOULD include a reserved version (see {{versions}}) while generating a Version Negotiation packet. The design of version negotiation permits a server to avoid maintaining state -for packets that it rejects in this fashion. The validation of version -negotiation (see {{version-validation}}) only validates the result of version -negotiation, which is the same no matter which reserved version was sent. -A server MAY therefore send different reserved version numbers in the Version -Negotiation Packet and in its transport parameters. +for packets that it rejects in this fashion. A client MAY send a packet using a reserved version number. This can be used to solicit a list of supported versions from a server. @@ -5083,8 +5079,7 @@ attacker can potentially send packets that will be accepted by QUIC endpoints. This version of QUIC attempts to detect this sort of attack, but it expects that endpoints will fail to establish a connection rather than recovering. For the most part, the cryptographic handshake protocol {{QUIC-TLS}} is responsible for -detecting tampering during the handshake, though additional validation is -required for version negotiation (see {{version-validation}}). +detecting tampering during the handshake. Endpoints are permitted to use other methods to detect and attempt to recover from interference with the handshake. Invalid packets may be identified and From 5ed9133eabe55169ba66cb1b8200f4f1f42c9d9e Mon Sep 17 00:00:00 2001 From: Magnus Westerlund Date: Tue, 15 Jan 2019 16:56:45 +0100 Subject: [PATCH 003/190] Initial text proposal for adding spin bit to transport specification. --- draft-ietf-quic-transport.md | 77 +++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 71b7bbc78e..f0ea25932a 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -89,6 +89,13 @@ informative: target: "https://web.archive.org/web/20150315054838/http://ha.ckers.org/slowloris/" + QUIC-MANAGEABILITY: + title: "Manageability of the QUIC Transport Protocol" + author: + - ins: M. Kuehlewind + date: 2018-10-22 + target: + "https://datatracker.ietf.org/doc/draft-ietf-quic-manageability/" --- abstract @@ -2803,6 +2810,46 @@ encoded as a single byte with the value 0x01. An endpoint MAY treat the receipt of a frame type that uses a longer encoding than necessary as a connection error of type PROTOCOL_VIOLATION. +## Latency Spin Bit {#spin-bit} + +The latency spin bit enables latency monitoring from observation points on the +network path throughout the duration of a connection. Since it is possible to +measure handshake RTT without a spin bit, it is sufficient to include the spin +bit in the short packet header. The spin bit therefore appears only after +version negotiation and connection establishment are completed. + +The spin bit utilizes a single bit in the first byte of the short header. The +spin bits location in the short header packets and procedure for how to set it +in both clients and servers are defined in {{short-header}}. + +Implementations MAY select to not implement the full spin bit functionality. In +that case they are only REQUIRED to implement what is defined for the spin bit +when disabled. + +Each endpoint unilateral decided if the spin bit is enabled or disabled for a +connection. Implementations SHOULD allow administrators of clients and servers +to disable the spin bit either globally or on a per-connection basis. Even when +the spin bit is not disabled by the administrator implementations SHOULD disable +the spin bit on a randomly chosen fraction of connections, except if connection +is explicitly configured to enable spin bit. + +The selection process SHOULD be designed such that on average the spin bit is +disabled for at least one eighth of network paths. The selection process should +be externally unpredictable but consistent for any given combination of source +and destination address/port. For instance, the implementation might have a +static key which it uses to key a pseudorandom function over these values and +use the output to determine whether to send the spin bit. The selection process +performed at the beginning of the connection SHOULD be applied for all paths +used by the connection. + +In case multiple connections share the same five-tuple, i.e. same source and +destination IP address and UDP port the setting of the spin bit needs to be +coordinated across all connections to ensure a clear signal to any on path +measurement point, however that might not be possible. + +On-path measurement and use of the Latency Spin Bit is further discussed in +{{QUIC-MANAGEABILITY}}. + # Packetization and Reliability {#packetization} @@ -3928,8 +3975,33 @@ Fixed Bit: Spin Bit (S): -: The sixth bit (0x20) of byte 0 is the Latency Spin Bit, set as described in - {{!SPIN=I-D.ietf-quic-spin-exp}}. +: The third most significant bit (0x20) of byte 0 is the Latency Spin Bit. + +: When the spin bit is disabled, endpoints MAY set the spin bit to any value, +and MUST accept any incoming value. It is RECOMMENDED that they +set the spin bit to a random value either chosen independently for each packet, +or chosen independently for each path and kept constant for that path. + +: If the spin bit is enabled for the connection the endpoint maintains a spin +value, 0 or 1, and sets the spin bit in the short header to the currently stored +value when a packet with a short header is sent out. The spin value is +initialized to 0 in the endpoint at connection start. Each endpoint also +remembers the highest packet number seen from its peer on the connection. + +: When a server receives a packet from a client, if that packet has a short +header and if it increments the highest packet number seen by the server from +the client, the server sets the spin value to the value observed in the spin bit +in the received packet. + +: When a client receives a packet from a server, if the packet has a short +header and if it increments the highest packet number seen by the client from +the server, it sets the spin value to the opposite of the spin bit in the +received packet. + +: The endpoint resets it spin value to zero when sending the first packet of a +given connection with a new connection ID. This reduces the risk that transient +spin bit state can be used to link flows across connection migration or ID +change. Reserved Bits (R): @@ -3977,6 +4049,7 @@ version. See {{QUIC-INVARIANTS}} for details on how packets from different versions of QUIC are interpreted. + # Transport Parameter Encoding {#transport-parameter-encoding} The format of the transport parameters is the TransportParameters struct from From 3a0b08c258651e6f9924108baa9b494dfe3774c1 Mon Sep 17 00:00:00 2001 From: David Schinazi Date: Tue, 15 Jan 2019 12:13:42 -0800 Subject: [PATCH 004/190] Revert changes to the invariants --- draft-ietf-quic-transport.md | 73 +++++++++--------------------------- 1 file changed, 18 insertions(+), 55 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 5eb36305bf..5fcb0399a5 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1137,16 +1137,15 @@ version downgrade attacks. When a draft implementation receives a Version Negotiation packet, it MAY use it to attempt a new connection with one of the supported versions. -The client MUST check that Destination Connection ID and Original Destination -Connection ID fields in the Version Negotiation packet match the Source and -Destination Connection ID fields in a packet that the client sent. If this -check fails, the packet MUST be discarded. +The client MUST check that the Destination and Source Connection ID fields +match the Source and Destination Connection ID fields in a packet that the +client sent. If this check fails, the packet MUST be discarded. Once the Version Negotiation packet is determined to be valid, the client then selects an acceptable protocol version from the list provided by the server. -The client then attempts to create a new connection using that version, and -the Source Connection ID from the Version Negotiation packet as its new -Destination Connection ID. +The client then attempts to create a new connection using that version. The new +connection MUST use a new random Destination Connection ID different from the +one it had previously sent. Note that this mechanism does not protect against downgrade attacks and MUST NOT be used outside of draft implementations. @@ -3421,7 +3420,7 @@ The layout of a Version Negotiation packet is: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+ -|1|R R R| ODCIL | +|1| Unused (7) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Version (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -3431,10 +3430,6 @@ The layout of a Version Negotiation packet is: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Connection ID (0/32..144) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Original Destination Connection ID (0/32..144) ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Number of Supported Versions (i) ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Supported Version 1 (32) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | [Supported Version 2 (32)] ... @@ -3443,55 +3438,23 @@ The layout of a Version Negotiation packet is: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | [Supported Version N (32)] ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Unused Payload (*) ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ {: #version-negotiation-format title="Version Negotiation Packet"} -The Version field of a Version Negotiation packet MUST be set to 0x00000000. -A Version Negotiation packet contains the following fields: - -Reserved Bits (R): - -: The three bits with a mask of 0x70 of byte 0 are reserved. They MUST be sent - sent as all-zeroes and MUST be ignored upon receipt. - -ODCIL: - -: The four least-significant bits of byte 0 encode the length of the Original - Destination Connection ID field. The length uses the same encoding as the - DCIL and SCIL fields. - -Original Destination Connection ID: - -: The Original Destination Connection ID contains the value of the Destination - Connection ID from the Initial packet that this Version Negotiation packet is - in response to. The length of this field is given in ODCIL. - -Number of Supported Versions: - -: The number of supported versions following this field, encoded as a - variable-length integer ({{integer-encoding}}). This field MUST NOT be zero. - -Supported Versions: - -: A list of 32-bit versions which the server supports. - -Unused Payload: - -: The rest of the packet after the supported versions is currently unused. - It MUST be sent empty and MUST be silently ignored upon reception. This - allows future extensibility of Version Negotiation packets. +The value in the Unused field is selected randomly by the server. +The Version field of a Version Negotiation packet MUST be set to 0x00000000. The server MUST include the value from the Source Connection ID field of the -packet it receives in the Destination Connection ID field. The server includes -a connection ID of its choice in the Source Connection ID field. This value -MUST not be equal to the Destination Connection ID field of the packet sent by -the client. Echoing both connection IDs (source is echoed in destination and -destination is echoed in original destination) gives clients some assurance -that the server received the packet and that the Version Negotiation packet -was not generated by an off-path attacker. +packet it receives in the Destination Connection ID field. The value for Source +Connection ID MUST be copied from the Destination Connection ID of the received +packet, which is initially randomly selected by a client. Echoing both +connection IDs gives clients some assurance that the server received the packet +and that the Version Negotiation packet was not generated by an off-path +attacker. + +The remainder of the Version Negotiation packet is a list of 32-bit versions +which the server supports. A Version Negotiation packet cannot be explicitly acknowledged in an ACK frame by a client. Receiving another Initial packet implicitly acknowledges a Version From 449d636415a868bd503ac6334257dcb1f9bb93af Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 21 Jan 2019 18:03:50 +1300 Subject: [PATCH 005/190] Allow stream-related frames in 0-RTT In #2344, @kazuho suggests that we could allow RESET_STREAM in 0-RTT. That seems slightly wrong, because why would someone send something then give up without receiving anything in return, but that is actually possible in the presence of packet loss. And changing your mind is perfectly acceptable. But RESET_STREAM doesn't really cover it. Streams can get blocked, requests can go out with additional flow control credits, and maybe even STOP_SENDING makes sense. So this changes it so that any stream-related frame (those that exist to convey application state or manage it), can be sent in 0-RTT. That seems more principled than just adding RESET_STREAM. Closes #2344. --- draft-ietf-quic-tls.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 275aa552d5..808c009055 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -334,9 +334,11 @@ encryption levels: - ACK frames MAY appear in packets of any encryption level other than 0-RTT, but can only acknowledge packets which appeared in that packet number space. -- STREAM frames MUST ONLY appear in the 0-RTT and 1-RTT levels. +- All stream- and flow control-related frame types (RESET_STREAM, STOP_SENDING, + STREAM, MAX_DATA, MAX_STREAM_DATA, MAX_STREAMS, DATA_BLOCKED, + STREAM_DATA_BLOCKED, and STREAM_BLOCKED) MAY appear in the 0-RTT level. -- All other frame types MUST only appear at the 1-RTT levels. +- All other frame types MAY appear at the 1-RTT levels. Because packets could be reordered on the wire, QUIC uses the packet type to indicate which level a given packet was encrypted under, as shown in From 59580812145936f7089586212155f14f4495d49f Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 22 Jan 2019 11:18:08 +1300 Subject: [PATCH 006/190] Expand the anti-replay story The inclusion of RESET_STREAM (and all other frame types) in 0-RTT inspired me to do some more analysis and due diligence on anti-replay. This adds a security considerations section with requirements for application protocols. That section explains more about what the risks for QUIC are, how QUIC itself isn't affected, but how an application protocol might be. It also adds a section to the HTTP draft citing RFC 8470, explaining how that analysis is sufficient for HTTP/3. --- draft-ietf-quic-http.md | 4 ++++ draft-ietf-quic-tls.md | 35 +++++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 2783a20624..6724bda6cd 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1447,6 +1447,10 @@ could pose a security risk to an incautious implementer. An implementation MUST ensure that the length of a frame exactly matches the length of the fields it contains. +The use of 0-RTT with HTTP/3 creates an exposure to replay attack. The +anti-replay mitigations in {{!HTTP-REPLAY=RFC8470}} MUST be applied when using +HTTP/3 with 0-RTT. + # IANA Considerations diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 808c009055..da4c783926 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -326,19 +326,12 @@ encryption levels: - CRYPTO frames MAY appear in packets of any encryption level except 0-RTT. -- CONNECTION_CLOSE MAY appear in packets of any encryption level other than - 0-RTT. - - PADDING frames MAY appear in packets of any encryption level. - ACK frames MAY appear in packets of any encryption level other than 0-RTT, but can only acknowledge packets which appeared in that packet number space. -- All stream- and flow control-related frame types (RESET_STREAM, STOP_SENDING, - STREAM, MAX_DATA, MAX_STREAM_DATA, MAX_STREAMS, DATA_BLOCKED, - STREAM_DATA_BLOCKED, and STREAM_BLOCKED) MAY appear in the 0-RTT level. - -- All other frame types MAY appear at the 1-RTT levels. +- All other frame types MUST be sent in the 0-RTT and 1-RTT levels. Because packets could be reordered on the wire, QUIC uses the packet type to indicate which level a given packet was encrypted under, as shown in @@ -1283,6 +1276,32 @@ Never assume that because it isn't in the security considerations section it doesn't affect security. Most of this document does. +## Replay Attacks with 0-RTT + +As described in Section 8 of {{!TLS13}}, use of TLS early data comes with an +exposure to replay attack. The use of 0-RTT in QUIC is similarly vulnerable to +replay attack. + +The management of QUIC protocol state based on the frame types defined in +{{QUIC-TRANSPORT}} is not vulnerable to replay. Processing of QUIC frames is +idempotent and does not produce invalid states if frames are reordered or lost. + +QUIC connections do not produce side-effects, except for those produced by the +application it serves. Replay risk in QUIC is therefore limited to those frames +that carry information that an application protocol consumes: STREAM, +RESET_STREAM, and STOP_SENDING. + +Extensions to QUIC might create an additional exposure to replay attack. QUIC +extensions MUST describe how replay attacks affects their operation. Extensions +MUST either be disabled in 0-RTT or provide replay mitigation strategies. + +An application protocol that uses 0-RTT MUST provide an analysis of the effects +of replay on that protocol. An application protocol that uses QUIC MUST +describe how the protocol uses 0-RTT and the measures that are employed to +protect against replay attack. Applications protocols can forbid the use of +0-RTT. + + ## Packet Reflection Attack Mitigation {#reflection} A small ClientHello that results in a large block of handshake messages from a From f9d24ec32312d0d0328c4d9057838d5653ece8e6 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 22 Jan 2019 11:25:35 +1300 Subject: [PATCH 007/190] Missing 'only' --- draft-ietf-quic-tls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index da4c783926..19d601478e 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -331,7 +331,7 @@ encryption levels: - ACK frames MAY appear in packets of any encryption level other than 0-RTT, but can only acknowledge packets which appeared in that packet number space. -- All other frame types MUST be sent in the 0-RTT and 1-RTT levels. +- All other frame types MUST only be sent in the 0-RTT and 1-RTT levels. Because packets could be reordered on the wire, QUIC uses the packet type to indicate which level a given packet was encrypted under, as shown in From 41aa3f31d73ea111e9565c05e91e5b536cbfc9b8 Mon Sep 17 00:00:00 2001 From: ihlar Date: Tue, 22 Jan 2019 15:16:21 +0100 Subject: [PATCH 008/190] Updated text on spinbit --- draft-ietf-quic-transport.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index f0ea25932a..f927631520 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2812,26 +2812,27 @@ of type PROTOCOL_VIOLATION. ## Latency Spin Bit {#spin-bit} -The latency spin bit enables latency monitoring from observation points on the -network path throughout the duration of a connection. Since it is possible to -measure handshake RTT without a spin bit, it is sufficient to include the spin -bit in the short packet header. The spin bit therefore appears only after -version negotiation and connection establishment are completed. +The latency spin bit enables passive latency monitoring from observation points +on the network path throughout the duration of a connection. The spin bit is +only present in the short packet header, since it is possible to measure the +initial RTT of a connection by observing the handshake. Therefore, the spin bit +will appear after version negotiation and connection establishment are +completed. -The spin bit utilizes a single bit in the first byte of the short header. The -spin bits location in the short header packets and procedure for how to set it -in both clients and servers are defined in {{short-header}}. +The spin bit utilizes a single bit in the first byte of the short header. The +location of the bit and procedures for how to set it by clients and servers are +defined in {{short-header}}. Implementations MAY select to not implement the full spin bit functionality. In that case they are only REQUIRED to implement what is defined for the spin bit -when disabled. +when it is disabled. -Each endpoint unilateral decided if the spin bit is enabled or disabled for a +Each endpoint unilaterally decides if the spin bit is enabled or disabled for a connection. Implementations SHOULD allow administrators of clients and servers -to disable the spin bit either globally or on a per-connection basis. Even when +to disable the spin bit either globally or on a per-connection basis. Even when the spin bit is not disabled by the administrator implementations SHOULD disable -the spin bit on a randomly chosen fraction of connections, except if connection -is explicitly configured to enable spin bit. +the spin bit on a randomly chosen fraction of connections, except for +connections that are explicitly configured to have the spin bit enabled. The selection process SHOULD be designed such that on average the spin bit is disabled for at least one eighth of network paths. The selection process should From 0fe91c8cb89eed4b0a63b5994c7287933d37a54c Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 23 Jan 2019 08:34:14 +1300 Subject: [PATCH 009/190] Fix CONNECTION_CLOSE --- draft-ietf-quic-tls.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 19d601478e..d189cda06b 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -324,7 +324,8 @@ the connection can usually appear at any encryption level, whereas those associated with transferring data can only appear in the 0-RTT and 1-RTT encryption levels: -- CRYPTO frames MAY appear in packets of any encryption level except 0-RTT. +- CRYPTO and CONNECTION_CLOSE frames MAY appear in packets of any encryption + level except 0-RTT. - PADDING frames MAY appear in packets of any encryption level. From a687f6c3af5df4c09e6853b462f688b1a0dd9818 Mon Sep 17 00:00:00 2001 From: Marcus Ihlar Date: Wed, 23 Jan 2019 10:43:54 +0100 Subject: [PATCH 010/190] reviewed version --- draft-ietf-quic-transport.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index f927631520..9cdd079ca2 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2817,7 +2817,8 @@ on the network path throughout the duration of a connection. The spin bit is only present in the short packet header, since it is possible to measure the initial RTT of a connection by observing the handshake. Therefore, the spin bit will appear after version negotiation and connection establishment are -completed. +completed. On-path measurement and use of the Latency Spin Bit is further +discussed in {{QUIC-MANAGEABILITY}}. The spin bit utilizes a single bit in the first byte of the short header. The location of the bit and procedures for how to set it by clients and servers are @@ -2831,13 +2832,13 @@ Each endpoint unilaterally decides if the spin bit is enabled or disabled for a connection. Implementations SHOULD allow administrators of clients and servers to disable the spin bit either globally or on a per-connection basis. Even when the spin bit is not disabled by the administrator implementations SHOULD disable -the spin bit on a randomly chosen fraction of connections, except for -connections that are explicitly configured to have the spin bit enabled. - -The selection process SHOULD be designed such that on average the spin bit is -disabled for at least one eighth of network paths. The selection process should -be externally unpredictable but consistent for any given combination of source -and destination address/port. For instance, the implementation might have a +the spin bit on a randomly chosen fraction of connections. However, connections +may be configured to explicitly enable spinning, for example in the case of +explicit customer support and debugging. +The random selection process SHOULD be designed such that on average the spin bit +is disabled for at least one eighth of network paths. The selection process +should be externally unpredictable but consistent for any given combination of source +and destination address and port. For instance, the implementation might have a static key which it uses to key a pseudorandom function over these values and use the output to determine whether to send the spin bit. The selection process performed at the beginning of the connection SHOULD be applied for all paths @@ -2846,11 +2847,7 @@ used by the connection. In case multiple connections share the same five-tuple, i.e. same source and destination IP address and UDP port the setting of the spin bit needs to be coordinated across all connections to ensure a clear signal to any on path -measurement point, however that might not be possible. - -On-path measurement and use of the Latency Spin Bit is further discussed in -{{QUIC-MANAGEABILITY}}. - +measurement point, however that might not be feasible. # Packetization and Reliability {#packetization} From e797a0a5f7f45f331c92c86340c56e7f6aca764c Mon Sep 17 00:00:00 2001 From: ihlar Date: Wed, 23 Jan 2019 13:42:00 +0100 Subject: [PATCH 011/190] Updated formatting --- 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 3ee5f76035..8fc07f1c8a 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2832,10 +2832,10 @@ on the network path throughout the duration of a connection. The spin bit is only present in the short packet header, since it is possible to measure the initial RTT of a connection by observing the handshake. Therefore, the spin bit will appear after version negotiation and connection establishment are -completed. On-path measurement and use of the Latency Spin Bit is further +completed. On-path measurement and use of the Latency Spin Bit is further discussed in {{QUIC-MANAGEABILITY}}. -The spin bit utilizes a single bit in the first byte of the short header. The +The spin bit utilizes a single bit in the first byte of the short header. The location of the bit and procedures for how to set it by clients and servers are defined in {{short-header}}. @@ -2847,17 +2847,17 @@ Each endpoint unilaterally decides if the spin bit is enabled or disabled for a connection. Implementations SHOULD allow administrators of clients and servers to disable the spin bit either globally or on a per-connection basis. Even when the spin bit is not disabled by the administrator implementations SHOULD disable -the spin bit on a randomly chosen fraction of connections. However, connections +the spin bit on a randomly chosen fraction of connections. However, connections may be configured to explicitly enable spinning, for example in the case of explicit customer support and debugging. -The random selection process SHOULD be designed such that on average the spin bit -is disabled for at least one eighth of network paths. The selection process -should be externally unpredictable but consistent for any given combination of source -and destination address and port. For instance, the implementation might have a -static key which it uses to key a pseudorandom function over these values and -use the output to determine whether to send the spin bit. The selection process -performed at the beginning of the connection SHOULD be applied for all paths -used by the connection. +The random selection process SHOULD be designed such that on average the spin +bit is disabled for at least one eighth of network paths. The selection process +should be externally unpredictable but consistent for any given combination of +source and destination address and port. For instance, the implementation might +have a static key which it uses to key a pseudorandom function over these values +and use the output to determine whether to send the spin bit. The selection +process performed at the beginning of the connection SHOULD be applied for all +paths used by the connection. In case multiple connections share the same five-tuple, i.e. same source and destination IP address and UDP port the setting of the spin bit needs to be From 63e18037753f70bb641b5a77a6c37bceba05baa5 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 30 Jan 2019 12:25:16 +0900 Subject: [PATCH 012/190] Remove requirement for reciprocal connection ID change Closes #1795, #2145. --- draft-ietf-quic-transport.md | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index ea9859ba5f..77491dbc84 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2110,19 +2110,10 @@ infrequently. Endpoints that use connection IDs with length greater than zero could have their activity correlated if their peers keep using the same destination connection ID -after migration. Endpoints that receive packets with a previously unused -Destination Connection ID SHOULD change to sending packets with a connection ID -that has not been used on any other network path. The goal here is to ensure -that packets sent on different paths cannot be correlated. To fulfill this -privacy requirement, endpoints that initiate migration and use connection IDs -with length greater than zero SHOULD provide their peers with new connection IDs -before migration. - -Caution: - -: If both endpoints change connection ID in response to seeing a change in - connection ID from their peer, then this can trigger an infinite sequence of - changes. +after migration. The goal here is to ensure that packets sent on different +paths cannot be correlated. To fulfill this privacy requirement, endpoints that +initiate migration and use connection IDs with length greater than zero SHOULD +provide their peers with new connection IDs before migration. ## Server's Preferred Address {#preferred-address} From 23014c8b8a59be658a5156ae46fcbacc7e681311 Mon Sep 17 00:00:00 2001 From: ianswett Date: Wed, 30 Jan 2019 12:42:18 +0900 Subject: [PATCH 013/190] remove redundant word Co-Authored-By: martinthomson --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 77491dbc84..62fa450799 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2110,7 +2110,7 @@ infrequently. Endpoints that use connection IDs with length greater than zero could have their activity correlated if their peers keep using the same destination connection ID -after migration. The goal here is to ensure that packets sent on different +after migration. The goal is to ensure that packets sent on different paths cannot be correlated. To fulfill this privacy requirement, endpoints that initiate migration and use connection IDs with length greater than zero SHOULD provide their peers with new connection IDs before migration. From fdfb19d5922e75b5d6b93eda217e3a9c242308f6 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Thu, 31 Jan 2019 16:43:17 +0900 Subject: [PATCH 014/190] Move PADDING up --- draft-ietf-quic-tls.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index d189cda06b..3d91f12916 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -324,11 +324,11 @@ the connection can usually appear at any encryption level, whereas those associated with transferring data can only appear in the 0-RTT and 1-RTT encryption levels: +- PADDING frames MAY appear in packets of any encryption level. + - CRYPTO and CONNECTION_CLOSE frames MAY appear in packets of any encryption level except 0-RTT. -- PADDING frames MAY appear in packets of any encryption level. - - ACK frames MAY appear in packets of any encryption level other than 0-RTT, but can only acknowledge packets which appeared in that packet number space. From 48002d0f68802958f856a2a15cb41b079e355e88 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 5 Feb 2019 09:41:47 +1100 Subject: [PATCH 015/190] Editorial changes --- draft-ietf-quic-transport.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 62fa450799..ffe3c04655 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2108,12 +2108,13 @@ genuine migrations. Changing port number can cause a peer to reset its congestion state (see {{migration-cc}}), so the port SHOULD only be changed infrequently. -Endpoints that use connection IDs with length greater than zero could have their -activity correlated if their peers keep using the same destination connection ID -after migration. The goal is to ensure that packets sent on different -paths cannot be correlated. To fulfill this privacy requirement, endpoints that -initiate migration and use connection IDs with length greater than zero SHOULD -provide their peers with new connection IDs before migration. +Endpoints that supply connection IDs with length greater than zero could have +their activity correlated if their peers keep using the same destination +connection ID after migration. To ensure that packets sent on different paths +cannot be correlated, endpoints SHOULD provide with new connection IDs before +peers migrate. To fulfill this privacy requirement, endpoints that initiate +migration and use connection IDs with length greater than zero SHOULD provide +their peers with new connection IDs before migration. ## Server's Preferred Address {#preferred-address} From 13698cbe311922a3995236dda960b4cdff49e36f Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 5 Feb 2019 09:52:43 +1100 Subject: [PATCH 016/190] New connection IDs are mandatory for intentional migration I could have sworn we agreed to this previously, but I also can't find where we captured it. So here it is. This was originally an editorial factoring of text, but I guess it needs to be a design issue now. Closes #2413. --- draft-ietf-quic-transport.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index ffe3c04655..66cd4c2f07 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2089,15 +2089,17 @@ different local addresses, as discussed in {{connection-id}}. For this to be effective endpoints need to ensure that connections IDs they provide cannot be linked by any other entity. -This eliminates the use of the connection ID for linking activity from -the same connection on different networks. Header protection ensures -that packet numbers cannot be used to correlate activity. This does not prevent -other properties of packets, such as timing and size, from being used to -correlate activity. +An endpoint MUST use a new connection ID if it initiates connection migration, +unless the peer has selected a zero-length connection ID. This eliminates the +use of the connection ID for linking activity from the same connection on +different networks. Header protection ensures that packet numbers cannot be +used to correlate activity. This does not prevent other properties of packets, +such as timing and size, from being used to correlate activity. Clients MAY move to a new connection ID at any time based on implementation-specific concerns. For example, after a period of network -inactivity NAT rebinding might occur when the client begins sending data again. +inactivity, where NAT rebinding might occur when the client begins sending data +again. A client might wish to reduce linkability by employing a new connection ID and source UDP port when sending traffic after a period of inactivity. Changing the @@ -2108,13 +2110,12 @@ genuine migrations. Changing port number can cause a peer to reset its congestion state (see {{migration-cc}}), so the port SHOULD only be changed infrequently. -Endpoints that supply connection IDs with length greater than zero could have -their activity correlated if their peers keep using the same destination -connection ID after migration. To ensure that packets sent on different paths -cannot be correlated, endpoints SHOULD provide with new connection IDs before -peers migrate. To fulfill this privacy requirement, endpoints that initiate -migration and use connection IDs with length greater than zero SHOULD provide -their peers with new connection IDs before migration. +An endpoint cannot migrate to a new path if it does not have a connection ID to +use on that path. An endpoint that exhausts available connection IDs can only +migrate if the peer chooses to use receive packets with zero-length connection +IDs. To ensure that migration is possible and packets sent on different paths +cannot be correlated, endpoints SHOULD provide new connection IDs before peers +migrate. ## Server's Preferred Address {#preferred-address} From d6fe1014583969a45f91f9e44022f61b87a8a200 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 5 Feb 2019 10:36:12 +1100 Subject: [PATCH 017/190] Reword zero-length caveat --- draft-ietf-quic-transport.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 66cd4c2f07..77a94ae051 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2111,11 +2111,11 @@ congestion state (see {{migration-cc}}), so the port SHOULD only be changed infrequently. An endpoint cannot migrate to a new path if it does not have a connection ID to -use on that path. An endpoint that exhausts available connection IDs can only -migrate if the peer chooses to use receive packets with zero-length connection -IDs. To ensure that migration is possible and packets sent on different paths -cannot be correlated, endpoints SHOULD provide new connection IDs before peers -migrate. +use on that path. An endpoint that exhausts available connection IDs cannot +migrate. If a peer chooses to receive packets with zero-length connection IDs, +an endpoint can always migrate. To ensure that migration is possible and +packets sent on different paths cannot be correlated, endpoints SHOULD provide +new connection IDs before peers migrate. ## Server's Preferred Address {#preferred-address} From 1d8af249df68710203ce2ca376823ee61d2dd9cc Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 5 Feb 2019 11:07:56 +0800 Subject: [PATCH 018/190] update the pseudo code to include packet number spaces --- draft-ietf-quic-recovery.md | 79 ++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 043ac4f167..fdc787b7bf 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -840,10 +840,10 @@ time_of_last_sent_ack_eliciting_packet: time_of_last_sent_crypto_packet: : The time the most recent crypto packet was sent. -largest_sent_packet: -: The packet number of the most recently sent packet. +largest_sent_packet[pn_space]: +: The packet number of the most recently sent packet in the packet number space. -largest_acked_packet: +largest_acked_packet[pn_space]: : The largest packet number acknowledged in the packet number space so far. latest_rtt: @@ -868,11 +868,12 @@ max_ack_delay: loss_time: : The time at which the next packet will be considered lost based on - exceeding the reordering window in time. + exceeding the reordering window in time. Only applies to the 1-RTT packet + number space. -sent_packets: -: An association of packet numbers to information about them. Described - in detail above in {{tracking-sent-packets}}. +sent_packets[pn_space]: +: An association of packet numbers in a packet number space to information + about them. Described in detail above in {{tracking-sent-packets}}. ## Initialization @@ -890,8 +891,9 @@ follows: min_rtt = infinite time_of_last_sent_ack_eliciting_packet = 0 time_of_last_sent_crypto_packet = 0 - largest_sent_packet = 0 - largest_acked_packet = 0 + for pn_space in packet number spaces: + largest_sent_packet[pn_space] = 0 + largest_acked_packet[pn_space] = 0 ~~~ @@ -903,20 +905,20 @@ to OnPacketSent are described in detail above in {{sent-packets-fields}}. Pseudocode for OnPacketSent follows: ~~~ - OnPacketSent(packet_number, ack_eliciting, in_flight, - is_crypto_packet, sent_bytes): - largest_sent_packet = packet_number - sent_packets[packet_number].packet_number = packet_number - sent_packets[packet_number].time_sent = now - sent_packets[packet_number].ack_eliciting = ack_eliciting - sent_packets[packet_number].in_flight = in_flight + OnPacketSent(packet_number, pn_space, ack_eliciting, + in_flight, is_crypto_packet, sent_bytes): + largest_sent_packet[pn_space] = packet_number + sent_packets[pn_space][packet_number].packet_number = packet_number + sent_packets[pn_space][packet_number].time_sent = now + sent_packets[pn_space][packet_number].ack_eliciting = ack_eliciting + sent_packets[pn_space][packet_number].in_flight = in_flight if (in_flight): if (is_crypto_packet): time_of_last_sent_crypto_packet = now if (ack_eliciting): time_of_last_sent_ack_eliciting_packet = now OnPacketSentCC(sent_bytes) - sent_packets[packet_number].size = sent_bytes + sent_packets[pn_space][packet_number].size = sent_bytes SetLossDetectionTimer() ~~~ @@ -928,16 +930,16 @@ When an ACK frame is received, it may newly acknowledge any number of packets. Pseudocode for OnAckReceived and UpdateRtt follow: ~~~ - OnAckReceived(ack): - largest_acked_packet = max(largest_acked_packet, + OnAckReceived(ack, pn_space): + largest_acked_packet[pn_space] = max(largest_acked_packet, ack.largest_acked) // If the largest acknowledged is newly acked and // ack-eliciting, update the RTT. - if (sent_packets[ack.largest_acked] && - sent_packets[ack.largest_acked].ack_eliciting): + if (sent_packets[pn_space][ack.largest_acked] && + sent_packets[pn_space][ack.largest_acked].ack_eliciting): latest_rtt = - now - sent_packets[ack.largest_acked].time_sent + now - sent_packets[pn_space][ack.largest_acked].time_sent UpdateRtt(latest_rtt, ack.ack_delay) // Process ECN information if present. @@ -945,14 +947,14 @@ Pseudocode for OnAckReceived and UpdateRtt follow: ProcessECN(ack) // Find all newly acked packets in this ACK frame - newly_acked_packets = DetermineNewlyAckedPackets(ack) + newly_acked_packets = DetermineNewlyAckedPackets(ack, pn_space) if (newly_acked_packets.empty()): return for acked_packet in newly_acked_packets: - OnPacketAcked(acked_packet.packet_number) + OnPacketAcked(acked_packet.packet_number, pn_space) - DetectLostPackets() + DetectLostPackets(pn_space) crypto_count = 0 pto_count = 0 @@ -986,16 +988,17 @@ function is called. Note that a single ACK frame may newly acknowledge several packets. OnPacketAcked must be called once for each of these newly acknowledged packets. -OnPacketAcked takes one parameter, acked_packet, which is the struct detailed in -{{sent-packets-fields}}. +OnPacketAcked takes two parameters: acked_packet, which is the struct detailed in +{{sent-packets-fields}}, and the packet number space that this ACK frame was sent +for. Pseudocode for OnPacketAcked follows: ~~~ - OnPacketAcked(acked_packet): + OnPacketAcked(acked_packet, pn_space): if (acked_packet.ack_eliciting): OnPacketAckedCC(acked_packet) - sent_packets.remove(acked_packet.packet_number) + sent_packets[pn_space].remove(acked_packet.packet_number) ~~~ @@ -1032,6 +1035,7 @@ Pseudocode for SetLossDetectionTimer follows: return if (loss_time != 0): // Time threshold loss detection. + // Only applies to the 1-RTT packet number space. loss_detection_timer.update(loss_time) return @@ -1061,7 +1065,8 @@ Pseudocode for OnLossDetectionTimeout follows: crypto_count++ else if (loss_time != 0): // Time threshold loss Detection - DetectLostPackets() + // Only applies to the 1-RTT packet number space. + DetectLostPackets(1-RTT) else: // PTO SendOneOrTwoPackets() @@ -1081,8 +1086,9 @@ is supplied. Pseudocode for DetectLostPackets follows: ~~~ -DetectLostPackets(): - loss_time = 0 +DetectLostPackets(pn_space): + if (pn_space == 1-RTT): + loss_time = 0 lost_packets = {} loss_delay = kTimeThreshold * max(latest_rtt, smoothed_rtt) @@ -1102,10 +1108,11 @@ DetectLostPackets(): sent_packets.remove(unacked.packet_number) if (unacked.in_flight): lost_packets.insert(unacked) - else if (loss_time == 0): - loss_time = unacked.time_sent + loss_delay - else: - loss_time = min(loss_time, unacked.time_sent + loss_delay) + else if (pn_space == 1-RTT): + if (loss_time == 0): + loss_time = unacked.time_sent + loss_delay + else: + loss_time = min(loss_time, unacked.time_sent + loss_delay) // Inform the congestion controller of lost packets and // let it decide whether to retransmit immediately. From 491d871829800a78661202e642839ab1e97100d8 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 5 Feb 2019 22:04:28 +1100 Subject: [PATCH 019/190] Explain more --- draft-ietf-quic-transport.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 77a94ae051..6bee4235c8 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2113,9 +2113,10 @@ infrequently. An endpoint cannot migrate to a new path if it does not have a connection ID to use on that path. An endpoint that exhausts available connection IDs cannot migrate. If a peer chooses to receive packets with zero-length connection IDs, -an endpoint can always migrate. To ensure that migration is possible and -packets sent on different paths cannot be correlated, endpoints SHOULD provide -new connection IDs before peers migrate. +an endpoint can always migrate - zero-length connection IDs provide no +significant linkability. To ensure that migration is possible and packets sent +on different paths cannot be correlated, endpoints SHOULD provide new connection +IDs before peers migrate. ## Server's Preferred Address {#preferred-address} From 894d6389ab962668807544bfb59911d4f57273f0 Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Tue, 5 Feb 2019 09:34:53 -0500 Subject: [PATCH 020/190] Update diagram: h2q is now h3 --- draft-ietf-quic-tls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 90e1f61cdd..936d1bc00d 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -244,7 +244,7 @@ shown below. +--------------+--------------+ +-------------+ | TLS | TLS | | QUIC | | Handshake | Alerts | | Applications| -| | | | (h2q, etc.) | +| | | | (h3, etc.) | +--------------+--------------+-+-------------+ | | | QUIC Transport | From 96b9fe88ce116bba073406d2f0ac65e02e37254f Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 6 Feb 2019 09:50:05 +1100 Subject: [PATCH 021/190] Editorial changes, stronger MUST --- draft-ietf-quic-transport.md | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 6bee4235c8..74f7a63f70 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2089,17 +2089,19 @@ different local addresses, as discussed in {{connection-id}}. For this to be effective endpoints need to ensure that connections IDs they provide cannot be linked by any other entity. +Endpoints MAY move to a new connection ID at any time. + An endpoint MUST use a new connection ID if it initiates connection migration, -unless the peer has selected a zero-length connection ID. This eliminates the -use of the connection ID for linking activity from the same connection on -different networks. Header protection ensures that packet numbers cannot be -used to correlate activity. This does not prevent other properties of packets, -such as timing and size, from being used to correlate activity. +unless the peer has selected a zero-length connection ID. Using a new +connection ID eliminates the use of the connection ID for linking activity from +the same connection on different networks. Header protection ensures that +packet numbers cannot be used to correlate activity. This does not prevent +other properties of packets, such as timing and size, from being used to +correlate activity. -Clients MAY move to a new connection ID at any time based on -implementation-specific concerns. For example, after a period of network -inactivity, where NAT rebinding might occur when the client begins sending data -again. +Unintentional changes in path without a change in connection ID are possible. +For example, after a period of network inactivity, NAT rebinding might cause +packets to be sent on a new path when the client resumes sending. A client might wish to reduce linkability by employing a new connection ID and source UDP port when sending traffic after a period of inactivity. Changing the @@ -2110,13 +2112,15 @@ genuine migrations. Changing port number can cause a peer to reset its congestion state (see {{migration-cc}}), so the port SHOULD only be changed infrequently. -An endpoint cannot migrate to a new path if it does not have a connection ID to -use on that path. An endpoint that exhausts available connection IDs cannot -migrate. If a peer chooses to receive packets with zero-length connection IDs, -an endpoint can always migrate - zero-length connection IDs provide no -significant linkability. To ensure that migration is possible and packets sent -on different paths cannot be correlated, endpoints SHOULD provide new connection -IDs before peers migrate. +An endpoint MUST NOT intentionally migrate to a new path if it does not have a +connection ID to use on that path. An endpoint that exhausts available +connection IDs cannot migrate. To ensure that migration is possible and packets +sent on different paths cannot be correlated, endpoints SHOULD provide new +connection IDs before peers migrate. + +If a peer chooses to receive packets with zero-length connection IDs, an +endpoint can always migrate - zero-length connection IDs provide no significant +linkability. ## Server's Preferred Address {#preferred-address} From 1bb6c3e804945f7adda97c2e7ec1785bda04a18d Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Wed, 6 Feb 2019 12:34:40 +0900 Subject: [PATCH 022/190] clarify what happens when consuming CIDs excessively --- draft-ietf-quic-transport.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 89a6c40ecf..fbeb10756a 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -972,8 +972,11 @@ the connection. ### Consuming and Retiring Connection IDs {#retiring-cids} An endpoint can change the connection ID it uses for a peer to another available -one at any time during the connection. An endpoint consumes connection IDs in -response to a migrating peer, see {{migration-linkability}} for more. +one at any time during the connection, though excessive consumption of +connection IDs might lead to running out of spares if the issuer limits the +frequency of issuance or the total number of connection IDs issued for each +connection. An endpoint consumes connection IDs in response to a migrating +peer, see {{migration-linkability}} for more. An endpoint maintains a set of connection IDs received from its peer, any of which it can use when sending packets. When the endpoint wishes to remove a From 88fac6e73653b10c6963af152ab93327c8102f80 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Wed, 6 Feb 2019 13:21:50 +0900 Subject: [PATCH 023/190] Revert "clarify what happens when consuming CIDs excessively" This reverts commit 1bb6c3e804945f7adda97c2e7ec1785bda04a18d. --- draft-ietf-quic-transport.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index fbeb10756a..89a6c40ecf 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -972,11 +972,8 @@ the connection. ### Consuming and Retiring Connection IDs {#retiring-cids} An endpoint can change the connection ID it uses for a peer to another available -one at any time during the connection, though excessive consumption of -connection IDs might lead to running out of spares if the issuer limits the -frequency of issuance or the total number of connection IDs issued for each -connection. An endpoint consumes connection IDs in response to a migrating -peer, see {{migration-linkability}} for more. +one at any time during the connection. An endpoint consumes connection IDs in +response to a migrating peer, see {{migration-linkability}} for more. An endpoint maintains a set of connection IDs received from its peer, any of which it can use when sending packets. When the endpoint wishes to remove a From a0ae02995b37cd83d163f334c7b71e0b1ddb13f6 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Wed, 6 Feb 2019 13:31:17 +0900 Subject: [PATCH 024/190] move the statement to the issuer side --- draft-ietf-quic-transport.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 89a6c40ecf..778d253c6c 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -961,12 +961,15 @@ cannot expect its peer to store and use all issued connection IDs. An endpoint SHOULD ensure that its peer has a sufficient number of available and unused connection IDs. While each endpoint independently chooses how many connection IDs to issue, endpoints SHOULD provide and maintain at least eight -connection IDs. The endpoint SHOULD do this by always supplying a new -connection ID when a connection ID is retired by its peer or when the endpoint -receives a packet with a previously unused connection ID. Endpoints that -initiate migration and require non-zero-length connection IDs SHOULD provide -their peers with new connection IDs before migration, or risk the peer closing -the connection. +connection IDs. The endpoint SHOULD do this by supplying a new connection ID +when a connection ID is retired by its peer or when the endpoint receives a +packet with a previously unused connection ID, though it MAY limit the frequency +or the total number of connection IDs issued for each connection to avoid the +risk of running out of connection IDs (see {{reset-token}}). + +Endpoints that initiate migration and require non-zero-length connection IDs +SHOULD provide their peers with new connection IDs before migration, or risk the +peer closing the connection. ### Consuming and Retiring Connection IDs {#retiring-cids} From 9400c2f9b2c5a235ce15377538bc8dc354467f39 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 6 Feb 2019 16:11:52 +1100 Subject: [PATCH 025/190] Replay protection is the responsibility of application protocols This is based on my recent conclusions about this subject. It rewrites the advice here by observing that QUIC does not inherently present a replay risk. Instead, application protocols, in their use of QUIC, might create an exposure to replay attack. Rather than try to perform an analysis in the transport, based on incomplete information, it is better to outline some risks (STREAM seems like the only obvious one here, frankly, though I've pointed out a couple of anti-patterns that might have accompanying replay risks) and let the application protocol designers perform a more complete analysis. We did that analysis for HTTP. I believe that to be sufficient. Though I might include mention of the fact that stream cancellation and other h2 mechanisms don't carry application semantics, but that is not a major source of regret. --- draft-ietf-quic-tls.md | 56 ++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 3d91f12916..54d9363d36 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1283,24 +1283,44 @@ As described in Section 8 of {{!TLS13}}, use of TLS early data comes with an exposure to replay attack. The use of 0-RTT in QUIC is similarly vulnerable to replay attack. -The management of QUIC protocol state based on the frame types defined in -{{QUIC-TRANSPORT}} is not vulnerable to replay. Processing of QUIC frames is -idempotent and does not produce invalid states if frames are reordered or lost. - -QUIC connections do not produce side-effects, except for those produced by the -application it serves. Replay risk in QUIC is therefore limited to those frames -that carry information that an application protocol consumes: STREAM, -RESET_STREAM, and STOP_SENDING. - -Extensions to QUIC might create an additional exposure to replay attack. QUIC -extensions MUST describe how replay attacks affects their operation. Extensions -MUST either be disabled in 0-RTT or provide replay mitigation strategies. - -An application protocol that uses 0-RTT MUST provide an analysis of the effects -of replay on that protocol. An application protocol that uses QUIC MUST -describe how the protocol uses 0-RTT and the measures that are employed to -protect against replay attack. Applications protocols can forbid the use of -0-RTT. +Endpoints MUST implement and use the replay protections described in {{!TLS13}}, +however it is recognized that these protections are imperfect. Therefore, +additional consideration of the risk of replay are needed. + +QUIC is not inherently vulnerable to replay attack. The management of QUIC +protocol state based on the frame types defined in {{QUIC-TRANSPORT}} is not +vulnerable to replay. Processing of QUIC frames is idempotent and cannot result +in invalid connection states if frames are reordered or lost. QUIC connections +do not produce effects that last beyond the lifetime of the connection, except +for those produced by the application protocol that QUIC serves. + +However, this does not count for costs that endpoints might incur as a result of +accepting 0-RTT. A server that accepts 0-RTT is exposed to the cost of handling +a new connection, plus the cost of processing 0-RTT packets. If replay +protections are unable to prevent multiple connections from being initiated, +this could increase these costs because attackers can send copies of 0-RTT +packets to different server instances, causing the processing to be repeated. +Servers MUST ensure that they account for any increase in costs before accepting +connections or 0-RTT. + +Ultimately, the responsibility for managing the risks of replay attacks with +0-RTT lies with an application protocol. An application protocol that uses QUIC +MUST describe how the protocol uses 0-RTT and the measures that are employed to +protect against replay attack. Disabling 0-RTT entirely is the most effective +strategy. + +In the core protocol, particular attention needs to be paid to STREAM frames, +which carry application data. If another frame type carries, or could carry, +application semantics, then the risk from replay attack needs to be considered. +For instance, though this is likely to be inadvisable, an application that +attached semantics to increases in flow control credit or stream cancellation +would need to assess whether those uses were vulnerable to replay attack. + +Extensions to QUIC might create an additional exposure to replay attack if they +are used by application protocols. QUIC extensions SHOULD describe how replay +attacks affects their operation. Application protocols MUST either disable +extensions in 0-RTT or provide replay mitigation strategies for any use of the +extension. ## Packet Reflection Attack Mitigation {#reflection} From 7c2660ecf7a11f42f7950615b9ad80ecdec8d280 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 6 Feb 2019 16:48:30 +1100 Subject: [PATCH 026/190] Editorial fix --- 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 74f7a63f70..e58afcc067 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2119,8 +2119,8 @@ sent on different paths cannot be correlated, endpoints SHOULD provide new connection IDs before peers migrate. If a peer chooses to receive packets with zero-length connection IDs, an -endpoint can always migrate - zero-length connection IDs provide no significant -linkability. +endpoint can always migrate, because zero-length connection IDs provide no +significant linkability. ## Server's Preferred Address {#preferred-address} From 17161f54da4f76f94cd4271af303792afad40c71 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 6 Feb 2019 21:57:44 +0800 Subject: [PATCH 027/190] introduce an enum for packet number spaces --- draft-ietf-quic-recovery.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index fdc787b7bf..8fbc6cfa9c 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -819,6 +819,16 @@ kGranularity: kInitialRtt: : The RTT used before an RTT sample is taken. The RECOMMENDED value is 100ms. +pn_space: +: An enum to enumerate the three packet number spaces. +~~~ + enum pn_space { + Initial, + Handshake, + 1-RTT, + } +~~~ + ## Variables of interest {#ld-vars-of-interest} Variables required to implement the congestion control mechanisms @@ -891,7 +901,7 @@ follows: min_rtt = infinite time_of_last_sent_ack_eliciting_packet = 0 time_of_last_sent_crypto_packet = 0 - for pn_space in packet number spaces: + for pn_space in [ Initial, Handshake, 1-RTT ]: largest_sent_packet[pn_space] = 0 largest_acked_packet[pn_space] = 0 ~~~ From 8280320ca7208e485af75d581f4a38d8d184a8a7 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Wed, 6 Feb 2019 22:02:40 +0800 Subject: [PATCH 028/190] fix line lengths --- draft-ietf-quic-recovery.md | 111 ++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 8fbc6cfa9c..d8773e749a 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -918,9 +918,11 @@ Pseudocode for OnPacketSent follows: OnPacketSent(packet_number, pn_space, ack_eliciting, in_flight, is_crypto_packet, sent_bytes): largest_sent_packet[pn_space] = packet_number - sent_packets[pn_space][packet_number].packet_number = packet_number + sent_packets[pn_space][packet_number].packet_number = + packet_number sent_packets[pn_space][packet_number].time_sent = now - sent_packets[pn_space][packet_number].ack_eliciting = ack_eliciting + sent_packets[pn_space][packet_number].ack_eliciting = + ack_eliciting sent_packets[pn_space][packet_number].in_flight = in_flight if (in_flight): if (is_crypto_packet): @@ -940,54 +942,54 @@ When an ACK frame is received, it may newly acknowledge any number of packets. Pseudocode for OnAckReceived and UpdateRtt follow: ~~~ - OnAckReceived(ack, pn_space): - largest_acked_packet[pn_space] = max(largest_acked_packet, - ack.largest_acked) - - // If the largest acknowledged is newly acked and - // ack-eliciting, update the RTT. - if (sent_packets[pn_space][ack.largest_acked] && - sent_packets[pn_space][ack.largest_acked].ack_eliciting): - latest_rtt = - now - sent_packets[pn_space][ack.largest_acked].time_sent - UpdateRtt(latest_rtt, ack.ack_delay) - - // Process ECN information if present. - if (ACK frame contains ECN information): - ProcessECN(ack) - - // Find all newly acked packets in this ACK frame - newly_acked_packets = DetermineNewlyAckedPackets(ack, pn_space) - if (newly_acked_packets.empty()): - return - - for acked_packet in newly_acked_packets: - OnPacketAcked(acked_packet.packet_number, pn_space) - - DetectLostPackets(pn_space) - - crypto_count = 0 - pto_count = 0 - - SetLossDetectionTimer() - - - UpdateRtt(latest_rtt, ack_delay): - // min_rtt ignores ack delay. - min_rtt = min(min_rtt, latest_rtt) - // Limit ack_delay by max_ack_delay - ack_delay = min(ack_delay, max_ack_delay) - // Adjust for ack delay if it's plausible. - if (latest_rtt - min_rtt > ack_delay): - latest_rtt -= ack_delay - // Based on {{?RFC6298}}. - if (smoothed_rtt == 0): - smoothed_rtt = latest_rtt - rttvar = latest_rtt / 2 - else: - rttvar_sample = abs(smoothed_rtt - latest_rtt) - rttvar = 3/4 * rttvar + 1/4 * rttvar_sample - smoothed_rtt = 7/8 * smoothed_rtt + 1/8 * latest_rtt +OnAckReceived(ack, pn_space): + largest_acked_packet[pn_space] = max(largest_acked_packet, + ack.largest_acked) + + // If the largest acknowledged is newly acked and + // ack-eliciting, update the RTT. + if (sent_packets[pn_space][ack.largest_acked] && + sent_packets[pn_space][ack.largest_acked].ack_eliciting): + latest_rtt = + now - sent_packets[pn_space][ack.largest_acked].time_sent + UpdateRtt(latest_rtt, ack.ack_delay) + + // Process ECN information if present. + if (ACK frame contains ECN information): + ProcessECN(ack) + + // Find all newly acked packets in this ACK frame + newly_acked_packets = DetermineNewlyAckedPackets(ack, pn_space) + if (newly_acked_packets.empty()): + return + + for acked_packet in newly_acked_packets: + OnPacketAcked(acked_packet.packet_number, pn_space) + + DetectLostPackets(pn_space) + + crypto_count = 0 + pto_count = 0 + + SetLossDetectionTimer() + + +UpdateRtt(latest_rtt, ack_delay): + // min_rtt ignores ack delay. + min_rtt = min(min_rtt, latest_rtt) + // Limit ack_delay by max_ack_delay + ack_delay = min(ack_delay, max_ack_delay) + // Adjust for ack delay if it's plausible. + if (latest_rtt - min_rtt > ack_delay): + latest_rtt -= ack_delay + // Based on {{?RFC6298}}. + if (smoothed_rtt == 0): + smoothed_rtt = latest_rtt + rttvar = latest_rtt / 2 + else: + rttvar_sample = abs(smoothed_rtt - latest_rtt) + rttvar = 3/4 * rttvar + 1/4 * rttvar_sample + smoothed_rtt = 7/8 * smoothed_rtt + 1/8 * latest_rtt ~~~ @@ -998,9 +1000,9 @@ function is called. Note that a single ACK frame may newly acknowledge several packets. OnPacketAcked must be called once for each of these newly acknowledged packets. -OnPacketAcked takes two parameters: acked_packet, which is the struct detailed in -{{sent-packets-fields}}, and the packet number space that this ACK frame was sent -for. +OnPacketAcked takes two parameters: acked_packet, which is the struct detailed +in {{sent-packets-fields}}, and the packet number space that this ACK frame was +sent for. Pseudocode for OnPacketAcked follows: @@ -1122,7 +1124,8 @@ DetectLostPackets(pn_space): if (loss_time == 0): loss_time = unacked.time_sent + loss_delay else: - loss_time = min(loss_time, unacked.time_sent + loss_delay) + loss_time = min(loss_time, unacked.time_sent + + loss_delay) // Inform the congestion controller of lost packets and // let it decide whether to retransmit immediately. From 09fcf151d1378efbff43d0eaf983a47a6f2c0e23 Mon Sep 17 00:00:00 2001 From: afrind Date: Wed, 6 Feb 2019 09:10:13 -0800 Subject: [PATCH 029/190] Replace the RequireInsertCount decoding algorithm (#2379) * Replace the RequireInsertCount decoding algorithm This is @mt's alternate algorithm from #1930, and includes some of @bencebeky's language from #2249. I renamed 'rounded' to 'MaxWrapped' - it is largest possible value for RequiredInsertCount that is 0 mod 2*MaxEntries. Fixes #1930 Fixes #2112 * Martin's feedback * * Indicate that the algorithm is an example * Make normative text for error handling --- draft-ietf-quic-qpack.md | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/draft-ietf-quic-qpack.md b/draft-ietf-quic-qpack.md index 5a38dff520..2f3c0993d7 100644 --- a/draft-ietf-quic-qpack.md +++ b/draft-ietf-quic-qpack.md @@ -861,30 +861,38 @@ have. The smallest entry has empty name and value strings and has the size of `MaxTableCapacity` is the maximum capacity of the dynamic table as specified by the decoder (see {{maximum-dynamic-table-capacity}}). +This encoding limits the length of the prefix on long-lived connections. + +The decoder can reconstruct the Required Insert Count using an algorithm such as +the following. If the decoder encounters a value of EncodedInsertCount that +could not have been produced by a conformant encoder, it MUST treat this as a +stream error of type `HTTP_QPACK_DECOMPRESSION_FAILED`. -The decoder reconstructs the Required Insert Count using the following -algorithm, where TotalNumberOfInserts is the total number of inserts into the -decoder's dynamic table: +TotalNumberOfInserts is the total number of inserts into the decoder's dynamic +table. ~~~ + FullRange = 2 * MaxEntries if EncodedInsertCount == 0: ReqInsertCount = 0 else: - InsertCount = EncodedInsertCount - 1 - CurrentWrapped = TotalNumberOfInserts mod (2 * MaxEntries) - - if CurrentWrapped >= InsertCount + MaxEntries: - # Insert Count wrapped around 1 extra time - ReqInsertCount += 2 * MaxEntries - else if CurrentWrapped + MaxEntries < InsertCount: - # Decoder wrapped around 1 extra time - CurrentWrapped += 2 * MaxEntries - - ReqInsertCount += TotalNumberOfInserts - CurrentWrapped + if EncodedInsertCount > FullRange: + Error + MaxValue = TotalNumberOfInserts + MaxEntries + + # MaxWrapped is the largest possible value of + # ReqInsertCount that is 0 mod 2*MaxEntries + MaxWrapped = floor(MaxValue / FullRange) * FullRange + ReqInsertCount = MaxWrapped + EncodedInsertCount - 1 + + # If ReqInsertCount exceeds MaxValue, the Encoder's value + # must have wrapped one fewer time + if ReqInsertCount > MaxValue: + if ReqInsertCount < FullRange: + Error + ReqInsertCount -= FullRange ~~~ -This encoding limits the length of the prefix on long-lived connections. - For example, if the dynamic table is 100 bytes, then the Required Insert Count will be encoded modulo 6. If a decoder has received 10 inserts, then an encoded value of 3 indicates that the Required Insert Count is 9 for the header block. From 7a2d570807ffcbe61df584b6144949c188842296 Mon Sep 17 00:00:00 2001 From: afrind Date: Wed, 6 Feb 2019 09:10:48 -0800 Subject: [PATCH 030/190] QPACK: Clarify how maximum dynamic table capacity can be set (#2330) * QPACK: Clarify how maximum dynamic table capacity can be set 0-RTT client Use remembered value If 0, server can increase in SETTINGS otherwise server must use this value in SETTINGS Everyone else Starts at 0 Can be set to non-zero by SETTINGS This started as a modification of #2257, but the differences were significant enough I split it off. Fixes #2276 * Martin's comments * Clarify 0-RTT a little more --- draft-ietf-quic-qpack.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/draft-ietf-quic-qpack.md b/draft-ietf-quic-qpack.md index 2f3c0993d7..414b7c1e23 100644 --- a/draft-ietf-quic-qpack.md +++ b/draft-ietf-quic-qpack.md @@ -396,7 +396,7 @@ without Huffman encoding applied. ### Dynamic Table Capacity and Eviction {#eviction} The encoder sets the capacity of the dynamic table, which serves as the upper -limit on its size. +limit on its size. The initial capcity of the dynamic table is zero. Before a new entry is added to the dynamic table, entries are evicted from the end of the dynamic table until the size of the dynamic table is less than or @@ -432,16 +432,21 @@ The encoder MUST not set a dynamic table capacity that exceeds this maximum, but it can choose to use a lower dynamic table capacity (see {{set-dynamic-capacity}}). +For clients using 0-RTT data in HTTP/3, the server's maximum table capacity is +the remembered value of the setting, or zero if the value was not previously +sent. When the client's 0-RTT value of the SETTING is 0, the server MAY set it +to a non-zero value in its SETTINGS frame. If the remembered value is non-zero, +the server MUST send the same non-zero value in its SETTINGS frame. If it +specifies any other value, or omits SETTINGS_QPACK_MAX_TABLE_CAPACITY from +SETTINGS, the encoder must treat this as a connection error of type +`HTTP_QPACK_DECODER_STREAM_ERROR`. -### Initial Dynamic Table Capacity +For HTTP/3 servers and HTTP/3 clients when 0-RTT is not attempted or is +rejected, the maximum table capacity is 0 until the encoder processes a SETTINGS +frame with a non-zero value of SETTINGS_QPACK_MAX_TABLE_CAPACITY. -The initial dynamic table capacity is determined by the corresponding setting -when HTTP requests or responses are first permitted to be sent. For clients -using 0-RTT data in HTTP/3, the initial table capacity is the remembered value -of the setting, even if the server later specifies a larger maximum dynamic -table capacity in its SETTINGS frame. For HTTP/3 servers and HTTP/3 clients -when 0-RTT is not attempted or is rejected, the initial table capacity is the -value of the setting in the peer's SETTINGS frame. +When the maximum table capacity is 0, the encoder MUST NOT insert entries into +the dynamic table, and MUST NOT send any instructions on the encoder stream. ### Absolute Indexing {#indexing} From e94bdc2cafb07ee711b91281591dc45637467bae Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Wed, 6 Feb 2019 11:02:53 -0800 Subject: [PATCH 031/190] Discard inconsistent packets --- draft-ietf-quic-transport.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 89a6c40ecf..012b842d68 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1010,8 +1010,10 @@ Endpoints can send a Stateless Reset ({{stateless-reset}}) for any packets that cannot be attributed to an existing connection. A stateless reset allows a peer to more quickly identify when a connection becomes unusable. -Packets that are matched to an existing connection, but for which the endpoint -cannot remove packet protection, are discarded. +Packets that are matched to an existing connection are discarded if the packets +are inconsistent with the state of that connection -- for example, if they +indicate a different protocol version than that of the connection, or if the +endpoint cannot remove packet protection. Invalid packets without packet protection, such as Initial, Retry, or Version Negotiation, MAY be discarded. An endpoint MUST generate a connection error if From 105dd3213812cde18c65240efc7ae1f339fae65b Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Wed, 6 Feb 2019 16:45:14 -0800 Subject: [PATCH 032/190] Removal is unsuccessful --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 012b842d68..883f79adaf 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1013,7 +1013,7 @@ to more quickly identify when a connection becomes unusable. Packets that are matched to an existing connection are discarded if the packets are inconsistent with the state of that connection -- for example, if they indicate a different protocol version than that of the connection, or if the -endpoint cannot remove packet protection. +removal of packet protection is unsuccessful. Invalid packets without packet protection, such as Initial, Retry, or Version Negotiation, MAY be discarded. An endpoint MUST generate a connection error if From f45707fa254156ed571645ff83a8001a362e7357 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 7 Feb 2019 09:03:17 +0800 Subject: [PATCH 033/190] kPacketNumberSpace --- draft-ietf-quic-recovery.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index d8773e749a..7ae4232db3 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -819,10 +819,10 @@ kGranularity: kInitialRtt: : The RTT used before an RTT sample is taken. The RECOMMENDED value is 100ms. -pn_space: +kPacketNumberSpace: : An enum to enumerate the three packet number spaces. ~~~ - enum pn_space { + enum kPacketNumberSpace { Initial, Handshake, 1-RTT, @@ -850,10 +850,10 @@ time_of_last_sent_ack_eliciting_packet: time_of_last_sent_crypto_packet: : The time the most recent crypto packet was sent. -largest_sent_packet[pn_space]: +largest_sent_packet[kPacketNumberSpace]: : The packet number of the most recently sent packet in the packet number space. -largest_acked_packet[pn_space]: +largest_acked_packet[kPacketNumberSpace]: : The largest packet number acknowledged in the packet number space so far. latest_rtt: @@ -881,7 +881,7 @@ loss_time: exceeding the reordering window in time. Only applies to the 1-RTT packet number space. -sent_packets[pn_space]: +sent_packets[kPacketNumberSpace]: : An association of packet numbers in a packet number space to information about them. Described in detail above in {{tracking-sent-packets}}. From 23720eb15b5abf9ceb28dcc2c2ed2c573c9a0ed7 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 7 Feb 2019 10:55:03 +0800 Subject: [PATCH 034/190] 1-RTT => Application data --- draft-ietf-quic-recovery.md | 100 ++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 7ae4232db3..5203a06443 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -825,7 +825,7 @@ kPacketNumberSpace: enum kPacketNumberSpace { Initial, Handshake, - 1-RTT, + Application data, } ~~~ @@ -878,8 +878,8 @@ max_ack_delay: loss_time: : The time at which the next packet will be considered lost based on - exceeding the reordering window in time. Only applies to the 1-RTT packet - number space. + exceeding the reordering window in time. Only applies to the Application data + packet number space. sent_packets[kPacketNumberSpace]: : An association of packet numbers in a packet number space to information @@ -901,7 +901,7 @@ follows: min_rtt = infinite time_of_last_sent_ack_eliciting_packet = 0 time_of_last_sent_crypto_packet = 0 - for pn_space in [ Initial, Handshake, 1-RTT ]: + for pn_space in [ Initial, Handshake, Applicaton data ]: largest_sent_packet[pn_space] = 0 largest_acked_packet[pn_space] = 0 ~~~ @@ -1027,38 +1027,38 @@ timers wake up late. Timers set in the past SHOULD fire immediately. Pseudocode for SetLossDetectionTimer follows: ~~~ - SetLossDetectionTimer(): - // Don't arm timer if there are no ack-eliciting packets - // in flight. - if (no ack-eliciting packets in flight): - loss_detection_timer.cancel() - return - - if (crypto packets are in flight): - // Crypto retransmission timer. - if (smoothed_rtt == 0): - timeout = 2 * kInitialRtt - else: - timeout = 2 * smoothed_rtt - timeout = max(timeout, kGranularity) - timeout = timeout * (2 ^ crypto_count) - loss_detection_timer.update( - time_of_last_sent_crypto_packet + timeout) - return - if (loss_time != 0): - // Time threshold loss detection. - // Only applies to the 1-RTT packet number space. - loss_detection_timer.update(loss_time) - return - - // Calculate PTO duration - timeout = - smoothed_rtt + 4 * rttvar + max_ack_delay - timeout = max(timeout, kGranularity) - timeout = timeout * (2 ^ pto_count) +SetLossDetectionTimer(): + // Don't arm timer if there are no ack-eliciting packets + // in flight. + if (no ack-eliciting packets in flight): + loss_detection_timer.cancel() + return + if (crypto packets are in flight): + // Crypto retransmission timer. + if (smoothed_rtt == 0): + timeout = 2 * kInitialRtt + else: + timeout = 2 * smoothed_rtt + timeout = max(timeout, kGranularity) + timeout = timeout * (2 ^ crypto_count) loss_detection_timer.update( - time_of_last_sent_ack_eliciting_packet + timeout) + time_of_last_sent_crypto_packet + timeout) + return + if (loss_time != 0): + // Time threshold loss detection. + // Only applies to the Application data packet number space. + loss_detection_timer.update(loss_time) + return + + // Calculate PTO duration + timeout = + smoothed_rtt + 4 * rttvar + max_ack_delay + timeout = max(timeout, kGranularity) + timeout = timeout * (2 ^ pto_count) + + loss_detection_timer.update( + time_of_last_sent_ack_eliciting_packet + timeout) ~~~ @@ -1070,21 +1070,21 @@ to be performed. Pseudocode for OnLossDetectionTimeout follows: ~~~ - OnLossDetectionTimeout(): - if (crypto packets are in flight): - // Crypto retransmission timeout. - RetransmitUnackedCryptoData() - crypto_count++ - else if (loss_time != 0): - // Time threshold loss Detection - // Only applies to the 1-RTT packet number space. - DetectLostPackets(1-RTT) - else: - // PTO - SendOneOrTwoPackets() - pto_count++ +OnLossDetectionTimeout(): + if (crypto packets are in flight): + // Crypto retransmission timeout. + RetransmitUnackedCryptoData() + crypto_count++ + else if (loss_time != 0): + // Time threshold loss Detection + // Only applies to the Application data packet number space. + DetectLostPackets(Application data) + else: + // PTO + SendOneOrTwoPackets() + pto_count++ - SetLossDetectionTimer() + SetLossDetectionTimer() ~~~ @@ -1099,7 +1099,7 @@ Pseudocode for DetectLostPackets follows: ~~~ DetectLostPackets(pn_space): - if (pn_space == 1-RTT): + if (pn_space == Application data): loss_time = 0 lost_packets = {} loss_delay = kTimeThreshold * max(latest_rtt, smoothed_rtt) @@ -1120,7 +1120,7 @@ DetectLostPackets(pn_space): sent_packets.remove(unacked.packet_number) if (unacked.in_flight): lost_packets.insert(unacked) - else if (pn_space == 1-RTT): + else if (pn_space == Application data): if (loss_time == 0): loss_time = unacked.time_sent + loss_delay else: From 9cd3dfef754d23334e54c779171fd13a266628d0 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 7 Feb 2019 23:23:09 +0800 Subject: [PATCH 035/190] Application data => ApplicationData --- draft-ietf-quic-recovery.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 5203a06443..c7688cb9eb 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -825,7 +825,7 @@ kPacketNumberSpace: enum kPacketNumberSpace { Initial, Handshake, - Application data, + ApplicationData, } ~~~ @@ -878,7 +878,7 @@ max_ack_delay: loss_time: : The time at which the next packet will be considered lost based on - exceeding the reordering window in time. Only applies to the Application data + exceeding the reordering window in time. Only applies to the ApplicationData packet number space. sent_packets[kPacketNumberSpace]: @@ -1047,7 +1047,7 @@ SetLossDetectionTimer(): return if (loss_time != 0): // Time threshold loss detection. - // Only applies to the Application data packet number space. + // Only applies to the ApplicationData packet number space. loss_detection_timer.update(loss_time) return @@ -1077,8 +1077,8 @@ OnLossDetectionTimeout(): crypto_count++ else if (loss_time != 0): // Time threshold loss Detection - // Only applies to the Application data packet number space. - DetectLostPackets(Application data) + // Only applies to the ApplicationData packet number space. + DetectLostPackets(ApplicationData) else: // PTO SendOneOrTwoPackets() @@ -1099,7 +1099,7 @@ Pseudocode for DetectLostPackets follows: ~~~ DetectLostPackets(pn_space): - if (pn_space == Application data): + if (pn_space == ApplicationData): loss_time = 0 lost_packets = {} loss_delay = kTimeThreshold * max(latest_rtt, smoothed_rtt) @@ -1120,7 +1120,7 @@ DetectLostPackets(pn_space): sent_packets.remove(unacked.packet_number) if (unacked.in_flight): lost_packets.insert(unacked) - else if (pn_space == Application data): + else if (pn_space == ApplicationData): if (loss_time == 0): loss_time = unacked.time_sent + loss_delay else: From c9da9ee12a8e9a7d48ba8e3818ed0df5a7e16e28 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Thu, 7 Feb 2019 21:56:51 +0530 Subject: [PATCH 036/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index c7688cb9eb..1e25cc3b3f 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -901,7 +901,7 @@ follows: min_rtt = infinite time_of_last_sent_ack_eliciting_packet = 0 time_of_last_sent_crypto_packet = 0 - for pn_space in [ Initial, Handshake, Applicaton data ]: + for pn_space in [ Initial, Handshake, ApplicatonData ]: largest_sent_packet[pn_space] = 0 largest_acked_packet[pn_space] = 0 ~~~ @@ -1045,6 +1045,7 @@ SetLossDetectionTimer(): loss_detection_timer.update( time_of_last_sent_crypto_packet + timeout) return + if (loss_time != 0): // Time threshold loss detection. // Only applies to the ApplicationData packet number space. From 6c33bd4e50acde88ccc6517cf4c8c4811bd1ed17 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Thu, 7 Feb 2019 15:15:41 -0800 Subject: [PATCH 037/190] Varint the frame types --- draft-ietf-quic-http.md | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 20c475bcd6..ef44fea9a9 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -423,7 +423,9 @@ All frames have the following format: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Type (8) | Length (i) ... +| Type (i) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Length (i) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Frame Payload (*) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -433,12 +435,10 @@ All frames have the following format: A frame includes the following fields: Type: - : An 8-bit type for the frame. - + : A variable-length type for the frame. Length: : A variable-length integer that describes the length of the Frame Payload. - This length does not include the Type field. Frame Payload: : A payload, the semantics of which are determined by the Type field. @@ -1498,15 +1498,17 @@ This document creates a new registration for version-negotiation hints in the ## Frame Types {#iana-frames} This document establishes a registry for HTTP/3 frame type codes. The "HTTP/3 -Frame Type" registry manages an 8-bit space. The "HTTP/3 Frame Type" registry -operates under either of the "IETF Review" or "IESG Approval" policies -{{?RFC8126}} for values from 0x00 up to and including 0xef, with values from -0xf0 up to and including 0xff being reserved for Experimental Use. +Frame Type" registry governs a 62-bit space. This space is split into three +spaces that are governed by different policies. Values between 0x00 and 0x3f (in +hexadecimal) are assigned via the Standards Action or IESG Review policies +{{!RFC8126}}. Values from 0x40 to 0x3fff operate on the Specification Required +policy {{!RFC8126}}. All other values are assigned to Private Use {{!RFC8126}}. While this registry is separate from the "HTTP/2 Frame Type" registry defined in -{{RFC7540}}, it is preferable that the assignments parallel each other. If an -entry is present in only one registry, every effort SHOULD be made to avoid -assigning the corresponding value to an unrelated operation. +{{RFC7540}}, it is preferable that the assignments parallel each other where the +code spaces overlap. If an entry is present in only one registry, every effort +SHOULD be made to avoid assigning the corresponding value to an unrelated +operation. New entries in this registry require the following information: @@ -1514,7 +1516,7 @@ Frame Type: : A name or label for the frame type. Code: -: The 8-bit code assigned to the frame type. +: The 62-bit code assigned to the frame type. Specification: : A reference to a specification that includes a description of the frame layout @@ -1540,15 +1542,9 @@ The entries in the following table are registered by this document. | DUPLICATE_PUSH | 0xE | {{frame-duplicate-push}} | | ---------------- | ------ | -------------------------- | -Additionally, each code of the format `0xb + (0x1f * N)` for values of N in the -range (0..7) (that is, `0xb`, `0x2a`, `0x49`, `0x68`, `0x87`, `0xa6`, `0xc5`, -and `0xe4`), the following values should be registered: - -Frame Type: -: Reserved - GREASE - -Specification: -: {{frame-grease}} +Additionally, each code of the format `0xb + (0x1f * N)` for all integer values +of N (that is, `0xb`, `0x2a`, ..., through `0x3fffffffffffffe8`) MUST NOT be +assigned by IANA. ## Settings Parameters {#iana-settings} From f52e62fc20caf3edd0bdd49dabc315b553542229 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Thu, 7 Feb 2019 15:18:03 -0800 Subject: [PATCH 038/190] Concomitant change to HTTP_MALFORMED_FRAME_TYPE --- draft-ietf-quic-http.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index ef44fea9a9..55d5940a36 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1441,9 +1441,10 @@ HTTP_GENERAL_PROTOCOL_ERROR (0x00FF): specific error code, or endpoint declines to use the more specific error code. HTTP_MALFORMED_FRAME (0x01XX): -: An error in a specific frame type. The frame type is included as the last - byte of the error code. For example, an error in a MAX_PUSH_ID frame would be - indicated with the code (0x10D). +: An error in a specific frame type. If the frame type is `0xfe` or less, the + type is included as the last byte of the error code. For example, an error in + a MAX_PUSH_ID frame would be indicated with the code (0x10D). The last byte + `0xff` is used to indicate any frame type greater than `0xfe`. # Security Considerations From cbe62b9866a22bcbbb70f285300510c205a494d2 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Thu, 7 Feb 2019 15:29:24 -0800 Subject: [PATCH 039/190] Varint the stream types --- draft-ietf-quic-http.md | 64 +++++++++++++++++++--------------------- draft-ietf-quic-qpack.md | 14 ++++----- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 55d5940a36..4feaba971d 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -303,15 +303,16 @@ specify a value of zero for the QUIC transport parameter ## Unidirectional Streams Unidirectional streams, in either direction, are used for a range of purposes. -The purpose is indicated by a stream type, which is sent as a single byte header -at the start of the stream. The format and structure of data that follows this -header is determined by the stream type. +The purpose is indicated by a stream type, which is sent as a variable-length +integer at the start of the stream. The format and structure of data that +follows this header is determined by the stream type. ~~~~~~~~~~ drawing - 0 1 2 3 4 5 6 7 -+-+-+-+-+-+-+-+-+ -|Stream Type (8)| -+-+-+-+-+-+-+-+-+ + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Stream Type (i) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~~~~~~~~ {: #fig-stream-header title="Unidirectional Stream Header"} @@ -340,8 +341,8 @@ the reception of the unidirectional stream header. ### Control Streams -A control stream is indicated by a stream type of `0x43` (ASCII 'C'). Data on -this stream consists of HTTP/3 frames, as defined in {{frames}}. +A control stream is indicated by a stream type of `0x00`. Data on this stream +consists of HTTP/3 frames, as defined in {{frames}}. Each side MUST initiate a single control stream at the beginning of the connection and send its SETTINGS frame as the first frame on this stream. If @@ -360,11 +361,11 @@ able to send stream data first after the cryptographic handshake completes. ### Push Streams -A push stream is indicated by a stream type of `0x50` (ASCII 'P'), followed by -the Push ID of the promise that it fulfills, encoded as a variable-length -integer. The remaining data on this stream consists of HTTP/3 frames, as defined -in {{frames}}, and fulfills a promised server push. Server push and Push IDs -are described in {{server-push}}. +A push stream is indicated by a stream type of `0x01`, followed by the Push ID +of the promise that it fulfills, encoded as a variable-length integer. The +remaining data on this stream consists of HTTP/3 frames, as defined in +{{frames}}, and fulfills a promised server push. Server push and Push IDs are +described in {{server-push}}. Only servers can push; if a server receives a client-initiated push stream, this MUST be treated as a stream error of type HTTP_WRONG_STREAM_DIRECTION. @@ -373,7 +374,9 @@ MUST be treated as a stream error of type HTTP_WRONG_STREAM_DIRECTION. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -|Stream Type (8)| Push ID (i) ... +| Stream Type (i) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Push ID (i) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~~~~~~~~ {: #fig-push-stream-header title="Push Stream Header"} @@ -1654,10 +1657,12 @@ The entries in the following table are registered by this document. ## Stream Types {#iana-stream-types} This document establishes a registry for HTTP/3 unidirectional stream types. The -"HTTP/3 Stream Type" registry manages an 8-bit space. The "HTTP/3 Stream Type" -registry operates under either of the "IETF Review" or "IESG Approval" policies -{{?RFC8126}} for values from 0x00 up to and including 0xef, with values from -0xf0 up to and including 0xff being reserved for Experimental Use. +"HTTP/3 Stream Type" registry governs a 62-bit space. This space is split into +three spaces that are governed by different policies. Values between 0x00 and +0x3f (in hexadecimal) are assigned via the Standards Action or IESG Review +policies {{!RFC8126}}. Values from 0x40 to 0x3fff operate on the Specification +Required policy {{!RFC8126}}. All other values are assigned to Private Use +{{!RFC8126}}. New entries in this registry require the following information: @@ -1665,7 +1670,7 @@ Stream Type: : A name or label for the stream type. Code: -: The 8-bit code assigned to the stream type. +: The 62-bit code assigned to the stream type. Specification: : A reference to a specification that includes a description of the stream type, @@ -1680,22 +1685,13 @@ The entries in the following table are registered by this document. | ---------------- | ------ | -------------------------- | ------ | | Stream Type | Code | Specification | Sender | | ---------------- | :----: | -------------------------- | ------ | -| Control Stream | 0x43 | {{control-streams}} | Both | -| Push Stream | 0x50 | {{server-push}} | Server | +| Control Stream | 0x00 | {{control-streams}} | Both | +| Push Stream | 0x01 | {{server-push}} | Server | | ---------------- | ------ | -------------------------- | ------ | -Additionally, for each code of the format `0x1f * N` for values of N in the -range (0..8) (that is, `0x00`, `0x1f`, `0x3e`, `0x5d`, `0x7c`, `0x9b`, `0xba`, -`0xd9`, `0xf8`), the following values should be registered: - -Stream Type: -: Reserved - GREASE - -Specification: -: {{stream-grease}} - -Sender: -: Both +Additionally, each code of the format `0x1f * N` for integer values of N (that +is, `0x00`, `0x1f`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be assigned by +IANA. --- back diff --git a/draft-ietf-quic-qpack.md b/draft-ietf-quic-qpack.md index 414b7c1e23..63cd4ed66a 100644 --- a/draft-ietf-quic-qpack.md +++ b/draft-ietf-quic-qpack.md @@ -585,12 +585,12 @@ and follows the definitions in [RFC7541] without modification. QPACK instructions occur in three locations, each of which uses a separate instruction space: - - The encoder stream is a unidirectional stream of type `0x48` (ASCII 'H') - which carries table updates from encoder to decoder. + - The encoder stream is a unidirectional stream of type `0x02` which carries + table updates from encoder to decoder. - - The decoder stream is a unidirectional stream of type `0x68` (ASCII 'h') - which carries acknowledgements of table modifications and header processing - from decoder to encoder. + - The decoder stream is a unidirectional stream of type `0x03` which carries + acknowledgements of table modifications and header processing from decoder to + encoder. - Finally, the contents of HEADERS and PUSH_PROMISE frames on request streams and push streams reference the QPACK table state. @@ -1136,8 +1136,8 @@ The entries in the following table are registered by this document. | ---------------------------- | ------ | ------------------------- | ------ | | Stream Type | Code | Specification | Sender | | ---------------------------- | :----: | ------------------------- | ------ | -| QPACK Encoder Stream | 0x48 | {{wire-format}} | Both | -| QPACK Decoder Stream | 0x68 | {{wire-format}} | Both | +| QPACK Encoder Stream | 0x02 | {{wire-format}} | Both | +| QPACK Decoder Stream | 0x03 | {{wire-format}} | Both | | ---------------------------- | ------ | ------------------------- | ------ | ## Error Code Registration From cf01b3d5674bdbf6e4cfc86992527753b41cb9e4 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Thu, 7 Feb 2019 15:35:21 -0800 Subject: [PATCH 040/190] Format values --- draft-ietf-quic-http.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 4feaba971d..894f693cd5 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1503,10 +1503,11 @@ This document creates a new registration for version-negotiation hints in the This document establishes a registry for HTTP/3 frame type codes. The "HTTP/3 Frame Type" registry governs a 62-bit space. This space is split into three -spaces that are governed by different policies. Values between 0x00 and 0x3f (in -hexadecimal) are assigned via the Standards Action or IESG Review policies -{{!RFC8126}}. Values from 0x40 to 0x3fff operate on the Specification Required -policy {{!RFC8126}}. All other values are assigned to Private Use {{!RFC8126}}. +spaces that are governed by different policies. Values between `0x00` and `0x3f` +(in hexadecimal) are assigned via the Standards Action or IESG Review policies +{{!RFC8126}}. Values from `0x40` to `0x3fff` operate on the Specification +Required policy {{!RFC8126}}. All other values are assigned to Private Use +{{!RFC8126}}. While this registry is separate from the "HTTP/2 Frame Type" registry defined in {{RFC7540}}, it is preferable that the assignments parallel each other where the @@ -1658,11 +1659,11 @@ The entries in the following table are registered by this document. This document establishes a registry for HTTP/3 unidirectional stream types. The "HTTP/3 Stream Type" registry governs a 62-bit space. This space is split into -three spaces that are governed by different policies. Values between 0x00 and +three spaces that are governed by different policies. Values between `0x00` and 0x3f (in hexadecimal) are assigned via the Standards Action or IESG Review -policies {{!RFC8126}}. Values from 0x40 to 0x3fff operate on the Specification -Required policy {{!RFC8126}}. All other values are assigned to Private Use -{{!RFC8126}}. +policies {{!RFC8126}}. Values from `0x40` to `0x3fff` operate on the +Specification Required policy {{!RFC8126}}. All other values are assigned to +Private Use {{!RFC8126}}. New entries in this registry require the following information: From 2d18efff91edde9ebdd64be308cabcf31d4ca66d Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Thu, 7 Feb 2019 15:38:26 -0800 Subject: [PATCH 041/190] Varint the Settings Identifiers --- draft-ietf-quic-http.md | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 894f693cd5..9d3bf106cf 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -674,14 +674,16 @@ treat the presence of the same parameter more than once as a connection error of type HTTP_MALFORMED_FRAME. The payload of a SETTINGS frame consists of zero or more parameters, each -consisting of an unsigned 16-bit setting identifier and a value which uses the +consisting of a setting identifier and a value, each of which uses the QUIC variable-length integer encoding. ~~~~~~~~~~~~~~~ drawing 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Identifier (16) | Value (i) ... +| Identifier (i) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Value (i) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~~~~~~~~~~~~~ {: #fig-ext-settings title="SETTINGS parameter format"} @@ -701,7 +703,7 @@ The following settings are defined in HTTP/3: : The default value is 0. However, this value SHOULD be set to a non-zero value by servers. See {{placeholders}} for usage. -Setting identifiers of the format `0x?a?a` are reserved to exercise the +Setting identifiers of the format `0x1f * N` are reserved to exercise the requirement that unknown identifiers be ignored. Such settings have no defined meaning. Endpoints SHOULD include at least one such setting in their SETTINGS frame. Endpoints MUST NOT consider such settings to have any meaning upon @@ -1554,10 +1556,12 @@ assigned by IANA. ## Settings Parameters {#iana-settings} This document establishes a registry for HTTP/3 settings. The "HTTP/3 Settings" -registry manages a 16-bit space. The "HTTP/3 Settings" registry operates under -the "Expert Review" policy {{?RFC8126}} for values in the range from 0x0000 to -0xefff, with values between and 0xf000 and 0xffff being reserved for -Experimental Use. The designated experts are the same as those for the "HTTP/2 +registry governs a 62-bit space. This space is split into three spaces that are +governed by different policies. Values between `0x00` and `0x3f` (in +hexadecimal) are assigned via the Standards Action or IESG Review policies +{{!RFC8126}}. Values from `0x40` to `0x3fff` operate on the Specification +Required policy {{!RFC8126}}. All other values are assigned to Private Use +{{!RFC8126}}. The designated experts are the same as those for the "HTTP/2 Settings" registry defined in {{RFC7540}}. While this registry is separate from the "HTTP/2 Settings" registry defined in @@ -1571,7 +1575,7 @@ Name: : A symbolic name for the setting. Specifying a setting name is optional. Code: -: The 16-bit code assigned to the setting. +: The 62-bit code assigned to the setting. Specification: : An optional reference to a specification that describes the use of the @@ -1590,15 +1594,9 @@ The entries in the following table are registered by this document. | NUM_PLACEHOLDERS | 0x8 | {{settings-parameters}} | | ---------------------------- | ------ | ------------------------- | -Additionally, each code of the format `0x?a?a` where each `?` is any four bits -(that is, `0x0a0a`, `0x0a1a`, etc. through `0xfafa`), the following values -should be registered: - -Name: -: Reserved - GREASE - -Specification: -: {{settings-parameters}} +Additionally, each code of the format `0x1f * N` for integer values of N (that +is, `0x00`, `0x1f`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be assigned by +IANA. ## Error Codes {#iana-error-codes} From 771c7d36a68f8df1a84e5e25421f36ac35f36ebf Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Thu, 7 Feb 2019 15:42:25 -0800 Subject: [PATCH 042/190] Mention the difference in HTTP/2 considerations --- draft-ietf-quic-http.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 9d3bf106cf..50dac1c8d9 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1816,7 +1816,9 @@ CONTINUATION (0x9): Frame types defined by extensions to HTTP/2 need to be separately registered for HTTP/3 if still applicable. The IDs of frames defined in {{!RFC7540}} have been -reserved for simplicity. See {{iana-frames}}. +reserved for simplicity. Note that the frame type space in HTTP/3 is +substantially larger (62 bits versus 8 bits), so many HTTP/3 frame types have no +equivalent HTTP/2 code point. See {{iana-frames}}. ## HTTP/2 SETTINGS Parameters {#h2-settings} @@ -1860,7 +1862,9 @@ use the full 32-bit space. Settings ported from HTTP/2 might choose to redefine the format of their settings to avoid using the 62-bit encoding. Settings need to be defined separately for HTTP/2 and HTTP/3. The IDs of -settings defined in {{!RFC7540}} have been reserved for simplicity. See +settings defined in {{!RFC7540}} have been reserved for simplicity. Note that +the settings identifier space in HTTP/3 is substantially larger (62 bits versus +16 bits), so many HTTP/3 settings have no equivalent HTTP/2 code point. See {{iana-settings}}. From 33cbc34885bb59c464218d48ed204bce3a0f585b Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Thu, 7 Feb 2019 15:46:47 -0800 Subject: [PATCH 043/190] Make frame type greasing consistent --- draft-ietf-quic-http.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 50dac1c8d9..058c91d1ca 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -886,12 +886,11 @@ the DUPLICATE_PUSH. ### Reserved Frame Types {#frame-grease} -Frame types of the format `0xb + (0x1f * N)` are reserved to exercise the -requirement that unknown types be ignored ({{extensions}}). These frames have no -semantic value, and can be sent when application-layer padding is desired. They -MAY also be sent on connections where no request data is currently being -transferred. Endpoints MUST NOT consider these frames to have any meaning upon -receipt. +Frame types of the format `0x1f * N` are reserved to exercise the requirement +that unknown types be ignored ({{extensions}}). These frames have no semantic +value, and can be sent when application-layer padding is desired. They MAY also +be sent on connections where no request data is currently being transferred. +Endpoints MUST NOT consider these frames to have any meaning upon receipt. The payload and length of the frames are selected in any manner the implementation chooses. @@ -1549,9 +1548,9 @@ The entries in the following table are registered by this document. | DUPLICATE_PUSH | 0xE | {{frame-duplicate-push}} | | ---------------- | ------ | -------------------------- | -Additionally, each code of the format `0xb + (0x1f * N)` for all integer values -of N (that is, `0xb`, `0x2a`, ..., through `0x3fffffffffffffe8`) MUST NOT be -assigned by IANA. +Additionally, each code of the format `0x1f * N` for integer values of N (that +is, `0x00`, `0x1f`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be assigned by +IANA. ## Settings Parameters {#iana-settings} From 6e5f470ee4e1b6f8bff1f3a24b20b29bcfed38f7 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Thu, 7 Feb 2019 15:59:32 -0800 Subject: [PATCH 044/190] Explicit value in fig-push-stream-header --- draft-ietf-quic-http.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 058c91d1ca..7a416a4d53 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -374,9 +374,7 @@ MUST be treated as a stream error of type HTTP_WRONG_STREAM_DIRECTION. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Stream Type (i) ... -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Push ID (i) ... +| 0x01 (8) | Push ID (i) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~~~~~~~~ {: #fig-push-stream-header title="Push Stream Header"} From f06211da71550e9a7ed03cc42d96ec5dc84dd3f0 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Thu, 7 Feb 2019 16:03:18 -0800 Subject: [PATCH 045/190] Non-zero values of N only --- draft-ietf-quic-http.md | 50 +++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 7a416a4d53..bc426e85fc 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -385,11 +385,12 @@ client MUST treat this as a connection error of type HTTP_DUPLICATE_PUSH. ### Reserved Stream Types {#stream-grease} -Stream types of the format `0x1f * N` are reserved to exercise the requirement -that unknown types be ignored. These streams have no semantic meaning, and can -be sent when application-layer padding is desired. They MAY also be sent on -connections where no request data is currently being transferred. Endpoints MUST -NOT consider these streams to have any meaning upon receipt. +Stream types of the format `0x1f * N` for non-zero values of N are reserved to +exercise the requirement that unknown types be ignored. These streams have no +semantic meaning, and can be sent when application-layer padding is desired. +They MAY also be sent on connections where no request data is currently being +transferred. Endpoints MUST NOT consider these streams to have any meaning upon +receipt. The payload and length of the stream are selected in any manner the implementation chooses. @@ -701,11 +702,11 @@ The following settings are defined in HTTP/3: : The default value is 0. However, this value SHOULD be set to a non-zero value by servers. See {{placeholders}} for usage. -Setting identifiers of the format `0x1f * N` are reserved to exercise the -requirement that unknown identifiers be ignored. Such settings have no defined -meaning. Endpoints SHOULD include at least one such setting in their SETTINGS -frame. Endpoints MUST NOT consider such settings to have any meaning upon -receipt. +Setting identifiers of the format `0x1f * N` for non-zero values of N are +reserved to exercise the requirement that unknown identifiers be ignored. Such +settings have no defined meaning. Endpoints SHOULD include at least one such +setting in their SETTINGS frame. Endpoints MUST NOT consider such settings to +have any meaning upon receipt. Because the setting has no defined meaning, the value of the setting can be any value the implementation selects. @@ -884,11 +885,12 @@ the DUPLICATE_PUSH. ### Reserved Frame Types {#frame-grease} -Frame types of the format `0x1f * N` are reserved to exercise the requirement -that unknown types be ignored ({{extensions}}). These frames have no semantic -value, and can be sent when application-layer padding is desired. They MAY also -be sent on connections where no request data is currently being transferred. -Endpoints MUST NOT consider these frames to have any meaning upon receipt. +Frame types of the format `0x1f * N` for non-zero values of N are reserved to +exercise the requirement that unknown types be ignored ({{extensions}}). These +frames have no semantic value, and can be sent when application-layer padding is +desired. They MAY also be sent on connections where no request data is currently +being transferred. Endpoints MUST NOT consider these frames to have any meaning +upon receipt. The payload and length of the frames are selected in any manner the implementation chooses. @@ -1546,9 +1548,9 @@ The entries in the following table are registered by this document. | DUPLICATE_PUSH | 0xE | {{frame-duplicate-push}} | | ---------------- | ------ | -------------------------- | -Additionally, each code of the format `0x1f * N` for integer values of N (that -is, `0x00`, `0x1f`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be assigned by -IANA. +Additionally, each code of the format `0x1f * N` for for non-zero integer values +of N (that is, `0x1f`, `0x3e`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be +assigned by IANA. ## Settings Parameters {#iana-settings} @@ -1591,9 +1593,9 @@ The entries in the following table are registered by this document. | NUM_PLACEHOLDERS | 0x8 | {{settings-parameters}} | | ---------------------------- | ------ | ------------------------- | -Additionally, each code of the format `0x1f * N` for integer values of N (that -is, `0x00`, `0x1f`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be assigned by -IANA. +Additionally, each code of the format `0x1f * N` for for non-zero integer values +of N (that is, `0x1f`, `0x3e`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be +assigned by IANA. ## Error Codes {#iana-error-codes} @@ -1685,9 +1687,9 @@ The entries in the following table are registered by this document. | Push Stream | 0x01 | {{server-push}} | Server | | ---------------- | ------ | -------------------------- | ------ | -Additionally, each code of the format `0x1f * N` for integer values of N (that -is, `0x00`, `0x1f`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be assigned by -IANA. +Additionally, each code of the format `0x1f * N` for non-zero integer values of +N (that is, `0x1f`, `0x3e`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be +assigned by IANA. --- back From fb9f6904c61e83188813376f8b6be1c09b622b82 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 8 Feb 2019 13:22:51 +1100 Subject: [PATCH 046/190] No connection ID = no migration --- draft-ietf-quic-transport.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index e58afcc067..9477f81439 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1853,7 +1853,9 @@ An endpoint also MUST NOT initiate connection migration if the peer sent the `disable_migration` transport parameter during the handshake. An endpoint which has sent this transport parameter, but detects that a peer has nonetheless migrated to a different network MAY treat this as a connection error of type -INVALID_MIGRATION. +INVALID_MIGRATION. Similarly, an endpoint MUST NOT migrate if its peer supplies +a zero-length connection ID as packets without a Destination Connection ID +cannot be attributed to a connection based on address tuple. Not all changes of peer address are intentional migrations. The peer could experience NAT rebinding: a change of address due to a middlebox, usually a NAT, @@ -2118,10 +2120,6 @@ connection IDs cannot migrate. To ensure that migration is possible and packets sent on different paths cannot be correlated, endpoints SHOULD provide new connection IDs before peers migrate. -If a peer chooses to receive packets with zero-length connection IDs, an -endpoint can always migrate, because zero-length connection IDs provide no -significant linkability. - ## Server's Preferred Address {#preferred-address} From 8d9bf8577027bc2639f3cc9d20b276de2863272d Mon Sep 17 00:00:00 2001 From: ianswett Date: Fri, 8 Feb 2019 13:25:16 -0800 Subject: [PATCH 047/190] Update draft-ietf-quic-http.md Co-Authored-By: MikeBishop --- draft-ietf-quic-http.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index bc426e85fc..f1c2d184a8 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -305,7 +305,7 @@ specify a value of zero for the QUIC transport parameter Unidirectional streams, in either direction, are used for a range of purposes. The purpose is indicated by a stream type, which is sent as a variable-length integer at the start of the stream. The format and structure of data that -follows this header is determined by the stream type. +follows this integer is determined by the stream type. ~~~~~~~~~~ drawing 0 1 2 3 From 5379931cb0dc3931c0dde09839420adb4f68dfb9 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 8 Feb 2019 14:37:22 -0800 Subject: [PATCH 048/190] Revert "Explicit value in fig-push-stream-header" This reverts commit 6e5f470ee4e1b6f8bff1f3a24b20b29bcfed38f7. --- draft-ietf-quic-http.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index f1c2d184a8..7dd589833f 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -374,7 +374,9 @@ MUST be treated as a stream error of type HTTP_WRONG_STREAM_DIRECTION. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| 0x01 (8) | Push ID (i) ... +| Stream Type (i) ... ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Push ID (i) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~~~~~~~~ {: #fig-push-stream-header title="Push Stream Header"} From 3e2dbea894c2e3fe4fe4d63e9592ddf4c1e0f1bc Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 8 Feb 2019 14:38:16 -0800 Subject: [PATCH 049/190] Varint explicit value --- draft-ietf-quic-http.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 7dd589833f..1b7ee2830d 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -374,7 +374,7 @@ MUST be treated as a stream error of type HTTP_WRONG_STREAM_DIRECTION. 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Stream Type (i) ... +| 0x01 (i) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Push ID (i) ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ From 0c33013556840e9f16f3e701cbb372f68b0ab124 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 8 Feb 2019 14:41:39 -0800 Subject: [PATCH 050/190] Review feedback --- draft-ietf-quic-http.md | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 1b7ee2830d..f156dcd91c 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -389,10 +389,9 @@ client MUST treat this as a connection error of type HTTP_DUPLICATE_PUSH. Stream types of the format `0x1f * N` for non-zero values of N are reserved to exercise the requirement that unknown types be ignored. These streams have no -semantic meaning, and can be sent when application-layer padding is desired. -They MAY also be sent on connections where no request data is currently being -transferred. Endpoints MUST NOT consider these streams to have any meaning upon -receipt. +semantics, and can be sent when application-layer padding is desired. They MAY +also be sent on connections where no data is currently being transferred. +Endpoints MUST NOT consider these streams to have any meaning upon receipt. The payload and length of the stream are selected in any manner the implementation chooses. @@ -439,7 +438,7 @@ All frames have the following format: A frame includes the following fields: Type: - : A variable-length type for the frame. + : A variable-length integer that identifies the frame type. Length: : A variable-length integer that describes the length of the Frame Payload. @@ -674,9 +673,9 @@ Parameters MUST NOT occur more than once in the SETTINGS frame. A receiver MAY treat the presence of the same parameter more than once as a connection error of type HTTP_MALFORMED_FRAME. -The payload of a SETTINGS frame consists of zero or more parameters, each -consisting of a setting identifier and a value, each of which uses the -QUIC variable-length integer encoding. +The payload of a SETTINGS frame consists of zero or more parameters. Each +parameter consists of a setting identifier and a value, both encoded as a QUIC +variable-length integer. ~~~~~~~~~~~~~~~ drawing 0 1 2 3 @@ -889,10 +888,10 @@ the DUPLICATE_PUSH. Frame types of the format `0x1f * N` for non-zero values of N are reserved to exercise the requirement that unknown types be ignored ({{extensions}}). These -frames have no semantic value, and can be sent when application-layer padding is -desired. They MAY also be sent on connections where no request data is currently -being transferred. Endpoints MUST NOT consider these frames to have any meaning -upon receipt. +frames have no semantics, and can be sent when application-layer padding is +desired. They MAY also be sent on connections where no data is currently being +transferred. Endpoints MUST NOT consider these frames to have any meaning upon +receipt. The payload and length of the frames are selected in any manner the implementation chooses. From 05b784f6985de0597a30faa611b6317d2bd56051 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 8 Feb 2019 14:45:48 -0800 Subject: [PATCH 051/190] Plurals --- draft-ietf-quic-http.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index f156dcd91c..2cca7b67ca 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -674,8 +674,8 @@ treat the presence of the same parameter more than once as a connection error of type HTTP_MALFORMED_FRAME. The payload of a SETTINGS frame consists of zero or more parameters. Each -parameter consists of a setting identifier and a value, both encoded as a QUIC -variable-length integer. +parameter consists of a setting identifier and a value, both encoded as QUIC +variable-length integers. ~~~~~~~~~~~~~~~ drawing 0 1 2 3 From c30019f681d092f3a04dee62bfed3bf868f610d2 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 8 Feb 2019 15:15:05 -0800 Subject: [PATCH 052/190] More plurals --- draft-ietf-quic-http.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 2cca7b67ca..308a4eea3a 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1818,7 +1818,7 @@ Frame types defined by extensions to HTTP/2 need to be separately registered for HTTP/3 if still applicable. The IDs of frames defined in {{!RFC7540}} have been reserved for simplicity. Note that the frame type space in HTTP/3 is substantially larger (62 bits versus 8 bits), so many HTTP/3 frame types have no -equivalent HTTP/2 code point. See {{iana-frames}}. +equivalent HTTP/2 code points. See {{iana-frames}}. ## HTTP/2 SETTINGS Parameters {#h2-settings} From 5b3abdedf454cccec4e2e0bbb1b5dcc3de261b46 Mon Sep 17 00:00:00 2001 From: MikkelFJ Date: Fri, 8 Feb 2019 15:55:35 -0800 Subject: [PATCH 053/190] Update draft-ietf-quic-transport.md Co-Authored-By: MikeBishop --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 883f79adaf..5c90b19ced 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1013,7 +1013,7 @@ to more quickly identify when a connection becomes unusable. Packets that are matched to an existing connection are discarded if the packets are inconsistent with the state of that connection -- for example, if they indicate a different protocol version than that of the connection, or if the -removal of packet protection is unsuccessful. +removal of packet protection is unsuccessful once the expected keys are available. Invalid packets without packet protection, such as Initial, Retry, or Version Negotiation, MAY be discarded. An endpoint MUST generate a connection error if From 5369ff2cf70a461899817aec983ac22e23684f15 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 8 Feb 2019 15:56:59 -0800 Subject: [PATCH 054/190] Sentence split --- draft-ietf-quic-transport.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 5c90b19ced..2a3a048882 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1011,9 +1011,10 @@ cannot be attributed to an existing connection. A stateless reset allows a peer to more quickly identify when a connection becomes unusable. Packets that are matched to an existing connection are discarded if the packets -are inconsistent with the state of that connection -- for example, if they -indicate a different protocol version than that of the connection, or if the -removal of packet protection is unsuccessful once the expected keys are available. +are inconsistent with the state of that connection. For example, packets are +discarded if they indicate a different protocol version than that of the +connection, or if the removal of packet protection is unsuccessful once the +expected keys are available. Invalid packets without packet protection, such as Initial, Retry, or Version Negotiation, MAY be discarded. An endpoint MUST generate a connection error if From 2631d02ffce77d14073ed4a80a7fd656ff8443d1 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 8 Feb 2019 16:01:02 -0800 Subject: [PATCH 055/190] Servers can still CANCEL, too. (#2426) * Servers can still CANCEL, too. * Apply suggestions from code review Co-Authored-By: MikeBishop --- draft-ietf-quic-http.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 20c475bcd6..77beec90a0 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1004,11 +1004,15 @@ some higher layer of software that might have taken some action as a result. The client can treat requests rejected by the server as though they had never been sent at all, thereby allowing them to be retried later on a new connection. Servers MUST NOT use the HTTP_REQUEST_REJECTED error code for requests which -were partially or fully processed. When a client sends a STOP_SENDING with -HTTP_REQUEST_CANCELLED, a server MAY indicate the error code -HTTP_REQUEST_REJECTED in the corresponding RESET_STREAM if no processing was -performed. Clients MUST NOT reset streams with the HTTP_REQUEST_REJECTED error -code except in response to a QUIC STOP_SENDING frame. +were partially or fully processed. When a server abandons a response after +partial processing, it SHOULD abort its response stream with the error code +HTTP_REQUEST_CANCELLED. + +When a client sends a STOP_SENDING with HTTP_REQUEST_CANCELLED, a server MAY +send the error code HTTP_REQUEST_REJECTED in the corresponding RESET_STREAM +if no processing was performed. Clients MUST NOT reset streams with the +HTTP_REQUEST_REJECTED error code except in response to a QUIC STOP_SENDING +frame that contains the same code. If a stream is cancelled after receiving a complete response, the client MAY ignore the cancellation and use the response. However, if a stream is cancelled @@ -1382,7 +1386,7 @@ HTTP_PUSH_ALREADY_IN_CACHE (0x04): : The server has attempted to push content which the client has cached. HTTP_REQUEST_CANCELLED (0x05): -: The client no longer needs the requested data. +: The request or its response is cancelled. HTTP_INCOMPLETE_REQUEST (0x06): : The client's stream terminated without containing a fully-formed request. From 633eca90a501c5a9179fc4703158a6aacf084c5f Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 8 Feb 2019 16:06:50 -0800 Subject: [PATCH 056/190] Migration in Security Considerations (#2427) * Migration in Security Considerations * Better incorporate Martin's feedback --- draft-ietf-quic-http.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 77beec90a0..220b769bb5 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1467,6 +1467,13 @@ could pose a security risk to an incautious implementer. An implementation MUST ensure that the length of a frame exactly matches the length of the fields it contains. +Certain HTTP implementations use the client address for logging or +access-control purposes. Since a QUIC client's address might change during a +connection (and future versions might support simultaneous use of multiple +addresses), such implementations will need to either actively retrieve the +client's current address or addresses when they are relevant or explicitly +accept that the original address might change. + # IANA Considerations From 55e4a7d55a9cb24cf650c3a4c97f0447dd06a5b7 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Fri, 8 Feb 2019 16:07:15 -0800 Subject: [PATCH 057/190] Indicate initial-only frames (#2425) * Indicate initial-only frames * Specific guidance --- draft-ietf-quic-http.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 220b769bb5..741535ca19 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -406,15 +406,19 @@ comparison between HTTP/2 and HTTP/3 frames is provided in {{h2-frames}}. | -------------- | -------------- | -------------- | ----------- | ------------------------ | | DATA | No | Yes | Yes | {{frame-data}} | | HEADERS | No | Yes | Yes | {{frame-headers}} | -| PRIORITY | Yes | Yes | No | {{frame-priority}} | +| PRIORITY | Yes | Yes (1) | No | {{frame-priority}} | | CANCEL_PUSH | Yes | No | No | {{frame-cancel-push}} | -| SETTINGS | Yes | No | No | {{frame-settings}} | +| SETTINGS | Yes (1) | No | No | {{frame-settings}} | | PUSH_PROMISE | No | Yes | No | {{frame-push-promise}} | | GOAWAY | Yes | No | No | {{frame-goaway}} | | MAX_PUSH_ID | Yes | No | No | {{frame-max-push-id}} | | DUPLICATE_PUSH | No | Yes | No | {{frame-duplicate-push}} | {: #stream-frame-mapping title="HTTP/3 frames and stream type overview"} +Certain frames can only occur as the first frame of a particular stream type; +these are indicated in {{stream-frame-mapping}} with a (1). Specific guidance +is provided in the relevant section. + ## Frame Layout All frames have the following format: From 4bf24681eee5235af5311fc939126195b16f6e40 Mon Sep 17 00:00:00 2001 From: martinduke Date: Fri, 8 Feb 2019 17:50:02 -0800 Subject: [PATCH 058/190] quic-tls nits I suspect these are uncontroversial. --- draft-ietf-quic-tls.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 936d1bc00d..9a7c3cc049 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -745,7 +745,7 @@ The keys used for packet protection are computed from the TLS secrets using the KDF provided by TLS. In TLS 1.3, the HKDF-Expand-Label function described in Section 7.1 of {{!TLS13}} is used, using the hash function from the negotiated cipher suite. Other versions of TLS MUST provide a similar function in order to -be used QUIC. +be used with QUIC. The current encryption level secret and the label "quic key" are input to the KDF to produce the AEAD key; the label "quic iv" is used to derive the IV, see @@ -788,7 +788,7 @@ The value of initial_salt is a 20 byte sequence shown in the figure in hexadecimal notation. Future versions of QUIC SHOULD generate a new salt value, thus ensuring that the keys are different for each version of QUIC. This prevents a middlebox that only recognizes one version of QUIC from seeing or -modifying the contents of handshake packets from future versions. +modifying the contents of Initial packets from future versions. The HKDF-Expand-Label function defined in TLS 1.3 MUST be used for Initial packets even where the TLS versions offered do not include TLS 1.3. @@ -1242,8 +1242,8 @@ protection for these values. The `extension_data` field of the quic_transport_parameters extension contains a value that is defined by the version of QUIC that is in use. The -quic_transport_parameters extension carries a TransportParameters when the -version of QUIC defined in {{QUIC-TRANSPORT}} is used. +quic_transport_parameters extension carries a TransportParameters struct when +the version of QUIC defined in {{QUIC-TRANSPORT}} is used. The quic_transport_parameters extension is carried in the ClientHello and the EncryptedExtensions messages during the handshake. From 325d2cbdab441cfb15c570aa084472dac88c09f1 Mon Sep 17 00:00:00 2001 From: martinduke Date: Fri, 8 Feb 2019 18:02:24 -0800 Subject: [PATCH 059/190] One more --- draft-ietf-quic-tls.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 9a7c3cc049..ad4f9b567d 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -14,7 +14,7 @@ pi: [toc, sortrefs, symrefs, docmapping] author: - ins: M. Thomson - name: Martin Thomson + name: Martin Thomsonf org: Mozilla email: mt@lowentropy.net role: editor @@ -216,7 +216,7 @@ Note that this omits the EndOfEarlyData message, which is not used in QUIC (see Data is protected using a number of encryption levels: -- Plaintext +- Initial Keys - Early Data (0-RTT) Keys - Handshake Keys - Application Data (1-RTT) Keys From 5bb4241cf1d9f48798abd48450087e2188ae372b Mon Sep 17 00:00:00 2001 From: martinduke Date: Fri, 8 Feb 2019 18:02:52 -0800 Subject: [PATCH 060/190] argh stray character --- draft-ietf-quic-tls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index ad4f9b567d..e7ff01a4af 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -14,7 +14,7 @@ pi: [toc, sortrefs, symrefs, docmapping] author: - ins: M. Thomson - name: Martin Thomsonf + name: Martin Thomson org: Mozilla email: mt@lowentropy.net role: editor From 5329e0ef079ef30e81e99eec1f9a4d9d9ba60179 Mon Sep 17 00:00:00 2001 From: martinduke Date: Fri, 8 Feb 2019 18:10:55 -0800 Subject: [PATCH 061/190] Minor TLS draft editorial corrections I am not quite as sure of these, but I believe they match the intent better. --- draft-ietf-quic-tls.md | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 936d1bc00d..3d1125e662 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -216,10 +216,12 @@ Note that this omits the EndOfEarlyData message, which is not used in QUIC (see Data is protected using a number of encryption levels: -- Plaintext -- Early Data (0-RTT) Keys -- Handshake Keys -- Application Data (1-RTT) Keys +- Initial Keys can be derived by any observer, and so they do not + provide cryptographic protection or authentication. +- Early Data (0-RTT) Keys. These keys are not forward-secure and must protect + only idempotent data. +- Handshake Keys do not authenticate either endpoint. +- Application Data (1-RTT) Keys provide full authentication and encryption. Application data may appear only in the early data and application data levels. Handshake and Alert messages may appear in any level. @@ -269,7 +271,7 @@ At a high level, there are two main interactions between the TLS and QUIC components: * The TLS component sends and receives messages via the QUIC component, with - QUIC providing a reliable stream abstraction to TLS. + QUIC providing a reliable stream and record abstraction to TLS. * The TLS component provides a series of updates to the QUIC component, including (a) new packet protection keys to install (b) state changes such as @@ -344,13 +346,14 @@ indicate which level a given packet was encrypted under, as shown in need to be sent, endpoints SHOULD use coalesced packets to send them in the same UDP datagram. -| Packet Type | Encryption Level | PN Space | -|:----------------|:-----------------|:----------| -| Initial | Initial secrets | Initial | -| 0-RTT Protected | 0-RTT | 0/1-RTT | -| Handshake | Handshake | Handshake | -| Retry | N/A | N/A | -| Short Header | 1-RTT | 0/1-RTT | +| Packet Type | Encryption Level | PN Space | +|:--------------------|:-----------------|:----------| +| Initial | Initial secrets | Initial | +| 0-RTT Protected | 0-RTT | 0/1-RTT | +| Handshake | Handshake | Handshake | +| Retry | N/A | N/A | +| Version Negotiation | N/A | N/A | +| Short Header | 1-RTT | 0/1-RTT | {: #packet-types-levels title="Encryption Levels by Packet Type"} Section 17 of {{QUIC-TRANSPORT}} shows how packets at the various encryption @@ -505,26 +508,24 @@ Rekey tx to 0-RTT Keys Get Handshake <------------- Initial Rekey rx to 0-RTT keys - Handshake Received - Rekey rx to Handshake keys + Rekey tx to Handshake keys Get Handshake <----------- Handshake + Rekey rx to Handshake keys Rekey tx to 1-RTT keys <--------------- 1-RTT Handshake Received -Rekey rx to Handshake keys +Rekey tx and rx to Handshake keys Handshake Received Get Handshake Handshake Complete Handshake -----------> -Rekey tx to 1-RTT keys +Rekey tx and rx to 1-RTT keys 1-RTT ---------------> Handshake Received Rekey rx to 1-RTT keys - Get Handshake Handshake Complete <--------------- 1-RTT -Handshake Received ~~~ {: #exchange-summary title="Interaction Summary between QUIC and TLS"} From 99e52fd4ebec4af1927828416189d52d7a91cc60 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 11 Feb 2019 09:17:24 +1100 Subject: [PATCH 062/190] Ted's comments --- draft-ietf-quic-transport.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 778d253c6c..e7ba232c29 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -968,8 +968,9 @@ or the total number of connection IDs issued for each connection to avoid the risk of running out of connection IDs (see {{reset-token}}). Endpoints that initiate migration and require non-zero-length connection IDs -SHOULD provide their peers with new connection IDs before migration, or risk the -peer closing the connection. +SHOULD ensure that the pool of connection IDs available to their peers allows +them to use a new connection ID on migration, as the peer will close the +connection if the pool is exhausted. ### Consuming and Retiring Connection IDs {#retiring-cids} From ac7f3818c75c1abac0c5f0068532cfd5dc636b3a Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 11 Feb 2019 10:41:09 +1100 Subject: [PATCH 063/190] Remove text, thanks Ian --- draft-ietf-quic-transport.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 9477f81439..b2d6b0e871 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2093,12 +2093,11 @@ linked by any other entity. Endpoints MAY move to a new connection ID at any time. -An endpoint MUST use a new connection ID if it initiates connection migration, -unless the peer has selected a zero-length connection ID. Using a new -connection ID eliminates the use of the connection ID for linking activity from -the same connection on different networks. Header protection ensures that -packet numbers cannot be used to correlate activity. This does not prevent -other properties of packets, such as timing and size, from being used to +An endpoint MUST use a new connection ID if it initiates connection migration. +Using a new connection ID eliminates the use of the connection ID for linking +activity from the same connection on different networks. Header protection +ensures that packet numbers cannot be used to correlate activity. This does not +prevent other properties of packets, such as timing and size, from being used to correlate activity. Unintentional changes in path without a change in connection ID are possible. @@ -2114,11 +2113,9 @@ genuine migrations. Changing port number can cause a peer to reset its congestion state (see {{migration-cc}}), so the port SHOULD only be changed infrequently. -An endpoint MUST NOT intentionally migrate to a new path if it does not have a -connection ID to use on that path. An endpoint that exhausts available -connection IDs cannot migrate. To ensure that migration is possible and packets -sent on different paths cannot be correlated, endpoints SHOULD provide new -connection IDs before peers migrate. +An endpoint that exhausts available connection IDs cannot migrate. To ensure +that migration is possible and packets sent on different paths cannot be +correlated, endpoints SHOULD provide new connection IDs before peers migrate. ## Server's Preferred Address {#preferred-address} From 932fdc4f5f0eba1438950ce5bfac10d9a6acb6b1 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 11 Feb 2019 10:57:20 +1100 Subject: [PATCH 064/190] Work on key diversity --- draft-ietf-quic-tls.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 936d1bc00d..caff149b1e 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1368,21 +1368,20 @@ In using TLS, the central key schedule of TLS is used. As a result of the TLS handshake messages being integrated into the calculation of secrets, the inclusion of the QUIC transport parameters extension ensures that handshake and 1-RTT keys are not the same as those that might be produced by a server running -TLS over TCP. However, 0-RTT keys only include the ClientHello message and -might therefore use the same secrets. To avoid the possibility of -cross-protocol key synchronization, additional measures are provided to improve -key separation. +TLS over TCP. To avoid the possibility of cross-protocol key synchronization, +additional measures are provided to improve key separation. The QUIC packet protection keys and IVs are derived using a different label than the equivalent keys in TLS. To preserve this separation, a new version of QUIC SHOULD define new labels for -key derivation for packet protection key and IV, plus the header -protection keys. +key derivation for packet protection key and IV, plus the header protection +keys. This version of QUIC uses the string "quic". Other versions can use a +version-specific label in place of that string. -The initial secrets also use a key that is specific to the negotiated QUIC -version. New QUIC versions SHOULD define a new salt value used in calculating -initial secrets. +The initial secrets use a key that is specific to the negotiated QUIC version. +New QUIC versions SHOULD define a new salt value used in calculating initial +secrets. # IANA Considerations From be67b4561b491c06a79c1688c8c35a9fffa7d2d9 Mon Sep 17 00:00:00 2001 From: Mark Nottingham Date: Mon, 11 Feb 2019 11:48:17 +1100 Subject: [PATCH 065/190] discussing --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f4e9546c9c..389c6403ad 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,7 +67,7 @@ Issues will be labeled by the Chairs as either `editorial` or `design`: * **Editorial** issues can be dealt with by the editor(s) without consensus or notification. Typically, any discussion will take place on the issue itself. -The `open` design issues in the issues list are those that we are currently or plan to discuss. When a design issue is `closed`, it implies that the issue has a proposed resolution that is reflected in the drafts; if a `closed` design issue is labeled with `has-consensus`, it means that the incorporated resolution has Working Group consensus. +The `open` design issues in the issues list are those that we are currently discussing, or plan to discuss. When a design issue is `closed`, it implies that the issue has a proposed resolution that is reflected in the drafts; if a `closed` design issue is labeled with `has-consensus`, it means that the incorporated resolution has Working Group consensus. Design issues can be discussed on the mailing list or the issues list. The editors can also propose resolutions to design issues for the group's consideration by incorporating them into the draft(s). From 9f6e285ad51c3439d5abd0ba24ad4ecd081c7a25 Mon Sep 17 00:00:00 2001 From: Mark Nottingham Date: Mon, 11 Feb 2019 12:05:04 +1100 Subject: [PATCH 066/190] Describe the two processes. --- CONTRIBUTING.md | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 389c6403ad..a8bb3ea5fe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,13 +67,46 @@ Issues will be labeled by the Chairs as either `editorial` or `design`: * **Editorial** issues can be dealt with by the editor(s) without consensus or notification. Typically, any discussion will take place on the issue itself. -The `open` design issues in the issues list are those that we are currently discussing, or plan to discuss. When a design issue is `closed`, it implies that the issue has a proposed resolution that is reflected in the drafts; if a `closed` design issue is labeled with `has-consensus`, it means that the incorporated resolution has Working Group consensus. +The open design issues in the issues list are those that we are currently discussing, or plan to discuss. They can be discussed on the mailing list or the issues list. -Design issues can be discussed on the mailing list or the issues list. The editors can also propose resolutions to design issues for the group's consideration by incorporating them into the draft(s). +We're currently using two different processes for issue resolution, depending on draft maturity. + +Note that in both processes, we use the `has-consensus` flag to denote an issue that we have consensus upon. Whether or not a design issue is closed does **not** reflect consensus of the Working Group; an issue's `open`/`closed` state is only used to organise our discussions. + +If you have a question or problem with an issue in the `closed` state, please comment on it (either in the issues list or mailing list), and we'll adjust its state accordingly. Note that reopening issues with `has-consensus` requires new information. + + +### Early-Stage Process + +The early-stage process gives more powers to the editors to incorporate what they believe to be the Working Group's position into the drafts; the focus of these drafts is on flexibility, so that changes don't have an inordinate amount of overhead. + +In this process, the editors can propose resolutions to design issues for the group's consideration by incorporating them into the draft(s), closing the issue. When a new draft is published, the design issues that have been closed since the last draft will be highlighted on the mailing list, to aid reviewers. Once consensus is confirmed, those issues will be labeled with [`has-consensus`](https://github.com/quicwg/base-drafts/issues?utf8=✓&q=label%3Ahas-consensus%20). -Note that whether or not a design issue is closed does **not** reflect consensus of the Working Group; an issue's `open`/`closed` state is only used to organise our discussions. If you have a question or problem with an issue in the `closed` state, please comment on it (either in the issues list or mailing list), and we'll adjust its state accordingly. Note that reopening issues with `has-consensus` requires new information. +When a design issue is `closed`, it implies that the issue has a proposed resolution that is reflected in the drafts; if a `closed` design issue is labeled with `has-consensus`, it means that the incorporated resolution has Working Group consensus. + +The drafts currently in the early stage are: + +* HTTP/3 +* QPACK +* Recovery + + +### Late-Stage Process + +The late-stage process attempts to reflect the Working Group's current consensus in the drafts; the latest draft reflects that consensus, modulo any open (or undiscovered) issues. The goal for a late-stage draft is to reduce unnecessary design changes in the protocol, thereby aiding reviewers and assuring that the drafts accurately reflect consensus. + +In this process, the Working Group will discuss each design issue, and the Chairs will judge consensus, labelling the issue as `has-consensus` (ideally based upon a Pull Request that specifies the exact changes to be made). + +Only after that will the change be merged and the issue be closed. + +The drafts currently in the late stage are: + +* Invariants +* Transporrt +* TLS + ### Discretionary Design Issue Labels From 755559b0e6d3653a6d4e8aaaa841efd795d8df23 Mon Sep 17 00:00:00 2001 From: martinduke Date: Sun, 10 Feb 2019 20:27:26 -0800 Subject: [PATCH 067/190] Update to reflect reviews Still some points of contention --- draft-ietf-quic-tls.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 3d1125e662..01f8144cd3 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -216,12 +216,10 @@ Note that this omits the EndOfEarlyData message, which is not used in QUIC (see Data is protected using a number of encryption levels: -- Initial Keys can be derived by any observer, and so they do not - provide cryptographic protection or authentication. -- Early Data (0-RTT) Keys. These keys are not forward-secure and must protect - only idempotent data. -- Handshake Keys do not authenticate either endpoint. -- Application Data (1-RTT) Keys provide full authentication and encryption. +- Initial Keys +- Early Data (0-RTT) Keys +- Handshake Keys +- Application Data (1-RTT) Keys Application data may appear only in the early data and application data levels. Handshake and Alert messages may appear in any level. @@ -525,7 +523,9 @@ Rekey tx and rx to 1-RTT keys Handshake Received Rekey rx to 1-RTT keys Handshake Complete + Get Handshake <--------------- 1-RTT +Handshake Received ~~~ {: #exchange-summary title="Interaction Summary between QUIC and TLS"} From 4d2821c5e79c741355ae8a69df024718e07835c9 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Sun, 10 Feb 2019 20:28:53 -0800 Subject: [PATCH 068/190] Update draft-ietf-quic-tls.md This is a better fix. Co-Authored-By: martinduke --- draft-ietf-quic-tls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index e7ff01a4af..3b101009b8 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -788,7 +788,7 @@ The value of initial_salt is a 20 byte sequence shown in the figure in hexadecimal notation. Future versions of QUIC SHOULD generate a new salt value, thus ensuring that the keys are different for each version of QUIC. This prevents a middlebox that only recognizes one version of QUIC from seeing or -modifying the contents of Initial packets from future versions. +modifying the contents of packets from future versions. The HKDF-Expand-Label function defined in TLS 1.3 MUST be used for Initial packets even where the TLS versions offered do not include TLS 1.3. From 88424b7b9d98937f2a17cdbb9556f292bacb5efd Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 11 Feb 2019 15:05:34 +0800 Subject: [PATCH 069/190] remove unused variable largest_sent_packet --- draft-ietf-quic-recovery.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 1e25cc3b3f..32cc271be3 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -850,9 +850,6 @@ time_of_last_sent_ack_eliciting_packet: time_of_last_sent_crypto_packet: : The time the most recent crypto packet was sent. -largest_sent_packet[kPacketNumberSpace]: -: The packet number of the most recently sent packet in the packet number space. - largest_acked_packet[kPacketNumberSpace]: : The largest packet number acknowledged in the packet number space so far. @@ -902,7 +899,6 @@ follows: time_of_last_sent_ack_eliciting_packet = 0 time_of_last_sent_crypto_packet = 0 for pn_space in [ Initial, Handshake, ApplicatonData ]: - largest_sent_packet[pn_space] = 0 largest_acked_packet[pn_space] = 0 ~~~ @@ -917,7 +913,6 @@ Pseudocode for OnPacketSent follows: ~~~ OnPacketSent(packet_number, pn_space, ack_eliciting, in_flight, is_crypto_packet, sent_bytes): - largest_sent_packet[pn_space] = packet_number sent_packets[pn_space][packet_number].packet_number = packet_number sent_packets[pn_space][packet_number].time_sent = now From 1f2a08e8156b845d5820af48ace8270dd735e86a Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 11 Feb 2019 19:10:56 +1100 Subject: [PATCH 070/190] Connection IDs for 0-RTT packets For #2398. --- draft-ietf-quic-transport.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 2a3a048882..342c6f9525 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1355,6 +1355,9 @@ long enough to fulfill the minimum size for every QUIC version it supports. The client populates the Source Connection ID field with a value of its choosing and sets the SCIL field to match. +The same Destination and Source Connection ID values are used for any 0-RTT +packets the client sends. + The Destination Connection ID field in the server's Initial packet contains a connection ID that is chosen by the recipient of the packet (i.e., the client); the Source Connection ID includes the connection ID that the sender of the @@ -1363,11 +1366,12 @@ 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. That means that a client might change the Destination -Connection ID twice during connection establishment, once in response to a -Retry and once in response to the first Initial packet from the server. Once a -client has received an Initial packet from the server, it MUST discard any -packet it receives with a different Source Connection ID. +for subsequent packets, including any subsequent 0-RTT packets. That means that +a client might change the Destination Connection ID twice during connection +establishment, once in response to a Retry and once in response to the first +Initial packet from the server. Once a client has received an Initial packet +from the server, it MUST discard any packet it receives with a different Source +Connection ID. A client MUST only change the value it sends in the Destination Connection ID in response to the first packet of each type it receives from the server (Retry or From ec2418410ceb50526dad6b8fe94f751378ff83fd Mon Sep 17 00:00:00 2001 From: ianswett Date: Mon, 11 Feb 2019 10:31:04 -0500 Subject: [PATCH 071/190] Add a loss_time per packet number space Fixes #2435 I failed to fully think this through when #2417 landed, but the intent was always that time threshold loss detection apply to Initial and Handshake packet number spaces, as well as ApplicationData. --- draft-ietf-quic-recovery.md | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 32cc271be3..ff48132cfb 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -873,10 +873,9 @@ max_ack_delay: received ACK frame may be larger due to late timers, reordering, or lost ACKs. -loss_time: -: The time at which the next packet will be considered lost based on - exceeding the reordering window in time. Only applies to the ApplicationData - packet number space. +loss_times[kPacketNumberSpace]: +: The time at which the next packet in that packet number space will be + considered lost based on exceeding the reordering window in time. sent_packets[kPacketNumberSpace]: : An association of packet numbers in a packet number space to information @@ -892,7 +891,6 @@ follows: loss_detection_timer.reset() crypto_count = 0 pto_count = 0 - loss_time = 0 smoothed_rtt = 0 rttvar = 0 min_rtt = infinite @@ -900,6 +898,7 @@ follows: time_of_last_sent_crypto_packet = 0 for pn_space in [ Initial, Handshake, ApplicatonData ]: largest_acked_packet[pn_space] = 0 + loss_times[pn_space] = 0 ~~~ @@ -1029,6 +1028,12 @@ SetLossDetectionTimer(): loss_detection_timer.cancel() return + for (loss_time : loss_times) { + if (loss_time != 0): + // Time threshold loss detection. + loss_detection_timer.update(loss_time) + return + if (crypto packets are in flight): // Crypto retransmission timer. if (smoothed_rtt == 0): @@ -1041,12 +1046,6 @@ SetLossDetectionTimer(): time_of_last_sent_crypto_packet + timeout) return - if (loss_time != 0): - // Time threshold loss detection. - // Only applies to the ApplicationData packet number space. - loss_detection_timer.update(loss_time) - return - // Calculate PTO duration timeout = smoothed_rtt + 4 * rttvar + max_ack_delay @@ -1095,8 +1094,7 @@ Pseudocode for DetectLostPackets follows: ~~~ DetectLostPackets(pn_space): - if (pn_space == ApplicationData): - loss_time = 0 + loss_times[pn_space] = 0 lost_packets = {} loss_delay = kTimeThreshold * max(latest_rtt, smoothed_rtt) @@ -1117,11 +1115,11 @@ DetectLostPackets(pn_space): if (unacked.in_flight): lost_packets.insert(unacked) else if (pn_space == ApplicationData): - if (loss_time == 0): - loss_time = unacked.time_sent + loss_delay + if (loss_times[pn_space] == 0): + loss_time[pn_space] = unacked.time_sent + loss_delay else: - loss_time = min(loss_time, unacked.time_sent + - loss_delay) + loss_time[pn_space] = min(loss_time[pn_space], + unacked.time_sent + loss_delay) // Inform the congestion controller of lost packets and // let it decide whether to retransmit immediately. From cee749c18d519bf4e26e281e212749b12fa9aee0 Mon Sep 17 00:00:00 2001 From: ianswett Date: Mon, 11 Feb 2019 10:45:48 -0500 Subject: [PATCH 072/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index ff48132cfb..848e42ca31 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1066,14 +1066,18 @@ Pseudocode for OnLossDetectionTimeout follows: ~~~ OnLossDetectionTimeout(): - if (crypto packets are in flight): + packets_lost = false + for pn_space in [ Initial, Handshake, ApplicatonData ]: + if (loss_times[pn_space] != 0): + // Time threshold loss Detection + DetectLostPackets(pn_space) + packets_lost = true + // Don't retransmit all crypto data if a packet was just lost. + if (!packets_lost && + crypto packets are in flight): // Crypto retransmission timeout. RetransmitUnackedCryptoData() crypto_count++ - else if (loss_time != 0): - // Time threshold loss Detection - // Only applies to the ApplicationData packet number space. - DetectLostPackets(ApplicationData) else: // PTO SendOneOrTwoPackets() From 5339f9a8b38958be9091ce2dd82a0639236a5428 Mon Sep 17 00:00:00 2001 From: ianswett Date: Mon, 11 Feb 2019 11:20:00 -0500 Subject: [PATCH 073/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 42 ++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 848e42ca31..238884d842 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -873,7 +873,7 @@ max_ack_delay: received ACK frame may be larger due to late timers, reordering, or lost ACKs. -loss_times[kPacketNumberSpace]: +loss_time[kPacketNumberSpace]: : The time at which the next packet in that packet number space will be considered lost based on exceeding the reordering window in time. @@ -898,7 +898,7 @@ follows: time_of_last_sent_crypto_packet = 0 for pn_space in [ Initial, Handshake, ApplicatonData ]: largest_acked_packet[pn_space] = 0 - loss_times[pn_space] = 0 + loss_time[pn_space] = 0 ~~~ @@ -1021,6 +1021,18 @@ timers wake up late. Timers set in the past SHOULD fire immediately. Pseudocode for SetLossDetectionTimer follows: ~~~ +// Returns the earliest loss_time and the packet number +// space it's from. Returns 0 if all times are 0. +GetEarliestLossTimer(): + time = loss_time[Initial] + space = Initial + for pn_space in [ Handshake, ApplicatonData ]: + if loss_time[pn_space] != 0 && + (time == 0 || loss_time[pn_space] < time): + time = loss_time[pn_space]; + space = Initial + return [time, space] + SetLossDetectionTimer(): // Don't arm timer if there are no ack-eliciting packets // in flight. @@ -1028,11 +1040,11 @@ SetLossDetectionTimer(): loss_detection_timer.cancel() return - for (loss_time : loss_times) { - if (loss_time != 0): - // Time threshold loss detection. - loss_detection_timer.update(loss_time) - return + [loss_time, pn_space] = GetEarliestLossTimer() + if (loss_time != 0): + // Time threshold loss detection. + loss_detection_timer.update(loss_time) + return if (crypto packets are in flight): // Crypto retransmission timer. @@ -1066,12 +1078,12 @@ Pseudocode for OnLossDetectionTimeout follows: ~~~ OnLossDetectionTimeout(): - packets_lost = false - for pn_space in [ Initial, Handshake, ApplicatonData ]: - if (loss_times[pn_space] != 0): - // Time threshold loss Detection - DetectLostPackets(pn_space) - packets_lost = true + [loss_time, pn_space] = GetEarliestLossTimer() + if (loss_time != 0): + // Time threshold loss Detection + DetectLostPackets(pn_space) + SetLossDetectionTimer() + return // Don't retransmit all crypto data if a packet was just lost. if (!packets_lost && crypto packets are in flight): @@ -1098,7 +1110,7 @@ Pseudocode for DetectLostPackets follows: ~~~ DetectLostPackets(pn_space): - loss_times[pn_space] = 0 + loss_time[pn_space] = 0 lost_packets = {} loss_delay = kTimeThreshold * max(latest_rtt, smoothed_rtt) @@ -1119,7 +1131,7 @@ DetectLostPackets(pn_space): if (unacked.in_flight): lost_packets.insert(unacked) else if (pn_space == ApplicationData): - if (loss_times[pn_space] == 0): + if (loss_time[pn_space] == 0): loss_time[pn_space] = unacked.time_sent + loss_delay else: loss_time[pn_space] = min(loss_time[pn_space], From f6e85a0fa4ca87228970e2af0bd2e81ca1697453 Mon Sep 17 00:00:00 2001 From: ianswett Date: Mon, 11 Feb 2019 11:20:25 -0500 Subject: [PATCH 074/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 238884d842..386c890b5d 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1023,7 +1023,7 @@ Pseudocode for SetLossDetectionTimer follows: ~~~ // Returns the earliest loss_time and the packet number // space it's from. Returns 0 if all times are 0. -GetEarliestLossTimer(): +GetEarliestLossTime(): time = loss_time[Initial] space = Initial for pn_space in [ Handshake, ApplicatonData ]: From da874788e729470f9587ad2194c334f5e71f528c Mon Sep 17 00:00:00 2001 From: ianswett Date: Mon, 11 Feb 2019 11:25:00 -0500 Subject: [PATCH 075/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 386c890b5d..6e3df1782d 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1040,7 +1040,7 @@ SetLossDetectionTimer(): loss_detection_timer.cancel() return - [loss_time, pn_space] = GetEarliestLossTimer() + [loss_time, pn_space] = GetEarliestLossTime() if (loss_time != 0): // Time threshold loss detection. loss_detection_timer.update(loss_time) @@ -1078,7 +1078,7 @@ Pseudocode for OnLossDetectionTimeout follows: ~~~ OnLossDetectionTimeout(): - [loss_time, pn_space] = GetEarliestLossTimer() + [loss_time, pn_space] = GetEarliestLossTime() if (loss_time != 0): // Time threshold loss Detection DetectLostPackets(pn_space) @@ -1130,7 +1130,7 @@ DetectLostPackets(pn_space): sent_packets.remove(unacked.packet_number) if (unacked.in_flight): lost_packets.insert(unacked) - else if (pn_space == ApplicationData): + else: if (loss_time[pn_space] == 0): loss_time[pn_space] = unacked.time_sent + loss_delay else: From d183dbcf3fec1a338259abe3fc657645b2b6fbaa Mon Sep 17 00:00:00 2001 From: ianswett Date: Mon, 11 Feb 2019 11:26:55 -0500 Subject: [PATCH 076/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 6e3df1782d..6e573be7cb 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1082,11 +1082,8 @@ OnLossDetectionTimeout(): if (loss_time != 0): // Time threshold loss Detection DetectLostPackets(pn_space) - SetLossDetectionTimer() - return // Don't retransmit all crypto data if a packet was just lost. - if (!packets_lost && - crypto packets are in flight): + else if (crypto packets are in flight): // Crypto retransmission timeout. RetransmitUnackedCryptoData() crypto_count++ From f489b47eac3826113e13d20986d521f003a7ed27 Mon Sep 17 00:00:00 2001 From: martinduke Date: Mon, 11 Feb 2019 10:25:37 -0800 Subject: [PATCH 077/190] Eliminate false sentence? It's untrue that any stream could be created by any endpoing. --- draft-ietf-quic-transport.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 2a3a048882..cb23045ac1 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -254,9 +254,8 @@ can open, carry data for, and close a stream. Streams can also be long-lived and can last the entire duration of a connection. Streams can be created by either endpoint, can concurrently send data -interleaved with other streams, and can be cancelled. Any stream can be -initiated by either endpoint. QUIC does not provide any means of ensuring -ordering between bytes on different streams. +interleaved with other streams, and can be cancelled. QUIC does not provide any +means of ensuring ordering between bytes on different streams. QUIC allows for an arbitrary number of streams to operate concurrently and for an arbitrary amount of data to be sent on any stream, subject to flow control From 1f289026eb971051250e36d4bf28f056f99f0c17 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 12 Feb 2019 08:23:06 +1100 Subject: [PATCH 078/190] A second pair of eyes and a bit of perspective --- draft-ietf-quic-transport.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 342c6f9525..76973ec595 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1353,10 +1353,10 @@ handshake, a client SHOULD select an initial Destination Connection ID length long enough to fulfill the minimum size for every QUIC version it supports. The client populates the Source Connection ID field with a value of its choosing -and sets the SCIL field to match. +and sets the SCIL field to indicate the length. -The same Destination and Source Connection ID values are used for any 0-RTT -packets the client sends. +The first flight of 0-RTT packets use the same Destination and Source Connection +ID values as the client's first Initial. The Destination Connection ID field in the server's Initial packet contains a connection ID that is chosen by the recipient of the packet (i.e., the client); From c95b96835c50b65abcf913744bd187ebbd92523e Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 12 Feb 2019 08:46:00 +1100 Subject: [PATCH 079/190] Ian's suggestion, tweaked --- draft-ietf-quic-transport.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index b2d6b0e871..f509aeb6cf 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2091,7 +2091,8 @@ different local addresses, as discussed in {{connection-id}}. For this to be effective endpoints need to ensure that connections IDs they provide cannot be linked by any other entity. -Endpoints MAY move to a new connection ID at any time. +At any time, endpoints MAY change the Destination Connection ID they send to a +value that has not been used on another path. An endpoint MUST use a new connection ID if it initiates connection migration. Using a new connection ID eliminates the use of the connection ID for linking From 77b4d08b99246b03c35e48b6dcef8bef34896f21 Mon Sep 17 00:00:00 2001 From: Nick Banks Date: Mon, 11 Feb 2019 14:31:04 -0800 Subject: [PATCH 080/190] Change Idle Timeout to Milliseconds --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 8085aa253a..c94a9fb6d0 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -4071,7 +4071,7 @@ original_connection_id (0x0000): idle_timeout (0x0001): -: The idle timeout is a value in seconds that is encoded as an integer, see +: The idle timeout is a value in milliseconds that is encoded as an integer, see ({{idle-timeout}}). If this parameter is absent or zero then the idle timeout is disabled. From 630bc71c3e54f9149ae472e00618e67da3ead32f Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Mon, 11 Feb 2019 16:47:07 -0800 Subject: [PATCH 081/190] Martin's suggested alternative to non-zero --- draft-ietf-quic-http.md | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 308a4eea3a..e0fd43ca00 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -387,11 +387,12 @@ client MUST treat this as a connection error of type HTTP_DUPLICATE_PUSH. ### Reserved Stream Types {#stream-grease} -Stream types of the format `0x1f * N` for non-zero values of N are reserved to -exercise the requirement that unknown types be ignored. These streams have no -semantics, and can be sent when application-layer padding is desired. They MAY -also be sent on connections where no data is currently being transferred. -Endpoints MUST NOT consider these streams to have any meaning upon receipt. +Stream types of the format `0x1f * N + 0x21` for integer values of N are +reserved to exercise the requirement that unknown types be ignored. These +streams have no semantics, and can be sent when application-layer padding is +desired. They MAY also be sent on connections where no data is currently being +transferred. Endpoints MUST NOT consider these streams to have any meaning upon +receipt. The payload and length of the stream are selected in any manner the implementation chooses. @@ -703,7 +704,7 @@ The following settings are defined in HTTP/3: : The default value is 0. However, this value SHOULD be set to a non-zero value by servers. See {{placeholders}} for usage. -Setting identifiers of the format `0x1f * N` for non-zero values of N are +Setting identifiers of the format `0x1f * N + 0x21` for integer values of N are reserved to exercise the requirement that unknown identifiers be ignored. Such settings have no defined meaning. Endpoints SHOULD include at least one such setting in their SETTINGS frame. Endpoints MUST NOT consider such settings to @@ -886,12 +887,12 @@ the DUPLICATE_PUSH. ### Reserved Frame Types {#frame-grease} -Frame types of the format `0x1f * N` for non-zero values of N are reserved to -exercise the requirement that unknown types be ignored ({{extensions}}). These -frames have no semantics, and can be sent when application-layer padding is -desired. They MAY also be sent on connections where no data is currently being -transferred. Endpoints MUST NOT consider these frames to have any meaning upon -receipt. +Frame types of the format `0x1f * N + 0x21` for integer values of N are reserved +to exercise the requirement that unknown types be ignored ({{extensions}}). +These frames have no semantics, and can be sent when application-layer padding +is desired. They MAY also be sent on connections where no data is currently +being transferred. Endpoints MUST NOT consider these frames to have any meaning +upon receipt. The payload and length of the frames are selected in any manner the implementation chooses. @@ -1549,8 +1550,8 @@ The entries in the following table are registered by this document. | DUPLICATE_PUSH | 0xE | {{frame-duplicate-push}} | | ---------------- | ------ | -------------------------- | -Additionally, each code of the format `0x1f * N` for for non-zero integer values -of N (that is, `0x1f`, `0x3e`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be +Additionally, each code of the format `0x1f * N + 0x21` for integer values of N +(that is, `0x21`, `0x40`, ..., through `0x‭3FFFFFFFFFFFFFFE‬`) MUST NOT be assigned by IANA. ## Settings Parameters {#iana-settings} @@ -1594,8 +1595,8 @@ The entries in the following table are registered by this document. | NUM_PLACEHOLDERS | 0x8 | {{settings-parameters}} | | ---------------------------- | ------ | ------------------------- | -Additionally, each code of the format `0x1f * N` for for non-zero integer values -of N (that is, `0x1f`, `0x3e`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be +Additionally, each code of the format `0x1f * N + 0x21` for integer values of N +(that is, `0x21`, `0x40`, ..., through `0x‭3FFFFFFFFFFFFFFE‬`) MUST NOT be assigned by IANA. ## Error Codes {#iana-error-codes} @@ -1688,8 +1689,8 @@ The entries in the following table are registered by this document. | Push Stream | 0x01 | {{server-push}} | Server | | ---------------- | ------ | -------------------------- | ------ | -Additionally, each code of the format `0x1f * N` for non-zero integer values of -N (that is, `0x1f`, `0x3e`, ..., through `0x‭3FFFFFFFFFFFFFFC‬`) MUST NOT be +Additionally, each code of the format `0x1f * N + 0x21` for integer values of N +(that is, `0x21`, `0x40`, ..., through `0x‭3FFFFFFFFFFFFFFE‬`) MUST NOT be assigned by IANA. --- back From b8de486e078aa7a8d115fe056e2f2aadc0596246 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 12 Feb 2019 09:40:21 +0800 Subject: [PATCH 082/190] the crypto timeout is based on the last crypto packet sent --- draft-ietf-quic-recovery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 32cc271be3..8fbcc0c51d 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -412,7 +412,7 @@ is available, or if the network changes, the initial RTT SHOULD be set to 100ms. When an acknowledgement is received, a new RTT is computed and the timer SHOULD be set for twice the newly computed smoothed RTT. -When crypto packets are sent, the sender MUST set a timer for the crypto +Every time a crypto packets is sent, the sender MUST set a timer for the crypto timeout period. Upon timeout, the sender MUST retransmit all unacknowledged CRYPTO data if possible. From 5e56e69566133b7ca55f33d90c0c73eced272880 Mon Sep 17 00:00:00 2001 From: Mark Nottingham Date: Tue, 12 Feb 2019 16:15:56 +1100 Subject: [PATCH 083/190] disambiguate the lists. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a8bb3ea5fe..3a869e093d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,7 +67,7 @@ Issues will be labeled by the Chairs as either `editorial` or `design`: * **Editorial** issues can be dealt with by the editor(s) without consensus or notification. Typically, any discussion will take place on the issue itself. -The open design issues in the issues list are those that we are currently discussing, or plan to discuss. They can be discussed on the mailing list or the issues list. +The open design issues in the issues list are those that we are currently discussing, or plan to discuss. They can be discussed on the mailing list or the issue itself. We're currently using two different processes for issue resolution, depending on draft maturity. From 89c8c3b8bd1e79692a93ab312820cea63f560a4a Mon Sep 17 00:00:00 2001 From: ianswett Date: Tue, 12 Feb 2019 11:50:09 -0500 Subject: [PATCH 084/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 6e573be7cb..2080d15b47 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1082,7 +1082,8 @@ OnLossDetectionTimeout(): if (loss_time != 0): // Time threshold loss Detection DetectLostPackets(pn_space) - // Don't retransmit all crypto data if a packet was just lost. + // Retransmit crypto data if no packets were lost + // and there are still crypto packets in flight. else if (crypto packets are in flight): // Crypto retransmission timeout. RetransmitUnackedCryptoData() From 8cfa8346c072d629f0b9397f9b7795327b90fc49 Mon Sep 17 00:00:00 2001 From: ianswett Date: Tue, 12 Feb 2019 11:50:46 -0500 Subject: [PATCH 085/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 2080d15b47..6898acf449 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1030,7 +1030,7 @@ GetEarliestLossTime(): if loss_time[pn_space] != 0 && (time == 0 || loss_time[pn_space] < time): time = loss_time[pn_space]; - space = Initial + space = pn_space return [time, space] SetLossDetectionTimer(): From f7fb4829175e975920b1026cc0d4431301a14dea Mon Sep 17 00:00:00 2001 From: ianswett Date: Tue, 12 Feb 2019 11:51:41 -0500 Subject: [PATCH 086/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 6898acf449..52823e89cd 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1040,7 +1040,7 @@ SetLossDetectionTimer(): loss_detection_timer.cancel() return - [loss_time, pn_space] = GetEarliestLossTime() + loss_time, _ = GetEarliestLossTime() if (loss_time != 0): // Time threshold loss detection. loss_detection_timer.update(loss_time) @@ -1078,7 +1078,7 @@ Pseudocode for OnLossDetectionTimeout follows: ~~~ OnLossDetectionTimeout(): - [loss_time, pn_space] = GetEarliestLossTime() + loss_time, pn_space = GetEarliestLossTime() if (loss_time != 0): // Time threshold loss Detection DetectLostPackets(pn_space) From f95c289d1b49ed188ba1aa940de4feb3133adc4d Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 13 Feb 2019 08:29:14 +1100 Subject: [PATCH 087/190] Mike's comments --- draft-ietf-quic-tls.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 15d6ac3196..7348d95721 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -318,10 +318,10 @@ long as they are associated with the same encryption level. For instance, an implementation might bundle a Handshake message and an ACK for some Handshake data into the same packet. -Each encryption level has a specific list of frames which may appear in it. The -rules here generalize those of TLS, in that frames associated with establishing -the connection can usually appear at any encryption level, whereas those -associated with transferring data can only appear in the 0-RTT and 1-RTT +Some frames are prohibited in different encryption levels, others cannot be +sent. The rules here generalize those of TLS, in that frames associated with +establishing the connection can usually appear at any encryption level, whereas +those associated with transferring data can only appear in the 0-RTT and 1-RTT encryption levels: - PADDING frames MAY appear in packets of any encryption level. @@ -334,6 +334,10 @@ encryption levels: - All other frame types MUST only be sent in the 0-RTT and 1-RTT levels. +Note that it is not possible to send some frames in 0-RTT for various reasons. +In addition to ACK, this includes CRYPTO, NEW_TOKEN, PATH_RESPONSE, and +RETIRE_CONNECTION_ID. + Because packets could be reordered on the wire, QUIC uses the packet type to indicate which level a given packet was encrypted under, as shown in {{packet-types-levels}}. When multiple packets of different encryption levels @@ -1318,9 +1322,9 @@ would need to assess whether those uses were vulnerable to replay attack. Extensions to QUIC might create an additional exposure to replay attack if they are used by application protocols. QUIC extensions SHOULD describe how replay -attacks affects their operation. Application protocols MUST either disable -extensions in 0-RTT or provide replay mitigation strategies for any use of the -extension. +attacks affects their operation. Application protocols MUST either prohibit the +use of extensions in 0-RTT or provide replay mitigation strategies for those +extensions that can be used. ## Packet Reflection Attack Mitigation {#reflection} From 6c4033e7dd54137152deb84d797fe6acc5ced2bd Mon Sep 17 00:00:00 2001 From: David Schinazi Date: Tue, 12 Feb 2019 14:04:32 -0800 Subject: [PATCH 088/190] Version Negotiation: incorporate feedback from MT and Ian --- draft-ietf-quic-transport.md | 38 ++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 535fa7f04a..f113521f5a 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1131,17 +1131,23 @@ expectation that it will eventually receive an Initial packet. ## Handling Version Negotiation Packets {#handle-vn} -How a client reacts to receiving a Version Negotiation packet is left as future -work defined by future versions of QUIC. Future versions of QUIC that define -version negotiation with QUIC version 1 MUST define a mechanism that prevents -version downgrade attacks. +When a client receives a Version Negotiation packet, it MUST abandon the +current connection attempt. Version Negotiation packets are designed to allow +future versions of QUIC to negotiate the version in use between endpoints. +It is therefore expected for future versions of QUIC to change how +implementations of this version of QUIC react to Version Negotiation packets. +How to perform version negotiation is left as future work defined by future +versions of QUIC. In particular, that future work will need to ensure +robustness against version downgrade attacks {{version-downgrade}}. + ### Version Negotiation Between Draft Versions \[\[RFC editor: please remove this section before publication.]] When a draft implementation receives a Version Negotiation packet, it MAY use -it to attempt a new connection with one of the supported versions. +it to attempt a new connection with one of the versions listed in the packet, +instead of abandoning the current connection attempt {{handle-vn}}. The client MUST check that the Destination and Source Connection ID fields match the Source and Destination Connection ID fields in a packet that the @@ -1311,11 +1317,6 @@ packet is received from the server, the client MUST use the same value unless it abandons the connection attempt and starts a new one. The initial Destination Connection ID is used to determine packet protection keys for Initial packets. -The final version used for a connection might be different from the version of -the first Initial from the client. To enable consistent routing through the -handshake, a client SHOULD select an initial Destination Connection ID length -long enough to fulfill the minimum size for every QUIC version it supports. - The client populates the Source Connection ID field with a value of its choosing and sets the SCIL field to match. @@ -3920,8 +3921,6 @@ The format of the transport parameters is the TransportParameters struct from language from Section 3 of {{!TLS13=RFC8446}}. ~~~ - uint32 QuicVersion; - enum { original_connection_id(0), idle_timeout(1), @@ -3945,9 +3944,7 @@ language from Section 3 of {{!TLS13=RFC8446}}. opaque value<0..2^16-1>; } TransportParameter; - struct { - TransportParameter parameters<0..2^16-1>; - } TransportParameters; + TransportParameter TransportParameters<0..2^16-1>; ~~~ {: #figure-transport-parameters title="Definition of TransportParameters"} @@ -5283,6 +5280,17 @@ correct instance, it is better to send a stateless reset than wait for connections to time out. However, this is acceptable only if the routing cannot be influenced by an attacker. +## Version Downgrade {#version-downgrade} + +This document defines QUIC Version Negotiation packets {{version-negotiation}}, +which can be used to negotiate the QUIC version used between two endpoints. +However, this document does not specify how this negotiation will be performed +between this version and subsequent future versions. In particular, Version +Negotiation packets do not contain any mechanism to prevent version downgrade +attacks. Future version of QUIC that wish to use Version Negotiation packets +to negotiate the use of that version MUST define a mechanism that is robust +against version downgrade attacks. + # IANA Considerations From 624cbf9087f69e9433ee5ddc6d1e217fd336f64b Mon Sep 17 00:00:00 2001 From: Lucas Pardue Date: Tue, 12 Feb 2019 23:07:28 +0000 Subject: [PATCH 089/190] Modify QPACK steam and instruction terminology (#2440) * Focus terminology on QPACK instructions rather than stream types * Mike's feedback --- draft-ietf-quic-qpack.md | 162 +++++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 76 deletions(-) diff --git a/draft-ietf-quic-qpack.md b/draft-ietf-quic-qpack.md index 63cd4ed66a..bb6a2d0f3b 100644 --- a/draft-ietf-quic-qpack.md +++ b/draft-ietf-quic-qpack.md @@ -311,8 +311,8 @@ streams, the decoder sends an Insert Count Increment instruction (see ## Decoder As in HPACK, the decoder processes header blocks and emits the corresponding -header lists. It also processes dynamic table modifications from instructions on -the encoder stream. +header lists. It also processes dynamic table modifications from encoder +instructions received on the encoder stream. The decoder MUST emit header fields in the order their representations appear in the input header block. @@ -320,8 +320,8 @@ the input header block. ### State Synchronization -The decoder stream ({{decoder-stream}}) signals key events at the decoder that -permit the encoder to track the decoder's state. These events are: +The decoder instructions ({{decoder-instructions}}) signal key events at the +decoder that permit the encoder to track the decoder's state. These events are: - Complete processing of a header block - Abandonment of a stream which might have remaining header blocks @@ -365,8 +365,8 @@ which has a fixed index over time. Its entries are defined in {{static-table}}. Note the QPACK static table is indexed from 0, whereas the HPACK static table is indexed from 1. -When the decoder encounters an invalid static table index on a request stream or -push stream it MUST treat this as a stream error of type +When the decoder encounters an invalid static table index in a header block +instruction it MUST treat this as a stream error of type `HTTP_QPACK_DECOMPRESSION_FAILED`. If this index is received on the encoder stream, this MUST be treated as a connection error of type `HTTP_QPACK_ENCODER_STREAM_ERROR`. @@ -374,8 +374,9 @@ stream, this MUST be treated as a connection error of type ## Dynamic Table {#table-dynamic} The dynamic table consists of a list of header fields maintained in first-in, -first-out order. The dynamic table is initially empty. Entries are added by -instructions on the encoder stream (see {{encoder-stream}}). +first-out order. Each HTTP/3 endpoint holds a dynamic table that is initially +empty. Entries are added by encoder instructions received on the encoder stream +(see {{encoder-instructions}}). The dynamic table can contain duplicate entries (i.e., entries with the same name and same value). Therefore, duplicate entries MUST NOT be treated as an @@ -446,7 +447,8 @@ rejected, the maximum table capacity is 0 until the encoder processes a SETTINGS frame with a non-zero value of SETTINGS_QPACK_MAX_TABLE_CAPACITY. When the maximum table capacity is 0, the encoder MUST NOT insert entries into -the dynamic table, and MUST NOT send any instructions on the encoder stream. +the dynamic table, and MUST NOT send any encoder instructions on the encoder +stream. ### Absolute Indexing {#indexing} @@ -463,7 +465,7 @@ The relative index begins at zero and increases in the opposite direction from the absolute index. Determining which entry has a relative index of "0" depends on the context of the reference. -On the encoder stream, a relative index of "0" always refers to the most +In encoder instructions, a relative index of "0" always refers to the most recently inserted value in the dynamic table. Note that this means the entry referenced by a given relative index will change while interpreting instructions on the encoder stream. @@ -483,7 +485,7 @@ d = count of entries dropped ~~~~~ {: title="Example Dynamic Table Indexing - Control Stream"} -Unlike on the encoder stream, relative indices on push and request streams are +Unlike encoder instructions, relative indices in header block instructions are relative to the Base at the beginning of the header block (see {{header-prefix}}). This ensures that references are stable even if the dynamic table is updated while decoding a header block. @@ -510,18 +512,17 @@ the first entry added after the Base, see {{post-base}}. n = count of entries inserted d = count of entries dropped ~~~~~ -{: title="Example Dynamic Table Indexing - Relative Index on Request Stream"} +{: title="Example Dynamic Table Indexing - Relative Index in Header Block"} ### Post-Base Indexing {#post-base} -A header block on the request stream can reference entries added after the entry -identified by the Base. This allows an encoder to process a header block in a -single pass and include references to entries added while processing this (or -other) header blocks. Newly added entries are referenced using Post-Base -instructions. Indices for Post-Base instructions increase in the same direction -as absolute indices, with the zero value being the first entry inserted after -the Base. +A header block can reference entries added after the entry identified by the +Base. This allows an encoder to process a header block in a single pass and +include references to entries added while processing this (or other) header +blocks. Newly added entries are referenced using Post-Base instructions. Indices +for Post-Base instructions increase in the same direction as absolute indices, +with the zero value being the first entry inserted after the Base. ~~~~~ drawing Base @@ -536,20 +537,20 @@ the Base. n = count of entries inserted d = count of entries dropped ~~~~~ -{: title="Example Dynamic Table Indexing - Post-Base Index on Request Stream"} +{: title="Example Dynamic Table Indexing - Post-Base Index in Header Block"} ### Invalid References -If the decoder encounters a reference on a request or push stream to a dynamic +If the decoder encounters a reference in a header block instruction to a dynamic table entry which has already been evicted or which has an absolute index greater than or equal to the declared Required Insert Count (see {{header-prefix}}), it MUST treat this as a stream error of type `HTTP_QPACK_DECOMPRESSION_FAILED`. -If the decoder encounters a reference on the encoder stream to a dynamic table -entry which has already been dropped, it MUST treat this as a connection error -of type `HTTP_QPACK_ENCODER_STREAM_ERROR`. +If the decoder encounters a reference in an encoder instruction to a dynamic +table entry which has already been dropped, it MUST treat this as a connection +error of type `HTTP_QPACK_ENCODER_STREAM_ERROR`. # Wire Format @@ -580,31 +581,41 @@ prefix integer. The remainder of the string literal is unmodified. A string literal without a prefix length noted is an 8-bit prefix string literal and follows the definitions in [RFC7541] without modification. -## Stream Types +## Instructions -QPACK instructions occur in three locations, each of which uses a separate -instruction space: +There are three separate QPACK instruction spaces. Encoder instructions +({{encoder-instructions}}) carry table updates, decoder instructions +({{decoder-instructions}}) carry acknowledgments of table modifications and +header processing, and header block instructions ({{header-block-instructions}}) +convey an encoded representation of a header list by referring to the QPACK +table state. - - The encoder stream is a unidirectional stream of type `0x02` which carries - table updates from encoder to decoder. +Encoder and decoder instructions appear on the unidirectional stream types +described in this section. Header block instructions are contained in HEADERS +and PUSH_PROMISE frames, which are conveyed on request or push streams as +described in {{HTTP3}}. - - The decoder stream is a unidirectional stream of type `0x03` which carries - acknowledgements of table modifications and header processing from decoder to - encoder. +### Encoder and Decoder Streams - - Finally, the contents of HEADERS and PUSH_PROMISE frames on request streams - and push streams reference the QPACK table state. +QPACK defines two unidirectional stream types: - -There MUST be exactly one of each unidirectional stream type in each direction. -Receipt of a second instance of either stream type MUST be treated as a -connection error of HTTP_WRONG_STREAM_COUNT. These streams MUST NOT be closed. -Closure of either unidirectional stream MUST be treated as a connection error of -type HTTP_CLOSED_CRITICAL_STREAM. + - An encoder stream is a unidirectional stream of type `0x02`. + It carries an unframed sequence of encoder instructions from encoder + to decoder. -This section describes the instructions which are possible on each stream type. + - A decoder stream is a unidirectional stream of type `0x03`. + It carries an unframed sequence of decoder instructions from decoder + to encoder. + + +HTTP/3 endpoints contain a QPACK encoder and decoder. Each endpoint MUST +initiate a single encoder stream and decoder stream. Receipt of a second +instance of either stream type be MUST treated as a connection error of type +HTTP_WRONG_STREAM_COUNT. These streams MUST NOT be closed. Closure of either +unidirectional stream type MUST be treated as a connection error of type +HTTP_CLOSED_CRITICAL_STREAM. -## Encoder Stream {#encoder-stream} +## Encoder Instructions {#encoder-instructions} Table updates can add a table entry, possibly using existing entries to avoid transmitting redundant information. The name can be transmitted as a reference @@ -612,8 +623,7 @@ to an existing entry in the static or the dynamic table or as a string literal. For entries which already exist in the dynamic table, the full entry can also be used by reference, creating a duplicate entry. -The contents of the encoder stream are an unframed sequence of the following -instructions. +This section specifies the following encoder instructions. ### Insert With Name Reference @@ -713,16 +723,15 @@ references (see {{reference-tracking}}). Changing the capacity of the dynamic table is not acknowledged as this instruction does not insert an entry. -## Decoder Stream +## Decoder Instructions {#decoder-instructions} -The decoder stream carries information used to ensure consistency of the dynamic -table. Information is sent from the decoder to the encoder; that is, the server -informs the client about the processing of the client's header blocks and table -updates, and the client informs the server about the processing of the server's -header blocks and table updates. +Decoder instructions provide information used to ensure consistency of the +dynamic table. They are sent from the decoder to the encoder on a decoder +stream; that is, the server informs the client about the processing of the +client's header blocks and table updates, and the client informs the server +about the processing of the server's header blocks and table updates. -The contents of the decoder stream are an unframed sequence of the following -instructions. +This section specifies the following decoder instructions. ### Insert Count Increment @@ -751,9 +760,9 @@ connection error of type `HTTP_QPACK_DECODER_STREAM_ERROR`. After processing a header block whose declared Required Insert Count is not zero, the decoder emits a Header Acknowledgement instruction on the decoder stream. The instruction begins with the '1' one-bit pattern and includes the -request stream's stream ID, encoded as a 7-bit prefix integer. It is used by -the peer's encoder to know when it is safe to evict an entry, and possibly -update the Known Received Count. +header block's associated stream ID, encoded as a 7-bit prefix integer. It is +used by the peer's encoder to know when it is safe to evict an entry, and +possibly update the Known Received Count. ~~~~~~~~~~ drawing 0 1 2 3 4 5 6 7 @@ -765,9 +774,9 @@ update the Known Received Count. The same Stream ID can be identified multiple times, as multiple header blocks can be sent on a single stream in the case of intermediate responses, trailers, -and pushed requests. Since header frames on each stream are received and -processed in order, this gives the encoder precise feedback on which header -blocks within a stream have been fully processed. +and pushed requests. Since HEADERS and PUSH_PROMISE frames on each stream are +received and processed in order, this gives the encoder precise feedback on +which header blocks within a stream have been fully processed. If an encoder receives a Header Acknowledgement instruction referring to a stream on which every header block with a non-zero Required Insert Count has @@ -811,11 +820,14 @@ An encoder cannot infer from this instruction that any updates to the dynamic table have been received. -## Request and Push Streams +## Header Block Instructions -HEADERS and PUSH_PROMISE frames on request and push streams reference the -dynamic table in a particular state without modifying it. Frames on these -streams emit the headers for an HTTP request or response. +HTTP/3 endpoints convert header lists to headers blocks and exchange them inside +HEADERS and PUSH_PROMISE frames. A decoder interprets header block instructions +in order to construct a header list. These instructions reference the static +table, or dynamic table in a particular state without modifying it. + +This section specifies the following header block instructions. ### Header Block Prefix {#header-prefix} @@ -1092,14 +1104,16 @@ The following error codes are defined for HTTP/3 to indicate failures of QPACK which prevent the stream or connection from continuing: HTTP_QPACK_DECOMPRESSION_FAILED (TBD): -: The decoder failed to interpret an instruction on a request or push stream and - is not able to continue decoding that header block. +: The decoder failed to interpret a header block instruction and is not + able to continue decoding that header block. HTTP_QPACK_ENCODER_STREAM_ERROR (TBD): -: The decoder failed to interpret an instruction on the encoder stream. +: The decoder failed to interpret an encoder instruction received on the + encoder stream. HTTP_QPACK_DECODER_STREAM_ERROR (TBD): -: The encoder failed to interpret an instruction on the decoder stream. +: The encoder failed to interpret a decoder instruction received on the + decoder stream. Upon encountering an error, an implementation MAY elect to treat it as a connection error even if this document prescribes that it MUST be treated as a @@ -1114,10 +1128,8 @@ TBD. ## Settings Registration -This document creates two new settings in the "HTTP/3 Settings" registry -established in {{HTTP3}}. - -The entries in the following table are registered by this document. +This document specifies two settings. The entries in the following table are +registered in the "HTTP/3 Settings" registry established in {{HTTP3}}. |------------------------------|--------|---------------------------| | Setting Name | Code | Specification | @@ -1128,10 +1140,8 @@ The entries in the following table are registered by this document. ## Stream Type Registration -This document creates two new settings in the "HTTP/3 Stream Type" registry -established in {{HTTP3}}. - -The entries in the following table are registered by this document. +This document specifies two stream types. The entries in the following table are +registered in the "HTTP/3 Stream Type" registry established in {{HTTP3}}. | ---------------------------- | ------ | ------------------------- | ------ | | Stream Type | Code | Specification | Sender | @@ -1142,8 +1152,8 @@ The entries in the following table are registered by this document. ## Error Code Registration -This document establishes the following new error codes in the "HTTP/3 Error -Code" registry established in {{HTTP3}}. +This document specifies three error codes. The entries in the following table +are registered in the "HTTP/3 Error Code" registry established in {{HTTP3}}. | --------------------------------- | ----- | ---------------------------------------- | ---------------------- | | Name | Code | Description | Specification | From 0974bda7da7977b5504d8eae222a1a57d5aa2af5 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 13 Feb 2019 10:17:36 +1100 Subject: [PATCH 090/190] Reword --- draft-ietf-quic-tls.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 7348d95721..c4f1cf34a3 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -334,9 +334,8 @@ encryption levels: - All other frame types MUST only be sent in the 0-RTT and 1-RTT levels. -Note that it is not possible to send some frames in 0-RTT for various reasons. -In addition to ACK, this includes CRYPTO, NEW_TOKEN, PATH_RESPONSE, and -RETIRE_CONNECTION_ID. +Note that it is not possible to send the following frames in 0-RTT for various +reasons: ACK, CRYPTO, NEW_TOKEN, PATH_RESPONSE, and RETIRE_CONNECTION_ID. Because packets could be reordered on the wire, QUIC uses the packet type to indicate which level a given packet was encrypted under, as shown in From 0bb2046abc730c39e245f1041a4c074ce714454d Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 13 Feb 2019 10:19:09 +1100 Subject: [PATCH 091/190] application semantics stuff --- draft-ietf-quic-tls.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index c4f1cf34a3..ba7351114f 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1322,8 +1322,8 @@ would need to assess whether those uses were vulnerable to replay attack. Extensions to QUIC might create an additional exposure to replay attack if they are used by application protocols. QUIC extensions SHOULD describe how replay attacks affects their operation. Application protocols MUST either prohibit the -use of extensions in 0-RTT or provide replay mitigation strategies for those -extensions that can be used. +use of any extensions that carry application semantics in 0-RTT or provide +replay mitigation strategies. ## Packet Reflection Attack Mitigation {#reflection} From 383268d00c14ab6e37c4c3fcfc6de8daf2122758 Mon Sep 17 00:00:00 2001 From: martinduke Date: Tue, 12 Feb 2019 15:38:52 -0800 Subject: [PATCH 092/190] Reword Immediate ACK Recommendation (#2424) * Reword Immediate ACK Recommendation * Trailing whitespace is annoying * Address review issues. * Update draft-ietf-quic-recovery.md Co-Authored-By: martinduke * Resolves all but one comment Still quibbling over the word "usually" * Update draft-ietf-quic-recovery.md Co-Authored-By: martinduke * Simplified the text * Update draft-ietf-quic-recovery.md Co-Authored-By: martinduke --- draft-ietf-quic-recovery.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 32cc271be3..199f2e2882 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -135,6 +135,12 @@ Crypto Packets: : Packets containing CRYPTO data sent in Initial or Handshake packets. +Out-of-order Packets: + +: Packets that do not increase the largest received packet number for its + packet number space by exactly one. Packets arrive out of order + when earlier packets are lost or delayed. + # Design of the QUIC Transmission Machinery All transmissions in QUIC are sent with a packet-level header, which indicates @@ -244,11 +250,10 @@ ack-eliciting packet. QUIC recovery algorithms do not assume the peer sends an ACK immediately when receiving a second ack-eliciting packet. In order to accelerate loss recovery and reduce timeouts, the receiver SHOULD -send an immediate ACK when it receives a new packet which is not one greater -than the largest received packet number. A receiver MAY send immediate ACKs -for the next few ack-eliciting packets that are received, but SHOULD NOT -send an immediate ACK for more than 1/8 RTT after receiving an out-of-order -packet. +send an immediate ACK after it receives an out-of-order packet. It could send +immediate ACKs for in-order packets for a period of time that SHOULD NOT exceed +1/8 RTT unless more out-of-order packets arrive. If every packet arrives out-of- +order, then an immediate ACK SHOULD be sent for every received packet. Similarly, packets marked with the ECN Congestion Experienced (CE) codepoint in the IP header SHOULD be acknowledged immediately, to reduce the peer's response From c4e459ffda2a56980f5e61322342566ab263c179 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Wed, 13 Feb 2019 10:01:09 +1000 Subject: [PATCH 093/190] attachment issue Co-Authored-By: martinthomson --- draft-ietf-quic-tls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index ba7351114f..892b6fd22e 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1316,7 +1316,7 @@ In the core protocol, particular attention needs to be paid to STREAM frames, which carry application data. If another frame type carries, or could carry, application semantics, then the risk from replay attack needs to be considered. For instance, though this is likely to be inadvisable, an application that -attached semantics to increases in flow control credit or stream cancellation +attaches semantics to increases in flow control credit or stream cancellation would need to assess whether those uses were vulnerable to replay attack. Extensions to QUIC might create an additional exposure to replay attack if they From 429a912f2062f3ad05ab6ed422ec0db2fc69d491 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 13 Feb 2019 11:13:15 +1100 Subject: [PATCH 094/190] Reword closing confirmation text Closes #2147. --- draft-ietf-quic-transport.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index a5c3320fb9..d91ea396f2 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2156,11 +2156,10 @@ endpoint in the draining state MUST NOT send any packets. Retaining packet protection keys is unnecessary once a connection is in the draining state. An endpoint MAY transition from the closing period to the draining period if it -can confirm that its peer is also closing or draining. Receiving a -CONNECTION_CLOSE frame is sufficient confirmation, as is receiving a stateless -reset. The draining period SHOULD end when the closing period would have ended. -In other words, the endpoint can use the same end time, but cease retransmission -of the closing packet. +can receives a CONNECTION_CLOSE frame or stateless reset, both of which indicate +that the peer is also closing or draining. The draining period SHOULD end when +the closing period would have ended. In other words, the endpoint can use the +same end time, but cease retransmission of the closing packet. Disposing of connection state prior to the end of the closing or draining period could cause delayed or reordered packets to be handled poorly. Endpoints that From f529d05ba87f57d6aa3f7d3b987300296f69b282 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 13 Feb 2019 11:16:38 +1100 Subject: [PATCH 095/190] Only applications know what can be retried Closes #2150. --- draft-ietf-quic-transport.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index a5c3320fb9..d169b7bff9 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2211,7 +2211,9 @@ endpoint. An endpoint that sends packets near the end of the idle timeout period of a peer risks having those packets discarded if its peer enters the draining state before the packets arrive. If a peer could timeout within an Probe Timeout (PTO, see Section 6.2.2 of {{QUIC-RECOVERY}}), it is advisable to -test for liveness before sending any data that cannot be retried safely. +test for liveness before sending any data that cannot be retried safely. Note +that it is likely that only application protocols or using applications will +know what information can be retried. ## Immediate Close From 95d380159040255309fd6ff32a5ebc7808f89cd3 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 12 Feb 2019 16:17:46 -0800 Subject: [PATCH 096/190] Apply MT suggestions from code review Co-Authored-By: DavidSchinazi --- 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 f113521f5a..e101ce051b 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -5287,8 +5287,8 @@ which can be used to negotiate the QUIC version used between two endpoints. However, this document does not specify how this negotiation will be performed between this version and subsequent future versions. In particular, Version Negotiation packets do not contain any mechanism to prevent version downgrade -attacks. Future version of QUIC that wish to use Version Negotiation packets -to negotiate the use of that version MUST define a mechanism that is robust +attacks. Future versions of QUIC that use Version Negotiation packets +MUST define a mechanism that is robust against version downgrade attacks. From 6f035221d174ff93d096ad67bbdc1a915fd4907d Mon Sep 17 00:00:00 2001 From: David Schinazi Date: Tue, 12 Feb 2019 16:18:21 -0800 Subject: [PATCH 097/190] Tweak from MT comment --- draft-ietf-quic-transport.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index e101ce051b..ed9e97e874 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1135,7 +1135,8 @@ When a client receives a Version Negotiation packet, it MUST abandon the current connection attempt. Version Negotiation packets are designed to allow future versions of QUIC to negotiate the version in use between endpoints. It is therefore expected for future versions of QUIC to change how -implementations of this version of QUIC react to Version Negotiation packets. +implementations which support multiple versions of QUIC react to Version +Negotiation packets when attempting to establish a connection of this version. How to perform version negotiation is left as future work defined by future versions of QUIC. In particular, that future work will need to ensure robustness against version downgrade attacks {{version-downgrade}}. From 54be05b2e2272bc8be25ae74b22d2b6a116e70e2 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 13 Feb 2019 11:20:57 +1100 Subject: [PATCH 098/190] "expected for" annoyed me --- draft-ietf-quic-transport.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index ed9e97e874..a96842d1f8 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1134,12 +1134,12 @@ expectation that it will eventually receive an Initial packet. When a client receives a Version Negotiation packet, it MUST abandon the current connection attempt. Version Negotiation packets are designed to allow future versions of QUIC to negotiate the version in use between endpoints. -It is therefore expected for future versions of QUIC to change how -implementations which support multiple versions of QUIC react to Version -Negotiation packets when attempting to establish a connection of this version. -How to perform version negotiation is left as future work defined by future -versions of QUIC. In particular, that future work will need to ensure -robustness against version downgrade attacks {{version-downgrade}}. +Future versions of QUIC might change how implementations that support multiple +versions of QUIC react to Version Negotiation packets when attempting to +establish a connection using this version. How to perform version negotiation +is left as future work defined by future versions of QUIC. In particular, +that future work will need to ensure robustness against version downgrade +attacks {{version-downgrade}}. ### Version Negotiation Between Draft Versions From 2a2935cce998d132a4156f55f89b80f35df32df2 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 13 Feb 2019 11:21:55 +1100 Subject: [PATCH 099/190] Reflow --- draft-ietf-quic-transport.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index a96842d1f8..f329c63819 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -5288,9 +5288,8 @@ which can be used to negotiate the QUIC version used between two endpoints. However, this document does not specify how this negotiation will be performed between this version and subsequent future versions. In particular, Version Negotiation packets do not contain any mechanism to prevent version downgrade -attacks. Future versions of QUIC that use Version Negotiation packets -MUST define a mechanism that is robust -against version downgrade attacks. +attacks. Future versions of QUIC that use Version Negotiation packets MUST +define a mechanism that is robust against version downgrade attacks. # IANA Considerations From 186160860e6d047a6e4ab2bea5001f4b220b16fa Mon Sep 17 00:00:00 2001 From: ianswett Date: Wed, 13 Feb 2019 09:29:58 +0800 Subject: [PATCH 100/190] =?UTF-8?q?Ian=E2=80=99s=20suggestion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: marten-seemann --- draft-ietf-quic-recovery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 8fbcc0c51d..cc9af15520 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -412,7 +412,7 @@ is available, or if the network changes, the initial RTT SHOULD be set to 100ms. When an acknowledgement is received, a new RTT is computed and the timer SHOULD be set for twice the newly computed smoothed RTT. -Every time a crypto packets is sent, the sender MUST set a timer for the crypto +Every time a crypto packet is sent, the sender MUST set a timer for the crypto timeout period. Upon timeout, the sender MUST retransmit all unacknowledged CRYPTO data if possible. From c13a9f565df1fee1cbfe12cf17e2923fc5affeea Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 13 Feb 2019 12:35:08 +1100 Subject: [PATCH 101/190] Initiate migration --- draft-ietf-quic-transport.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index f509aeb6cf..0b5638e566 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1853,9 +1853,9 @@ An endpoint also MUST NOT initiate connection migration if the peer sent the `disable_migration` transport parameter during the handshake. An endpoint which has sent this transport parameter, but detects that a peer has nonetheless migrated to a different network MAY treat this as a connection error of type -INVALID_MIGRATION. Similarly, an endpoint MUST NOT migrate if its peer supplies -a zero-length connection ID as packets without a Destination Connection ID -cannot be attributed to a connection based on address tuple. +INVALID_MIGRATION. Similarly, an endpoint MUST NOT initiate migration if its +peer supplies a zero-length connection ID as packets without a Destination +Connection ID cannot be attributed to a connection based on address tuple. Not all changes of peer address are intentional migrations. The peer could experience NAT rebinding: a change of address due to a middlebox, usually a NAT, From ef1db5c4d58ddb2f2830e2032ddeb977cc285201 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 13 Feb 2019 12:48:32 +1100 Subject: [PATCH 102/190] oops grammar --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index d91ea396f2..c0f307fe01 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2156,7 +2156,7 @@ endpoint in the draining state MUST NOT send any packets. Retaining packet protection keys is unnecessary once a connection is in the draining state. An endpoint MAY transition from the closing period to the draining period if it -can receives a CONNECTION_CLOSE frame or stateless reset, both of which indicate +receives a CONNECTION_CLOSE frame or stateless reset, both of which indicate that the peer is also closing or draining. The draining period SHOULD end when the closing period would have ended. In other words, the endpoint can use the same end time, but cease retransmission of the closing packet. From be00d3c1013de2900569cf4ea374cf53069b6188 Mon Sep 17 00:00:00 2001 From: ianswett Date: Wed, 13 Feb 2019 09:02:14 -0500 Subject: [PATCH 103/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 52823e89cd..b28b1e4257 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1031,7 +1031,7 @@ GetEarliestLossTime(): (time == 0 || loss_time[pn_space] < time): time = loss_time[pn_space]; space = pn_space - return [time, space] + return time, space SetLossDetectionTimer(): // Don't arm timer if there are no ack-eliciting packets From 8c4d201ddaaf56c992628b63e63efe000ea89580 Mon Sep 17 00:00:00 2001 From: martinduke Date: Wed, 13 Feb 2019 11:17:41 -0800 Subject: [PATCH 104/190] Fix packet and stream numbers in example The choices were odd for a "typical" example --- draft-ietf-quic-transport.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index a5c3320fb9..561d442b63 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1266,7 +1266,7 @@ Initial[1]: ACK[0] Handshake[0]: CRYPTO[FIN], ACK[0] 1-RTT[0]: STREAM[0, "..."], ACK[0] -> - 1-RTT[1]: STREAM[55, "..."], ACK[0] + 1-RTT[1]: STREAM[3, "..."], ACK[0] <- Handshake[1]: ACK[0] ~~~~ {: #tls-1rtt-handshake title="Example 1-RTT Handshake"} @@ -1288,9 +1288,9 @@ Initial[0]: CRYPTO[CH] Initial[1]: ACK[0] Handshake[0]: CRYPTO[FIN], ACK[0] -1-RTT[2]: STREAM[0, "..."] ACK[0] -> +1-RTT[1]: STREAM[0, "..."] ACK[0] -> - 1-RTT[1]: STREAM[55, "..."], ACK[1,2] + 1-RTT[1]: STREAM[3, "..."], ACK[0,1] <- Handshake[1]: ACK[0] ~~~~ {: #tls-0rtt-handshake title="Example 0-RTT Handshake"} From 5d5ef61581fc19c2b35c80544f1d43d403eaf6c8 Mon Sep 17 00:00:00 2001 From: martinduke Date: Wed, 13 Feb 2019 11:19:11 -0800 Subject: [PATCH 105/190] Fixed final ACK the ack of 0 had already been acked, shouldn't ack any more --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 561d442b63..04fde89642 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1290,7 +1290,7 @@ Initial[1]: ACK[0] Handshake[0]: CRYPTO[FIN], ACK[0] 1-RTT[1]: STREAM[0, "..."] ACK[0] -> - 1-RTT[1]: STREAM[3, "..."], ACK[0,1] + 1-RTT[1]: STREAM[3, "..."], ACK[1] <- Handshake[1]: ACK[0] ~~~~ {: #tls-0rtt-handshake title="Example 0-RTT Handshake"} From 988f7b0bff4bb485875dce1093b3210793ac378c Mon Sep 17 00:00:00 2001 From: Mark Nottingham Date: Thu, 14 Feb 2019 17:35:23 +1100 Subject: [PATCH 106/190] typo --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3a869e093d..d3dfd4b5e6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -104,7 +104,7 @@ Only after that will the change be merged and the issue be closed. The drafts currently in the late stage are: * Invariants -* Transporrt +* Transporr * TLS From 4b8ee3091ea4f6dca009801d8b57c8eff602ff17 Mon Sep 17 00:00:00 2001 From: Mark Nottingham Date: Thu, 14 Feb 2019 17:42:00 +1100 Subject: [PATCH 107/190] yeah let's try that again. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d3dfd4b5e6..ff856b648c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -104,7 +104,7 @@ Only after that will the change be merged and the issue be closed. The drafts currently in the late stage are: * Invariants -* Transporr +* Transport * TLS From 10bf5e61b5b165d7bffadbd89a533d619fc8d361 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 14 Feb 2019 23:03:32 +0800 Subject: [PATCH 108/190] describe what happens when the PTO timer expires (#2455) * describe what happens when the PTO timer expires * Martin's suggestion Co-Authored-By: marten-seemann * Nick's suggestion --- draft-ietf-quic-recovery.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 199f2e2882..f057d39373 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -511,9 +511,10 @@ delay sending an acknowledgement. The PTO value MUST be set to at least kGranularity, to avoid the timer expiring immediately. -When a PTO timer expires, the PTO period MUST be set to twice its current value. -This exponential reduction in the sender's rate is important because the PTOs -might be caused by loss of packets or acknowledgements due to severe congestion. +When a PTO timer expires, the sender probes the network as described in the next +section. The PTO period MUST be set to twice its current value. This exponential +reduction in the sender's rate is important because the PTOs might be caused by +loss of packets or acknowledgements due to severe congestion. A sender computes its PTO timer every time an ack-eliciting packet is sent. A sender might choose to optimize this by setting the timer fewer times if it From 5a15b96470fee82bf047a21e6956f1a2b7adb9ce Mon Sep 17 00:00:00 2001 From: martinduke Date: Thu, 14 Feb 2019 15:50:41 -0800 Subject: [PATCH 109/190] Address Validation Nits Although not super-important, the biggest decision in here is that the packet number of the response to a RETRY is 1. Based on interop experience, I believe this is the semi-consensus of implementers. --- draft-ietf-quic-transport.md | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 40007ea60a..4f58cd0025 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1472,11 +1472,11 @@ is not overly constrained by the amplification restriction. Packet loss, in particular loss of a Handshake packet from the server, can cause a situation in which the server cannot send when the client has no data to send and the anti-amplification limit is reached. In order to avoid this causing a -handshake deadlock, clients SHOULD send a packet upon a handshake timeout, as -described in {{QUIC-RECOVERY}}. If the client has no data to retransmit and does -not have Handshake keys, it SHOULD send an Initial packet in a UDP datagram of -at least 1200 bytes. If the client has Handshake keys, it SHOULD send a -Handshake packet. +handshake deadlock, clients SHOULD send a packet upon a crypto retransmission +timeout, as described in {{QUIC-RECOVERY}}. If the client has no data to +retransmit and does not have Handshake keys, it SHOULD send an Initial packet in +a UDP datagram of at least 1200 bytes. If the client has Handshake keys, it +SHOULD send a Handshake packet. A server might wish to validate the client address before starting the cryptographic handshake. QUIC uses a token in the Initial packet to provide @@ -1494,9 +1494,10 @@ controller. Clients are only constrained by the congestion controller. Upon receiving the client's Initial packet, the server can request address validation by sending a Retry packet ({{packet-retry}}) containing a token. This -token MUST be repeated by the client in all Initial packets it sends after it -receives the Retry packet. In response to processing an Initial containing a -token, a server can either abort the connection or permit it to proceed. +token MUST be repeated by the client in all Initial packets it sends for that +connection after it receives the Retry packet. In response to processing an +Initial containing a token, a server can either abort the connection or permit +it to proceed. As long as it is not possible for an attacker to generate a valid token for its own address (see {{token-integrity}}) and the client is able to return @@ -1516,9 +1517,9 @@ Initial[0]: CRYPTO[CH] -> <- Retry+Token -Initial+Token[0]: CRYPTO[CH] -> +Initial+Token[1]: CRYPTO[CH] -> - Initial[0]: CRYPTO[SH] ACK[0] + Initial[0]: CRYPTO[SH] ACK[1] Handshake[0]: CRYPTO[EE, CERT, CV, FIN] <- 1-RTT[0]: STREAM[1, "..."] ~~~~ @@ -1536,10 +1537,10 @@ The server uses the NEW_TOKEN frame {{frame-new-token}} to provide the client with an address validation token that can be used to validate future connections. The client includes this token in Initial packets to provide address validation in a future connection. The client MUST include the token in -all Initial packets it sends, unless a Retry replaces the token with a newer -token. The client MUST NOT use the token provided in a Retry for future -connections. Servers MAY discard any Initial packet that does not carry the -expected token. +all Initial packets it sends, unless a Retry or NEW_TOKEN frame replaces the +token with a newer one. The client MUST NOT use the token provided in a Retry +for future connections. Servers MAY discard any Initial packet that does not +carry the expected token. Unlike the token that is created for a Retry packet, there might be some time between when the token is created and when the token is subsequently used. @@ -1549,8 +1550,8 @@ 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. -A token SHOULD be constructed to be easily distinguishable from tokens that are -sent in Retry packets as they are carried in the same field. +A token SHOULD be constructed for the server to easily distinguish it from +tokens that are sent in Retry packets as they are carried in the same field. If the client has a token received in a NEW_TOKEN frame on a previous connection to what it believes to be the same server, it SHOULD include that value in the @@ -1585,7 +1586,7 @@ Note: the packet is that the client might have received the token in a previous connection using the NEW_TOKEN frame, and if the server has lost state, it might be unable to validate the token at all, leading to connection failure if - the packet is discarded. A server MAY encode tokens provided with NEW_TOKEN + the packet is discarded. A server SHOULD encode tokens provided with NEW_TOKEN frames and Retry packets differently, and validate the latter more strictly. In a stateless design, a server can use encrypted and authenticated tokens to From e29d87232df0cb575a627f749a65e731a8aeb2ff Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 15 Feb 2019 11:01:35 +1100 Subject: [PATCH 110/190] wrap --- draft-ietf-quic-transport.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 4f58cd0025..694af255dd 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1586,8 +1586,9 @@ Note: the packet is that the client might have received the token in a previous connection using the NEW_TOKEN frame, and if the server has lost state, it might be unable to validate the token at all, leading to connection failure if - the packet is discarded. A server SHOULD encode tokens provided with NEW_TOKEN - frames and Retry packets differently, and validate the latter more strictly. + the packet is discarded. A server SHOULD encode tokens provided with + NEW_TOKEN frames and Retry packets differently, and validate the latter more + strictly. In a stateless design, a server can use encrypted and authenticated tokens to pass information to clients that the server can later recover and use to From 83793ef5f0c83635d9bface209af0c2f8d18bfd8 Mon Sep 17 00:00:00 2001 From: martinduke Date: Fri, 15 Feb 2019 06:56:13 -0800 Subject: [PATCH 111/190] Refer to "installing keys" instead of "rekeying" Per @mIkebishop's advice We're still a little stuck on whether or not QUIC provides a TLS record abstraction. If we can't resolve soon, I'll just separate out that change. --- draft-ietf-quic-tls.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 01f8144cd3..5986c8559e 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -500,28 +500,27 @@ Client Server Get Handshake Initial -------------> -Rekey tx to 0-RTT Keys +Install tx 0-RTT Keys 0-RTT ---------------> Handshake Received Get Handshake <------------- Initial - Rekey rx to 0-RTT keys - Rekey tx to Handshake keys + Install rx 0-RTT keys + Install Handshake keys Get Handshake <----------- Handshake - Rekey rx to Handshake keys - Rekey tx to 1-RTT keys + Install tx 1-RTT keys <--------------- 1-RTT Handshake Received -Rekey tx and rx to Handshake keys +Install tx Handshake keys Handshake Received Get Handshake Handshake Complete Handshake -----------> -Rekey tx and rx to 1-RTT keys +Install 1-RTT keys 1-RTT ---------------> Handshake Received - Rekey rx to 1-RTT keys + Install rx 1-RTT keys Handshake Complete Get Handshake <--------------- 1-RTT From 59f74c2da53986065a2db47cfea9a64330e19939 Mon Sep 17 00:00:00 2001 From: martinduke Date: Fri, 15 Feb 2019 09:40:17 -0800 Subject: [PATCH 112/190] Eliminate duplicate word typo --- draft-ietf-quic-transport.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 694af255dd..13e836c182 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2485,10 +2485,10 @@ specific to the transport, including all those described in this document, are carried the QUIC-specific variant of the CONNECTION_CLOSE frame. A CONNECTION_CLOSE frame could be sent in a packet that is lost. An endpoint -SHOULD be prepared to retransmit a packet containing containing a -CONNECTION_CLOSE frame if it receives more packets on a terminated connection. -Limiting the number of retransmissions and the time over which this final packet -is sent limits the effort expended on terminated connections. +SHOULD be prepared to retransmit a packet containing a CONNECTION_CLOSE frame if +it receives more packets on a terminated connection. Limiting the number of +retransmissions and the time over which this final packet is sent limits the +effort expended on terminated connections. An endpoint that chooses not to retransmit packets containing a CONNECTION_CLOSE frame risks a peer missing the first such packet. The only mechanism available @@ -2498,7 +2498,6 @@ use the stateless reset process ({{stateless-reset}}). An endpoint that receives an invalid CONNECTION_CLOSE frame MUST NOT signal the existence of the error to its peer. - ## Stream Errors If an application-level error affects a single stream, but otherwise leaves the From df865be876424549e7c9731b622255d38c39a077 Mon Sep 17 00:00:00 2001 From: martinduke Date: Fri, 15 Feb 2019 09:53:10 -0800 Subject: [PATCH 113/190] Packetization Nits The deleted parenthetical is not accurate, and is unnecessary: 0-RTT and 1-RTT with various key phases share a PN space without sharing keys. I prefer the MUST NOT in coalescing, but if there are objections I can revert it. --- draft-ietf-quic-transport.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 694af255dd..b67188475e 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2594,7 +2594,7 @@ MUST attempt to process the remaining packets. Retry packets ({{packet-retry}}), Version Negotiation packets ({{packet-version}}), and packets with a short header ({{short-header}}) do not -contain a Length field and so cannot be followed by other packets in the same +contain a Length field and so MUST NOT be followed by other packets in the same UDP datagram. @@ -2607,17 +2607,18 @@ maintains a separate packet number for sending and receiving. Packet numbers are limited to this range because they need to be representable in whole in the Largest Acknowledged field of an ACK frame ({{frame-ack}}). When present in a long or short header however, packet numbers are reduced and -encoded in 1 to 4 bytes, see {{packet-encoding}}). +encoded in 1 to 4 bytes (see {{packet-encoding}}). -Version Negotiation ({{packet-version}}) and Retry {{packet-retry}} packets do -not include a packet number. +Version Negotiation ({{packet-version}}) and Retry ({{packet-retry}}) packets +do not include a packet number. Packet numbers are divided into 3 spaces in QUIC: -- Initial space: All Initial packets {{packet-initial}} are in this space. -- Handshake space: All Handshake packets {{packet-handshake}} are in this space. +- Initial space: All Initial packets ({{packet-initial}}) are in this space. +- Handshake space: All Handshake packets ({{packet-handshake}}) are in this +space. - Application data space: All 0-RTT and 1-RTT encrypted packets - {{packet-protected}} are in this space. + ({{packet-protected}}) are in this space. As described in {{QUIC-TLS}}, each packet type uses different protection keys. @@ -2636,11 +2637,10 @@ the packet number by at least one. algorithms easier to implement between the two packet types. A QUIC endpoint MUST NOT reuse a packet number within the same packet number -space in one connection (that is, under the same cryptographic keys). If the -packet number for sending reaches 2^62 - 1, the sender MUST close the connection -without sending a CONNECTION_CLOSE frame or any further packets; an endpoint MAY -send a Stateless Reset ({{stateless-reset}}) in response to further packets that -it receives. +space in one connection. If the packet number for sending reaches 2^62 - 1, the +sender MUST close the connection without sending a CONNECTION_CLOSE frame or any +further packets; an endpoint MAY send a Stateless Reset ({{stateless-reset}}) in +response to further packets that it receives. A receiver MUST discard a newly unprotected packet unless it is certain that it has not processed another packet with the same packet number from the same From 406827459ab28fe105236b4280b86d3547c8ef15 Mon Sep 17 00:00:00 2001 From: martinduke Date: Fri, 15 Feb 2019 14:33:11 -0800 Subject: [PATCH 114/190] Reverting MUST NOT --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index b67188475e..b94ffc6593 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2594,7 +2594,7 @@ MUST attempt to process the remaining packets. Retry packets ({{packet-retry}}), Version Negotiation packets ({{packet-version}}), and packets with a short header ({{short-header}}) do not -contain a Length field and so MUST NOT be followed by other packets in the same +contain a Length field and so cannot be followed by other packets in the same UDP datagram. From 61d998987087752e17e8aec34651c64791e36aba Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 18 Feb 2019 04:34:29 +0900 Subject: [PATCH 115/190] Unrelated change --- draft-ietf-quic-transport.md | 1 + 1 file changed, 1 insertion(+) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 13e836c182..bcc3b1cfc0 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2498,6 +2498,7 @@ use the stateless reset process ({{stateless-reset}}). An endpoint that receives an invalid CONNECTION_CLOSE frame MUST NOT signal the existence of the error to its peer. + ## Stream Errors If an application-level error affects a single stream, but otherwise leaves the From 8420fe3891cc3f86f30bc90f5e6f787bc1fb9a2d Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Mon, 18 Feb 2019 13:46:31 +0900 Subject: [PATCH 116/190] fix incorrect field name --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index c7ae1b40da..e5abd255b5 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2317,7 +2317,7 @@ of bytes following it that are set to unpredictable values. The last 16 bytes of the datagram contain a Stateless Reset Token. A stateless reset will be interpreted by a recipient as a packet with a short -header. For the packet to appear as valid, the Random Bits field needs to +header. For the packet to appear as valid, the Unpredictable Bits field needs to include at least 182 bits of data (or 23 bytes, less the two fixed bits). This is intended to allow for a Destination Connection ID of the maximum length permitted, with a minimal packet number, and payload. The Stateless Reset Token From e805db0ae6a7a7523db338dee5632696cd1b7e40 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Sun, 17 Feb 2019 21:38:56 -0800 Subject: [PATCH 117/190] Wrap --- draft-ietf-quic-transport.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index e5abd255b5..b74b5f3b4f 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2317,9 +2317,9 @@ of bytes following it that are set to unpredictable values. The last 16 bytes of the datagram contain a Stateless Reset Token. A stateless reset will be interpreted by a recipient as a packet with a short -header. For the packet to appear as valid, the Unpredictable Bits field needs to -include at least 182 bits of data (or 23 bytes, less the two fixed bits). This -is intended to allow for a Destination Connection ID of the maximum length +header. For the packet to appear as valid, the Unpredictable Bits field needs +to include at least 182 bits of data (or 23 bytes, less the two fixed bits). +This is intended to allow for a Destination Connection ID of the maximum length permitted, with a minimal packet number, and payload. The Stateless Reset Token corresponds to the minimum expansion of the packet protection AEAD. More unpredictable bytes might be necessary if the endpoint could have negotiated a From f1707b40f2077f0d0ece7ee221222c8e15202878 Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Tue, 19 Feb 2019 11:29:04 -0500 Subject: [PATCH 118/190] Add #2302 to the list of items changed since ID-17 --- draft-ietf-quic-transport.md | 1 + 1 file changed, 1 insertion(+) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index b74b5f3b4f..e0807b51e5 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -5500,6 +5500,7 @@ Issue and pull request numbers are listed with a leading octothorp. - Set a maximum value for max_ack_delay transport parameter (#2282, #2301) - Allow server preferred address for both IPv4 and IPv6 (#2122, #2296) - Corrected requirements for migration to a preferred address (#2146, #2349) +- ACK of non-existent packet is illegal (#2298, #2302) ## Since draft-ietf-quic-transport-16 From dfc141920a7008059e37bfa9d6082611ee681f4b Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Tue, 19 Feb 2019 08:48:28 -0800 Subject: [PATCH 119/190] Fix PTO computation (#2480) --- draft-ietf-quic-recovery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index f057d39373..f7613f8cac 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -496,7 +496,7 @@ When an ack-eliciting packet is transmitted, the sender schedules a timer for the PTO period as follows: ~~~ -PTO = max(smoothed_rtt + 4*rttvar + max_ack_delay, kGranularity) +PTO = smoothed_rtt + max(4*rttvar, kGranularity) + max_ack_delay ~~~ kGranularity, smoothed_rtt, rttvar, and max_ack_delay are defined in From 4d20e6cef061b54a673987f1031c358d730a544d Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Tue, 19 Feb 2019 15:33:00 -0800 Subject: [PATCH 120/190] editorial reword --- draft-ietf-quic-recovery.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index cc9af15520..1451224381 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -412,9 +412,10 @@ is available, or if the network changes, the initial RTT SHOULD be set to 100ms. When an acknowledgement is received, a new RTT is computed and the timer SHOULD be set for twice the newly computed smoothed RTT. -Every time a crypto packet is sent, the sender MUST set a timer for the crypto -timeout period. Upon timeout, the sender MUST retransmit all unacknowledged -CRYPTO data if possible. +When a crypto packet is sent, the sender MUST set a timer for the crypto +timeout period. This timer MUST be updated when a new crypto packet is sent. +Upon timeout, the sender MUST retransmit all unacknowledged CRYPTO data if +possible. Until the server has validated the client's address on the path, the amount of data it can send is limited, as specified in {{QUIC-TRANSPORT}}. If not all From 1d963da48653f883864ff3238b35aed9f9674f4a Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 21 Feb 2019 11:14:32 +0800 Subject: [PATCH 121/190] add the pn_space index for largest_acked_packet --- draft-ietf-quic-recovery.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index d5857c9d41..d98d5c31d2 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -944,8 +944,8 @@ Pseudocode for OnAckReceived and UpdateRtt follow: ~~~ OnAckReceived(ack, pn_space): - largest_acked_packet[pn_space] = max(largest_acked_packet, - ack.largest_acked) + largest_acked_packet[pn_space] = + max(largest_acked_packet[pn_space], ack.largest_acked) // If the largest acknowledged is newly acked and // ack-eliciting, update the RTT. @@ -1123,10 +1123,10 @@ DetectLostPackets(pn_space): lost_send_time = now() - loss_delay // Packets with packet numbers before this are deemed lost. - lost_pn = largest_acked_packet - kPacketThreshold + lost_pn = largest_acked_packet[pn_space] - kPacketThreshold foreach unacked in sent_packets: - if (unacked.packet_number > largest_acked_packet): + if (unacked.packet_number > largest_acked_packet[pn_space]): continue // Mark packet as lost, or set time when it should be marked. From 0f9343bb1bace2205da6cba14ac20ea6e1c2f5b9 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Fri, 22 Feb 2019 11:16:06 +0900 Subject: [PATCH 122/190] Update draft-ietf-quic-transport.md Co-Authored-By: kazuho --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index e7ba232c29..55ecf07947 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -963,7 +963,7 @@ unused connection IDs. While each endpoint independently chooses how many connection IDs to issue, endpoints SHOULD provide and maintain at least eight connection IDs. The endpoint SHOULD do this by supplying a new connection ID when a connection ID is retired by its peer or when the endpoint receives a -packet with a previously unused connection ID, though it MAY limit the frequency +packet with a previously unused connection ID. However, it MAY limit the frequency or the total number of connection IDs issued for each connection to avoid the risk of running out of connection IDs (see {{reset-token}}). From d1759eba7ed116861a44d960461a606e73353c52 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Fri, 22 Feb 2019 11:16:17 +0900 Subject: [PATCH 123/190] Update draft-ietf-quic-transport.md Co-Authored-By: kazuho --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 55ecf07947..a6b762b2d3 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -967,7 +967,7 @@ packet with a previously unused connection ID. However, it MAY limit the freque or the total number of connection IDs issued for each connection to avoid the risk of running out of connection IDs (see {{reset-token}}). -Endpoints that initiate migration and require non-zero-length connection IDs +An endpoint that initiates migration and requires non-zero-length connection IDs SHOULD ensure that the pool of connection IDs available to their peers allows them to use a new connection ID on migration, as the peer will close the connection if the pool is exhausted. From b5c3945f5931aa1eba5db7b57033b6b6f43ab324 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Fri, 22 Feb 2019 11:16:25 +0900 Subject: [PATCH 124/190] Update draft-ietf-quic-transport.md Co-Authored-By: kazuho --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index a6b762b2d3..38aa6ef470 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -968,7 +968,7 @@ or the total number of connection IDs issued for each connection to avoid the risk of running out of connection IDs (see {{reset-token}}). An endpoint that initiates migration and requires non-zero-length connection IDs -SHOULD ensure that the pool of connection IDs available to their peers allows +SHOULD ensure that the pool of connection IDs available to its peer allows them to use a new connection ID on migration, as the peer will close the connection if the pool is exhausted. From 6efa27b7fb38316400cb767a2dbd7ae03c4bfcb9 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Fri, 22 Feb 2019 11:16:48 +0900 Subject: [PATCH 125/190] Update draft-ietf-quic-transport.md Co-Authored-By: kazuho --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 38aa6ef470..3e6198094d 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -969,7 +969,7 @@ risk of running out of connection IDs (see {{reset-token}}). An endpoint that initiates migration and requires non-zero-length connection IDs SHOULD ensure that the pool of connection IDs available to its peer allows -them to use a new connection ID on migration, as the peer will close the +the peer to use a new connection ID on migration, as the peer will close the connection if the pool is exhausted. From 24fddef652d8cae49c614e4fe634a7895c355021 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Fri, 22 Feb 2019 11:22:55 +0900 Subject: [PATCH 126/190] wordwrap --- draft-ietf-quic-transport.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 3e6198094d..bfb2cea3e3 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -963,13 +963,13 @@ unused connection IDs. While each endpoint independently chooses how many connection IDs to issue, endpoints SHOULD provide and maintain at least eight connection IDs. The endpoint SHOULD do this by supplying a new connection ID when a connection ID is retired by its peer or when the endpoint receives a -packet with a previously unused connection ID. However, it MAY limit the frequency -or the total number of connection IDs issued for each connection to avoid the -risk of running out of connection IDs (see {{reset-token}}). +packet with a previously unused connection ID. However, it MAY limit the +frequency or the total number of connection IDs issued for each connection to +avoid the risk of running out of connection IDs (see {{reset-token}}). An endpoint that initiates migration and requires non-zero-length connection IDs -SHOULD ensure that the pool of connection IDs available to its peer allows -the peer to use a new connection ID on migration, as the peer will close the +SHOULD ensure that the pool of connection IDs available to its peer allows the +peer to use a new connection ID on migration, as the peer will close the connection if the pool is exhausted. From 3453f54d7409bbc10615aba219808e1d0ebcb649 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Mon, 4 Feb 2019 14:32:00 +0530 Subject: [PATCH 127/190] Close connection if peer becomes unreachable --- draft-ietf-quic-transport.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index e0807b51e5..d940789321 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1765,6 +1765,11 @@ NAT rebinding is not connection migration as defined in this section, though an endpoint SHOULD perform path validation ({{migrate-validate}}) if it detects a change in the IP address of its peer. +When a client finds the server unreachable over any path, the client might close +its connection to the server (see {{termination}}). A client capable of +connection migration MAY wait for new paths to become available before declaring +the server unreachable. + This document limits migration of connections to new client addresses, except as described in {{preferred-address}}. Clients are responsible for initiating all migrations. Servers do not send non-probing packets (see {{probing}}) toward a @@ -2125,14 +2130,15 @@ UDP ports, destination CID, and a local secret. # Connection Termination {#termination} -Connections should remain open until they become idle for a pre-negotiated -period of time. A QUIC connection, once established, can be terminated in one -of three ways: +An established QUIC connection can be terminated in one of three ways: * idle timeout ({{idle-timeout}}) * immediate close ({{immediate-close}}) * stateless reset ({{stateless-reset}}) +In addition, an endpoint MAY drop a connection and discard all connection state +without informing the peer if it is unable to reach the peer. + ## Closing and Draining Connection States {#draining} From 7a4ad29ff77eaf72ee0ce0e6d0a77f06083ec7c6 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Thu, 21 Feb 2019 18:49:29 -0800 Subject: [PATCH 128/190] comments --- draft-ietf-quic-transport.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index d940789321..1ef65a4dd3 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1765,10 +1765,9 @@ NAT rebinding is not connection migration as defined in this section, though an endpoint SHOULD perform path validation ({{migrate-validate}}) if it detects a change in the IP address of its peer. -When a client finds the server unreachable over any path, the client might close -its connection to the server (see {{termination}}). A client capable of -connection migration MAY wait for new paths to become available before declaring -the server unreachable. +When an endpoint has no validated path on which to send packets, it MAY discard +connection state. An endpoint capable of connection migration MAY wait for a +new path to become available before discarding connection state. This document limits migration of connections to new client addresses, except as described in {{preferred-address}}. Clients are responsible for initiating all @@ -2136,8 +2135,8 @@ An established QUIC connection can be terminated in one of three ways: * immediate close ({{immediate-close}}) * stateless reset ({{stateless-reset}}) -In addition, an endpoint MAY drop a connection and discard all connection state -without informing the peer if it is unable to reach the peer. +An endpoint MAY discard connection state if it does not have a validated path on +which it can send packets (see {{migrate-validate}}). ## Closing and Draining Connection States {#draining} From 51cfe3c3ba82ba397a9d8bbb013a1677fbda1796 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Sat, 23 Feb 2019 19:36:59 -0800 Subject: [PATCH 129/190] applications or protocols Reverse the two for readability. Co-Authored-By: martinthomson --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index d169b7bff9..b2563aa7ae 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2212,7 +2212,7 @@ period of a peer risks having those packets discarded if its peer enters the draining state before the packets arrive. If a peer could timeout within an Probe Timeout (PTO, see Section 6.2.2 of {{QUIC-RECOVERY}}), it is advisable to test for liveness before sending any data that cannot be retried safely. Note -that it is likely that only application protocols or using applications will +that it is likely that only applications or application protocols will know what information can be retried. From 46db3de1501a93a7e0954e0030124cf9849e0e5a Mon Sep 17 00:00:00 2001 From: Nick Banks Date: Mon, 25 Feb 2019 08:45:04 -0800 Subject: [PATCH 130/190] Persistent Congestion Time Threshold (#2365) * Persistent Congestion Time Threshold * Some of Ian's comments * mikkelfj's suggestion Co-Authored-By: nibanks * mikkelfj's suggestion Co-Authored-By: nibanks * Jana's offline suggestions * tab to spaces * Ian's suggestion * Ian's suggestion Co-Authored-By: nibanks * More of Ian's suggestions * Fix build error * Ian's suggestion Co-Authored-By: nibanks * Ian's suggestion Co-Authored-By: nibanks * Ian's suggestion Co-Authored-By: nibanks * More of Ian's suggestions * Ian's suggestion Co-Authored-By: nibanks * Ian's suggestions * Ian's suggestion Co-Authored-By: nibanks * slight redesign and example * forgot to hit save first... * whitespace removal * editorial nits * another nit * Ian's suggestion Co-Authored-By: nibanks * Marten's suggestion * Jana's suggestions * Change back to largest_lost_packet --- draft-ietf-quic-recovery.md | 66 +++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index d98d5c31d2..e7ec4fe6a7 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -652,14 +652,50 @@ packets might cause the sender's bytes in flight to exceed the congestion window until an acknowledgement is received that establishes loss or delivery of packets. +## Persistent Congestion + When an ACK frame is received that establishes loss of all in-flight packets -sent prior to a threshold number of consecutive PTOs (pto_count is more than -kPersistentCongestionThreshold, see {{cc-consts-of-interest}}), the network is -considered to be experiencing persistent congestion, and the sender's congestion -window MUST be reduced to the minimum congestion window (kMinimumWindow). This -response of collapsing the congestion window on persistent congestion is -functionally similar to a sender's response on a Retransmission Timeout (RTO) in -TCP {{RFC5681}}. +sent over a long enough period of time, the network is considered to be +experiencing persistent congestion. Commonly, this can be established by +consecutive PTOs, but since the PTO timer is reset when a new ack-eliciting +packet is sent, an explicit duration must be used to account for those cases +where PTOs do not occur or are substantially delayed. This duration is the +equivalent of kPersistentCongestionThreshold consecutive PTOs, and is computed +as follows: +~~~ +(smoothed_rtt + 4 * rttvar + max_ack_delay) * + ((2 ^ kPersistentCongestionThreshold) - 1) +~~~ + +For example, assume: + + smoothed_rtt = 1 + rttvar = 0 + max_ack_delay = 0 + kPersistentCongestionThreshold = 2 + +If an eck-eliciting packet is sent at time = 0, the following scenario would +illustrate persistent congestion: + + t=0 | Send Pkt #1 (App Data) + t=1 | Send Pkt #2 (PTO 1) + t=3 | Send Pkt #3 (PTO 2) + t=7 | Send Pkt #4 (PTO 3) + t=8 | Recv ACK of Pkt #4 + +The first three packets are determined to be lost when the ACK of packet 4 is +received at t=8. The congestion period is calculated as the time between the +oldest and newest lost packets: (3 - 0) = 3. The duration for persistent +congestion is equal to: (1 * ((2 ^ kPersistentCongestionThreshold) - 1)) = 3. +Because the threshold was reached and because none of the packets between the +oldest and the newest packets are acknowledged, the network is considered to +have experienced persistent congestion. + +When persistent congestion is established, the sender's congestion window MUST +be reduced to the minimum congestion window (kMinimumWindow). This response of +collapsing the congestion window on persistent congestion is functionally +similar to a sender's response on a Retransmission Timeout (RTO) in TCP +{{RFC5681}} after Tail Loss Probes (TLP) {{TLP}}. ## Pacing {#pacing} @@ -1288,9 +1324,6 @@ window. congestion_window *= kLossReductionFactor congestion_window = max(congestion_window, kMinimumWindow) ssthresh = congestion_window - // Collapse congestion window if persistent congestion - if (pto_count > kPersistentCongestionThreshold): - congestion_window = kMinimumWindow ~~~ @@ -1317,6 +1350,15 @@ Invoked by loss detection from DetectLostPackets when new packets are detected lost. ~~~ + InPersistentCongestion(largest_lost_packet): + pto = smoothed_rtt + 4 * rttvar + max_ack_delay + congestion_period = + pto * (2 ^ kPersistentCongestionThreshold - 1) + // Determine if all packets in the window before the + // newest lost packet, including the edges, are marked + // lost + return IsWindowLost(largest_lost_packet, congestion_period) + OnPacketsLost(lost_packets): // Remove lost packets from bytes_in_flight. for (lost_packet : lost_packets): @@ -1326,6 +1368,10 @@ are detected lost. // Start a new congestion epoch if the last lost packet // is past the end of the previous recovery epoch. CongestionEvent(largest_lost_packet.time_sent) + + // Collapse congestion window if persistent congestion + if (InPersistentCongestion(largest_lost_packet)): + congestion_window = kMinimumWindow ~~~ From 5dd4eb2fdd0773ec59d84fd348e308ccbdebf903 Mon Sep 17 00:00:00 2001 From: Lucas Pardue Date: Fri, 15 Feb 2019 00:33:42 +0000 Subject: [PATCH 131/190] Fix inconsistent leading zeros Simply making this consistent through the document by doing the minimal change and removing leading 0s. Happy to add them if we prefer. --- draft-ietf-quic-http.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 0a206d50cb..7587565f2a 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -495,7 +495,7 @@ HEADERS frames can only be sent on request / push streams. ### PRIORITY {#frame-priority} -The PRIORITY (type=0x02) frame specifies the client-advised priority of a +The PRIORITY (type=0x2) frame specifies the client-advised priority of a request, server push or placeholder. A PRIORITY frame identifies an element to prioritize, and an element upon which @@ -747,7 +747,7 @@ with its 0-RTT data. ### PUSH_PROMISE {#frame-push-promise} -The PUSH_PROMISE frame (type=0x05) is used to carry a promised request header +The PUSH_PROMISE frame (type=0x5) is used to carry a promised request header set from server to client on a request stream, as in HTTP/2. ~~~~~~~~~~ drawing From 8599157ea22332605b283f2b807dfa87bbd496a3 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Mon, 25 Feb 2019 10:29:26 -0800 Subject: [PATCH 132/190] Rework GOAWAY text (again) (#2457) * Rework GOAWAY text (again) * Un-although * Restate "complete successfully" * Jana's suggestions --- draft-ietf-quic-http.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 7587565f2a..597b127df6 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1259,21 +1259,22 @@ identified by a QUIC MAX_STREAM_ID frame, and MAY be zero if no requests were processed. Servers SHOULD NOT increase the QUIC MAX_STREAM_ID limit after sending a GOAWAY frame. -Once GOAWAY is sent, the server MUST reject requests sent on streams with an -identifier greater than or equal to the indicated last Stream ID. Clients MUST -NOT send new requests on the connection after receiving GOAWAY, although -requests might already be in transit. A new connection can be established for -new requests. - -If the client has sent requests on streams with a Stream ID greater than or -equal to that indicated in the GOAWAY frame, those requests are considered -rejected ({{request-cancellation}}). Clients SHOULD cancel any requests on -streams above this ID. Servers MAY also reject requests on streams below the -indicated ID if these requests were not processed. +Clients MUST NOT send new requests on the connection after receiving GOAWAY; +a new connection MAY be established to send additional requests. + +Some requests might already be in transit. If the client has already sent +requests on streams with a Stream ID greater than or equal to that indicated in +the GOAWAY frame, those requests will not be processed and MAY be retried by the +client on a different connection. The client MAY cancel these requests. It is +RECOMMENDED that the server explicitly reject such requests (see +{{request-cancellation}}) in order to clean up transport state for the affected +streams. Requests on Stream IDs less than the Stream ID in the GOAWAY frame might have -been processed; their status cannot be known until they are completed -successfully, reset individually, or the connection terminates. +been processed; their status cannot be known until a response is received, the +stream is reset individually, or the connection terminates. Servers MAY reject +individual requests on streams below the indicated ID if these requests were not +processed. Servers SHOULD send a GOAWAY frame when the closing of a connection is known in advance, even if the advance notice is small, so that the remote peer can From cd3d1c18774fd6ad72a34372ff5de0ad71b2e935 Mon Sep 17 00:00:00 2001 From: Mike Bishop Date: Wed, 27 Feb 2019 10:25:55 -0800 Subject: [PATCH 133/190] Changelog catchup --- draft-ietf-quic-http.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 597b127df6..a5770f35ed 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1950,13 +1950,23 @@ Error codes need to be defined for HTTP/2 and HTTP/3 separately. See > **RFC Editor's Note:** Please remove this section prior to publication of a > final version of this document. +## Since draft-ietf-quic-http-18 + +- Resetting streams following a GOAWAY is recommended, but not required + (#2256,#2457) +- Use variable-length integers throughout (#2437,#2233,#2253,#2275) + - Variable-length frame types, stream types, and settings identifiers + - Renumbered stream type assignments + - Modified associated reserved values +- Frame layout switched from Length-Type-Value to Type-Length-Value + (#2395,#2235) + ## Since draft-ietf-quic-http-17 - HTTP_REQUEST_REJECTED is used to indicate a request can be retried (#2106, #2325) - Changed error code for GOAWAY on the wrong stream (#2231, #2343) - ## Since draft-ietf-quic-http-16 - Rename "HTTP/QUIC" to "HTTP/3" (#1973) @@ -1972,7 +1982,6 @@ Error codes need to be defined for HTTP/2 and HTTP/3 separately. See (#1922) - Removed prohibition of zero-length DATA frames (#2098) - ## Since draft-ietf-quic-http-15 Substantial editorial reorganization; no technical changes. From 741c13ca04f9fa0c939d391f1d2e2cec1c695a2b Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Thu, 28 Feb 2019 13:39:52 +0000 Subject: [PATCH 134/190] Fix PTO calculation in pseudo-code (#2489) --- draft-ietf-quic-recovery.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index e7ec4fe6a7..37779c76de 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1103,8 +1103,7 @@ SetLossDetectionTimer(): // Calculate PTO duration timeout = - smoothed_rtt + 4 * rttvar + max_ack_delay - timeout = max(timeout, kGranularity) + smoothed_rtt + max(4 * rttvar, kGranularity) + max_ack_delay timeout = timeout * (2 ^ pto_count) loss_detection_timer.update( From 7cb406602d5c1b8f1d50cc2c0cc2d04ef42cfa24 Mon Sep 17 00:00:00 2001 From: ianswett Date: Thu, 28 Feb 2019 08:41:15 -0500 Subject: [PATCH 135/190] Use kGranularity in InPersistentCongestion() --- draft-ietf-quic-recovery.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 37779c76de..89dc7fdf74 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1350,7 +1350,7 @@ are detected lost. ~~~ InPersistentCongestion(largest_lost_packet): - pto = smoothed_rtt + 4 * rttvar + max_ack_delay + pto = smoothed_rtt + max(4 * rttvar, kGranularity) + max_ack_delay congestion_period = pto * (2 ^ kPersistentCongestionThreshold - 1) // Determine if all packets in the window before the From 0bb9a5c49be458919f53c771515c7dbf0fb82637 Mon Sep 17 00:00:00 2001 From: ianswett Date: Thu, 28 Feb 2019 09:19:36 -0500 Subject: [PATCH 136/190] Update draft-ietf-quic-recovery.md --- draft-ietf-quic-recovery.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 89dc7fdf74..b90658da86 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1350,7 +1350,8 @@ are detected lost. ~~~ InPersistentCongestion(largest_lost_packet): - pto = smoothed_rtt + max(4 * rttvar, kGranularity) + max_ack_delay + pto = smoothed_rtt + max(4 * rttvar, kGranularity) + + max_ack_delay congestion_period = pto * (2 ^ kPersistentCongestionThreshold - 1) // Determine if all packets in the window before the From 27360d28ddec90726dc0a6872c394a1e239064a5 Mon Sep 17 00:00:00 2001 From: ianswett Date: Sun, 3 Mar 2019 12:50:02 -0500 Subject: [PATCH 137/190] Limit Initial Window to 14720 bytes Fix #2491 --- draft-ietf-quic-recovery.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 37779c76de..3f4c092fd2 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1202,8 +1202,9 @@ kMaxDatagramSize: kInitialWindow: : Default limit on the initial amount of data in flight, in bytes. Taken from - {{?RFC6928}}. The RECOMMENDED value is the minimum of 10 * kMaxDatagramSize - and max(2* kMaxDatagramSize, 14600)). + {{?RFC6928}}, but increased slightly to account for the smaller 8 byte + overhead of UDP vs 20 bytes for TCP. The RECOMMENDED value is the minimum + of 10 * kMaxDatagramSize and max(2* kMaxDatagramSize, 14720)). kMinimumWindow: : Minimum congestion window in bytes. The RECOMMENDED value is From 8a324cf402b7b341f8b518a41a0bcaafc046bd46 Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Wed, 20 Feb 2019 13:56:53 +0000 Subject: [PATCH 138/190] Clarify what to do when ALPN negotiation fails --- draft-ietf-quic-tls.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index c30176664a..c31848df75 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1216,7 +1216,8 @@ negotiation. TLS uses Application Layer Protocol Negotiation (ALPN) {{!RFC7301}} to select an application protocol. Unless another mechanism is used for agreeing on an application protocol, endpoints MUST use ALPN for this purpose. When using ALPN, endpoints MUST abort a connection if an application -protocol is not negotiated. +protocol is not negotiated with a no_application_protocol alert (as per +{{!RFC7301}}). An application-layer protocol MAY restrict the QUIC versions that it can operate over. Servers MUST select an application protocol compatible with the QUIC From da213ba2a19b3f09c0920b054aafc5a809b826b6 Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Wed, 27 Feb 2019 17:19:22 +0000 Subject: [PATCH 139/190] Clarify that no_application_protocol must also be used by clients --- draft-ietf-quic-tls.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index c31848df75..bd0a03bada 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1216,8 +1216,9 @@ negotiation. TLS uses Application Layer Protocol Negotiation (ALPN) {{!RFC7301}} to select an application protocol. Unless another mechanism is used for agreeing on an application protocol, endpoints MUST use ALPN for this purpose. When using ALPN, endpoints MUST abort a connection if an application -protocol is not negotiated with a no_application_protocol alert (as per -{{!RFC7301}}). +protocol is not negotiated with a no_application_protocol alert. While +{{!RFC7301}} only specifies that servers use this alert, QUIC clients MUST also +use it to terminate a connection when ALPN negotiation fails. An application-layer protocol MAY restrict the QUIC versions that it can operate over. Servers MUST select an application protocol compatible with the QUIC From 7fc379f00624b1f436f3c5a4275c3793c3d0a6a7 Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Mon, 4 Mar 2019 15:22:40 +0000 Subject: [PATCH 140/190] Specify error code for no_application_protocol --- draft-ietf-quic-tls.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index bd0a03bada..071bb47a90 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1216,9 +1216,9 @@ negotiation. TLS uses Application Layer Protocol Negotiation (ALPN) {{!RFC7301}} to select an application protocol. Unless another mechanism is used for agreeing on an application protocol, endpoints MUST use ALPN for this purpose. When using ALPN, endpoints MUST abort a connection if an application -protocol is not negotiated with a no_application_protocol alert. While -{{!RFC7301}} only specifies that servers use this alert, QUIC clients MUST also -use it to terminate a connection when ALPN negotiation fails. +protocol is not negotiated with a no_application_protocol alert (error code +0x178). While {{!RFC7301}} only specifies that servers use this alert, QUIC +clients MUST also use it to terminate a connection when ALPN negotiation fails. An application-layer protocol MAY restrict the QUIC versions that it can operate over. Servers MUST select an application protocol compatible with the QUIC From 4edeb3a5c323b54d37302749fdc2156d6a172332 Mon Sep 17 00:00:00 2001 From: ianswett Date: Tue, 5 Mar 2019 17:42:16 -0500 Subject: [PATCH 141/190] Close the connection if MAX_STREAMS is too large Fixes #2487 --- draft-ietf-quic-transport.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index b14d13ed02..a5d366bfb1 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -849,7 +849,10 @@ initial_stream_id_for_type) can be opened (see {{long-packet-types}}). Initial limits are set in the transport parameters (see {{transport-parameter-definitions}}) and subsequently limits are advertised using MAX_STREAMS frames ({{frame-max-streams}}). Separate limits apply to -unidirectional and bidirectional streams. +unidirectional and bidirectional streams. When a MAX_STREAMS frame is received +that permits more streams than can be expressed by the stream ID +(i.e. greater than 2^60 - 1), the connection MUST be immediately closed with a +connection error of type STREAM_LIMIT_ERROR (see {{immediate-close}}). Endpoints MUST NOT exceed the limit set by their peer. An endpoint that receives a STREAM frame with a stream ID exceeding the limit it has sent MUST From ec689a0e70809c53a887ffd4a8cd22de8fa68882 Mon Sep 17 00:00:00 2001 From: martinduke Date: Mon, 4 Mar 2019 16:37:33 -0800 Subject: [PATCH 142/190] Change error code for DUPLICATE_PUSH I believe UNEXPECTED_FRAME is the preferred type. --- draft-ietf-quic-http.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index a5770f35ed..8a3cffa48e 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -861,7 +861,7 @@ DUPLICATE_PUSH frame on any other stream MUST be treated as a connection error of type HTTP_WRONG_STREAM. A client MUST NOT send a DUPLICATE_PUSH frame. A server MUST treat the receipt -of a DUPLICATE_PUSH frame as a connection error of type HTTP_MALFORMED_FRAME. +of a DUPLICATE_PUSH frame as a connection error of type HTTP_UNEXPECTED_FRAME. ~~~~~~~~~~ drawing 0 1 2 3 From e03aa6b5caf2644e813c4412d2cfe162b72e7134 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Thu, 7 Mar 2019 12:21:12 +1100 Subject: [PATCH 143/190] Taking Mikkel's review/suggestions into account, trimming, adding --- draft-ietf-quic-tls.md | 58 ++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 892b6fd22e..a4d4199650 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1290,40 +1290,38 @@ Endpoints MUST implement and use the replay protections described in {{!TLS13}}, however it is recognized that these protections are imperfect. Therefore, additional consideration of the risk of replay are needed. -QUIC is not inherently vulnerable to replay attack. The management of QUIC -protocol state based on the frame types defined in {{QUIC-TRANSPORT}} is not -vulnerable to replay. Processing of QUIC frames is idempotent and cannot result -in invalid connection states if frames are reordered or lost. QUIC connections -do not produce effects that last beyond the lifetime of the connection, except -for those produced by the application protocol that QUIC serves. - -However, this does not count for costs that endpoints might incur as a result of -accepting 0-RTT. A server that accepts 0-RTT is exposed to the cost of handling -a new connection, plus the cost of processing 0-RTT packets. If replay -protections are unable to prevent multiple connections from being initiated, -this could increase these costs because attackers can send copies of 0-RTT -packets to different server instances, causing the processing to be repeated. -Servers MUST ensure that they account for any increase in costs before accepting -connections or 0-RTT. +QUIC is not vulnerable to replay attack, except via the application protocol +information it might carry. The management of QUIC protocol state based on the +frame types defined in {{QUIC-TRANSPORT}} is not vulnerable to replay. +Processing of QUIC frames is idempotent and cannot result in invalid connection +states if frames are replayed, reordered or lost. QUIC connections do not +produce effects that last beyond the lifetime of the connection, except for +those produced by the application protocol that QUIC serves. + +Note: + +: TLS session tickets and address validation tokens are used to carry QUIC + configuration information between connections. These MUST NOT be used to + carry application state. The potential for reuse of these tokens means that + they require stronger protections against replay. + +A server that accepts 0-RTT on a connection incurs a higher cost than accepting +a connection without 0-RTT. This includes higher processing and computation +costs. Servers need to consider the probability of replay and all associated +costs when accepting 0-RTT. Ultimately, the responsibility for managing the risks of replay attacks with 0-RTT lies with an application protocol. An application protocol that uses QUIC MUST describe how the protocol uses 0-RTT and the measures that are employed to -protect against replay attack. Disabling 0-RTT entirely is the most effective -strategy. - -In the core protocol, particular attention needs to be paid to STREAM frames, -which carry application data. If another frame type carries, or could carry, -application semantics, then the risk from replay attack needs to be considered. -For instance, though this is likely to be inadvisable, an application that -attaches semantics to increases in flow control credit or stream cancellation -would need to assess whether those uses were vulnerable to replay attack. - -Extensions to QUIC might create an additional exposure to replay attack if they -are used by application protocols. QUIC extensions SHOULD describe how replay -attacks affects their operation. Application protocols MUST either prohibit the -use of any extensions that carry application semantics in 0-RTT or provide -replay mitigation strategies. +protect against replay attack. An analysis of replay risk needs to consider +all QUIC protocol features carry application semantics. + +Disabling 0-RTT entirely is the most effective defense against replay attack. + +QUIC extensions MUST describe how replay attacks affects their operation, or +prohibit their use in 0-RTT. Application protocols MUST either prohibit the use +of extensions that carry application semantics in 0-RTT or provide replay +mitigation strategies. ## Packet Reflection Attack Mitigation {#reflection} From b737e89ad4ed987984ece6b296c484eb0f8af06b Mon Sep 17 00:00:00 2001 From: ianswett Date: Thu, 7 Mar 2019 14:13:45 -0500 Subject: [PATCH 144/190] Martin/Kazuho's suggestion --- draft-ietf-quic-transport.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index a5d366bfb1..75aa886092 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -849,10 +849,12 @@ initial_stream_id_for_type) can be opened (see {{long-packet-types}}). Initial limits are set in the transport parameters (see {{transport-parameter-definitions}}) and subsequently limits are advertised using MAX_STREAMS frames ({{frame-max-streams}}). Separate limits apply to -unidirectional and bidirectional streams. When a MAX_STREAMS frame is received -that permits more streams than can be expressed by the stream ID -(i.e. greater than 2^60 - 1), the connection MUST be immediately closed with a -connection error of type STREAM_LIMIT_ERROR (see {{immediate-close}}). +unidirectional and bidirectional streams. + +If a max_streams transport parameter or MAX_STREAMS frame carries a value +greater than 2^60, which implies a maximum stream ID that cannot be expressed, +then the connection MUST be immediately closed with a connection error of +type STREAM_LIMIT_ERROR (see {{immediate-close}}). Endpoints MUST NOT exceed the limit set by their peer. An endpoint that receives a STREAM frame with a stream ID exceeding the limit it has sent MUST From fc64707b237c37fee03e21caabb256d30ace5074 Mon Sep 17 00:00:00 2001 From: ianswett Date: Thu, 7 Mar 2019 14:22:45 -0500 Subject: [PATCH 145/190] Update draft-ietf-quic-transport.md --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 75aa886092..f6fca6072e 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -849,7 +849,7 @@ initial_stream_id_for_type) can be opened (see {{long-packet-types}}). Initial limits are set in the transport parameters (see {{transport-parameter-definitions}}) and subsequently limits are advertised using MAX_STREAMS frames ({{frame-max-streams}}). Separate limits apply to -unidirectional and bidirectional streams. +unidirectional and bidirectional streams. If a max_streams transport parameter or MAX_STREAMS frame carries a value greater than 2^60, which implies a maximum stream ID that cannot be expressed, From 01d76802c343bea31b1d8428e8558b5722973d86 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Thu, 7 Mar 2019 17:20:28 -0500 Subject: [PATCH 146/190] Update draft-ietf-quic-transport.md Co-Authored-By: ianswett --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index f6fca6072e..20ea3e984e 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -851,7 +851,7 @@ limits are set in the transport parameters (see using MAX_STREAMS frames ({{frame-max-streams}}). Separate limits apply to unidirectional and bidirectional streams. -If a max_streams transport parameter or MAX_STREAMS frame carries a value +If a max_streams transport parameter or MAX_STREAMS frame is received with a value greater than 2^60, which implies a maximum stream ID that cannot be expressed, then the connection MUST be immediately closed with a connection error of type STREAM_LIMIT_ERROR (see {{immediate-close}}). From 74c725afef91dc3dfeb659751d3512d07f7558aa Mon Sep 17 00:00:00 2001 From: ianswett Date: Thu, 7 Mar 2019 17:21:49 -0500 Subject: [PATCH 147/190] Update draft-ietf-quic-transport.md --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 20ea3e984e..6157ab0776 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -852,7 +852,7 @@ using MAX_STREAMS frames ({{frame-max-streams}}). Separate limits apply to unidirectional and bidirectional streams. If a max_streams transport parameter or MAX_STREAMS frame is received with a value -greater than 2^60, which implies a maximum stream ID that cannot be expressed, +greater than 2^60, allowing a maximum stream ID that cannot be expressed, then the connection MUST be immediately closed with a connection error of type STREAM_LIMIT_ERROR (see {{immediate-close}}). From 1ecbbea933dd4f4d382523f6d51e7e145576a5b9 Mon Sep 17 00:00:00 2001 From: ianswett Date: Thu, 7 Mar 2019 17:24:49 -0500 Subject: [PATCH 148/190] Update draft-ietf-quic-transport.md --- 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 6157ab0776..445ac732b0 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -851,8 +851,8 @@ limits are set in the transport parameters (see using MAX_STREAMS frames ({{frame-max-streams}}). Separate limits apply to unidirectional and bidirectional streams. -If a max_streams transport parameter or MAX_STREAMS frame is received with a value -greater than 2^60, allowing a maximum stream ID that cannot be expressed, +If a max_streams transport parameter or MAX_STREAMS frame is received with a +value greater than 2^60, allowing a maximum stream ID that cannot be expressed, then the connection MUST be immediately closed with a connection error of type STREAM_LIMIT_ERROR (see {{immediate-close}}). From 0a7ac9f173420f081d2bd773d9943d2929cf3ff7 Mon Sep 17 00:00:00 2001 From: ianswett Date: Thu, 7 Mar 2019 19:05:53 -0500 Subject: [PATCH 149/190] Jana's suggestion --- draft-ietf-quic-transport.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 445ac732b0..cc9c4656bf 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -852,9 +852,10 @@ using MAX_STREAMS frames ({{frame-max-streams}}). Separate limits apply to unidirectional and bidirectional streams. If a max_streams transport parameter or MAX_STREAMS frame is received with a -value greater than 2^60, allowing a maximum stream ID that cannot be expressed, -then the connection MUST be immediately closed with a connection error of -type STREAM_LIMIT_ERROR (see {{immediate-close}}). +value greater than 2^60, this allows a maximum stream ID that cannot be +expressed as a variable-length integer (see {{integer-encoding}}). +If either is received, the connection MUST be immediately closed with a +connection error of type STREAM_LIMIT_ERROR (see {{immediate-close}}). Endpoints MUST NOT exceed the limit set by their peer. An endpoint that receives a STREAM frame with a stream ID exceeding the limit it has sent MUST From 3b3a20ffee013668fd77b5dc83004782e41f2746 Mon Sep 17 00:00:00 2001 From: martinduke Date: Fri, 8 Mar 2019 13:10:26 -0800 Subject: [PATCH 150/190] Change illegal PRIORITY frame to a conn error Fixes #2507. --- draft-ietf-quic-http.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 8a3cffa48e..8d8fc6910a 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -603,8 +603,8 @@ to open MUST be treated as an HTTP_LIMIT_EXCEEDED error. A PRIORITY frame received on any stream other than a request or control stream MUST be treated as a connection error of type HTTP_WRONG_STREAM. -PRIORITY frames received by a client MUST be treated as a stream error of type -HTTP_UNEXPECTED_FRAME. +PRIORITY frames received by a client MUST be treated as a connection error of +type HTTP_UNEXPECTED_FRAME. ### CANCEL_PUSH {#frame-cancel-push} From 8ecbcb2799a9ed27844b476c098328897a334ca3 Mon Sep 17 00:00:00 2001 From: ianswett Date: Sat, 9 Mar 2019 04:28:28 -0500 Subject: [PATCH 151/190] Mike's suggestion --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index cc9c4656bf..7ab0972ac9 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -854,7 +854,7 @@ unidirectional and bidirectional streams. If a max_streams transport parameter or MAX_STREAMS frame is received with a value greater than 2^60, this allows a maximum stream ID that cannot be expressed as a variable-length integer (see {{integer-encoding}}). -If either is received, the connection MUST be immediately closed with a +If either is received, the connection MUST be closed immediately with a connection error of type STREAM_LIMIT_ERROR (see {{immediate-close}}). Endpoints MUST NOT exceed the limit set by their peer. An endpoint that From e5ca7387db8a6eac53d655304dc4be07673c8d1e Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 11 Mar 2019 09:47:27 +1100 Subject: [PATCH 152/190] Editorial tweaks --- draft-ietf-quic-tls.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index a4d4199650..36ecd6ea9c 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1288,7 +1288,7 @@ replay attack. Endpoints MUST implement and use the replay protections described in {{!TLS13}}, however it is recognized that these protections are imperfect. Therefore, -additional consideration of the risk of replay are needed. +additional consideration of the risk of replay is needed. QUIC is not vulnerable to replay attack, except via the application protocol information it might carry. The management of QUIC protocol state based on the @@ -1302,8 +1302,8 @@ Note: : TLS session tickets and address validation tokens are used to carry QUIC configuration information between connections. These MUST NOT be used to - carry application state. The potential for reuse of these tokens means that - they require stronger protections against replay. + carry application semantics. The potential for reuse of these tokens means + that they require stronger protections against replay. A server that accepts 0-RTT on a connection incurs a higher cost than accepting a connection without 0-RTT. This includes higher processing and computation @@ -1314,7 +1314,7 @@ Ultimately, the responsibility for managing the risks of replay attacks with 0-RTT lies with an application protocol. An application protocol that uses QUIC MUST describe how the protocol uses 0-RTT and the measures that are employed to protect against replay attack. An analysis of replay risk needs to consider -all QUIC protocol features carry application semantics. +all QUIC protocol features that carry application semantics. Disabling 0-RTT entirely is the most effective defense against replay attack. From 0d863091bd45ff90606a21388cd61fa5ba36e98c Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 11 Mar 2019 15:11:13 +1100 Subject: [PATCH 153/190] Remove CERT/CV from 0-RTT example, closes #2505 --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index b14d13ed02..0cbf14ef54 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1287,7 +1287,7 @@ Initial[0]: CRYPTO[CH] 0-RTT[0]: STREAM[0, "..."] -> Initial[0]: CRYPTO[SH] ACK[0] - Handshake[0] CRYPTO[EE, CERT, CV, FIN] + Handshake[0] CRYPTO[EE, FIN] <- 1-RTT[0]: STREAM[1, "..."] ACK[0] Initial[1]: ACK[0] From 28ec88eb67ccdd96adaed1ea078693a999a8993e Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 11 Mar 2019 15:24:47 +1100 Subject: [PATCH 154/190] Application errors can be used in STOP_SENDING Closes #2513. --- 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 0cbf14ef54..3b2c274a6b 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -5127,8 +5127,8 @@ See {{iana-error-codes}} for details of registering new error codes. Application protocol error codes are 16-bit unsigned integers, but the management of application error codes are left to application protocols. Application protocol error codes are used for the RESET_STREAM frame -({{frame-reset-stream}}) and the CONNECTION_CLOSE frame with a type of 0x1d -({{frame-connection-close}}). +({{frame-reset-stream}}), the STOP_SENDING frame ({{frame-stop-sending}}), and +the CONNECTION_CLOSE frame with a type of 0x1d ({{frame-connection-close}}). # Security Considerations From 32dcf40597acf9be31400cb6abe395acc6f47a3e Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 11 Mar 2019 17:01:46 +1100 Subject: [PATCH 155/190] Changes for -transport and -tls --- draft-ietf-quic-tls.md | 5 +++++ draft-ietf-quic-transport.md | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index c30176664a..176a5171da 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1600,6 +1600,11 @@ cb54df7884 Issue and pull request numbers are listed with a leading octothorp. +## Since draft-ietf-quic-tls-18 + +- Increased the set of permissible frames in 0-RTT (#2344, #2355) + + ## Since draft-ietf-quic-tls-17 - Endpoints discard initial keys as soon as handshake keys are available (#1951, diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 3b2c274a6b..f6f765ad58 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -5494,6 +5494,22 @@ DecodePacketNumber(largest_pn, truncated_pn, pn_nbits): Issue and pull request numbers are listed with a leading octothorp. +## Since draft-ietf-quic-transport-18 + +- Removed version negotation; version negotiation, including authentication of + the result, will be addressed in the next version of QUIC (#1773, #2313) +- Added discussion of the use of IPv6 flow labels (#2348, #2399) +- A connection ID can't be retired in a packet that uses that connection ID + (#2101, #2420) +- Idle timeout transport parameter is in milliseconds (from seconds) (#2453, + #2454) +- Endpoints are required to use new connnection IDs when they use new network + paths (#2413, #2414) +- Increased the set of permissible frames in 0-RTT (#2344, #2355) +- Prohibit the use of MAX_STREAM_ID/max_stream_id of greater than 2^60 (#2487, + #2499) +- Failing to negotiate ALPN is a fatal error (#2495, #2483) + ## Since draft-ietf-quic-transport-17 - Stream-related errors now use STREAM_STATE_ERROR (#2305) From bcdb4cf9bfcad92ebed553542385f27ea604aa58 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 11 Mar 2019 17:08:32 +1100 Subject: [PATCH 156/190] Add a few missing HTTP -19 entries --- draft-ietf-quic-http.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 8d8fc6910a..4de87a0826 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1960,6 +1960,8 @@ Error codes need to be defined for HTTP/2 and HTTP/3 separately. See - Modified associated reserved values - Frame layout switched from Length-Type-Value to Type-Length-Value (#2395,#2235) +- Specified error code for servers receiving DUPLICATE_PUSH (#2497) +- Use connection error for invalid PRIORITY (#2507, #2508) ## Since draft-ietf-quic-http-17 From dd656cab08abc51a3e00b12a9c1c8da78b49afa9 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 11 Mar 2019 17:14:52 +1100 Subject: [PATCH 157/190] qpack -07 changes --- draft-ietf-quic-qpack.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/draft-ietf-quic-qpack.md b/draft-ietf-quic-qpack.md index bb6a2d0f3b..ddab4338e3 100644 --- a/draft-ietf-quic-qpack.md +++ b/draft-ietf-quic-qpack.md @@ -1328,6 +1328,10 @@ return controlBuffer, prefixBuffer + streamBuffer > **RFC Editor's Note:** Please remove this section prior to publication of a > final version of this document. +## Since draft-ietf-quic-qpack-06 + +- Clarify initial dynamic table capacity maximums (#2276, #2330, #2330) + ## Since draft-ietf-quic-qpack-05 - Introduced the terms dynamic table capacity and maximum dynamic table From c91af55f435dfee951ee027cfbd3dac696876f24 Mon Sep 17 00:00:00 2001 From: ianswett Date: Mon, 11 Mar 2019 11:38:50 -0400 Subject: [PATCH 158/190] Recovery Changelog for -19 --- draft-ietf-quic-recovery.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 3cafc529b5..f410525e5b 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1383,6 +1383,18 @@ are detected lost. Issue and pull request numbers are listed with a leading octothorp. +## Since draft-ietf-quic-recovery-18 + +- Change IW byte limit to 14720 from 14600 (#2494) +- Update PTO calculation to match RFC6298 (#2480, #2489, #2490) +- Improve loss detection's description of multiple packet number spaces and + pseudocode (#2485, #2451, #2417) +- Declare persistent congestion even if non-probe packets are sent and don't + make persistent congestion more aggressive than RTO verified was (#2365, + #2244) +- Move pseudocode to the appendices (#2408) +- What to send on multiple PTOs (#2380) + ## Since draft-ietf-quic-recovery-17 - After Probe Timeout discard in-flight packets or send another (#2212, #1965) From 923c4d203d2c5892352c135735fb347ba3bbcbda Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Mon, 11 Mar 2019 17:04:46 +0000 Subject: [PATCH 159/190] QPACK table lookup noob clarifications (#2438) * Return empty string if table does not have a value * Ignore header value from table for literals with name reference * Reword according to Martin's suggestion * Apply suggestions from Mike Co-Authored-By: ghedo --- draft-ietf-quic-qpack.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/draft-ietf-quic-qpack.md b/draft-ietf-quic-qpack.md index bb6a2d0f3b..21bad8843e 100644 --- a/draft-ietf-quic-qpack.md +++ b/draft-ietf-quic-qpack.md @@ -362,6 +362,9 @@ addressed. The static table consists of a predefined static list of header fields, each of which has a fixed index over time. Its entries are defined in {{static-table}}. +All entries in the static table have a name and a value. However, values can be +empty (that is, have a length of 0). + Note the QPACK static table is indexed from 0, whereas the HPACK static table is indexed from 1. @@ -1005,6 +1008,9 @@ pattern. If the entry is in the dynamic table with an absolute index greater than or equal to the Base, the representation starts with the '0000' four-bit pattern. +Only the header field name stored in the static or dynamic table is used. Any +header field value MUST be ignored. + The following bit, 'N', indicates whether an intermediary is permitted to add this header to the dynamic header table on subsequent hops. When the 'N' bit is set, the encoded header MUST always be encoded with a literal representation. In From 6b9732d1e62d21fda7854532f1e9d646df089ded Mon Sep 17 00:00:00 2001 From: Lucas Pardue Date: Mon, 11 Mar 2019 17:05:46 +0000 Subject: [PATCH 160/190] More specific IANA registration xref (#2470) --- draft-ietf-quic-qpack.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-qpack.md b/draft-ietf-quic-qpack.md index 21bad8843e..f28c7186dc 100644 --- a/draft-ietf-quic-qpack.md +++ b/draft-ietf-quic-qpack.md @@ -598,7 +598,7 @@ described in this section. Header block instructions are contained in HEADERS and PUSH_PROMISE frames, which are conveyed on request or push streams as described in {{HTTP3}}. -### Encoder and Decoder Streams +### Encoder and Decoder Streams {#enc-dec-stream-def} QPACK defines two unidirectional stream types: @@ -1152,8 +1152,8 @@ registered in the "HTTP/3 Stream Type" registry established in {{HTTP3}}. | ---------------------------- | ------ | ------------------------- | ------ | | Stream Type | Code | Specification | Sender | | ---------------------------- | :----: | ------------------------- | ------ | -| QPACK Encoder Stream | 0x02 | {{wire-format}} | Both | -| QPACK Decoder Stream | 0x03 | {{wire-format}} | Both | +| QPACK Encoder Stream | 0x02 | {{enc-dec-stream-def}} | Both | +| QPACK Decoder Stream | 0x03 | {{enc-dec-stream-def}} | Both | | ---------------------------- | ------ | ------------------------- | ------ | ## Error Code Registration From 81cf97e1f58ff5880acde8a9b46fef45b075e377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bence=20B=C3=A9ky?= Date: Mon, 11 Mar 2019 13:13:20 -0400 Subject: [PATCH 161/190] Clarify when a dynamic table entry can be evicted. (#2261) * Clarify when a dynamic table entry can be evicted. * Incorporate some of @martinthomson's comments. --- draft-ietf-quic-qpack.md | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/draft-ietf-quic-qpack.md b/draft-ietf-quic-qpack.md index f28c7186dc..0fabe0c217 100644 --- a/draft-ietf-quic-qpack.md +++ b/draft-ietf-quic-qpack.md @@ -210,10 +210,20 @@ acknowledged by the decoder. ### Blocked Dynamic Table Insertions {#blocked-insertion} +A dynamic table entry is considered blocking and cannot be evicted until its +insertion has been acknowledged and there are no outstanding unacknowledged +references to the entry. In particular, a dynamic table entry that has never +been referenced can still be blocking. + +Note: +: A blocking entry is unrelated to a blocked stream, which is a stream that a + decoder cannot decode as a result of references to entries that are not yet + available. Any encoder that uses the dynamic table has to keep track of + blocked entries, whereas blocked streams are optional. + An encoder MUST NOT insert an entry into the dynamic table (or duplicate an -existing entry) if doing so would evict an entry with unacknowledged references. -For header blocks that might rely on the newly added entry, the encoder can use -a literal representation. +existing entry) if doing so would evict a blocking entry. In this case, the +encoder can send literal representations of header fields. To ensure that the encoder is not prevented from adding new entries, the encoder can avoid referencing entries that are close to eviction. Rather than @@ -223,7 +233,7 @@ reference such an entry, the encoder can emit a Duplicate instruction (see Determining which entries are too close to eviction to reference is an encoder preference. One heuristic is to target a fixed amount of available space in the dynamic table: either unused space or space that can be reclaimed by evicting -unreferenced entries. To achieve this, the encoder can maintain a draining +non-blocking entries. To achieve this, the encoder can maintain a draining index, which is the smallest absolute index in the dynamic table that it will emit a reference for. As new entries are inserted, the encoder increases the draining index to maintain the section of the table that it will not reference. @@ -329,10 +339,9 @@ decoder that permit the encoder to track the decoder's state. These events are: Knowledge that a header block with references to the dynamic table has been processed permits the encoder to evict entries to which no unacknowledged -references remain, regardless of whether those references were potentially -blocking (see {{blocked-insertion}}). When a stream is reset or abandoned, the -indication that these header blocks will never be processed serves a similar -function; see {{stream-cancellation}}. +references remain (see {{blocked-insertion}}). When a stream is reset or +abandoned, the indication that these header blocks will never be processed +serves a similar function (see {{stream-cancellation}}). The decoder chooses when to emit Insert Count Increment instructions (see {{insert-count-increment}}). Emitting an instruction after adding each new @@ -405,8 +414,8 @@ limit on its size. The initial capcity of the dynamic table is zero. Before a new entry is added to the dynamic table, entries are evicted from the end of the dynamic table until the size of the dynamic table is less than or equal to (table capacity - size of new entry) or until the table is empty. The -encoder MUST NOT evict a dynamic table entry unless it has first been -acknowledged by the decoder. +encoder MUST NOT evict a blocking dynamic table entry (see +{{blocked-insertion}}). If the size of the new entry is less than or equal to the dynamic table capacity, then that entry is added to the table. It is an error if the encoder @@ -721,9 +730,9 @@ that exceeds this limit as a connection error of type `HTTP_QPACK_ENCODER_STREAM_ERROR`. Reducing the dynamic table capacity can cause entries to be evicted (see -{{eviction}}). This MUST NOT cause the eviction of entries with outstanding -references (see {{reference-tracking}}). Changing the capacity of the dynamic -table is not acknowledged as this instruction does not insert an entry. +{{eviction}}). This MUST NOT cause the eviction of blocking entries (see +{{blocked-insertion}}). Changing the capacity of the dynamic table is not +acknowledged as this instruction does not insert an entry. ## Decoder Instructions {#decoder-instructions} From 1281676099be89184bd8a85b59600b4142dc3e47 Mon Sep 17 00:00:00 2001 From: ianswett Date: Wed, 13 Mar 2019 11:52:22 -0400 Subject: [PATCH 162/190] Update draft-ietf-quic-transport.md --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 7ab0972ac9..cd0e1c24b9 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -852,7 +852,7 @@ using MAX_STREAMS frames ({{frame-max-streams}}). Separate limits apply to unidirectional and bidirectional streams. If a max_streams transport parameter or MAX_STREAMS frame is received with a -value greater than 2^60, this allows a maximum stream ID that cannot be +value greater than 2^60, this would allow a maximum stream ID that cannot be expressed as a variable-length integer (see {{integer-encoding}}). If either is received, the connection MUST be closed immediately with a connection error of type STREAM_LIMIT_ERROR (see {{immediate-close}}). From 79c731c4d580296d1a3e38e42733c7b52d88b779 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Wed, 13 Mar 2019 08:54:49 -0700 Subject: [PATCH 163/190] Rephrase size requirement for Initial packets --- draft-ietf-quic-transport.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 86c46c0fbe..8b4844869a 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1468,10 +1468,11 @@ magnitude of any amplification attack that can be mounted using spoofed source addresses. In determining this limit, servers only count the size of successfully processed packets. -Clients MUST pad UDP datagrams that contain only Initial packets to at least -1200 bytes. Once a client has received an acknowledgment for a Handshake packet -it MAY send smaller datagrams. Sending padded datagrams ensures that the server -is not overly constrained by the amplification restriction. +Clients MUST ensure that UDP datagrams containing Initial packets are sized to +at least 1200 bytes, padding packets in the datagram if necessary. Once a +client has received an acknowledgment for a Handshake packet it MAY send smaller +datagrams. Sending padded datagrams ensures that the server is not overly +constrained by the amplification restriction. Packet loss, in particular loss of a Handshake packet from the server, can cause a situation in which the server cannot send when the client has no data to send From 679bfedb604324fde8488730050b1c16e9698317 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Wed, 13 Mar 2019 16:42:25 +0000 Subject: [PATCH 164/190] Apply Jana's suggestions from review Co-Authored-By: ghedo --- draft-ietf-quic-tls.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 071bb47a90..e908a7faf9 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1215,9 +1215,9 @@ QUIC requires that the cryptographic handshake provide authenticated protocol negotiation. TLS uses Application Layer Protocol Negotiation (ALPN) {{!RFC7301}} to select an application protocol. Unless another mechanism is used for agreeing on an application protocol, endpoints MUST use ALPN for this -purpose. When using ALPN, endpoints MUST abort a connection if an application -protocol is not negotiated with a no_application_protocol alert (error code -0x178). While {{!RFC7301}} only specifies that servers use this alert, QUIC +purpose. When using ALPN, endpoints MUST immediately close a connection (see Section 10.3 in {{QUIC-TRANSPORT}}) if an application +protocol is not negotiated with a no_application_protocol TLS alert (QUIC error code +0x178, see {{tls-errors}}). While {{!RFC7301}} only specifies that servers use this alert, QUIC clients MUST also use it to terminate a connection when ALPN negotiation fails. An application-layer protocol MAY restrict the QUIC versions that it can operate From 406beb3a8e8cf75e0b27ba65fcf1fc50cc1b9b80 Mon Sep 17 00:00:00 2001 From: Masanori Ogino Date: Thu, 14 Mar 2019 13:11:43 +0900 Subject: [PATCH 165/190] QPACK: Use the term "HTTP/3" in the title --- draft-ietf-quic-qpack.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-qpack.md b/draft-ietf-quic-qpack.md index 45894bc2c2..11c8cafbcc 100644 --- a/draft-ietf-quic-qpack.md +++ b/draft-ietf-quic-qpack.md @@ -1,5 +1,5 @@ --- -title: "QPACK: Header Compression for HTTP over QUIC" +title: "QPACK: Header Compression for HTTP/3" abbrev: QPACK docname: draft-ietf-quic-qpack-latest date: {DATE} From da3ed6adfb34ed00dc4422de030657e148bdcc2f Mon Sep 17 00:00:00 2001 From: Alessandro Ghedini Date: Thu, 14 Mar 2019 21:30:01 +0000 Subject: [PATCH 166/190] Fix lint errors --- draft-ietf-quic-tls.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index e908a7faf9..f2b6f542ee 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1215,10 +1215,12 @@ QUIC requires that the cryptographic handshake provide authenticated protocol negotiation. TLS uses Application Layer Protocol Negotiation (ALPN) {{!RFC7301}} to select an application protocol. Unless another mechanism is used for agreeing on an application protocol, endpoints MUST use ALPN for this -purpose. When using ALPN, endpoints MUST immediately close a connection (see Section 10.3 in {{QUIC-TRANSPORT}}) if an application -protocol is not negotiated with a no_application_protocol TLS alert (QUIC error code -0x178, see {{tls-errors}}). While {{!RFC7301}} only specifies that servers use this alert, QUIC -clients MUST also use it to terminate a connection when ALPN negotiation fails. +purpose. When using ALPN, endpoints MUST immediately close a connection (see +Section 10.3 in {{QUIC-TRANSPORT}}) if an application protocol is not +negotiated with a no_application_protocol TLS alert (QUIC error code 0x178, +see {{tls-errors}}). While {{!RFC7301}} only specifies that servers use this +alert, QUIC clients MUST also use it to terminate a connection when ALPN +negotiation fails. An application-layer protocol MAY restrict the QUIC versions that it can operate over. Servers MUST select an application protocol compatible with the QUIC From 9723f0f0441d604ddae99628b4f83ad7cf72d67b Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 12 Mar 2019 09:36:24 +1100 Subject: [PATCH 167/190] Remove aspirational changes --- draft-ietf-quic-transport.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 86c46c0fbe..fdbaa04907 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -5500,9 +5500,6 @@ Issue and pull request numbers are listed with a leading octothorp. - Endpoints are required to use new connnection IDs when they use new network paths (#2413, #2414) - Increased the set of permissible frames in 0-RTT (#2344, #2355) -- Prohibit the use of MAX_STREAM_ID/max_stream_id of greater than 2^60 (#2487, - #2499) -- Failing to negotiate ALPN is a fatal error (#2495, #2483) ## Since draft-ietf-quic-transport-17 From a69e90d091a8543392d5f5452c4dd31919b06fe6 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 15 Mar 2019 13:10:33 -0700 Subject: [PATCH 168/190] Update draft-ietf-quic-transport.md Co-Authored-By: janaiyengar --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 8b4844869a..1eedf298e8 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1469,7 +1469,7 @@ addresses. In determining this limit, servers only count the size of successfully processed packets. Clients MUST ensure that UDP datagrams containing Initial packets are sized to -at least 1200 bytes, padding packets in the datagram if necessary. Once a +at least 1200 bytes, adding padding to packets in the datagram as necessary. Once a client has received an acknowledgment for a Handshake packet it MAY send smaller datagrams. Sending padded datagrams ensures that the server is not overly constrained by the amplification restriction. From 50011f231f3bb9094f85cc5953c05c64883759d4 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Fri, 15 Mar 2019 13:12:25 -0700 Subject: [PATCH 169/190] reflow --- draft-ietf-quic-transport.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 1eedf298e8..bf5a5a8ac2 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1469,10 +1469,10 @@ addresses. In determining this limit, servers only count the size of successfully processed packets. Clients MUST ensure that UDP datagrams containing Initial packets are sized to -at least 1200 bytes, adding padding to packets in the datagram as necessary. Once a -client has received an acknowledgment for a Handshake packet it MAY send smaller -datagrams. Sending padded datagrams ensures that the server is not overly -constrained by the amplification restriction. +at least 1200 bytes, adding padding to packets in the datagram as necessary. +Once a client has received an acknowledgment for a Handshake packet it MAY send +smaller datagrams. Sending padded datagrams ensures that the server is not +overly constrained by the amplification restriction. Packet loss, in particular loss of a Handshake packet from the server, can cause a situation in which the server cannot send when the client has no data to send From 5f598aa2e789cbdcfbc4c9f6c3f571e6e3e2b3b1 Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Fri, 15 Mar 2019 17:29:04 -0700 Subject: [PATCH 170/190] Add section number to reference (#2525) --- draft-ietf-quic-recovery.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index f410525e5b..c84d0fba85 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -423,10 +423,11 @@ Upon timeout, the sender MUST retransmit all unacknowledged CRYPTO data if possible. Until the server has validated the client's address on the path, the amount of -data it can send is limited, as specified in {{QUIC-TRANSPORT}}. If not all -unacknowledged CRYPTO data can be sent, then all unacknowledged CRYPTO data sent -in Initial packets should be retransmitted. If no data can be sent, then no -alarm should be armed until data has been received from the client. +data it can send is limited, as specified in Section 8.1 of {{QUIC-TRANSPORT}}. +If not all unacknowledged CRYPTO data can be sent, then all unacknowledged +CRYPTO data sent in Initial packets should be retransmitted. If no data can be +sent, then no alarm should be armed until data has been received from the +client. Because the server could be blocked until more packets are received, the client MUST start the crypto retransmission timer even if there is no unacknowledged From 320e155ccf6f4e4c3b648b696c418ebfa305d878 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 20 Mar 2019 10:34:15 +1100 Subject: [PATCH 171/190] Quote brackets. Closes #2517. --- draft-ietf-quic-recovery.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index c84d0fba85..f855ed22ae 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -894,7 +894,7 @@ time_of_last_sent_ack_eliciting_packet: time_of_last_sent_crypto_packet: : The time the most recent crypto packet was sent. -largest_acked_packet[kPacketNumberSpace]: +largest_acked_packet\[kPacketNumberSpace]: : The largest packet number acknowledged in the packet number space so far. latest_rtt: @@ -917,11 +917,11 @@ max_ack_delay: received ACK frame may be larger due to late timers, reordering, or lost ACKs. -loss_time[kPacketNumberSpace]: +loss_time\[kPacketNumberSpace]: : The time at which the next packet in that packet number space will be considered lost based on exceeding the reordering window in time. -sent_packets[kPacketNumberSpace]: +sent_packets\[kPacketNumberSpace]: : An association of packet numbers in a packet number space to information about them. Described in detail above in {{tracking-sent-packets}}. From c3ea995ab186f5b2e81f396155b0d2891299ad03 Mon Sep 17 00:00:00 2001 From: martinduke Date: Wed, 20 Mar 2019 12:33:38 -0700 Subject: [PATCH 172/190] Many frames have flags in the type now Updating a little old text. --- draft-ietf-quic-transport.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index d1d0bb8b4d..321fe68ab0 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2708,8 +2708,9 @@ additional type-dependent fields: {: #frame-layout title="Generic Frame Layout"} The frame types defined in this specification are listed in {{frame-types}}. -The Frame Type in STREAM frames is used to carry other frame-specific flags. -For all other frames, the Frame Type field simply identifies the frame. These +The Frame Type in ACK, STREAM, MAX_STREAMS, STREAMS_BLOCKED, and +CONNECTION_CLOSE frames is used to carry other frame-specific flags. For all +other frames, the Frame Type field simply identifies the frame. These frames are explained in more detail in {{frame-formats}}. | Type Value | Frame Type Name | Definition | From 3c383577676d512c4aba0f9ae7b9f26f9e56967d Mon Sep 17 00:00:00 2001 From: martinduke Date: Wed, 20 Mar 2019 16:32:44 -0700 Subject: [PATCH 173/190] In which I surrender I still disagree with the critique, but it is way less important than the rest of the PR. Perhaps someone can show me the error of my ways over some Czech beer. --- draft-ietf-quic-tls.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 5986c8559e..6557880e09 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -269,7 +269,7 @@ At a high level, there are two main interactions between the TLS and QUIC components: * The TLS component sends and receives messages via the QUIC component, with - QUIC providing a reliable stream and record abstraction to TLS. + QUIC providing a reliable stream abstraction to TLS. * The TLS component provides a series of updates to the QUIC component, including (a) new packet protection keys to install (b) state changes such as From c8ed4bb6fe0db5c5eb348b4a7d697d27746c4a50 Mon Sep 17 00:00:00 2001 From: martinduke Date: Wed, 20 Mar 2019 16:44:58 -0700 Subject: [PATCH 174/190] disallow port changes on disable_migration Some infrastructures are likely to load balance on port as well as address. --- 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 321fe68ab0..f953b6410f 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -4091,8 +4091,8 @@ disable_migration (0x000c): : The disable migration transport parameter is included if the endpoint does not support connection migration ({{migration}}). Peers of an endpoint that sets this transport parameter 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. + ({{probing}}), from a local address or port other than that used to perform + the handshake. This parameter is a zero-length value. preferred_address (0x000d): From 43a46542cce2a6b5a2797e672a432243cfc10f68 Mon Sep 17 00:00:00 2001 From: martinduke Date: Wed, 20 Mar 2019 16:48:59 -0700 Subject: [PATCH 175/190] Nit in ECN format section missing prepositions --- draft-ietf-quic-transport.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 321fe68ab0..a3d7e0d973 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -4365,16 +4365,16 @@ counts, as follows: The three ECN Counts are: ECT(0) Count: -: A variable-length integer representing the total number packets received with - the ECT(0) codepoint. +: A variable-length integer representing the total number of packets received + with the ECT(0) codepoint. ECT(1) Count: -: A variable-length integer representing the total number packets received with - the ECT(1) codepoint. +: A variable-length integer representing the total number of packets received + with the ECT(1) codepoint. CE Count: -: A variable-length integer representing the total number packets received with - the CE codepoint. +: A variable-length integer representing the total number of packets received + with the CE codepoint. ECN counts are maintained separately for each packet number space. From 6270c390c36db9f07475d76a38d1190e24b76fd8 Mon Sep 17 00:00:00 2001 From: martinduke Date: Wed, 20 Mar 2019 16:51:05 -0700 Subject: [PATCH 176/190] Clarify meaning of RESET_STREAM Saying it "terminates a stream" dangerously makes it sound like it has the same meaning as HTTP/2, which is false. --- 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 321fe68ab0..5c4930321c 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -4381,8 +4381,8 @@ ECN counts are maintained separately for each packet number space. ## RESET_STREAM Frame {#frame-reset-stream} -An endpoint uses a RESET_STREAM frame (type=0x04) to abruptly terminate a -stream. +An endpoint uses a RESET_STREAM frame (type=0x04) to abruptly terminate the +sending part of a stream. After sending a RESET_STREAM, an endpoint ceases transmission and retransmission of STREAM frames on the identified stream. A receiver of RESET_STREAM can From 6503c9e2b728b99bbecc0d658858ff32238f44bf Mon Sep 17 00:00:00 2001 From: Nick Harper Date: Thu, 21 Mar 2019 11:46:29 -0700 Subject: [PATCH 177/190] Editorial changes to transport draft --- draft-ietf-quic-transport.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index db335b20c3..7683ab27c2 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -3276,7 +3276,7 @@ decodes to the decimal value 151288809941952652; the four byte sequence 9d 7f 3e 7d decodes to 494878333; the two byte sequence 7b bd decodes to 15293; and the single byte 25 decodes to 37 (as does the two byte sequence 40 25). -Error codes ({{error-codes}}) and versions {{versions}} are described using +Error codes ({{error-codes}}) and versions ({{versions}}) are described using integers, but do not use this encoding. @@ -4224,15 +4224,15 @@ Largest Acknowledged: ACK Delay: -: A variable-length integer including the time in microseconds that the largest - acknowledged packet, as indicated in the Largest Acknowledged field, was - received by this peer to when this ACK was sent. The value of the ACK Delay - field is scaled by multiplying the encoded value by 2 to the power of the - value of the `ack_delay_exponent` transport parameter set by the sender of the - ACK frame. The `ack_delay_exponent` defaults to 3, or a multiplier of 8 (see - {{transport-parameter-definitions}}). Scaling in this fashion allows for a - larger range of values with a shorter encoding at the cost of lower - resolution. +: A variable-length integer representing the time delta in microseconds between + when this ACK was sent and when the largest acknowledged packet, as indicated + in the Largest Acknowledged field, was received by this peer. The value of + the ACK Delay field is scaled by multiplying the encoded value by 2 to the + power of the value of the `ack_delay_exponent` transport parameter set by the + sender of the ACK frame. The `ack_delay_exponent` defaults to 3, or a + multiplier of 8 (see {{transport-parameter-definitions}}). Scaling in this + fashion allows for a larger range of values with a shorter encoding at the + cost of lower resolution. ACK Range Count: From b1a879ed8badcf11ce554d6a34d73812a2279e9b Mon Sep 17 00:00:00 2001 From: Lucas Pardue Date: Wed, 20 Mar 2019 11:39:44 +0000 Subject: [PATCH 178/190] Bump SETTINGS_NUM_PLACEHOLDERS codepoint to 0x9 Fixes #2443. Leave 0x8 open and unreserved so that some future extension document can use it for WebSockets (if they so wish). --- draft-ietf-quic-http.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index b69e26fb35..ad98fd52d8 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -704,7 +704,7 @@ The following settings are defined in HTTP/3: SETTINGS_MAX_HEADER_LIST_SIZE (0x6): : The default value is unlimited. See {{header-formatting}} for usage. - SETTINGS_NUM_PLACEHOLDERS (0x8): + SETTINGS_NUM_PLACEHOLDERS (0x9): : The default value is 0. However, this value SHOULD be set to a non-zero value by servers. See {{placeholders}} for usage. @@ -1612,7 +1612,7 @@ The entries in the following table are registered by this document. | Reserved | 0x4 | N/A | | Reserved | 0x5 | N/A | | MAX_HEADER_LIST_SIZE | 0x6 | {{settings-parameters}} | -| NUM_PLACEHOLDERS | 0x8 | {{settings-parameters}} | +| NUM_PLACEHOLDERS | 0x9 | {{settings-parameters}} | | ---------------------------- | ------ | ------------------------- | Additionally, each code of the format `0x1f * N + 0x21` for integer values of N From 553840d4d755698b00518268dd300a9d186219db Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Tue, 26 Mar 2019 16:56:05 +0100 Subject: [PATCH 179/190] Simplify kPersistentThreshold --- draft-ietf-quic-recovery.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index f855ed22ae..6a3d8b9ccf 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -660,12 +660,11 @@ sent over a long enough period of time, the network is considered to be experiencing persistent congestion. Commonly, this can be established by consecutive PTOs, but since the PTO timer is reset when a new ack-eliciting packet is sent, an explicit duration must be used to account for those cases -where PTOs do not occur or are substantially delayed. This duration is the -equivalent of kPersistentCongestionThreshold consecutive PTOs, and is computed +where PTOs do not occur or are substantially delayed. This duration is computed as follows: + ~~~ -(smoothed_rtt + 4 * rttvar + max_ack_delay) * - ((2 ^ kPersistentCongestionThreshold) - 1) +(smoothed_rtt + 4 * rttvar + max_ack_delay) * kPersistentCongestionThreshold ~~~ For example, assume: @@ -673,7 +672,7 @@ For example, assume: smoothed_rtt = 1 rttvar = 0 max_ack_delay = 0 - kPersistentCongestionThreshold = 2 + kPersistentCongestionThreshold = 3 If an eck-eliciting packet is sent at time = 0, the following scenario would illustrate persistent congestion: @@ -687,10 +686,10 @@ illustrate persistent congestion: The first three packets are determined to be lost when the ACK of packet 4 is received at t=8. The congestion period is calculated as the time between the oldest and newest lost packets: (3 - 0) = 3. The duration for persistent -congestion is equal to: (1 * ((2 ^ kPersistentCongestionThreshold) - 1)) = 3. -Because the threshold was reached and because none of the packets between the -oldest and the newest packets are acknowledged, the network is considered to -have experienced persistent congestion. +congestion is equal to: (1 * kPersistentCongestionThreshold) = 3. Because the +threshold was reached and because none of the packets between the oldest and the +newest packets are acknowledged, the network is considered to have experienced +persistent congestion. When persistent congestion is established, the sender's congestion window MUST be reduced to the minimum congestion window (kMinimumWindow). This response of @@ -1216,13 +1215,14 @@ kLossReductionFactor: The RECOMMENDED value is 0.5. kPersistentCongestionThreshold: -: Number of consecutive PTOs required for persistent congestion to be - established. The rationale for this threshold is to enable a sender to use + +: Period of time for persistent congestion to be established, specified as a PTO + multiplier. The rationale for this threshold is to enable a sender to use initial PTOs for aggressive probing, as TCP does with Tail Loss Probe (TLP) {{TLP}} {{RACK}}, before establishing persistent congestion, as TCP does with a Retransmission Timeout (RTO) {{?RFC5681}}. The RECOMMENDED value for - kPersistentCongestionThreshold is 2, which is equivalent to having two TLPs - before an RTO in TCP. + kPersistentCongestionThreshold is 3, which is approximately equivalent to + having two TLPs before an RTO in TCP. ## Variables of interest {#vars-of-interest} @@ -1354,8 +1354,7 @@ are detected lost. InPersistentCongestion(largest_lost_packet): pto = smoothed_rtt + max(4 * rttvar, kGranularity) + max_ack_delay - congestion_period = - pto * (2 ^ kPersistentCongestionThreshold - 1) + congestion_period = pto * kPersistentCongestionThreshold // Determine if all packets in the window before the // newest lost packet, including the edges, are marked // lost From f506e4b7339efcfa727634c5722f51ae26be7c9f Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Tue, 26 Mar 2019 16:59:58 +0100 Subject: [PATCH 180/190] nit --- draft-ietf-quic-recovery.md | 1 - 1 file changed, 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 6a3d8b9ccf..65b400a0a5 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -1215,7 +1215,6 @@ kLossReductionFactor: The RECOMMENDED value is 0.5. kPersistentCongestionThreshold: - : Period of time for persistent congestion to be established, specified as a PTO multiplier. The rationale for this threshold is to enable a sender to use initial PTOs for aggressive probing, as TCP does with Tail Loss Probe (TLP) From 1ffdc072f500a98521db502ae421fa2c20b4569d Mon Sep 17 00:00:00 2001 From: Jana Iyengar Date: Tue, 26 Mar 2019 18:13:25 +0100 Subject: [PATCH 181/190] lint --- draft-ietf-quic-recovery.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-recovery.md b/draft-ietf-quic-recovery.md index 65b400a0a5..77b98298e2 100644 --- a/draft-ietf-quic-recovery.md +++ b/draft-ietf-quic-recovery.md @@ -664,7 +664,8 @@ where PTOs do not occur or are substantially delayed. This duration is computed as follows: ~~~ -(smoothed_rtt + 4 * rttvar + max_ack_delay) * kPersistentCongestionThreshold +(smoothed_rtt + 4 * rttvar + max_ack_delay) * + kPersistentCongestionThreshold ~~~ For example, assume: From 059724bbe0862fa0bf040774d5203338fbef0b72 Mon Sep 17 00:00:00 2001 From: Magnus Westerlund Date: Tue, 15 Jan 2019 16:56:45 +0100 Subject: [PATCH 182/190] Initial text proposal for adding spin bit to transport specification. --- draft-ietf-quic-transport.md | 77 +++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 7683ab27c2..3f486d51dc 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -89,6 +89,13 @@ informative: target: "https://web.archive.org/web/20150315054838/http://ha.ckers.org/slowloris/" + QUIC-MANAGEABILITY: + title: "Manageability of the QUIC Transport Protocol" + author: + - ins: M. Kuehlewind + date: 2018-10-22 + target: + "https://datatracker.ietf.org/doc/draft-ietf-quic-manageability/" --- abstract @@ -2751,6 +2758,46 @@ encoded as a single byte with the value 0x01. An endpoint MAY treat the receipt of a frame type that uses a longer encoding than necessary as a connection error of type PROTOCOL_VIOLATION. +## Latency Spin Bit {#spin-bit} + +The latency spin bit enables latency monitoring from observation points on the +network path throughout the duration of a connection. Since it is possible to +measure handshake RTT without a spin bit, it is sufficient to include the spin +bit in the short packet header. The spin bit therefore appears only after +version negotiation and connection establishment are completed. + +The spin bit utilizes a single bit in the first byte of the short header. The +spin bits location in the short header packets and procedure for how to set it +in both clients and servers are defined in {{short-header}}. + +Implementations MAY select to not implement the full spin bit functionality. In +that case they are only REQUIRED to implement what is defined for the spin bit +when disabled. + +Each endpoint unilateral decided if the spin bit is enabled or disabled for a +connection. Implementations SHOULD allow administrators of clients and servers +to disable the spin bit either globally or on a per-connection basis. Even when +the spin bit is not disabled by the administrator implementations SHOULD disable +the spin bit on a randomly chosen fraction of connections, except if connection +is explicitly configured to enable spin bit. + +The selection process SHOULD be designed such that on average the spin bit is +disabled for at least one eighth of network paths. The selection process should +be externally unpredictable but consistent for any given combination of source +and destination address/port. For instance, the implementation might have a +static key which it uses to key a pseudorandom function over these values and +use the output to determine whether to send the spin bit. The selection process +performed at the beginning of the connection SHOULD be applied for all paths +used by the connection. + +In case multiple connections share the same five-tuple, i.e. same source and +destination IP address and UDP port the setting of the spin bit needs to be +coordinated across all connections to ensure a clear signal to any on path +measurement point, however that might not be possible. + +On-path measurement and use of the Latency Spin Bit is further discussed in +{{QUIC-MANAGEABILITY}}. + # Packetization and Reliability {#packetization} @@ -3882,8 +3929,33 @@ Fixed Bit: Spin Bit (S): -: The sixth bit (0x20) of byte 0 is the Latency Spin Bit, set as described in - {{!SPIN=I-D.ietf-quic-spin-exp}}. +: The third most significant bit (0x20) of byte 0 is the Latency Spin Bit. + +: When the spin bit is disabled, endpoints MAY set the spin bit to any value, +and MUST accept any incoming value. It is RECOMMENDED that they +set the spin bit to a random value either chosen independently for each packet, +or chosen independently for each path and kept constant for that path. + +: If the spin bit is enabled for the connection the endpoint maintains a spin +value, 0 or 1, and sets the spin bit in the short header to the currently stored +value when a packet with a short header is sent out. The spin value is +initialized to 0 in the endpoint at connection start. Each endpoint also +remembers the highest packet number seen from its peer on the connection. + +: When a server receives a packet from a client, if that packet has a short +header and if it increments the highest packet number seen by the server from +the client, the server sets the spin value to the value observed in the spin bit +in the received packet. + +: When a client receives a packet from a server, if the packet has a short +header and if it increments the highest packet number seen by the client from +the server, it sets the spin value to the opposite of the spin bit in the +received packet. + +: The endpoint resets it spin value to zero when sending the first packet of a +given connection with a new connection ID. This reduces the risk that transient +spin bit state can be used to link flows across connection migration or ID +change. Reserved Bits (R): @@ -3933,6 +4005,7 @@ version. See {{QUIC-INVARIANTS}} for details on how packets from different versions of QUIC are interpreted. + # Transport Parameter Encoding {#transport-parameter-encoding} The format of the transport parameters is the TransportParameters struct from From 3b9e2f9ceec6cc2c16bb06e0aa7b9a809f49225b Mon Sep 17 00:00:00 2001 From: ihlar Date: Tue, 22 Jan 2019 15:16:21 +0100 Subject: [PATCH 183/190] Updated text on spinbit --- draft-ietf-quic-transport.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 3f486d51dc..a452711f41 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2760,26 +2760,27 @@ of type PROTOCOL_VIOLATION. ## Latency Spin Bit {#spin-bit} -The latency spin bit enables latency monitoring from observation points on the -network path throughout the duration of a connection. Since it is possible to -measure handshake RTT without a spin bit, it is sufficient to include the spin -bit in the short packet header. The spin bit therefore appears only after -version negotiation and connection establishment are completed. +The latency spin bit enables passive latency monitoring from observation points +on the network path throughout the duration of a connection. The spin bit is +only present in the short packet header, since it is possible to measure the +initial RTT of a connection by observing the handshake. Therefore, the spin bit +will appear after version negotiation and connection establishment are +completed. -The spin bit utilizes a single bit in the first byte of the short header. The -spin bits location in the short header packets and procedure for how to set it -in both clients and servers are defined in {{short-header}}. +The spin bit utilizes a single bit in the first byte of the short header. The +location of the bit and procedures for how to set it by clients and servers are +defined in {{short-header}}. Implementations MAY select to not implement the full spin bit functionality. In that case they are only REQUIRED to implement what is defined for the spin bit -when disabled. +when it is disabled. -Each endpoint unilateral decided if the spin bit is enabled or disabled for a +Each endpoint unilaterally decides if the spin bit is enabled or disabled for a connection. Implementations SHOULD allow administrators of clients and servers -to disable the spin bit either globally or on a per-connection basis. Even when +to disable the spin bit either globally or on a per-connection basis. Even when the spin bit is not disabled by the administrator implementations SHOULD disable -the spin bit on a randomly chosen fraction of connections, except if connection -is explicitly configured to enable spin bit. +the spin bit on a randomly chosen fraction of connections, except for +connections that are explicitly configured to have the spin bit enabled. The selection process SHOULD be designed such that on average the spin bit is disabled for at least one eighth of network paths. The selection process should From a31a0e3b4ebc544fb11f6e45fcb2e2fb6212fe80 Mon Sep 17 00:00:00 2001 From: Marcus Ihlar Date: Wed, 23 Jan 2019 10:43:54 +0100 Subject: [PATCH 184/190] reviewed version --- draft-ietf-quic-transport.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index a452711f41..5da0f03764 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2765,7 +2765,8 @@ on the network path throughout the duration of a connection. The spin bit is only present in the short packet header, since it is possible to measure the initial RTT of a connection by observing the handshake. Therefore, the spin bit will appear after version negotiation and connection establishment are -completed. +completed. On-path measurement and use of the Latency Spin Bit is further +discussed in {{QUIC-MANAGEABILITY}}. The spin bit utilizes a single bit in the first byte of the short header. The location of the bit and procedures for how to set it by clients and servers are @@ -2779,13 +2780,13 @@ Each endpoint unilaterally decides if the spin bit is enabled or disabled for a connection. Implementations SHOULD allow administrators of clients and servers to disable the spin bit either globally or on a per-connection basis. Even when the spin bit is not disabled by the administrator implementations SHOULD disable -the spin bit on a randomly chosen fraction of connections, except for -connections that are explicitly configured to have the spin bit enabled. - -The selection process SHOULD be designed such that on average the spin bit is -disabled for at least one eighth of network paths. The selection process should -be externally unpredictable but consistent for any given combination of source -and destination address/port. For instance, the implementation might have a +the spin bit on a randomly chosen fraction of connections. However, connections +may be configured to explicitly enable spinning, for example in the case of +explicit customer support and debugging. +The random selection process SHOULD be designed such that on average the spin bit +is disabled for at least one eighth of network paths. The selection process +should be externally unpredictable but consistent for any given combination of source +and destination address and port. For instance, the implementation might have a static key which it uses to key a pseudorandom function over these values and use the output to determine whether to send the spin bit. The selection process performed at the beginning of the connection SHOULD be applied for all paths @@ -2794,11 +2795,7 @@ used by the connection. In case multiple connections share the same five-tuple, i.e. same source and destination IP address and UDP port the setting of the spin bit needs to be coordinated across all connections to ensure a clear signal to any on path -measurement point, however that might not be possible. - -On-path measurement and use of the Latency Spin Bit is further discussed in -{{QUIC-MANAGEABILITY}}. - +measurement point, however that might not be feasible. # Packetization and Reliability {#packetization} From dcb0475762dea7a89a6edfdcdf9d85fef00fcc5b Mon Sep 17 00:00:00 2001 From: ihlar Date: Wed, 23 Jan 2019 13:42:00 +0100 Subject: [PATCH 185/190] Updated formatting --- 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 5da0f03764..0cbf66e30c 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2765,10 +2765,10 @@ on the network path throughout the duration of a connection. The spin bit is only present in the short packet header, since it is possible to measure the initial RTT of a connection by observing the handshake. Therefore, the spin bit will appear after version negotiation and connection establishment are -completed. On-path measurement and use of the Latency Spin Bit is further +completed. On-path measurement and use of the Latency Spin Bit is further discussed in {{QUIC-MANAGEABILITY}}. -The spin bit utilizes a single bit in the first byte of the short header. The +The spin bit utilizes a single bit in the first byte of the short header. The location of the bit and procedures for how to set it by clients and servers are defined in {{short-header}}. @@ -2780,17 +2780,17 @@ Each endpoint unilaterally decides if the spin bit is enabled or disabled for a connection. Implementations SHOULD allow administrators of clients and servers to disable the spin bit either globally or on a per-connection basis. Even when the spin bit is not disabled by the administrator implementations SHOULD disable -the spin bit on a randomly chosen fraction of connections. However, connections +the spin bit on a randomly chosen fraction of connections. However, connections may be configured to explicitly enable spinning, for example in the case of explicit customer support and debugging. -The random selection process SHOULD be designed such that on average the spin bit -is disabled for at least one eighth of network paths. The selection process -should be externally unpredictable but consistent for any given combination of source -and destination address and port. For instance, the implementation might have a -static key which it uses to key a pseudorandom function over these values and -use the output to determine whether to send the spin bit. The selection process -performed at the beginning of the connection SHOULD be applied for all paths -used by the connection. +The random selection process SHOULD be designed such that on average the spin +bit is disabled for at least one eighth of network paths. The selection process +should be externally unpredictable but consistent for any given combination of +source and destination address and port. For instance, the implementation might +have a static key which it uses to key a pseudorandom function over these values +and use the output to determine whether to send the spin bit. The selection +process performed at the beginning of the connection SHOULD be applied for all +paths used by the connection. In case multiple connections share the same five-tuple, i.e. same source and destination IP address and UDP port the setting of the spin bit needs to be From 566f243679608c9527bac01217684563b8d79fc2 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Thu, 28 Mar 2019 17:35:57 +0900 Subject: [PATCH 186/190] Update draft-ietf-quic-transport.md Co-Authored-By: ihlar --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 8fc07f1c8a..55fc7a660e 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2835,7 +2835,7 @@ will appear after version negotiation and connection establishment are completed. On-path measurement and use of the Latency Spin Bit is further discussed in {{QUIC-MANAGEABILITY}}. -The spin bit utilizes a single bit in the first byte of the short header. The +The spin bit uses a single bit in the first byte of the short header. The location of the bit and procedures for how to set it by clients and servers are defined in {{short-header}}. From 2e646143d9d9e5abcb7a577b1771073ad6a76e2b Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Thu, 28 Mar 2019 17:36:27 +0900 Subject: [PATCH 187/190] Update draft-ietf-quic-transport.md Co-Authored-By: ihlar --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 55fc7a660e..fbcd231f4a 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2848,7 +2848,7 @@ connection. Implementations SHOULD allow administrators of clients and servers to disable the spin bit either globally or on a per-connection basis. Even when the spin bit is not disabled by the administrator implementations SHOULD disable the spin bit on a randomly chosen fraction of connections. However, connections -may be configured to explicitly enable spinning, for example in the case of +could be configured to explicitly enable spinning, for example in the case of explicit customer support and debugging. The random selection process SHOULD be designed such that on average the spin bit is disabled for at least one eighth of network paths. The selection process From 9d406584812ed1534405490998d8f31814303deb Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Thu, 28 Mar 2019 17:36:58 +0900 Subject: [PATCH 188/190] Update draft-ietf-quic-transport.md Co-Authored-By: ihlar --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index fbcd231f4a..c4e015a7b3 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -4000,7 +4000,7 @@ and MUST accept any incoming value. It is RECOMMENDED that they set the spin bit to a random value either chosen independently for each packet, or chosen independently for each path and kept constant for that path. -: If the spin bit is enabled for the connection the endpoint maintains a spin +: If the spin bit is enabled for the connection, the endpoint maintains a spin value, 0 or 1, and sets the spin bit in the short header to the currently stored value when a packet with a short header is sent out. The spin value is initialized to 0 in the endpoint at connection start. Each endpoint also From a1e6f8f4cfe10a5a7fc5f17a4fb189ae526973fe Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Thu, 28 Mar 2019 17:37:41 +0900 Subject: [PATCH 189/190] Update draft-ietf-quic-transport.md Co-Authored-By: ihlar --- draft-ietf-quic-transport.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index c4e015a7b3..88d3ba8874 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -4001,7 +4001,7 @@ set the spin bit to a random value either chosen independently for each packet, or chosen independently for each path and kept constant for that path. : If the spin bit is enabled for the connection, the endpoint maintains a spin -value, 0 or 1, and sets the spin bit in the short header to the currently stored +value and sets the spin bit in the short header to the currently stored value when a packet with a short header is sent out. The spin value is initialized to 0 in the endpoint at connection start. Each endpoint also remembers the highest packet number seen from its peer on the connection. From 5d48bb8d1565608a75463ebc2223e28dfa25a00a Mon Sep 17 00:00:00 2001 From: ihlar Date: Thu, 28 Mar 2019 10:24:17 +0100 Subject: [PATCH 190/190] Restructuring of spin bit text --- draft-ietf-quic-transport.md | 129 +++++++++++++++++------------------ 1 file changed, 63 insertions(+), 66 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index eda0b561de..f270ccf9dc 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2758,45 +2758,6 @@ encoded as a single byte with the value 0x01. An endpoint MAY treat the receipt of a frame type that uses a longer encoding than necessary as a connection error of type PROTOCOL_VIOLATION. -## Latency Spin Bit {#spin-bit} - -The latency spin bit enables passive latency monitoring from observation points -on the network path throughout the duration of a connection. The spin bit is -only present in the short packet header, since it is possible to measure the -initial RTT of a connection by observing the handshake. Therefore, the spin bit -will appear after version negotiation and connection establishment are -completed. On-path measurement and use of the Latency Spin Bit is further -discussed in {{QUIC-MANAGEABILITY}}. - -The spin bit uses a single bit in the first byte of the short header. The -location of the bit and procedures for how to set it by clients and servers are -defined in {{short-header}}. - -Implementations MAY select to not implement the full spin bit functionality. In -that case they are only REQUIRED to implement what is defined for the spin bit -when it is disabled. - -Each endpoint unilaterally decides if the spin bit is enabled or disabled for a -connection. Implementations SHOULD allow administrators of clients and servers -to disable the spin bit either globally or on a per-connection basis. Even when -the spin bit is not disabled by the administrator implementations SHOULD disable -the spin bit on a randomly chosen fraction of connections. However, connections -could be configured to explicitly enable spinning, for example in the case of -explicit customer support and debugging. -The random selection process SHOULD be designed such that on average the spin -bit is disabled for at least one eighth of network paths. The selection process -should be externally unpredictable but consistent for any given combination of -source and destination address and port. For instance, the implementation might -have a static key which it uses to key a pseudorandom function over these values -and use the output to determine whether to send the spin bit. The selection -process performed at the beginning of the connection SHOULD be applied for all -paths used by the connection. - -In case multiple connections share the same five-tuple, i.e. same source and -destination IP address and UDP port the setting of the spin bit needs to be -coordinated across all connections to ensure a clear signal to any on path -measurement point, however that might not be feasible. - # Packetization and Reliability {#packetization} A sender bundles one or more frames in a QUIC packet (see {{frames}}). @@ -3927,33 +3888,8 @@ Fixed Bit: Spin Bit (S): -: The third most significant bit (0x20) of byte 0 is the Latency Spin Bit. - -: When the spin bit is disabled, endpoints MAY set the spin bit to any value, -and MUST accept any incoming value. It is RECOMMENDED that they -set the spin bit to a random value either chosen independently for each packet, -or chosen independently for each path and kept constant for that path. - -: If the spin bit is enabled for the connection, the endpoint maintains a spin -value and sets the spin bit in the short header to the currently stored -value when a packet with a short header is sent out. The spin value is -initialized to 0 in the endpoint at connection start. Each endpoint also -remembers the highest packet number seen from its peer on the connection. - -: When a server receives a packet from a client, if that packet has a short -header and if it increments the highest packet number seen by the server from -the client, the server sets the spin value to the value observed in the spin bit -in the received packet. - -: When a client receives a packet from a server, if the packet has a short -header and if it increments the highest packet number seen by the client from -the server, it sets the spin value to the opposite of the spin bit in the -received packet. - -: The endpoint resets it spin value to zero when sending the first packet of a -given connection with a new connection ID. This reduces the risk that transient -spin bit state can be used to link flows across connection migration or ID -change. +: The third most significant bit (0x20) of byte 0 is the Latency Spin Bit, set +as described in {{spin-bit}}. Reserved Bits (R): @@ -4002,7 +3938,68 @@ 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. +### Latency Spin Bit {#spin-bit} +The latency spin bit enables passive latency monitoring from observation points +on the network path throughout the duration of a connection. The spin bit is +only present in the short packet header, since it is possible to measure the +initial RTT of a connection by observing the handshake. Therefore, the spin bit +will appear after version negotiation and connection establishment are +completed. On-path measurement and use of the Latency Spin Bit is further +discussed in {{QUIC-MANAGEABILITY}}. + +The spin bit uses a single bit in the first byte of the short header. The +location of the bit and procedures for how to set it by clients and servers are +defined in {{short-header}}. + +Implementations MAY select to not implement the full spin bit functionality. In +that case they are only REQUIRED to implement what is defined for the spin bit +when it is disabled. + +Each endpoint unilaterally decides if the spin bit is enabled or disabled for a +connection. Implementations SHOULD allow administrators of clients and servers +to disable the spin bit either globally or on a per-connection basis. Even when +the spin bit is not disabled by the administrator implementations MUST disable +the spin bit on a randomly chosen fraction of connections. However, connections +could be configured to explicitly enable spinning, for example in the case of +explicit customer support and debugging. +The random selection process SHOULD be designed such that on average the spin +bit is disabled for at least one eighth of network paths. The selection process +should be externally unpredictable but consistent for any given combination of +source and destination address and port. The selection process performed at the +beginning of the connection SHOULD be applied for all paths used by the +connection. + +In case multiple connections share the same five-tuple, i.e. same source and +destination IP address and UDP port the setting of the spin bit needs to be +coordinated across all connections to ensure a clear signal to any on path +measurement point, however that might not be feasible. + +When the spin bit is disabled, endpoints MAY set the spin bit to any value, and +MUST accept any incoming value. It is RECOMMENDED that they set the spin bit to +a random value either chosen independently for each packet, or chosen +independently for each path and kept constant for that path. + +If the spin bit is enabled for the connection, the endpoint maintains a spin +value and sets the spin bit in the short header to the currently stored +value when a packet with a short header is sent out. The spin value is +initialized to 0 in the endpoint at connection start. Each endpoint also +remembers the highest packet number seen from its peer on the connection. + +When a server receives a packet from a client, if that packet has a short header +and if it increments the highest packet number seen by the server from the +client, the server sets the spin value to the value observed in the spin bit in +the received packet. + +When a client receives a packet from a server, if the packet has a short header +and if it increments the highest packet number seen by the client from the +server, it sets the spin value to the opposite of the spin bit in the received +packet. + +An endpoint resets its spin value to zero when sending the first packet of a +given connection with a new connection ID. This reduces the risk that transient +spin bit state can be used to link flows across connection migration or ID +change. # Transport Parameter Encoding {#transport-parameter-encoding}