Subject: Re: [MMUSIC] Merging ICE aggressive and regular nomination (was Re: [tram] Comment on draft-williams-peer-redirect-01: might it not converge?)

From: Iñaki Baz Castillo <[email-masked]>
Date: Fri, 1 Aug 2014 10:15:53 +0200

2014-08-01 3:06 GMT+02:00 Justin Uberti <[email-masked]>:
> On Thu, Jul 31, 2014 at 5:34 PM, Martin Thomson <[email-masked]>
> wrote:
>>
>> On 31 July 2014 15:40, Iñaki Baz Castillo <[email-masked]> wrote:
>> > - For DTLS it means complexity in the sense that a separate DTLS
>> > session/context is required for each "transport".
>>
>> Not really.  DTLS "says" that, but it doesn't functionally rely on a
>> stable 5-tuple in any real fashion.
>>
>> Other protocols that rely on UDP are likely to be similar.  Reliance
>> in name only.
>
>
> Think of ICE as a virtual socket.

I assume you mean "DTLS" rather than "ICE".

> At higher layers, you don't know the
> address of the remote endpoint or exactly how it will be contacted, but you
> know if you send something on the virtual socket it will make it to the
> remote endpoint. That's all DTLS needs to know.

Sure. But for that, in case of UDP, you need a *separate* DTLS
"virtual socket" for each different UDP remote address from which you
receive DTLS packets (you don't want to pass two different ClientHello
to the same DTLS virtual socket, assuming that each DTLS virtual
socket handles a single DTLS session/context, right?).

Well, I will try to explain my concern better:

- Let's assume that peerA is a full ICE agent and announces two host
candidates (due to two interfaces eth0 and eth1 connected to
Internet).

- peerB is also full ICE agent which announces a single host candidate.

- To simplify, both agree on rtcp-mux and so on.

- peerA is the controlling and uses aggressive nomination.

- At some point peerB receives a ICE USE-CANDIDATE in its socket
coming from peerA's eth0 and another ICE USE-CANDIDATE in its same
socket coming from peerA's eth1. Let's name those paths "pair1" and
"pair2", both of them are "valid" (regardless which is the
"selected"/"nominated" one).

- And since it is being said in this thread that "ICE is not supposed
to find a *single* transport path" then peerA sends two different DTLS
ClientHello, one over pair1 and the other over pair2.

- Both ClientHello reach the *same* socket on peerB. If peerB holds a
single DTLS "virtual socket" (this is: a single DTLS session/context)
then the second ClientHello will be discarded by the DTLS session (as
it has already received a previous ClientHello with different seq
number and so on). And it would be difficult for peerB to know whether
it must send back its DTLS generated response packets to peerA's eth0
or eth1.

Is it clear now what I mean?

There are two ways to handle this "issue":

1) Ignore any DTLS packet received over a non selected/nominated ICE
pair (so both peers must compute the same selected pair after ICE
procedures and just use *that* for sending DTLS).

2) Allow DTLS packets received over any valid ICE pair (those from
which the remote peer has sent valid and authenticated Binding
requests with USE-CANDIDATE). For this a separate DTLS
session/context/virtual-socket is needed for each valid ICE pair.

PS: In the text above I'm assuming that peerA initiates two different
DTLS handshakes over pair1 and pair2. In case bullet 2) is the way to
go, may we assume/mandate at least that peerA MUST perform a *single*
DTLS handshake (regardless packets are sent and received via pair1 or
pair2 or via both of them)?

Thanks a lot.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Fri, 1 Aug 2014 10:36:38 +0200

> I assume you mean "DTLS" rather than "ICE".

Sorry, you meant "ICE".
Then I assume that I'm right in the PS comment at the end of my
previous mail, is that correct?

Thanks a lot.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Martin Thomson <[email-masked]>
Date: Fri, 1 Aug 2014 09:04:25 -0700

> pair2 or via both of them)?

You can only have one DTLS connection, however...

Sending two ClientHellos is OK, because DTLS requires retransmission
of ClientHello to deal with packet loss.  The server should treat
those as duplicates (and if they don't carry the same information, you
are setting yourself up for failure when it comes to generating the
Finished message).

---

From: Justin Uberti <[email-masked]>
Date: Fri, 1 Aug 2014 16:02:42 -0700

> are setting yourself up for failure when it comes to generating the

Agreed. I don't understand why peerA would issue 2 *different* ClientHellos
to the two remote candidates; peerA only wants to establish a *single* DTLS
connection.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Sun, 3 Aug 2014 00:06:26 +0200

> are setting yourself up for failure when it comes to generating the

OK, that's clear. If a single DTLS handshake is allowed then things
become easier.

Just a question: how to determine the remote address for sending data?
Theoretically that is determined by the "selected ICE pair", but what
about if, at some point, the remote peer sends a valid SRTP packet
from a different address (let's imagine it is an address from which a
valid ICE Binding request with USE-CANDIDATE was previously received
assuming the remote peer uses aggressive nomination)?. Should the
local peer change its sending address?

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Emil Ivov <[email-masked]>
Date: Sun, 3 Aug 2014 00:29:47 +0200

Well, that is exactly the case we set out to resolve for aggressive
nomination before we decided to have ourselves a new version of ICE :-).

If I understand correctly though, with the new ICE version (the one where
regular is the new aggressive) you should be prepared to handle this case
until you get a USE-CANDIDATE. From then on this would be your only pair.

--sent from my mobile
On 03 Aug 2014 12:06 AM, "Iñaki Baz Castillo" <[email-masked]> wrote:

> _______________________________________________
> mmusic mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/mmusic
>

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Sun, 3 Aug 2014 13:21:31 +0200

> until you get a USE-CANDIDATE. From then on this would be your only pair.

Hi, which "new ICE version (the one where regular is the new
aggressive)" do you mean? I'm lost. draft-rfc5245bis does not change
that at all:

http://tools.ietf.org/html/draft-ietf-mmusic-rfc5245bis-02#section-8.1.1

Do I miss something? Sure I do :)

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Emil Ivov <[email-masked]>
Date: Sun, 3 Aug 2014 15:43:20 +0200

The one that's currently being discussed on this list, where there won't be
an explicit aggressive nomination mode and regular nomination would
(really) allow for media to be exchanged before it completes (which it
supposedly does already although it's a bit unclear on the matter)

--sent from my mobile

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Sun, 3 Aug 2014 16:20:38 +0200

2014-08-03 15:43 GMT+02:00 Emil Ivov <[email-masked]>:
> an explicit aggressive nomination mode and regular nomination would (really)
> allow for media to be exchanged before it completes (which it supposedly
> does already although it's a bit unclear on the matter)

OK, got it. Just a comment:

Regardless how the "new ICE" looks, please don't change the rule "just
one DTLS handshake". I say that because in a previous mail it is said
that ICE Binding requests may be encapsulated into DTLS HelloClient
packets, so danger here:

- PeerA is controlling and has two network interfaces.
- PeerB has a single interface.
- PeerA sends two connectivity checks (so DTLS HelloClient + ICE
Binding Request), one from each interface, to the single interface of
PeerB.
- In that case both ICE Requests are different (different
transactionId and so on) so both DTLS HelloClient packets must also be
different, and hence we are talking about *two* separate DTLS
handshakes, which means that PeerB MUST handle two different DTLS
sessions into the same local candidate/interface.

If so, the "just one DTLS handshake" rule and the rationale about "ICE
is a virtual socket" get violated.

Please consider that.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Martin Thomson <[email-masked]>
Date: Sun, 3 Aug 2014 08:02:29 -0700

> sessions into the same local candidate/interface.

I think that you are jumping to conclusions here. What Dan suggested isn't
really part of what Emil is talking about, it is an additional
optimization. As such, it's orthogonal.

If we were to couple DTLS with the connectivity check, it seems like we
would have to require some tweaks to the process in order to avoid the
problem you describe. I think that you have identified a real problem. It
might be that we need to exclude that transaction identifier from the
integrity check to fix that, which is a non-trivial change. The obvious
solution - requiring identical transaction identifiers - removes the
on-push guarantee, at least to the extent that an attacker can modify
signaling and spoof valid source addresses.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Sun, 3 Aug 2014 17:44:58 +0200

2014-08-03 17:02 GMT+02:00 Martin Thomson <[email-masked]>:
> solution - requiring identical transaction identifiers - removes the on-push
> guarantee, at least to the extent that an attacker can modify signaling and
> spoof valid source addresses.

I don't like the idea of including an ICE Binding request into a DTLS
packet. ICE requests are supposed to "open the path" and thus STUN
packets should be the first ones. Instead, DTLS is "application data
to be carried over the open path". We must respect that.

So why not the opposite?: Add the DTLS ClientHello packet into a new
STUN attribute (may be called "DTLS_PACKET"). Issues above solved:

- STUN is processed as normal.

- The *same* DTLS HelloClient can be set into *different* ICE Binding
requests, so there is a single DTLS handshake.

- From the point of view of the sender, it is the same scenario in
which the sender sends a ICE Binding request followed by a DTLS
HelloClient, but with the guarantee that the ICE request will arrive
"first" :)

- From the point of view of the receiver, it first receives (and
validates) the ICE Binding request, then generates the ICE response
and then processes the DTLS HelloClient contained in the "DTLS_PACKET"
attribute of the Binding request. This adds very little complexity to
existing implementations.

Thoughts?

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Sun, 3 Aug 2014 18:22:49 +0200

> existing implementations.

More on this:

- If the receiver supports the "DTLS_PACKET" STUN attribute it will
add the DTLS ServerHello response (along with others) into the
"DTLS_PACKET" of the ICE Binding Response.

- If the ICE response has no "DTLS_PACKET" attribute then the client
must send a "common" DTLS ClientHello.

- DTLS packets to be exchanged after the STUN exchange (regardless
DTLS_PACKET was supported or not) can be directly sent over UDP/TCP.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Justin Uberti <[email-masked]>
Date: Sun, 3 Aug 2014 11:02:05 -0700

On Sun, Aug 3, 2014 at 8:02 AM, Martin Thomson <[email-masked]>
wrote:

> Yes. I think we've lost sight of the original intent of this thread -
either allowing aggressive nomination to make dynamic decisions like
regular nomination, or combining the two concepts entirely.

Let's try to focus on the details of that particular problem in this thread.

---

From: José Luis Millán <[email-masked]>
Date: Mon, 4 Aug 2014 11:36:01 +0200

Hi,

2014-07-31 0:01 GMT+02:00 Martin Thomson <[email-masked]>:
> On 30 July 2014 14:48, Emil Ivov <[email-masked]> wrote:
>> When it's RTP you don't care where you get it from as long as you do. If
>> it's a DTLS client halo then what do you do exactly?
>>
>> Can the controlling agent simply respond on a different valid pair than the
>> one on which it received it? (This is what Chrome currently does but its
>> frowned upon by the DTLS/SRTP draft which binds the context to a specific
>> address:port). Does the controlled agent need to resend it on the new pair
>> after it gets the USE-CANDIDATE?
>
> RFC 5764 says this:
>    A single DTLS-SRTP session only protects data carried over
>    a single UDP source and destination port pair.
>
> But I'll postulate that this is only because the alternative (a
> shifting substrate) was not yet conceived.  There is nothing in (D)TLS
> that requires anything of the underlying transport protocol,
> intentionally.  (c.f., tcpinc wg)
>
> Firefox code seems to be OK (at least superficially) with the idea
> that packets can arrive from anywhere.  However, I can see why some
> implementations might get sad if things shift around.

Do you mean that some implementations might get sad because this is
something they simply do not support today (managing a single DTLS
connection with data coming form different underlying transport
protocols) or that doing it leads to any backward compatibility issue?

-- 
José Luis Millán

---

From: Martin Thomson <[email-masked]>
Date: Mon, 4 Aug 2014 10:58:36 -0700

> protocols) or that doing it leads to any backward compatibility issue?

If a DTLS implementation fixates on a 5-tuple, then that is a problem
if critical packets arrive on other paths, and won't appear on the
fixated path.  That's not something I've seen, but it's a plausible
outcome.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Fri, 8 Aug 2014 12:49:34 +0200

2014-07-31 21:08 GMT+02:00 Justin Uberti <[email-masked]>:
> As discussed earlier, DTLS does not require a separate context for each
> tuple. DTLS should be agnostic about the lower layer protocol (and we should
> probably create an errata to resolve this confusion).

Hi Justin, I agree with that (and I like that), but Chrome does not
behave in that way. My experiment:

- The server gives a UDP and TCP candidate to Chrome.

- Chrome nominates UDP (ICE stuff), sends the DTLS handshake and then media.

- Later the server closes its UDP socket, so STUN requests from Chrome
are not replied.

- At some point Chrome decides to open a TCP connection with the TCP
candidate. It also sends ICE stuff (OK).

- The problem: Chrome *sends* a new DTLS handshake over the new TCP connection.

This is wrong since the server already has a *working* and
*established* DTLS session (which as you say MUST be transport
agnostic), so the new DTLS HelloClient is ignored by the DTLS
machinery at server side and thus, media is never sent.

IMHO Chrome should not attempt a new DTLS handshake given that it was
already done before over the "ICE virtual socket". You opinion please?

BTW: Let me know if you want me to open a bug report, but I would love
having this clear :)

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Kevin Dempsey <[email-masked]>
Date: Fri, 8 Aug 2014 12:21:20 +0100

Does the new TCP connection require an ICE restart? If so, then I think an
new DTLS handshake (and fingerprint check) should be required as the server
may not be connected to the same endpoint anymore.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Fri, 8 Aug 2014 13:29:18 +0200

> may not be connected to the same endpoint anymore.

Why is ICE restart required at all? We are stating that ICE is a
virtual socket regardless how many valid pairs (UDP or TCP) it
handles. The peer can send media (so also DTLS) over any of those
valid pairs at any time without requiring ICE restart (am I wrong?).

My scenario is a good example of how good ICE can be by itself,
without requiring "restart" or a new SDP O/A signaling. Upon TCP
disconnection there is no need to perform a new DTLS handshake since
the "ICE virtual socket" was still open and both Chrome and the server
have already agreed on which layer 4 tuples can be used to carry media
and DTLS stuff is done. Both peers should be able to change the valid
pair at any time without requiring signaling or ICE restart.

NOTE: Issue open in Chrome:
https://code.google.com/p/chromium/issues/detail?id=401923

-- 
Iñaki Baz Castillo
<[email-masked]>