[sr-dev] recursive calls to failure_route strange behavior
Miklos Tirpak
miklos at iptel.org
Fri Nov 20 18:02:50 CET 2009
On 11/20/2009 05:32 PM, Daniel-Constantin Mierla wrote:
> Hello,
>
> On 20.11.2009 17:04 Uhr, Miklos Tirpak wrote:
>> Hi Daniel,
>>
>> On 11/20/2009 04:38 PM, Daniel-Constantin Mierla wrote:
>>>
>>>
>>> On 20.11.2009 9:53 Uhr, Miklos Tirpak wrote:
>>>> On 11/20/2009 12:58 AM, Andres Moya wrote:
>>>>> Dear all!
>>>>>
>>>>> Please help. I have problem dealing with recursive call in failure
>>>>> route.
>>>>>
>>>>> this route happen first time for authentication to external SIP
>>>>> provider (react on code 401), then it have response 480 i want to
>>>>> direct traffic to another operator via cr_route.
>>>>>
>>>>> First i relay INVITE and getting 401, then sending authentication,
>>>>> but provider gives 480. I can see it in a dump of SIP session. But
>>>>> my failure_route still thinking that reply code is 401 on second
>>>>> reply. Maybe because i dont understand well how branches concept
>>>>> work here? Or using kamailio 3.0? ;) Looks like it give me status
>>>>> code of first reply and ignoring actual code in reply. :( I don't
>>>>> know if it something with development version or my own
>>>>> misunderstanding. sorry
>>>>
>>>> This is correct, the proxy must choose one of the two responses to
>>>> forward and 401 has higher precedence than 480 (RFC3261, 16.7:
>>>> "Choosing the best response"). The failure route always works on the
>>>> selected response as opposed to the last response received.
>>> I think this is wrong imo, if I got it right from your email, because
>>> the failure route should work on a selected reply from the last set
>>> of branches in serial forking.
>>>
>>> Do you say that if I get 301 with couple of contacts, then in failure
>>> route I create new branches, relay, all failed because of timeout
>>> and/or busy, I get back in failure route with the 301?
>>
>> yes.
>>
>>>
>>> I cannot drop all replies because maybe the reply I want to be sent
>>> back to caller is from a previous branch. Think at:
>>>
>>> A calls B
>>> B phone gives busy
>>> B has redirect to C in such case
>>> C phone gives timeout
>>> C has now redirect to voice mail
>>> Voice mail returns server failure
>>>
>>> If I need to drop the replies then I will send the 500 reply which is
>>> wrong. If I do no drop replies, then it is hard to implement the
>>> proper logic for different kinds of redirects:
>>> - no answer
>>> - busy
>>
>> Yes, the above case is quite complicated, by default I think the 408
>> will be sent back because it is the lowest response code.
>>
>> The priority list is: 6xx > 3xx > 4xx > 5xx.
>> The lowest response wins within the class but 401, 407, 415, 420, 484
>> are preferred over other 4xx responses.
> also 487 (request canceled) has the highest priority.
>
>
>>
>> If this is an issue then we can implement more sophisticated drop
>> commands that drop only selected branches, for example a single branch
>> that is being processed in failure route.
>
> It just looks a bit unpredictable right now, mainly with what happens in
> failure route because the reply code presented there is not what is
> expected. So I would add a parameter:
>
> t_drop_replies("all");
> t_drop_replies("last");
>
This sounds good!
> It is not hard to implement at all. In SR is a flag to mark the start of
> last set of branches -- so getting the first branch in the last step
> would be:
>
> for(first_branch=t->nr_of_outgoings-1; first_branch>=0; first_branch--)
> if(t->uac[first_branch].flags&TM_UAC_FLAG_FB)
> break;
>
t_drop_replies("last") may be a bit confusing if it is called from
failure route, imagine the following case:
1. A calls B
2. B does not answer -> 408
3. B has redirect to C
4. C is busy -> 486
5. reply route is executed with the lowest response code received that
is 408 in this case.
If t_drop_replies("last") is called in 5) then it will drop the 486
although 408 is being processed. This means that it is hard to check in
5) whether to call t_drop_replies("last") because all the conditions
work on the 408. So "last" means the last branches not the last
processed by failure route.
Anyway, this may be a corner case, and it is still better than we
currently have. It may also make sense to drop a reply from reply_route
because the status code of the reply can be checked without being
affected by the other replies. Something like t_drop_replies("current")
> But I would do it opposite, to have script simpler (and be K compatible
> and have uac_redirect and other k modules work as expected :-) ),
> instead of drop function, have drop by default the replies from last set
> of branches, and then t_keep_replies() so one ca decide to keep the
> replies. Probably can be switched one way or another (K or S) but config
> compatibility mode.
I am fine with this of course, we just need to have the drop capability
in one or another way.
Thanks,
Miklos
>
> Cheers,
> Daniel
>
>>
>> Miklos
>>
>>>
>>> Cheers,
>>> Daniel
>>>
>>>>
>>>> Try to add t_drop_replies() to the failure route block when the 401
>>>> is processed. This function drops all the existing replies, 401 in
>>>> your case, hence 401 will not be selected again when 480 is received.
>>>
>
More information about the sr-dev
mailing list