Hmmm...
Thank you very much for support
I use
subst('/^From:(.*)sip:[^@]*@[a-zA-Z0-9\.]+(.*)$/From:\1sip:$avp(i:21)@$avp(i:24)\2/i');
now replace work strange i can see first time it said correct to:
From: <sip:andres.moya4@sipdiscount.com;transport=UDP>;tag=19790648.
for both - first INVITE and second with auth header
Second time i am sending to provider:
From:
<sip:andres.moya4@sipdiscount.com;transport=UDP>;tag=19790648.From:
<sip:21100036838@terrasip.net;transport=UDP>;tag=19790648.
and then with auth header:
From: <sip:andres.moya4@sipdiscount.com;transport=UDP>;tag=19790648.
something is wrong again :(
You can see i used flags to split first subst call from second one.
Second time it is not doing substitution, it is adding to From header
:) But then looks like uac_auth removes one :)
I don't care to restore From field, i need it just work.
uac_replace_from do nothing then caller in failure_route via sub route
second time. maybe it set From for first branch?
I want it go on list of providers and authenticate then asked.
I have branch_route, i tried to arm t_on_branch , but xlog in this route
never write anything in log. I don't know how to use branches. I just
know that if i want to call t_relay(), i should always say -
append_branch() ;) Any one can explain briefly how branches supposed to
work? Especially how to use branch_route. I feel i am nearly there. I
guess author of auc module can maybe be interested to add loading of
authentication data from database.
my number is sip:andres.moya@riki.ru (not email), anyone welcome to
call... testing
ok my logic is
if (number PSTN) {
route (PSTN_RELAY);
}
route[PSTN_RELAY]{
do first stage cr_route.....
route(LOAD_AUTH);
t_relay();
}
##### 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","LOAD_AUTH: searching authentication for host host:
$rd");
$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","LOAD_AUTH: for $rd loaded data user: $avp(i:21)
pass: $avp(i:22) realm: $avp(i:23) domain: $avp(i:24)");
# replace from_user@from_domain
xlog("L_INFO","LOAD_AUTH: changing From: ->
sip:$avp(i:21)@$avp(i:24)");
#uac_replace_from("sip:$avp(i:21)@$avp(i:24)");
#uac_replace_from doesnt work in failure route.
if (!isflagset(30)) {
subst('/^From:(.*)sip:[^@]*@[a-zA-Z0-9\.]+(.*)$/From:\1sip:$avp(i:21)@$avp(i:24)\2/i');
} else {
subst('/^From:(.*)sip:[^@]*@[a-zA-Z0-9\.]+(.*)$/From:\1sip:$avp(i:21)@$avp(i:24)\2/i');
}
setflag(30);
}
# 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 not
sent yet
xlog("L_INFO","LOAD_AUTH: flag 10 reset and Authorization header
clered. returning\n");
return(1);
}
failure_route[FAIL_ONE] {
xlog("L_INFO","entering failure route with code: $T_reply_code \n");
#if (t_grep_status("415")) xlog("L_INFO","415! \n");
if ( t_check_status("401|407") ) # Unathorised reply
{ xlog("L_INFO","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
xlog ("L_INFO","for $rd using: $avp(i:21) pass: $avp(i:22) realm:
$avp(i:23) domain: $avp(i:24)");
remove_hf("Authorization"); # remove client authentication
if (uac_auth()) # adding auth header
{xlog ("\nMessage:\n$mb\n\n");
xlog("L_INFO","Authorization header set, sending...\n");
# mark that auth was performed
setflag(10);
# next time i want t_check_status look at some other errstatus
t_drop_replies();
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("415|480|408|5[0-9][0-9]")) {
if ( isflagset(11) && t_check_status("415|480|408|5[0-9][0-9]")) {
# next time i want t_check_status look at some other errstatus
t_drop_replies();
xlog("L_INFO", "FAIL_ONE: got code $T_reply_code will try next
carrier domain\n");
revert_uri();
if (!cr_next_domain("$avp(s:carrier)", "$avp(s:domain)",
"$avp(s:rc_pstn_num)",
"$avp(s:rc_host)", "$T_reply_code",
"$avp(s:domain)")) {
xlog("L_ERR", "cr_next_domain failed\n");
exit;
}
if (!cr_route("$avp(s:carrier)", "$avp(s:domain)",
"$avp(s:rc_pstn_num)", "$avp(s:rc_pstn_num)",
"call_id")) {
xlog("L_ERR", "cr_route failed\n");
exit;
}
route(LOAD_AUTH);
xlog("L_INFO", "FAIL_ONE: done LOAD_AUTH, relaying to next
provider: $rd\n");
t_on_failure("FAIL_ONE");
append_branch();
if (!t_relay()) {
xlog("L_ERR", "t_relay to $rd failed\n");
exit;
}
exit;
}
#!ifdef WITH_NAT
if (is_method("INVITE")
&& (isbflagset("6") || isflagset(5))) {
unforce_rtp_proxy();
}
#!endif
if (t_is_canceled()) {
exit;
}
t_reply("404","Not found");
}
Miklos Tirpak wrote:
[please keep the list CC-d because others may also be
interested in
the solution or may know the answer better.]
On 11/20/2009 07:06 PM, Andres Moya wrote:
Can i ask one more question here. It is
complicated, i am using
uac_replace_from and uac_auth.
I am using failure route to process authentication if necessary and
redirect on next carrier.
If i authenticated with one provider, then fot let say 415 ( i set
only speex in UAC to get it ;) ). Ok SER send request to second
provider, i use
uac_replace_from once again in my LOAD_AUTH route
then uac_auth again.
Ok. now i see from ngrep that uac_replace_from did nothing in from
field and use user@domain for first provider, authentication failed :(
Which authentication fails? The first or the second one?
The first should work, at least the from header should be rewritten by
the function.
The second authentication will not work this way (if it requires a
different from header) because the proxy "remembers" for the header
changes done before the first t_relay() function call and applies the
same header modifications also for any other branch added from failure
route. Hence, the outgoing SIP request to the second provider will
contain the same from HF as the request to the first provider.
The easiest way is to apply the header modifications in branch route
if you do not need to reuse them later from failure route.
Modifications done in branch routes are valid only within that branch.
I moved uac_replace_from to my failure route to call once again
before uac_auth, but got config error as i can't use uac_replace_from
in failure_route.
I think you already use this function from failure route because it is
in a route block that is included from failure route. The only
difference is that the syntax checker does not recognize the issue. I
am not familiar with uac_replace_from() but after having a quick look
at the function I think it is safe to use it from here.
Ok i will use textops to rewrite, but it is ugly?
The main difference is that uac_replace_from() restores the original
From HF when the response if forwarded. If you use textops module then
you need to restore the header manually.
no. Maybe i should call uac_replace_from in
branch route?
I would suggest this way. Both for the first and for the second provider.
Miklos
>
> Thanks