Subject: [quicwg/base-drafts] Inconsistency in STOP_SENDING requirements relative to resetting streams in general (#2884)

From: mjoras <[email-masked]>
Date: Tue, 09 Jul 2019 08:37:02 -0700

Section 11.2 of the transport draft reads:

>RESET_STREAM MUST be instigated by the protocol using QUIC, either directly or through the receipt of a STOP_SENDING frame from a peer. RESET_STREAM carries 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.

This would suggest that the transport implementation itself should not be deciding to send RESET_STREAMs on its own, rather it is a matter of the application protocol using QUIC. However, it is somewhat weaselly about STOP_SENDING. My original interpretation of this text was that the implementation should expose the fact that a STOP_SENDING has been received, but it is up to the application protocol to actually reset the stream. This interpretation is not consistent with section 3.5, Solicited State Transitions: 

> A STOP_SENDING frame requests that the receiving endpoint send a RESET_STREAM frame. An endpoint that receives a STOP_SENDING frame MUST send a RESET_STREAM frame if the stream is in the Ready or Send state. If the stream is in the Data Sent state and any outstanding data is declared lost, an endpoint SHOULD send a RESET_STREAM frame in lieu of a retransmission.
I believe the only reasonable way to interpret this is that the transport itself should respond to the STOP_SENDING by issuing a RESET_STREAM.

Requiring that the QUIC implementation itself reset the stream seems to go against the philosophy that the protocol should have complete control over resets. It's true that in the case of receiving a STOP_SENDING, the protocol on the other side is asking for a RESET_STREAM, but the entity being solicited should be its peer protocol implementation, not the QUIC implementation. I believe we can fix this by altering the normative text requiring sending a RESET_STREAM, instead prescribing that an application protocol ought to handle STOP_SENDING by eventually fulfilling the solicited reset.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2884

---

From: Martin Thomson <[email-masked]>
Date: Tue, 09 Jul 2019 23:53:14 -0700

I don't see any inconsistency here.  This is the relevant text:

> RESET_STREAM MUST be instigated by the protocol using QUIC, either directly or through the receipt of a STOP_SENDING frame from a peer.

This says that RESET_STREAM is only sent if the application protocol asks for it.  That means either the local stack or the remote stack.  

As you say, the transport is required to send RESET_STREAM in response to STOP_SENDING.  I can firm that up.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2884#issuecomment-509933938

---

From: mjoras <[email-masked]>
Date: Wed, 10 Jul 2019 09:40:14 -0700

I am suggesting more than an editorial change, actually. I'm disputing that it makes sense for the transport to be the one initiating the RESET_STREAM as opposed to the STOP_SENDING merely being informative to the application protocol, i.e. it should be the application protocol's responsibility to respond to the STOP_SENDING by resetting the stream.

>From an implementation standpoint, one would obviously want feedback on receiving a STOP_SENDING frame. This makes it so the implementation has to make a choice when receiving the STOP_SENDING. Is it supposed to reset the stream before or after delivering this information to the application protocol? This has consequences as resetting the stream before informing the application obviously effects the stream state.

Is there any disadvantage to instead only requiring that the transport inform the application protocol of the receipt of the STOP_SENDING, and then the application protocol is left to decide when to actually reset the relevant stream?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2884#issuecomment-510138171

---

From: ianswett <[email-masked]>
Date: Wed, 10 Jul 2019 09:45:19 -0700

There are two concerns that come to mind.
1) The application can implement this incorrectly.
2) The application may be slow to process the STOP_SENDING, and in the meantime a lot of unnecessary data may be sent.  Doing this at the transport layer allows immediate processing.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2884#issuecomment-510139914

---

From: MikkelFJ <[email-masked]>
Date: Wed, 10 Jul 2019 10:02:05 -0700

The application may also have delivered everything including FIN.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2884#issuecomment-510145616

---

From: mjoras <[email-masked]>
Date: Wed, 10 Jul 2019 10:13:17 -0700

> The application can implement this incorrectly.

The application can also incorrectly implement having its stream reset without notification, as is currently allowed by the spec. The spec as written IMO encourages confusing semantics with respect to STOP_SENDING, as it forces the transport to send the reset and leaves it up to the implementation to decide how and when it notifies the application.

> The application may be slow to process the STOP_SENDING, and in the meantime a lot of unnecessary data may be sent. Doing this at the transport layer allows immediate processing.

We don't need to be prescriptive in saying the application MUST handle it, i.e. we don't need to disallow transport implementations from responding to the STOP_SENDING without application input. I am suggesting that we not require that the transport be the one to do it. I don't see an advantage to allowing the application to take control of sending the reset if it wants to. 

> The application may also have delivered everything including FIN.

I don't see how this is a concern. For such cases either the application can still issue a reset for the stream, or the transport implementation can optionally take control of it and issue the reset itself.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2884#issuecomment-510149568

---

From: MikkelFJ <[email-masked]>
Date: Wed, 10 Jul 2019 10:28:31 -0700

> I don't see how this is a concern. For such cases either the application can still issue a reset for the stream, or the transport implementation can optionally take control of it and issue the rese…

It may not be in the application protocols best interest to have a forced reset in this case.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/2884#issuecomment-510154903