Subject: [quicwg/base-drafts] Renumber packet types and invert Connection ID Flag (#956)

From: Colin Perkins <[email-masked]>
Date: Wed, 22 Nov 2017 17:53:51 +0000 (UTC)

This commit makes the following changes:

- Renumber long header packet types to count from 0x7f downwards, rather than from 0x01 upwards
- Renumber short header packet types to count from 0x1f downward, rather than from 0x01 upward
- Invert the sense of the Connection ID Flag in the short header packets, to become an Omit Connection ID Flag

This is a purely syntactic change, with no semantic impact on QUIC.

The purpose of the changes is to make it possible to easily demultiplex QUIC and STUN packets running on a single UDP port, to enable peer to peer use of QUIC. It also enables demultiplexing of WebRTC packets and QUIC packets on a single UDP port.

Discussed in QUIC and AVTCORE working groups at IETF 100 (draft-aboba-avtcore-quic-multiplexing-01) and on QUIC mailing list.

Addresses issue #426 
You can view, comment on, or merge this pull request online at:

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

-- Commit Summary --

  * Renumber packet types and invert Connection ID Flag

-- File Changes --

    M draft-ietf-quic-transport.md (52)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/956.patch
https://github.com/quicwg/base-drafts/pull/956.diff

-- 
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/pull/956

---

From: Martin Thomson <[email-masked]>
Date: Wed, 22 Nov 2017 23:07:56 +0000 (UTC)

martinthomson approved this pull request.

Thanks Colin.  As you say, this is a fairly modest change, but I'd like to double check that this doesn't cause issues for people who are already deploying versions of QUIC that might be hard to run concurrent with these new codepoints.

That includes @janaiyengar and @dtikhonov at a minimum.

-- 
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/pull/956#pullrequestreview-78599919

---

From: Marten Seemann <[email-masked]>
Date: Wed, 22 Nov 2017 23:39:49 +0000 (UTC)

I recently implemented the [header parsing logic for quic-go](https://github.com/lucas-clemente/quic-go/blob/master/internal/wire/header.go#L34-L72), such that it can handle both gQUIC and IETF QUIC. You might find my summary of the different formats for the type byte useful: https://docs.google.com/document/d/162BtfR84c6xTvAG6AaPK0dXSQXKahMrtJOXxNnpcwDw/edit?usp=sharing.

The current packet header format has the nice property that it is possible to decide if the packet is a gQUIC or an IETF QUIC packet by just looking at the type byte. This is possible due to the following properties:

### for packets sent by the server

For packets sent by the server the client already knows the QUIC version needed for parsing the packet, as soon as version negotiation is completed. Therefore, the only requirement here is that the type byte used for the Version Negotiation Packet in IETF QUIC is not used in gQUIC, and the type byte used for the gQUIC VNP is not used in IETF QUIC.
This property is guaranteed by the first bit of the type byte alone already (0x80 is unset in gQUIC, and set for an IETF QUIC VNP).

### for packets sent by the client

All gQUIC packets have bits 0x80 and 0x40 unset, and currently IETF QUIC packets either have 0x80 set (for long headers) or 0x40 set (for short headers, if connection ID omission is not allowed, which I assume is what server implementations will do).
This property would be changed by this PR (because the connection ID bit is inverted), so a server wouldn't be able to distinguish between gQUIC and short header 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/pull/956#issuecomment-346501729

---

From: Colin Perkins <[email-masked]>
Date: Wed, 22 Nov 2017 23:44:33 +0000 (UTC)

I haven't looked at gQUIC, but does it matter that the "server wouldn't be able to distinguish between gQUIC and short header packets"? Can it tell from the initial long header packets if the flow is gQUIC or IETF QUIC?

-- 
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/pull/956#issuecomment-346502425

---

From: Marten Seemann <[email-masked]>
Date: Wed, 22 Nov 2017 23:50:21 +0000 (UTC)

In order to do that, you would have to associate the packet with a flow, which would mean that the server would have to extract the connection ID from the header first. This might or might not be possible, depending on how we shift around the location of the connection ID.
Furthermore, this would have the not so nice property that packet handling would not be truly stateless anymore (since you'd have to do lookups in the connection maps). 

-- 
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/pull/956#issuecomment-346503278

---

From: Martin Thomson <[email-masked]>
Date: Thu, 23 Nov 2017 00:10:59 +0000 (UTC)

First, assume that you require a connection ID at the server.  The general case for packets sent by clients in gQUIC is 0b00pp1000.  The change to short headers in this PR makes the typical IETF QUIC type byte 0b00k111pp, though obviously we don't make any promises about those 1 octets (and we will probably want to grease them).

One possible strategy we could pursue here is to disable greasing until we wean people off gQUIC.  Or - perhaps better - negotiate greasing.  Actually, I like that second idea, because it suits Colin's use case very nicely.

-- 
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/pull/956#issuecomment-346506034

---

From: Marten Seemann <[email-masked]>
Date: Thu, 23 Nov 2017 00:26:50 +0000 (UTC)

@martinthomson: Right, I missed that part. Relying on bit 0x4 might be the solution here.
It doesn't change your argument, but clients in gQUIC can set the Version Flag, so the general case will be 0b00pp100v.

In general, I don't think greasing should be negotiated (we should always grease as much as possible), but if that's the only way to make a transition possible, this wouldn't be a bad option.

-- 
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/pull/956#issuecomment-346508009

---

From: Martin Thomson <[email-masked]>
Date: Thu, 23 Nov 2017 00:31:57 +0000 (UTC)

I wouldn't have suggested negotiation if not for this realtime case.  There, they probably want us to avoid using certain values (blame RFC 7983).  Negotiation would be a solution to that problem, and as long as the overwhelming majority of QUIC traffic greased, then it would all work out.  Of course, they negotiate sessions and could limit greasing to a narrower range of values.

-- 
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/pull/956#issuecomment-346508652

---

From: Colin Perkins <[email-masked]>
Date: Thu, 23 Nov 2017 00:36:22 +0000 (UTC)

Right – we likely want to grease by default, but have the ability to disable/limit greasing for certain flows where we know the greasing will conflict with other uses of the port. 

-- 
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/pull/956#issuecomment-346509151

---

From: Dmitri Tikhonov <[email-masked]>
Date: Thu, 23 Nov 2017 22:48:38 +0000 (UTC)

I did a [write-up about this](https://www.ietf.org/mail-archive/web/quic/current/msg02009.html) some time ago. I think this change will make it easier to differentiate between gQUIC and QUIC.  Types 0x1F, 0x1E, and 0x1D would give us the following gQUIC interpretations, in order:

1. 2-byte packet number; connection ID, nonce, public reset, version bits set.
1. 2-byte packet number; connection ID, nonce, public reset bits set.
1. 2-byte packet number; connection ID, nonce, version bits set.

gQUIC public resets do not have two-byte packet numbers.  Likewise, gQUIC version negotiation packets are unlikely to have two-byte packet numbers.

-- 
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/pull/956#issuecomment-346706234

---

From: ianswett <[email-masked]>
Date: Tue, 28 Nov 2017 16:37:06 +0000 (UTC)

I think this change doesn't change how difficult it is to support GQUIC and IETF QUIC at once.

The fact we're not moving the connection ID really helps, since we can always lookup by connection ID first, and then if nothing is found, try to parse it as a handshake packet that creates a new connection.

On the client side, the main issue would be version negotiation, since for every other packet, the client knows the version in use.  This VN codepoint is not used in GQUIC, so we should be all set.

But to pop the stack, I'm trying to walk through why the heuristics approach outlined in the draft isn't sufficient in practice.  The negatives like not being able to run DTLS and QUIC at the same time on the same 5-tuple seem like non-issues.  Can someone outline what the issues are that motivate this change?
https://tools.ietf.org/html/draft-aboba-avtcore-quic-multiplexing-01#section-2.3

The issue of greasing is real.  Unfortunately, I think we may need a way to communicate codepoints not to grease for WebRTC, GQUIC, and other future use cases.

If a server is running GQUIC and IETF QUIC at once, then it is actually using all the codepoints, just for two different protocols, so the space is effectively being greased.

-- 
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/pull/956#issuecomment-347582777

---

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

It's possible that we can still grease even for cases where multiplexing with RTP is desired, we just might multiplex less.  Would it help if I wrote up what I am considering specifying for greasing?

-- 
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/pull/956#issuecomment-347743336

---

From: Martin Thomson <[email-masked]>
Date: Wed, 29 Nov 2017 10:32:56 +0000 (UTC)

Merged #956.

-- 
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/pull/956#event-1363228686

---

From: Dmitri Tikhonov <[email-masked]>
Date: Wed, 29 Nov 2017 13:15:03 +0000 (UTC)

> I think this change doesn't change how difficult it is to support GQUIC and IETF QUIC at once.

Could you please elaborate why you think that?

And (emphasis added):
> The fact we're not moving the connection ID really helps, since *we can always lookup by connection ID first*, and then if nothing is found, try to parse it as a handshake packet that creates a new connection.

This is quite expensive compared to simply examining the packet header!  One can also imagine a situation where a demultiplexer forwards packets to two separate (processes or machines) QUIC implementations: gQUIC and IETF QUIC.  The demux would not have the associated state.

The fallback to looking up a connection for each packet to determine which QUIC version it is should be used as last resort.  I hope we can avoid it.

-- 
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/pull/956#issuecomment-347856752

---

From: Marten Seemann <[email-masked]>
Date: Wed, 29 Nov 2017 13:17:13 +0000 (UTC)

I'm surprised this was merged already. The problem of stateless packet handling wasn't solved, since relying on bit 0x4 will not work as soon as we start greasing (or change anything else for the short headers).

-- 
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/pull/956#issuecomment-347857262

---

From: ianswett <[email-masked]>
Date: Wed, 29 Nov 2017 13:28:55 +0000 (UTC)

Agreed on this merging sooner than I expected.  I realize we want to nail down the type byte, but I'm still not sure why we're doing this?

@dtikhonov You seemed to think it made supporting both at once easier than before?  Is that because all the new code points are either undefined or in practice unused in GQUIC?

@martinthomson Yes, I think it would help to have a specific greasing proposal written up that deals with both coexistence of GQUIC and IETF QUIC, as well as IETF QUIC and WebRTC.

-- 
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/pull/956#issuecomment-347860169

---

From: Colin Perkins <[email-masked]>
Date: Wed, 29 Nov 2017 13:37:11 +0000 (UTC)

> It's possible that we can still grease even for cases where multiplexing with RTP is desired, we just might multiplex less. 

When multiplexing, don’t grease the ranges being used by the protocols that you’re multiplexing with. You’re already exercising the ability to send packets using those bits.

> Would it help if I wrote up what I am considering specifying for greasing?

Likely, yes

-- 
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/pull/956#issuecomment-347862270

---

From: Dmitri Tikhonov <[email-masked]>
Date: Wed, 29 Nov 2017 14:08:51 +0000 (UTC)

@ianswett:  The reason I think this change makes it easier is that some of the [potential ambiguities](https://www.ietf.org/mail-archive/web/quic/current/msg02009.html) no longer exist.  The heuristics to tell one version from another using the new packet type numbering scheme based are described in [my original post above](https://github.com/quicwg/base-drafts/pull/956#issuecomment-346706234).  You state that you do not think this change make it easier to differentiate between packet types; I'd like to know why.

-- 
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/pull/956#issuecomment-347870674

---

From: ianswett <[email-masked]>
Date: Wed, 29 Nov 2017 14:52:49 +0000 (UTC)

Our server always requires connection id to be present on packets it receives, so the ambiguity you mention in your original post is not a problem.

With the previous numbering scheme, on the server side, we can just look at the first two bits.  If either is 1, then it's IETF QUIC, and if both are 0, it's GQUIC.

In the new scheme, I can still check the first bit for the long header, and then I can check the nonce bit, and if it's that's 1, it must be IETF QUIC because the client never sends a diversification nonce.  

But I believe the nonce bit is the bit that would end up being the spin bit, which could start making things pretty tricky.  It's probably worth thinking through what happens if two bits are reserved for measurement.

-- 
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/pull/956#issuecomment-347883901

---

From: Dmitri Tikhonov <[email-masked]>
Date: Wed, 29 Nov 2017 15:13:23 +0000 (UTC)

> With the previous numbering scheme, on the server side, we can just look at the first two bits. If either is 1, then it's IETF QUIC, and if both are 0, it's GQUIC.

I see.  If one can assume that 0x40 (multipath) bit is never set in GQUIC, then this is indeed very easy.  I did not make this assumption in my analyses to err on the conservative side.

> But I believe the nonce bit is the bit that would end up being the spin bit, which could start making things pretty tricky. It's probably worth thinking through what happens if two bits are reserve…

Are you saying that the packet type in the short header would be narrower and occupy fewer than the currently-allocated low five bits?  (I apologize for not being on top of this development.)

-- 
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/pull/956#issuecomment-347890390

---

From: Marten Seemann <[email-masked]>
Date: Wed, 29 Nov 2017 17:10:41 +0000 (UTC)

> But I believe the nonce bit is the bit that would end up being the spin bit, which could start making things pretty tricky.

That would be really unpleasant. What is the reason for inverting the Connection ID flag?
We had a type byte format that worked perfectly in all corner cases, and by merging this PR, we just destroyed this feature and create a big problem for all people who have gQUIC deployed.

-- 
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/pull/956#issuecomment-347929195

---

From: ianswett <[email-masked]>
Date: Wed, 29 Nov 2017 17:22:48 +0000 (UTC)

Yes, the 0x40 bit is always 0, because we never deployed multipath.

There's been quite a bit of discussion about the spin bit, including a new draft sent out today: 
https://datatracker.ietf.org/doc/html/draft-trammell-quic-spin-00

The current proposal makes the type shorter, but the nonce bit would still always be 1 in the above proposal, so as long as no other bits are used for anything, we should still be able to use the plan of looking at the first bit or the nonce bit to detect IETF QUIC?

But as Marten says, this PR definitely makes things more complex than I originally thought, particularly in light of other potential header changes.

-- 
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/pull/956#issuecomment-347932912

---

From: janaiyengar <[email-masked]>
Date: Wed, 29 Nov 2017 19:10:45 +0000 (UTC)

I'm surprised to see this PR merged -- I don't think we had agreed on STUN types being necessary to multiplex with. In addition to concerns about GQUIC vs QUIC, there remains the high-level question of what do we need to multiplex QUIC with on the same port. This was a conversation that made good progress in Singapore, and I was expecting to continue it and finalize on list.

-- 
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/pull/956#issuecomment-347964273

---

From: janaiyengar <[email-masked]>
Date: Wed, 29 Nov 2017 20:03:54 +0000 (UTC)

Let's have discussions on issues and not PRs. Let's please continue this on #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/pull/956#issuecomment-347979609