From 8d49e58bc5e2e6c23035474a7ee9376846ddcec3 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 31 Jul 2017 15:47:48 +1000 Subject: [PATCH 01/15] Refactor the section on connection termination --- draft-ietf-quic-transport.md | 99 ++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 38 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 1bee212f4d..63223d6736 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1428,42 +1428,65 @@ TODO: see issue #161 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: - -1. Explicit Shutdown: An endpoint sends a CONNECTION_CLOSE frame to - terminate the connection. An endpoint MAY use application-layer mechanisms - prior to a CONNECTION_CLOSE to indicate that the connection will soon be - terminated. On termination of the active streams, a CONNECTION_CLOSE may be - sent. If an endpoint sends a CONNECTION_CLOSE frame while unterminated - streams are active (no FIN bit or RST_STREAM frames have been sent or - received for one or more streams), then the peer must assume that the streams - were incomplete and were abnormally terminated. - -2. Implicit Shutdown: The default idle timeout is a required parameter in - connection negotiation. The maximum is 10 minutes. If there is no network - activity for the duration of the idle timeout, the connection is closed. By - default a CONNECTION_CLOSE frame will be sent. A silent close option can be - enabled when it is expensive to send an explicit close, such as mobile - networks that must wake up the radio. - -3. Stateless Reset: An endpoint that loses state can use this procedure to cause - the connection to terminate early, see {{stateless-reset}} for details. - -After receiving either a CONNECTION_CLOSE frame or a Public Reset, an -endpoint MUST NOT send additional packets on that connection. After -sending either a CONNECTION_CLOSE frame or a Public Reset packet, -implementations MUST NOT send any non-closing packets on that -connection. If additional packets are received after this time and -before idle_timeout seconds has passed, implementations SHOULD respond -to them by sending a CONNECTION_CLOSE (which MAY just be a duplicate -of the previous CONNECTION_CLOSE packet) but MAY also send a Public -Reset packet. Implementations SHOULD throttle these responses, for -instance by exponentially backing off the number of packets which are -received before sending a response. After this time, implementations -SHOULD respond to unexpected packets with a Public Reset packet. - - -## Stateless Reset {#stateless-reset} +of four ways: negotiated shutdown, idle timeout, immediate close, and a +connection reset. + + +### Negotiated Shutdown + +An application protocol might arrange to abandon a connection after negotiating +a graceful shutdown. The application protocol exchanges whatever messages that +are needed to cause both endpoints to agree to close the connection, after which +the connection is closed. A negotiated shutdown might not result in exchanging +messages that are visible to the transport. + + +### Idle Timeout + +A connection that remains idle for longer than the idle timeout (see +{{transport-parameter-definitions}} becomes closed. Either peer removes +connection state if they have neither sent nor received a packet for this time. + +The time at which an idle timeout takes effect won't be perfectly synchronized +on peers. Endpoints might allow for the possibility that the remote side might +attempt to send packets before the timeout. In this case, an endpoint might +choose to retain enough information to generate a CONNECTION_CLOSE. Endpoints +MAY instead rely on sending Public Reset in response to packets that arrive +after an idle timeout. + + +### Immediate Close + +An endpoint sends a CONNECTION_CLOSE frame to terminate the connection +immediately. A CONNECTION_CLOSE causes all open streams to immediately become +closed; open streams can be assumed to be implicitly reset. After receiving a +CONNECTION_CLOSE frame, endpoints MUST NOT send additional packets on that +connection. + +An peer that receives a CONNECTION_CLOSE might have sent packets that will +arrive after the endpoint sends CONNECTION_CLOSE. An endpoint SHOULD respond to +these packets with another CONNECTION_CLOSE message. To minimize the state that +an endpoint maintains in this case, they MAY send the exact same +CONNECTION_CLOSE packet. + +Note: + +: This intentionally contradicts other advice in this document that recommends + the creation of new packet numbers for every packet. Sending new packet + numbers is primarily of advantage to loss recovery and congestion control, + which are not expected to be relevant for a closed connection. Retransmitting + the final packet requires less state at the server. + +Implementations SHOULD limit the number of CONNECTION_CLOSE messages they +generate. For instance, an implementation could exponentially increase the +number of packets that it receives before sending the packet containing +CONNECTION_CLOSE. Once enough time has passed to allow a peer to receive the +CONNECTION_CLOSE, an endpoint SHOULD discard per-connection state and MAY +instead rely on sending a stateless reset in response to any further incoming +packets. + + +### Stateless Reset {#stateless-reset} A stateless reset is provided as an option of last resort for a server that does not have access to the state of a connection. A server crash or outage might @@ -1526,7 +1549,7 @@ endpoint that wishes to communicate a fatal connection error MUST use a CONNECTION_CLOSE frame if it has sufficient state to do so. -### Detecting a Stateless Reset +#### Detecting a Stateless Reset A client detects a potential stateless reset when a packet with a short header cannot be decrypted. The client then performs a constant-time comparison of the @@ -1536,7 +1559,7 @@ the connection MUST be terminated immediately. Otherwise, the packet can be discarded. -### Calculating a Stateless Reset Token +#### Calculating a Stateless Reset Token The stateless reset token MUST be difficult to guess. In order to create a Stateless Reset Token, a server could randomly generate {{!RFC4086}} a secret From 8e420577bee7fe96bc34200eb823348b0596f1a4 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 11 Aug 2017 14:57:10 +1000 Subject: [PATCH 02/15] Split error code space This creates two orthogonal spaces for error codes. Application error codes can be used for both connection and stream errors and are under the control of the application protocol. Transport error codes are QUIC-controlled, but can only terminate the connection. To fix this, I had to add IANA considerations for error codes, plus a few extra tweaks. I think that the error code space could be narrowed to 16 bits after this, if only to keep things sane. Closes #132. --- draft-ietf-quic-tls.md | 41 ++++-- draft-ietf-quic-transport.md | 261 +++++++++++++++++++++-------------- 2 files changed, 188 insertions(+), 114 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 262abe6368..d107031922 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1505,11 +1505,13 @@ SHOULD track redundant packets and treat excessive volumes of any non-productive packets as indicative of an attack. -# Error codes {#errors} +# Error Codes {#errors} -The portion of the QUIC error code space allocated for the crypto handshake is -0xC0000000-0xFFFFFFFF. The following error codes are defined when TLS is used -for the crypto handshake: +This document defines error codes from the error code space used in +{{QUIC-TRANSPORT}}. To avoid collisions, these codes are defined in the range +0xC0000000-0xFFFFFFFF. + +The following error codes are defined when TLS is used for the crypto handshake: TLS_HANDSHAKE_FAILED (0xC000001C): : The TLS handshake failed. @@ -1523,24 +1525,35 @@ TLS_FATAL_ALERT_RECEIVED (0xC000001E): # IANA Considerations -This document does not create any new IANA registries, but it does utilize the -following registries: +This document does not create any new IANA registries, but it registers the +values in the following registries: -* QUIC Transport Parameter Registry - IANA is to register the three values found - in {{errors}}. +* QUIC Transport Error Codes Registry {{QUIC-TRANSPORT}} - IANA is to register + the three error codes found in {{errors}}, these are summarized in + {{iana-errors}}. -* TLS ExtensionsType Registry - IANA is to register the - quic_transport_parameters extension found in {{quic_parameters}}. Assigning - 26 to the extension would be greatly appreciated. The Recommended column is - to be marked Yes. +* TLS ExtensionsType Registry + {{!TLS-REGISTRIES=I-D.ietf-tls-iana-registry-updates}} - IANA is to register + the quic_transport_parameters extension found in {{quic_parameters}}. + Assigning 26 to the extension would be greatly appreciated. The Recommended + column is to be marked Yes. -* TLS Exporter Label Registry - IANA is requested to register - "EXPORTER-QUIC 0-RTT Secret" from {{zero-rtt-secrets}}; +* TLS Exporter Label Registry {{!TLS-REGISTRIES}} - IANA is requested to + register "EXPORTER-QUIC 0-RTT Secret" from {{zero-rtt-secrets}}; "EXPORTER-QUIC client 1-RTT Secret" and "EXPORTER-QUIC server 1-RTT Secret" from {{one-rtt-secrets}}; "EXPORTER-QUIC Packet Number Secret" {{packet-number-gaps}}. The DTLS column is to be marked No. The Recommended column is to be marked Yes. +| Value | Error | Description | Specification | +|:-----------|:--------------------------|:--------------| +| 0xC000001C | TLS_HANDSHAKE_FAILED | {{errors}} | +| 0xC000001D | TLS_FATAL_ALERT_GENERATED | {{errors}} | +| 0xC000001E | TLS_FATAL_ALERT_RECEIVED | {{errors}} | +{: #iana-errors title="QUIC Transport Error Codes for TLS"} + + + --- back # Contributors diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 63223d6736..b439b262ce 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -721,8 +721,8 @@ increase by at least one after sending any packet, unless otherwise specified A QUIC endpoint MUST NOT reuse a packet number within the same connection (that is, under the same cryptographic keys). If the packet number for sending reaches 2^64 - 1, the sender MUST close the connection without sending a -CONNECTION_CLOSE frame or any further packets; the sender MAY send a Public -Reset packet in response to further packets that it receives. +TRANSPORT_CLOSE frame or any further packets; the sender MAY send a Public Reset +packet in response to further packets that it receives. To reduce the number of bits required to represent the packet number over the wire, only the least significant bits of the packet number are transmitted. The @@ -844,7 +844,8 @@ explained in more detail as they are referenced later in the document. |:------------|:------------------|:----------------------------| | 0x00 | PADDING | {{frame-padding}} | | 0x01 | RST_STREAM | {{frame-rst-stream}} | -| 0x02 | CONNECTION_CLOSE | {{frame-connection-close}} | +| 0x02 | TRANSPORT_CLOSE | {{frame-transport-close}} | +| 0x03 | APPLICATION_CLOSE | {{frame-application-close}} | | 0x04 | MAX_DATA | {{frame-max-data}} | | 0x05 | MAX_STREAM_DATA | {{frame-max-stream-data}} | | 0x06 | MAX_STREAM_ID | {{frame-max-stream-id}} | @@ -1450,24 +1451,24 @@ connection state if they have neither sent nor received a packet for this time. The time at which an idle timeout takes effect won't be perfectly synchronized on peers. Endpoints might allow for the possibility that the remote side might attempt to send packets before the timeout. In this case, an endpoint might -choose to retain enough information to generate a CONNECTION_CLOSE. Endpoints -MAY instead rely on sending Public Reset in response to packets that arrive -after an idle timeout. +choose to retain enough information to generate a packet containing +TRANSPORT_CLOSE (see {{immediate-close}}). Endpoints MAY instead rely on +sending Public Reset in response to packets that arrive after an idle timeout. ### Immediate Close -An endpoint sends a CONNECTION_CLOSE frame to terminate the connection -immediately. A CONNECTION_CLOSE causes all open streams to immediately become -closed; open streams can be assumed to be implicitly reset. After receiving a -CONNECTION_CLOSE frame, endpoints MUST NOT send additional packets on that -connection. +An endpoint sends a TRANSPORT_CLOSE or APPLICATION_CLOSE frame to terminate the +connection immediately. These frames causes all open streams to immediately +become closed; open streams can be assumed to be implicitly reset. After +receiving a either a TRANSPORT_CLOSE or APPLICATION_CLOSE frame, endpoints MUST +NOT send additional packets on that connection. -An peer that receives a CONNECTION_CLOSE might have sent packets that will -arrive after the endpoint sends CONNECTION_CLOSE. An endpoint SHOULD respond to -these packets with another CONNECTION_CLOSE message. To minimize the state that -an endpoint maintains in this case, they MAY send the exact same -CONNECTION_CLOSE packet. +An peer that receives either close frame might have sent packets that will +arrive after the endpoint sent the packet. An endpoint SHOULD respond to these +packets with another TRANSPORT_CLOSE or APPLICATION_CLOSE frame. To minimize +the state that an endpoint maintains in this case, they MAY send the exact same +packet. Note: @@ -1477,11 +1478,11 @@ Note: which are not expected to be relevant for a closed connection. Retransmitting the final packet requires less state at the server. -Implementations SHOULD limit the number of CONNECTION_CLOSE messages they -generate. For instance, an implementation could exponentially increase the -number of packets that it receives before sending the packet containing -CONNECTION_CLOSE. Once enough time has passed to allow a peer to receive the -CONNECTION_CLOSE, an endpoint SHOULD discard per-connection state and MAY +Implementations SHOULD limit the number of packets they generate after sending +either TRANSPORT_CLOSE or APPLICATION_CLOSE. For instance, an implementation +could exponentially increase the number of packets that it receives before +sending another packet. Once enough time has passed to allow a peer to receive +the final packet, an endpoint SHOULD discard per-connection state and MAY instead rely on sending a stateless reset in response to any further incoming packets. @@ -1492,7 +1493,8 @@ A stateless reset is provided as an option of last resort for a server that does not have access to the state of a connection. A server crash or outage might result in clients continuing to send data to a server that is unable to properly continue the connection. A server that wishes to communicate a fatal connection -error MUST use a CONNECTION_CLOSE frame if it has sufficient state to do so. +error MUST use a TRANSPORT_CLOSE or APPLICATION_CLOSE frame if it has sufficient +state to do so. To support this process, the server sends a stateless_reset_token value during the handshake in the transport parameters. This value is protected by @@ -1546,7 +1548,7 @@ indistinguishable from a regular packet. A stateless reset is not appropriate for signaling error conditions. An endpoint that wishes to communicate a fatal connection error MUST use a -CONNECTION_CLOSE frame if it has sufficient state to do so. +TRANSPORT_CLOSE or APPLICATION_CLOSE frame if it has sufficient state to do so. #### Detecting a Stateless Reset @@ -1632,7 +1634,7 @@ The RST_STREAM frame is as follows: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Stream ID (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Error Code (32) | +| Application Protocol Error Code (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + Final Offset (64) + @@ -1646,43 +1648,51 @@ Stream ID: : The 32-bit Stream ID of the stream being terminated. -Error code: +Application Protocol Error Code: -: A 32-bit error code which indicates why the stream is being closed. +: A 32-bit application protocol error code (see {{app-error-codes}}) which + indicates why the stream is being closed. -Final offset: +Final Offset: : A 64-bit unsigned integer indicating the absolute byte offset of the end of data written on this stream by the RST_STREAM sender. -## CONNECTION_CLOSE frame {#frame-connection-close} +## TRANSPORT_CLOSE frame {#frame-transport-close} -An endpoint sends a CONNECTION_CLOSE frame (type=0x02) to notify its peer that -the connection is being closed. If there are open streams that haven't been -explicitly closed, they are implicitly closed when the connection is closed. -The frame is as follows: +An endpoint sends a TRANSPORT_CLOSE frame (type=0x02) to notify its peer that +the connection is being closed. TRANSPORT_CLOSE is used to signal errors at the +QUIC layer, or the absence of errors (with the NO_ERROR code). + +If there are open streams that haven't been explicitly closed, they are +implicitly closed when the connection is closed. + +The TRANSPORT_CLOSE frame is as follows: ~~~ 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Error Code (32) | +| Error Code (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Reason Phrase Length (16) | [Reason Phrase (*)] ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ -The fields of a CONNECTION_CLOSE frame are as follows: +The fields of a TRANSPORT_CLOSE frame are as follows: Error Code: : A 32-bit error code which indicates the reason for closing this connection. + TRANSPORT_CLOSE uses codes from the space defined in {{error-codes}}; + APPLICATION_CLOSE uses codes from the application protocol error code space + ({{app-error-codes}}). Reason Phrase Length: : A 16-bit unsigned number specifying the length of the reason phrase in bytes. - Note that a CONNECTION_CLOSE frame cannot be split between packets, so in + Note that a TRANSPORT_CLOSE frame cannot be split between packets, so in practice any limits on packet size will also limit the space available for a reason phrase. @@ -1693,6 +1703,17 @@ Reason Phrase: This SHOULD be a UTF-8 encoded string {{!RFC3629}}. +## APPLICATION_CLOSE frame {#frame-application-close} + +An APPLICATION_CLOSE frame (type=0x03) uses the same format as the +TRANSPORT_CLOSE frame ({{frame-transport-close}}), except that it uses error +codes from the application protocol error code space ({{app-error-codes}}) +instead of the transport error code space. + +Other than the error code space, the format and semantics of the +APPLICATION_CLOSE frame are identical to the TRANSPORT_CLOSE frame. + + ## MAX_DATA Frame {#frame-max-data} The MAX_DATA frame (type=0x04) is used in flow control to inform the peer of @@ -2650,11 +2671,10 @@ discarded upon receipt. This avoids potential ambiguity about which STREAM frames count toward flow control. Upon receipt of a STOP_SENDING frame on a stream in the "open" or "half-closed -(remote)" states, an endpoint MUST send a RST_STREAM with an error code of -QUIC_RECEIVED_RST. If the STOP_SENDING frame is received on a stream that is -already in the "half-closed (local)" or "closed" states, a RST_STREAM frame MAY -still be sent in order to cancel retransmission of previously-sent STREAM -frames. +(remote)" states, an endpoint MUST send a RST_STREAM frame. If the STOP_SENDING +frame is received on a stream that is already in the "half-closed (local)" or +"closed" states, a RST_STREAM frame MAY still be sent in order to cancel +retransmission of previously-sent STREAM frames. While STOP_SENDING frames are retransmittable, an implementation MAY choose not to retransmit a lost STOP_SENDING frame if the stream has already been closed @@ -2926,32 +2946,39 @@ frame that signals the error. Where this specification identifies error conditions, it also identifies the error code that is used. A stateless reset ({{stateless-reset}}) is not suitable for any error that can -be signaled with a CONNECTION_CLOSE or RST_STREAM frame. A stateless reset MUST -NOT be used by an endpoint that has the state necessary to send a frame on the -connection. +be signaled with a TRANSPORT_CLOSE, APPLICATION_CLOSE, or RST_STREAM frame. A +stateless reset MUST NOT be used by an endpoint that has the state necessary to +send a frame on the connection. ## Connection Errors Errors that result in the connection being unusable, such as an obvious violation of protocol semantics or corruption of state that affects an entire -connection, MUST be signaled using a CONNECTION_CLOSE frame -({{frame-connection-close}}). An endpoint MAY close the connection in this -manner, even if the error only affects a single stream. +connection, MUST be signaled using a TRANSPORT_CLOSE or APPLICATION_CLOSE frame +({{frame-transport-close}}, {{frame-application-close}}). An endpoint MAY close +the connection in this manner, even if the error only affects a single stream. -A CONNECTION_CLOSE frame could be sent in a packet that is lost. An endpoint -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. +Application protocols can signal application-specific protocol errors using the +APPLICATION_CLOSE frame. Errors that are specific to the transport, including +all those described in this document, are carried in a TRANSPORT_CLOSE frame. +Other than the type of error code they carry, these frames are identical in +format and semantics. -An endpoint that chooses not to retransmit packets containing CONNECTION_CLOSE -risks a peer missing the first such packet. The only mechanism available to an -endpoint that continues to receive data for a terminated connection is to use -the stateless reset process ({{stateless-reset}}). +A TRANSPORT_CLOSE or APPLICATION_CLOSE frame could be sent in a packet that is +lost. An endpoint SHOULD be prepared to retransmit a packet containing either +frame type 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 receives an invalid CONNECTION_CLOSE frame MUST NOT signal the -existence of the error to its peer. +An endpoint that chooses not to retransmit packets containing TRANSPORT_CLOSE or +APPLICATION_CLOSE risks a peer missing the first such packet. The only +mechanism available to an endpoint that continues to receive data for a +terminated connection is to use the stateless reset process +({{stateless-reset}}). + +An endpoint that receives an invalid TRANSPORT_CLOSE or APPLICATION_CLOSE frame +MUST NOT signal the existence of the error to its peer. ## Stream Errors @@ -2965,58 +2992,34 @@ Stream 0 is critical to the functioning of the entire connection. If stream 0 is closed with either a RST_STREAM or STREAM frame bearing the FIN flag, an endpoint MUST generate a connection error of type PROTOCOL_VIOLATION. -Some application protocols make other streams critical to that protocol. An -application protocol does not need to inform the transport that a stream is -critical; it can instead generate appropriate errors in response to being -notified that the critical stream is closed. - -An endpoint MAY send a RST_STREAM frame in the same packet as a CONNECTION_CLOSE -frame. - +A stream error is always an application-layer construct. A RST_STREAM MUST NOT +be generated by the QUIC transport layer. Resetting a stream at the transport +layer could cause unrecoverable loss of application protocol state. Application +protocols might require certain streams to be reliably delivered in order to +guarantee consistent state between endpoints. For this reason, all errors that +can be detected at the transport layer result in connection errors. -## Error Codes +An endpoint that detects a stream error MAY choose to treat the error as a +connection error and send an APPLICATION_CLOSE frame in place of RST_STREAM. -Error codes are 32 bits long, with the first two bits indicating the source of -the error code: -0x00000000-0x3FFFFFFF: -: Application-specific error codes. Defined by each application-layer protocol. +## Transport Error Codes {#error-codes} -0x40000000-0x7FFFFFFF: -: Reserved for host-local error codes. These codes MUST NOT be sent to a peer, - but MAY be used in API return codes and logs. - -0x80000000-0xBFFFFFFF: -: QUIC transport error codes, including packet protection errors. Applicable to - all uses of QUIC. - -0xC0000000-0xFFFFFFFF: -: Cryptographic error codes. Defined by the cryptographic handshake protocol - in use. +Transport error codes are 32 bits long. This section lists the defined QUIC transport error codes that may be used in a -CONNECTION_CLOSE or RST_STREAM frame. Error codes share a common code space. -Some error codes apply only to either streams or the entire connection and have -no defined semantics in the other context. +TRANSPORT_CLOSE frame. These errors apply to the entire connection. NO_ERROR (0x80000000): -: An endpoint uses this with CONNECTION_CLOSE to signal that the connection is - being closed abruptly in the absence of any error. An endpoint uses this with - RST_STREAM to signal that the stream is no longer wanted or in response to the - receipt of a RST_STREAM for that stream. +: An endpoint uses this with TRANSPORT_CLOSE to signal that the connection is + being closed abruptly in the absence of any error. INTERNAL_ERROR (0x80000001): : The endpoint encountered an internal error and cannot continue with the connection. -CANCELLED (0x80000002): - -: An endpoint sends this with RST_STREAM to indicate that the stream is not - wanted and that no application action was taken for the stream. This error - code is not valid for use with CONNECTION_CLOSE. - FLOW_CONTROL_ERROR (0x80000003): : An endpoint received more data than it permitted in its advertised data limits @@ -3065,10 +3068,6 @@ PROTOCOL_VIOLATION (0x8000000A): : An endpoint detected an error with protocol compliance that was not covered by more specific error codes. -QUIC_RECEIVED_RST (0x80000035): - -: Terminating stream because peer sent a RST_STREAM or STOP_SENDING. - FRAME_ERROR (0x800001XX): : An endpoint detected an error in a specific frame type. The frame type is @@ -3076,6 +3075,18 @@ FRAME_ERROR (0x800001XX): MAX_STREAM_ID frame would be indicated with the code (0x80000106). +## Application Protocol Error Codes {#app-error-codes} + +Application protocol error codes are 32-bits long, but the management of +application error codes are left to application protocols. Application protocol +error codes are used for the RST_STREAM ({{frame-rst-stream}}) and +APPLICATION_CLOSE ({{frame-application-close}}) frames. + +Application protocols SHOULD define an error codes for use when sending a +RST_STREAM in response to a STOP_SENDING frame. Otherwise, there is no +restriction on the use of the 32-bit error code space for application protocols. + + # Security and Privacy Considerations ## Spoofed ACK Attack @@ -3194,8 +3205,7 @@ accessible. The 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 initial contents of this registry are shown in -{{iana-tp-table}}. +The initial contents of this registry are shown in {{iana-tp-table}}. | Value | Parameter Name | Specification | |:-------|:------------------------|:------------------------------------| @@ -3209,6 +3219,57 @@ The initial contents of this registry are shown in {: #iana-tp-table title="Initial QUIC Transport Parameters Entries"} +## QUIC Transport Error Codes Registry {#iana-error-codes} + +IANA \[SHALL add/has added] a registry for "QUIC Transport Error Codes" under a +"QUIC Protocol" heading. + +The "QUIC Transport Error Codes" registry governs a 32-bit space. This space is +split into two spaces that are governed by different policies. Values with the +first byte in the range 0x00 to 0xfe (in hexadecimal) are assigned via the +Specification Required policy {{!RFC5226}}. Values with the first byte 0xff are +reserved for Private Use {{!RFC5226}}. + +Registrations MUST include the following fields: + +Value: + +: The numeric value of the assignment (registrations will be between 0x00000000 + and 0xfeffffff). + +Code: + +: A short mnemonic for the parameter. + +Description: + +: A brief description of the error code semantics, which MAY be a summary if a + specification reference is provided. + +Specification: + +: A reference to a publicly available specification for the value. + +The initial contents of this registry are shown in {{iana-error-table}}. Note +that FRAME_ERROR takes the range from 0x80000100 to 0x800001ff and private use +occupies the range from 0xfe000000 to 0xffffffff. + +| Value | Error | Description | Specification | +|:------------|:--------------------------|:------------------------------|:----------------| +| 0x0 | NO_ERROR | No error | {{error-codes}} | +| 0x1 | INTERNAL_ERROR | Implementation error | {{error-codes}} | +| 0x3 | FLOW_CONTROL_ERROR | Flow control error | {{error-codes}} | +| 0x4 | STREAM_ID_ERROR | Invalid stream ID | {{error-codes}} | +| 0x5 | STREAM_STATE_ERROR | Frame received in invalid stream state | {{error-codes}} | +| 0x6 | FINAL_OFFSET_ERROR | Change to final stream offset | {{error-codes}} | +| 0x7 | FRAME_FORMAT_ERROR | Generic frame format 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}} | +| 0x100-0x1FF | FRAME_ERROR | Specific frame format error | {{error-codes}} | +{: #iana-error-table title="Initial QUIC Transport Error Codes Entries"} + + --- back # Contributors From b6e9172086f74bd897f35f5a9d18517fd71e1873 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 11 Aug 2017 15:00:56 +1000 Subject: [PATCH 03/15] s/Public Reset/Stateless Reset/ --- 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 b439b262ce..192678dee7 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -721,8 +721,8 @@ increase by at least one after sending any packet, unless otherwise specified A QUIC endpoint MUST NOT reuse a packet number within the same connection (that is, under the same cryptographic keys). If the packet number for sending reaches 2^64 - 1, the sender MUST close the connection without sending a -TRANSPORT_CLOSE frame or any further packets; the sender MAY send a Public Reset -packet in response to further packets that it receives. +TRANSPORT_CLOSE frame or any further packets; the sender MAY send a Stateless +Reset packet in response to further packets that it receives. To reduce the number of bits required to represent the packet number over the wire, only the least significant bits of the packet number are transmitted. The @@ -1453,7 +1453,8 @@ on peers. Endpoints might allow for the possibility that the remote side might attempt to send packets before the timeout. In this case, an endpoint might choose to retain enough information to generate a packet containing TRANSPORT_CLOSE (see {{immediate-close}}). Endpoints MAY instead rely on -sending Public Reset in response to packets that arrive after an idle timeout. +sending Stateless Reset in response to packets that arrive after an idle +timeout. ### Immediate Close From 5e3029f9546cf79bdd24815c419260d5a1775a75 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 11 Aug 2017 15:07:10 +1000 Subject: [PATCH 04/15] Get codes consistent --- draft-ietf-quic-transport.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 192678dee7..7462ffb0ca 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -3011,32 +3011,32 @@ Transport error codes are 32 bits long. This section lists the defined QUIC transport error codes that may be used in a TRANSPORT_CLOSE frame. These errors apply to the entire connection. -NO_ERROR (0x80000000): +NO_ERROR (0x0): : An endpoint uses this with TRANSPORT_CLOSE to signal that the connection is being closed abruptly in the absence of any error. -INTERNAL_ERROR (0x80000001): +INTERNAL_ERROR (0x1): : The endpoint encountered an internal error and cannot continue with the connection. -FLOW_CONTROL_ERROR (0x80000003): +FLOW_CONTROL_ERROR (0x3): : An endpoint received more data than it permitted in its advertised data limits (see {{flow-control}}). -STREAM_ID_ERROR (0x80000004): +STREAM_ID_ERROR (0x4): : An endpoint received a frame for a stream identifier that exceeded its advertised maximum stream ID. -STREAM_STATE_ERROR (0x80000005): +STREAM_STATE_ERROR (0x5): : An endpoint received a frame for a stream that was not in a state that permitted that frame (see {{stream-states}}). -FINAL_OFFSET_ERROR (0x80000006): +FINAL_OFFSET_ERROR (0x6): : An endpoint received a STREAM frame containing data that exceeded the previously established final offset. Or an endpoint received a RST_STREAM @@ -3044,36 +3044,36 @@ FINAL_OFFSET_ERROR (0x80000006): that was already received. Or an endpoint received a RST_STREAM frame containing a different final offset to the one already established. -FRAME_FORMAT_ERROR (0x80000007): +FRAME_FORMAT_ERROR (0x7): : An endpoint received a frame that was badly formatted. For instance, an empty STREAM frame that omitted the FIN flag, or an ACK frame that has more acknowledgment ranges than the remainder of the packet could carry. This is a generic error code; an endpoint SHOULD use the more specific frame format - error codes (0x800001XX) if possible. + error codes (0x1XX) if possible. -TRANSPORT_PARAMETER_ERROR (0x80000008): +TRANSPORT_PARAMETER_ERROR (0x8): : An endpoint received transport parameters that were badly formatted, included an invalid value, was absent even though it is mandatory, was present though it is forbidden, or is otherwise in error. -VERSION_NEGOTIATION_ERROR (0x80000009): +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 (0x8000000A): +PROTOCOL_VIOLATION (0xA): : An endpoint detected an error with protocol compliance that was not covered by more specific error codes. -FRAME_ERROR (0x800001XX): +FRAME_ERROR (0x1XX): : An endpoint detected an error in a specific frame type. The frame type is included as the last octet of the error code. For example, an error in a - MAX_STREAM_ID frame would be indicated with the code (0x80000106). + MAX_STREAM_ID frame would be indicated with the code (0x106). ## Application Protocol Error Codes {#app-error-codes} @@ -3252,8 +3252,8 @@ Specification: : A reference to a publicly available specification for the value. The initial contents of this registry are shown in {{iana-error-table}}. Note -that FRAME_ERROR takes the range from 0x80000100 to 0x800001ff and private use -occupies the range from 0xfe000000 to 0xffffffff. +that FRAME_ERROR takes the range from 0x100 to 0x1FF and private use occupies +the range from 0XFE000000 to 0XFFFFFFFF. | Value | Error | Description | Specification | |:------------|:--------------------------|:------------------------------|:----------------| From 65308ffb40a39e3bfd6a9433e2514bb070f94306 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 11 Aug 2017 15:15:17 +1000 Subject: [PATCH 05/15] Make STOP_SENDING application-specific as well --- draft-ietf-quic-transport.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 7462ffb0ca..952ac25074 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1635,7 +1635,7 @@ The RST_STREAM frame is as follows: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Stream ID (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Application Protocol Error Code (32) | +| App Protocol Error Code (16) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + Final Offset (64) + @@ -1943,7 +1943,7 @@ follows: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Stream ID (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Error Code (32) | +| App Error Code (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ @@ -1952,8 +1952,9 @@ The fields are: Stream ID: : The 32-bit Stream ID of the stream being ignored. -Error Code: -: The application-specified reason the sender is ignoring the stream. +App Error Code: +: A 32-bit, application-specified reason the sender is ignoring the stream (see + {{app-error-codes}}). ## ACK Frame {#frame-ack} @@ -3075,6 +3076,8 @@ FRAME_ERROR (0x1XX): included as the last octet of the error code. For example, an error in a MAX_STREAM_ID frame would be indicated with the code (0x106). +See {{iana-error-codes}} for details of registering new error codes. + ## Application Protocol Error Codes {#app-error-codes} @@ -3083,9 +3086,10 @@ application error codes are left to application protocols. Application protocol error codes are used for the RST_STREAM ({{frame-rst-stream}}) and APPLICATION_CLOSE ({{frame-application-close}}) frames. -Application protocols SHOULD define an error codes for use when sending a -RST_STREAM in response to a STOP_SENDING frame. Otherwise, there is no -restriction on the use of the 32-bit error code space for application protocols. +Application protocols SHOULD define an error codes for indicating no error and +for use when sending a RST_STREAM in response to a STOP_SENDING frame. +Otherwise, there is no restriction on the use of the 16-bit error code space for +application protocols. # Security and Privacy Considerations From 49c3d5fc8f2c79aefc5620d103cfc1f5ba03678b Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 11 Aug 2017 15:16:25 +1000 Subject: [PATCH 06/15] Split errors in HTTP too --- draft-ietf-quic-http.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index d9078162ae..79e3e719d0 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -846,16 +846,15 @@ length as a connection error of type HTTP_MALFORMED_MAX_PUSH_ID. QUIC allows the application to abruptly terminate (reset) individual streams or the entire connection when an error is encountered. These are referred to as "stream errors" or "connection errors" and are described in more detail in -[QUIC-TRANSPORT]. +{{QUIC-TRANSPORT}}. This section describes HTTP-specific error codes which can be used to express the cause of a connection or stream error. ## HTTP-Defined QUIC Error Codes {#http-error-codes} -QUIC allocates error codes 0x0000-0x3FFF to application protocol definition. The -following error codes are defined by HTTP for use in QUIC RST_STREAM and -CONNECTION_CLOSE frames. +The following error codes are defined by HTTP for use in QUIC RST_STREAM and +APPLICATION_CLOSE frames. HTTP_PUSH_REFUSED (0x01): : The server has attempted to push content which the client will not accept @@ -1244,7 +1243,7 @@ The entries in the following table are registered by this document. ## Error Codes {#iana-error-codes} This document establishes a registry for HTTP/QUIC error codes. The -"HTTP/QUIC Error Code" registry manages a 30-bit space. The "HTTP/QUIC +"HTTP/QUIC Error Code" registry manages a 32-bit space. The "HTTP/QUIC Error Code" registry operates under the "Expert Review" policy {{?RFC5226}}. @@ -1259,7 +1258,7 @@ Name: : A name for the error code. Specifying an error code name is optional. Code: -: The 30-bit error code value. +: The 32-bit error code value. Description: : A brief description of the error code semantics, longer if no detailed From 7e1397efea19538b6d58291dd45a296f560b0527 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 11 Aug 2017 15:18:39 +1000 Subject: [PATCH 07/15] Refine description of HTTP codes --- draft-ietf-quic-http.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 79e3e719d0..2f2590df3f 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -851,10 +851,10 @@ the entire connection when an error is encountered. These are referred to as This section describes HTTP-specific error codes which can be used to express the cause of a connection or stream error. -## HTTP-Defined QUIC Error Codes {#http-error-codes} +## HTTP/QUIC Error Codes {#http-error-codes} -The following error codes are defined by HTTP for use in QUIC RST_STREAM and -APPLICATION_CLOSE frames. +The following error codes are defined for use in QUIC RST_STREAM and +APPLICATION_CLOSE frames when using HTTP/QUIC. HTTP_PUSH_REFUSED (0x01): : The server has attempted to push content which the client will not accept From 2396a4ed45c357b4985603cae4f6983769bae5e3 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 11 Aug 2017 15:21:00 +1000 Subject: [PATCH 08/15] Move TLS errors closer --- draft-ietf-quic-tls.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index d107031922..261ab7bf2c 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1508,18 +1508,17 @@ packets as indicative of an attack. # Error Codes {#errors} This document defines error codes from the error code space used in -{{QUIC-TRANSPORT}}. To avoid collisions, these codes are defined in the range -0xC0000000-0xFFFFFFFF. +{{QUIC-TRANSPORT}}. The following error codes are defined when TLS is used for the crypto handshake: -TLS_HANDSHAKE_FAILED (0xC000001C): +TLS_HANDSHAKE_FAILED (0x201): : The TLS handshake failed. -TLS_FATAL_ALERT_GENERATED (0xC000001D): +TLS_FATAL_ALERT_GENERATED (0x202): : A TLS fatal alert was sent, causing the TLS connection to end prematurely. -TLS_FATAL_ALERT_RECEIVED (0xC000001E): +TLS_FATAL_ALERT_RECEIVED (0x203): : A TLS fatal alert was received, causing the TLS connection to end prematurely. @@ -1545,11 +1544,11 @@ values in the following registries: {{packet-number-gaps}}. The DTLS column is to be marked No. The Recommended column is to be marked Yes. -| Value | Error | Description | Specification | -|:-----------|:--------------------------|:--------------| -| 0xC000001C | TLS_HANDSHAKE_FAILED | {{errors}} | -| 0xC000001D | TLS_FATAL_ALERT_GENERATED | {{errors}} | -| 0xC000001E | TLS_FATAL_ALERT_RECEIVED | {{errors}} | +| Value | Error | Description | Specification | +|:------|:--------------------------|:----------------------|:--------------| +| 0x201 | TLS_HANDSHAKE_FAILED | TLS handshake failure | {{errors}} | +| 0x202 | TLS_FATAL_ALERT_GENERATED | Sent TLS alert | {{errors}} | +| 0x203 | TLS_FATAL_ALERT_RECEIVED | Receives TLS alert | {{errors}} | {: #iana-errors title="QUIC Transport Error Codes for TLS"} From 99633e65a74613ae8862bccb41eba527e405dffb Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 11 Aug 2017 15:25:44 +1000 Subject: [PATCH 09/15] Match the names --- 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 952ac25074..215883f405 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1649,7 +1649,7 @@ Stream ID: : The 32-bit Stream ID of the stream being terminated. -Application Protocol Error Code: +App Protocol Error Code: : A 32-bit application protocol error code (see {{app-error-codes}}) which indicates why the stream is being closed. From 9be383bd88b1bace90ffd17bd7075c8ad0c35785 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 11 Aug 2017 15:29:44 +1000 Subject: [PATCH 10/15] Add HTTP_NO_ERROR --- draft-ietf-quic-http.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 2f2590df3f..5c43acd7d8 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -856,6 +856,10 @@ the cause of a connection or stream error. The following error codes are defined for use in QUIC RST_STREAM and APPLICATION_CLOSE frames when using HTTP/QUIC. +HTTP_NO_ERROR (0x00): +: No error. This is used when the connection or stream needs to be closed, but + there is no error to signal. + HTTP_PUSH_REFUSED (0x01): : The server has attempted to push content which the client will not accept on this connection. @@ -1066,7 +1070,7 @@ The HTTP/2 error codes defined in Section 7 of {{!RFC7540}} map to QUIC error codes as follows: NO_ERROR (0x0): -: QUIC_NO_ERROR +: HTTP_NO_ERROR PROTOCOL_ERROR (0x1): : No single mapping. See new HTTP_MALFORMED_* error codes defined in @@ -1272,6 +1276,7 @@ The entries in the following table are registered by this document. |-----------------------------------|--------|----------------------------------------|----------------------| | Name | Code | Description | Specification | |-----------------------------------|--------|----------------------------------------|----------------------| +| HTTP_NO_ERROR | 0x00 | No error | {{http-error-codes}} | | HTTP_PUSH_REFUSED | 0x01 | Client refused pushed content | {{http-error-codes}} | | HTTP_INTERNAL_ERROR | 0x02 | Internal error | {{http-error-codes}} | | HTTP_PUSH_ALREADY_IN_CACHE | 0x03 | Pushed content already cached | {{http-error-codes}} | From d687a9aae47258dca51db9b5a3d63494a1014fbf Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 15 Aug 2017 11:21:05 +1000 Subject: [PATCH 11/15] Review comments --- draft-ietf-quic-tls.md | 2 +- draft-ietf-quic-transport.md | 36 +++++++++++++++--------------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/draft-ietf-quic-tls.md b/draft-ietf-quic-tls.md index 261ab7bf2c..118483fd6c 100644 --- a/draft-ietf-quic-tls.md +++ b/draft-ietf-quic-tls.md @@ -1507,7 +1507,7 @@ packets as indicative of an attack. # Error Codes {#errors} -This document defines error codes from the error code space used in +This section defines error codes from the error code space used in {{QUIC-TRANSPORT}}. The following error codes are defined when TLS is used for the crypto handshake: diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 215883f405..afd8ae0dfc 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1635,7 +1635,7 @@ The RST_STREAM frame is as follows: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Stream ID (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| App Protocol Error Code (16) | +| App Protocol Error Code (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | + Final Offset (64) + @@ -1934,8 +1934,9 @@ Stateless Reset Token: An endpoint may use a STOP_SENDING frame (type=0x0c) to communicate that incoming data is being discarded on receipt at application request. This -signals a peer to abruptly terminate transmission on a stream. The frame is as -follows: +signals a peer to abruptly terminate transmission on a stream. + +The STOP_SENDING frame is as follows: ~~~ 0 1 2 3 @@ -1956,6 +1957,7 @@ App Error Code: : A 32-bit, application-specified reason the sender is ignoring the stream (see {{app-error-codes}}). + ## ACK Frame {#frame-ack} Receivers send ACK frames to inform senders which packets they have received and @@ -2971,12 +2973,8 @@ A TRANSPORT_CLOSE or APPLICATION_CLOSE frame could be sent in a packet that is lost. An endpoint SHOULD be prepared to retransmit a packet containing either frame type 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 TRANSPORT_CLOSE or -APPLICATION_CLOSE risks a peer missing the first such packet. The only -mechanism available to an endpoint that continues to receive data for a -terminated connection is to use the stateless reset process +limits the effort expended on terminated connections. An endpoint that does not +retransmit this packet could be forced to use the stateless reset process ({{stateless-reset}}). An endpoint that receives an invalid TRANSPORT_CLOSE or APPLICATION_CLOSE frame @@ -2994,15 +2992,11 @@ Stream 0 is critical to the functioning of the entire connection. If stream 0 is closed with either a RST_STREAM or STREAM frame bearing the FIN flag, an endpoint MUST generate a connection error of type PROTOCOL_VIOLATION. -A stream error is always an application-layer construct. A RST_STREAM MUST NOT -be generated by the QUIC transport layer. Resetting a stream at the transport -layer could cause unrecoverable loss of application protocol state. Application -protocols might require certain streams to be reliably delivered in order to -guarantee consistent state between endpoints. For this reason, all errors that -can be detected at the transport layer result in connection errors. - -An endpoint that detects a stream error MAY choose to treat the error as a -connection error and send an APPLICATION_CLOSE frame in place of RST_STREAM. +RST_STREAM MUST be instigated by the application and MUST carry an application +error code. Resetting a stream without knowledge of the application protocol +could cause the protocol to enter an unrecoverable state. Application protocols +might require certain streams to be reliably delivered in order to guarantee +consistent state between endpoints. ## Transport Error Codes {#error-codes} @@ -3086,9 +3080,9 @@ application error codes are left to application protocols. Application protocol error codes are used for the RST_STREAM ({{frame-rst-stream}}) and APPLICATION_CLOSE ({{frame-application-close}}) frames. -Application protocols SHOULD define an error codes for indicating no error and -for use when sending a RST_STREAM in response to a STOP_SENDING frame. -Otherwise, there is no restriction on the use of the 16-bit error code space for +Application protocols SHOULD define error codes for indicating no error and for +use when sending a RST_STREAM in response to a STOP_SENDING frame. Otherwise, +there is no restriction on the use of the 16-bit error code space for application protocols. From 790c6d7d8bdb8e0183363559d5534b5e428b93e9 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Mon, 4 Sep 2017 14:45:10 +1000 Subject: [PATCH 12/15] Move STOP_SENDING to HTTP/QUIC This is really an application-layer concept because it deals with the cancellation of streams and the transport should never be doing that. Closes #758. --- draft-ietf-quic-http.md | 51 ++++++++++++++++++++++++ draft-ietf-quic-transport.md | 77 +++++------------------------------- 2 files changed, 61 insertions(+), 67 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 5c43acd7d8..16f0d0ebbc 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -389,6 +389,23 @@ HTTP_PUSH_ALREADY_IN_CACHE; see {{errors}}). This asks the server not to transfer the data and indicates that it will be discarded upon receipt. +## Solicited Stream Cancellation + +If an endpoint is no longer interested in the data being received, it MAY send a +STOP_SENDING frame to request prompt closure of the stream in the opposite +direction. This typically indicates that the receiving application is no longer +reading from the stream, but does not guarantee that incoming data will be +ignored. + +Upon receipt of a STOP_SENDING frame on a stream in the "open" or "half-closed +(remote)" states, an endpoint MUST send a QUIC RST_STREAM frame. If the +STOP_SENDING frame is received on a stream that is already in the "half-closed +(local)" or "closed" states, a RST_STREAM frame MAY still be sent in order to +cancel retransmission of previously-sent STREAM frames. Sending a STOP_SENDING +frame has no effect on the state of the QUIC stream until the RST_STREAM frame +is sent. + + # HTTP Framing Layer {#http-framing-layer} Frames are used on each stream. This section describes HTTP framing in QUIC and @@ -841,6 +858,38 @@ A server MUST treat a MAX_PUSH_ID frame payload that is other than 4 octets in length as a connection error of type HTTP_MALFORMED_MAX_PUSH_ID. +## STOP_SENDING Frame {#frame-stop-sending} + +An endpoint may use a STOP_SENDING frame (type=0x0E) to communicate that +incoming data is being discarded on receipt at application request. This +requests that the recipient send a RST_STREAM on the identified stream. + +STOP_SENDING is sent on the control stream. An endpoint MUST treat receipt of +STOP_SENDING on any other stream as a connection error of type +HTTP_WRONG_STREAM. + +The STOP_SENDING frame is as follows: + +~~~ 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 ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Stream ID (32) | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Error Code (32) | ++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +~~~ + +The fields are: + +Stream ID: +: The 32-bit Stream ID of the stream being ignored. + +Error Code: +: A 32-bit error code containing the reason for requesting that the stream be + reset (see {{http-error-codes}}). + + # Error Handling {#errors} QUIC allows the application to abruptly terminate (reset) individual streams or @@ -1203,6 +1252,7 @@ The entries in the following table are registered by this document. | Reserved | 0x8 | N/A | | Reserved | 0x9 | N/A | | MAX_PUSH_ID | 0xD | {{frame-max-push-id}} | +| STOP_SENDING | 0xE | {{frame-stop-sending}} | |----------------|------|--------------------------| ## Settings Parameters {#iana-settings} @@ -1312,6 +1362,7 @@ The original authors of this specification were Robbie Shade and Mike Warres. ## Since draft-ietf-quic-http-05 - Made push ID sequential, add MAX_PUSH_ID, remove SETTINGS_ENABLE_PUSH (#709) +- Added STOP_SENDING frame (#758) ## Since draft-ietf-quic-http-04 diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index afd8ae0dfc..b260522fe0 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -854,7 +854,6 @@ explained in more detail as they are referenced later in the document. | 0x09 | STREAM_BLOCKED | {{frame-stream-blocked}} | | 0x0a | STREAM_ID_NEEDED | {{frame-stream-id-needed}} | | 0x0b | NEW_CONNECTION_ID | {{frame-new-connection-id}} | -| 0x0c | STOP_SENDING | {{frame-stop-sending}} | | 0xa0 - 0xbf | ACK | {{frame-ack}} | | 0xc0 - 0xff | STREAM | {{frame-stream}} | {: #frame-types title="Frame Types"} @@ -1930,34 +1929,6 @@ Stateless Reset Token: connection ID is used (see {{stateless-reset}}). -## STOP_SENDING Frame {#frame-stop-sending} - -An endpoint may use a STOP_SENDING frame (type=0x0c) to communicate that -incoming data is being discarded on receipt at application request. This -signals a peer to abruptly terminate transmission on a stream. - -The STOP_SENDING frame is as follows: - -~~~ - 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 ID (32) | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| App Error Code (32) | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -~~~ - -The fields are: - -Stream ID: -: The 32-bit Stream ID of the stream being ignored. - -App Error Code: -: A 32-bit, application-specified reason the sender is ignoring the stream (see - {{app-error-codes}}). - - ## ACK Frame {#frame-ack} Receivers send ACK frames to inform senders which packets they have received and @@ -2388,9 +2359,6 @@ When a packet is detected as lost, the sender re-sends any frames as necessary: * ACK and PADDING frames MUST NOT be retransmitted. ACK frames containing updated information will be sent as described in {{frame-ack}}. -* STOP_SENDING frames MUST be retransmitted, unless the stream has become closed - in the appropriate direction. See {{solicited-state-transitions}}. - * All other frames MUST be retransmitted. Upon detecting losses, a sender MUST take appropriate congestion control action. @@ -2605,8 +2573,8 @@ Any frame type that mentions a stream ID can be sent in this state. A stream that is in the "half-closed (local)" state MUST NOT be used for sending on new STREAM frames. Retransmission of data that has already been sent on -STREAM frames is permitted. An endpoint MAY also send MAX_STREAM_DATA and -STOP_SENDING in this state. +STREAM frames is permitted. An endpoint MAY also send MAX_STREAM_DATA in this +state. An endpoint that closes a stream MUST NOT send data beyond the final offset that it has chosen, see {{state-closed}} for details. @@ -2661,31 +2629,6 @@ Reordering might cause frames to be received after closing, see {{state-hc-remote}}. -## Solicited State Transitions - -If an endpoint is no longer interested in the data being received, it MAY send a -STOP_SENDING frame on a stream in the "open" or "half-closed (local)" state to -prompt closure of the stream in the opposite direction. This typically -indicates that the receiving application is no longer reading from the stream, -but is not a guarantee that incoming data will be ignored. - -STREAM frames received after sending STOP_SENDING are still counted toward the -connection and stream flow-control windows, even though these frames will be -discarded upon receipt. This avoids potential ambiguity about which STREAM -frames count toward flow control. - -Upon receipt of a STOP_SENDING frame on a stream in the "open" or "half-closed -(remote)" states, an endpoint MUST send a RST_STREAM frame. If the STOP_SENDING -frame is received on a stream that is already in the "half-closed (local)" or -"closed" states, a RST_STREAM frame MAY still be sent in order to cancel -retransmission of previously-sent STREAM frames. - -While STOP_SENDING frames are retransmittable, an implementation MAY choose not -to retransmit a lost STOP_SENDING frame if the stream has already been closed -in the appropriate direction since the frame was first generated. -See {{packetization}}. - - ## Stream Concurrency {#stream-concurrency} An endpoint limits the number of concurrently active incoming streams by @@ -2858,9 +2801,10 @@ controller. RST_STREAM terminates one direction of a stream abruptly. Whether any action or response can or should be taken on the data already received is an application-specific issue, but it will often be the case that upon receipt of a -RST_STREAM an endpoint will choose to stop sending data in its own direction. If -the sender of a RST_STREAM wishes to explicitly state that no future data will -be processed, that endpoint MAY send a STOP_SENDING frame at the same time. +RST_STREAM an endpoint will choose to stop sending data in its own direction. +Application protocols might define a mechanism to request that a peer send a +RST_STREAM for cases where stream data is no longer wanted. + ### Data Limit Increments {#fc-credit} @@ -3080,11 +3024,6 @@ application error codes are left to application protocols. Application protocol error codes are used for the RST_STREAM ({{frame-rst-stream}}) and APPLICATION_CLOSE ({{frame-application-close}}) frames. -Application protocols SHOULD define error codes for indicating no error and for -use when sending a RST_STREAM in response to a STOP_SENDING frame. Otherwise, -there is no restriction on the use of the 16-bit error code space for -application protocols. - # Security and Privacy Considerations @@ -3304,6 +3243,10 @@ Issue and pull request numbers are listed with a leading octothorp. ## Since draft-ietf-quic-transport-04 +- Removed STOP_SENDING frame (#758) + +## Since draft-ietf-quic-transport-04 + - Introduce STOP_SENDING frame, RST_STREAM only resets in one direction (#165) - Removed GOAWAY; application protocols are responsible for graceful shutdown (#696) From 2cff85c9d30eb4701b83890e36dec159e8208cc1 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Wed, 6 Sep 2017 11:21:33 +1000 Subject: [PATCH 13/15] Jana's comments --- draft-ietf-quic-transport.md | 76 ++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index afd8ae0dfc..75a7dea562 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -721,7 +721,7 @@ increase by at least one after sending any packet, unless otherwise specified A QUIC endpoint MUST NOT reuse a packet number within the same connection (that is, under the same cryptographic keys). If the packet number for sending reaches 2^64 - 1, the sender MUST close the connection without sending a -TRANSPORT_CLOSE frame or any further packets; the sender MAY send a Stateless +CONNECTION_CLOSE frame or any further packets; the sender MAY send a Stateless Reset packet in response to further packets that it receives. To reduce the number of bits required to represent the packet number over the @@ -844,7 +844,7 @@ explained in more detail as they are referenced later in the document. |:------------|:------------------|:----------------------------| | 0x00 | PADDING | {{frame-padding}} | | 0x01 | RST_STREAM | {{frame-rst-stream}} | -| 0x02 | TRANSPORT_CLOSE | {{frame-transport-close}} | +| 0x02 | CONNECTION_CLOSE | {{frame-connection-close}} | | 0x03 | APPLICATION_CLOSE | {{frame-application-close}} | | 0x04 | MAX_DATA | {{frame-max-data}} | | 0x05 | MAX_STREAM_DATA | {{frame-max-stream-data}} | @@ -1452,22 +1452,22 @@ The time at which an idle timeout takes effect won't be perfectly synchronized on peers. Endpoints might allow for the possibility that the remote side might attempt to send packets before the timeout. In this case, an endpoint might choose to retain enough information to generate a packet containing -TRANSPORT_CLOSE (see {{immediate-close}}). Endpoints MAY instead rely on +CONNECTION_CLOSE (see {{immediate-close}}). Endpoints MAY instead rely on sending Stateless Reset in response to packets that arrive after an idle timeout. ### Immediate Close -An endpoint sends a TRANSPORT_CLOSE or APPLICATION_CLOSE frame to terminate the +An endpoint sends a CONNECTION_CLOSE or APPLICATION_CLOSE frame to terminate the connection immediately. These frames causes all open streams to immediately become closed; open streams can be assumed to be implicitly reset. After -receiving a either a TRANSPORT_CLOSE or APPLICATION_CLOSE frame, endpoints MUST +receiving a either a CONNECTION_CLOSE or APPLICATION_CLOSE frame, endpoints MUST NOT send additional packets on that connection. An peer that receives either close frame might have sent packets that will arrive after the endpoint sent the packet. An endpoint SHOULD respond to these -packets with another TRANSPORT_CLOSE or APPLICATION_CLOSE frame. To minimize +packets with another CONNECTION_CLOSE or APPLICATION_CLOSE frame. To minimize the state that an endpoint maintains in this case, they MAY send the exact same packet. @@ -1480,7 +1480,7 @@ Note: the final packet requires less state at the server. Implementations SHOULD limit the number of packets they generate after sending -either TRANSPORT_CLOSE or APPLICATION_CLOSE. For instance, an implementation +either CONNECTION_CLOSE or APPLICATION_CLOSE. For instance, an implementation could exponentially increase the number of packets that it receives before sending another packet. Once enough time has passed to allow a peer to receive the final packet, an endpoint SHOULD discard per-connection state and MAY @@ -1494,8 +1494,8 @@ A stateless reset is provided as an option of last resort for a server that does not have access to the state of a connection. A server crash or outage might result in clients continuing to send data to a server that is unable to properly continue the connection. A server that wishes to communicate a fatal connection -error MUST use a TRANSPORT_CLOSE or APPLICATION_CLOSE frame if it has sufficient -state to do so. +error MUST use a CONNECTION_CLOSE or APPLICATION_CLOSE frame if it has +sufficient state to do so. To support this process, the server sends a stateless_reset_token value during the handshake in the transport parameters. This value is protected by @@ -1549,7 +1549,7 @@ indistinguishable from a regular packet. A stateless reset is not appropriate for signaling error conditions. An endpoint that wishes to communicate a fatal connection error MUST use a -TRANSPORT_CLOSE or APPLICATION_CLOSE frame if it has sufficient state to do so. +CONNECTION_CLOSE or APPLICATION_CLOSE frame if it has sufficient state to do so. #### Detecting a Stateless Reset @@ -1660,16 +1660,16 @@ Final Offset: data written on this stream by the RST_STREAM sender. -## TRANSPORT_CLOSE frame {#frame-transport-close} +## CONNECTION_CLOSE frame {#frame-connection-close} -An endpoint sends a TRANSPORT_CLOSE frame (type=0x02) to notify its peer that -the connection is being closed. TRANSPORT_CLOSE is used to signal errors at the -QUIC layer, or the absence of errors (with the NO_ERROR code). +An endpoint sends a CONNECTION_CLOSE frame (type=0x02) to notify its peer that +the connection is being closed. CONNECTION_CLOSE is used to signal errors at +the QUIC layer, or the absence of errors (with the NO_ERROR code). If there are open streams that haven't been explicitly closed, they are implicitly closed when the connection is closed. -The TRANSPORT_CLOSE frame is as follows: +The CONNECTION_CLOSE frame is as follows: ~~~ 0 1 2 3 @@ -1681,19 +1681,19 @@ The TRANSPORT_CLOSE frame is as follows: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ -The fields of a TRANSPORT_CLOSE frame are as follows: +The fields of a CONNECTION_CLOSE frame are as follows: Error Code: : A 32-bit error code which indicates the reason for closing this connection. - TRANSPORT_CLOSE uses codes from the space defined in {{error-codes}}; - APPLICATION_CLOSE uses codes from the application protocol error code space - ({{app-error-codes}}). + CONNECTION_CLOSE uses codes from the space defined in {{error-codes}} + (APPLICATION_CLOSE uses codes from the application protocol error code space, + see {{app-error-codes}}). Reason Phrase Length: : A 16-bit unsigned number specifying the length of the reason phrase in bytes. - Note that a TRANSPORT_CLOSE frame cannot be split between packets, so in + Note that a CONNECTION_CLOSE frame cannot be split between packets, so in practice any limits on packet size will also limit the space available for a reason phrase. @@ -1707,12 +1707,12 @@ Reason Phrase: ## APPLICATION_CLOSE frame {#frame-application-close} An APPLICATION_CLOSE frame (type=0x03) uses the same format as the -TRANSPORT_CLOSE frame ({{frame-transport-close}}), except that it uses error +CONNECTION_CLOSE frame ({{frame-connection-close}}), except that it uses error codes from the application protocol error code space ({{app-error-codes}}) instead of the transport error code space. Other than the error code space, the format and semantics of the -APPLICATION_CLOSE frame are identical to the TRANSPORT_CLOSE frame. +APPLICATION_CLOSE frame are identical to the CONNECTION_CLOSE frame. ## MAX_DATA Frame {#frame-max-data} @@ -1944,16 +1944,18 @@ The STOP_SENDING frame is as follows: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Stream ID (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| App Error Code (32) | +| Application Error Code (32) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ~~~ The fields are: Stream ID: + : The 32-bit Stream ID of the stream being ignored. -App Error Code: +Application Error Code: + : A 32-bit, application-specified reason the sender is ignoring the stream (see {{app-error-codes}}). @@ -2674,11 +2676,11 @@ connection and stream flow-control windows, even though these frames will be discarded upon receipt. This avoids potential ambiguity about which STREAM frames count toward flow control. -Upon receipt of a STOP_SENDING frame on a stream in the "open" or "half-closed -(remote)" states, an endpoint MUST send a RST_STREAM frame. If the STOP_SENDING -frame is received on a stream that is already in the "half-closed (local)" or -"closed" states, a RST_STREAM frame MAY still be sent in order to cancel -retransmission of previously-sent STREAM frames. +A STOP_SENDING frame on a stream in the "open" or "half-closed (remote)" states, +requests that the the receiving application send a RST_STREAM frame. If the +STOP_SENDING frame is received on a stream that is already in the "half-closed +(local)" or "closed" states, a RST_STREAM frame MAY still be sent in order to +cancel retransmission of previously-sent STREAM frames. While STOP_SENDING frames are retransmittable, an implementation MAY choose not to retransmit a lost STOP_SENDING frame if the stream has already been closed @@ -2950,7 +2952,7 @@ frame that signals the error. Where this specification identifies error conditions, it also identifies the error code that is used. A stateless reset ({{stateless-reset}}) is not suitable for any error that can -be signaled with a TRANSPORT_CLOSE, APPLICATION_CLOSE, or RST_STREAM frame. A +be signaled with a CONNECTION_CLOSE, APPLICATION_CLOSE, or RST_STREAM frame. A stateless reset MUST NOT be used by an endpoint that has the state necessary to send a frame on the connection. @@ -2959,17 +2961,17 @@ send a frame on the connection. Errors that result in the connection being unusable, such as an obvious violation of protocol semantics or corruption of state that affects an entire -connection, MUST be signaled using a TRANSPORT_CLOSE or APPLICATION_CLOSE frame -({{frame-transport-close}}, {{frame-application-close}}). An endpoint MAY close +connection, MUST be signaled using a CONNECTION_CLOSE or APPLICATION_CLOSE frame +({{frame-connection-close}}, {{frame-application-close}}). An endpoint MAY close the connection in this manner, even if the error only affects a single stream. Application protocols can signal application-specific protocol errors using the APPLICATION_CLOSE frame. Errors that are specific to the transport, including -all those described in this document, are carried in a TRANSPORT_CLOSE frame. +all those described in this document, are carried in a CONNECTION_CLOSE frame. Other than the type of error code they carry, these frames are identical in format and semantics. -A TRANSPORT_CLOSE or APPLICATION_CLOSE frame could be sent in a packet that is +A CONNECTION_CLOSE or APPLICATION_CLOSE frame could be sent in a packet that is lost. An endpoint SHOULD be prepared to retransmit a packet containing either frame type if it receives more packets on a terminated connection. Limiting the number of retransmissions and the time over which this final packet is sent @@ -2977,7 +2979,7 @@ limits the effort expended on terminated connections. An endpoint that does not retransmit this packet could be forced to use the stateless reset process ({{stateless-reset}}). -An endpoint that receives an invalid TRANSPORT_CLOSE or APPLICATION_CLOSE frame +An endpoint that receives an invalid CONNECTION_CLOSE or APPLICATION_CLOSE frame MUST NOT signal the existence of the error to its peer. @@ -3004,11 +3006,11 @@ consistent state between endpoints. Transport error codes are 32 bits long. This section lists the defined QUIC transport error codes that may be used in a -TRANSPORT_CLOSE frame. These errors apply to the entire connection. +CONNECTION_CLOSE frame. These errors apply to the entire connection. NO_ERROR (0x0): -: An endpoint uses this with TRANSPORT_CLOSE to signal that the connection is +: An endpoint uses this with CONNECTION_CLOSE to signal that the connection is being closed abruptly in the absence of any error. INTERNAL_ERROR (0x1): From 48d141c2e80a2e1795dc10665b883abd1076d7c5 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Fri, 8 Sep 2017 08:25:56 +1000 Subject: [PATCH 14/15] Small tweak at Mike's suggestion --- draft-ietf-quic-http.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 5c43acd7d8..606882ac69 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -1066,11 +1066,11 @@ QUIC has the same concepts of "stream" and "connection" errors that HTTP/2 provides. However, because the error code space is shared between multiple components, there is no direct portability of HTTP/2 error codes. -The HTTP/2 error codes defined in Section 7 of {{!RFC7540}} map to QUIC error -codes as follows: +The HTTP/2 error codes defined in Section 7 of {{!RFC7540}} map to the HTTP over +QUIC error codes as follows: NO_ERROR (0x0): -: HTTP_NO_ERROR +: HTTP_NO_ERROR in {{http-error-codes}}. PROTOCOL_ERROR (0x1): : No single mapping. See new HTTP_MALFORMED_* error codes defined in From d104aa005a826d7d4f879a79d892e3588ffccac9 Mon Sep 17 00:00:00 2001 From: Martin Thomson Date: Tue, 12 Sep 2017 09:59:06 +1000 Subject: [PATCH 15/15] Some small amount of rewording --- 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 21c333a128..59ae50610d 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -860,9 +860,10 @@ length as a connection error of type HTTP_MALFORMED_MAX_PUSH_ID. ## STOP_SENDING Frame {#frame-stop-sending} -An endpoint may use a STOP_SENDING frame (type=0x0E) to communicate that -incoming data is being discarded on receipt at application request. This -requests that the recipient send a RST_STREAM on the identified stream. +An endpoint uses a STOP_SENDING frame (type=0x0E) to communicate that incoming +data is being discarded on receipt at application request. This indicates to +the recipient that sending a RST_STREAM on the identified stream would avoid +wasting bandwidth. STOP_SENDING is sent on the control stream. An endpoint MUST treat receipt of STOP_SENDING on any other stream as a connection error of type