Hi, I would like to insist in the 408 problem when it's locally generated due to fr_timer timeout in SIP UDP. Let's suppose this very simple example:
- Call from UAC to proxy. - Proxy routes it to a gateway (no failover to other gateways).
3 cases:
a) Gateway replies 408, so TM selects 408 (OK).
b) Provisional responses are received but fr_inv_timer expires, so TM generates a local 408. The client receives 408 (OK).
c) No reponse at all from gateway so fr_timer expires and TM generates a local 408. The client receives 408 (WRONG).
Obviously in case "c" it doesn't make sense to send a 408 to the client as the fact is that the gateway is unreachable, so a 500 should be replied to the client.
So what is the problem? In case "c" there should be a "transport error". According to RFC 3261 if an UDP transaction gets a ICMP "port unreachable" it should generate a local 503. And if it receives no UDP reply at all (neither an ICMP notification) then it should generate a local 408.
Problems with this: - SR doesn't rely on received ICMP (it neither receives them AFAIK). - If the gateway is down there will be not a ICMP message (neither if the gateway TCP/IP stack doesn't generate such ICMP notifications).
So with the current TM design an UDP transport error just can cause a local 408, and never a 503. This is the main problem.
Unfortunatelly such 408 is painful as the examples above show. This is the reason I propose TM to generate a local 503 if no response at all is received for a UDP requests (when fr_timer expires).
More or less the same info in this report: http://sip-router.org/tracker/index.php?do=details&task_id=55
Regards.
Iñaki Baz Castillo writes:
Unfortunatelly such 408 is painful as the examples above show. This is the reason I propose TM to generate a local 503 if no response at all is received for a UDP requests (when fr_timer expires).
inaki,
from rfc3261:
21.4.9 408 Request Timeout The server could not produce a response within a suitable amount of time, for example, if it could not determine the location of the user in time.
1.5.4 503 Service Unavailable The server is temporarily unable to process the request due to a temporary overloading or maintenance of the server.
if there is no response from server, there is no way for the proxy to know that the server is "temporarily overloaded or under maintenance". it seems that 503 needs to come from the server itself. so in this case 408 looks a more appropriate response to me.
-- juha
2010/4/9 Juha Heinanen jh@tutpro.com:
Iñaki Baz Castillo writes:
> Unfortunatelly such 408 is painful as the examples above show. This is > the reason I propose TM to generate a local 503 if no response at all > is received for a UDP requests (when fr_timer expires).
inaki,
from rfc3261:
21.4.9 408 Request Timeout The server could not produce a response within a suitable amount of time, for example, if it could not determine the location of the user in time.
1.5.4 503 Service Unavailable The server is temporarily unable to process the request due to a temporary overloading or maintenance of the server.
if there is no response from server, there is no way for the proxy to know that the server is "temporarily overloaded or under maintenance". it seems that 503 needs to come from the server itself. so in this case 408 looks a more appropriate response to me.
I understand your point, but it would make more sense if 408 is just caused when a transaction fails due to fr_timer (no provisional response from destination). But this is not the case as TM generates 408 when fr_inv_timer expires (maybe 60-120 seconds after receiving a provisional response). So the 408 is a confussing response:
- In the first case (fr_timer expires) there has been a real error (alarm). - In the second case (fr_inv_timer) there has been no problem, just the call progress took so long that the proxy has decided to cancel it.
Perhaps in the second case the proxy should generate a 480 and leave the 408 just for fr_timer expiration?
2010/4/9 Iñaki Baz Castillo ibc@aliax.net:
I understand your point, but it would make more sense if 408 is just caused when a transaction fails due to fr_timer (no provisional response from destination). But this is not the case as TM generates 408 when fr_inv_timer expires (maybe 60-120 seconds after receiving a provisional response). So the 408 is a confussing response:
- In the first case (fr_timer expires) there has been a real error (alarm).
- In the second case (fr_inv_timer) there has been no problem, just
the call progress took so long that the proxy has decided to cancel it.
Perhaps in the second case the proxy should generate a 480 and leave the 408 just for fr_timer expiration?
For example, RFC 3398 (SIP-ISUP mapping) states this mapping:
Response received Cause value in the REL 408 Request timeout 102 Recovery on timer expiry
ISUP Cause value SIP response 102 recovery of timer expiry 504 Gateway timeout
Humm, perhaps TM should generate a 504 when fr_inv_timer expires if the INVITE has no Expires header?:
RFC 3261
21.5.5 504 Server Time-out
The server did not receive a timely response from an external server it accessed in attempting to process the request. 408 (Request Timeout) should be used instead if there was no response within the period specified in the Expires header field from the upstream server.
But the above leaves the door open for a 408 even if the proxy receives provisiona responses... Humm, I will open a thread in sip-implementors about it.
On Friday 09 April 2010, Iñaki Baz Castillo wrote:
I understand your point, but it would make more sense if 408 is just caused when a transaction fails due to fr_timer (no provisional response from destination). But this is not the case as TM generates 408 when fr_inv_timer expires (maybe 60-120 seconds after receiving a provisional response). So the 408 is a confussing response:
- In the first case (fr_timer expires) there has been a real error (alarm).
- In the second case (fr_inv_timer) there has been no problem, just
the call progress took so long that the proxy has decided to cancel it.
Perhaps in the second case the proxy should generate a 480 and leave the 408 just for fr_timer expiration?
Hi Iñaki,
hm, i'd opt to keep the 408 here. What about setting a flag if you received a provisional response in reply_route, and then check this in your failure_route when you process the 408? We do it this way, and did not found any problems so far. I think Juha also proposed something like this earlier.
Cheers,
Henning
Henning Westerholt writes:
hm, i'd opt to keep the 408 here. What about setting a flag if you received a provisional response in reply_route, and then check this in your failure_route when you process the 408? We do it this way, and did not found any problems so far. I think Juha also proposed something like this earlier.
yes, that is what i proposed and have been using myself for years. i don't see any need to make changes in tm for this.
-- juha
On 4/12/10 1:28 PM, Juha Heinanen wrote:
Henning Westerholt writes:
hm, i'd opt to keep the 408 here. What about setting a flag if you received a provisional response in reply_route, and then check this in your failure_route when you process the 408? We do it this way, and did not found any problems so far. I think Juha also proposed something like this earlier.
yes, that is what i proposed and have been using myself for years. i don't see any need to make changes in tm for this.
in 3.0 there are some extra functions that may help figuring out the type of timeout - t_branch_timeout() and t_branch_replied(): http://kamailio.org/docs/modules/stable/modules/tm.html#t_branch_timeout
Cheers, Daniel
2010/4/13 Daniel-Constantin Mierla miconda@gmail.com:
in 3.0 there are some extra functions that may help figuring out the type of timeout - t_branch_timeout() and t_branch_replied(): http://kamailio.org/docs/modules/stable/modules/tm.html#t_branch_timeout
It could be valid, yes:
failure_route[0]{ if (t_branch_timeout()){ if (t_branch_replied()) log("timeout after receiving a reply (no answer?)\n"); else log("timeout, remote side seems to be down\n"); # ... } }
However I wonder if the description of the funcion is correct:
------------------ 1.5.21. t_branch_replied()
Returns true if the failure route is executed for a branch that did receive at least one reply in the past (the "current" reply is not taken into account). It can be used only from the failure_route. -------------------
What does is mean "Returns true if the failure route is executed for a branch that ..."? Perhaps it means "Returns true if the failure route is executed for a winning branch that ..."?
On Apr 13, 2010 at 10:11, I??aki Baz Castillo ibc@aliax.net wrote:
2010/4/13 Daniel-Constantin Mierla miconda@gmail.com:
in 3.0 there are some extra functions that may help figuring out the type of timeout - t_branch_timeout() and t_branch_replied(): http://kamailio.org/docs/modules/stable/modules/tm.html#t_branch_timeout
It could be valid, yes:
failure_route[0]{ if (t_branch_timeout()){ if (t_branch_replied()) log("timeout after receiving a reply (no answer?)\n"); else log("timeout, remote side seems to be down\n"); # ... } }
However I wonder if the description of the funcion is correct:
1.5.21. t_branch_replied()
Returns true if the failure route is executed for a branch that did receive at least one reply in the past (the "current" reply is not taken into account). It can be used only from the failure_route.
What does is mean "Returns true if the failure route is executed for a branch that ..."? Perhaps it means "Returns true if the failure route is executed for a winning branch that ..."?
Yes: returns true if the winning branch received at least one reply in the past (winning branch == branch for each the failure route is executed).
Andrei P.S.: you might also want to check: t_any_replied(), t_any_timeout() and t_grep_status() (other related new functions from a k < 3.0 point of view).
On 4/14/10 7:58 AM, Andrei Pelinescu-Onciul wrote:
On Apr 13, 2010 at 10:11, I??aki Baz Castilloibc@aliax.net wrote:
2010/4/13 Daniel-Constantin Mierlamiconda@gmail.com:
in 3.0 there are some extra functions that may help figuring out the type of timeout - t_branch_timeout() and t_branch_replied(): http://kamailio.org/docs/modules/stable/modules/tm.html#t_branch_timeout
It could be valid, yes:
failure_route[0]{ if (t_branch_timeout()){ if (t_branch_replied()) log("timeout after receiving a reply (no answer?)\n"); else log("timeout, remote side seems to be down\n"); # ... } }
However I wonder if the description of the funcion is correct:
1.5.21. t_branch_replied()
Returns true if the failure route is executed for a branch that did receive at least one reply in the past (the "current" reply is not taken into account). It can be used only from the failure_route.
What does is mean "Returns true if the failure route is executed for a branch that ..."? Perhaps it means "Returns true if the failure route is executed for a winning branch that ..."?
Yes: returns true if the winning branch received at least one reply in the past (winning branch == branch for each the failure route is executed).
but if it is a 408 received, without any prior 1xx, t_branch_replied() will be false, right?
Maybe a new function t_is_local_reply() would be good to return true if it is a local generated (faked) reply or false for received reply.
Cheers, Daniel
Andrei P.S.: you might also want to check: t_any_replied(), t_any_timeout() and t_grep_status() (other related new functions from a k< 3.0 point of view).
2010/4/14 Daniel-Constantin Mierla miconda@gmail.com:
but if it is a 408 received, without any prior 1xx, t_branch_replied() will be false, right?
As far as I understand the doc it should be 'true'. This is, if I'm right t_branch_replied() is true if the winning branch has received *any* response (provisional or final).
Also, if I'm right, t_branch_timeout() returns true just in case fr_timer or fr_inv_timer (after receiving provisional responses) expires. Using both functions there is a definitive way to check if the winning branch is a local 408 due to fr_timer (exactly what I wanted to achieve).
Maybe a new function t_is_local_reply() would be good to return true if it is a local generated (faked) reply or false for received reply.
As it was in kamailio < 3.0 :)
However, in which cases (apart from the local timeout) is it useful to determine if a response is locally generated? I just can imagine it for downstream TCP errors.
Regards.
2010/4/12 Juha Heinanen jh@tutpro.com:
Henning Westerholt writes:
> hm, i'd opt to keep the 408 here. What about setting a flag if you > received a provisional response in reply_route, and then check this > in your failure_route when you process the 408? We do it this way, > and did not found any problems so far. I think Juha also proposed > something like this earlier.
yes, that is what i proposed and have been using myself for years. i don't see any need to make changes in tm for this.
Hi, I already explained in other thread that this is not accourate enough. Example: - branch 1 replies 180 followed by a 503 (it sets the flag(1XX_RECEIVED). - branch 2 raises fr_timer timeout (no response at all from the server 2).
You inspect the chosen reply in failure route and get 408, and also you inspect the flag(1XX_RECEIVED) and it's enabled, so you understand (wrongly) that the 408 local timeout was generated after ringing, but that's not true. And most probably you would prefer to choose the 503 (so 500) rather than the local generated 408 (due to fr_timer expiration).