Conflicting MUST in RFC7540

Hi,

I was occasionally seeing a random report from h2spec on haproxy about an
inappropriate RST_STREAM sent by haproxy in response to a CONTINUATION
frame after END_STREAM. I looked at the spec and there are indeed some
conflicting MUST. It's not the first time I notice this but this one is
relatively clear. I'm not sure how we should handle these ones.

Basically, half of the protocol rules are defined in the list of states,
suggesting what to do if some frames are seen, and the other ones are
defined in the list of frames, suggesting how they interact with other
frames.

Here the test (http2/6.10/5) does this :

      HEADERS (ES=1)
      CONTINUATION (EH=1)
      CONTINUATION (EH=1)

After receiving the first CONTINUATION frame, the stream becomes
half-closed (remote). The rule in 5.1 for this state says :

      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.

This is what haproxy does before entering the frame parsing loop. But
later in 6.10 the rule for CONTINUATION frame says :

   A CONTINUATION frame MUST be preceded by a HEADERS, PUSH_PROMISE or
   CONTINUATION frame without the END_HEADERS flag set.  A recipient
   that observes violation of this rule MUST respond with a connection
   error (Section 5.4.1) of type PROTOCOL_ERROR.

This is what h2spec is looking for and haproxy indeed checks this inside
the frame parsing loop.

Depending on the timing and how frames are packed together, we hit either
the first or the second condition.

I'd be inclined to consider that errors in response to any frame which might
have resulted in a compression state inconsistency must always be treated as
a connection error. As such at every place where we recommend to produce a
stream error, we should add "or connection error if the frame is of type
HEADERS, PUSH_PROMISE, or CONTINUATION". Ideally the state-dependent rules
should only be defined per state, and the rules for each frame should only
be related to the frame's format and not its relation to other frames.

What do you think ? Am I missing something ? Should I file an errata ?

Thanks,
Willy

Received on Thursday, 24 January 2019 05:44:30 UTC