Subject: [quicwg/base-drafts] Restrict RST to data streams, require replay (#274)

From: Mike Bishop <[email-masked]>
Date: Wed, 08 Feb 2017 14:33:41 -0800

Fixes #176, but I'm hoping we can find a cleaner way to do this.
You can view, comment on, or merge this pull request online at:

  https://github.com/quicwg/base-drafts/pull/274

-- Commit Summary --

  * Restrict RST to data streams, require replay

-- File Changes --

    M draft-ietf-quic-http.md (15)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/274.patch
https://github.com/quicwg/base-drafts/pull/274.diff

-- 
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/pull/274

---

From: Martin Thomson <[email-masked]>
Date: Wed, 08 Feb 2017 15:23:20 -0800

martinthomson commented on this pull request.

> @@ -201,6 +201,21 @@ additional framing. Note that a request or response without a body will cause
 this stream to be half-closed in the corresponding direction without
 transferring data.
 
+Because the message control stream contains HPACK data which manipulates
+connection-level state, the message control stream MUST NOT be closed with a
+stream-level error.  If an implementation chooses to reject a request with a
+QUIC error code, it MUST trigger a RST_STREAM on the data stream only.  An
+implementation MAY close (FIN) a message control stream without completing a
+full HTTP message if the data stream has been abruptly closed.  Data on message
+control streams MUST be fully consumed, or the connection terminated.
+
+If a message control stream is terminated abruptly by the transport layer (e.g.
+with QUIC_TOO_MANY_OPEN_STREAMS), any frames already sent on that stream MUST
+be re-played on another message control stream as soon as the maximum number of
+streams permits.  If the implementation no longer requires the response to this
+request, it MAY abruptly terminate the corresponding data stream at the same
+time.

I think that this is easier to handle with: "If a message control stream is terminated by a RST_STREAM *for any reason*, an endpoint MUST terminate the connection with a YOU_SCREWED_UP error code."  Attempting to rescue the situation isn't worth the effort and aside from exceeding concurrent stream limits during 0-RTT.

I don't think that there is any reason that the transport would legitimately need to close a stream on its own.  Even in that case, that should really be done by the application.

-- 
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/pull/274#pullrequestreview-20896552

---

From: Ryan Hamilton <[email-masked]>
Date: Wed, 08 Feb 2017 15:35:10 -0800

RyanAtGoogle commented on this pull request.

@martinthomson I love the idea of always tearing down, but I'm a bit nervous about the interactions with stream limits and REFUSED streams. You mention 0-RTT in your comment. Is your idea that 0-RTT streams may need to be retried and not result in the connection being closed and might have to do a retry dance?

---

From: Martin Thomson <[email-masked]>
Date: Wed, 08 Feb 2017 15:44:24 -0800

Anyone who exceeds a stream limit is violating the protocol (we need to address the issue of squishiness in that limit).  And refusing a stream is easy: refuse the data stream.  If the concern is that headers will consume stream limit until they resolve, I think that's a feature, not a bug.

0-RTT streams that end up exceeding some server limit can be refused by hitting the data stream.  The control stream can be left to run to completion.  If the server can't handle that (because the limits have been reduced by more than 50% perhaps), then it probably should reject 0-RTT.

A server might have to reject the connection (after all, it might only discover this sort of dire condition after foolishly/optimistically accepting 0-RTT), but that means that a new connection will have to created by the client.  Mike already has text about needing to retry in #236.  In the end, I think that sort of retry is something clients that attempt 0-RTT will just have to deal with.

---

From: Mike Bishop <[email-masked]>
Date: Tue, 14 Feb 2017 13:32:43 -0800

MikeBishop commented on this pull request.

I think the concern is that the transport layer doesn't necessarily know what's a data stream versus a control stream.  And if the application layer has said "Give me no more than 10 streams at a time," it seems... odd for the QUIC layer to then say "Here are 20 streams that have just arrived; if you'd like to shoot 10 of them, feel free."  The app already set the limit, and that limit should be enforced.

And if that enforcement causes the whole connection to get torn down, that might be okay.

---

From: Martin Thomson <[email-masked]>
Date: Tue, 14 Feb 2017 16:58:03 -0800

That's right.  Though 0-RTT is a complication.  An application that enables 0-RTT has to be prepared to accept more than its current limit.  That is, up to its previously advertised limit or the defaults, whichever is greater (damn, I still think that's an awful decision).

Outside of that, I think the goal should be that if the limit is exceeded, it should be punished with immediate termination of the connection.  The transport can enforce that easily enough.