Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rename to CLOSE_STREAM, make error code optional #11

Merged
merged 2 commits into from
Jun 13, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
79 changes: 46 additions & 33 deletions draft-ietf-quic-reliable-stream-reset.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ QUIC ({{!RFC9000}}) defines a RESET_STREAM frame to reset a stream. When a
sender resets a stream, it stops retransmitting STREAM frames for this stream.
On the receiver side, there is no guarantee that any of the data sent on that
stream is delivered to the application.
This document defines a new QUIC frame, the RELIABLE_RESET_STREAM frame, that
resets a stream, while guaranteeing reliable delivery of stream data up to a
certain byte offset.
This document defines a new QUIC frame, the CLOSE_STREAM frame, that allows
closing and resetting of a stream, while guaranteeing reliable delivery of
stream data up to a certain byte offset.

--- middle

Expand All @@ -66,7 +66,7 @@ might want to use a stream reset to signal that error, at the same time making
sure that all data being read previously is delivered to the peer.

This document describes a QUIC extension defining a new frame type, the
RELIABLE_RESET_STREAM frame. This frame allows an endpoint to mark a portion at
CLOSE_STREAM frame. This frame allows an endpoint to mark a portion at
the beginning of the stream which will then be guaranteed to be delivered to
receiver's application, even if the stream was reset.

Expand All @@ -77,7 +77,7 @@ receiver's application, even if the stream was reset.
# Negotiating Extension Use

Endpoints advertise their support of the extension described in this document by
sending the reliable_reset_stream (0x727273) transport parameter
sending the close_stream (0x17f7586d2cb570) transport parameter
(Section 7.4 of {{!RFC9000}}) with an empty value. An implementation that
understands this transport parameter MUST treat the receipt of a non-empty
value as a connection error of type TRANSPORT_PARAMETER_ERROR.
Expand All @@ -87,29 +87,30 @@ remember the value of this transport parameter. If 0-RTT data is accepted by
the server, the server MUST not disable this extension on the resumed
connection.

# RELIABLE_RESET_STREAM Frame
# CLOSE_STREAM Frame

Conceptually, the RELIABLE_RESET_STREAM frame is a RESET_STREAM frame with an
Conceptually, the CLOSE_STREAM frame is a RESET_STREAM frame with an
added Reliable Size field.

~~~
RELIABLE_RESET_STREAM Frame {
Type (i) = 0x72,
CLOSE_STREAM Frame {
Type (i) = 0x20..0x21,
Stream ID (i),
Application Protocol Error Code (i),
[Application Protocol Error Code (i)],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if this were unconditional. A value of 0 (or whatever application error equates to no error) is fine.

I see why you made this choice, but if the goal is to send STREAM+FIN, then STREAM+FIN exists. This frame only makes sense if reliable size < final size.

Final Size (i),
Reliable Size (i),
}
~~~

RELIABLE_RESET_STREAM frames contain the following fields:
The CLOSE_STREAM frames contain the following fields:

Stream ID: A variable-length integer encoding of the stream ID of
the stream being terminated.

Application Protocol Error Code: A variable-length integer
containing the application protocol error code (see Section 20.2)
that indicates why the stream is being closed.
that indicates why the stream is being closed. If the Type is 0x20,
this field is not included.

Final Size: A variable-length integer indicating the final size of
the stream by the RESET_STREAM sender, in units of bytes; see
Expand All @@ -122,50 +123,62 @@ Reliable Size: A variable-length integer indicating the amount of
If the Reliable Size is larger than the Final Size, the receiver MUST close the
connection with a connection error of type FRAME_ENCODING_ERROR.

Semantically, a RESET_STREAM frame is equivalent to a RELIABLE_RESET_STREAM
frame with the Reliable Size set to 0.
CLOSE_STREAM frames are ack-eliciting. When lost, they MUST be retransmitted,
unless the stream state has transitioned to "Data Recvd" or "Reset Recvd" due
to transmission and acknowledgement of other frames (see {{multiple-frames}}).

RELIABLE_RESET_STREAM frames are ack-eliciting. When lost, they MUST be
retransmitted, unless a RESET_STREAM frame or another RELIABLE_RESET_STREAM
frame was sent for the same stream (see {{multiple-frames}}).
# Closing Streams

# Resetting Streams
## Without an Error

When closing a stream with an error, the node has the choise between a STREAM
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

choice

frame that carries the FIN bit and a CLOSE_STREAM frame of type 0x20.

The CLOSE_STREAM frame can be used to reduce the reliable offset after a
STREAM frame with a FIN bit has been sent. If STREAM frames containing data
up to that byte offset are lost, the initiator MUST retransmit this data, as
described in (Section 13.3 of {{!RFC9000}}). Data sent beyond that byte offset
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{{Section 13.3 of !RFC9000}}

SHOULD NOT be retransmitted.

## Using an Error Code

When resetting a stream, the node has the choice between using a RESET_STREAM
frame and a RELIABLE_RESET_STREAM frame. When using a RESET_STREAM frame, the
behavior is unchanged from the behavior described in ({{!RFC9000}}).
frame and a CLOSE_STREAM frame of type 0x21. When using a RESET_STREAM frame,
the behavior is unchanged from the behavior described in ({{!RFC9000}}).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lose the parentheses.


The initiator MUST guarantee reliable delivery of stream data of at least
When using the CLOSE_STREAM frame, the initiator MUST guarantee reliable delivery of stream data of at least
Reliable Size bytes. If STREAM frames containing data up to that byte offset
are lost, the initiator MUST retransmit this data, as described in
are lost, the initiator MUST retransmit this data, as described in
(Section 13.3 of {{!RFC9000}}). Data sent beyond that byte offset SHOULD NOT be
retransmitted.

As described in (Section 3.2 of {{RFC9000}}), it MAY deliver data beyond that
offset to the application.

## Multiple RELIABLE_RESET_STREAM / RESET_STREAM frames {#multiple-frames}
## Multiple CLOSE_STREAM / RESET_STREAM frames {#multiple-frames}

The initiator MAY send multiple RELIABLE_RESET_STREAM frames for the same
The initiator MAY send multiple CLOSE_STREAM frames for the same
stream in order to reduce the Reliable Size. It MAY also send a RESET_STREAM
frame, which is equivalent to sending a RELIABLE_RESET_STREAM frame with a
frame, which is equivalent to sending a CLOSE_STREAM frame with a
Reliable Size of 0.

When sending multiple frames for the same stream, the initiator MUST NOT increase
the Reliable Size. When receiving a RELIABLE_RESET_STREAM frame with a lower
the Reliable Size. When receiving a CLOSE_STREAM frame with a lower
Reliable Size, the receiver only needs to deliver data up the lower Reliable
Size to the application. It MUST NOT expect the delivery of any data beyond that
byte offset.

Reordering of packets might lead to a RELIABLE_RESET_STREAM frame with a higher
Reliable Size being received after a RELIABLE_RESET_STREAM frame with a lower
Reliable Size. The receiver MUST ignore any RELIABLE_RESET_STREAM frame that
Reordering of packets might lead to a CLOSE_STREAM frame with a higher
Reliable Size being received after a CLOSE_STREAM frame with a lower
Reliable Size. The receiver MUST ignore any CLOSE_STREAM frame that
increases the Reliable Size.

When sending another RELIABLE_RESET_STREAM or RESET_STREAM frame for the same
stream, the initiator MUST NOT change the Application Error Code or the Final
Size. If the receiver detects a change in those fields, it MUST close the
connection with a connection error of type STREAM_STATE_ERROR.
When sending another CLOSE_STREAM, RESET_STREAM or STREAM frame carrying a FIN
bit for the same stream, the initiator MUST NOT change the Application Error
Code or the Final Size. This also means that sending CLOSE_STREAM frames of
different types is not permitted. If the receiver detects a change in those
fields, it MUST close the connection with a connection error of type
STREAM_STATE_ERROR.

# Security Considerations

Expand Down