From ddb9802b899ae8365753185ed8387db7d8a6f2f8 Mon Sep 17 00:00:00 2001 From: ianswett Date: Thu, 22 Jun 2017 20:09:14 -0400 Subject: [PATCH 1/4] Adding unidirectional streams --- draft-ietf-quic-transport.md | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index ea3c69818a..1668678128 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -1483,10 +1483,13 @@ subsequent sections. ## STREAM Frame {#frame-stream} STREAM frames implicitly create a stream and carry stream data. The type byte -for a STREAM frame contains embedded flags, and is formatted as `11FSSOOD`. +for a STREAM frame contains embedded flags, and is formatted as `1UFSSOOD`. These bits are parsed as follows: -* The first two bits must be set to 11, indicating that this is a STREAM frame. +* The first bit must be set to 1, indicating that this is a STREAM frame. + +* 'U' is the UNI bit, which is used to indicate this is a unidirectional + stream, and no stream frames may be sent in response. * `F` is the FIN bit, which is used for stream termination. @@ -2301,7 +2304,8 @@ Streams in QUIC provide a lightweight, ordered, and bidirectional byte-stream abstraction modeled closely on HTTP/2 streams {{?RFC7540}}. Streams can be created either by the client or the server, can concurrently send -data interleaved with other streams, and can be cancelled. +data interleaved with other streams, can be cancelled, and can be opened in +unidirectional mode. Data that is received on a stream is delivered in order within that stream, but there is no particular delivery order across streams. Transmit ordering among @@ -2357,11 +2361,11 @@ shown in the following figure and described below. +--------+ | send/recv STREAM/RST - recv MSD/SB + recv MSD/SB | v - recv FIN/ +--------+ send FIN/ - recv RST | | send RST + recv FIN/ +--------+ send FIN/ + recv RST/send UNI | | send RST/recv UNI ,---------| open |-----------. / | | \ v +--------+ v @@ -2382,6 +2386,7 @@ shown in the following figure and described below. STREAM: a STREAM frame FIN: FIN flag in a STREAM frame + UNI: UNI flag in a STREAM frame RST: RST_STREAM frame MSD: MAX_STREAM_DATA frame SB: STREAM_BLOCKED frame @@ -2461,9 +2466,10 @@ Any frame type that mentions a stream ID can be sent in this state. ### half-closed (local) 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 +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 -RST_STREAM in this state. +RST_STREAM in this state. A stream immediately transitions to +"half-closed (local)" if it is created with the UNI flag set. An endpoint that closes a stream MUST NOT send data beyond the final offset that it has chosen, see {{state-closed}} for details. @@ -2483,8 +2489,8 @@ after a frame bearing the FIN flag is sent. A stream is "half-closed (remote)" when the stream is no longer being used by the peer to send any data. An endpoint will have either received all data that -a peer has sent or will have received a RST_STREAM frame and discarded any -received data. +a peer has sent, will have sent an UNI flag on the stream, or will have +received a RST_STREAM frame and discarded any received data. Once all data has been either received or discarded, a sender is no longer obligated to update the maximum received data for the connection. @@ -2757,7 +2763,8 @@ is increased. The final offset is the count of the number of octets that are transmitted on a stream. For a stream that is reset, the final offset is carried explicitly in the RST_STREAM frame. Otherwise, the final offset is the offset of the end of -the data carried in STREAM frame marked with a FIN flag. +the data carried in STREAM frame marked with a FIN flag, or 0 in the case of +received streams with the UNI flag set. An endpoint will know the final offset for a stream when the stream enters the "half-closed (remote)" state. However, if there is reordering or loss, an From d254f76fa4495cff46b920ed08fe1b02c3f4d465 Mon Sep 17 00:00:00 2001 From: ianswett Date: Thu, 22 Jun 2017 21:04:00 -0400 Subject: [PATCH 2/4] Update --- draft-ietf-quic-transport.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 1668678128..237bc76420 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -884,8 +884,8 @@ 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}} | -| 0xa0 - 0xbf | ACK | {{frame-ack}} | -| 0xc0 - 0xff | STREAM | {{frame-stream}} | +| 0x60 - 0x7f | ACK | {{frame-ack}} | +| 0x80 - 0xff | STREAM | {{frame-stream}} | {: #frame-types title="Frame Types"} # Life of a Connection @@ -1610,7 +1610,7 @@ entropy on demand, which should be adequate protection against most opportunistic acknowledgement attacks. The type byte for a ACK frame contains embedded flags, and is formatted as -`101NLLMM`. These bits are parsed as follows: +`011NLLMM`. These bits are parsed as follows: * The first three bits must be set to 101 indicating that this is an ACK frame. @@ -2577,6 +2577,9 @@ the data limits set by its peer. The cryptographic handshake stream, Stream 0, is exempt from the connection-level data limits established by MAX_DATA. Stream 0 is still subject to stream-level data limits and MAX_STREAM_DATA. +If a STREAM frame is received for a stream that was previously specified as +unidirectional, the connection MUST be closed with QUIC_INVALID_FRAME_DATA. + Flow control is described in detail in {{flow-control}}, and congestion control is described in the companion document {{QUIC-RECOVERY}}. From fee594a3d1bcc0f3876401bc2fd96db4a6866ac3 Mon Sep 17 00:00:00 2001 From: ianswett Date: Wed, 28 Jun 2017 20:38:55 -0400 Subject: [PATCH 3/4] Update draft-ietf-quic-transport.md --- draft-ietf-quic-transport.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/draft-ietf-quic-transport.md b/draft-ietf-quic-transport.md index 237bc76420..db08b60690 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2405,6 +2405,12 @@ coordinate the creation of streams; they are created unilaterally by either endpoint. Endpoints can use acknowledgments to understand the peer's subjective view of stream state at any given time. +Only the initiator of a stream may send a STREAM frame without receiving one +unless otherwise specified by the application. All implicitly opened streams +must remain in the IDLE state until a STREAM frame has been received. If a +RST is received on a stream reserved for the peer before any STREAM frame +has been received, it will immediately transition to the closed state. + In the absence of more specific guidance elsewhere in this document, implementations SHOULD treat the receipt of a frame that is not expressly permitted in the description of a state as a connection error (see @@ -2469,7 +2475,8 @@ A stream that is in the "half-closed (local)" state MUST NOT be used for sending 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 RST_STREAM in this state. A stream immediately transitions to -"half-closed (local)" if it is created with the UNI flag set. +"half-closed (local)" if it is created when a STREAM frame with the UNI flag +set is received. An endpoint that closes a stream MUST NOT send data beyond the final offset that it has chosen, see {{state-closed}} for details. @@ -2577,8 +2584,9 @@ the data limits set by its peer. The cryptographic handshake stream, Stream 0, is exempt from the connection-level data limits established by MAX_DATA. Stream 0 is still subject to stream-level data limits and MAX_STREAM_DATA. -If a STREAM frame is received for a stream that was previously specified as -unidirectional, the connection MUST be closed with QUIC_INVALID_FRAME_DATA. +If a STREAM frame is received and the UNI bit does not match the UNI bit of +previous STREAM frames for that stream id, the connection MUST be closed with +QUIC_INVALID_FRAME_DATA. Flow control is described in detail in {{flow-control}}, and congestion control is described in the companion document {{QUIC-RECOVERY}}. @@ -2767,7 +2775,7 @@ The final offset is the count of the number of octets that are transmitted on a stream. For a stream that is reset, the final offset is carried explicitly in the RST_STREAM frame. Otherwise, the final offset is the offset of the end of the data carried in STREAM frame marked with a FIN flag, or 0 in the case of -received streams with the UNI flag set. +incoming unidirectional streams. An endpoint will know the final offset for a stream when the stream enters the "half-closed (remote)" state. However, if there is reordering or loss, an @@ -2965,7 +2973,7 @@ QUIC_INVALID_NEGOTIATED_VALUE (0x80000017): QUIC_DECOMPRESSION_FAILURE (0x80000018): : There was an error decompressing data. - +pu QUIC_NETWORK_IDLE_TIMEOUT (0x80000019): : The connection timed out due to no network activity. From 0dbd1f805c412cb694c26a3b50bc7b3e6b647666 Mon Sep 17 00:00:00 2001 From: ianswett Date: Wed, 28 Jun 2017 20:43:25 -0400 Subject: [PATCH 4/4] Trailing whitespace --- 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 db08b60690..2b8631e43f 100644 --- a/draft-ietf-quic-transport.md +++ b/draft-ietf-quic-transport.md @@ -2361,7 +2361,7 @@ shown in the following figure and described below. +--------+ | send/recv STREAM/RST - recv MSD/SB + recv MSD/SB | v recv FIN/ +--------+ send FIN/