Re: Conflicting MUST in RFC7540

Hi Martin,

On Thu, Jan 24, 2019 at 06:29:54PM +1100, Martin Thomson wrote:
> Hi Willy,
> 
> It looks like you have a classic case of the error precedence problem,
> loved the world over by test engineers.

Absolutely!

> The CONTINUATION frame here is clearly in error in two different ways and
> which error you hit could depend on the structure of your code.
> 
> Code that performs processing on every byte in order might hit the type byte
> first and perform checks for CONTINUATION.  Similarly, if you handle
> CONTINUATION at the framing layer, you might do this as well.  These stacks
> might conclude that a PROTOCOL_ERROR is the right answer because the
> preceding frame was not an open HEADERS or CONTINUATION.
> 
> Code that parses the frame header and attributes frames to streams first
> might generate the STREAM_CLOSED error because the associated stream is
> closed.

These are indeed the two cases that happen depending on the context.

> The problem is that both are right: that error exists and they are obligated
> to report it.  Sending both error codes isn't really a good idea because it
> probably violates other MUST statements, so you have to pick one.

I'm not suggesting to send both codes, rather to indicate to implementations
how to proceed in general when facing a state issue. I *think* that it should
be reasonable to suggest that stream errors should be replaced with connection
errors for HEADERS/CONTINUATION/PUSH_PROMISE because the compression context
cannot recover from these ones when placed out of stream (which is a protocol
error, thus an implementation error).

> It looks like we did a reasonable job of avoiding this sort of problem in h2,
> probably as a result of not using many different error codes (Mike can
> consider h3 to be on notice here :), but this one is probably worth some text
> on.  I'm inclined to address the problem generically rather than
> specifically.  We might not have many other cases of this in RFC 7540, but I
> can't guarantee that some h2 extension won't create a similar sort of
> conflict when two error cases collide.

I've found a few other ones in the past that I had to address so that
h2spec doesn't complain, I was fine with doing so because either choice
was OK. I really think that the problematic ones are for these few frames
which affect the compression state.

> My view is that there is no correct answer.  There are two errors and we
> shouldn't ask implementations to conform here.  Implementations should be
> able to choose any structure they like that meets protocol requirements AND
> they should be allowed to report the first error they encounter.  To that
> end, if there is an erratum, I would prefer that it say something like this,
> added to Section 5.4 (Error Handling):
> 
>   This specification or its extensions could define error conditions that
>   result in conflicting requirements about which error code is sent when
>   multiple errors are present.  Implementations MAY respond to the first
>   error condition that they detect.  Consequently, if multiple errors are
>   present, different implementations could produce different error codes.
>   However, a connection error MUST NOT be suppressed as a result of reporting
>   a stream error.

Do you imply by the last sentence that both a stream error and a connection
error should be sent in this case ? If so, it sounds less natural to me
because it could significantly complicate error paths depending on the
implementations. What about something like this :

    When a violation could result either in a stream error or a connection
    error depending on where the condition is matched, the connection error
    has precedence and must be applied.

Thanks!
Willy

Received on Thursday, 24 January 2019 07:50:24 UTC