Subject: More on demultiplexing

From: Eric Rescorla <[email-masked]>
Date: Wed, 6 Dec 2017 10:41:48 -0800

I've been doing some thinking about the QUIC muxing story. It seems
like the case that everyone has in their head is WebRTC, so I'd like
to focus on that. It seems to me that there are two main deployment models
one might have in mind:

- A browser unilaterally decides to support QUIC-WebRTC and just advertises
  it in its SDP, so that if that browser encounters another such browser,
  they do QUIC

- A service provider decides to do QUIC-WebRTC and turns it on for
  clients which can do it.

These have different muxing requirements, and then there are also
some subchoices about whether you want everything in WebRTC to be QUIC
or just parts of it.

As background, current WebRTC stacks attempt to mux all of the
following protocols on the same 5-tuple:

- STUN (for ICE and for TURN)
- TURN channels
- DTLS (for key management)
- SRTP (for media)

Note that I don't say SCTP because that's encapsulated in DTLS.

STUN
I think the general consensus is that we need to be able to mux STUN
with QUIC, because otherwise we would need to reinvent all of STUN
and ICE and that would be very not fun, and in some ways problematic
because the non-ICE parts of STUN don't assume any server authentication
so it's not clear how you would ever think to do them with QUIC.

TURN
TURN can either run over STUN, in which case it's covered by the previous
case, or it can run in channels, which are not. If you're willing to
abandon channels, then you don't have a problem. If you're not, then you
need TURN channels to work. I've heard suggestions that we should run
TURN over QUIC but I don't think that's sensible because the point of
TURN channels is to reduce overhead, and at that point you probably
could run the non-channel version of TURN without too much overhead
loss vis-a-vis QUIC and then you wouldn't have to address other problems
(e.g., server auth) that we never really resolved with TURN-TLS and would
maybe come back with QUIC.

DTLS and SRTP
Exactly what you need here depends on the deployment model. One might
imagine having QUIC-WebRTC in which the media and data channels are both
carried on QUIC, but you might also imagine having the data channel be
QUIC but the media being carried over RTP. I know there's active work
on a mapping for media over QUIC, but it's obviously not as straightforward
as a datachannels mapping, for which QUIC is basically a drop-in replacement
for SCTP, so that's a consideration here.

In the case where you wanted SRTP separately, you would then need to
either (a) figure out a way to demux SRTP and QUIC or (b) not run them
on the same 5-tuple.  (b) seems natural at some level, but
we adopted BUNDLE for a reason and this would push against that. So,
it seems to me that if you want to run data-over-QUIC and
media-over-SRTP you probably do need to figure out how to demux.

In the case where you mux SRTP and QUIC on the same 5-tuple, you then
have to address key management. You could, of course, run DTLS-SRTP
and demux DTLS, but it seems like you could probably just use QUIC's
TLS handshake the way you run DTLS-SRTP and do the SRTP exporter from
there, so maybe you don't need to mux DTLS.

-Ekr

---

From: Ted Hardie <[email-masked]>
Date: Wed, 6 Dec 2017 11:15:46 -0800

Howdy,

Some additional thoughts and clarifying questions in-line.

> to focus on that. It seems to me that there are two main deployment models
I think there is a case zero here that we all agree should just work:
downloading the javascript application for WebRTC should be the same over
HTTPS-QUIC as it is for HTTPS-TLS.  It's worth saying out loud only because
we have to remember that this support is orthogonal: it neither helps nor
hurts the WebRTC application's functioning once it is loaded in the browser.

> - A service provider decides to do QUIC-WebRTC and turns it on for
Probably worth pasting the usual ascii art here for the benefit of folks
who think about QUIC and haven't thought about WebRTC much:

                +-----------+             +-----------+
                |   Web     |             |   Web     |
                |           |  Signaling  |           |
                |           |-------------|           |
                |  Server   |   path      |  Server   |
                |           |             |           |
                +-----------+             +-----------+
                     /                           \
                    /                             \ Application-defined
                   /                               \ over
                  /                                 \ HTTPS/WebSockets
                 /  Application-defined over         \
                /   HTTPS/WebSockets                  \
               /                                       \
         +-----------+                           +-----------+
         |JS/HTML/CSS|                           |JS/HTML/CSS|
         +-----------+                           +-----------+
         +-----------+                           +-----------+
         |           |                           |           |
         |           |                           |           |
         |  Browser  | ------------------------- |  Browser  |
         |           |          Media path       |           |
         |           |                           |           |
         +-----------+                           +-----------+

In your case one, the SDP flows over the signaling path, which is why this
isn't an 'open box with enclosed ax' situation.  For your case two, I'm
assuming you mean a conference bridge situation, where the clients notify
the bridge that they can handle QUIC and the bridge speaks some QUIC and
some non-QUIC flavors of WebRTC.

> for SCTP, so that's a consideration here.
I agree that the QUIC substitution for the current data channel stack is
pretty straight forward.

On the media side, I have a question about using a PERC-like approach with
QUIC.  PERC's framework document gives this summary of its goals and
methods:

   This solution framework focuses on the end-to-end privacy and
   integrity of the participant's media by limiting access of the end-
   to-end key information to trusted entities.  However, this framework
   does give a Media Distributor access to RTP headers and all or most
   header extensions, as well as the ability to modify a certain subset
   of those headers and to add header extensions.  Packets received by a
   Media Distributor or an endpoint are authenticated hop-by-hop.

   To enable all of the above, this framework defines the use of two
   security contexts and two associated encryption keys: an "inner" key
   (an E2E key distinct for each transmitted media flow) for
   authenticated encryption of RTP media between endpoints and an
   "outer" key (HBH key) known only to media distributor and the
   adjacent endpoint) for the hop between an endpoint and a Media
   Distributor or between Media Distributor.  Reference the following
   figure.

If I am reading this correctly, the parallel method to use in PERC for QUIC
would have a set of private keys for the media and would carry the media
encrypted with those keys in one set of streams, but would make the header
information available on a different set of streams, encrypted only at the
transport layer .  That makes the header information something that QUIC
can pass up to the media distributor (presuming the endpoints were speaking
QUIC to the media distributor), but the RTP protected as PERC intends.

That looks fairly do-able to me, but my familiarity with PERC is glancing
at best, so it would be useful if someone with more familiarity could
comment.  Supporting PERC has a lot of benefits for privacy, and I would
like to make architectural support for it a requirement, if the timing
allows.

> I think if you bundled all the media on one 5-tuple and had QUIC on
another, the core NAT exhaustion problem would not be that bad.  There are
some corner cases where the media is meant to be tightly synced to the
media and might end up on a different path because it is a different
5-tuple.  If the paths are not equivalent latency, that can bite you.

> there, so maybe you don't need to mux DTLS.
Having to run DTLS for DTLS-SRTP seems kind of sub-optimal to me, but
that's a gut reaction rather than a measured analysis.

Ted

---

From: Mikkel Fahnøe Jørgensen <[email-masked]>
Date: Wed, 6 Dec 2017 11:17:27 -0800

On 6 December 2017 at 19.42.37, Eric Rescorla ([email-masked]) wrote:

to focus on that.

Well, the concern is probably that QUIC might not have a routable UDP port
otherwise, and WebRTC is likely available.

Another case could be port 53 for QUIC/DNS.

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 6 Dec 2017 11:24:51 -0800

On Wed, Dec 6, 2017 at 11:17 AM, Mikkel Fahnøe Jørgensen <[email-masked]
> wrote:

> otherwise, and WebRTC is likely available.
I don't understand what you are saying here. WebRTC does not have a defined
port.

-Ekr

---

From: Mikkel Fahnøe Jørgensen <[email-masked]>
Date: Wed, 6 Dec 2017 11:39:01 -0800

I was considering corporate and server firewalls, e.g. having QUIC traffic
piggy backing on open ports for things like video chat, but come to think
of it, this has more to do with NAT traversal.

---

From: Colin Perkins <[email-masked]>
Date: Wed, 6 Dec 2017 23:43:53 +0000

> On 6 Dec 2017, at 18:41, Eric Rescorla <[email-masked]> wrote:
> 
> so it’s not clear how you would ever think to do them with QUIC.

Agree.

> maybe come back with QUIC.

Do TURN channels need to demux with QUIC? I was assuming we’d run STUN/TURN channels to a server, or QUIC+STUN+DTLS+SRTP to a server, but not both? (i.e., it’s either a TURN server or a media endpoint, but not both).

> media-over-SRTP you probably do need to figure out how to demux.

agree.

> there, so maybe you don't need to mux DTLS.

Exporting SRTP keys  from the QUIC handshake seems  sensible, but is an extra level of specification complexity. I suspect we’ll want SRTP demux short term, key export in medium term, and RTP-in-QUIC in longer term.

-- 
Colin Perkins
https://csperkins.org/

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 6 Dec 2017 15:47:04 -0800

On Wed, Dec 6, 2017 at 3:43 PM, Colin Perkins <[email-masked]> wrote:

> Do TURN channels need to demux with QUIC? I was assuming we’d run
> STUN/TURN channels to a server, or QUIC+STUN+DTLS+SRTP to a server, but not
> both? (i.e., it’s either a TURN server or a media endpoint, but not both).
>

You might (for instance) start sending data to a TURN server and then have
a srflx candidate succeed.

> Exporting SRTP keys  from the QUIC handshake seems  sensible, but is an
> extra level of specification complexity. I suspect we’ll want SRTP demux
> short term

Note that if you don't expert keys, then you need DTLS demux (or no bundle)

-Ekr

---

From: Cullen Jennings <[email-masked]>
Date: Thu, 7 Dec 2017 11:59:42 -0700

> On Dec 6, 2017, at 12:15 PM, Ted Hardie <[email-masked]> wrote:
> 
> I think if you bundled all the media on one 5-tuple and had QUIC on another, the core NAT exhaustion problem would not be that bad. 

It would be twice as bad :-) When creating the offer, the device that creates it does not know if it will be getting QUIC based stuff or not so you want to include both in the offer. For the same reason we don't want to gather two ports for RTC and RTCP, I think we will want to run both on same port. I think google's data showed that nat traversal success rates were worse when using two ports instead of one. 

So my preference would be to be able to multiplex WebRTC using QUIC and and WebRTC not using QUIC on the same port.

---

From: Jana Iyengar <[email-masked]>
Date: Thu, 7 Dec 2017 11:46:08 -0800

Up-leveling for a moment: Is it reasonable to consider a model where the
endpoints determine which protocols need to be muxed and therefore which
type bytes are kosher to use for QUIC on any given connection?

I'll describe a simple strawman which is only meant to be illustrative.
Strawman: Each application knows what protocols it may need to mux on the
same port, and therefore knows which first bytes it may need to mux. Based
on this information, in its transport params sent during the QUIC
handshake, the client sends a list of packet types to avoid. The server
similarly sends its list to the client in its transport params. Both
endpoints use the union of the two sets as the packet types to avoid using
in this connection.

Both ends are now free to grease packet types over the rest of the type
space. The greasing algorithm we specify for QUIC v1 will do the right
thing and avoid using the types that the endpoints have agreed on.

This leads to two types of packet types:
- Muxing-agnostic packet types: We'd have to use some long header types to
do the handshake where we communicate the muxing list. These might conflict
with a muxing list if it exists, so we may want to choose these types a bit
more carefully for QUIC v1. That said, I think this would only be a couple
of packet types (Initial and Handshake types probably?) This may also be
useful given that load balancers will likely want to know about handshake
packets anyways.
- Muxing-aware packet types: The rest of the packet types can be greased
over the rest of the type space, avoiding values known to belong to
protocols one of the endpoints wants to mux.

Does this seem anywhere near reasonable? What am I missing if it isn't?

On Thu, Dec 7, 2017 at 10:59 AM, Cullen Jennings <[email-masked]> wrote:

> another, the core NAT exhaustion problem would not be that bad.
>
> It would be twice as bad :-) When creating the offer, the device that
> creates it does not know if it will be getting QUIC based stuff or not so
> you want to include both in the offer. For the same reason we don't want to
> gather two ports for RTC and RTCP, I think we will want to run both on same
> port. I think google's data showed that nat traversal success rates were
> worse when using two ports instead of one.
>
> So my preference would be to be able to multiplex WebRTC using QUIC and
> and WebRTC not using QUIC on the same port.
>
>
>

---

From: Christian Huitema <[email-masked]>
Date: Thu, 7 Dec 2017 11:51:28 -0800

> So my preference would be to be able to multiplex WebRTC using QUIC and and WebRTC not using QUIC on the same port. 
+1. When dealing with NAT, there is a cost per port to "opening a hole
for the port", in terms of messages to open the port, risks to cause
resource exhaustion in a local NAT, and requirement to keep the port
alive. Everything on one port is nice.

By the way, how strongly do we feel about making decisions based on
first byte alone? In the case of QUIC, the connection ID provides a
pretty big clue. If we use that, demux becomes significantly simpler.
There are still issues during the connection phase, as the first message
from the peer carries an unknown connection ID, but that could be
handled with special logic. Also, don't STUN messages carry a magic
number precisely to help demuxing?

-- Christian Huitema

---

From: Jana Iyengar <[email-masked]>
Date: Thu, 7 Dec 2017 12:00:39 -0800

> alive. Everything on one port is nice.

I agree on this point. It's more than just nice -- it avoids strange
partial failures when one part of the communication works (over one port)
but the other part (over the other port) doesn't.

> number precisely to help demuxing?

Why have the same conversation once in one place when we can have it twice
in two places :-) I raised this  point in #426
<https://github.com/quicwg/base-drafts/issues/426>, and Colin responded
there, you may want to take a look. He does suggest using connection ID,
but it's not yet clear to me that the C bit needs to be changed in that
case.

---

From: Bernard Aboba <[email-masked]>
Date: Thu, 7 Dec 2017 15:10:12 -0500

On Dec 6, 2017, at 2:15 PM, Ted Hardie <[email-masked]> wrote:
>> 
> I agree that the QUIC substitution for the current data channel stack is pretty straight forward.

[BA] Not quite true yet. To be able to completely substitute for SCTP, QUIC needs support for unreliable streams. One message per stream and a timer enables support for maxPacketLifetime, but not maxRetransmits. So for now QUIC cannot provide every use case supported by an SCTP data channel. That means that some applications might want both (e.g. SCTP for small unreliable messages, QUIC for a background file transfer).

> That looks fairly do-able to me, but my familiarity with PERC is glancing at best, so it would be useful if someone with more familiarity could comment. 

[BA] There is a basic question here which is whether the Javascript is trusted. Creating two transports under JS control is not the same model PERC is using, where the KMF is administered separately from the conferencing service.

> I think if you bundled all the media on one 5-tuple and had QUIC on another, the core NAT exhaustion problem would not be that bad. 

[BA] Virtually all WebRTC applications use BUNDLE today so the market for “not that bad” doesn’t seem very big. 

> Having to run DTLS for DTLS-SRTP seems kind of sub-optimal to me, but that's a gut reaction rather than a measured analysis.

[BA] Sub-optimal perhaps, but initial deployments won’t support QUIC-SRTP and could need to multiplex DTLS with QUIC anyway.

---

From: Bernard Aboba <[email-masked]>
Date: Thu, 7 Dec 2017 15:11:55 -0500

> Exporting SRTP keys  from the QUIC handshake seems  sensible, but is an extra level of specification complexity. I suspect we’ll want SRTP demux short term, key export in medium term, and RTP-in-QU…

[BA] +1.

---

From: Ian Swett <[email-masked]>
Date: Thu, 7 Dec 2017 16:48:24 -0500

I was thinking along those lines as well, Jana, since I think we have a
pretty general problem here, and if we grease the type byte, I think we can
create a fairly simple solution.

As you mentioned, the WebRTC over QUIC mapping would have to specify which
QUIC codepoints could not be used in the short and long header.  As a
slight tweak on your idea, I think that only the application should specify
what codepoints cannot be greased for the long header, but the transport
params can contain additional codepoints which are to be avoided by the
peer in the short header.  So the list of codepoints to avoid are not
negotiated, but communicated.(ie: the client might be fine with anything
and the server might exclude DTLS codepoints).  And any codepoints the
application mapping specifies should be avoided do not need to be
communicated in transport params.

As an example, this means that even if the types are 0 through 3, those
codepoints may be excluded and never sent on the wire and in reality,
numbers more similar to the submitted PR#956 may be sent on wire.

This means there may be conflicts between the long header and a different
application that happens to be running on a given port, but those can be
handled by looking for long headers and checking the version before doing
any more expensive processing.

Cases like WebRTC should be easy to handle by excluding the problematic
codepoints in the WebRTC over QUIC mapping.

The only(obvious) rule is that you can't exclude all ways to express a
given type, but that's dependent upon the exact type byte greasing
approach, which hopefully we can separate from the multiplexing approach.