diff --git a/rfc9000.md b/rfc9000.md index 2116db5a59..2b8e7110f8 100644 --- a/rfc9000.md +++ b/rfc9000.md @@ -78,6 +78,7 @@ normative: role: editor TLS13: RFC8446 + RFC8126: informative: @@ -4610,8 +4611,8 @@ Packet Number Length: : In packet types that contain a Packet Number field, the least significant two bits (those with a mask of 0x03) of byte 0 contain the length of the packet number, encoded as an unsigned, two-bit integer that is one less than the - length of the packet number field in bytes. That is, the length of the packet - number field is the value of this field, plus one. These bits are protected + length of the Packet Number field in bytes. That is, the length of the Packet + Number field is the value of this field, plus one. These bits are protected using header protection; see {{Section 5.4 of QUIC-TLS}}. Length: @@ -4622,9 +4623,9 @@ Length: Packet Number: -: The packet number field is 1 to 4 bytes long. The packet number is protected +: The Packet Number field is 1 to 4 bytes long. The packet number is protected using header protection; see {{Section 5.4 of QUIC-TLS}}. The length of the - packet number field is encoded in the Packet Number Length bits of byte 0; see + Packet Number field is encoded in the Packet Number Length bits of byte 0; see above. ### Version Negotiation Packet {#packet-version} @@ -5073,8 +5074,8 @@ Packet Number Length: : The least significant two bits (those with a mask of 0x03) of byte 0 contain the length of the packet number, encoded as an unsigned, two-bit integer that - is one less than the length of the packet number field in bytes. That is, the - length of the packet number field is the value of this field, plus one. These + is one less than the length of the Packet Number field in bytes. That is, the + length of the Packet Number field is the value of this field, plus one. These bits are protected using header protection; see {{Section 5.4 of QUIC-TLS}}. Destination Connection ID: @@ -5084,9 +5085,9 @@ Destination Connection ID: Packet Number: -: The packet number field is 1 to 4 bytes long. The packet number is protected +: The Packet Number field is 1 to 4 bytes long. The packet number is protected using header protection; see - {{Section 5.4 of QUIC-TLS}}. The length of the packet number field is encoded + {{Section 5.4 of QUIC-TLS}}. The length of the Packet Number field is encoded in Packet Number Length field. See {{packet-encoding}} for details. Packet Payload: @@ -6513,26 +6514,25 @@ descriptions of known attacks and countermeasures. A complete security analysis of QUIC is outside the scope of this document. This section provides an informal description of the desired security properties -as an aid to implementors and to help guide protocol analysis. +as an aid to implementers and to help guide protocol analysis. QUIC assumes the threat model described in {{?SEC-CONS=RFC3552}} and provides protections against many of the attacks that arise from that model. For this purpose, attacks are divided into passive and active attacks. Passive -attackers have the capability to read packets from the network, while active -attackers also have the capability to write packets into the network. However, -a passive attack could involve an attacker with the ability to cause a routing +attackers have the ability to read packets from the network, while active +attackers also have the ability to write packets into the network. However, a +passive attack could involve an attacker with the ability to cause a routing change or other modification in the path taken by packets that comprise a connection. Attackers are additionally categorized as either on-path attackers or off-path -attackers. An on-path attacker can read, -modify, or remove any packet it observes such that it no longer reaches its -destination, while an off-path attacker observes the packets, but cannot prevent -the original packet from reaching its intended destination. Both types of -attackers can also transmit arbitrary packets. This definition differs from -that of {{Section 3.5 of SEC-CONS}} in that an off-path attacker is able to -observe packets. +attackers. An on-path attacker can read, modify, or remove any packet it +observes such that the packet no longer reaches its destination, while an +off-path attacker observes the packets but cannot prevent the original packet +from reaching its intended destination. Both types of attackers can also +transmit arbitrary packets. This definition differs from that of {{Section 3.5 +of SEC-CONS}} in that an off-path attacker is able to observe packets. Properties of the handshake, protected packets, and connection migration are considered separately. @@ -6570,12 +6570,12 @@ Prior to address validation, endpoints are limited in what they are able to send. Endpoints cannot send data toward an unvalidated address in excess of three times the data received from that address. -Note: - -: The anti-amplification limit only applies when an endpoint responds to packets - received from an unvalidated address. The anti-amplification limit does not - apply to clients when establishing a new connection or when initiating - connection migration. + #### Server-Side DoS @@ -6593,7 +6593,7 @@ new connection establishment without incurring this cost. An on-path or off-path attacker can force a handshake to fail by replacing or racing Initial packets. Once valid Initial packets have been exchanged, -subsequent Handshake packets are protected with the handshake keys and an +subsequent Handshake packets are protected with the Handshake keys and an on-path attacker cannot force handshake failure other than by dropping packets to cause endpoints to abandon the attempt. @@ -6633,14 +6633,14 @@ Both on-path and off-path attackers can mount a passive attack in which they save observed packets for an offline attack against packet protection at a future time; this is true for any observer of any packet on any network. -A blind attacker, one who injects packets without being able to observe valid -packets for a connection, is unlikely to be successful, since packet protection -ensures that valid packets are only generated by endpoints that possess the -key material established during the handshake; see {{handshake}} and -{{handshake-properties}}. Similarly, any active attacker that observes packets +An attacker that injects packets without being able to observe valid packets for +a connection is unlikely to be successful, since packet protection ensures that +valid packets are only generated by endpoints that possess the key material +established during the handshake; see Sections {{ +Note: Modifying endpoints to apply these protections is more efficient than + deploying network-based protections, as endpoints do not need to perform any + additional processing when sending to an address that has been validated. + ## Slowloris Attacks -The attacks commonly known as Slowloris ({{SLOWLORIS}}) try to keep many +The attacks commonly known as Slowloris {{SLOWLORIS}} try to keep many connections to the target endpoint open and hold them open as long as possible. These attacks can be executed against a QUIC endpoint by generating the minimum amount of activity necessary to avoid being closed for inactivity. This might @@ -7168,17 +7168,16 @@ stream data in an attempt to force the sender to store the unacknowledged stream data for retransmission. The attack on receivers is mitigated if flow control windows correspond to -available memory. However, some receivers will over-commit memory and -advertise flow control offsets in the aggregate that exceed actual available -memory. The over-commitment strategy can lead to better performance when -endpoints are well behaved, but renders endpoints vulnerable to the stream -fragmentation attack. +available memory. However, some receivers will overcommit memory and advertise +flow control offsets in the aggregate that exceed actual available memory. The +overcommitment strategy can lead to better performance when endpoints are well +behaved, but renders endpoints vulnerable to the stream fragmentation attack. -QUIC deployments SHOULD provide mitigations against stream fragmentation -attacks. Mitigations could consist of avoiding over-committing memory, -limiting the size of tracking data structures, delaying reassembly -of STREAM frames, implementing heuristics based on the age and -duration of reassembly holes, or some combination. +QUIC deployments SHOULD provide mitigations for stream fragmentation attacks. +Mitigations could consist of avoiding overcommitting memory, limiting the size +of tracking data structures, delaying reassembly of STREAM frames, implementing +heuristics based on the age and duration of reassembly holes, or some +combination of these. ## Stream Commitment Attack @@ -7207,8 +7206,9 @@ streams. ## Peer Denial of Service {#useless} QUIC and TLS both contain frames or messages that have legitimate uses in some -contexts, but that can be abused to cause a peer to expend processing resources -without having any observable impact on the state of the connection. +contexts, but these frames or messages can be abused to cause a peer to expend +processing resources without having any observable impact on the state of the +connection. Messages can also be used to change and revert state in small or inconsequential ways, such as by sending small increments to flow control limits. @@ -7220,7 +7220,7 @@ exhaust processing capacity. While there are legitimate uses for all messages, implementations SHOULD track cost of processing relative to progress and treat excessive quantities of any non-productive packets as indicative of an attack. Endpoints MAY respond to -this condition with a connection error, or by dropping packets. +this condition with a connection error or by dropping packets. ## Explicit Congestion Notification Attacks {#security-ecn} @@ -7239,25 +7239,26 @@ successfully processed; see {{ecn}}. ## Stateless Reset Oracle {#reset-oracle} -Stateless resets create a possible denial of service attack analogous to a TCP +Stateless resets create a possible denial-of-service attack analogous to a TCP reset injection. This attack is possible if an attacker is able to cause a stateless reset token to be generated for a connection with a selected connection ID. An attacker that can cause this token to be generated can reset an active connection with the same connection ID. -If a packet can be routed to different instances that share a static key, for -example by changing an IP address or port, then an attacker can cause the server -to send a stateless reset. To defend against this style of denial of service, -endpoints that share a static key for stateless reset (see {{reset-token}}) MUST -be arranged so that packets with a given connection ID always arrive at an -instance that has connection state, unless that connection is no longer active. +If a packet can be routed to different instances that share a static key -- for +example, by changing an IP address or port -- then an attacker can cause the +server to send a stateless reset. To defend against this style of denial of +service, endpoints that share a static key for stateless resets (see +{{reset-token}}) MUST be arranged so that packets with a given connection ID +always arrive at an instance that has connection state, unless that connection +is no longer active. More generally, servers MUST NOT generate a stateless reset if a connection with the corresponding connection ID could be active on any endpoint using the same static key. In the case of a cluster that uses dynamic load balancing, it is possible that a -change in load balancer configuration could occur while an active instance +change in load-balancer configuration could occur while an active instance retains connection state. Even if an instance retains connection state, the change in routing and resulting stateless reset will result in the connection being terminated. If there is no chance of the packet being routed to the @@ -7268,8 +7269,8 @@ be influenced by an attacker. ## Version Downgrade {#version-downgrade} -This document defines QUIC Version Negotiation packets in -{{version-negotiation}} that can be used to negotiate the QUIC version used +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 @@ -7293,10 +7294,10 @@ The length of QUIC packets can reveal information about the length of the content of those packets. The PADDING frame is provided so that endpoints have some ability to obscure the length of packet content; see {{frame-padding}}. -Note however that defeating traffic analysis is challenging and the subject of -active research. Length is not the only way that information might leak. -Endpoints might also reveal sensitive information through other side channels, -such as the timing of packets. +Defeating traffic analysis is challenging and the subject of active research. +Length is not the only way that information might leak. Endpoints might also +reveal sensitive information through other side channels, such as the timing of +packets. # IANA Considerations {#iana} @@ -7315,17 +7316,17 @@ registries. ### Provisional Registrations {#iana-provisional} -Provisional registration of codepoints are intended to allow for private use and -experimentation with extensions to QUIC. Provisional registrations only require -the inclusion of the codepoint value and contact information. However, +Provisional registrations of codepoints are intended to allow for private use +and experimentation with extensions to QUIC. Provisional registrations only +require the inclusion of the codepoint value and contact information. However, provisional registrations could be reclaimed and reassigned for another purpose. -Provisional registrations require Expert Review, as defined in {{Section 4.5 -of RFC8126}}. Designated expert(s) are advised that only registrations for an -excessive proportion of remaining codepoint space or the very first unassigned -value (see {{iana-random}}) can be rejected. +Provisional registrations require Expert Review, as defined in {{Section 4.5 of +RFC8126}}. The designated expert or experts are advised that only registrations +for an excessive proportion of remaining codepoint space or the very first +unassigned value (see {{iana-random}}) can be rejected. -Provisional registrations will include a date field that indicates when the +Provisional registrations will include a Date field that indicates when the registration was last updated. A request to update the date on any provisional registration can be made without review from the designated expert(s). @@ -7342,7 +7343,7 @@ Specification: : A reference to a publicly available specification for the value. Date: -: The date of last update to the registration. +: The date of the last update to the registration. Change Controller: : The entity that is responsible for the definition of the registration. @@ -7352,22 +7353,23 @@ Contact: Notes: : Supplementary notes about the registration. +{: spacing="compact"} Provisional registrations MAY omit the Specification and Notes fields, plus any additional fields that might be required for a permanent registration. The Date -field is not required as part of requesting a registration as it is set to the +field is not required as part of requesting a registration, as it is set to the date the registration is created or updated. ### Selecting Codepoints {#iana-random} -New uses of codepoints from QUIC registries SHOULD use a randomly selected +New requests for codepoints from QUIC registries SHOULD use a randomly selected codepoint that excludes both existing allocations and the first unallocated codepoint in the selected space. Requests for multiple codepoints MAY use a contiguous range. This minimizes the risk that differing semantics are attributed to the same codepoint by different implementations. -Use of the first unassigned codepoint is reserved for allocation using the +The use of the first unassigned codepoint is reserved for allocation using the Standards Action policy; see {{Section 4.9 of RFC8126}}. The early codepoint assignment process {{!EARLY-ASSIGN=RFC7120}} can be used for these values. @@ -7387,15 +7389,15 @@ codepoint is unassigned and the requirements of the registration policy are met. A request might be made to remove an unused provisional registration from the registry to reclaim space in a registry, or portion of the registry (such as the 64-16383 range for codepoints that use variable-length encodings). This SHOULD -be done only for the codepoints with the earliest recorded date and entries that -have been updated less than a year prior SHOULD NOT be reclaimed. +be done only for the codepoints with the earliest recorded date, and entries +that have been updated less than a year prior SHOULD NOT be reclaimed. -A request to remove a codepoint MUST be reviewed by the designated expert(s). -The expert(s) MUST attempt to determine whether the codepoint is still in use. +A request to remove a codepoint MUST be reviewed by the designated experts. The +experts MUST attempt to determine whether the codepoint is still in use. Experts are advised to contact the listed contacts for the registration, plus as wide a set of protocol implementers as possible in order to determine whether -any use of the codepoint is known. The expert(s) are advised to allow at least -four weeks for responses. +any use of the codepoint is known. The experts are also advised to allow at +least four weeks for responses. If any use of the codepoints is identified by this search or a request to update the registration is made, the codepoint MUST NOT be reclaimed. Instead, the @@ -7407,24 +7409,24 @@ registration, the codepoint MAY be removed from the registry. This review and consultation process also applies to requests to change a provisional registration into a permanent registration, except that the goal is -not to determine whether there is no use of the codepoint, but to determine that +not to determine whether there is no use of the codepoint but to determine that the registration is an accurate representation of any deployed usage. ### Permanent Registrations {#iana-permanent} Permanent registrations in QUIC registries use the Specification Required policy -({{!RFC8126}}), unless otherwise specified. The designated expert(s) verify -that a specification exists and is readily accessible. Expert(s) are encouraged -to be biased towards approving registrations unless they are abusive, frivolous, -or actively harmful (not merely aesthetically displeasing, or architecturally -dubious). The creation of a registry MAY specify additional constraints on -permanent registrations. +({{Section 4.6 of RFC8126}}), unless otherwise specified. The designated expert +or experts verify that a specification exists and is readily accessible. +Experts are encouraged to be biased towards approving registrations unless they +are abusive, frivolous, or actively harmful (not merely aesthetically +displeasing or architecturally dubious). The creation of a registry MAY specify +additional constraints on permanent registrations. The creation of a registry MAY identify a range of codepoints where registrations are governed by a different registration policy. For instance, -the frame type registry in {{iana-frames}} has a stricter policy for codepoints -in the range from 0 to 63. +the "QUIC Frame Types" registry ({{iana-frames}}) has a stricter policy for +codepoints in the range from 0 to 63. Any stricter requirements for permanent registrations do not prevent provisional registrations for affected codepoints. For instance, a provisional registration @@ -7433,38 +7435,39 @@ for a frame type of 61 could be requested. All registrations made by Standards Track publications MUST be permanent. All registrations in this document are assigned a permanent status and list a -change controller of the IETF and a contact of the QUIC working group +change controller of the IETF and a contact of the QUIC Working Group (quic@ietf.org). ## QUIC Versions Registry {#iana-version} -IANA \[SHALL add/has added] a registry for "QUIC Versions" under a "QUIC" -heading. +IANA has added a registry for "QUIC Versions" under a "QUIC" heading. The "QUIC Versions" registry governs a 32-bit space; see {{versions}}. This registry follows the registration policy from {{iana-policy}}. Permanent registrations in this registry are assigned using the Specification Required -policy ({{!RFC8126}}). +policy ({{Section 4.6 of RFC8126}}). -The codepoint of 0x00000001 to the protocol is assigned with permanent status -to the protocol defined in this document. The codepoint of 0x00000000 is -permanently reserved; the note for this codepoint \[shall] indicate\[s] that -this version is reserved for Version Negotiation. +The codepoint of 0x00000001 to the protocol is assigned with permanent status to +the protocol defined in this document. The codepoint of 0x00000000 is +permanently reserved; the note for this codepoint indicates that this version is +reserved for version negotiation. -All codepoints that follow the pattern 0x?a?a?a?a are reserved and MUST NOT be -assigned by IANA and MUST NOT appear in the listing of assigned values. +All codepoints that follow the pattern 0x?a?a?a?a are reserved, MUST NOT be +assigned by IANA, and MUST NOT appear in the listing of assigned values. -## QUIC Transport Parameter Registry {#iana-transport-parameters} +## QUIC Transport Parameters Registry {#iana-transport-parameters} -IANA \[SHALL add/has added] a registry for "QUIC Transport Parameters" under a -"QUIC" heading. +IANA has added a registry for "QUIC Transport Parameters" under a "QUIC" +heading. The "QUIC Transport Parameters" registry governs a 62-bit space. This registry follows the registration policy from {{iana-policy}}. Permanent registrations -in this registry are assigned using the Specification Required policy -({{!RFC8126}}). +in this registry are assigned using the Specification Required policy ({{Section +4.6 of RFC8126}}), except for values between 0x00 and 0x3f (in hexadecimal), +inclusive, which are assigned using Standards Action or IESG Approval as defined +in {{Sections 4.9 and 4.10 of RFC8126}}. In addition to the fields in {{iana-provisional}}, permanent registrations in this registry MUST include the following field: @@ -7494,29 +7497,28 @@ The initial contents of this registry are shown in {{iana-tp-table}}. | 0x0e | active_connection_id_limit | {{transport-parameter-definitions}} | | 0x0f | initial_source_connection_id | {{transport-parameter-definitions}} | | 0x10 | retry_source_connection_id | {{transport-parameter-definitions}} | -{: #iana-tp-table title="Initial QUIC Transport Parameters Entries"} +{: #iana-tp-table title="Initial QUIC Transport Parameters Registry Entries"} -Each value of the format `31 * N + 27` for integer values of N (that is, 27, 58, +Each value of the form `31 * N + 27` for integer values of N (that is, 27, 58, 89, ...) are reserved; these values MUST NOT be assigned by IANA and MUST NOT appear in the listing of assigned values. ## QUIC Frame Types Registry {#iana-frames} -IANA \[SHALL add/has added] a registry for "QUIC Frame Types" under a -"QUIC" heading. +IANA has added a registry for "QUIC Frame Types" under a "QUIC" heading. The "QUIC Frame Types" registry governs a 62-bit space. This registry follows the registration policy from {{iana-policy}}. Permanent registrations in this -registry are assigned using the Specification Required policy ({{!RFC8126}}), -except for values between 0x00 and 0x3f (in hexadecimal; inclusive), which are -assigned using Standards Action or IESG Approval as defined in {{Sections 4.9 -and 4.10 of RFC8126}}. +registry are assigned using the Specification Required policy ({{Section 4.6 of +RFC8126}}), except for values between 0x00 and 0x3f (in hexadecimal), inclusive, +which are assigned using Standards Action or IESG Approval as defined in +{{Sections 4.9 and 4.10 of RFC8126}}. In addition to the fields in {{iana-provisional}}, permanent registrations in this registry MUST include the following field: -Frame Name: +Frame Type Name: : A short mnemonic for the frame type. @@ -7534,15 +7536,15 @@ that the registry does not include the "Pkts" and "Spec" columns from ## QUIC Transport Error Codes Registry {#iana-error-codes} -IANA \[SHALL add/has added] a registry for "QUIC Transport Error Codes" under a -"QUIC" heading. +IANA has added a registry for "QUIC Transport Error Codes" under a "QUIC" +heading. The "QUIC Transport Error Codes" registry governs a 62-bit space. This space is -split into three regions that are governed by different policies. Permanent +split into three ranges that are governed by different policies. Permanent registrations in this registry are assigned using the Specification Required -policy ({{!RFC8126}}), except for values between 0x00 and 0x3f (in hexadecimal; -inclusive), which are assigned using Standards Action or IESG Approval as -defined in {{Sections 4.9 and 4.10 of RFC8126}}. +policy ({{Section 4.6 of RFC8126}}), except for values between 0x00 and 0x3f (in +hexadecimal), inclusive, which are assigned using Standards Action or IESG +Approval as defined in {{Sections 4.9 and 4.10 of RFC8126}}. In addition to the fields in {{iana-provisional}}, permanent registrations in this registry MUST include the following fields: @@ -7571,13 +7573,13 @@ The initial contents of this registry are shown in {{iana-error-table}}. | 0x08 | TRANSPORT_PARAMETER_ERROR | Error in transport parameters | {{error-codes}} | | 0x09 | CONNECTION_ID_LIMIT_ERROR | Too many connection IDs received | {{error-codes}} | | 0x0a | PROTOCOL_VIOLATION | Generic protocol violation | {{error-codes}} | -| 0x0b | INVALID_TOKEN | Invalid Token Received | {{error-codes}} | +| 0x0b | INVALID_TOKEN | Invalid token received | {{error-codes}} | | 0x0c | APPLICATION_ERROR | Application error | {{error-codes}} | | 0x0d | CRYPTO_BUFFER_EXCEEDED | CRYPTO data buffer overflowed | {{error-codes}} | | 0x0e | KEY_UPDATE_ERROR | Invalid packet protection update | {{error-codes}} | | 0x0f | AEAD_LIMIT_REACHED | Excessive use of packet protection keys | {{error-codes}} | | 0x10 | NO_VIABLE_PATH | No viable network path exists | {{error-codes}} | -{: #iana-error-table title="Initial QUIC Transport Error Codes Entries"} +{: #iana-error-table title="Initial QUIC Transport Error Codes Registry Entries"} --- back @@ -7588,16 +7590,16 @@ The pseudocode in this section describes sample algorithms. These algorithms are intended to be correct and clear, rather than being optimally performant. The pseudocode segments in this section are licensed as Code Components; see the -copyright notice. +Copyright Notice. ## Sample Variable-Length Integer Decoding {#sample-varint} -The pseudocode in {{alg-varint}} shows how a variable-length integer can be -read from a stream of bytes. The function ReadVarint takes a single argument, a -sequence of bytes which can be read in network byte order. +The pseudocode in {{alg-varint}} shows how a variable-length integer can be read +from a stream of bytes. The function ReadVarint takes a single argument -- a +sequence of bytes, which can be read in network byte order. -~~~ +~~~pseudocode ReadVarint(data): // The length of variable-length integers is encoded in the // first two bits of the first byte. @@ -7628,10 +7630,10 @@ an appropriate size for packet number encodings. The EncodePacketNumber function takes two arguments: * full_pn is the full packet number of the packet being sent. -* largest_acked is the largest packet number which has been acknowledged by the +* largest_acked is the largest packet number that has been acknowledged by the peer in the current packet number space, if any. -~~~ +~~~pseudocode EncodePacketNumber(full_pn, largest_acked): // The number of bits must be at least one more @@ -7646,7 +7648,7 @@ EncodePacketNumber(full_pn, largest_acked): num_bytes = ceil(min_bits / 8) // Encode the integer value and truncate to - // the num_bytes least-significant bytes. + // the num_bytes least significant bytes. return encode(full_pn, num_bytes) ~~~ {: #alg-encode-pn title="Sample Packet Number Encoding Algorithm"} @@ -7673,7 +7675,7 @@ The DecodePacketNumber function takes three arguments: * truncated_pn is the value of the Packet Number field. * pn_nbits is the number of bits in the Packet Number field (8, 16, 24, or 32). -~~~ +~~~pseudocode DecodePacketNumber(largest_pn, truncated_pn, pn_nbits): expected_pn = largest_pn + 1 pn_win = 1 << pn_nbits @@ -7719,23 +7721,22 @@ implement different methods. The path is assigned an ECN state that is one of "testing", "unknown", "failed", or "capable". On paths with a "testing" or "capable" state the endpoint sends -packets with an ECT marking, by default ECT(0); otherwise, the endpoint sends +packets with an ECT marking -- ECT(0) by default; otherwise, the endpoint sends unmarked packets. -To start testing a path, the ECN state is set to "testing" and existing ECN +To start testing a path, the ECN state is set to "testing", and existing ECN counts are remembered as a baseline. -The testing period runs for a number of packets or a limited time, as -determined by the endpoint. The goal is not to limit the duration of the -testing period, but to ensure that enough marked packets are sent for received -ECN counts to provide a clear indication of how the path treats marked packets. -{{ecn-validation}} suggests limiting this to 10 packets or 3 times the probe -timeout. +The testing period runs for a number of packets or a limited time, as determined +by the endpoint. The goal is not to limit the duration of the testing period, +but to ensure that enough marked packets are sent for received ECN counts to +provide a clear indication of how the path treats marked packets. +{{ecn-validation}} suggests limiting this to ten packets or three times the PTO. After the testing period ends, the ECN state for the path becomes "unknown". -From the "unknown" state, successful validation of the ECN counts an ACK frame -(see {{ecn-ack}}) causes the ECN state for the path to become "capable", unless -no marked packet has been acknowledged. +From the "unknown" state, successful validation of the ECN counts in an ACK +frame (see {{ecn-ack}}) causes the ECN state for the path to become "capable" +unless no marked packet has been acknowledged. If validation of ECN counts fails at any time, the ECN state for the affected path becomes "failed". An endpoint can also mark the ECN state for a path as