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
route[PSTN_RELAY] { # open trans or it will complain on uac_replace_from if (!t_check_trans()) t_newtran();
#!ifdef WITH_NAT if (check_route_param("nat=yes")) { setbflag("6"); } if (isflagset(5) || isbflagset("6")) { route(RTPPROXY); } #!endif
cr_user_carrier("$fU", "$fd", "$avp(s:carrier)");
xlog ("L_INFO","carrier $avp(s:carrier) selected for $fU at $fd\n"); $avp(s:domain)="route_domain1"; if( !cr_route("$avp(s:carrier)", "$avp(s:domain)", "$rU", "$rU", "call_id") ){ sl_send_reply("403", "Not allowed"); xlog ("cr_route failed for $rU from $fU@$fd\n"); t_release(); exit; }
#loading auth information for $rd (ruri domain) and replace "From" header route (LOAD_AUTH);
xlog ("L_INFO","relaying to $rd\n");
#reducing size to fit MTU remove_hf("User-Agent"); remove_hf("P-Preferred-Identity"); remove_hf("Record-route"); remove_hf("a=nortpproxy");
# setflag(11); # so failroute can procees carrierroute backup # we do all in one failure block; t_on_failure("FAIL_ONE");
if (!t_relay()) { sl_reply_error(); }
exit;
}
##### LOAD_AUTH ########## # loading authentication information from carrierauth table # set From field according to carrierauth information # arguments: # $rd - request uri doamin, sip provider carrier # returns: # avp(i:20) - rewrited host = $rd # avp(i:21) - auth user # avp(i:22) - auth pass # avp(i:23) - auth realm # avp(i:24) - auth domain
route[LOAD_AUTH]{ xlog ("L_INFO","searching authentication for $rd host"); $avp(i:20)=$rd;
if ( avp_db_query( "SELECT username, password, realm, domain FROM carrierauth WHERE hostname='$rd'", "$avp(i:21);$avp(i:22);$avp(i:23);$avp(i:24)") > 0 ) { xlog ("L_INFO"," for $rd got user: $avp(i:21) pass: $avp(i:22) realm: $avp(i:23) domain: $avp(i:24)");
# replace from_user@from_domain xlog("L_INFO","changing from -> sip:$avp(i:21)@$avp(i:24)"); uac_replace_from("sip:$avp(i:21)@$avp(i:24)"); }
# we are not relaying authentications :) remove_hf("Authorization"); # remove client authentication
# reset flag to mark no authentication yet performed resetflag(10); # let's use 10 to know uac authentication was sent
return(1);
}
failure_route[FAIL_ONE] { xlog("L_INFO","failure reply: $T_rpl($rr) $T_rpl($rs) $T_reply_code $branch(count) $rb\n"); ####### ####### Here is a problem. Error code $T_reply_code is always 401 even for second time... I have 480 on ngrep #######
if ( t_check_status("401|407") ) # Unathorised reply { xlog("Authentication required \n"); # have we already tried to authenticate? do we have auth information loaded? if (isflagset(10) || $avp(i:21)==$null ) # auth was already sent or we don't have auth info { xlog("Authentication to $avp(i:20) provider as $avp(i:21)@$avp(i:24) failed\n"); t_reply("503","Authentication failed"); avp_delete("$avp(i:20)"); avp_delete("$avp(i:21)"); avp_delete("$avp(i:22)"); avp_delete("$avp(i:23)"); avp_delete("$avp(i:24)"); exit(); # :(
}
# if call from here LOAD_AUTH will look for original uri, not rewriten before if( !is_avp_set("$avp(i:20)") || $avp(i:20)=='') # if LAOD_AUTH was not done yet route (LOAD_AUTH); # loads auth avps and rewrite 'from' field
# this avps loaded before by LOAD_AUTH # avp(i:20) - rewrited host # avp(i:21) - auth user # avp(i:22) - auth pass # avp(i:23) - auth realm # avp(i:24) - auth domain
remove_hf("Authorization"); # remove client authentication if (uac_auth()) # adding auth header { xlog("L_INFO","Authorization header set, sending..."); # mark that auth was performed setflag(10); # trigger again the failure route t_on_failure("FAIL_ONE"); # repeat the request with auth response this time append_branch(); # ? t_relay(); exit; } }
# In case of failure on PSTN provider, send it to an alternative route: if ( t_check_status("408|5[0-9][0-9]")) { # if ( isflagset(11) && t_check_status("408|5[0-9][0-9]")) {
revert_uri(); if (!cr_next_domain("$avp(s:carrier)", "$avp(s:domain)", "$rU", "$rd", "$T_reply_code", "$avp(s:domain)")) { xlog("L_ERR", "cr_next_domain failed\n"); exit; } if (!cr_route("$avp(s:carrier)", "$avp(s:domain)", "$rU", "$rU", "call_id")) { xlog("L_ERR", "cr_route failed\n"); exit; }
route(LOAD_AUTH);
t_on_failure("FAIL_ONE"); append_branch(); if (!t_relay()) { xlog("L_ERR", "t_relay to $rd failed\n"); exit; }
}
#!ifdef WITH_NAT if (is_method("INVITE") && (isbflagset("6") || isflagset(5))) { unforce_rtp_proxy(); } #!endif
if (t_is_canceled()) { exit; }
# uncomment the following lines if you want to block client # redirect based on 3xx replies. ##if (t_check_status("3[0-9][0-9]")) { ##t_reply("404","Not found"); ## exit; ##}
# uncomment the following lines if you want to redirect the failed # calls to a different new destination ##if (t_check_status("486|408")) { ## sethostport("192.168.2.100:5060"); ## append_branch(); ## # do not set the missed call flag again ## t_relay(); ##} }
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.
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.
Miklos
route[PSTN_RELAY] { # open trans or it will complain on uac_replace_from if (!t_check_trans()) t_newtran();
#!ifdef WITH_NAT if (check_route_param("nat=yes")) { setbflag("6"); } if (isflagset(5) || isbflagset("6")) { route(RTPPROXY); } #!endif
cr_user_carrier("$fU", "$fd", "$avp(s:carrier)");
xlog ("L_INFO","carrier $avp(s:carrier) selected for $fU at $fd\n"); $avp(s:domain)="route_domain1"; if( !cr_route("$avp(s:carrier)", "$avp(s:domain)", "$rU", "$rU", "call_id") ){ sl_send_reply("403", "Not allowed"); xlog ("cr_route failed for $rU from $fU@$fd\n"); t_release(); exit; }
#loading auth information for $rd (ruri domain) and replace "From" header route (LOAD_AUTH);
xlog ("L_INFO","relaying to $rd\n");
#reducing size to fit MTU remove_hf("User-Agent"); remove_hf("P-Preferred-Identity"); remove_hf("Record-route"); remove_hf("a=nortpproxy");
# setflag(11); # so failroute can procees carrierroute backup # we do all in one failure block; t_on_failure("FAIL_ONE");
if (!t_relay()) { sl_reply_error(); } exit;
}
##### LOAD_AUTH ########## # loading authentication information from carrierauth table # set From field according to carrierauth information # arguments: # $rd - request uri doamin, sip provider carrier # returns: # avp(i:20) - rewrited host = $rd # avp(i:21) - auth user # avp(i:22) - auth pass # avp(i:23) - auth realm # avp(i:24) - auth domain
route[LOAD_AUTH]{ xlog ("L_INFO","searching authentication for $rd host"); $avp(i:20)=$rd;
if ( avp_db_query( "SELECT username, password, realm, domain FROM carrierauth WHERE hostname='$rd'", "$avp(i:21);$avp(i:22);$avp(i:23);$avp(i:24)") > 0 ) { xlog ("L_INFO"," for $rd got user: $avp(i:21) pass: $avp(i:22) realm: $avp(i:23) domain: $avp(i:24)");
# replace from_user@from_domain xlog("L_INFO","changing from -> sip:$avp(i:21)@$avp(i:24)"); uac_replace_from("sip:$avp(i:21)@$avp(i:24)");
}
# we are not relaying authentications :) remove_hf("Authorization"); # remove client authentication
# reset flag to mark no authentication yet performed resetflag(10); # let's use 10 to know uac authentication was sent
return(1);
}
failure_route[FAIL_ONE] { xlog("L_INFO","failure reply: $T_rpl($rr) $T_rpl($rs) $T_reply_code $branch(count) $rb\n"); ####### ####### Here is a problem. Error code $T_reply_code is always 401 even for second time... I have 480 on ngrep #######
if ( t_check_status("401|407") ) # Unathorised reply { xlog("Authentication required \n"); # have we already tried to authenticate? do we have auth information loaded? if (isflagset(10) || $avp(i:21)==$null ) # auth was already sent or we don't have auth info { xlog("Authentication to $avp(i:20) provider as $avp(i:21)@$avp(i:24) failed\n"); t_reply("503","Authentication failed"); avp_delete("$avp(i:20)"); avp_delete("$avp(i:21)"); avp_delete("$avp(i:22)"); avp_delete("$avp(i:23)"); avp_delete("$avp(i:24)"); exit(); # :(
} # if call from here LOAD_AUTH will look for original uri, not
rewriten before if( !is_avp_set("$avp(i:20)") || $avp(i:20)=='') # if LAOD_AUTH was not done yet route (LOAD_AUTH); # loads auth avps and rewrite 'from' field
# this avps loaded before by LOAD_AUTH # avp(i:20) - rewrited host # avp(i:21) - auth user # avp(i:22) - auth pass # avp(i:23) - auth realm # avp(i:24) - auth domain remove_hf("Authorization"); # remove client authentication if (uac_auth()) # adding auth header { xlog("L_INFO","Authorization header set, sending..."); # mark that auth was performed setflag(10); # trigger again the failure route t_on_failure("FAIL_ONE"); # repeat the request with auth response this time append_branch(); # ? t_relay(); exit; }
}
# In case of failure on PSTN provider, send it to an alternative route: if ( t_check_status("408|5[0-9][0-9]")) { # if ( isflagset(11) && t_check_status("408|5[0-9][0-9]")) {
revert_uri(); if (!cr_next_domain("$avp(s:carrier)", "$avp(s:domain)", "$rU", "$rd", "$T_reply_code", "$avp(s:domain)")) { xlog("L_ERR", "cr_next_domain failed\n"); exit; } if (!cr_route("$avp(s:carrier)", "$avp(s:domain)", "$rU", "$rU", "call_id")) { xlog("L_ERR", "cr_route failed\n"); exit; } route(LOAD_AUTH); t_on_failure("FAIL_ONE"); append_branch(); if (!t_relay()) { xlog("L_ERR", "t_relay to $rd failed\n"); exit; }
}
#!ifdef WITH_NAT if (is_method("INVITE") && (isbflagset("6") || isflagset(5))) { unforce_rtp_proxy(); } #!endif
if (t_is_canceled()) { exit; }
# uncomment the following lines if you want to block client # redirect based on 3xx replies. ##if (t_check_status("3[0-9][0-9]")) { ##t_reply("404","Not found"); ## exit; ##}
# uncomment the following lines if you want to redirect the failed # calls to a different new destination ##if (t_check_status("486|408")) { ## sethostport("192.168.2.100:5060"); ## append_branch(); ## # do not set the missed call flag again ## t_relay(); ##} }
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
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?
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
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.
On 20.11.2009 16:38 Uhr, 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?
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.
... actually, while it might be questionable whether to select the reply to be sent back to caller from last serial forking set of branches or from entire set of branches, triggering failure route should be with a reply from last set of branches, otherwise you cannot take the right decision for new branches.
Cheers, Daniel
If I do no drop replies, then it is hard to implement the proper logic for different kinds of redirects:
- no answer
- busy
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.
Daniel-Constantin Mierla píše v Pá 20. 11. 2009 v 16:53 +0100:
On 20.11.2009 16:38 Uhr, 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?
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.
... actually, while it might be questionable whether to select the reply to be sent back to caller from last serial forking set of branches or from entire set of branches, triggering failure route should be with a reply from last set of branches, otherwise you cannot take the right decision for new branches.
If I understand correctly, then whenever you start above mentioned "new set of branches" just call t_drop_replies() and you are done.
Michal
Cheers, Daniel
If I do no drop replies, then it is hard to implement the proper logic for different kinds of redirects:
- no answer
- busy
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.
Hi,
On 11/20/2009 04:57 PM, Michal Matyska wrote:
Daniel-Constantin Mierla píše v Pá 20. 11. 2009 v 16:53 +0100:
On 20.11.2009 16:38 Uhr, 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?
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.
... actually, while it might be questionable whether to select the reply to be sent back to caller from last serial forking set of branches or from entire set of branches, triggering failure route should be with a reply from last set of branches, otherwise you cannot take the right decision for new branches.
If I understand correctly, then whenever you start above mentioned "new set of branches" just call t_drop_replies() and you are done.
yes, you can solve it this way.
Back to Daniel's example, if I was the caller then I would like to receive the 486 back so that I know that the callee is busy and I should retry the call later. This means that the 408 should be dropped, but only if there was already a branch replied with 486. Or the 408 should be given some preference from failure route. Neither of them is implemented as far as I know. On the other hand, the script can get really complicated because of these checks and drops.
Miklos
Michal
Cheers, Daniel
If I do no drop replies, then it is hard to implement the proper logic for different kinds of redirects:
- no answer
- busy
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.
On 20.11.2009 16:57 Uhr, Michal Matyska wrote:
Daniel-Constantin Mierla píše v Pá 20. 11. 2009 v 16:53 +0100:
On 20.11.2009 16:38 Uhr, 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?
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.
... actually, while it might be questionable whether to select the reply to be sent back to caller from last serial forking set of branches or from entire set of branches, triggering failure route should be with a reply from last set of branches, otherwise you cannot take the right decision for new branches.
If I understand correctly, then whenever you start above mentioned "new set of branches" just call t_drop_replies() and you are done.
i said "questionable about selection of reply to send back but not about what code is presented to failure route". So yes, if I want only from last set of branches, it is ok what you say. But if not, then you are screwed up with serial forking logic.
the t_drop_replies() drops all branches, even there were two or more serial forking steps, not the replies from the last set of branches -- I checked the code. It just not look coherent.
Cheers, Daniel
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.
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.
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.
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");
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;
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.
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.
On 20.11.2009 17:32 Uhr, 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");
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;
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.
errata: by config compatibility mode (e.g., #!KAMAILIO and #!SER)
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.
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.