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(a)lists.sip-router.org
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev