Subject: STOP_SENDING

From: Martin Thomson <[email-masked]>
Date: Mon, 31 Jul 2017 10:10:59 +1000

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

As mentioned in Prague, I want to merge the PR formerly known as
DISINTEREST.  Mike has updated it and it is now ready to do.  I plan
to merge this in 48 hours, absent any substantial objections.

---

From: Subodh Iyengar <[email-masked]>
Date: Mon, 31 Jul 2017 23:57:34 +0000

I commented on the PR, but had a design comment

Sending one more frame type has the added burden of needing to retransmit it before we go to closed state unless we make STOP_SENDING non retransmittable. Since this frame type is advisory anyway, does it really need to be retransmittable? Also it doesn't make sense to send this if we have received the peers RST. A peer's RST might have raced with our STOP_SENDING and the peer might have got rid of state for the stream. Thus any retransmitted STOP_SENDING frames might just be ignored.

Previously we had a bidirectional RST. With this change, it makes me a bit nervous for an endpoint to rely on a peer following advisory behavior for them to be able to close their stream, for example what would we do about a client that chooses not to send a RST on STOP_SENDING, do we rely on stream limits only? close the connection? It would be much more comfortable with a client MUST send a RST when getting a STOP_SENDING.

Subodh

________________________________
From: QUIC <[email-masked]> on behalf of Martin Thomson <[email-masked]>
Sent: Sunday, July 30, 2017 5:10 PM
To: QUIC WG
Subject: STOP_SENDING

---

From: Mike Bishop <[email-masked]>
Date: Tue, 1 Aug 2017 00:29:03 +0000

Yeah, the retransmission piece of it is interesting.  I can see an argument for making it non-retransmittable, but having guidance to periodically resend it if you continue to receive data.  (Kind of like ACKs - you don't blindly re-send the frame, you re-evaluate what needs to be sent.)  However, that seems heavier-weight than simply sending it reliably.  Note that only STREAM frames block the transition to "closed," and even there the transition happens when you have "completed sending," which I don't read as everything having been ACK'd unless we added that definition somewhere else.

The previous RST was only somewhat bidirectional - when you sent a RST_STREAM, you didn't know the other side's final offset, so you couldn't wind down their side of the stream until they also sent a RST_STREAM.  That's still the case, but now it's more honest - the stream continues to be open in the other direction until they actually send the RST_STREAM.

Conceptually, I'd be okay with a "MUST send RST_STREAM unless the stream is already closed," but this is almost impossible to verify, even if you start tracking what streams show up in packet numbers after the ACK of the packet that contained the STOP_SENDING frame.  My general rule is that if the other party can't be certain whether you violated a MUST, it needs to be a SHOULD.

From: QUIC [mailto:[email-masked]] On Behalf Of Subodh Iyengar
Sent: Monday, July 31, 2017 4:58 PM
To: Martin Thomson <[email-masked]>; QUIC WG <[email-masked]>
Subject: Re: STOP_SENDING

Subodh

________________________________
From: QUIC <[email-masked]<mailto:[email-masked]>> on behalf of Martin Thomson <[email-masked]<mailto:[email-masked]>>
Sent: Sunday, July 30, 2017 5:10 PM
To: QUIC WG
Subject: STOP_SENDING

https://github.com/quicwg/base-drafts/pull/171<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fquicwg%2Fbase-drafts%2Fpull%2F171&data=04%7C01%7Cmichael.bishop%40microsoft.com%7C296782094b2c423d21f108d4d86fefcf%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636371422734759522%7CUnknown%7CVW5rbm93bnx7IlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiT3RoZXIifQ%3D%3D%7C-1&sdata=W1OI1vIeX7yxBvszcG6lc7PJss6qtdI2k%2F0d8WG%2F%2BfY%3D&reserved=0>

---

From: Martin Thomson <[email-masked]>
Date: Tue, 1 Aug 2017 10:53:30 +1000

Wow, nice catch Subodh, that's somewhat subtle.  This is a frame that
affects stream state that isn't caught up in the state machine.

Mike is right that you can make the retransmission logic for
STOP_SENDING independent of the stream state, but I think that could
be more cumbersome to manage in implementation than is ideal.

I think that the simple fix here is as Subodh suggests: mandate the
sending of RST_STREAM in response to STOP_SENDING unless the stream is
already closed.  We can then note the optimization that this enables:
you can stop sending STOP_SENDING when the stream is closed.

Regarding MUST - I recognize that we fall back to the halting problem,
but I can still construct a test that will in most cases detect
misbehaviour: have someone send an infinitely long stream, send
STOP_SENDING in every packet, if they acknowledge packets for some
time without sending RST_STREAM, something is badly wrong.  It's not
deterministic, but it's still worth mandating.

Mike,

The relationship between retransmissions and stream states is
something that remains open in my mind.  What we have appears to be
largely driven by some design choices in the Google implementation.  I
don't know if we have an open issue that tracks that, we've
flip-flopped on our position over time and I don't think that we have
a firm consensus on this.  That said, it matters much less now that we
have MAX_STREAM_ID.

On 1 August 2017 at 10:29, Mike Bishop <[email-masked]> wrote:
> Yeah, the retransmission piece of it is interesting.  I can see an argument
> for making it non-retransmittable, but having guidance to periodically
> resend it if you continue to receive data.  (Kind of like ACKs – you don’t
> blindly re-send the frame, you re-evaluate what needs to be sent.)  However,
> that seems heavier-weight than simply sending it reliably.  Note that only
> STREAM frames block the transition to “closed,” and even there the
> transition happens when you have “completed sending,” which I don’t read as
> everything having been ACK’d unless we added that definition somewhere else.
>
>
>
> The previous RST was only somewhat bidirectional – when you sent a
> RST_STREAM, you didn’t know the other side’s final offset, so you couldn’t
> wind down their side of the stream until they also sent a RST_STREAM.
> That’s still the case, but now it’s more honest – the stream continues to be
> open in the other direction until they actually send the RST_STREAM.
>
>
>
> Conceptually, I’d be okay with a “MUST send RST_STREAM unless the stream is
> already closed,” but this is almost impossible to verify, even if you start
> tracking what streams show up in packet numbers after the ACK of the packet
> that contained the STOP_SENDING frame.  My general rule is that if the other
> party can’t be certain whether you violated a MUST, it needs to be a SHOULD.
>
>
>
> Sending one more frame type has the added burden of needing to retransmit it
> before we go to closed state unless we make STOP_SENDING non
> retransmittable. Since this frame type is advisory anyway, does it really
> need to be retransmittable? Also it doesn't make sense to send this if we
> have received the peers RST. A peer's RST might have raced with our
> STOP_SENDING and the peer might have got rid of state for the stream. Thus
> any retransmitted STOP_SENDING frames might just be ignored.
>
>
>
> Previously we had a bidirectional RST. With this change, it makes me a bit
> nervous for an endpoint to rely on a peer following advisory behavior for
> them to be able to close their stream, for example what would we do about a
> client that chooses not to send a RST on STOP_SENDING, do we rely on stream
> limits only? close the connection? It would be much more comfortable with a
> client MUST send a RST when getting a STOP_SENDING.
>
> Subodh
>
>
>