Subject: [BEHAVE] TURN Allocation retransmission behavior

From: "Rohan Mahy" <[email-masked]>
Date: Thu, 7 Feb 2008 08:36:23 -0800

From Philip Mathews:
*) Stateful allocation issue: In general, sending an Allocate Request on
5-tuple where there is an existing allocation is not allowed; instead, to
refresh the allocation the client uses the Refresh Request.  However, there
is the issue that, over UDP, retransmissions are allowed. Everyone agrees on
the high-level concept, but there were some comments about the exact text in
the TURN-06 document.
There was a lot of discussion here, which I did not capture. However, in the
end this seems to boil down to the best way of implementing the above
high-level intent.
ACTION: Rohan to send proposed text to the mailing list by the end of Wed,
30 Jan 2008.

Hopefully this is better late than never:

DISCUSSION:
If an Allocate request succeeded, the text in the STUN base spec indicates
that a retransmission (an *identical* request) must result in an identical
response.  I don't think this is a generally a problem.  As the text below
mentions, except for my caveats mentioned below, the server can recompute a
bitwise identical response from the information that is probably stored with
the allocation anyway. I think where folks had a problem with this is that
if the request received an error response or if the client is actively
trying to mess with the server, the response won't be identical, but that is
non-problem.

CAVEAT 1:
One side effect of this requirement is that any nonce provided could (very,
very rarely) become stale between being used for the initial allocation and
the time the retransmission was received. The server should check that the
same credentials are present and are the same as the credentials used to
authenticate the original request. In the code path for rebuilding
retransmissions, the server should assume that it already checked nonce
freshness the first time.

CAVEAT 2:
If a late Allocation retransmission and a de-Allocation cross on the wire,
it is possible that the allocation state has been destroyed already. In this
case, I think it should be acceptable to provide a neutral error or ignore
the retransmission, but I do not have a strong feeling about this.

This brings up a more general race condition question. Is it necessary to
prevent the reuse of UDP allocations for some short period of time in case
late traffic might get forwarded?

CURRENT TEXT (Section 5.2.1):
When the server receives the Allocate Request, it begins by processing it
according to the base protocol procedures described in [STUN], plus the
Long-Term Credential Mechanism procedures if the server is using this
mechanism.

It then checks if the 5-tuple used for the Allocate Request matches the
5-tuple used for an existing allocation. If there is a match, then:

    * If the transport protocol is UDP, and the transaction id in the
request message matches the transaction id used for the original allocation,
then the server treats this as a retransmission of the original request, and
replies with the same response as it did to the original request. The server
may do this by either storing its original response and resending it, or by
rebuilding its original response from other state data.
    * If the transport protocol is not UDP, or if the transaction id in the
request message does not match the transaction id used for the original
allocation, then the server replies with an error response containing the
error code 437 Allocation Mismatch.

If the 5-tuple does not match an existing allocation, then processing
continues as described below.

PROPOSED TEXT:
When the server receives the Allocate Request, it begins by processing it
according to the base protocol procedures described in [STUN].

It then checks if the 5-tuple used for the Allocate Request matches the
5-tuple used for an existing allocation. If there is a match, then:

    * If the allocation has already been recently deleted, the server
replies with an appropriate neutral error response.
    * If the transport protocol is UDP, and the transaction id in the
request message matches the transaction id used for the original allocation,
then the server treats this as a retransmission of the original request. The
server may reply with either the original stored response, or by rebuilding
a new response from stored state data.  If the request is a retransmission,
the rebuilt response will be identical to the original response.
    * If the transport protocol is not UDP, or if the transaction id in the
request message does not match the transaction id used for the original
allocation, then the server replies with an error response containing the
error code 437 Allocation Mismatch.

If the 5-tuple does not match an existing allocation, then the server
follows the Long-Term Credential Mechanism procedures if the server is using
this mechanism. If authentication is successful processing continues as
described below.

thanks,
-rohan

From Section 7.3.1, 3rd paragraph of 3489bis-13:
   If the request uses UDP transport and is a retransmission of a
   request for which the server has already generated a success response
   within the last 10 seconds, the server MUST retransmit the same
   success response.  One way for a server to do this is to remember all
   transaction IDs received over UDP and their corresponding responses
   in the last 10 seconds.  Another way is to reprocess the request and
   recompute the response.  The latter technique MUST only be applied to
   requests which are idempotent (a request is considered idempotent
   when the same request can be safely repeated without impacting the
   overall state of the system) and result in the same success response
   for the same request.  The Binding method is considered to idempotent
   in this way (even though certain rare network events could cause the
   reflexive transport address value to change).  Extensions to STUN
   SHOULD state whether their request types have this property or not.
_______________________________________________
Behave mailing list
[email-masked]
http://www.ietf.org/mailman/listinfo/behave