Subject: [BEHAVE] Comments on draft-ietf-behave-turn-05

From: Eric Rescorla <[email-masked]>
Date: Sun, 02 Dec 2007 21:04:44 -0800

$Id: draft-ietf-behave-turn-05-rev.txt,v 1.3 2007/12/03 05:00:28 ekr Exp $

General comments below.

PORT-DEPENDENT FILTERING
As I understand the functionality provided by this draft, it's acting
like an address-restricted NAT. I.e., if I allocate address X:x and
then send a packet to Y:y via this allocation, this creates a
permission for Y:*, so that a packet from Y:z gets forwarded to the
client. Do I have that right?

This is different from what I understand to be the sort of
address/port filtering behavior typically used by address-dependent
filtered NATs and firewalls, namely that the pinhole opened is only
X:x-Y:y, not X:x-Y:*. This is pretty clearly intended as a security
feature (note that I'm not claiming it actually provides security) and
bypassing it unnecessarily [0] seems like a move which is going to
disincentivize TURN deployment. Note that you get this behavior *even
if* you have a good NAT and ICE eventually settles on a non-relayed
path.

I'm assuming that the intent here is to allow TURN clients to easily
talk to nodes behind NATs with address-dependent port mapping.  If so,
I think this is probably misguided. The purpose of TURN is to fix your
own broken NAT, not other people's broken NATs.  One could certainly
argue that fixing other people's NATs is a positive side effect, but I
don't think it is, at least in part since it totally screws up the
incentive model: we want to reward people with good NATs, not force
them to use TURN anyway.

Note that this also means that you can't get early media if ICE
is not being used, but of course that would also be true if you
had a NAT with port-dependent filtering, so I don't think 
that's a disaster.

So, I think it would be best to restrict the permissions being opened
here to just those address/port which the client specifically
addresses. 

COMPLEXITY
If you abandon the notion that you can get datagrams from ports
that you haven't explicitly specified, then it's possible to 
radically simplify the protocol by discarding both Send Indication
and Data Indication. The basic protocol only has three components:

- Allocate     -- as described in S 6
- Bind         -- open a permission for a specific 5-tuple
- Data framing -- as described in S 4

So, the way this would work is as follows:

Client                     Server                     Peer
------                     ------                     ----
ALLOCATE ->
                <- OK(addr = X:x)

BIND(Channel=1, Remote=Y:y) ->
                            <- OK              

                                  <- Message1 (Y:y -> X:x)
     <- DATA(Channel=1, Message1)

DATA(Channel=1,Message2) ->
                           Message2 ->

In the terminology of the current draft, BIND does two things:

1. Opens up a permission for X:x <-> Y:y
2. Assigns a channel # to the permission

We can dispense with Data Indication because no packet can be sent
from the Server to the Client until a permission is opened and the
permission and the channel assignment come together.

We can dispense with Send Indication because it's preceded by a
channel assignment using BIND. The Server can simply discard any
framed messages it receives prior to the receipt of the BIND. Now, one
could argue that if you're using UDP from the Client to the TURN
Server, then the BIND could get lost in which case the data will be
dropped and that this is bad (note that this can't happen with TCP). I
actually think this is just fine--in order for protocols to work well,
the path from the Client to the TURN Server has to be pretty reliable,
and since the Peer can't respond anyway until the BIND is received,
this probably isn't a big deal. However, if this is really a concern
you could keep Send Indication around, but without the channel
establishment side effects.

[0] Yes, I appreciate that the general function of TURN is to bypass
middlebox policies, but that seems like something to minimize.

-Ekr

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

---

From: Marc Petit-Huguenin <[email-masked]>
Date: Mon, 03 Dec 2007 13:32:58 -0800

Hi Eric,

> here to just those address/port which the client specifically

I think that you are assuming that TURN is used only with ICE, i.e. for
the purpose of carrying RTP streams.  But the first section of TURN-05
states that "TURN is designed to be a general-purpose relay mechanism
for NAT traversal."

One of my test client for TURN-05 is a TFTP client, because TFTP does
not work behind a Port Dependent Filtering NAT.  If the permissions are
restricted to address/port, then a TURN-ified TFTP client will no longer
work.

In fact I would advocate the exact opposite - having a configuration
option in the Allocate to choose if permissions are disabled, address
only or address/port.

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

---

From: <[email-masked]>
Date: Mon, 3 Dec 2007 23:59:43 +0200

I'll second Marc's proposal. Hopefully we can agree on this change in
tomorrow's session.

Of course, now there remains the second problem with TURN which is
probably a bit harder solve. I.e. how to make TURN to support e2e
TLS/DTLS security association between TURN client and peer. 

/Mikael 

>-----Original Message-----
>From: ext Marc Petit-Huguenin [mailto:[email-masked]] 
>Sent: 03.12.2007 23:33
>To: Eric Rescorla
>Cc: [email-masked]
>Subject: Re: [BEHAVE] Comments on draft-ietf-behave-turn-05
>
>Hi Eric,
>
>Eric Rescorla wrote:
>> Note that this also means that you can't get early media if 
>ICE is not 
>> being used, but of course that would also be true if you had a NAT 
>> with port-dependent filtering, so I don't think that's a disaster.
>> 
>I think that you are assuming that TURN is used only with ICE, 
>i.e. for the purpose of carrying RTP streams.  But the first 
>section of TURN-05 states that "TURN is designed to be a 
>general-purpose relay mechanism for NAT traversal."
>
>One of my test client for TURN-05 is a TFTP client, because 
>TFTP does not work behind a Port Dependent Filtering NAT.  If 
>the permissions are restricted to address/port, then a 
>TURN-ified TFTP client will no longer work.
>
>In fact I would advocate the exact opposite - having a 
>configuration option in the Allocate to choose if permissions 
>are disabled, address only or address/port.
>
>> 
>> 
>> COMPLEXITY
>> If you abandon the notion that you can get datagrams from ports that 
>> you haven't explicitly specified, then it's possible to radically 
>> simplify the protocol by discarding both Send Indication and Data 
>> Indication. The basic protocol only has three components:
>> 
>> 1. Opens up a permission for X:x <-> Y:y 2. Assigns a 
>channel # to the 
>> permission
>>

---

From: Rémi Denis-Courmont <[email-masked]>
Date: Tue, 4 Dec 2007 00:07:53 +0200

Le Monday 03 December 2007 23:59:43 ext [email-masked], vous avez 
> TLS/DTLS security association between TURN client and peer.

There is no such issue. TURN is application-layer protocol-agnostic; you can 
run TLS on top of a TURN-relayed TCP session, as you can run DTLS on top of a 
TURN-relayed UDP session.

-- 
Rémi Denis-Courmont

---

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

Eric,

Interesting suggestion. I agree that what you propose would simplify the 
draft further, which is a good thing. But I disagree with your 
assessment that this behavior is odd. RFC 4787 on NAT UDP behavior 
requirements says:

   REQ-8:  If application transparency is most important, it is
       RECOMMENDED that a NAT have an "Endpoint-Independent Filtering"
       behavior.  If a more stringent filtering behavior is most
       important, it is RECOMMENDED that a NAT have an "Address-Dependent
       Filtering" behavior.

AFAIK, this group found no additional security benefits from address and 
port dependent filtering.

You are correct in your assessment that the current behavior is requied 
for TURN to work without TWO relays when the other side is behind 
address-depenent. This isn't a corner case; I think we expect this to be 
a common configuration.

It also allows a single TURN server to be used when the other side is 
behind an address or address-and-port dependent mapping NAT, but its a 
residential nat with a single IP. This is a good case to support.

So, I am opposed to making this change in TURN.

-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

---

From: "Derek MacDonald" <[email-masked]>
Date: Mon, 3 Dec 2007 14:24:00 -0800

I second Jonathan on this.  In a lot of cases both parties will be using the
same SP and will consequently suffer the pain of both relays, and might not
have any control over what NATs their customers buy.

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 03 Dec 2007 14:38:24 -0800

At Mon, 03 Dec 2007 17:10:16 -0500,
> port dependent filtering.

Well, as I said in my message, I'm not claiming that there are
additional security benefits to having port-dependent filtering.
I'm observing that it's a fairly common policy, especially for
firewalls, and that bypassing that acts as a disincentive for
people who have such firewalls to deploy.

> residential nat with a single IP. This is a good case to support.

Well, this is what I'm arguing gets the incentive match wrong.

> So, I am opposed to making this change in TURN.

I'd observe that one can still significantly simplify TURN even
if one wants to preserve this behavior. The change is to preserve
Data Indication but remove Send Indication. Channel assignment 
is done via Bind, as described in my original message.

-Ekr

---

From: Philip Matthews <[email-masked]>
Date: Mon, 3 Dec 2007 19:18:41 -0800

> is done via Bind, as described in my original message.

If I understand the proposal, then I think there is a problem.
What if the client has lots of data to send, but has not yet received
the Bind Response from the server? What does it do?

Consider the following example

C                                             T
|------ Bind (channel=1, remote=Y:y)----> X   |  (lost!)
|-------[1] Data packet #1 ------------------>|  (dropped)
|-------[1] Data packet #2 ------------------>|  (dropped)
|-------[1] Data packet #3 ------------------>|  (dropped)
|-------[1] Data packet #4 ------------------>|  (dropped)
|------ Bind (channel=1, remote=Y:y) -------->|  (resend)
|<----------- Bind Response (OK)--------------|
Here the server drops all the data flowing on channel [1]
until the client times out and retransmits the Bind Request.

By contrast, the proposal in the document works as follows
C                                                        T
|---Send (channel=1, remote=Y:y, data=packet#1)----> X  |  (lost!)
|---Send (channel=1, remote=Y:y, data=packet#2)------>  |  (accepted)
|---Send (channel=1, remote=Y:y, data=packet#3)------>  |  (accepted)
|<------------ ChannelConf (channel=1) ---------------  |  (confirm)
|---[1] packet#4 ----------------------------------->   |  (accepted)

With the existing proposal, the client can send multiple Send  
Indications
containing the the remote destination and the corresponding channel
number, until it receives a ChannelConfirmation Indication.

The design group considered this idea back in September,
but opted for the design currently in the document
for the above reason.

- Philip

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 03 Dec 2007 19:28:03 -0800

At Mon, 3 Dec 2007 19:18:41 -0800,
> the Bind Response from the server? What does it do?

It keeps transmitting and potentially escalates the retransmit
of the Bind.

> until the client times out and retransmits the Bind Request.

Yes, as I said in my message:

   Now, one could argue that if you're using UDP from the Client to
   the TURN Server, then the BIND could get lost in which case the
   data will be dropped and that this is bad (note that this can't
   happen with TCP). I actually think this is just fine--in order for
   protocols to work well, the path from the Client to the TURN Server
   has to be pretty reliable, and since the Peer can't respond anyway
   until the BIND is received, this probably isn't a big
   deal. However, if this is really a concern you could keep Send
   Indication around, but without the channel establishment side
   effects.

I can think of another approach too: do "fast retransmit" of the Bind,
e.g., clocked at one every X data packets. Remember that if there's
any significant packet loss, then you have a serious problem, so you
don't need to see the ACK to do anything, just have high confidence
that the Bind will get through. Moreover, if you have high packet
loss for the Bind, then it's pretty hard to complain about loss
in the data stream.

> but opted for the design currently in the document

Right. As I said above, I don't consider this advantage enough
to justify the added complexity--in particularly the overloading
of the SendIndication to both carry data and do the channel
assignment. If it's really considered a showstopper to lose
*any* data packets due to a loss of the Bind, then I think the
protocol would be removed by separating Send Indication and
Bind functionality.

-Ekr

---

From: Rohan Mahy <[email-masked]>
Date: Mon, 3 Dec 2007 20:00:50 -0800

On Dec 3, 2007, at 7:28 PM, Eric Rescorla wrote:
>    happen with TCP).

Note that with TCP, no Channel Confirmation Indication is needed either.

> I actually think this is just fine--in order for
>    deal.

If there is 100ms of RTT time between the client and the TURN server  
and I need to send lots of packets to send the initial frame.  Lets  
say I need to send 30 packets in a burst before I receive could  
possibly receive a response.  That's 30 STUN transactions and several  
of their retransmits before I can send unencapsulated.

> However, if this is really a concern you could keep Send
> e.g., clocked at one every X data packets.

I don't think hammering the network with retransmissions of little  
value until you have a good idea of RTT is going to improve the  
likelihood that your traffic is going to arrive. Note that the *DATA*  
doesn't need to be retransmitted, just the channel binding.

> Remember that if there's

The problem I described has no packet loss

thanks,
-rohan

---

From: Eric Rescorla <[email-masked]>
Date: Mon, 03 Dec 2007 22:25:34 -0800

At Mon, 3 Dec 2007 20:00:50 -0800,
> Note that with TCP, no Channel Confirmation Indication is needed either.

Yes, but I'm not complaining about the channel confirmation as
a form of chattiness but as a form of unclean protocol semantics.
That's why I said that you should have a separate Bind even if
you wanted to retain both Send and Data Indications.

> of their retransmits before I can send unencapsulated.

I'm unable to map what you're saying onto the mechanism I was
describing, since I'm not proposing that you initiate a 
STUN request for each data packet you want to send. Rather,
once you've sent a Bind, you simply use the channel you
advertised and start sending packets with that channel
immediately. In zero packet loss situations, this simply
works. If there is packet loss and you're unlucky enough
to lose the Bind, then the data packets get dropped until
the retransmit of the Bind, hence the faster retransmit
algorithm I suggested below.

> likelihood that your traffic is going to arrive.

I didn't suggest "hammering" it. I suggested sending retransmits
of the Bind at some fraction of the data rate. I don't have 
numbers on hand, but I would think 1/10-1/5 would be appropriate
given reasonable assumptions about packet loss/reordering.

> Note that the *DATA*  

Nor did I suggest retransmitting the data, just the Bind request.

> The problem I described has no packet loss

Then I apparently don't understand the problem you're describing.
Please explain the sequence of events you're talking about
in more detail.

-Ekr

---

From: Rohan Mahy <[email-masked]>
Date: Tue, 4 Dec 2007 08:16:58 -0800

Hi,

Modifying the retransmission rules of STUN in TURN does not seem like  
a big win.  For one thing, this kind of rules change would make it  
more difficult to use/build an off-the-shelf STUN library.

This seems like a pretty egregious change just to placate a  
philosophical/religious argument: "a form of unclean protocol  
semantics".

Can you provide some concrete thing on the wire that actually does  
not work with the proposed mechanism in the draft?

thanks,
-rohan

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 04 Dec 2007 08:41:26 -0800

At Tue, 4 Dec 2007 08:16:58 -0800,
> more difficult to use/build an off-the-shelf STUN library.

Well, I'm pretty familiar with STUN libraries and I don't think
it would make it particularly hard. [0] In particular, I would note
that STUN libraries MUST allow cancellation of transactions
in order to support ICE, and also probably has to support
retransmission limits, and so this functionality can 
be supported by cancelling the STUN transaction and starting
a new one.

> philosophical/religious argument: "a form of unclean protocol  

Once again, as I noted, it's worth adding Bind *even* if you
retain Data and Send Indications.

> not work with the proposed mechanism in the draft?

That's the standard I would apply to whether I want to fix a
finished, deployed protocol, not to whether to consider 
architectural cleanliness in a new protocol design.

-Ekr

[0] And of course, one might ask why it's a fixed point that
TURN needs to use STUN.

---

From: Rohan Mahy <[email-masked]>
Date: Tue, 4 Dec 2007 09:56:44 -0800

Eric,

I think modifying the retransmission timers on a *per-request* basis  
is architecturally unclean.  I have provided some concrete reasons  
why.  You provided no algorithm or basis in theory for deciding how  
quickly to do a fast retransmit.  If you retransmit too fast, you are  
sending useless data, if you retransmit too slowly, the receiver has  
to throw away data that it did not have to throw away in the proposal  
in the draft.  Using the mechanism in the draft, all data that  
arrives can be used.

Your proposal works less well than the one in the draft. Therefore I  
expect you to explain concretely what is so bad about the proposal in  
the draft, other than asserting that it is "unclean".

thanks,
-rohan

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 04 Dec 2007 10:32:38 -0800

At Tue, 4 Dec 2007 09:56:44 -0800,
> the draft, other than asserting that it is "unclean".

For the third time now, there are two separate issues:

1. Whether the Send Indication should as a side effect establish
   the channel.

2. Whether there should be a Send Indication to allow data to be
   transmitted prior to the establishment of a channel.

I think that using Send Indication having as a side effect establishing
the channel is pretty clearly architecturally unclean. There should
be a separate Bind. Having a separate Bind *with a Send Indication*
has exactly the same packet loss characteristics as the current
design. 

This brings us to the second issue, namely, once there is a distinct
Bind command, should there be a Send Indication at all. As I observed
in my review, I think this is of fairly marginal value. If there
is significant packet loss on the route to the TURN server, then
the system isn't really going to work at all, and so the risk of
losing media packets during the retransmit interval *if* the 
Bind is lost. I could be wrong about this, of course, but I'd
be interested to understand what you think the network flow model
it is that makes this feature important.

-Ekr

---

From: Rohan Mahy <[email-masked]>
Date: Tue, 4 Dec 2007 11:41:48 -0800

Eric,

You have not addressed any of my questions.  How do you pick the  
value of the retransmit timer?  Without a good basis for the timer,  
the behavior under your proposal would be brittle.

More comments inline.

> be a separate Bind.

What bad thing happens if we perform these two operations (sending  
data and establishing a channel) in one message?  My analysis is that  
nothing bad happens.

All other things being equal (if you had a proposal which worked as  
well), I would be inclined to agree with you. However, in the absence  
of such a proposal, your comment is pretty academic and not a  
compelling reason to change the document.

> Having a separate Bind *with a Send Indication*

Please reread my previous mail and envision the case of the TURN  
client sending video to a non-ICE peer. Assume that the first packet  
containing a Bind is dropped.

These don't have the same properties.

> in my review, I think this is of fairly marginal value.

The WG strongly disagrees with you, and has on multiple occasions  
confirmed that decision.

> If there

The network flow model is making the TURN server look similar from a  
traffic delivery perspective to a NAT.  Preventing a traffic from  
being delivered until a binding is established is a significant  
divergence from that fundamental principle.

thanks,
-rohan

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 04 Dec 2007 13:51:58 -0800

At Tue, 4 Dec 2007 11:41:48 -0800,
Rohan Mahy wrote:
> You have not addressed any of my questions.

Well, I've been trying to, but it seems that we're talking past each
other.

>  How do you pick the  
> value of the retransmit timer? 

I was suggesting basing it on the packet rate. I.e., every X packets
you would abort the current STUN transaction (if any) and start a new
one. Picking X would require some analysis of the maximum number of
packets you were willing to lose compared to the probability of packet
loss (see below for a very cursory analysis.)

> compelling reason to change the document.

Actually, I think at least one of the variants I proposed *does*
work as well.

> These don't have the same properties.

Well, as I've been trying to explain, I suggested two separate
things.

For clarity, here's what I was proposing under (1).

1. The client sends data under Data Indications.
2. The server sends data under Send Indications.
3. At any time, the client can issue a Bind which requests that
   a given 5-tuple be a given channel.
4. On receipt of the Bind, the server can send unencapsulated.
5. On receipt of the OK from the Bind, the client can send
   unencapsulated.

I.e.,

Client                                      Server
------                                      ------
ALLOCATE ->
                                             <- OK
                                <- Data Indication
Send Indication ->
Bind ->
                            <- Unencapsulated Data
                                             <- OK
Unencapsulated Data ->

Do you agree that this has the same properties as
the current draft? If not, can you please explain why in 
detail?

Why do I think this is an improvement? Because it has explicit
semantics for the transition between encapsulated an unencapsulated
mode, which is architecturally cleaner. It also has the nice side
effect that each 5-tuple only corresponds to one channel, but this
is a minor convenience for implementors.

Now, let's turn to my point (2) from my previous message, which
suggested the same scheme as I just described with the removal of
point (1). I.e., you would need to Bind before sending unencapsulated
data.

Yes, it's absolutely true that if you remove Data indication *and* the
Bind is lost, some packets will be lost. It's quite straightforward to
minimize this loss by adapting the rate at which you send Binds to
match the rate at which you send packets. I.e., if you send Binds
every R frames and your overall packet loss probability is L, then the
mean number of lost packets is given by:
   
   inf
   ----
   \          i
    >    R * L  
   /
   ----
  i = 1

Using standard formulas, this sum gives R/(1-L). 

So, if, for instance, you have a packet loss rate of .1 (which is
fairly severe) and you're willing to transmit a Bind for every 10
packets (10% overhead) then you will on average lose one packet, which
seems pretty modest, especially when you consider that you will on
average lose 10% of the data packets during the entire life of
the connection.

> The WG strongly disagrees with you, and has on multiple occasions  

Hmm... I don't recall these, but if you can point me to some of those
occasions, I'll be happy to review the discussion.

Best,
-Ekr

---

From: Rohan Mahy <[email-masked]>
Date: Tue, 4 Dec 2007 14:16:56 -0800

Hi Eric,

I now realize that you intend the binding to be bidirectional.  
Currently the channel numbers are asymmetric. The reason is that the  
UAC can Sent to and create a binding for one target IP address and  
port, which creates a permission for the entire target IP address,  
and then receive data from a different port number (or numbers) than  
expected.  The UAC needs to detect this and use different channel  
numbers for these.

JDR has slide on this today.

thanks,
-rohan

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 04 Dec 2007 14:14:52 -0800

At Tue, 4 Dec 2007 14:16:56 -0800,
> JDR has slide on this today.

Ah. Well, now I see why were talking past each other. Thanks
for the clarification. That said, I think that what I suggested
would, with the appropriate rules, work in that situation,
but I'll be happy to explain that when JDR shows his slides.

-Ekr