Subject: [BEHAVE] Alternative channel binding mechanism for TURN

From: Jonathan Rosenberg <[email-masked]>
Date: Fri, 07 Dec 2007 14:02:47 -0500

Several folks met last night at the TURN ad-hoc to discuss the various 
open issues. One of the biggest was whether we should change the channel 
binding mechanism from what is in the document (using Send along with a 
confirmation indication) to what ekr suggested. We wrote down what that 
alternate flow would look like and came up with pros and cons. Here is 
what we came up with.

The mechanism that ekr is proposing basically looks like this:

        Client         TURN Server         Peer             Peer2
           |                |                |                |
           |                |                |                |
           |                |                |                |
           |(1) [0]Allocate |                |                |
           |--------------->|                |                |
           |                |                |                |
           |                |                |                |
           |(2) [0]AllocOK  |                |                |
           |<---------------|                |                |
           |                |                |                |
           |                |                |                |
           |Data to send    |                |                |
           |                |                |                |
           |                |                |                |
           |                |                |                |
           |(3) [0]ChannelBind(7)            |                |
           |--------------->|                |                |
           |                |                |                |
           |                |                |                |
           |(4) [0]Send     |                |                |
           |--------------->|                |                |
           |                |                |                |
           |                |                |                |
           |                |(5) UDP Packet  |                |
           |                |--------------->|                |
           |                |                |                |
           |                |                |                |
           |(6) [0]BindOK   |                |                |
           |<---------------|                |                |
           |                |                |                |
           |                |                |                |
           |(7) [7]UDP Packet                |                |
           |--------------->|                |                |
           |                |                |                |
           |                |                |                |
           |                |(8) UDP Packet  |                |
           |                |--------------->|                |
           |                |                |                |
           |                |                |                |
           |                |(9) UDP Packet  |                |
           |                |<---------------|                |
           |                |                |                |
           |                |                |                |
           |(10) [7]UDP Packet               |                |
           |<---------------|                |                |
           |                |                |                |
           |                |                |                |
           |                |(11) UDP Packet |                |
           |                |<--------------------------------|
           |                |                |                |
           |                |                |                |
           |                |Permission Open |                |
           |                |                |                |
           |                |                |                |
           |                |                |                |
           |(12) [0]Data Ind.                |                |
           |<---------------|                |                |
           |                |                |                |
           |                |                |                |
           |(13) [0]ChannelBind(8)           |                |
           |--------------->|                |                |
           |                |                |                |
           |                |                |                |
           |(14) [0]BindOK  |                |                |
           |<---------------|                |                |
           |                |                |                |
           |                |                |                |
           |                |(15) UDP Packet |                |
           |                |<--------------------------------|
           |                |                |                |
           |                |                |                |
           |(16) [8]UDP Packet               |                |
           |<---------------|                |                |
           |                |                |                |
           |                |                |                |
           |                |                |                |
           |                |                |                |

In terms of notation, the square brackets in front of a TURN message 
indicate what channel that message is on.

The client does the Allocate as currently defined (messages 1,2). 
Shortly thereafter, the client has data to send. It knows that it will 
have a bunch of data, so it would like to create a channel for 
communications with the specific peer. One of the benefits of this 
proposed flow (noted further below), is that by separating data 
transmission from channel binding, we can make channel binding something 
a client can do at its discretion. In this case, it wants to bind a 
channel for this particular peer.

So, it sends a ChannelBind transaction, on the turn channel (channel 0). 
The client requests channel 7 for communications to and from the peer. 
At this point, the client is prepared to receive data on channel 7. In 
ekr's proposed flow, there is a single channel number for traffic both 
to and from a particular peer. When the server receives the ChannelBind, 
it creates channel 7 and maps it to the peer. From this point forward, 
the server will relay traffic from that peer, towards the client, over 
channel 7. Furthermore, it will accept traffic from the client, on 
channel 7, and forward to the peer. Note that, even though the client 
has not received the response to the ChannelBind request, the server is 
guaranteed that the client is prepared to receive data on channel 7.

However, the client doesn't want to wait for the ChannelBind response to 
send the data. Until it gets that response, it cannot send data over 
that channel. So, until then, it sends data encapsulated using the Send 
indication (message 4). When the server receives this, it relays the 
data to the peer (message 5) and opens a permission to the corresponding 
IP address (the folks in the room last night were unsure if ChannelBind 
also creates a permission, with opinion slightly in favor of no).

Now, at some point the ChannelBind response is received by the client 
(message 6). After that point, the client can now send data to this peer 
unencapsulated, on the bound channel. So, it uses channel 7 (message 7) 
and the TURN server relays data to the peer (message 8).

Now, the peer sends data towards the TURN server (message 9). In this 
particular case, a channel has already been bound to this peer on the 
TURN server. So, the TURN server sends the data to the client on the 
existing channel (message 10). Another peer (for example), with the same 
IP address but from a different port, now sends data to the TURN server 
(message 11). Since a permission is open for this IP address, the TURN 
server will relay the data to the client. However, there is no channel 
bound for this peer. As a consequence, the server encapsulates the data 
in a Data indication (message 12). Note that, the server itself does NOT 
try to bind a channel. Only the client can do that.

Instead, the client, upon receiving the data, decides it would like a 
channel for this second peer. So, it sends a ChannelBind (message 13) 
for this new peer. This is received by the TURN server and it binds 
channel 8 to this peer, and sends the response (message 14). Now, when 
the next datagram arrives from this new peer (message 15), it is sent to 
the client unencapsulated on channel 8 (message 16).

In comparing this technique (Ekrs Technique) with the one in 
draft-ietf-behave-turn-05 (Current Technique), we came up with the 
following pros and cons:

Ekrs Technique
--------------

PRO: Allows the client to decide, on a case by case basis, whether to 
pay the overhead (ChannelBind transaction) to bind a channel to a peer. 
For example, in ICE exchanges, the client could skip channel binding for 
the connectivity checks, and only do the binding if ICE selects the peer 
  transport address.

PRO: Related to the previous point, the current channel binding 
mechanism does not allow a client to remove or delete a channel binding. 
Thus, for an allocation which is very long lived, the client could 
eventually run out of channels and need to re-allocate to clear them all 
or get more channels. Since Ekrs Technique allows the client to 
selectively channel bind, when used with protocols like ICE where it is 
not needed to channel bind for all peers, the allocation will 'last 
longer' - that is, channel numbers get exhausted more slowly. 
Architecturally, this is because Ekrs Technique separates channel 
binding and data transmission, whereas the Current Technique combines them.

CON: Under packet loss, it is possible that the ChannelBind request 
could be lost. If so, it will be retransmitted an RTO later. This means 
that, the amount of time between request and response is equal to RTT + 
2^N * RTO, where N is the number of packet losses. The client cannot 
send unencapsulated data until the ChannelBind response is received. 
This duration is therefore equal to RTT+ 2^N*RTO, which is longer than 
the Current Technique. There was split opinions on whether this was a 
big deal or not, but it is a CON.

PRO: Seems simpler to have a single channel number for messages in both 
directions

PRO: If a channel binding is in place for a peer, the first data from 
that peer can be sent immediatley unencapsulated. With the Current 
Technique, since channel numbers are always different in each direction, 
the first packet (and indeed, the first RTT set of packets after the 
first) will be sent encapsulated.

PRO: there is a documented security concern with the Current Technique 
in TURN-5. Since ChannelConfirm is an indication, it is unauthenticated. 
An attacker could, upon seeing a Send indication from a client, send a 
faked ChannelConfirm indication, and then cause the Send request to be 
discarded. As a consequence, the client will believe the channel is 
bound, when it is not. The client will, for the remaining duration of 
the allocation, send data on that channel, and it will be discarded by 
the TURN server. The client will not know that this happened. With Ekrs 
Technique, this attack is mitigated.

PRO: Does not require the client to receive requests and send responses. 
There has been some debate on whether this is important. Note that this 
PRO is shared by both techniques.

PRO: A client could, as a matter of local implementation choice, elect 
to not implement or use Send. Instead, it can wait for channels to be 
bound and send data unencapsulated. This does mean that clients would 
either drop data to be send prior to receiving the ChannelBind response, 
else delay sending to that time.

Current Technique
-----------------

CON: Each Send indication (and Data indication) causes a ChannelConfirm 
indication. If the client is sending a lot of data, say, at rate R, this 
will cause R*RTT number of ChannelConfirm messages to be sent. In 
essence, the server 'spams' the client will redundant ChannelConfirm 
messages, even when there was no packet loss.

PRO: The amount of time until a client can sent unencapsulated data is 
equal to RTT + T*N, where N is the number of packet losses and T is the 
inter-arrival time between data from client to the peer. This number 
will typically be lower than Ekrs Technique under conditions of packet 
loss. Note that they are identical in conditions of no packet loss.

PRO: In the case of TCP between client and server, the server can omit 
sending ChannelConfirm and the client can send data unencapsulated 
immediately. With Ekrs technique, the client can also send data 
unencapsulated immediately, but since ChannelBind is a transaction, a 
response is still required.

PRO: Does not require the client to receive requests and send responses. 
There has been some debate on whether this is important. Note that this 
PRO is shared by both techniques.

Of the folks present, most (including myself) were in favor of Ekrs 
Technique. Consequently, we'd like to confirm this decision, and see if 
there is rough consensus to go with Ekrs technique.

Thanks,
Jonathan R.
-- 
Jonathan D. Rosenberg, Ph.D.                   499 Thornall St.
Cisco Fellow                                   Edison, NJ 08837
Cisco, Voice Technology Group
[email-masked]
http://www.jdrosen.net                         PHONE: (408) 902-3084
http://www.cisco.com

_______________________________________________
Behave mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/behave

---

From: Marc Petit-Huguenin <[email-masked]>
Date: Fri, 07 Dec 2007 12:57:26 -0800

> alternate flow would look like and came up with pros and cons. Here is

I am in favor of the new technique, mostly because of the security issue
it fixes.

This said changing basic stuff like this each 4 months is way past
annoying.  Couldn't EKR be part of the design team?

The first version of TURN was released November 14, 2001.  6 years after
I still have nothing to deploy.

-- 
Marc Petit-Huguenin           [                                 ]
Home: [email-masked] [RFC1855-compliant space for rent ]
Work: [email-masked]            [                                 ]
[                                                               ]

---

From: Jonathan Rosenberg <[email-masked]>
Date: Mon, 10 Dec 2007 10:03:02 -0500

Marc,

I appreciate and share your frustration here. There are many factors 
that have contributed to the overly long lifetime on this draft (over 6 
years as you say), including lack of a working group for a long time. 
Frankly, up until this point, it has never had the deep scrutiny it is 
now getting to turn it into a solid protocol (no pun intended). I and 
the rest of the design team and really committed to getting this DONE 
and not having another IETF discussion on it like the one we just had.

Thanks for your patience and support,
Jonathan R.

---

From: "Derek MacDonald" <[email-masked]>
Date: Mon, 10 Dec 2007 19:35:15 -0800

I am in favour of the new technique because it avoids the following
issues(as well as the benefits described by Jonathan)

* the packet rate is not double the media rate while the channel is
established.  This would only likely be an issue when a call forks to many
endpoints, but might be more of an issue in a future application of turn.
* With turn-05, there is a very weird edge case that could technically
occur.  If the server or the client runs out of channel numbers the
allocation should be restarted.  With turn-05, the client and the server
must keep track of both client and server channel #'s, as this will not
necessarily be symmetric.  It will *likely* be, but it isn't guaranteed.
Unfortunately, if the server runs out(or is low) of channels, there is no
way to signal to the client that an new allocation needs to be created.

In any case, suspect most client implementations would not track server
channel #s...so if we can avoid it, we should.  Another issue in turn-05 is
tat there is no recovery mechanism for when an allocation runs out of
channels in either mechanism.  With ekr's mechanism, we can fall back to
allocated data with a little more overhead and no loss of function.

That said, there are a couple of edge cases we need to consider if we use
the new mechanism, due to the lack of a 3-way handshake in the ChannelBind
transaction.

1. should we treat encapsulated data as an imlicit ACK of the relevant
ChannelBind?
2. what should the client behavior be when the ChannelBind fails?

Personally, I think #1 is fine, but it should be an optional optimization
for the client. The server has no way of knowing if a BindOK response was
received by the client.

For, #2 I want to define ChannelBind failure as:  the client did not receive
a ChannelBind response or(optionally) encapsulated data on the channel

At the ad-hoc, we thought that the client should treat the allocation as
dead.  Dead is not particlarily well defined in this context, specifically:
should the client assume that data sent on other channels is not being
delivered?

This could get quite complicated, so I propose the following client behavior
in this case:

   If a ChannelBind transaction fails, the turn client should invalidate the
allocation and apply the same application logic that would be used when a
NAT reboot/rebind is detected.

This maps back to the general architectural scope of turn as a NAT upgrade
rather than a NAT replacement.

-Derek

---

From: Jonathan Rosenberg <[email-masked]>
Date: Wed, 12 Dec 2007 23:18:45 -0500

Derek,

Great point on the client not knowing when the server ran out of 
channels. I had not considered this, and it is another benefit of Ekrs 
proposal.

To address your points below, I don't believe we should say anything 
about treating encapsulated data as an indication of receipt of 
ChannelBind. If an implementation wants to do this on its own thats 
fine, but I don't want to put anything in the protocol around it.

In terms of, what happens if the CHannelBind times out, this is a more 
general issue. What happens if Refresh times out? Same problem. I think 
we need to add text, as you describe, that says in all such cases the 
client considers the allocation invalidated, and it has to grab a new one.

-Jonathan R.

Derek MacDonald wrote:
> established.  This would only likely be an issue when a call forks to 
> many endpoints, but might be more of an issue in a future application of 
> turn.
> necessarily be symmetric.  It will *likely* be, but it isn't 
> guaranteed.  Unfortunately, if the server runs out(or is low) of 
> channels, there is no way to signal to the client that an new allocation 
> needs to be created.
> 
> channel #s...so if we can avoid it, we should.  Another issue in turn-05 
> is tat there is no recovery mechanism for when an allocation runs out of 
> That said, there are a couple of edge cases we need to consider if we 
> use the new mechanism, due to the lack of a 3-way handshake in the 
> ChannelBind transaction.
> 
> Personally, I think #1 is fine, but it should be an optional 
> optimization for the client. The server has no way of knowing if a 
> BindOK response was received by the client.
> 
> For, #2 I want to define ChannelBind failure as:  the client did not 
> receive a ChannelBind response or(optionally) encapsulated data on the 
> channel
> 
> dead.  Dead is not particlarily well defined in this context, 
> specifically:  should the client assume that data sent on other channels 
> is not being delivered?
> 
> This could get quite complicated, so I propose the following client 
> behavior in this case:
> 
>    If a ChannelBind transaction fails, the turn client should invalidate 
> the allocation and apply the same application logic that would be used 
> when a NAT reboot/rebind is detected.
> 
> This maps back to the general architectural scope of turn as a NAT 
> upgrade rather than a NAT replacement.
> 
> -Derek
> 
> On Dec 7, 2007 11:02 AM, Jonathan Rosenberg < [email-masked] 
> <mailto:[email-masked]>> wrote:
> 
>     [email-masked] <mailto:[email-masked]>
>     http://www.jdrosen.net <http://www.jdrosen.net>                    
>         PHONE: (408) 902-3084
>     http://www.cisco.com
> 
> 
>     [email-masked] <mailto:[email-masked]>