Re: Suspected errata on 7540 wrt stream states

On Wed, Dec 27, 2017 at 04:55:52PM +0200, Ilari Liusvaara wrote:
> On Wed, Dec 27, 2017 at 02:54:46PM +0100, Willy Tarreau wrote:
> > But there are not that many ways to reach the closed state :
> >   - END_STREAM in both directions
> >   - RST_STREAM in any direction
> > 
> > Also by definition, a closed stream is ... closed. So when you receive a
> > frame for such a stream most of the time you don't remember what condition
> > caused it to be closed.
> 
> The spec requires distinguishing:
> 
> 1) Stream was "recently" fully closed by RST_STREAM you sent.
> 2) Stream was "recently" fully closed by END_STREAM you sent (impiles
>    that the other side has sent END_STREAM before).
> 3) Any other case (not "recently" closed, or remote side fully closed
>    it via RST_STREAM or END_STREAM).

That's exactly what I'm doing with various stream-specific flags reporting
what was seen on each of them.

> There is no upper bound what "recently" means. I would expect at least
> tens of seconds if not minutes.

Well for a gateway even tens of seconds is not practical as it can quickly
lead to millions or tens of millions of closed streams stored in memory.
In my case I still have the ability to proceed with "recently" seen streams
that have not yet been purged (ie those not yet closed at the application
level), which is enough to try to do what is best most of the time.

> In case 1)
> 
> - PUSH_PROMISE is processed normally.
> - PRIORITY is processed normally.
> - DATA updates connection window, but is otherwise ignored.
> - All other frames are ignored.
> 
> In case 2)
> 
> - PRIORITY is processed normally.
> - WINDOW_UPDATE is ignored.
> - RST_STREAM is ignored.
> - All other frames trigger connection error.
> 
> In case 3)
> 
> - PRIORITY is processed normally.
> - All other frames trigger connection error.

Well I think that's what I'm trying to aim for. In addition to this, 5.1.1
mandates that HEADERS and PUSH_PROMISE always trigger a connection error
on closed streams regardless of how they were closed :

   The identifier of a newly established stream MUST be numerically
   greater than all streams that the initiating endpoint has opened or
   reserved.  This governs streams that are opened using a HEADERS frame
   and streams that are reserved using PUSH_PROMISE.  An endpoint that
   receives an unexpected stream identifier MUST respond with a
   connection error (Section 5.4.1) of type PROTOCOL_ERROR.

As you can see this automatically covers closed streams since their IDs
are numerically lower than the next allowed one by definition.

> > > So if RST_STREAM is not involved, it depends on if you have sent
> > > END_STREAM.
> > > 
> > > 1) If no, it is stream error.
> > > 2) If yes, it is connection error.
> > 
> > But if you haven't sent END_STREAM (case 1), the only way it may end
> > up in closed state is by receiving RST_STREAM, which contradicts the
> > condition :-)
> 
> Case 1 is half-closed case. Case 2 is full close.

Yes I agree, which is why we can't have case 1 in closed state. That's
what I meant, which led me to consider that its specific rule being
listed as part of the "closed" stream was not much relevant there and
more to the half-closed one.

> > > If you have sent RST_STREAM and then receive END_STREAM and then DATA
> > > (all in "short" succession), that is no error.
> > 
> > Well, I'm starting to think that I will fall back all these situations to
> > connection error, given that a stream error may always be elevated to a
> > connection error. It will cover all these cases at once.
> 
> Just beware that you don't send connection errors on any possibly racy
> case. Because such implementation is buggy and such spec is errorneous.

Yes I've noticed this after writing it and preferred to rollback on this.
If I don't have the stream in the local list I'm not back to sending RST
to avoid such race. However I'm trying hard to send the GOAWAY when I'm
absolutely certain the peer did something not allowed (ie I still have
the stream in the list and the stream was closed normally).

I'm trying to stick as close as possible to the spec without risking to
fall on the unreliable side.

Thanks!
Willy

Received on Wednesday, 27 December 2017 15:14:47 UTC