Subject: Error code cleanup

From: Martin Thomson <[email-masked]>
Date: Mon, 24 Apr 2017 14:41:30 +1000

The TLS and HTTP drafts now have some nice error code lists.  And by
nice I mean short and precise.  Each error code is justified and most
either point to a distinct reaction or a distinct cause (the latter
I'm less enthusiastic about with HTTP, but that is just a quibble).

I've been working on fixing error codes for the transport.

Here's what I'm going to propose for the breakdown of error codes in
the transport piece.  I won't name these yet, there are reasons to
parallel codes in the HTTP spec.  Some of these might be broken down
finer into codes that identify specific causes, but I might push back
on doing that too aggressively.

I have 13 codes here.  TLS has 3, HTTP has 17 (which I think is too
high, but what do I know). We might want to discuss reducing the size
of the error code space a little at some point.

I went through the existing codes and all are either invalid or
covered here - as far as I can see.  Clearly, this is still early
enough that there might be new codes added, but I think that the above
list is close enough.

I plan to write this up during this week.  I'm sharing this in the
hopes that someone might help by correcting any mistakes that I've
made.

# internal errors

* this error was my fault, probably a bug or resource issue on my end
that means I can't continue

I don't think that we want to highlight the difference between
different internal errors here lest we provide instructions on how to
trigger DoS or bugs.  Having just one code in this category seems
right.

# errors that aren't errors

* this isn't an error (in case we use one of the error messages to signal close)

* this isn't an error, you asked me to generate this error (for the
case where RST_STREAM causes RST_STREAM to be sent, or for the
proposed DISINTEREST frame)

* this isn't an error, I just don't want this stream any more (the
general form of the cancellation request)

# errors that are protocol violations

* you did something wrong, but nothing specific was appropriate (this
is a general catch-all error code for use when other protocol
violations aren't appropriate)

* you send me more data than I allowed (flow control)

* you opened a stream before I said you could use it (streams)

* you sent a frame on a stream that was in a state that doesn't allow that

* you sent data on a stream past the final data offset, or you seem to
have moved the final offset

* you sent a badly-formatted frame (this includes things that have bad
lengths primarily; I think that includes an empty STREAM with no FIN
flag; the range of errors here doesn't really seem to justify an error
code per frame type)

* your transport parameters were invalid

* the version negotiation fields in your transport parameters don't
match with my understanding of what we did during version negotiation,
IT'S AN ATTACK! (this could have been part of transport parameter
validation, but the fact that this is an attack rather than just a
screwup is a good reason to use a different code)

# errors that aren't protocol issues violations, but they need a signal anyway

* enhance your calm (this is the name we used in h2 to signal all
sorts of cases where an endpoint could tell the other side to cool off
a little, this usually includes activity that might look like a DoS
attack, but it might also be sent to clients who are behaving
themselves if the server is feeling under the weather)

# errors that I don't think need codes (yet)

* receiving a packet that contains no payload, even if it can be
authenticated (implementations should just discard these without even
trying to decrypt them)

* an attempt to close stream 0 (use the generic code)

* receiving a packet that is too big (we haven't actually got any text
imposing limits on packet size; in theory the maximum size remains at
the UDP maximum; we do have issue #383 which we to add a code if we
decide to do anything)

---

From: "Roy T. Fielding" <[email-masked]>
Date: Mon, 24 Apr 2017 11:05:32 -0700

> On Apr 23, 2017, at 9:41 PM, Martin Thomson <[email-masked]> wrote:
> 

Assuming we are only talking about transport codes, I would expect

 * parameter too long

   for any length-delimited parameter;

 * unrecognized application

   for quic recipients that might detect multiple app protocols;

 * timeout before application-level

   for the rare case where the transport is unable to continue before
   it can invoke anything that might respond with application-level semantics; and

 * timeout while decrypting

   because that can happen and is near impossible to determine otherwise.

....Roy

---

From: Martin Thomson <[email-masked]>
Date: Thu, 27 Apr 2017 13:31:38 +1000

> Assuming we are only talking about transport codes, I would expect

I've subsumed this in what I'm proposing be called FRAME_FORMAT_ERROR.
I don't see a lot of value in being more precise given that the action
is the same: the other side is busted somehow.

>    for quic recipients that might detect multiple app protocols;

TLS handles this for us.  RFC 7301 defines a no_application_protocol
alert, which QUIC will use.

>  * timeout while decrypting

I'm going to argue that these don't need to be signaled over the wire.
We expect that applications will have to deal with these annoying
error conditions, but the other side doesn't need to be informed about
these specific conditions.  An endpoint that wants to signal something
can use one of the more generic codes.

Happy to open issues for those errors on which we don't agree, I'm not
militant about any of this stuff, I'm just looking to make a solid
start.

---

From: Martin Thomson <[email-masked]>
Date: Thu, 27 Apr 2017 13:42:49 +1000

Top posting because I now have the PR:

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

Please take a look, I don't plan to wait very long before merging this one.