Subject: [BEHAVE] TURN major issues and proposed fixes

From: "Rohan Mahy" <[email-masked]>
Date: Fri, 19 Jan 2007 20:02:59 -0800

Hi Folks,

The following issues have all come up from implementors of TURN and
are big enough issues that I wanted to get some list feedback before
incorporating these in a new rev.

1. Allocations, Bindings, Permissions, Timeouts, and the Active Destination.

The current text is still a bit fuzzy and inconsistent about what is a
difference between permission and a binding and what keeps bindings
open. Also, many implementors have expressed confusion between the
behavior of an ordinary NAT binding and a "STUN Relay binding", so I
am proposing we skip the binding terminology in favor of "permission".
Much of the following came from consensus at one of the meetings. I've
come up with the following proposal which fills out a consistent set
of rules:
- Remove the terminology "binding" altogether inside the TURN server.
Only use "binding" when talking about a "real" NAT (ex: between the
TURN client and the TURN server)
- All requests and indications except for initial Allocation requests
are sent in the context of a matching valid allocation, otherwise they
are rejected (requests) or discarded silently (Indications).
- Allocations are explicitly refreshed via subsequent allocation
requests.  Allocation timeout values are on the order of minutes. Send
and Data indications do not refresh Allocations. Allocation timers are
based on the LIFETIME attribute.
- Each allocation can have zero or more permissions
- When allocations are destroyed all related permissions are deleted.
- Permissions are only created by Send Indications over UDP and
Connect Requests over TCP.
- Data sent to a peer (via send Indications and unencapsulated data
sent to the active destination) by the TURN client refresh the
relevant permission. Data to one permission does not refresh other
permissions associated with the same binding.
- The expected timeout interval for all permissions for an allocation
is conveyed from the server to the client using the REFRESH-INTERVAL
attribute in an initial successful Allocate Response.
- The active destination is changed only with the Set Active
Destination Request for an allocation. The active destination is
completely independent of any permissions.

2. SetActiveDestination should not be limited to existing permissions
Current text in some places says that the active destination needs to
be an existing permission. This is actually unnecessary however, and
loosening this restriction is useful.
Take the case where the TURN client receives a SIP INVITE with an
offer, and the TURN client wishes to accept the offer. The TURN client
should be able to set the active destination immediately before
issuing its first Send request (to this destination). Using this order
of operations insures that the TURN client receives all data traffic
unencapsulated. This provides for more consistent bandwidth usage in
this case.

The proposal is to change the current text to completely decouple the
active destination from any permissions.  A permission controls
whether traffic flows.  The active destination controls whether
traffic flowing over a binding is encapsulated of not.

An alternative to this proposal is to create a new permission if no
permission for the active destination exists.  The problem is that
this does not result in sending any data to the peer (as described in
the applicability statement and UNSAF considerations), it is
completely implicit behavior, and the opposite operation (clearing the
active destination) does not delete permissions.

3. SetActiveDestination changing destinations

Currently there are several pages of text devoted to a timer based
state machine that needs to be implemented on both the server and the
client to handle the case of switching the active destination from one
address to another. The problem is that  over UDP, the client cannot
tell which unencapsulated data is from the old active destination vs.
the new active destination.

However, requiring timers and a state machine on the server is a
significant implementation burden which provides no benefit for the
TURN server or its administrative domain.

The proposal is to put this problem completely into the hands of the
client.  Some clients may never wish to change the active destination
for example and will have no need to implement anything special.
Those clients that want to change the active destination over UDP are
required to clear the active destination, wait for an appropriate
interval (5 seconds is suggested), then set the active destination to
the new address.

Specific proposed text for items 2 and 3 and also delete the TIMER-VAL
attribute:

<section title="Set Active Destination Request">
<section title="Client Behavior">
<t>
The Set Active Destination address allows the client to create an
optimized relay function between it and the server. When the server
receives packets from a particular preferred external client, the
server will forward those packets towards the client without
encapsulating them in a Data Indication. Similarly, the client can
send non-STUN packets to the server without encapsulation, and these
are forwarded to the external client. Sending and receiving data in
unencapsulated form is critical for efficiency purposes. One of the
primary use cases for the STUN relay usage is in support of Voice over
IP (VoIP), which uses very small UDP packets to begin with. The extra
overhead of an additional layer of encapsulation is considered
unacceptable.
</t><t>
The Set Active Destination request is used by the client to provide
the identity of this preferred external client. The Set Active
Destination address MAY contain a REMOTE-ADDRESS attribute. This
attribute, when present, provides the address of the preferred
external client to the server. When absent, it clears the value of the
preferred external client. This address has no effect on the existence
of any permissions.
</t><t>
The client MUST NOT send a Set Active Destination request with a
REMOTE-ADDRESS attribute over an unreliable link (ex: UDP) if an
active destination is already set for that allocation. If the client
wishes to set a new active destination, it MUST wait until 5 seconds
after a successful response is received to a Set Destination Request
removing the active destination. Failure to wait could cause the
client to receive and attribute late data forwarded by the STUN relay
server to the wrong peer.
</t><t>
<list><t>Consider the case where the active destination is set, and
the server is relaying packets towards the client. The client knows
the IP address and port where the packets came from - the current
value of the active destination. The client issues a Set Active
Destination Request to change the active destination, and receives a
response. A moment later, a data packet is received, not encapsulated
in a STUN Data Indication. What is the source if this packet? Is it
the active destination that existed prior to the Set Active
Destination request, or the one after? If the transport between the
client and the STUN server is not reliable, there is no way to
know.</t></list>
</t>
</section>

<section title="Server Behavior">
<t>
The Set Active Destination Request is used by a client to set the
forwarding destination of all data that is not encapsulated in STUN
Send Indications. In addition, when a matching permission is present,
all data received from that external client will be forwarded to the
STUN client without being encapsulated in a Data Indication. This
request does not modify any permissions.
</t><t>
The request MUST be authenticated using the same shared secret as the
one associated with the allocation, or be authenticated using a short
term password derived from that shared secret. If the request was
authenticated but not with such a matching credential, the server MUST
generate an error response with a 441 response code.
</t><t>
If the Set Active Destination request does not contain a
REMOTE-ADDRESS attribute, the value of the active destination is
cleared. If the Set Active Destination request contains a
REMOTE-ADDRESS attribute, and the active destination is not set, the
active destination is set to that IP address and port. If an active
destination is already set, and the request was received over a
reliable transport, the active destination is changed to the new
value.  If the active destination is already set and the request was
received over UDP, the Set Active Destination request is rejected with
a 439 Active Destination Already Set error response.  This prevents
the race condition described in the previous section.
</t>
</section>
</section>

4. Opening TCP permissions

Currently TCP to TCP traffic between TURN servers requires the TURN
servers to implement simultaneous open.

SYN ->
<- SYN
SYN-ACK ->
<- ACK

Option A is to leave this as is and to clarify this non-obvious
implication to implementors (you cannot receive an incoming connection
unless you first try to open one with the Connect request.  Option B
is to include an explicit Open Permission Request to create a specific
permission for the TURN server to receive a TCP SYN from one specific
IP address and port number.

I will implement Option A unless there is strong desire on the list to
do something else.

thanks,
-rohan

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

---

From: "Brian Stucker" <[email-masked]>
Date: Mon, 22 Jan 2007 18:21:00 -0600

> -----Original Message-----
> From: Rohan Mahy [mailto:[email-masked]] 
> Sent: Friday, January 19, 2007 10:03 PM
> To: [email-masked]
> Cc: Rohan Mahy
> Subject: [BEHAVE] TURN major issues and proposed fixes
> 
> Hi Folks,
> 
> The following issues have all come up from implementors of 
> TURN and are big enough issues that I wanted to get some list 
> feedback before incorporating these in a new rev.
> 
> The current text is still a bit fuzzy and inconsistent about 
> what is a difference between permission and a binding and 
> what keeps bindings open. Also, many implementors have 
> expressed confusion between the behavior of an ordinary NAT 
> binding and a "STUN Relay binding", so I am proposing we skip 
> the binding terminology in favor of "permission".
> Much of the following came from consensus at one of the 
> meetings. I've come up with the following proposal which 
> fills out a consistent set of rules:
> Only use "binding" when talking about a "real" NAT (ex: 
> between the TURN client and the TURN server)

Sounds good.

> - All requests and indications except for initial Allocation 
> requests are sent in the context of a matching valid 
> allocation, otherwise they are rejected (requests) or 
> discarded silently (Indications).

Sounds good.

> - Allocations are explicitly refreshed via subsequent 
> allocation requests.  Allocation timeout values are on the 
> order of minutes. Send and Data indications do not refresh 
> Allocations. Allocation timers are based on the LIFETIME attribute.

I'm confused. What's the relation between LIFETIME and REFRESH-INTERVAL
below? If the allocation expires, then the permissions go with it
because the permissions were created in the context of an allocation.

> - Permissions are only created by Send Indications over UDP 
> and Connect Requests over TCP.

This means that an offerer would have to generate RTP traffic to an
answerer to get RTP traffic sent back to it. What if I want to setup a
one-way stream to me in which it's inappropriate to generate traffic in
the other direction, only to make the TURN server happy? Why not let Set
Active Destination also create a permission?

> - Data sent to a peer (via send Indications and 
> unencapsulated data sent to the active destination) by the 
> TURN client refresh the relevant permission. Data to one 
> permission does not refresh other permissions associated with 
> the same binding.

Sounds good.

> - The expected timeout interval for all permissions for an 
> allocation is conveyed from the server to the client using 
> the REFRESH-INTERVAL attribute in an initial successful 
> Allocate Response.

How does this relate to LIFETIME (see above)?

> Destination Request for an allocation. The active destination 
> is completely independent of any permissions.

There's some text about the Set Active Destination Request creating a
permission in section 9.2 that's been floating about on the list as
being used to allow an originator to tell the TURN server to allow
traffic from that destination. This would make it possible for a
permission to be created without requiring the originator to generate
traffic to the actual intended destination. I think this should be
allowed. Are you proposing changing this?

> 
> 2. SetActiveDestination should not be limited to existing 
> permissions Current text in some places says that the active 
> destination needs to be an existing permission. This is 
> actually unnecessary however, and loosening this restriction 
> is useful.
> Take the case where the TURN client receives a SIP INVITE 
> with an offer, and the TURN client wishes to accept the 
> offer. The TURN client should be able to set the active 
> destination immediately before issuing its first Send request 
> (to this destination). Using this order of operations insures 
> that the TURN client receives all data traffic 
> unencapsulated. This provides for more consistent bandwidth 
> usage in this case.

This does not (to me) appear to mesh with some of the points you've made
above. I thought paragraph 5 on page 19 of the draft made the
expectation pretty clear:

   If the Set Active Destination request contains a REMOTE-ADDRESS
   attribute, the IP address contained within it is added to the
   permissions for this allocation, if it was not already present.

> 
> The proposal is to change the current text to completely 
> decouple the active destination from any permissions.  A 
> permission controls whether traffic flows.  The active 
> destination controls whether traffic flowing over a binding 
> is encapsulated of not.
> 
> An alternative to this proposal is to create a new permission 
> if no permission for the active destination exists.  The 
> problem is that this does not result in sending any data to 
> the peer (as described in the applicability statement and 
> UNSAF considerations), it is completely implicit behavior, 
> and the opposite operation (clearing the active destination) 
> does not delete permissions.

Why not add an operation to explicitly clear the active destination
then?

> Currently there are several pages of text devoted to a timer 
> based state machine that needs to be implemented on both the 
> server and the client to handle the case of switching the 
> active destination from one address to another. The problem 
> is that  over UDP, the client cannot tell which 
> unencapsulated data is from the old active destination vs.
> However, requiring timers and a state machine on the server 
> is a significant implementation burden which provides no 
> benefit for the TURN server or its administrative domain.
> 
> The proposal is to put this problem completely into the hands 
> of the client.  Some clients may never wish to change the 
> active destination for example and will have no need to 
> implement anything special.
> Those clients that want to change the active destination over 
> UDP are required to clear the active destination, wait for an 
> appropriate interval (5 seconds is suggested), then set the 
> active destination to the new address.
> 
> <section title="Set Active Destination Request"> <section 
> title="Client Behavior"> <t> The Set Active Destination 
> address allows the client to create an optimized relay 
> function between it and the server. When the server receives 
> packets from a particular preferred external client, the 
> encapsulating them in a Data Indication. Similarly, the 
> client can send non-STUN packets to the server without 
> encapsulation, and these are forwarded to the external 
> client. Sending and receiving data in unencapsulated form is 
> critical for efficiency purposes. One of the primary use 
> cases for the STUN relay usage is in support of Voice over IP 
> (VoIP), which uses very small UDP packets to begin with. The 
> extra overhead of an additional layer of encapsulation is 
> considered unacceptable.
> </t><t>
> The Set Active Destination request is used by the client to 
> provide the identity of this preferred external client. The 
> Set Active Destination address MAY contain a REMOTE-ADDRESS 
> attribute. This attribute, when present, provides the address 
> of the preferred external client to the server. When absent, 
> it clears the value of the preferred external client. This 
> address has no effect on the existence of any permissions.
> </t><t>
> The client MUST NOT send a Set Active Destination request 
> with a REMOTE-ADDRESS attribute over an unreliable link (ex: 
> UDP) if an active destination is already set for that 
> allocation. If the client wishes to set a new active 
> destination, it MUST wait until 5 seconds after a successful 
> response is received to a Set Destination Request removing 
> the active destination. Failure to wait could cause the 
> client to receive and attribute late data forwarded by the 
> STUN relay server to the wrong peer.
> </t><t>
> <list><t>Consider the case where the active destination is 
> set, and the server is relaying packets towards the client. 
> The client knows the IP address and port where the packets 
> came from - the current value of the active destination. The 
> client issues a Set Active Destination Request to change the 
> active destination, and receives a response. A moment later, 
> a data packet is received, not encapsulated in a STUN Data 
> Indication. What is the source if this packet? Is it the 
> active destination that existed prior to the Set Active 
> Destination request, or the one after? If the transport 
> between the client and the STUN server is not reliable, there 
> is no way to know.</t></list> </t> </section>
> 
> The Set Active Destination Request is used by a client to set 
> the forwarding destination of all data that is not 
> encapsulated in STUN Send Indications. In addition, when a 
> matching permission is present, all data received from that 
> external client will be forwarded to the STUN client without 
> being encapsulated in a Data Indication. This request does 
> not modify any permissions.
> </t><t>
> The request MUST be authenticated using the same shared 
> secret as the one associated with the allocation, or be 
> authenticated using a short term password derived from that 
> shared secret. If the request was authenticated but not with 
> such a matching credential, the server MUST generate an error 
> response with a 441 response code.
> </t><t>
> REMOTE-ADDRESS attribute, the value of the active destination 
> is cleared. If the Set Active Destination request contains a 
> REMOTE-ADDRESS attribute, and the active destination is not 
> set, the active destination is set to that IP address and 
> port. If an active destination is already set, and the 
> request was received over a reliable transport, the active 
> destination is changed to the new value.  If the active 
> destination is already set and the request was received over 
> UDP, the Set Active Destination request is rejected with a 
> 439 Active Destination Already Set error response.  This 
> prevents the race condition described in the previous section.
> </t>
> </section>
> </section>
> 
> Currently TCP to TCP traffic between TURN servers requires 
> the TURN servers to implement simultaneous open.
> 
> SYN ->
> <- SYN
> SYN-ACK ->
> <- ACK
> 
> Option A is to leave this as is and to clarify this 
> non-obvious implication to implementors (you cannot receive 
> an incoming connection unless you first try to open one with 
> the Connect request.  Option B is to include an explicit Open 
> Permission Request to create a specific permission for the 
> TURN server to receive a TCP SYN from one specific IP address 
> and port number.
> 
> I will implement Option A unless there is strong desire on 
> the list to do something else.
> 
> thanks,
> -rohan
>

---

From: Rohan Mahy <[email-masked]>
Date: Tue, 23 Jan 2007 08:24:40 -0800

Hi Brian,

Thanks for your comments.  My responses are inline.

> because the permissions were created in the context of an allocation.

I expect that the LIFETIME might be on the order of 15 minutes, and the 
REFRESH-INTERVAL for a UDP permission might be on the order of 30 
seconds.

Under the proposal here, you need to send data to the target of each 
permission at least every 30 seconds to keep the permission alive.  I 
assume this also is likely to have the side effect of keeping NAT 
bindings alive as well.  You separately need to send a (re)Allocate 
Request to the TURN server at least every 15 minutes to refresh the 
allocation.  As you pointed out, if you don't do this, the whole 
allocation goes away and all the related permissions with it.

> Active Destination also create a permission?

This would be a change from the Applicability, Introduction, and UNSAF 
considerations as I read them.  There is a lot of text in those 
sections about how we only create a permission when we have sent data 
to that target.

> allowed. Are you proposing changing this?

can you paste that into this thread please?

> above.

Can you be more specific about that?
This proposed change makes the active destination used by the TURN 
server only for deciding when to send unwrapped data and to decide how 
to process unwrapped data it receives.
You can set the active destination to anything you'd like.  IIF traffic 
is received and there is a permission (because you sent traffic there) 
it gets wrapped in a Data indication unless it was received from the 
active destination.

Also, if you set the active destination, there may be no need to wrap 
your first bit of outgoing data in a Send request.

> I thought paragraph 5 on page 19 of the draft made the

This paragraph is later contradicted a few paragraphs later.  We need 
to change one of the paragraphs.

> Why not add an operation to explicitly clear the active destination

We can clear the active destination just fine now, its just that that 
has no effect on permissions.

What we don't have is a way to explicitly delete a permission.  I 
proposed a Close Binding Request verb back in Montreal and there was 
pretty overwhelming reaction to get rid of it.

>> 3. SetActiveDestination changing destinations

Do you have any comments on proposals 3 or 4?

thanks,
-rohan