Re: Suspected errata on 7540 wrt stream states

Hi Ilari,

On Wed, Dec 27, 2017 at 03:19:51PM +0200, Ilari Liusvaara wrote:
> On Wed, Dec 27, 2017 at 09:57:53AM +0100, Willy Tarreau wrote:
> > Hi all,
> > 
> > while taking a closer look at some of the issues reported by h2spec on
> > haproxy's h2 implementation, I found that it reported something that I
> > thought I had properly handled, namely the receipt of frames after the
> > ES flag. Taking a closer look, I implemented what is indicated in 5.1 :
> > 
> >    open:
> >       (...) an endpoint receiving an END_STREAM flag causes the
> >       stream state to become "half-closed (remote)".
> > 
> >    half-closed (remote):
> >       (...) If an endpoint receives additional frames, other than
> >       WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in
> >       this state, it MUST respond with a stream error (Section 5.4.2) of
> >       type STREAM_CLOSED.
> > 
> > And indeed, when haproxy sees, say, a DATA frame after ES, it sends an
> > RST_STREAM with error type STREAM_CLOSED.
> > 
> > But h2spec expects to see a connection error here, which surprized me a
> > bit. So I continued to read and found what rule it relies on :
> > 
> >    closed:
> >       (...) Similarly, an endpoint
> >       that receives any frames after receiving a frame with the
> >       END_STREAM flag set MUST treat that as a connection error
> >       (Section 5.4.1) of type STREAM_CLOSED, unless the frame is
> >       permitted as described below.
> > 
> > So in fact here I suspect that this last paragraph has nothing to do with
> > the closed state but is in fact related to the half-closed(remote) one,
> > and it contradicts the rule dictated in the half-closed(remote) description.
> > 
> > Am I overlooking anything ? Should I implement a connection error to be
> > more conservative ? Should I file an errata given that we're seeing two
> > conflicting MUST ?
> 
> One of the rules is about half-open state and the other is about closed
> state.

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.

> 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 :-)

> (Not that this makes very much sense, but at least the spec does not
> seem to conflict with itself).
> 
> 
> Then there is more whacky case if RST_STREAM is involved:
> 
> 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.

Willy

Received on Wednesday, 27 December 2017 13:55:20 UTC