I have one Kamailio that makes an outbound register on two Asterisk.
I have a dispatcher with that same two Asterisk destinations, on INVITE
message I call replace_from("", ) in order
to call a internal extension and on failure route I receive 401 and call
the process of authorization is OK.
The problem is that if the first Asterisk fail and I get 500 on
failure route I can not call replace_from() because
is not valid on the block.
Is there any way to make this type of authorization process after receiving
a 500 on failure route of dispatcher ?
Below my cfg file.
Thanks in advance.
Antonio Couto
#!KAMAILIO#!ifdef WITH_DEBUG#!define DBGLEVEL 3#!else#!define DBGLEVEL 2#!endif
# - flags# FLT_ - per transaction (message) flags# FLB_ - per branch
flags#!define FLT_ACC 1#!define FLT_ACCMISSED 2#!define FLT_ACCFAILED
3#!define FLT_NATS 5
#!define FLB_NATB 6#!define FLB_NATSIPPING 7
####### Global Parameters #########
/* LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR, ... */
debug=DBGLEVEL
/* set to 'yes' to print log messages to terminal or use '-E' cli
option */log_stderror=no
memdbg=5
memlog=5
log_facility=LOG_LOCAL0log_prefix="{$mt $hdr(CSeq) $ci} "
children=8
auto_aliases=noenable_tls=noenable_sctp=no
tcp_accept_no_cl=yes
# SIP port
listen=udp:192.168.0.201:5060# xhttp port
listen=tcp:127.0.0.1:8181
loadmodule "xhttp.so"
loadmodule "jsonrpcs.so"
loadmodule "kex.so"
loadmodule "corex.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "acc.so"
loadmodule "dispatcher.so"
loadmodule "htable.so"
loadmodule "db_text.so"
loadmodule "dialog.so"
loadmodule "uac.so"
# ----------------- setting module-specific parameters ---------------
# ----- jsonrpcs params -----
modparam("jsonrpcs", "pretty_format", 1)
modparam("jsonrpcs", "transport", 1)
# ----- sanity params -----
modparam("sanity", "autodrop", 0)
# ----- tm params -----# default retransmission timeout: 2sec
modparam("tm", "fr_timer", 1500)# default invite retransmission
timeout after 1xx: 40sec
modparam("tm", "fr_inv_timer", 40000)
# ----- rr params -----# set next param to 1 to add value to ;lr param
(helps with some UAs)
modparam("rr", "enable_full_lr", 0)
modparam("rr", "append_fromtag", 1)
# account triggers (flags)
modparam("acc", "log_flag", FLT_ACC)
modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)
modparam("acc", "log_extra",
"src_user=$fU;src_domain=$fd;src_ip=$si;"
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
# ----- dispatcher params -----
modparam("dispatcher", "list_file",
"/etc/kamailio/dispatcher.list")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "xavp_dst", "_dsdst_")
modparam("dispatcher", "xavp_ctx", "_dsctx_")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_from",
"sip:proxy@kamailio.org")
modparam("dispatcher", "ds_ping_interval", 1)
modparam("dispatcher", "ds_probing_mode", 1)
modparam("dispatcher", "ds_probing_threshold", 1)
modparam("dispatcher", "ds_inactive_threshold", 1)
modparam("dispatcher", "ds_timer_mode", 1)
modparam("db_text", "db_mode", 1)
modparam("db_text", "emptystring", 1)
modparam("dialog", "dlg_flag", 4)
modparam("dialog", "track_cseq_updates", 1)
modparam("uac", "restore_dlg", 1)
modparam("uac", "reg_db_url",
"text:///etc/kamailio/dbtext")
modparam("uac", "reg_db_table", "uacreg")
modparam("uac", "reg_timer_interval", 60)
modparam("uac", "reg_retry_interval", 60)
modparam("uac", "reg_contact_addr", "192.168.0.201:5060")
modparam("uac","auth_username_avp","$avp(auser)")
modparam("uac","auth_password_avp","$avp(apass)")
modparam("uac","auth_realm_avp","$avp(arealm)")
####### Routing Logic ########
# main request routing logic
request_route {
# per request initial checks
route(REQINIT);
# CANCEL processing
if (is_method("CANCEL")) {
if (t_check_trans()) {
route(RELAY);
}
exit;
}
# handle retransmissions
if (!is_method("ACK")) {
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
}
# handle requests within SIP dialogs
route(WITHINDLG);
# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE")) {
record_route();
}
# account only INVITEs
if (is_method("INVITE")) {
setflag(FLT_ACC); # do accounting
}
if ($rU==$null) {
# request with no Username in RURI
sl_send_reply("484","Address Incomplete");
exit;
}
# dispatch destinations
if (is_method("INVITE")) {
route(DISPATCH);
}
else {
sl_send_reply("501","Not Implemented");
exit;
}
}
# Dispatch requests
route[DISPATCH] {
if ($si == "192.168.0.44" and $sp == 5060) {
xlog("L_ALERT","from switch $si:$sp)\n");
$var(groupid) = "2";
}
else{
xlog("L_ALERT","from others $si:$sp)\n");
$var(groupid) = "1";
}
if(!ds_select_dst($var(groupid), "11")) {
send_reply("503", "Service Unavailable");
exit;
}
if ($du =~ "192.168.0.210") {
xlog("L_ALERT", "SCRIPT: uac_replace_from\n");
uac_replace_from("", "sip:4000@192.168.0.201:5060");
}
xlog("L_ALERT", "SCRIPT: going to <$ru> via <$du> (attrs:
$xavp(_dsdst_=>attrs))\n");
t_on_failure("RTF_DISPATCH");
route(RELAY);
exit;
}
failure_route[RTF_DISPATCH] {
$var(ts) = t_get_status_code();
xlog("L_ALERT","ALERT: failure_route[RTF_DISPATCH]] from $si:$rp
status:$var(ts)\n");
if (t_is_canceled()) {
exit;
}
if(t_check_status("401|407")) {
$avp(auser) = "4000";
$avp(apass) = "1234";
$avp(arealm) = "asterisk";
if (uac_auth()) {
route(RELAY);
}
exit;
}
if (t_check_status("500") or (t_branch_timeout() and !t_branch_replied())) {
if (ds_next_dst()) {
xlog("L_ALERT", "retrying to <$ru> via <$du> (attrs:
$xavp(_dsdst_=>attrs))\n");
t_on_failure("RTF_DISPATCH");
route(RELAY);
exit;
}
}
}
# Per SIP request initial checks
route[REQINIT] {
if($ua =~ "friendly|scanner|sipcli|sipvicious|VaxSIPUserAgent") {
# silent drop for scanners - uncomment next line if want to reply
# sl_send_reply("200", "OK");
exit;
}
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483","Too Many Hops");
exit;
}
if(is_method("OPTIONS") && uri==myself && $rU==$null) {
sl_send_reply("200","Keepalive");
exit;
}
if(!sanity_check("17895", "7")) {
xlog("Malformed SIP request from $si:$sp\n");
exit;
}
}
# Handle requests within SIP dialogs
route[WITHINDLG] {
if (!has_totag()) {
return;
}
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route()) {
if (is_method("BYE")) {
setflag(FLT_ACC); # do accounting ...
setflag(FLT_ACCFAILED); # ... even if the transaction fails
}
route(RELAY);
exit;
}
if (is_method("ACK")) {
if (t_check_trans()) {
# no loose-route, but stateful ACK;
# must be an ACK after a 487
# or e.g. 404 from upstream server
route(RELAY);
exit;
} else {
# ACK without matching transaction ... ignore and discard
exit;
}
}
sl_send_reply("500","Server Internal Error");
exit;
}
# Wrapper for relaying requests
route[RELAY] {
# enable additional event routes for forwarded requests
# - serial forking, RTP relaying handling, a.s.o.
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}
if (is_method("INVITE|SUBSCRIBE|UPDATE")) {
if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY");
}
if (is_method("INVITE")) {
if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE");
}
if (!t_relay()) {
sl_reply_error();
}
exit;
}
# jsonrpc dispatch
event_route[xhttp:request] {
if ($hu =~ "^/RPC") {
jsonrpc_dispatch();
}
else {
xhttp_reply("200", "OK", "text/html",
"<html><body>Wrong URL $hu</body></html>");
}
}