Subject: [quicwg/base-drafts] One packet type in invariants (#963)

From: Mike Bishop <[email-masked]>
Date: Tue, 28 Nov 2017 23:28:30 +0000 (UTC)

The set of packet types is version-dependent, *except* that Version Negotiation has a fixed packet type across all versions.  We could make packet types entirely version-dependent by a simple change:  Version Negotiation packets always indicate a version of '0', and the type field is randomized on send / ignored on receipt.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/963

---

From: Mike Bishop <[email-masked]>
Date: Tue, 28 Nov 2017 23:38:27 +0000 (UTC)

If we land #939 first, we have the option of saying that version 0 packets don't have a packet number and saving a few bytes, but the question is open whether we want to have what becomes a third packet header.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/963#issuecomment-347701469

---

From: Martin Thomson <[email-masked]>
Date: Wed, 29 Nov 2017 00:37:20 +0000 (UTC)

I think that it makes sense to continue to mark Version Negotiation as long.  Otherwise there is some amount of guessing required to find the Version field.  That suggests that it continues to use that bit, but that doesn't necessarily constrain us to the use of a particular type beyond that.

The expected order of operations for receipt of a packet is to check the long header bit, then to check the version.  Once that is done, we could say that the type is ignored.  That means we could make it entirely randomized (which effectively destroys our future ability to use those bits), a specific value (which would allow us to generate other signals for clients that support future versions if we specified that packets are ignore if other values are found there), or define a more specific scheme.

I don't think that there is any value in versioning version negotiation.  That way leads to madness.  I'm ambivalent about random vs. specific value.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/963#issuecomment-347712686

---

From: Marten Seemann <[email-masked]>
Date: Thu, 30 Nov 2017 21:12:13 +0000 (UTC)

Defining a fixed value for the type byte of the version negotiation packet has the nice property that for the client, the only thing you need to do when parsing a packet header is look at the type byte (it's the same principle I'm arguing for in #426).

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/963#issuecomment-348322192

---

From: Mike Bishop <[email-masked]>
Date: Thu, 30 Nov 2017 21:14:29 +0000 (UTC)

That's a desire I'm sympathetic to, but a packet inherently cannot be self-describing from the first byte unless you already know what version you're interpreting the first byte against.  I'm willing to take a slightly slower path in the cases where that's not true.

On a client, that's less of a problem (I think), because at any given time, there are at most two versions you could get -- the one you sent, or version negotiation.  That means that the type value could be quasi-invariant -- it's version-dependent, except that some value has to be reserved for version negotiation, but since the server obviously didn't speak your version that value has to be fixed across versions.  I don't like something being kinda-sorta-invariant, but it would work.

On a server, where you come into an initial packet with no advance knowledge of the connection's version, the space is infinite, so the process *must* be to find the long header bit, find the version field, and then either start version negotiation (if you don't recognize it) or begin version-specific parsing (if you do).  Servers will have to look at more than the first byte to establish the expected packet layout.

And if we're willing to say that you have to look at the version field to figure out the packet layout, then I think the requirement becomes:

- From the first byte, you can identify the location of the Version field
- If you already know the version, you can identify the packet layout from the first byte (but please verify the version)

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/963#issuecomment-348322783

---

From: MikkelFJ <[email-masked]>
Date: Thu, 30 Nov 2017 21:57:52 +0000 (UTC)

I'd argue for testing long header bit, then check for version 0 and for other known versions.

I'd argue against randommizing the type byte for version 0. The reason being that it makes it difficult to multiplex other protocols over the same connection. QUIC version numbers may also be chosen very carefully to avoid conflicts with other protocols where there might be conflicts beyond the first byte when the high bit is set.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/963#issuecomment-348334055

---

From: janaiyengar <[email-masked]>
Date: Fri, 01 Dec 2017 00:48:54 +0000 (UTC)

I agree with @MikeBishop. I don't think there's a need to specify the order of processing things, but thank you for laying it out clearly. That said, randomizing it right now will conflict with the same types that #956 seeks to avoid. Greasing the packet type will run into that, so we'll need to specify carefully how to grease this byte. 

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/963#issuecomment-348368434

---

From: Christian Huitema <[email-masked]>
Date: Fri, 01 Dec 2017 02:04:40 +0000 (UTC)

I would rather use a constant value, and actually keep the version negotiation type that we have already defined. Yes, this will constrain further versions to not redefine that type. But then, so what?

I am also very lukewarm about the idea of making packet types version dependent, e.g. having sometimes the client initial be 17 and some times 29. That will require implementations to insert some level of indirection between the abstract types used internally and the type in the wire format. This looks like gratuitous complexity.

I like the idea of removing the dependency on the sequence number. That's a clear benefit, since implementations cannot guarantee that they can parse sequence numbers from unsupported versions.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/963#issuecomment-348380351

---

From: janaiyengar <[email-masked]>
Date: Thu, 30 Nov 2017 21:50:10 -0800

@huitema: are you suggesting that we make packet types version-independent? That seems unnecessary rigidity, since a later version of QUIC shouldn't have to deal with legacy types it's not using. For instance, we currently use different short types for different packet number sizes; it's seems quite likely that we'll change that in future versions.

I think it's a good idea to be clear about what won't change and what will across versions. Our general premise has been so far to assume packet type will change across versions, which is why VN packets stick out, and using the version field instead of type for them makes _all_ types version independent. There's value in this that we can unequivocally that packet type must not be interpreted by stateless middleboxes, otherwise we have to equivocate.

Agreed on removing packet number from VN packets.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/963#issuecomment-348407727

---

From: janaiyengar <[email-masked]>
Date: Thu, 30 Nov 2017 21:59:46 -0800

@marten-seemann : I agree that it's simpler with simply a type byte, but honestly I don't think it's much more complex with a version field in the picture as well. It's a bit of getting used to, but the value is in the clarity about the type field being entirely version-dependent, for both long and short header packets (which it almost was, but this makes it entirely so.)

Importantly, making the type field version dependent and stating it as such hopefully forces middleboxes to actually pay attention to the version field, and middlebox implementers to read the spec. This is a big part of greasing -- to ensure that implementers have to go read the spec to figure out how to parse packets instead of looking for patterns on the wire -- and having types be different across versions helps, IMO.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/issues/963#issuecomment-348408958