Subject: Re: [quicwg/base-drafts] QUIC header format/demultiplexing (#426)

From: janaiyengar <[email-masked]>
Date: Wed, 06 Dec 2017 15:25:26 +0000 (UTC)

Copying discussion from #956 so that it's happening on this bug instead.

@ronieven said: "My understanding from the meeting was that there is no need to multiplex short header with stun so the change of the type values for the short header is a surprise and I did not see any discussion on the QUIC mailing list about this change. It is not mentioned also in the Singapore meeting notes. The change that was agreed as far as I remember was to flip the value of the connection ID flag since it will be on for the peer to peer case."

@csperkins said: "We certainly need to demux QUIC short header packets with STUN, to maintain bindings.

Changing the packet type values doesn't prevent the spin bit, although it might change which bit is used as the spin bit."

@britram said: "Note also that #989 would give us more degrees of freedom in the short header first octet."

@ekr said: "Colin is right here. You have to multiplex short headers with STUN b/c of consent checks, as well as candidates you learn about late"

-- 
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/426#issuecomment-349672705

---

From: janaiyengar <[email-masked]>
Date: Wed, 06 Dec 2017 15:35:45 +0000 (UTC)

@csperkins: I appreciate the need to mux with STUN packets. RFC 5389 says however: "In some usages, STUN must be multiplexed with other protocols (e.g., [MMUSIC-ICE], [SIP-OUTBOUND]).  In these usages, there must be a way to inspect a packet and determine if it is a STUN packet or not. STUN provides three fields in the STUN header with fixed values that can be used for this purpose.  If this is not sufficient, then STUN packets can also contain a FINGERPRINT value, which can further be used to distinguish the packets." Isn't this FINGERPRINT to be used for exactly this sort of use case where it conflicts with other packet types? Why doesn't demuxing on the FINGERPRINT work?

Separately, I'm not convinced that we need to mux with other protocols. If we agree on the need to mux QUIC packet types with STUN, then we lose only 4 packet types... but we seem to have put aside a lot more than that in #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/issues/426#issuecomment-349676110

---

From: Colin Perkins <[email-masked]>
Date: Wed, 06 Dec 2017 16:48:04 +0000 (UTC)

If all you care about is demuxing QUIC and STUN, then there are several alternatives. The fingerprint is one option, certainly. Inspecting the first two bits of the packet and checking for the presence of STUN Magic Cookie is another that's simpler (especially if we revert the C bit in the short header packets). 

I do think there are use cases for demuxing QUIC with other protocols, however (@aboba likely has input too). #956 (and the -08 draft) supports this with only minimal changes to QUIC (renumbering fields, no semantic changes). 

We do need to document a long-term stable demux algorithm for QUIC and STUN, and decide to what extent we want a stable algorithm for demuxing QUIC and other protocols. My feeling is that one of the QUIC invariants has to be an algorithm for demuxing QUIC and STUN, but for demultiplexing QUIC and other protocols we should say "this works for QUIC v1, but we don't guarantee for future versions of 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/issues/426#issuecomment-349700820

---

From: Martin Thomson <[email-masked]>
Date: Wed, 06 Dec 2017 12:27:07 -0800

@janaiyengar, we have reserved no packet types.  We have just changed the values we use.  If we don't have the freedom to do that between QUIC versions, then the entire invariants exercise was pointless.  As @csperkins says, the hacky multiplexing scheme used for realtime uses will need to assess every QUIC version independently.  That's possible viable there because of the use of session negotiation (SDP and all that).

-- 
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/426#issuecomment-349764267

---

From: ianswett <[email-masked]>
Date: Wed, 06 Dec 2017 22:17:49 +0000 (UTC)

I completely agree with your last point Martin, that we have no reserved packet types.  However, we still have some important issues to resolve, including greasing and possibly changing the packet number format, and we should resolve those before we do hacky changes, since solving those will likely cause us to do different hacky changes in the future.  Using TLS 1.3 as a model, I think we should hold off on hacky changes until towards the very end of the process.

I sent out PR #995 because draft 08 already introduced a ton of changes, this one was unnecessary at this stage, and there is a lot of discussion on this matter still, so there's no point in changing things now.  I'm happy that we're having that discussion on the list and here, so I think we'll figure out what we really need to make QUIC and WebRTC coexist.

I'd also like to be in a place where we can QUIC can coexist with other protocols fairly easily in general.  I don't have any concrete proposals yet, but UDP 443 is fairly heavily used, so it'd be nice to find a more general solution.

-- 
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/426#issuecomment-349793441

---

From: janaiyengar <[email-masked]>
Date: Wed, 06 Dec 2017 23:09:11 +0000 (UTC)

@csperkins: Agreed that #956 changes packet type syntax only, and it solves the problem of avoiding any collision with the space in RFC 7983. But as @ianswett points out, we want to do greasing, which might introduce semantics into this space. From where I see it, we can't be done sorting out packet types until two things are resolved: which collisions to avoid, and how, if possible, to do greasing.

@martinthomson: I agree that we don't have any reserved packet types, and so we are free to change them across versions. My note earlier was about *this* version of QUIC -- QUIC v1, or more precisely, draft -08. The packet types chosen in #956 have a very specific end-goal -- to avoid a collision with 7983. Given that, only one of two things is true: either QUICv1 packet types avoid a collision with 7983, in which case we are setting those types aside as not usable (what I termed "reserved") for QUIC v1; or QUICv1 packet types don't avoid a collision with 7983, in which case #956 is entirely cosmetic. Which of these is reflected in the packet type choices in draft -08?

-- 
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/426#issuecomment-349805614

---

From: Colin Perkins <[email-masked]>
Date: Wed, 06 Dec 2017 23:12:09 +0000 (UTC)

@janaiyengar is greasing a problem? Grease as much as you like, unless you want to multiplex. If you want to multiplex, you know what you're multiplexing with, and so can avoid those packet types when greasing. Yes, we should write this down. 

-- 
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/426#issuecomment-349806242

---

From: janaiyengar <[email-masked]>
Date: Wed, 06 Dec 2017 15:31:26 -0800

@csperkins I agree, and that's exactly the discussion I'm trying to have -- specifically, what do we *need* to multiplex with?

-- 
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/426#issuecomment-349810249

---

From: Colin Perkins <[email-masked]>
Date: Wed, 06 Dec 2017 23:36:59 +0000 (UTC)

@janaiyengar we _need_ to multiplex with STUN, else we'll end up reinventing it within QUIC when we want to run peer-to-peer. 

We want to multiplex with WebRTC (DTLS, RTP, STUN) since people want to use QUIC in place of the WebRTC data channel (and because it might be useful to run WebRTC from the server you're running HTTP/QUIC from). We likely also want to multiplex with gQUIC as a transition.

In practice, I think we need to mandate STUN demux in the QUIC spec. Anything else can be left for a separate document – it doesn't affect how QUIC greases, and muxing other protocols doesn't have to be written into the QUIC documents. We just need to be a little careful as we define QUIC v1.

-- 
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/426#issuecomment-349811382

---

From: janaiyengar <[email-masked]>
Date: Wed, 06 Dec 2017 23:48:03 +0000 (UTC)

I agree with most of your classification, with the caveat that gQUIC is a slightly different beast in that we need to be able to demux for a short while until everything is off of gQUIC, and then we don't need to worry about it anymore.

On STUN, I heard you say earlier that we can use the FINGERPRINT for this purpose. Is it reasonable to use this instead of the packet type to demux from 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/issues/426#issuecomment-349813393

---

From: Roni Even <[email-masked]>
Date: Wed, 06 Dec 2017 22:30:19 -0800

If we only want STUN demux we had a problem with the short header and my recollection is that the solution was to flip the value of the C bit since connection ID will not be needed in peer to peer assuming that for client server we will not need STUN.

-- 
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/426#issuecomment-349876026

---

From: Colin Perkins <[email-masked]>
Date: Thu, 07 Dec 2017 12:41:22 +0000 (UTC)

@janaiyengar you can't just use the fingerprint. The algorithm to identify STUN is to check that the first two bits of the packet are 00, then check the magic cookie (bits 33-64 = 0x2112A442), then if necessary find and check the fingerprint attribute. Checking the fingerprint is relatively expensive.

QUIC long header packets don't conflict with STUN, since QUIC long header packets start 0b1x and STUN packets start 0b00. The fingerprint isn't needed.

QUIC short header packets don't conflict if either the C bit is 1 or the C bit is set to 0 and bits 33-64 differ from 0x2112A442. We can avoid collisions without requiring the STUN FINGERPRINT by making the C bit an Omit Connection ID bit (as in #956), and changing the Connection ID to be either (a) a 63-bit value with bit 64 always set to 1; or (b) a 56-bit value in the range 64 to 2^62-1 (i.e., a 64-bit value where the top two and the lower six bits are set to zero) formatted using the variable length integer encoding.

Both these changes seem conceptually clean, and would be QUIC version independent and fit with the invariants. 

That said, I think there's value in demuxing with WebRTC traffic in addition to STUN, at least for QUIC version 1. Renumbering the fields as in #956 is independent of the above discussion of how to demux STUN, doesn't change QUIC semantics, and enables us to do this. 

-- 
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/426#issuecomment-349955910

---

From: Marten Seemann <[email-masked]>
Date: Thu, 07 Dec 2017 12:47:59 +0000 (UTC)

@csperkins: Does your argument assume that connection IDs are never omitted when QUIC is multiplexed with STUN? If so, we have a tradeoff here (is sending the 8 byte connection ID on every packet more expensive than checking the fingerprint?).

-- 
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/426#issuecomment-349957391

---

From: Colin Perkins <[email-masked]>
Date: Thu, 07 Dec 2017 04:53:49 -0800

@marten-seemann no, it doesn't assume that. In short header packets C = 1 to mean connection ID is omitted avoids collisions with STUN. If the Connection ID is present, then C = 0 which makes the first two bits of the packet match those of STUN packets, but if we change the legal values of Connection ID as in my previous we still avoid collisions with STUN when the Connection ID is present. No STUN FINGERPRINT needed in either case.

-- 
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/426#issuecomment-349958649

---

From: ianswett <[email-masked]>
Date: Thu, 07 Dec 2017 16:19:21 +0000 (UTC)

> @marten-seemann no, it doesn't assume that. In short header packets C = 1 to mean connection ID is omitted avoids collisions with STUN. If the Connection ID is present, then C = 0 which makes the f…

Sorry, but I'm still a bit confused on the connection ID bit flip in general.

As Marten mentions, there are use cases for both omitting the connection ID from all packets when multiplexing QUIC with WebRTC and use cases for including it.  So inverting the meaning doesn't help solve any problems, unless you don't care about one of these?

-- 
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/426#issuecomment-350017471

---

From: Colin Perkins <[email-masked]>
Date: Thu, 07 Dec 2017 22:24:47 +0000 (UTC)

I was misreading the packet formats, which perhaps wasn't helping... But, to summarise, a STUN packet header is formatted as:

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |0 0|     STUN Message Type     |         Message Length        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                   Magic Cookie  = 0x2112A442                  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    |                     Transaction ID (96 bits)                  |
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

This is straight-forward to demux with QUIC long header packets, since they have the initial bit set to 1 and STUN has it set to zero. 

QUIC short header packets are:

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |0|C|K|   Type  |     [Connection ID (64)]                      |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                     [Connection ID (64)]                      |
    +               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |               |X X X X X X X X X X X X X X X X X X X X X X X X 
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X...
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

I assume the common case is that the Connection ID is not present. If we define C=1 to mean that the Connection ID is not present, then the first two bits of the QUIC short header packet will be 01. This is straight-forward to demux from STUN, since those bits are 00 in STUN packets.

If the Connection ID is present, then the QUIC short header packet will have C=0 and so start with the first two bits equal to 00, which matches the first two bits of a STUN packet. We also see that the 64-bit QUIC Connection ID occupies the same space as the last 8 bits of the STUN Message Type, the 16-bit Message Length, the Magic Cookie, and the first 8-bits of the Transaction ID. To demultiplex such a QUIC packet from STUN, we need to either (1) use the STUN FINGERPRINT; (2) redefine the QUIC Connection ID to be 63-bit value that encoded into a 64 bits for both long- and short-header packets, with the encoding chosen so that one of the middle bits is set to avoid collisions with the STUN magic cookie when sent in short header packets; or (3) choose the QUIC short header type values to avoid conflicts with STUN message types (which is what #956 does). None of these are pleasant, but I tend to think (3) is best, since it also allows demux of WebRTC traffic.

-- 
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/426#issuecomment-350113232

---

From: janaiyengar <[email-masked]>
Date: Thu, 07 Dec 2017 20:28:51 -0800

@csperkins : Does this mean that the short header type values in #956 are adequate and that redefining the C bit is unnecessary? That seems to follow unless I'm missing something.

I expect that the Connection ID will be present on all packets going from the client to the server (including ack packets) and that it will mostly be absent on packets going from the server to the client. This is what GQUIC does at the moment, and Google servers will require the client to always include connection ID on packets it sends.

-- 
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/426#issuecomment-350169269