Subject: Re: [BEHAVE] TURN: technical review by September 1

From: "Bruce Lowekamp" <[email-masked]>
Date: Wed, 1 Aug 2007 16:18:13 -0400

On 7/31/07, Rémi Denis-Courmont <[email-masked]> wrote:
> At this point, the server really can only do one of three things:
> (1) queue an indefinitely big amount of data,
> (2) stop dequeing data from the TURN client until TCP_B gets "decongested",
> (3) drop data for B, and reset/timeout connection with B.

> (2) is flawed, as communication between client and peer A will be unduly
> disrupted. It is an obvious security issue if A and B do not trust each
> others. Even then, it is probably unacceptable: if say, B looses connectivity
> for some reason, the flow to A will be totally disrupted until TCP_B
> connection times out. There are similar problem if connectivity to B is much
> slower or less reliable than that to A.

I think that 2 is the only possible "correct" behavior, because 1 is
unimplementable and 3 breaks the basic TCP model merely because one
destination has lower throughput than another.  2's problem is that it
restricts both connections to the poorer of the pair (whether
deliberate attack or poor provisioning), but at least they both behave
like valid TCP connections.

There's another possibility of making the protocol more complex by
signalling queueing on the client connection, but I really don't think
we want that.

But unless there's a compelling reason to support it, I think it would
be better if TURN just says one peer per client connection.  I'm not
aware of a compelling reason.  If there is a compelling reason to
support it, I think big red flags and possibly even SHOULD NOT
language should be used to discourage its use except when necessary.

Bruce

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

---

From: <[email-masked]>
Date: Mon, 6 Aug 2007 12:32:06 +0300

>-----Original Message-----
>From: ext Dan Wing [mailto:[email-masked]] 
>Sent: 30 July, 2007 20:27
>To: [email-masked]
>Cc: 'Rohan Mahy'; [email-masked]
>Subject: [BEHAVE] TURN: technical review by September 1
>
>In Chicago at IETF-69 we explained the urgency around 
>rfc3489bis ("STUNbis") and TURN.  ICE needs to be published at 
>the same time as rfc3489bis and TURN because ICE normatively 
>references those documents.  Rfc3489bis underwent substantial 
>revision between -06 and -08, and I just WGLC'd rfc3489bis-08 
>a few minutes ago.  However, TURN is not yet ready to be WGLC'd.

Frankly, I do not understand why ICE normatively depends on TURN.
I could use SOCKS, UPnP, NAT-PMP, you-name-it... to generate
my candidates, yet ICE does not depend on these.

Of course, STUNbis is a dependency due to embracing and extending
the STUN messages format. But TURN... ??? In fact, while I understand
it might be late to "fix" this, I do not understand why ICE
specifically mention TURN all over the place in the details, while it
mentions tons of other potential non-normative ways to obtain
candidates in its introduction, but this is a minor almost-editorial
issue. So why is TURN not an informative reference?

However... I am sorry to say that, but I think it would be wrong to
Declare TURN "ready" before we´ve had the chance to examine its
Interactions with ICE-TCP, and that´s not something I can put within
5 weeks (counting from the end of last IETF). I mean, ICE-TCP is no
easy task in itself, and it would clearly be a pita when TURN turns
out to work fine with UDP and be broken with TCP (I would really like
we do not reproduce the mistakes from MSRP this time).

An alternative is to split TURN into UDP/UDP, first and the other
combinations separately, but I would not like this at all if I were
one of the editor. That´s what´s been done with ICE though, and I
expect that´s what implementors do - Does anyone know of a ICE-TCP
stack out yet at all?

Regards,

-- 
Rémi Denis-Courmont
Software Engineer
Nokia TP/SP, Helsinki

---

From: <[email-masked]>
Date: Mon, 6 Aug 2007 12:54:18 +0300

>From: [email-masked] [mailto:[email-masked]]
>
>> (2) is flawed, as communication between client and peer A will be 
>> unduly disrupted. It is an obvious security issue if A and B do not 
>> trust each others. Even then, it is probably unacceptable: if say, B 
>> looses connectivity for some reason, the flow to A will be totally 
>> disrupted until TCP_B connection times out. There are 
>> similar problem if connectivity to B is much slower or less reliable
>> than that to A.

>I think that 2 is the only possible "correct" behavior, 
>because 1 is unimplementable and 3 breaks the basic TCP model 
>merely because one destination has lower throughput than 
>another.  2's problem is that it restricts both connections to 
>the poorer of the pair (whether deliberate attack or poor 
>provisioning), but at least they both behave like valid TCP 
>connections.

(2) is hardly more correct than (3). B could bring its TCP window
to zero for as long as the TCP timeout, then accept a few bytes,
and go back to zero, and so on...

And then, there´s the issue that it allows a single TURN client to
exhaust the server resources more easily.

>There's another possibility of making the protocol more 
>complex by signalling queueing on the client connection, but I 
>really don't think we want that.

Agreed. That would be the proper solution, but that would also
be overly complicated. At the end, we´d redefine conveying datagrams
on top of TCP, so you can do TCP over TCP :-(

>But unless there's a compelling reason to support it, I think 
>it would be better if TURN just says one peer per client 
>connection.  I'm not aware of a compelling reason.  If there 
>is a compelling reason to support it, I think big red flags 
>and possibly even SHOULD NOT language should be used to 
>discourage its use except when necessary.

Personnaly, I tend to agree with Alfred and Evgeniy:
Multiple simultaneously-active connections should not be supported
at all. In fact, the send&data indications format is not quite
Suited for connection-oriented transports.

By the way, does ICE-TCP requires the TURN server to accept
multiple connections? If so, how does this fit with the requirements
to only allow one connection in order not to "bypass security"?

-- 
Rémi Denis-Courmont
Software Engineer
Nokia TP/SP, Helsinki

---

From: Rohan Mahy <[email-masked]>
Date: Mon, 6 Aug 2007 07:36:46 -0700

Hi Remi,

I seem to remember that gathering TURN candidates specifically was a  
SHOULD in a previous version of ICE.  Now it just says: "Agents  
SHOULD obtain relayed candidates..." but doesn't specify a specific  
method.  Even so, it seems that normatively describing how to use at  
least one method with ICE is quite important.

A related issue is that since SIP calls can fork, ICE needs to work  
in this environment, so any relay protocol needs to have  
deterministic behavior in this environment. I personally would not  
have done TURN if we did not need support for forking.  Without  
forking we could have reused another relay protocol (like SOCKS).

And as much as I would like to wish otherwise, I suspect you are  
right that we don't know how well TURN TCP really works without an  
early implementation ICE TCP.

thanks,
-rohan

---

From: Rohan Mahy <[email-masked]>
Date: Mon, 6 Aug 2007 07:38:13 -0700

Hi Remi,

I think (2) is the normal, default handling for TCP to TCP relays.   
Yes, B could make its window very, very small, but TCP A is still no  
worse off than a direct connection to the peer would have been.  I  
also don't see how this exhausts server resources.  The server does  
not have to do any work while it is not reading. It just needs to  
keep connection state for the two connections.

The TURN server could still set some minimum responsiveness or  
throughput metric after which it employs (3), but (2) is still the  
best default IMO.

thanks,
-rohan

---

From: Rémi Denis-Courmont <[email-masked]>
Date: Tue, 7 Aug 2007 09:37:42 +0300

> forking we could have reused another relay protocol (like SOCKS).

After a bit of thinking, I doubt forking really requires multiplexing 
TCP-over-TCP. The client can simply reconnect to the TURN server and request 
the same port number as was already allocated using REQUESTED-PORT-PROPS, 
REQUESTED-IP and REQUESTED-TRANSPORT, and preserve 1:1 TCP connection 
relaying.

As such, I see no reasons for allowing 1:N (TCP|TLS)-to-TCP.

-- 
Rémi Denis-Courmont

---

From: Rohan Mahy <[email-masked]>
Date: Tue, 7 Aug 2007 07:03:02 -0700

Hi Rémi,

I have to think about this suggestion a bit more.  Today, sending a  
new Allocate request with an existing allocated address and port  
causes a move.  We would need to add a new attribute at least.

I'm not sure this is really any simpler than supporting and (briefly)  
using 1:N TCP connections.  I don't think it is a practical problem  
to limit the speed of the client to TURN server connection to the  
speed of the slowest of the server to peer connections, but this  
would be good to model.

thanks,
-rohan

---

From: Rémi Denis-Courmont <[email-masked]>
Date: Thu, 9 Aug 2007 14:01:29 +0300

Hello,

> causes a move.  We would need to add a new attribute at least.

While I do understand the point of moving a UDP flow, I doubt moving a TCP 
session makes any sense. If the TCP connection breaks, the server and the 
server cannot really know up to where the other side has successfully 
received data - all they know is that it's somewhere between the highest 
received acknowledgement sequence and the highest sent sequence. But within 
the window, it's unknown by design.

In theory, both sides could replicate "stream offsets" above the socket layer, 
and exchange them when moving a connection, but I think nobody wants to go 
into that. And we'd have to replicate the TCP window buffers as well to 
support retransmission.

As such, I really think "moving" should be restricted to UDP server-to-peer 
flows. For TCP server-to-peer flows, if the client-to-server session breaks, 
the server must break the server-to-peer connection.

> speed of the slowest of the server to peer connections, but this

Say I want to send a 2gigs movie to a forked MSRP session. Should the fastest 
receiver wait for the slowest one? As a user, I definitely expect the fastest 
to not to have to wait.

-- 
Rémi Denis-Courmont

---

From: Rohan Mahy <[email-masked]>
Date: Fri, 10 Aug 2007 07:14:58 -0700

> receiver wait for the slowest one? As a user, I definitely expect  

Yes, I still think it is reasonable for the fastest receiver to wait  
for the slowest one.  This only happens during the period where you  
are forking.  You probably won't start sending a 2gig movie until  
you've resolved which instance you are sending it to, and therefore  
selected a single fork by then.

thanks,
-rohan

---

From: Rémi Denis-Courmont <[email-masked]>
Date: Mon, 13 Aug 2007 10:15:47 +0300

> selected a single fork by then.

I do not quite agree. To recap, there are lots of issues with 1:N TURN/TCP 
sessions.

First, there is no TCP protocol that supports forking as of now. Contrary to 
my earlier assumption (my mistake), MSRP does not support forking at all. 
Quoting draft-ietf-simple-message-sessions-19 §5.4:

   (...) The
   node MUST also check to make sure the session is not already in use
   on another connection.  If the session is already in use, it MUST
   reject the request with a 506 response.

      If it were legal to have multiple connections associated with the
      same session, a security problem would exist.  If the initial SEND
      request is not protected, an eavesdropper might learn the URI, and
      use it to insert messages into the session via a different
      connection.

Second, I am still doubtful how practical it would be to "resolve" a fork when 
the slowest peer is very slow.

Third, there is no way for the client to request resetting a TCP session. One 
simple way would have been to close the TURN connection, but that only works 
if we have 1:1 connection, and disallow "moving" TCP connections.

Forth, I may have missed something, but how will support for multiple TCP not 
contradict the security requirement NOT to allow running servers?

Fifth, and loosely related, "moving" TCP connections is not generally 
possible. It might work for TCP-framed RTP. But it does not work with 
any "normally TCP" protocol, such as TLS or MSRP, as these cannot cope with 
reordering or packet loss.

-- 
Rémi Denis-Courmont