Subject: [BEHAVE] Duplicate request handling

From: Simon Perreault <[email-masked]>
Date: Wed, 23 Apr 2008 17:10:28 -0400

Hi,

[draft-ietf-behave-rfc3489bis-15], Section 7.3.1, contains the following:

   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 40 seconds, the server MUST retransmit the same
   success response.

From the absence of indications pertaining to the case where the response was 
not a success, I deduce that the server must not remember the transaction and 
simply try again to fulfill a duplicated request, hoping that this new 
attempt succeeds. Am I right?

Thanks,
Simon
_______________________________________________
Behave mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/behave

---

From: "Benny Prijono" <[email-masked]>
Date: Thu, 24 Apr 2008 14:49:20 +0100

>  attempt succeeds. Am I right?

From my understanding, it doesn't have to be like that. Server may
just retransmit the same failure response for the same request
retransmission if it wants to. In fact I think server should do this
especially for non-idempotent requests, otherwise we may end up with
different state between the client and the server. For example,
imagine when TURN server first returns failure response, then
successful response on the second Allocate retransmission. Client most
likely will ignore the second response retransmission, hence client
thinks that the Allocate has failed while the server thinks it has
been successful.

Cheers
 Benny

---

From: Simon Perreault <[email-masked]>
Date: Thu, 24 Apr 2008 09:57:02 -0400

Hi Benny,

> thinks that the Allocate has failed while the server thinks it has

I think you're right and that the spec should be changed. Any kind of response 
(success or error) for any kind of request (indempotent or not) should be 
remembered and retransmitted when a duplicate request is detected. This is 
transport-level stuff which doesn't have to be concerned about 
application-level stuff.

Simon

---

From: Philip Matthews <[email-masked]>
Date: Thu, 24 Apr 2008 15:06:23 -0400

> transport-level stuff which doesn't have to be concerned about

I agree. We had implicitly assumed that it was ok to report different  
failure codes or succeed after reporting failure, but Benny's example  
shows this is not true.

Note that the request MUST have the same transaction id. If it has a  
different transaction id, then it is a different transaction (and thus  
not a resent) and the behavior can be different.

- Philip

---

From: Bruce Lowekamp <[email-masked]>
Date: Thu, 24 Apr 2008 17:49:36 -0400

> transport-level stuff which doesn't have to be concerned about

I think this is really imposing a lot of state on a stun server to  
solve a problem that's already solved by what's in  the text.  A TURN  
allocate is not idempotent.  You have to remember the response per  
transaction id.  That's already covered by 7.3.1.

To impose that requirement for all STUN transactions essentially  
prevents a high-throughput stun server (for binding requests) from  
being deployed.  If all it's doing is binding requests, the entire  
server really is very minimal and requires little state.  13 says  
that a basic STUN server SHOULD NOT use authentication, which is also  
there to minimize the state required for a pure STUN server.  The  
resulting service can be very high throughput with minimalistic  
resources.  If it has to cache every response it's issued over the  
last 40 seconds, that's a huge data structure that serves no useful  
purpose as far as I can tell.

Bruce

---

From: Simon Perreault <[email-masked]>
Date: Thu, 24 Apr 2008 18:26:04 -0400

> purpose as far as I can tell.

No. A response to a Binding request doesn't depend on any state. So you don't 
have to remember all past responses.

What I meant was that a response, success or not, indempotent or not, should 
be the same for a given transaction ID during the 40 seconds following the 
initial reception. As is already mentioned in the draft, you can store the 
past responses or you can generate a new response from scratch if it 
generates the same response.
_______________________________________________
Behave mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/behave

---

From: Bruce Lowekamp <[email-masked]>
Date: Thu, 24 Apr 2008 18:36:38 -0400

> generates the same response.

OK, great.  Then we agree.  When your previous message said "any  
response should be remembered"  and that it was a transport-level  
issue and not application, I had the other impression.

Bruce

---

From: "Dan Wing" <[email-masked]>
Date: Thu, 24 Apr 2008 15:43:36 -0700

> generates the same response.

Let me throw a wrench into this discussion...

Considering the current text in rfc3489bis, imagine the following
occurs:

  1. STUN client sends a STUN request, which traverses a NAT and 
     arrives at STUN server, and STUN server generates a response.
  2. The NAT in front of the STUN client crashes before the response
     is received.
  3. The NAT in front of the STUN client reboots 5 seconds later and
     becomes operational.
  4. The STUN client's NNth retransmission is sent, which gets a 
     different mapping than (1).
  
Per the text in rfc3489bis, because the transaction-id is the same,
the reponse is supposed to be the same.

But in the case above, we wouldn't want that, would we??

(If you don't like "NAT crashes", or you feel a NAT cannot boot back
up in 5 seconds then consider a slightly different case:  the home
network is multi-homed (two NATs to two different ISPs), and 
one of the NATs dies (or one ISP dies) and the other NAT begins
routing traffic from the STUN client towards the Internet.  This 
would cause the same situation as above.)

-d

---

From: Simon Perreault <[email-masked]>
Date: Thu, 24 Apr 2008 18:52:13 -0400

> But in the case above, we wouldn't want that, would we??

Yes it should be the same. That's what we want. Just consider it like a 
retransmission, as if we were operating over TCP.

The client will know its new mapped address when it issues a new Binding 
request, with a new transaction ID. Exactly the same as the case when the NAT 
crashes and reboots after the response was received correctly. There's a 
certain amount of time during which the client will have a wrong mapped 
address and the RTP (or whatever else) will get lost and everyone will wonder 
why and then we'll curse at NATs and we'll all migrate to IPv6 and they lived 
happily ever after.
_______________________________________________
Behave mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/behave

---

From: Simon Perreault <[email-masked]>
Date: Thu, 24 Apr 2008 19:00:40 -0400

> retransmission, as if we were operating over TCP.

Precision because I wasn't making a lot of sense:

It might appear in this case that the stateless server is better because it 
reacts faster to changes in the network. But then it introduces the potential 
to confuse the client when it receives multiple responses to the same request 
containing different content.

So it might appear that you *do* need to remember all previous responses. But 
that would be a stupid thing to do from an implementor's point of view for 
the case of a Binding-only STUN server. So just generate a new response, let 
the client be confused and sort it out (i.e. by using the first one received 
and throwing all other duplicate responses).

So my only gripe with the current text is that it applies only to success 
responses. Remove the "success" part and be done with it.
_______________________________________________
Behave mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/behave

---

From: Rémi Denis-Courmont <[email-masked]>
Date: Fri, 25 Apr 2008 10:09:55 +0300

> retransmission, as if we were operating over TCP.

Oh, no. I strongly disagree. If the NAT reboots and yields a different 
mapping, the TURN server has to consider this is a different client, hence 
return a different result.

Imagine a client with weak transaction ID randomness (which may be unavoidable 
given 1/ hardware constraints, and 2/ that "secure" randomness is better used 
for cryptography than for NAT traversal). We'd have a trivial denial of 
service attack/hijacking.

In the case Dan describes, there is no problem in considering the two requests 
as different. The earlier mapping will simply expire, as the client will use 
the later one.

-- 
Rémi Denis-Courmont

---

From: Rémi Denis-Courmont <[email-masked]>
Date: Fri, 25 Apr 2008 10:12:49 +0300

Le Thursday 24 April 2008 16:49:20 ext Benny Prijono, vous avez écrit :
> Server may

So what is the big deal? The server will just garbage collect the allocation 
eventually. This is perfectly normal operation. Clients can always "vanish" 
unexpectedly, such as if their network connection fails.

It's totally fine if the server thinks a request has succeeded and the client 
thinks it's failed. Only the opposite would be an issue.

---

From: Simon Perreault <[email-masked]>
Date: Fri, 25 Apr 2008 07:51:51 -0400

> return a different result.

Can I s/TURN/STUN/ or you were really talking about the specifics of TURN?

So basically what you're saying is that a transaction is identified not only 
by the transaction ID but also by the mapped address. The STUN 3-tuple? ;) 
But the text doesn't specify that.

I can't think of any situation where what you're suggesting wouldn't be the 
right thing to do.

And, once again, a server that remembers responses and another that 
regenerates new ones for indempotent request would yield exactly the same 
result if they detect retransmissions by considering the 3-tuple instead of 
only the TID.
_______________________________________________
Behave mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/behave

---

From: Bruce Lowekamp <[email-masked]>
Date: Thu, 24 Apr 2008 18:36:38 -0400

Bruce

---

From: "Benny Prijono" <[email-masked]>
Date: Fri, 25 Apr 2008 13:54:18 +0100

>  unexpectedly, such as if their network connection fails.

Sure client vanishing in TURN is not a big deal and it's just
something that we have to accept in real life.

>  thinks it's failed. Only the opposite would be an issue.

I disagree here. Big deal or not, I think it just doesn't make sense
to return both failure and successful response in the same
transaction.

If server resource is your concern, Simon's proposal doesn't suggest
that server must always cache failure responses. It only suggests that
server returns the same failure response for the same request (or
should it be the same failure class?), which means that server can
always return 400 or 401 response statelessly for example, since
retransmission of the request will always yield the same response. I
think this is good and I support that.

Cheers
 Benny

---

From: "Benny Prijono" <[email-masked]>
Date: Fri, 25 Apr 2008 14:37:24 +0100

>  But the text doesn't specify that.

Interestingly we probably do this already in TURN. In TURN, the
5-tuple matching would probably the very first thing that the server
checks when processing a packet, to get the client allocation context.
It may do this even before passing the request to STUN "transaction
layer". Well at least that's what I do in my code, since response
retransmission is done by (or in the context of) client allocation,
once the client allocation is created by the first successful
response. So in this case, the request retransmission after NAT reboot
will be handled as a brand new allocation since the 5-tuple is
different.

>  I can't think of any situation where what you're suggesting wouldn't be the

Well it kinds of breaks the idempotent-ness property of a request
(imagine if we have PleaseDebitMyBankAccount request in STUN, your
account will be debited twice). It may also not help if the client
receives two different successful responses, as the client will ignore
the second response and we're back with the same problem.

On the other hand, this may have an advantage, for example when only
the later responses get through after NAT reboot hence client will get
the latest result, and it's natural with what we do in TURN.

Frankly I'm not sure which one to choose.

>  result if they detect retransmissions by considering the 3-tuple instead of

I agree.

Cheers
 Benny

---

From: Bruce Lowekamp <[email-masked]>
Date: Fri, 25 Apr 2008 09:39:50 -0400

> containing different content.

A client following the rules of 7.3 will discard the second response  
("the agent checks that the transaction ID matches a transaction that  
is still in progress").  Presumably if someone implements a client  
that doesn't both to remember its own transaction IDs, they either  
know it doesn't matter for their application or it's just a bug.

> responses. Remove the "success" part and be done with it.

I've been trying to construct a case where it matters that the  
response isn't a success response.  The only case I've been able to  
come up with is 500.  In that case, the server has said it has a  
temporary error and the client can retry.  The client is allowed to  
resend the original request.  But since all 300 and 400 response  
codes indicate the current transaction has failed (although in many  
cases it may be retried, I believe it will always be a new tid), I  
think in those cases the response should always be the same.

Bruce