You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5339 lines
188 KiB
5339 lines
188 KiB
|
|
[% MACRO logreq_init GET kamailio.proxy.log.request_init.join(' ') -%]
|
|
[% MACRO logreq GET kamailio.proxy.log.request.join(' ') -%]
|
|
[% MACRO logres_init GET kamailio.proxy.log.response_init.join(' ') -%]
|
|
[% MACRO logres GET kamailio.proxy.log.response.join(' ') -%]
|
|
[% PROCESS '/usr/lib/ngcp-ngcpcfg/get_hostname'; hostname = out -%]
|
|
[% argv.host=hostname; argv.type='sip_int'; PROCESS '/usr/lib/ngcp-ngcpcfg/get_all_shared_ips_for_host'; sip_int_ips = out -%]
|
|
[% IF !sip_int_ips.size -%]
|
|
[% argv.host=hostname; argv.type='sip_int'; PROCESS '/usr/lib/ngcp-ngcpcfg/get_all_ips_for_host'; sip_int_ips = out -%]
|
|
[% END -%]
|
|
[% argv.role='lb'; argv.type='sip_ext'; PROCESS '/usr/lib/ngcp-ngcpcfg/get_all_shared_ips'; sip_ext_ips = out -%]
|
|
[% IF !sip_ext_ips.size -%]
|
|
[% argv.role='lb'; argv.type='sip_ext'; PROCESS '/usr/lib/ngcp-ngcpcfg/get_all_ips'; sip_ext_ips = out -%]
|
|
[% END -%]
|
|
[% argv.role='lb'; argv.type='sip_int'; PROCESS '/usr/lib/ngcp-ngcpcfg/get_all_shared_ips'; sip_lb_ips = out -%]
|
|
[% IF !sip_lb_ips.size -%]
|
|
[% argv.role='lb'; argv.type='sip_int'; PROCESS '/usr/lib/ngcp-ngcpcfg/get_all_ips'; sip_lb_ips = out -%]
|
|
[% END -%]
|
|
#TODO: FLAG_FORWARD, FLAG_EXT_TIMEOUT: vars correctly set?
|
|
|
|
########################################################################
|
|
# Entry route for new request
|
|
########################################################################
|
|
route[ROUTE_PRX_REQUEST]
|
|
{
|
|
$var(proxylu_src) = 0;
|
|
$var(proxylu_dst_caller) = 0;
|
|
$var(proxylu_dst_callee) = 0;
|
|
#!ifdef PROXY_LOOKUP
|
|
route(ROUTE_FIX_PROXYLU_URI);
|
|
#!endif
|
|
|
|
if($avp(s:nat) == 1)
|
|
{
|
|
setbflag(FLB_NATB);
|
|
}
|
|
if($avp(s:af) == 6)
|
|
{
|
|
setbflag(FLB_CALLER_IPV6);
|
|
}
|
|
|
|
if(is_method("CANCEL") && t_check_trans())
|
|
{
|
|
route(ROUTE_STOP_RTPPROXY_BRANCH);
|
|
}
|
|
else if(is_method("BYE"))
|
|
{
|
|
route(ROUTE_STOP_RTPPROXY);
|
|
}
|
|
|
|
#!ifdef AUTH_BYE
|
|
if(is_method("BYE"))
|
|
{
|
|
if(!from_any_gw($avp(s:ip), $avp(s:protoid)) && !ds_is_from_list("3"))
|
|
{
|
|
route(ROUTE_AUTH);
|
|
#!ifdef ENABLE_AUTHCHECK
|
|
sl_send_reply("101", "Connecting");
|
|
#!endif
|
|
}
|
|
}
|
|
#!endif
|
|
|
|
|
|
# these need to be avps because we need it in reply/failure-route
|
|
$(avp(s:from_faxserver)[*]) = 0;
|
|
$(avp(s:to_faxserver)[*]) = 0;
|
|
$(avp(s:cf_from_pstn)[*]) = 0;
|
|
$(avp(s:from_pstn)[*]) = 0;
|
|
$(avp(s:em_call)[*]) = 0;
|
|
|
|
# need to initialise variables in failure route as well
|
|
$var(loose_routed) = 0;
|
|
$var(no_acc) = 0;
|
|
$var(no_auth) = 0;
|
|
$var(forward) = 0;
|
|
$var(redirected_forward) = 0;
|
|
$var(external_domain) = 0;
|
|
$var(ext_timeout) = 0;
|
|
$var(noauth) = 0;
|
|
$var(from_trusted) = 0;
|
|
$var(to_pstn) = 0;
|
|
$var(reset_acc_callee) = 0;
|
|
$var(no_sbc) = 0;
|
|
$var(sendfax) = 0;
|
|
$var(local_endpoint) = 0;
|
|
$var(cf_loop) = 0;
|
|
$var(rtpp_flags) = 0;
|
|
$var(ice_flags) = 0;
|
|
$var(foreign_dom) = 0;
|
|
|
|
$(avp(s:initial_caller_ipv46_for_rtpproxy)[*]) = $null;
|
|
|
|
if(loose_route())
|
|
{
|
|
record_route();
|
|
if(check_route_param("rtpprx=yes"))
|
|
{
|
|
# force rtpproxy
|
|
setbflag(FLB_RTPPROXY);
|
|
add_rr_param(";rtpprx=yes");
|
|
}
|
|
if(!has_totag())
|
|
{
|
|
if($du != $null && is_domain_local("$dd"))
|
|
{
|
|
xlog("L_INFO", "Reset initial local route - [% logreq -%]\n");
|
|
$du = $null;
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Initial loose-routing rejected - [% logreq -%]\n");
|
|
sl_send_reply("403", "Initial Loose-Routing Forbidden");
|
|
exit;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# Work around sems-sbc sending a Route header
|
|
# also for non-200 ACK.
|
|
if(is_method("ACK") && $oU == "proxylu_callee")
|
|
{
|
|
xlog("L_INFO", "Trying to consume proxylu ACK - [% logreq -%]\n");
|
|
t_check_trans();
|
|
|
|
xlog("L_INFO", "Drop misrouted proxylu ACK - [% logreq -%]\n");
|
|
exit;
|
|
}
|
|
else if(is_method("BYE"))
|
|
{
|
|
setflag(FLAG_ACC_FAILED);
|
|
setflag(FLAG_ACC_DB);
|
|
}
|
|
if(is_direction("downstream"))
|
|
{
|
|
setflag(FLAG_DOWNSTREAM);
|
|
}
|
|
else
|
|
{
|
|
setflag(FLAG_UPSTREAM);
|
|
}
|
|
if(has_body("application/sdp") && isbflagset(FLB_RTPPROXY))
|
|
{
|
|
if(isflagset(FLAG_DOWNSTREAM))
|
|
{ #same direction as original dialog-forming request
|
|
if(check_route_param("ice_callee=replace"))
|
|
{
|
|
xlog("L_INFO", "Replace existing ICE candidates (if any) for callee with mediaproxy ICE canditate - [% logreq -%]\n");
|
|
$var(ice_flags) = "+";
|
|
add_rr_param(";ice_callee=replace");
|
|
setbflag(FLB_ICE_CALLEE_REPLACE);
|
|
}
|
|
else if(check_route_param("ice_callee=strip"))
|
|
{
|
|
xlog("L_INFO", "Remove existing ICE candidates (if any) for callee - [% logreq -%]\n");
|
|
$var(ice_flags) = "-";
|
|
add_rr_param(";ice_callee=strip");
|
|
setbflag(FLB_ICE_CALLEE_STRIP);
|
|
}
|
|
else if(check_route_param("ice_callee=add"))
|
|
{
|
|
xlog("L_INFO", "Add mediaproxy as ICE candidate for callee - [% logreq -%]\n");
|
|
add_rr_param(";ice_callee=add");
|
|
setbflag(FLB_ICE_CALLEE_ADD);
|
|
}
|
|
# Set caller flags for use in onreply_route later
|
|
if(check_route_param("ice_caller=replace"))
|
|
{
|
|
add_rr_param(";ice_caller=replace");
|
|
setbflag(FLB_ICE_CALLER_REPLACE);
|
|
}
|
|
else if(check_route_param("ice_caller=strip"))
|
|
{
|
|
add_rr_param(";ice_caller=strip");
|
|
setbflag(FLB_ICE_CALLER_STRIP);
|
|
}
|
|
else if(check_route_param("ice_caller=add"))
|
|
{
|
|
add_rr_param(";ice_caller=add");
|
|
setbflag(FLB_ICE_CALLER_ADD);
|
|
}
|
|
}
|
|
else if(isflagset(FLAG_UPSTREAM))
|
|
{ #opposite direction to original dialog-forming request
|
|
if(check_route_param("ice_caller=replace"))
|
|
{
|
|
xlog("L_INFO", "Replace existing ICE candidates (if any) for caller with mediaproxy ICE canditate - [% logreq -%]\n");
|
|
$var(ice_flags) = "+";
|
|
add_rr_param(";ice_caller=replace");
|
|
setbflag(FLB_ICE_CALLER_REPLACE);
|
|
}
|
|
else if(check_route_param("ice_caller=strip"))
|
|
{
|
|
xlog("L_INFO", "Remove existing ICE candidates (if any) for caller - [% logreq -%]\n");
|
|
$var(ice_flags) = "-";
|
|
add_rr_param(";ice_caller=strip");
|
|
setbflag(FLB_ICE_CALLER_STRIP);
|
|
}
|
|
else if(check_route_param("ice_caller=add"))
|
|
{
|
|
xlog("L_INFO", "Add mediaproxy as ICE candidate for caller - [% logreq -%]\n");
|
|
add_rr_param(";ice_caller=add");
|
|
setbflag(FLB_ICE_CALLER_ADD);
|
|
}
|
|
# Set callee flags for use in onreply_route later
|
|
if(check_route_param("ice_callee=replace"))
|
|
{
|
|
add_rr_param(";ice_callee=replace");
|
|
setbflag(FLB_ICE_CALLEE_REPLACE);
|
|
}
|
|
else if(check_route_param("ice_callee=strip"))
|
|
{
|
|
add_rr_param(";ice_callee=strip");
|
|
setbflag(FLB_ICE_CALLEE_STRIP);
|
|
}
|
|
else if(check_route_param("ice_callee=add"))
|
|
{
|
|
add_rr_param(";ice_callee=add");
|
|
setbflag(FLB_ICE_CALLEE_ADD);
|
|
}
|
|
}
|
|
if(is_method("ACK"))
|
|
{
|
|
xlog("L_INFO", "Force mediaproxy lookup for forward direction - [% logreq -%]\n");
|
|
$var(rtpp_flags) = "FRWOC1";
|
|
if($var(ice_flags) != 0)
|
|
{
|
|
$var(rtpp_flags) = $var(rtpp_flags) + $var(ice_flags);
|
|
}
|
|
rtpproxy_answer($var(rtpp_flags));
|
|
}
|
|
else
|
|
{
|
|
# always force an rtpproxy lookup in reply for a
|
|
# loose-routed request, even for ack, because there
|
|
# is no reply for that anyways
|
|
setbflag(FLB_RTPPROXY_LOOKUP);
|
|
|
|
$var(rtpp_flags) = "FRWOC";
|
|
if(check_route_param("mpd=ee"))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy for forward direction for IPv6/IPv6 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "EE1";
|
|
add_rr_param(";mpd=ee");
|
|
}
|
|
else if(check_route_param("mpd=ii"))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy for forward direction for IPv4/IPv4 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "II1";
|
|
add_rr_param(";mpd=ii");
|
|
}
|
|
else if(isflagset(FLAG_DOWNSTREAM))
|
|
{
|
|
# same direction as original request, so we can
|
|
# use the same v4/v6 mapping
|
|
if(check_route_param("mpd=ie"))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy for forward direction for IPv4/IPv6 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "IE1";
|
|
add_rr_param(";mpd=ie");
|
|
}
|
|
else if(check_route_param("mpd=ei"))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy for forward direction for IPv6/IPv4 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "EI1";
|
|
add_rr_param(";mpd=ei");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No mediaproxy direction flags for downstream re-INVITE, use mediaproxy fallback for forward direction for IPv4/IPv4 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "II1";
|
|
}
|
|
}
|
|
else if(isflagset(FLAG_UPSTREAM))
|
|
{
|
|
# switch ei/ie flags for upstream reinvite
|
|
if(check_route_param("mpd=ie"))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy for forward direction for IPv4/IPv6 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "EI1";
|
|
add_rr_param(";mpd=ie");
|
|
}
|
|
else if(check_route_param("mpd=ei"))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy for forward direction for IPv6/IPv4 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "IE1";
|
|
add_rr_param(";mpd=ei");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No mediaproxy direction flags for upstream re-INVITE, use mediaproxy fallback for forward direction for IPv4/IPv4 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "II1";
|
|
}
|
|
}
|
|
if($var(ice_flags) != 0)
|
|
{
|
|
$var(rtpp_flags) = $var(rtpp_flags) + $var(ice_flags);
|
|
}
|
|
rtpproxy_offer($var(rtpp_flags));
|
|
}
|
|
}
|
|
|
|
$var(loose_routed) = 1;
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
}
|
|
|
|
if(is_method("CANCEL|ACK"))
|
|
{
|
|
route(ROUTE_LOCAL);
|
|
}
|
|
|
|
if($fu == "sip:faxserver@sipwise.local" && ds_is_from_list("2"))
|
|
{
|
|
$var(sendfax) = 1;
|
|
}
|
|
|
|
if(is_method("INVITE"))
|
|
{
|
|
route(ROUTE_INVITE);
|
|
}
|
|
exit;
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'clear-peer-preferences-caller'
|
|
########################################################################
|
|
route[ROUTE_CLEAR_PEER_OUT_PREF]
|
|
{
|
|
xlog("L_INFO", "[LUA] Clean peer preferences for caller' - [% logreq -%]\n");
|
|
if (!lua_run("ngcp_clean", "caller", "peer")) {
|
|
sl_send_reply("500", "Internal Error");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'load-peer-preferences-caller'
|
|
########################################################################
|
|
route[ROUTE_LOAD_PEER_OUT_PREF]
|
|
{
|
|
xlog("L_INFO", "[LUA] Load peer preferences for peer host '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
if (!lua_run("ngcp_load_caller", "$avp(s:lcr_flags)")) {
|
|
sl_send_reply("500", "Internal Error");
|
|
exit;
|
|
}
|
|
xlog("L_INFO", "Load peer preferences for peer host '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
avp_db_load("$avp(s:lcr_flags)", "*/peer_preferences");
|
|
|
|
avp_copy("$avp(s:use_rtpproxy)", "$avp(s:callee_use_rtpproxy)/d");
|
|
avp_copy("$avp(s:ipv46_for_rtpproxy)", "$avp(s:peer_callee_ipv46_for_rtpproxy)/d");
|
|
|
|
avp_copy("$avp(s:outbound_socket)", "$avp(s:peer_callee_outbound_socket)/d");
|
|
|
|
if($avp(s:sst_enable) == $null)
|
|
{
|
|
$(avp(s:sst_enable)[*]) = "[% sems.sbc.session_timer.enable %]";
|
|
}
|
|
avp_copy("$avp(s:sst_enable)", "$avp(s:peer_callee_sst_enable)/d");
|
|
if($avp(s:sst_expires) == $null)
|
|
{
|
|
$(avp(s:sst_expires)[*]) = [% sems.sbc.session_timer.session_expires %];
|
|
}
|
|
avp_copy("$avp(s:sst_expires)", "$avp(s:peer_callee_sst_expires)/d");
|
|
if($avp(s:sst_min_timer) == $null)
|
|
{
|
|
$(avp(s:sst_min_timer)[*]) = [% sems.sbc.session_timer.min_timer %];
|
|
}
|
|
avp_copy("$avp(s:sst_min_timer)", "$avp(s:peer_callee_sst_min_timer)/d");
|
|
if($avp(s:sst_max_timer) == $null)
|
|
{
|
|
$(avp(s:sst_max_timer)[*]) = [% sems.sbc.session_timer.max_timer %];
|
|
}
|
|
avp_copy("$avp(s:sst_max_timer)", "$avp(s:peer_callee_sst_max_timer)/d");
|
|
if($avp(s:sst_refresh_method) == $null)
|
|
{
|
|
$(avp(s:sst_refresh_method)[*]) = "UPDATE_FALLBACK_INVITE";
|
|
}
|
|
avp_copy("$avp(s:sst_refresh_method)", "$avp(s:peer_callee_sst_refresh_method)/d");
|
|
|
|
avp_copy("$avp(s:outbound_from_user)", "$avp(s:callee_outbound_from_user)/d");
|
|
if($avp(s:callee_outbound_from_user) == $null)
|
|
{
|
|
$avp(s:callee_outbound_from_user) = "npn";
|
|
}
|
|
avp_copy("$avp(s:outbound_from_display)", "$avp(s:callee_outbound_from_display)/d");
|
|
avp_copy("$avp(s:outbound_pai_user)", "$avp(s:callee_outbound_pai_user)/d");
|
|
avp_copy("$avp(s:outbound_ppi_user)", "$avp(s:callee_outbound_ppi_user)/d");
|
|
avp_copy("$avp(s:outbound_diversion)", "$avp(s:callee_outbound_diversion)/d");
|
|
|
|
xlog("L_INFO", "Load dialplan IDs for peer host '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
avp_copy("$avp(s:rewrite_caller_out_dpid)", "$avp(s:pstn_dp_caller_out_id)/d");
|
|
avp_copy("$avp(s:rewrite_callee_out_dpid)", "$avp(s:pstn_dp_callee_out_id)/d");
|
|
avp_delete("$avp(s:rewrite_caller_in_dpid)/g");
|
|
avp_delete("$avp(s:rewrite_callee_in_dpid)/g");
|
|
xlog("L_INFO", "Fetched dialplan IDs caller_out='$avp(s:pstn_dp_caller_out_id)', callee_out='$avp(s:pstn_dp_callee_out_id)' - [% logreq -%]\n");
|
|
|
|
}
|
|
|
|
|
|
########################################################################
|
|
# Request route 'clear-peer-preferences-callee'
|
|
########################################################################
|
|
route[ROUTE_CLEAR_PEER_IN_PREF]
|
|
{
|
|
xlog("L_INFO", "[LUA] Clean peer preferences for callee' - [% logreq -%]\n");
|
|
if (!lua_run("ngcp_clean", "callee", "peer")) {
|
|
sl_send_reply("500", "Internal Error");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'load-peer-preferences-caller'
|
|
########################################################################
|
|
route[ROUTE_LOAD_PEER_IN_PREF]
|
|
{
|
|
xlog("L_INFO", "[LUA] Load peer preferences for peer host '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
if (!lua_run("ngcp_load_peer_caller", "$avp(s:lcr_flags)")) {
|
|
sl_send_reply("500", "Internal Error");
|
|
exit;
|
|
}
|
|
|
|
xlog("L_INFO", "Load peer preferences for peer host '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
avp_db_load("$avp(s:lcr_flags)", "*/peer_preferences");
|
|
|
|
avp_copy("$avp(s:peer_auth_user)", "$avp(s:peer_peer_callee_auth_user)/d");
|
|
avp_copy("$avp(s:peer_auth_pass)", "$avp(s:peer_peer_callee_auth_pass)/d");
|
|
avp_copy("$avp(s:peer_auth_realm)", "$avp(s:peer_peer_callee_auth_realm)/d");
|
|
|
|
avp_copy("$avp(s:use_rtpproxy)", "$avp(s:caller_use_rtpproxy)/d");
|
|
|
|
avp_copy("$avp(s:force_outbound_calls_to_peer)", "$avp(s:caller_force_outbound_calls_to_peer)/d");
|
|
|
|
avp_copy("$avp(s:inbound_upn)", "$avp(s:caller_inbound_upn)/d");
|
|
if($avp(s:caller_inbound_upn) == $null)
|
|
{
|
|
$(avp(s:caller_inbound_upn)[*]) = "from_user";
|
|
}
|
|
avp_copy("$avp(s:inbound_npn)", "$avp(s:caller_inbound_npn)/d");
|
|
if($avp(s:caller_inbound_npn) == $null)
|
|
{
|
|
$(avp(s:caller_inbound_npn)[*]) = "from_user";
|
|
}
|
|
avp_copy("$avp(s:inbound_uprn)", "$avp(s:caller_inbound_uprn)/d");
|
|
if($avp(s:caller_inbound_uprn) == $null)
|
|
{
|
|
$(avp(s:caller_inbound_uprn)[*]) = "from_user";
|
|
}
|
|
|
|
xlog("L_INFO", "Load dialplan IDs for peer host '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
avp_copy("$avp(s:rewrite_caller_in_dpid)", "$avp(s:pstn_dp_caller_in_id)/d");
|
|
avp_copy("$avp(s:rewrite_callee_in_dpid)", "$avp(s:pstn_dp_callee_in_id)/d");
|
|
avp_delete("$avp(s:rewrite_caller_out_dpid)/g");
|
|
avp_delete("$avp(s:rewrite_callee_out_dpid)/g");
|
|
xlog("L_INFO", "Fetched dialplan IDs caller_in='$avp(s:pstn_dp_caller_in_id)', callee_in='$avp(s:pstn_dp_callee_in_id)' - [% logreq -%]\n");
|
|
|
|
avp_copy("$avp(s:ipv46_for_rtpproxy)", "$avp(s:peer_caller_ipv46_for_rtpproxy)/d");
|
|
|
|
if($avp(s:initial_caller_ipv46_for_rtpproxy) == $null)
|
|
{
|
|
$avp(s:initial_caller_ipv46_for_rtpproxy) = $avp(s:peer_caller_ipv46_for_rtpproxy);
|
|
}
|
|
|
|
|
|
avp_copy("$avp(s:ip_header)", "$avp(s:caller_ip_header)/d");
|
|
if($avp(s:caller_ip_header) == $null)
|
|
{
|
|
$(avp(s:caller_ip_header)[*]) = "P-NGCP-Src-Ip";
|
|
}
|
|
if($avp(s:caller_ip_val) == $null)
|
|
{
|
|
if($hdr($avp(s:caller_ip_header)) != $null)
|
|
{
|
|
xlog("L_INFO", "Use '$avp(s:caller_ip_header)' for CDR IP - [% logreq -%]\n");
|
|
$(avp(s:caller_ip_val)[*]) = $hdr($avp(s:caller_ip_header));
|
|
}
|
|
else if($hdr(P-NGCP-Src-Ip) != $null)
|
|
{
|
|
xlog("L_INFO", "CDR IP header '$avp(s:caller_ip_header)' not found, use 'P-NGCP-Src-Ip' - [% logreq -%]\n");
|
|
$(avp(s:caller_ip_val)[*]) = $hdr(P-NGCP-Src-Ip);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "CDR IP header '$avp(s:caller_ip_header)' and 'P-NGCP-Src-Ip' not found, use received IP - [% logreq -%]\n");
|
|
$(avp(s:caller_ip_val)[*]) = $si;
|
|
}
|
|
}
|
|
|
|
if($avp(s:sst_enable) == $null)
|
|
{
|
|
$(avp(s:sst_enable)[*]) = "[% sems.sbc.session_timer.enable %]";
|
|
}
|
|
avp_copy("$avp(s:sst_enable)", "$avp(s:peer_caller_sst_enable)/d");
|
|
if($avp(s:sst_expires) == $null)
|
|
{
|
|
$(avp(s:sst_expires)[*]) = [% sems.sbc.session_timer.session_expires %];
|
|
}
|
|
avp_copy("$avp(s:sst_expires)", "$avp(s:peer_caller_sst_expires)/d");
|
|
if($avp(s:sst_min_timer) == $null)
|
|
{
|
|
$(avp(s:sst_min_timer)[*]) = [% sems.sbc.session_timer.min_timer %];
|
|
}
|
|
avp_copy("$avp(s:sst_min_timer)", "$avp(s:peer_caller_sst_min_timer)/d");
|
|
if($avp(s:sst_max_timer) == $null)
|
|
{
|
|
$(avp(s:sst_max_timer)[*]) = [% sems.sbc.session_timer.max_timer %];
|
|
}
|
|
avp_copy("$avp(s:sst_max_timer)", "$avp(s:peer_caller_sst_max_timer)/d");
|
|
if($avp(s:sst_refresh_method) == $null)
|
|
{
|
|
$(avp(s:sst_refresh_method)[*]) = "UPDATE_FALLBACK_INVITE";
|
|
}
|
|
avp_copy("$avp(s:sst_refresh_method)", "$avp(s:peer_caller_sst_refresh_method)/d");
|
|
|
|
# explicitely clear them as they're reloaded later
|
|
$(avp(s:outbound_from_display)[*]) = $null;
|
|
$(avp(s:outbound_from_user)[*]) = $null;
|
|
$(avp(s:outbound_pai_user)[*]) = $null;
|
|
$(avp(s:outbound_ppi_user)[*]) = $null;
|
|
$(avp(s:outbound_diversion)[*]) = $null;
|
|
|
|
#Dialog handling for incoming pstn call
|
|
dlg_manage();
|
|
set_dlg_profile("total");
|
|
xlog("L_INFO", "Dialog set mark total - [% logreq -%]\n");
|
|
set_dlg_profile("peer","$avp(s:lcr_flags)");
|
|
xlog("L_INFO", "Dialog set mark peer to '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
|
|
}
|
|
|
|
|
|
########################################################################
|
|
# Request route 'clear-callee-dom-preferences-caller'
|
|
########################################################################
|
|
route[ROUTE_CLEAR_CALLEE_DOMAIN_PREF]
|
|
{
|
|
xlog("L_INFO", "[LUA] Clean domain preferences for caller' - [% logreq -%]\n");
|
|
if (!lua_run("ngcp_clean", "callee", "dom")) {
|
|
sl_send_reply("500", "Internal Error");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'load-callee-dom-preferences-caller'
|
|
########################################################################
|
|
route[ROUTE_LOAD_CALLEE_DOMAIN_PREF]
|
|
{
|
|
xlog("L_INFO", "[LUA] Clean domain preferences for callee' - [% logreq -%]\n");
|
|
if (!lua_run("ngcp_load_callee", "", "$ru")) {
|
|
sl_send_reply("500", "Internal Error");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'clear-usr-preferences-caller'
|
|
########################################################################
|
|
route[ROUTE_CLEAR_CALLER_PREF]
|
|
{
|
|
xlog("L_INFO", "[LUA] Clear caller preferences - [% logreq -%]\n");
|
|
if (!lua_run("ngcp_clean", "caller", "usr")) {
|
|
sl_send_reply("500", "Internal Error");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'clear-usr-preferences-callee'
|
|
########################################################################
|
|
route[ROUTE_CLEAR_CALLEE_PREF]
|
|
{
|
|
xlog("L_INFO", "[LUA] Clear callee preferences - [% logreq -%]\n");
|
|
if (!lua_run("ngcp_clean", "callee")) {
|
|
sl_send_reply("500", "Internal Error");
|
|
exit;
|
|
}
|
|
t_reset_fr();
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'usr-preferences-caller'
|
|
########################################################################
|
|
route[ROUTE_LOAD_CALLER_PREF]
|
|
{
|
|
route(ROUTE_CLEAR_CALLER_PREF);
|
|
|
|
$var(pref_domain) = 0;
|
|
if($var(forward) == 1 || $var(cf_loop) == 1 || $avp(s:from_faxserver) == 1)
|
|
{
|
|
$var(pref_domain) = "sip:" + $fU + "@" + $avp(s:acc_caller_domain);
|
|
}
|
|
else
|
|
{
|
|
if ($var(from_trusted) != 1)
|
|
{
|
|
$var(pref_domain) = "sip:" + $fU + "@" + $avp(s:caller_domain);
|
|
}
|
|
else
|
|
{
|
|
$var(pref_domain) = $fu;
|
|
}
|
|
}
|
|
|
|
xlog("L_INFO", "[LUA] Load caller preferences for uuid '$avp(s:caller_uuid)' and domain part of uri '$var(pref_domain)' - [% logreq -%]\n");
|
|
if (!lua_run("ngcp_load_caller", "$avp(s:caller_uuid)", "$var(pref_domain)")) {
|
|
sl_send_reply("500", "Internal Error");
|
|
exit;
|
|
}
|
|
lua_run("print_loaded_prefs", "caller");
|
|
|
|
xlog("L_INFO", "Load caller preferences for uuid '$avp(s:caller_uuid)' and domain part of uri '$var(pref_domain)' - [% logreq -%]\n");
|
|
|
|
# load domain specific avps
|
|
avp_db_load("$var(pref_domain)/domain", "*/dom_preferences");
|
|
|
|
avp_copy("$avp(s:force_outbound_calls_to_peer)", "$avp(s:caller_dom_force_outbound_calls_to_peer)/d");
|
|
|
|
avp_copy("$avp(s:inbound_upn)", "$avp(s:caller_dom_inbound_upn)/d");
|
|
avp_copy("$avp(s:inbound_uprn)", "$avp(s:caller_dom_inbound_uprn)/d");
|
|
avp_copy("$avp(s:extension_in_npn)", "$avp(s:caller_dom_extension_in_npn)/d");
|
|
|
|
avp_copy("$avp(s:rewrite_caller_in_dpid)", "$avp(s:caller_dp_dom_caller_in)/d");
|
|
avp_copy("$avp(s:rewrite_callee_in_dpid)", "$avp(s:caller_dp_dom_callee_in)/d");
|
|
avp_delete("$avp(s:rewrite_caller_out_dpid)/g");
|
|
avp_delete("$avp(s:rewrite_callee_out_dpid)/g");
|
|
|
|
avp_copy("$avp(s:ipv46_for_rtpproxy)", "$avp(s:caller_dom_ipv46_for_rtpproxy)/d");
|
|
|
|
avp_copy("$avp(s:sst_enable)", "$avp(s:caller_dom_sst_enable)/d");
|
|
avp_copy("$avp(s:sst_expires)", "$avp(s:caller_dom_sst_expires)/d");
|
|
avp_copy("$avp(s:sst_min_timer)", "$avp(s:caller_dom_sst_min_timer)/d");
|
|
avp_copy("$avp(s:sst_max_timer)", "$avp(s:caller_dom_sst_max_timer)/d");
|
|
avp_copy("$avp(s:sst_refresh_method)", "$avp(s:caller_dom_sst_refresh_method)/d");
|
|
|
|
avp_copy("$avp(s:sound_set)", "$avp(s:caller_dom_sound_set)/d");
|
|
avp_copy("$avp(s:ip_header)", "$avp(s:caller_dom_ip_header)/d");
|
|
avp_copy("$avp(s:ncos_id)", "$avp(s:caller_dom_ncos_id)/d");
|
|
avp_copy("$avp(s:adm_ncos_id)", "$avp(s:caller_dom_adm_ncos_id)/d");
|
|
|
|
avp_copy("$avp(s:allow_out_foreign_domain)", "$avp(s:caller_dom_allow_out_foreign_domain)/d");
|
|
|
|
# load caller specific avps
|
|
avp_db_load("$avp(s:caller_uuid)", "*");
|
|
avp_copy("$avp(s:account_id)", "$avp(s:caller_account_id)/d");
|
|
if($avp(s:caller_account_id) == $null)
|
|
{
|
|
$(avp(s:caller_account_id)[*]) = 0;
|
|
}
|
|
if($avp(s:cli) != $null)
|
|
{
|
|
avp_copy("$avp(s:cli)", "$avp(s:caller_cli_netprov)/d");
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:caller_cli_netprov)[*]) = $fU;
|
|
}
|
|
if($avp(s:caller_domain) == $null)
|
|
{
|
|
$(avp(s:caller_domain_netprov)[*]) = $fd;
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:caller_domain_netprov)[*]) = $avp(s:caller_domain);
|
|
}
|
|
# use network-provided domain for accounting. when coming from cf loop, it's already set correctly
|
|
if($var(cf_loop) != 1)
|
|
{
|
|
$(avp(s:acc_caller_domain)[*]) = $(avp(s:caller_domain_netprov)[*]);
|
|
}
|
|
|
|
|
|
avp_copy("$avp(s:svc_ac)", "$avp(s:caller_svc_ac)/d");
|
|
if($avp(s:caller_clir) != 1)
|
|
{
|
|
$(avp(s:caller_clir)[*]) = $null;
|
|
avp_copy("$avp(s:clir)", "$avp(s:caller_clir)/d");
|
|
}
|
|
avp_copy("$avp(s:lock)", "$avp(s:caller_lock)/d");
|
|
avp_copy("$avp(s:block_out_override_pin)", "$avp(s:caller_block_override)/d");
|
|
avp_copy("$avp(s:adm_block_out_override_pin)", "$avp(s:caller_adm_block_override)/d");
|
|
avp_copy("$avp(s:allowed_clis)", "$avp(s:caller_allowed_clis)/gd");
|
|
avp_copy("$avp(s:user_cli)", "$avp(s:caller_user_cli)/gd");
|
|
|
|
avp_copy("$avp(s:block_out_mode)", "$avp(s:caller_block_out_mode)/d");
|
|
avp_copy("$avp(s:block_out_list)", "$avp(s:caller_block_out_list)/gd");
|
|
avp_copy("$avp(s:adm_block_out_mode)", "$avp(s:caller_adm_block_out_mode)/d");
|
|
avp_copy("$avp(s:adm_block_out_list)", "$avp(s:caller_adm_block_out_list)/gd");
|
|
avp_copy("$avp(s:ncos_id)", "$avp(s:caller_ncos_id)/d");
|
|
if($avp(s:caller_ncos_id) == $null && $avp(s:caller_dom_ncos_id) != $null)
|
|
{
|
|
$(avp(s:caller_ncos_id)[*]) = $avp(s:caller_dom_ncos_id);
|
|
}
|
|
avp_copy("$avp(s:adm_ncos_id)", "$avp(s:caller_adm_ncos_id)/d");
|
|
if($avp(s:caller_adm_ncos_id) == $null && $avp(s:caller_dom_adm_ncos_id) != $null)
|
|
{
|
|
$(avp(s:caller_adm_ncos_id)[*]) = $avp(s:caller_dom_adm_ncos_id);
|
|
}
|
|
avp_copy("$avp(s:peer_auth_user)", "$avp(s:caller_peer_auth_user)/d");
|
|
avp_copy("$avp(s:peer_auth_pass)", "$avp(s:caller_peer_auth_pass)/d");
|
|
avp_copy("$avp(s:peer_auth_realm)", "$avp(s:caller_peer_auth_realm)/d");
|
|
|
|
avp_copy("$avp(s:ext_subscriber_id)", "$avp(s:caller_ext_subscriber_id)/d");
|
|
avp_copy("$avp(s:ext_contract_id)", "$avp(s:caller_ext_contract_id)/d");
|
|
avp_copy("$avp(s:prepaid)", "$avp(s:caller_prepaid)/d");
|
|
|
|
avp_copy("$avp(s:inbound_upn)", "$avp(s:caller_inbound_upn)/d");
|
|
if($avp(s:caller_inbound_upn) == $null && $avp(s:caller_dom_inbound_upn) != $null)
|
|
{
|
|
$(avp(s:caller_inbound_upn)[*]) = $avp(s:caller_dom_inbound_upn);
|
|
}
|
|
if($avp(s:caller_inbound_upn) == $null) # if there's also no dom-pref
|
|
{
|
|
$(avp(s:caller_inbound_upn)[*]) = "from_user";
|
|
}
|
|
avp_copy("$avp(s:extension_in_npn)", "$avp(s:caller_extension_in_npn)/d");
|
|
if($avp(s:caller_extension_in_npn) == $null && $avp(s:caller_dom_extension_in_npn) != $null)
|
|
{
|
|
$(avp(s:caller_extension_in_npn)[*]) = $avp(s:caller_dom_extension_in_npn);
|
|
}
|
|
avp_copy("$avp(s:inbound_uprn)", "$avp(s:caller_inbound_uprn)/d");
|
|
if($avp(s:caller_inbound_uprn) == $null && $avp(s:caller_dom_inbound_uprn) != $null)
|
|
{
|
|
$(avp(s:caller_inbound_uprn)[*]) = $avp(s:caller_dom_inbound_uprn);
|
|
}
|
|
if($avp(s:caller_inbound_uprn) == $null) # if there's also no dom-pref
|
|
{
|
|
$(avp(s:caller_inbound_uprn)[*]) = "npn";
|
|
}
|
|
|
|
avp_copy("$avp(s:sound_set)", "$avp(s:caller_sound_set)/d");
|
|
if($avp(s:caller_sound_set) == $null && $avp(s:caller_dom_sound_set) != $null)
|
|
{
|
|
$(avp(s:caller_sound_set)[*]) = $avp(s:caller_dom_sound_set);
|
|
}
|
|
|
|
avp_copy("$avp(s:ipv46_for_rtpproxy)", "$avp(s:caller_ipv46_for_rtpproxy)/d");
|
|
# only do ipv4/ipv6 rtpproxy checks for the initial caller,
|
|
# since this will be the one handling the SDP of the reply
|
|
if($avp(s:initial_caller_ipv46_for_rtpproxy) == $null)
|
|
{
|
|
if($avp(s:caller_ipv46_for_rtpproxy) != $null)
|
|
{
|
|
$avp(s:initial_caller_ipv46_for_rtpproxy) = $avp(s:caller_ipv46_for_rtpproxy);
|
|
}
|
|
else if($avp(s:caller_dom_ipv46_for_rtpproxy) != $null)
|
|
{
|
|
$avp(s:initial_caller_ipv46_for_rtpproxy) = $avp(s:caller_dom_ipv46_for_rtpproxy);
|
|
}
|
|
}
|
|
|
|
avp_copy("$avp(s:force_outbound_calls_to_peer)", "$avp(s:caller_force_outbound_calls_to_peer)/d");
|
|
if($avp(s:caller_force_outbound_calls_to_peer) == $null && $avp(s:caller_dom_force_outbound_calls_to_peer) == 1)
|
|
{
|
|
$avp(s:caller_force_outbound_calls_to_peer) = 1;
|
|
}
|
|
|
|
if($avp(s:first_caller_use_rtpproxy) == $null)
|
|
{
|
|
$(avp(s:first_caller_use_rtpproxy)[*]) = $xavp(caller_real_prefs=>use_rtpproxy);
|
|
}
|
|
|
|
if($avp(s:rewrite_caller_in_dpid) == $null) #any null of the 4 rewrite preferences means all null
|
|
{
|
|
xlog("L_INFO", "Load dialplan IDs for domain '$var(pref_domain)' - [% logreq -%]\n");
|
|
xlog("L_INFO", "Fetched dialplan IDs caller_in='$avp(s:caller_dp_dom_caller_in)', callee_in='$avp(s:caller_dp_dom_callee_in)' - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Load dialplan IDs for user '$avp(s:caller_uuid)' - [% logreq -%]\n");
|
|
avp_copy("$avp(s:rewrite_caller_in_dpid)", "$avp(s:caller_dp_dom_caller_in)/d");
|
|
avp_copy("$avp(s:rewrite_callee_in_dpid)", "$avp(s:caller_dp_dom_callee_in)/d");
|
|
avp_delete("$avp(s:rewrite_caller_out_dpid)/g");
|
|
avp_delete("$avp(s:rewrite_callee_out_dpid)/g");
|
|
xlog("L_INFO", "Fetched dialplan IDs caller_in='$avp(s:caller_dp_dom_caller_in)', callee_in='$avp(s:caller_dp_dom_callee_in)' - [% logreq -%]\n");
|
|
}
|
|
|
|
avp_copy("$avp(s:ip_header)", "$avp(s:caller_ip_header)/d");
|
|
if($avp(s:caller_ip_header) == $null && $avp(s:caller_dom_ip_header) != $null)
|
|
{
|
|
$(avp(s:caller_ip_header)[*]) = $avp(s:caller_dom_ip_header);
|
|
}
|
|
if($avp(s:caller_ip_header) == $null)
|
|
{
|
|
$(avp(s:caller_ip_header)[*]) = "P-NGCP-Src-Ip";
|
|
}
|
|
if($avp(s:caller_ip_val) == $null)
|
|
{
|
|
if($hdr($avp(s:caller_ip_header)) != $null)
|
|
{
|
|
xlog("L_INFO", "Use '$avp(s:caller_ip_header)' for CDR IP - [% logreq -%]\n");
|
|
$(avp(s:caller_ip_val)[*]) = $hdr($avp(s:caller_ip_header));
|
|
}
|
|
else if($hdr(P-NGCP-Src-Ip) != $null)
|
|
{
|
|
xlog("L_INFO", "CDR IP header '$avp(s:caller_ip_header)' not found, use 'P-NGCP-Src-Ip' - [% logreq -%]\n");
|
|
$(avp(s:caller_ip_val)[*]) = $hdr(P-NGCP-Src-Ip);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "CDR IP header '$avp(s:caller_ip_header)' and 'P-NGCP-Src-Ip' not found, use received IP - [% logreq -%]\n");
|
|
$(avp(s:caller_ip_val)[*]) = $si;
|
|
}
|
|
}
|
|
|
|
avp_copy("$avp(s:allow_out_foreign_domain)", "$avp(s:caller_allow_out_foreign_domain)/d");
|
|
if($avp(s:caller_allow_out_foreign_domain) == $null && $avp(s:caller_dom_allow_out_foreign_domain) != $null)
|
|
{
|
|
$(avp(s:caller_allow_out_foreign_domain)[*]) = $avp(s:caller_dom_allow_out_foreign_domain);
|
|
}
|
|
if(!is_domain_local("$rd"))
|
|
{
|
|
if($avp(s:caller_allow_out_foreign_domain) == 1)
|
|
{
|
|
xlog("L_WARN", "Allow call to foreign domain by preference - [% logreq -%]\n");
|
|
$var(foreign_dom) = 1;
|
|
}
|
|
else
|
|
{
|
|
xlog("L_WARN", "Reject call to foreign domain - [% logreq -%]\n");
|
|
t_reply("403", "Call to foreign domain rejected");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
|
|
$var(block_override) = 0;
|
|
$var(adm_block_override) = 0;
|
|
#!ifdef ENABLE_VSC
|
|
if(uri =~ "^sip:\*[% sems.vsc.block_override_code %]\*")
|
|
{
|
|
$var(ov_len) = 0;
|
|
$var(adm_ov_len) = 0;
|
|
strip([% sems.vsc.block_override_code.length + 2 %]);
|
|
if($avp(s:caller_block_override) != $null)
|
|
{
|
|
$var(ov_len) = $(avp(s:caller_block_override){s.len});
|
|
$var(pin) = $(rU{s.substr, 0, $var(ov_len)});
|
|
if($avp(s:caller_block_override) == $var(pin))
|
|
{
|
|
xlog("L_INFO", "Block override PIN '$avp(s:caller_block_override)' accepted - [% logreq -%]\n");
|
|
$var(block_override) = 1;
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Block override PIN '$var(pin)' does not match '$avp(s:caller_block_override)', rejected - [% logreq -%]\n");
|
|
}
|
|
}
|
|
if($avp(s:caller_adm_block_override) != $null)
|
|
{
|
|
$var(adm_ov_len) = $(avp(s:caller_adm_block_override){s.len});
|
|
$var(pin) = $(rU{s.substr, 0, $var(adm_ov_len)});
|
|
if($avp(s:caller_adm_block_override) == $var(pin))
|
|
{
|
|
xlog("L_INFO", "Administrative Block override PIN '$avp(s:caller_adm_block_override)' accepted - [% logreq -%]\n");
|
|
$var(adm_block_override) = 1;
|
|
$var(block_override) = 1;
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Administrative Block override PIN '$var(pin)' does not match '$avp(s:caller_adm_block_override)', rejected - [% logreq -%]\n");
|
|
}
|
|
|
|
}
|
|
if($var(adm_block_override) == 1)
|
|
{
|
|
$rU = $(rU{s.substr, $var(adm_ov_len), 0});
|
|
}
|
|
else if($var(block_override) == 1)
|
|
{
|
|
$rU = $(rU{s.substr, $var(ov_len), 0});
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Reject PIN override attempt - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "block_override_pin_wrong";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Incorrect Override PIN";
|
|
route(ROUTE_EARLY_REJECT);
|
|
|
|
}
|
|
}
|
|
#!endif
|
|
|
|
avp_copy("$avp(s:sst_enable)", "$avp(s:caller_sst_enable)/d");
|
|
if($avp(s:caller_sst_enable) == $null)
|
|
{
|
|
if($avp(s:caller_dom_sst_enable) != $null)
|
|
{
|
|
$(avp(s:caller_sst_enable)[*]) = $avp(s:caller_dom_sst_enable);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:caller_sst_enable)[*]) = "[% sems.sbc.session_timer.enable %]";
|
|
}
|
|
}
|
|
avp_copy("$avp(s:sst_expires)", "$avp(s:caller_sst_expires)/d");
|
|
if($avp(s:caller_sst_expires) == $null)
|
|
{
|
|
if($avp(s:caller_dom_sst_expires) != $null)
|
|
{
|
|
$(avp(s:caller_sst_expires)[*]) = $avp(s:caller_dom_sst_expires);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:caller_sst_expires)[*]) = [% sems.sbc.session_timer.session_expires %];
|
|
}
|
|
}
|
|
avp_copy("$avp(s:sst_min_timer)", "$avp(s:caller_sst_min_timer)/d");
|
|
if($avp(s:caller_sst_min_timer) == $null)
|
|
{
|
|
if($avp(s:caller_dom_sst_min_timer) != $null)
|
|
{
|
|
$(avp(s:caller_sst_min_timer)[*]) = $avp(s:caller_dom_sst_min_timer);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:caller_sst_min_timer)[*]) = [% sems.sbc.session_timer.min_timer %];
|
|
}
|
|
}
|
|
avp_copy("$avp(s:sst_max_timer)", "$avp(s:caller_sst_max_timer)/d");
|
|
if($avp(s:caller_sst_max_timer) == $null)
|
|
{
|
|
if($avp(s:caller_dom_sst_max_timer) != $null)
|
|
{
|
|
$(avp(s:caller_sst_max_timer)[*]) = $avp(s:caller_dom_sst_max_timer);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:caller_sst_max_timer)[*]) = [% sems.sbc.session_timer.max_timer %];
|
|
}
|
|
}
|
|
avp_copy("$avp(s:sst_refresh_method)", "$avp(s:caller_sst_refresh_method)/d");
|
|
if($avp(s:caller_sst_refresh_method) == $null)
|
|
{
|
|
if($avp(s:caller_dom_sst_refresh_method) != $null)
|
|
{
|
|
$(avp(s:caller_sst_refresh_method)[*]) = $avp(s:caller_dom_sst_refresh_method);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:caller_sst_refresh_method)[*]) = "UPDATE_FALLBACK_INVITE";
|
|
}
|
|
}
|
|
|
|
# explicitely clear them as they're reloaded later
|
|
$(avp(s:outbound_from_display)[*]) = $null;
|
|
$(avp(s:outbound_from_user)[*]) = $null;
|
|
$(avp(s:outbound_pai_user)[*]) = $null;
|
|
$(avp(s:outbound_ppi_user)[*]) = $null;
|
|
$(avp(s:outbound_diversion)[*]) = $null;
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'usr-preferences-callee'
|
|
########################################################################
|
|
route[ROUTE_LOAD_CALLEE_PREF]
|
|
{
|
|
|
|
xlog("L_INFO", "[LUA] Load callee preferences for uuid '$avp(s:callee_uuid)' - [% logreq -%]\n");
|
|
if (!lua_run("ngcp_load_callee", "$avp(s:callee_uuid)")) {
|
|
sl_send_reply("500", "Internal Error");
|
|
exit;
|
|
}
|
|
lua_run("print_loaded_prefs", "caller");
|
|
|
|
xlog("L_INFO", "Load callee preferences for uuid '$avp(s:callee_uuid)' - [% logreq -%]\n");
|
|
|
|
# load domain specific avps
|
|
avp_db_load("$ru/domain", "*/dom_preferences");
|
|
avp_copy("$avp(s:cc)", "$avp(s:callee_cc)/d");
|
|
|
|
avp_copy("$avp(s:force_inbound_calls_to_peer)", "$avp(s:callee_dom_force_inbound_calls_to_peer)/d");
|
|
|
|
avp_copy("$avp(s:rewrite_caller_out_dpid)", "$avp(s:callee_dp_dom_caller_out)/d");
|
|
avp_copy("$avp(s:rewrite_callee_out_dpid)", "$avp(s:callee_dp_dom_callee_out)/d");
|
|
avp_delete("$avp(s:rewrite_caller_in_dpid)/g");
|
|
avp_delete("$avp(s:rewrite_callee_in_dpid)/g");
|
|
|
|
avp_copy("$avp(s:outbound_from_display)", "$avp(s:callee_dom_outbound_from_display)/d");
|
|
avp_copy("$avp(s:outbound_from_user)", "$avp(s:callee_dom_outbound_from_user)/d");
|
|
avp_copy("$avp(s:outbound_pai_user)", "$avp(s:callee_dom_outbound_pai_user)/d");
|
|
avp_copy("$avp(s:outbound_ppi_user)", "$avp(s:callee_dom_outbound_ppi_user)/d");
|
|
avp_copy("$avp(s:outbound_diversion)", "$avp(s:callee_dom_outbound_diversion)/d");
|
|
|
|
avp_copy("$avp(s:ipv46_for_rtpproxy)", "$avp(s:callee_dom_ipv46_for_rtpproxy)/d");
|
|
|
|
avp_copy("$avp(s:sst_enable)", "$avp(s:callee_dom_sst_enable)/d");
|
|
avp_copy("$avp(s:sst_expires)", "$avp(s:callee_dom_sst_expires)/d");
|
|
avp_copy("$avp(s:sst_min_timer)", "$avp(s:callee_dom_sst_min_timer)/d");
|
|
avp_copy("$avp(s:sst_max_timer)", "$avp(s:callee_dom_sst_max_timer)/d");
|
|
avp_copy("$avp(s:sst_refresh_method)", "$avp(s:callee_dom_sst_refresh_method)/d");
|
|
|
|
avp_copy("$avp(s:sound_set)", "$avp(s:callee_dom_sound_set)/d");
|
|
avp_copy("$avp(s:mobile_push_enable)", "$avp(s:callee_dom_mobile_push_enable)/d");
|
|
|
|
# load callee avps
|
|
avp_db_load("$avp(s:callee_uuid)", "*");
|
|
avp_copy("$avp(s:account_id)", "$avp(s:callee_account_id)/d");
|
|
if($avp(s:callee_account_id) == $null)
|
|
{
|
|
$(avp(s:callee_account_id)[*]) = 0;
|
|
}
|
|
avp_copy("$avp(s:cc)", "$avp(s:callee_cc)/d");
|
|
avp_copy("$avp(s:ac)", "$avp(s:callee_ac)/d");
|
|
avp_copy("$avp(s:cfu)", "$avp(s:callee_cfu)/gd");
|
|
avp_copy("$avp(s:cfna)", "$avp(s:callee_cfna)/gd");
|
|
avp_copy("$avp(s:cfb)", "$avp(s:callee_cfb)/gd");
|
|
avp_copy("$avp(s:cft)", "$avp(s:callee_cft)/gd");
|
|
avp_copy("$avp(s:ringtimeout)", "$avp(s:callee_ringtimeout)/d");
|
|
avp_copy("$avp(s:lock)", "$avp(s:callee_lock)/d");
|
|
avp_copy("$avp(s:e164_to_ruri)", "$avp(s:callee_e164_to_ruri)/d");
|
|
avp_copy("$avp(s:force_inbound_calls_to_peer)", "$avp(s:callee_force_inbound_calls_to_peer)/d");
|
|
|
|
avp_copy("$avp(s:block_in_mode)", "$avp(s:callee_block_in_mode)/d");
|
|
avp_copy("$avp(s:block_in_list)", "$avp(s:callee_block_in_list)/gd");
|
|
avp_copy("$avp(s:block_in_clir)", "$avp(s:callee_block_in_clir)/d");
|
|
avp_copy("$avp(s:adm_block_in_mode)", "$avp(s:callee_adm_block_in_mode)/d");
|
|
avp_copy("$avp(s:adm_block_in_list)", "$avp(s:callee_adm_block_in_list)/gd");
|
|
avp_copy("$avp(s:adm_block_in_clir)", "$avp(s:callee_adm_block_in_clir)/d");
|
|
|
|
avp_copy("$avp(s:ext_subscriber_id)", "$avp(s:callee_ext_subscriber_id)/d");
|
|
avp_copy("$avp(s:ext_contract_id)", "$avp(s:callee_ext_contract_id)/d");
|
|
|
|
avp_copy("$avp(s:peer_auth_user)", "$avp(s:callee_peer_auth_user)/d");
|
|
avp_copy("$avp(s:peer_auth_pass)", "$avp(s:callee_peer_auth_pass)/d");
|
|
avp_copy("$avp(s:peer_auth_realm)", "$avp(s:callee_peer_auth_realm)/d");
|
|
|
|
|
|
avp_copy("$avp(s:sound_set)", "$avp(s:callee_sound_set)/d");
|
|
if($avp(s:callee_sound_set) == $null && $avp(s:callee_dom_sound_set) != $null)
|
|
{
|
|
$(avp(s:callee_sound_set)[*]) = $avp(s:callee_dom_sound_set);
|
|
}
|
|
|
|
if($avp(s:callee_force_inbound_calls_to_peer) == 1 || $avp(s:callee_dom_force_inbound_calls_to_peer) == 1)
|
|
{
|
|
$avp(s:callee_force_inbound_calls_to_peer) = 1;
|
|
}
|
|
#manwe -- Move to only method INVITE?
|
|
avp_copy("$avp(s:use_rtpproxy)", "$avp(s:callee_use_rtpproxy)/d");
|
|
if($avp(s:callee_use_rtpproxy) == $null && $avp(s:callee_dom_use_rtpproxy) != $null)
|
|
{
|
|
$avp(s:callee_use_rtpproxy) = $avp(s:callee_dom_use_rtpproxy);
|
|
}
|
|
|
|
avp_copy("$avp(s:ipv46_for_rtpproxy)", "$avp(s:callee_ipv46_for_rtpproxy)/d");
|
|
if($avp(s:callee_ipv46_for_rtpproxy) == $null && $avp(s:callee_dom_ipv46_for_rtpproxy) != $null)
|
|
{
|
|
$avp(s:callee_ipv46_for_rtpproxy) = $avp(s:callee_dom_ipv46_for_rtpproxy);
|
|
}
|
|
|
|
avp_copy("$avp(s:outbound_from_user)", "$avp(s:callee_outbound_from_user)/d");
|
|
if($avp(s:callee_outbound_from_user) == $null && $avp(s:callee_dom_outbound_from_user) != $null)
|
|
{
|
|
$(avp(s:callee_outbound_from_user)[*]) = $avp(s:callee_dom_outbound_from_user);
|
|
}
|
|
if($avp(s:callee_outbound_from_user) == $null)
|
|
{
|
|
$avp(s:callee_outbound_from_user) = "npn";
|
|
}
|
|
avp_copy("$avp(s:outbound_from_display)", "$avp(s:callee_outbound_from_display)/d");
|
|
if($avp(s:callee_outbound_from_display) == $null && $avp(s:callee_dom_outbound_from_display) != $null)
|
|
{
|
|
$(avp(s:callee_outbound_from_display)[*]) = $avp(s:callee_dom_outbound_from_display);
|
|
}
|
|
avp_copy("$avp(s:outbound_pai_user)", "$avp(s:callee_outbound_pai_user)/d");
|
|
if($avp(s:callee_outbound_pai_user) == $null && $avp(s:callee_dom_outbound_pai_user) != $null)
|
|
{
|
|
$(avp(s:callee_outbound_pai_user)[*]) = $avp(s:callee_dom_outbound_pai_user);
|
|
}
|
|
avp_copy("$avp(s:outbound_ppi_user)", "$avp(s:callee_outbound_ppi_user)/d");
|
|
if($avp(s:callee_outbound_ppi_user) == $null && $avp(s:callee_dom_outbound_ppi_user) != $null)
|
|
{
|
|
$(avp(s:callee_outbound_ppi_user)[*]) = $avp(s:callee_dom_outbound_ppi_user);
|
|
}
|
|
avp_copy("$avp(s:outbound_diversion)", "$avp(s:callee_outbound_diversion)/d");
|
|
if($avp(s:callee_outbound_diversion) == $null && $avp(s:callee_dom_outbound_diversion) != $null)
|
|
{
|
|
$(avp(s:callee_outbound_diversion)[*]) = $avp(s:callee_dom_outbound_diversion);
|
|
}
|
|
|
|
if($avp(s:rewrite_caller_out_dpid) == $null) # any null of the 4 rewrite preferences means all null
|
|
{
|
|
xlog("L_INFO", "Load dialplan IDs for domain '$rd' - [% logreq -%]\n");
|
|
xlog("L_INFO", "Fetched dialplan IDs caller_out='$avp(s:callee_dp_dom_caller_out)', callee_out='$avp(s:callee_dp_dom_callee_out)' - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Load dialplan IDs for user '$avp(s:callee_uuid)' - [% logreq -%]\n");
|
|
avp_copy("$avp(s:rewrite_caller_out_dpid)", "$avp(s:callee_dp_dom_caller_out)/d");
|
|
avp_copy("$avp(s:rewrite_callee_out_dpid)", "$avp(s:callee_dp_dom_callee_out)/d");
|
|
avp_delete("$avp(s:rewrite_caller_in_dpid)/g");
|
|
avp_delete("$avp(s:rewrite_callee_in_dpid)/g");
|
|
xlog("L_INFO", "Fetched dialplan IDs caller_out='$avp(s:callee_dp_dom_caller_out)', callee_out='$avp(s:callee_dp_dom_callee_out)' - [% logreq -%]\n");
|
|
}
|
|
|
|
avp_copy("$avp(s:sst_enable)", "$avp(s:callee_sst_enable)/d");
|
|
if($avp(s:callee_sst_enable) == $null)
|
|
{
|
|
if($avp(s:callee_dom_sst_enable) != $null)
|
|
{
|
|
$(avp(s:callee_sst_enable)[*]) = $avp(s:callee_dom_sst_enable);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:callee_sst_enable)[*]) = "[% sems.sbc.session_timer.enable %]";
|
|
}
|
|
}
|
|
avp_copy("$avp(s:sst_expires)", "$avp(s:callee_sst_expires)/d");
|
|
if($avp(s:callee_sst_expires) == $null)
|
|
{
|
|
if($avp(s:callee_dom_sst_expires) != $null)
|
|
{
|
|
$(avp(s:callee_sst_expires)[*]) = $avp(s:callee_dom_sst_expires);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:callee_sst_expires)[*]) = [% sems.sbc.session_timer.session_expires %];
|
|
}
|
|
}
|
|
avp_copy("$avp(s:sst_min_timer)", "$avp(s:callee_sst_min_timer)/d");
|
|
if($avp(s:callee_sst_min_timer) == $null)
|
|
{
|
|
if($avp(s:callee_dom_sst_min_timer) != $null)
|
|
{
|
|
$(avp(s:callee_sst_min_timer)[*]) = $avp(s:callee_dom_sst_min_timer);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:callee_sst_min_timer)[*]) = [% sems.sbc.session_timer.min_timer %];
|
|
}
|
|
}
|
|
avp_copy("$avp(s:sst_max_timer)", "$avp(s:callee_sst_max_timer)/d");
|
|
if($avp(s:callee_sst_max_timer) == $null)
|
|
{
|
|
if($avp(s:callee_dom_sst_max_timer) != $null)
|
|
{
|
|
$(avp(s:callee_sst_max_timer)[*]) = $avp(s:callee_dom_sst_max_timer);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:callee_sst_max_timer)[*]) = [% sems.sbc.session_timer.max_timer %];
|
|
}
|
|
}
|
|
avp_copy("$avp(s:sst_refresh_method)", "$avp(s:callee_sst_refresh_method)/d");
|
|
if($avp(s:callee_sst_refresh_method) == $null)
|
|
{
|
|
if($avp(s:callee_dom_sst_refresh_method) != $null)
|
|
{
|
|
$(avp(s:callee_sst_refresh_method)[*]) = $avp(s:callee_dom_sst_refresh_method);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:callee_sst_refresh_method)[*]) = "UPDATE_FALLBACK_INVITE";
|
|
}
|
|
}
|
|
avp_copy("$avp(s:mobile_push_enable)", "$avp(s:callee_mobile_push_enable)/d");
|
|
if($avp(s:callee_mobile_push_enable) == 1 || $avp(s:callee_dom_mobile_push_enable) == 1)
|
|
{
|
|
$(avp(s:callee_mobile_push_enable)[*]) = 1;
|
|
}
|
|
avp_copy("$avp(s:prepaid)", "$avp(s:callee_prepaid)/d");
|
|
if(is_method("INVITE"))
|
|
{
|
|
# dialog mark for local callee
|
|
set_dlg_profile("user","$avp(s:callee_uuid)");
|
|
set_dlg_profile("account","$avp(s:callee_account_id)");
|
|
xlog("L_INFO", "Dialog set user, account to '$avp(s:callee_uuid)/$avp(s:callee_account_id)' - [% logreq -%]\n");
|
|
|
|
if( (avp_check("$avp(s:callee_lock)", "eq/s:3") || avp_check("$avp(s:callee_lock)", "eq/s:4")) &&
|
|
$avp(s:from_faxserver) == 0 && $avp(s:from_voicebox) == 0 )
|
|
{
|
|
xlog("L_INFO", "Callee locked for incoming with mode '$avp(s:callee_lock)' - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "locked_in";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Callee locked";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
# dialog count for callee subscriber/dom concurrent max
|
|
if($xavp(callee_real_prefs=>concurrent_max) != $null && $xavp(callee_real_prefs=>concurrent_max) != 0)
|
|
{
|
|
if(get_profile_size("user","$avp(s:callee_uuid)","$avp(s:size)"))
|
|
{
|
|
if ($avp(s:size) > $xavp(callee_real_prefs=>concurrent_max))
|
|
{
|
|
xlog("L_INFO", "Concurrent max calls exceeded for callee '$avp(s:callee_uuid)' - [% logreq -%]\n");
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "max_calls_in";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 486;
|
|
$(avp(s:announce_reason)[*]) = "Busy";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
}
|
|
# dialog count for callee subscriber/dom concurrent max per account
|
|
if($xavp(callee_real_prefs=>concurrent_max_per_account) != $null && $xavp(callee_real_prefs=>concurrent_max_per_account) != 0)
|
|
{
|
|
if(get_profile_size("account","$avp(s:callee_account_id)","$avp(s:size)"))
|
|
{
|
|
if ($avp(s:size) > $xavp(callee_real_prefs=>concurrent_max_per_account))
|
|
{
|
|
xlog("L_INFO", "Concurrent max calls per account exceeded for callee '$avp(s:callee_uuid)' in account '$avp(s:callee_account_id)' - [% logreq -%]\n");
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "max_calls_in";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 486;
|
|
$(avp(s:announce_reason)[*]) = "Busy";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
# check incoming block-list
|
|
route(ROUTE_BLOCK_IN);
|
|
|
|
if($avp(s:nohunt) == 1)
|
|
{
|
|
$(avp(s:callee_cfu)[*]) = $null;
|
|
}
|
|
while($avp(s:callee_cfu) != $null)
|
|
{
|
|
$var(cf_id) = $(avp(s:callee_cfu)[0]);
|
|
xlog("L_INFO", "CFU to CF map id '$var(cf_id)' found - [% logreq -%]\n");
|
|
route(ROUTE_LOAD_CF_MAP);
|
|
if($avp(s:cf_destinations) == $null)
|
|
{
|
|
xlog("L_INFO", "CFU skipped due to forward destinations definitions - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_CHECK_CF_PERIOD);
|
|
if($rc == 1)
|
|
{
|
|
$ru = $(avp(s:cf_destinations)[0]);
|
|
if($ru =~ "^sip:localuser@.+\.local$")
|
|
{
|
|
t_reset_fr();
|
|
$(avp(s:cf_destinations)[*]) = $null;
|
|
$(avp(s:cf_timeouts)[*]) = $null;
|
|
$(avp(s:cf_periods)[*]) = $null;
|
|
$(avp(s:callee_cfu)[*]) = $null;
|
|
$ru = "sip:" + $avp(s:acc_callee_user) + "@" + $avp(s:acc_callee_domain);
|
|
xlog("L_INFO", "Stop hunting for CFU to own subscriber - [% logreq -%]\n");
|
|
break;
|
|
}
|
|
|
|
xlog("L_INFO", "CFU to destination '$(avp(s:cf_destinations)[0])' with timeout '$(avp(s:cf_timeouts)[0])' activated - [% logreq -%]\n");
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
$(avp(s:callee_fr_inv_timer)[*]) = $(avp(s:cf_timeouts)[0]) * 1000;
|
|
t_set_fr("$avp(s:callee_fr_inv_timer)");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_depth)[*]) = $(avp(s:cf_depth){s.int}) + 1;
|
|
route(ROUTE_ACC_CF);
|
|
$(avp(s:acc_state)[*]) = "cfu";
|
|
$(avp(s:acc_caller_user)[*]) = $avp(s:acc_callee_user);
|
|
$(avp(s:acc_caller_domain)[*]) = $avp(s:acc_callee_domain);
|
|
route(ROUTE_EXECUTE_CF_LOOP);
|
|
exit;
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "CFU skipped due to time period definitions - [% logreq -%]\n");
|
|
}
|
|
}
|
|
$(avp(s:callee_cfu)[0]) = $null;
|
|
}
|
|
|
|
if($avp(s:callee_cft) != $null)
|
|
{
|
|
if($avp(s:callee_ringtimeout) != $null)
|
|
{
|
|
xlog("L_INFO", "Setting ring timeout to $avp(s:callee_ringtimeout) secs - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:callee_ringtimeout)[*]) = 180;
|
|
xlog("L_INFO", "Setting default ring timeout to $avp(s:callee_ringtimeout) secs - [% logreq -%]\n");
|
|
}
|
|
$(avp(s:callee_fr_inv_timer)[*]) = $avp(s:callee_ringtimeout) * 1000;
|
|
t_set_fr("$avp(s:callee_fr_inv_timer)");
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route to load call-forward maps - needs $var(cf_id) set
|
|
########################################################################
|
|
route[ROUTE_LOAD_CF_MAP]
|
|
{
|
|
$(avp(s:cf_destinations)[*]) = $null;
|
|
$(avp(s:cf_timeouts)[*]) = $null;
|
|
$(avp(s:cf_periods)[*]) = $null;
|
|
|
|
avp_db_query("select d.destination, d.timeout from provisioning.voip_cf_destinations d, provisioning.voip_cf_destination_sets ds, provisioning.voip_cf_mappings m where m.id=$var(cf_id) and m.destination_set_id=ds.id and d.destination_set_id=ds.id order by d.priority asc", "$avp(s:cf_destinations),$avp(s:cf_timeouts)");
|
|
xlog("L_INFO", "Loaded CF destination set for CF map id '$var(cf_id)': '$(avp(s:cf_destinations)[*])' - [% logreq -%]\n");
|
|
xlog("L_INFO", "Loaded CF timeouts for CF map id '$var(cf_id)': '$(avp(s:cf_timeouts)[*])' - [% logreq -%]\n");
|
|
|
|
avp_db_query("select concat(if(p.year is null, '', concat('yr{', p.year, '} ')), if(p.month is null, '', concat('mo{', p.month, '} ')), if(p.mday is null, '', concat('md{', p.mday, '} ')), if(p.wday is null, '', concat('wd{', p.wday, '} ')), if(p.hour is null, '', concat('hr{', p.hour, '} ')), if(p.minute is null, '', concat('min{', p.minute, '} '))) as period from provisioning.voip_cf_periods p, provisioning.voip_cf_time_sets ts, provisioning.voip_cf_mappings m where m.id=$var(cf_id) and m.time_set_id=ts.id and p.time_set_id=ts.id", "$avp(s:cf_periods)");
|
|
if($avp(s:cf_periods) != $null)
|
|
{
|
|
xlog("L_INFO", "Loaded CF time destination set for CF map id '$var(cf_id)': '$(avp(s:cf_periods)[*])' - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No CF time destination set for CF map id '$var(cf_id)' found, CF is done always - [% logreq -%]\n");
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route to check CF time period
|
|
########################################################################
|
|
route[ROUTE_CHECK_CF_PERIOD]
|
|
{
|
|
if($avp(s:cf_periods) != $null)
|
|
{
|
|
$(avp(s:tmp_cf_periods)[*]) = $null;
|
|
avp_copy("$avp(s:cf_periods)", "$avp(s:tmp_cf_periods)/g");
|
|
while($avp(s:tmp_cf_periods) != $null)
|
|
{
|
|
xlog("L_INFO", "Checking CF time period '$(avp(s:tmp_cf_periods)[0])' - [% logreq -%]\n");
|
|
if(time_period_match("$(avp(s:tmp_cf_periods)[0])", "$TS"))
|
|
{
|
|
xlog("L_INFO", "CF time period '$(avp(s:tmp_cf_periods)[0])' matched, performing call-forward - [% logreq -%]\n");
|
|
return(1);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:tmp_cf_periods)[0]) = $null;
|
|
}
|
|
}
|
|
return(-1);
|
|
}
|
|
else
|
|
{
|
|
return(1);
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'acc-caller'
|
|
########################################################################
|
|
route[ROUTE_ACC_CALLER]
|
|
{
|
|
if($avp(s:caller_ext_subscriber_id) == $null)
|
|
{
|
|
$avp(s:caller_ext_subscriber_id) = '';
|
|
}
|
|
if($avp(s:caller_ext_contract_id) == $null)
|
|
{
|
|
$avp(s:caller_ext_contract_id) = '';
|
|
}
|
|
if($avp(s:caller_peer_auth_user) != $null)
|
|
{
|
|
$(avp(s:acc_caller_pau)[*]) = $avp(s:caller_peer_auth_user);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:acc_caller_pau)[*]) = '';
|
|
}
|
|
if($avp(s:caller_peer_auth_realm) != $null)
|
|
{
|
|
$(avp(s:acc_caller_par)[*]) = $avp(s:caller_peer_auth_realm);
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:acc_caller_par)[*]) = '';
|
|
}
|
|
|
|
xlog("L_INFO", "Setting acc source-leg for uuid '$avp(s:caller_uuid)': '$avp(s:caller_uuid)|$avp(s:acc_caller_user)|$avp(s:acc_caller_domain)|$avp(s:caller_cli_userprov)|$avp(s:caller_ext_subscriber_id)|$avp(s:caller_ext_contract_id)|$avp(s:caller_account_id)|$avp(s:acc_caller_pau)|$avp(s:acc_caller_par)|$avp(s:caller_clir)|$avp(s:acc_state)|$avp(s:caller_ip_val)|$TV(Sn)' - [% logreq -%]\n");
|
|
$avp(i:901) = $avp(s:caller_uuid) + "|" + $avp(s:acc_caller_user) + "|" + $avp(s:acc_caller_domain) + "|" + $avp(s:caller_cli_userprov) + "|" + $avp(s:caller_ext_subscriber_id) + "|" + $avp(s:caller_ext_contract_id) + "|" + $avp(s:caller_account_id) + "|" + $avp(s:acc_caller_pau) + "|" + $avp(s:acc_caller_par) + "|" + $avp(s:caller_clir) + "|" + $avp(s:acc_state) + "|" + $avp(s:caller_ip_val) + "|" + $TV(Sn);
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'acc-callee'
|
|
########################################################################
|
|
route[ROUTE_ACC_CALLEE]
|
|
{
|
|
if($avp(s:callee_ext_subscriber_id) == $null)
|
|
{
|
|
$avp(s:callee_ext_subscriber_id) = '';
|
|
}
|
|
if($avp(s:callee_ext_contract_id) == $null)
|
|
{
|
|
$avp(s:callee_ext_contract_id) = '';
|
|
}
|
|
if($var(proxylu_src) == 1 || $var(proxylu_dst_callee == 1))
|
|
{
|
|
$(avp(s:callee_acc_proxylu)[*]) = 1;
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:callee_acc_proxylu)[*]) = 0;
|
|
}
|
|
|
|
xlog("L_INFO", "Setting acc destination-leg for uuid '$avp(s:callee_uuid)': '$avp(s:callee_acc_proxylu)|$avp(s:callee_ext_subscriber_id)|$avp(s:callee_ext_contract_id)|$avp(s:callee_account_id)|$avp(s:acc_callee_dialed)|$avp(s:callee_uuid)|$avp(s:acc_callee_user)|$avp(s:acc_callee_domain)|$avp(s:acc_callee_user_in)|$avp(s:acc_callee_domain_in)' - [% logreq -%]\n");
|
|
$avp(i:902) = "" + $avp(s:callee_acc_proxylu) + "|" + $avp(s:callee_ext_subscriber_id) + "|" + $avp(s:callee_ext_contract_id) + "|" + $avp(s:callee_account_id) + "|" + $avp(s:acc_callee_dialed) + "|" + $avp(s:callee_uuid) + "|" + $avp(s:acc_callee_user) + "|" + $avp(s:acc_callee_domain) + "|" + $avp(s:acc_callee_user_in) + "|" + $avp(s:acc_callee_domain_in);
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'acc-failure'
|
|
########################################################################
|
|
route[ROUTE_ACC_FAILURE]
|
|
{
|
|
xlog("L_INFO", "Accounting failed request for uuid '$avp(s:caller_uuid)' - [% logreq -%]\n");
|
|
if($avp(s:acc_callee_user) == $null)
|
|
{
|
|
$avp(s:acc_callee_user) = $rU;
|
|
}
|
|
if($avp(s:acc_callee_domain) == $null)
|
|
{
|
|
$avp(s:acc_callee_domain) = $rd;
|
|
}
|
|
if($avp(s:caller_uuid) == $null)
|
|
{
|
|
$avp(s:caller_uuid) = 0;
|
|
}
|
|
if($avp(s:callee_uuid) == $null)
|
|
{
|
|
$avp(s:callee_uuid) = 0;
|
|
}
|
|
route(ROUTE_ACC_CALLER);
|
|
route(ROUTE_ACC_CALLEE);
|
|
resetflag(FLAG_ACC_FAILED);
|
|
t_flush_flags();
|
|
acc_db_request("404", "acc");
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'cfu-acc'
|
|
########################################################################
|
|
route[ROUTE_ACC_CF]
|
|
{
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
|
|
route(ROUTE_ACC_CALLER);
|
|
route(ROUTE_ACC_CALLEE);
|
|
}
|
|
|
|
########################################################################
|
|
# Check for anonymization
|
|
########################################################################
|
|
route[ROUTE_CLIR]
|
|
{
|
|
if($avp(s:from_pstn) == 0 && uri =~ "^sip:\*[% sems.vsc.clir_code %]\*")
|
|
{
|
|
strip([% sems.vsc.clir_code.length + 2 %]);
|
|
if($avp(s:caller_clir) == 1)
|
|
{
|
|
xlog("L_INFO", "Per-call CLIR disabled - [% logreq -%]\n");
|
|
$(avp(s:caller_clir)[*]) = 0;
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Per-call CLIR enabled - [% logreq -%]\n");
|
|
$(avp(s:caller_clir)[*]) = 1;
|
|
}
|
|
}
|
|
|
|
if($avp(s:caller_clir) == 1)
|
|
{
|
|
xlog("L_INFO", "Caller anonymization - [% logreq -%]\n");
|
|
}
|
|
else if(avp_check("$fn", "fm/[Aa]nonymous") || avp_check("$fn", "fm/\"[Aa]nonymous\""))
|
|
{
|
|
$(avp(s:caller_clir)[*]) = 1;
|
|
xlog("L_INFO", "Caller anonymization user-provided (display) - [% logreq -%]\n");
|
|
}
|
|
else if(avp_check("$fU", "fm/[Aa]nonymous"))
|
|
{
|
|
$(avp(s:caller_clir)[*]) = 1;
|
|
xlog("L_INFO", "Caller anonymization user-provided (user) - [% logreq -%]\n");
|
|
}
|
|
else if(is_present_hf("Privacy") && $hdr(Privacy) == "id")
|
|
{
|
|
$(avp(s:caller_clir)[*]) = 1;
|
|
xlog("L_INFO", "Caller anonymization user-provided (privacy) - [% logreq -%]\n");
|
|
}
|
|
|
|
# set to 0 for marking it in CDR
|
|
if($avp(s:caller_clir) == $null)
|
|
{
|
|
$(avp(s:caller_clir)[*]) = 0;
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route to stop rtpproxy for all branches
|
|
########################################################################
|
|
route[ROUTE_STOP_RTPPROXY]
|
|
{
|
|
xlog("L_INFO", "Stop mediaproxy for all branches - [% logreq -%]\n");
|
|
rtpproxy_destroy();
|
|
}
|
|
|
|
########################################################################
|
|
# Request route to stop rtpproxy for current branch
|
|
########################################################################
|
|
route[ROUTE_STOP_RTPPROXY_BRANCH]
|
|
{
|
|
xlog("L_INFO", "Stop mediaproxy for current branch using first Via - [% logreq -%]\n");
|
|
rtpproxy_destroy("1");
|
|
}
|
|
|
|
|
|
########################################################################
|
|
# Request route 'base-outbound'
|
|
########################################################################
|
|
route[ROUTE_OUTBOUND]
|
|
{
|
|
if(is_present_hf("P-Asserted-Identity"))
|
|
{
|
|
remove_hf("P-Asserted-Identity");
|
|
}
|
|
if(is_present_hf("P-Preferred-Identity"))
|
|
{
|
|
remove_hf("P-Preferred-Identity");
|
|
}
|
|
if(is_present_hf("Remote-Party-ID"))
|
|
{
|
|
remove_hf("Remote-Party-ID");
|
|
}
|
|
if(is_present_hf("Privacy"))
|
|
{
|
|
remove_hf("Privacy");
|
|
}
|
|
|
|
if($var(loose_routed) != 1 && $var(no_acc) != 1)
|
|
{
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
|
|
route(ROUTE_ACC_CALLER);
|
|
route(ROUTE_ACC_CALLEE);
|
|
}
|
|
if($var(loose_routed) != 1)
|
|
{
|
|
if($var(no_sbc) == 1)
|
|
{
|
|
t_on_branch("BRANCH_ROUTE_NO_SBC");
|
|
}
|
|
else
|
|
{
|
|
t_on_branch("BRANCH_ROUTE_SBC");
|
|
}
|
|
setflag(FLAG_DOWNSTREAM);
|
|
}
|
|
|
|
t_on_reply("REPLY_ROUTE_NAT");
|
|
|
|
if($var(proxylu_src) != 1)
|
|
{
|
|
if(is_present_hf("Proxy-Authorization"))
|
|
{
|
|
remove_hf("Proxy-Authorization");
|
|
}
|
|
if(is_present_hf("Authorization"))
|
|
{
|
|
remove_hf("Authorization");
|
|
}
|
|
}
|
|
|
|
xlog("L_INFO", "Relaying request, du='$du' - [% logreq -%]\n");
|
|
|
|
# no 100 (we already sent it)
|
|
if(!t_relay_to("0x01"))
|
|
{
|
|
sl_reply_error();
|
|
if(is_method("INVITE"))
|
|
{
|
|
route(ROUTE_STOP_RTPPROXY_BRANCH);
|
|
}
|
|
}
|
|
exit;
|
|
}
|
|
|
|
########################################################################
|
|
# Request route to extract CLI from SIP message
|
|
# in: $var(ccli_selector), $var(ccli_desc)
|
|
# out: $var(ccli_user), $var(ccli_domain)
|
|
########################################################################
|
|
route[ROUTE_GET_CALLER_CLI]
|
|
{
|
|
if($var(ccli_selector) == "ppi_user" && is_present_hf("P-Preferred-Identity"))
|
|
{
|
|
$var(ccli_user) = $pU;
|
|
$var(ccli_domain) = $pd;
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(ccli_user)' taken from PPI - [% logreq -%]\n");
|
|
}
|
|
else if($var(ccli_selector) == "pai_user" && is_present_hf("P-Asserted-Identity"))
|
|
{
|
|
$var(ccli_user) = $(ai{uri.user});
|
|
$var(ccli_domain) = $(ai{uri.host});
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(ccli_user)' taken from PAI - [% logreq -%]\n");
|
|
}
|
|
else if($var(ccli_selector) == "rpid_user" && is_present_hf("Remote-Party-ID"))
|
|
{
|
|
$var(ccli_user) = $(re{uri.user});
|
|
$var(ccli_domain) = $(re{uri.host});
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(ccli_user)' taken from RPID - [% logreq -%]\n");
|
|
}
|
|
else if($var(ccli_selector) == "from_display" && $fn != $null && $(fn{s.len}) > 0)
|
|
{
|
|
$var(ccli_user) = $fn;
|
|
# strip optional double-quotes
|
|
if($var(ccli_user) =~ "^\".+\"$")
|
|
{
|
|
#$var(ccli_user) = $(var(ccli_user){s.select,1,"});
|
|
# TODO: the above seems to break in unpredictable cases, use old/safe way for now
|
|
$(avp(s:tmp)[*]) = $var(ccli_user);
|
|
avp_subst("$avp(s:tmp)", "/^\"?([^\"]*)\"?$/\1/");
|
|
$var(ccli_user) = $avp(s:tmp);
|
|
$(avp(s:tmp)[*]) = $null;
|
|
}
|
|
$var(ccli_domain) = $fd;
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(ccli_user)' taken from From-Display - [% logreq -%]\n");
|
|
}
|
|
else if($var(ccli_selector) == "from_user")
|
|
{
|
|
$var(ccli_user) = $fU;
|
|
$var(ccli_domain) = $fd;
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(ccli_user)' taken from From-User - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
$var(ccli_user) = $fU;
|
|
$var(ccli_domain) = $fd;
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(ccli_user)' taken from From-User as fallback, should be from '$var(ccli_selector)' - [% logreq -%]\n");
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'base-route-invite'
|
|
########################################################################
|
|
route[ROUTE_INVITE]
|
|
{
|
|
#unescape before escaping to not encode '%' as '%25'
|
|
if(uri =~ "\%[0-9]+")
|
|
{
|
|
$var(uuser) = $(rU{s.unescape.user});
|
|
$rU = $(var(uuser){s.escape.user});
|
|
}
|
|
else
|
|
{
|
|
$rU = $(rU{s.escape.user});
|
|
}
|
|
|
|
$(avp(s:from_voicebox)[*]) = $null;
|
|
$(avp(s:pstn)[*]) = 0;
|
|
$(avp(s:cf_depth)[*]) = 0;
|
|
$(avp(s:to_voicebox)[*]) = $null;
|
|
$(avp(s:size)[*]) = 0;
|
|
|
|
|
|
route(ROUTE_LOAD_CALLEE_DOMAIN_PREF);
|
|
route(ROUTE_FIND_CALLER);
|
|
setflag(FLAG_ACC_FAILED);
|
|
setflag(FLAG_ACC_DB);
|
|
if(!t_check_trans())
|
|
{
|
|
t_newtran();
|
|
}
|
|
$avp(s:acc_callee_dialed) = $rU;
|
|
|
|
if($avp(s:from_pstn) == 1)
|
|
{
|
|
$avp(s:acc_caller_user) = $fU;
|
|
$avp(s:acc_caller_domain) = $avp(s:ip);
|
|
}
|
|
else if($avp(s:from_faxserver) != 1 && $var(cf_loop) != 1)
|
|
{
|
|
# if coming from CF loop, it's already passed by header
|
|
# for normal calls, set it using From
|
|
$avp(s:acc_caller_user) = $fU;
|
|
$avp(s:acc_caller_domain) = $fd;
|
|
}
|
|
if($var(cf_loop) != 1)
|
|
{
|
|
$(avp(s:acc_state)[*]) = "call";
|
|
}
|
|
|
|
if($avp(s:from_pstn) != 1 && $var(proxylu_dst_callee) != 1)
|
|
{
|
|
route(ROUTE_LOAD_CALLER_PREF);
|
|
if($avp(s:from_faxserver) != 1 && $avp(s:from_voicebox) != 1 && $var(cf_loop) != 1)
|
|
{
|
|
# set dialog for calls from subscriber
|
|
dlg_manage();
|
|
set_dlg_profile("total");
|
|
xlog("L_INFO", "Dialog set total - [% logreq -%]\n");
|
|
set_dlg_profile("user","$avp(s:caller_uuid)");
|
|
set_dlg_profile("userout","$avp(s:caller_uuid)");
|
|
set_dlg_profile("account","$avp(s:caller_account_id)");
|
|
set_dlg_profile("accountout","$avp(s:caller_account_id)");
|
|
xlog("L_INFO", "Dialog set user, userout, account, accountout to '$avp(s:caller_uuid)/$avp(s:caller_account_id)' - [% logreq -%]\n");
|
|
}
|
|
}
|
|
|
|
# IP authorization
|
|
if(
|
|
($avp(s:ignore_allowed_ips) == $null &&
|
|
$avp(s:allowed_ips_grp) == $null &&
|
|
$avp(s:man_allowed_ips_grp) == $null) ||
|
|
$avp(s:from_pstn) == 1 ||
|
|
$avp(s:from_faxserver) == 1 ||
|
|
$avp(s:from_voicebox) == 1 ||
|
|
$var(proxylu_dst_callee) == 1
|
|
)
|
|
{
|
|
xlog("L_INFO", "IP authorization for caller not provisioned, allow call - [% logreq -%]\n");
|
|
}
|
|
else if($avp(s:ignore_allowed_ips) == 1)
|
|
{
|
|
xlog("L_INFO", "IP authorization for caller disabled, allow call - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:ipauth_id)[*]) = 0;
|
|
if($avp(s:allowed_ips_grp) == $null)
|
|
{
|
|
$(avp(s:allowed_ips_grp)[*]) = 0;
|
|
}
|
|
if($avp(s:man_allowed_ips_grp) == $null)
|
|
{
|
|
$(avp(s:man_allowed_ips_grp)[*]) = 0;
|
|
}
|
|
|
|
avp_db_query("SELECT id FROM address WHERE ip_addr = INET_NTOA(INET_ATON('$(avp(s:ip){s.escape.common})') & (0xFFFFFFFF << 32 - mask & 0xFFFFFFFF)) and grp in ($avp(s:allowed_ips_grp), $avp(s:man_allowed_ips_grp))", "$avp(s:ipauth_id)");
|
|
|
|
if($avp(s:ipauth_id) == 0)
|
|
{
|
|
xlog("L_WARN", "No ipauth id found for caller, block call - [% logreq -%]\n");
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "unauth_caller_ip";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Unauthorized IP detected";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Found ipauth id '$avp(s:ipauth_id)' for caller, call authorized on IP level - [% logreq -%]\n");
|
|
}
|
|
}
|
|
|
|
$(avp(s:tmp)[*]) = $null;
|
|
if($var(cf_loop) == 1)
|
|
{
|
|
xlog("L_INFO", "Use NPN '$avp(s:caller_cli_netprov)' as UPN for CF loop - [% logreq -%]\n");
|
|
$(avp(s:caller_cli_userprov)[*]) = $avp(s:caller_cli_netprov);
|
|
$(avp(s:caller_domain_userprov)[*]) = $avp(s:caller_domain_netprov);
|
|
}
|
|
else if($var(proxylu_dst_callee) == 1)
|
|
{
|
|
xlog("L_INFO", "Use UPN '$avp(s:caller_cli_userprov)' and NPN '$avp(s:caller_cli_netprov)' from source proxy - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:caller_cli_userprov)[*]) = $null;
|
|
$(avp(s:caller_domain_userprov)[*]) = $null;
|
|
|
|
# extract UPN
|
|
if($avp(s:from_faxserver) == 1)
|
|
{
|
|
$(avp(s:caller_cli_userprov)[*]) = $avp(s:acc_caller_user);
|
|
$(avp(s:caller_domain_userprov)[*]) = $avp(s:acc_caller_domain);
|
|
# in case of calls from internal services, NPN==UPN
|
|
$(avp(s:caller_cli_netprov)[*]) = $avp(s:caller_cli_userprov);
|
|
$(avp(s:caller_domain_netprov)[*]) = $avp(s:caller_domain_userprov);
|
|
}
|
|
else
|
|
{
|
|
$var(ccli_selector) = $avp(s:caller_inbound_upn);
|
|
$var(ccli_desc) = "User-Provided CLI";
|
|
route(ROUTE_GET_CALLER_CLI);
|
|
$(avp(s:caller_cli_userprov)[*]) = $var(ccli_user);
|
|
$(avp(s:caller_domain_userprov)[*]) = $var(ccli_domain);
|
|
}
|
|
# extract NPN
|
|
if($avp(s:from_pstn) == 1)
|
|
{
|
|
$var(ccli_selector) = $avp(s:caller_inbound_npn);
|
|
$var(ccli_desc) = "Network-Provided CLI";
|
|
route(ROUTE_GET_CALLER_CLI);
|
|
$(avp(s:caller_cli_netprov)[*]) = $var(ccli_user);
|
|
$(avp(s:caller_domain_netprov)[*]) = $var(ccli_domain);
|
|
}
|
|
else if($avp(s:from_faxserver) == 1 || $avp(s:from_voicebox) == 1)
|
|
{
|
|
# in case of calls from internal services, NPN==UPN
|
|
$(avp(s:caller_cli_netprov)[*]) = $avp(s:caller_cli_userprov);
|
|
$(avp(s:caller_domain_netprov)[*]) = $avp(s:caller_domain_userprov);
|
|
}
|
|
}
|
|
# extract UPRN
|
|
# If it's a proxylu destination, the value is passed via
|
|
# headers from the source.
|
|
if($var(proxylu_dst_callee) != 1)
|
|
{
|
|
$(avp(s:forwarder_cli_userprov)[*]) = $null;
|
|
$(avp(s:forwarder_domain_userprov)[*]) = $null;
|
|
$var(ccli_user) = $null;
|
|
$var(ccli_domain) = $null;
|
|
$var(ccli_selector) = $avp(s:caller_inbound_uprn);
|
|
$var(ccli_desc) = "User-Provided Redirecting CLI";
|
|
route(ROUTE_GET_FORWARDER_CLI);
|
|
$(avp(s:forwarder_cli_userprov)[*]) = $var(ccli_user);
|
|
$(avp(s:forwarder_domain_userprov)[*]) = $var(ccli_domain);
|
|
}
|
|
|
|
if($avp(s:from_pstn) == 1 && $avp(s:pstn_dp_caller_in_id) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying caller-in peer rewrite rules on user-provided CLI using dpid '$avp(s:pstn_dp_caller_in_id)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:pstn_dp_caller_in_id)", "$avp(s:caller_cli_userprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting user-provided CLI '$avp(s:caller_cli_userprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$(avp(s:caller_cli_userprov)[*]) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$avp(s:caller_cli_userprov)' found - [% logreq -%]\n");
|
|
}
|
|
|
|
xlog("L_INFO", "Applying caller-in peer rewrite rules on network-provided CLI using dpid '$avp(s:pstn_dp_caller_in_id)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:pstn_dp_caller_in_id)", "$avp(s:caller_cli_netprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting network-provided CLI '$avp(s:caller_cli_netprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$(avp(s:caller_cli_netprov)[*]) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$avp(s:caller_cli_netprov)' found - [% logreq -%]\n");
|
|
}
|
|
|
|
if($avp(s:forwarder_cli_userprov) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying caller-in peer rewrite rules on user-provided Redirecting CLI using dpid '$avp(s:pstn_dp_caller_in_id)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:pstn_dp_caller_in_id)", "$avp(s:forwarder_cli_userprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting user-provided Redirecting CLI '$avp(s:forwarder_cli_userprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$(avp(s:forwarder_cli_userprov)[*]) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$avp(s:forwarder_cli_userprov)' found - [% logreq -%]\n");
|
|
}
|
|
}
|
|
}
|
|
else if($avp(s:from_pstn) != 1 && $avp(s:caller_dp_dom_caller_in) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying caller-in domain rewrite rules on user-provided CLI using dpid '$avp(s:caller_dp_dom_caller_in)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:caller_dp_dom_caller_in)", "$avp(s:caller_cli_userprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting user-provided CLI '$avp(s:caller_cli_userprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$avp(s:caller_cli_userprov) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$avp(s:caller_cli_userprov)' found - [% logreq -%]\n");
|
|
}
|
|
|
|
if($avp(s:forwarder_cli_userprov) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying caller-in domain rewrite rules on user-provided Redirecting CLI using dpid '$avp(s:caller_dp_dom_caller_in)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:caller_dp_dom_caller_in)", "$avp(s:forwarder_cli_userprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting user-provided Redirecting CLI '$avp(s:forwarder_cli_userprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$(avp(s:forwarder_cli_userprov)[*]) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$avp(s:forwarder_cli_userprov)' found - [% logreq -%]\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
if($avp(s:caller_cli_userprov) != $null && $avp(s:from_pstn) != 1 &&
|
|
$avp(s:from_faxserver) != 1 && $avp(s:from_voicebox) != 1 &&
|
|
$var(proxylu_dst_callee) != 1)
|
|
{
|
|
# Check UPN
|
|
$var(ccli_desc) = "User-provided CLI";
|
|
$var(userprov_cli) = $avp(s:caller_cli_userprov);
|
|
$var(userprov_domain) = $avp(s:caller_domain_userprov);
|
|
route(ROUTE_CHECK_USERPROV_CLI);
|
|
$(avp(s:caller_cli_userprov)[*]) = $var(userprov_cli);
|
|
$(avp(s:caller_domain_userprov)[*]) = $var(userprov_domain);
|
|
}
|
|
if($avp(s:forwarder_cli_userprov) != $null && $avp(s:from_pstn) != 1 &&
|
|
$avp(s:from_faxserver) != 1 && $avp(s:from_voicebox) != 1 &&
|
|
$var(proxylu_dst_callee) != 1)
|
|
{
|
|
# Check UPRN
|
|
$var(ccli_desc) = "User-provided Redirecting CLI";
|
|
$var(userprov_cli) = $avp(s:forwarder_cli_userprov);
|
|
$var(userprov_domain) = $avp(s:forwarder_domain_userprov);
|
|
route(ROUTE_CHECK_USERPROV_CLI);
|
|
$(avp(s:forwarder_cli_userprov)[*]) = $var(userprov_cli);
|
|
$(avp(s:forwarder_domain_userprov)[*]) = $var(userprov_domain);
|
|
}
|
|
|
|
# in case of CF loops, it's already set at that point
|
|
if($var(cf_loop) != 1)
|
|
{
|
|
if($avp(s:first_caller_cli_userprov) == $null)
|
|
{
|
|
$avp(s:first_caller_cli_userprov) = $avp(s:caller_cli_userprov);
|
|
$avp(s:first_caller_domain_userprov) = $avp(s:caller_domain_userprov);
|
|
|
|
xlog("L_INFO", "Setting '$avp(s:first_caller_cli_userprov)@$avp(s:first_caller_domain_userprov)' as initiating user-provided CLI - [% logreq -%]\n");
|
|
}
|
|
if($avp(s:first_caller_cli_netprov) == $null)
|
|
{
|
|
$avp(s:first_caller_cli_netprov) = $avp(s:caller_cli_netprov);
|
|
$avp(s:first_caller_domain_netprov) = $avp(s:caller_domain_netprov);
|
|
|
|
xlog("L_INFO", "Setting '$avp(s:first_caller_cli_netprov)@$avp(s:first_caller_domain_netprov)' as initiating network-provided CLI - [% logreq -%]\n");
|
|
}
|
|
}
|
|
|
|
route(ROUTE_CLIR);
|
|
|
|
route(ROUTE_FIND_CALLEE);
|
|
}
|
|
|
|
########################################################################
|
|
# Request route to extract forwarder CLI
|
|
# in: $var(ccli_selector), $var(ccli_desc)
|
|
# out: $var(ccli_user), $var(ccli_domain)
|
|
########################################################################
|
|
route[ROUTE_GET_FORWARDER_CLI]
|
|
{
|
|
if($var(cf_loop) == 1)
|
|
{
|
|
if($var(ccli_selector) == "npn" || $var(ccli_selector) == "npn_diversion")
|
|
{
|
|
$var(ccli_user) = $avp(s:caller_cli_netprov);
|
|
$var(ccli_domain) = $avp(s:caller_domain_netprov);
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(ccli_user)' taken from NPN - [% logreq -%]\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(($var(ccli_selector) == "diversion" || $var(ccli_selector) == "npn_diversion")
|
|
&& is_present_hf("Diversion"))
|
|
{
|
|
$var(ccli_user) = $(di{uri.user});
|
|
$var(ccli_domain) = $(di{uri.host});
|
|
remove_hf("Diversion");
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(ccli_user)' taken from Diversion - [% logreq -%]\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route to check user-provided CLI
|
|
# in: $var(userprov_cli), $var(userprov_domain)
|
|
# out: $var(userprov_cli), $var(userprov_domain)
|
|
# uses helper route ROUTE_CHECK_CLI_ALLOWED
|
|
########################################################################
|
|
route[ROUTE_CHECK_USERPROV_CLI]
|
|
{
|
|
if($avp(s:caller_extension_in_npn) == 1)
|
|
{
|
|
xlog("L_INFO", "Checking $var(ccli_desc) against subscriber aliases - [% logreq -%]\n");
|
|
if(avp_check("$var(userprov_cli)", "fm/$avp(s:caller_cli)/g"))
|
|
{
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(userprov_cli)' accepted - matches E.164 number '$avp(s:caller_cli)' - [% logreq -%]\n");
|
|
$(avp(s:caller_cli_netprov)[*]) = $var(userprov_cli);
|
|
#$(avp(s:caller_domain_netprov)[*]) = $avp(s:caller_domain_userprov);
|
|
}
|
|
else
|
|
{
|
|
avp_delete("$avp(s:caller_base_cli)/g");
|
|
avp_db_query("select d.alias_username from dbaliases d, subscriber s where s.username = d.username and s.uuid='$avp(s:caller_uuid)' and d.alias_username like concat(left('$(var(userprov_cli){s.escape.common})', 7), '%') and instr('$(var(userprov_cli){s.escape.common})', d.alias_username)=1 order by length(d.alias_username) desc limit 1", "$avp(s:caller_base_cli)");
|
|
if($avp(s:caller_base_cli) != $null)
|
|
{
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(userprov_cli)' accepted - matches alias number '$avp(s:caller_base_cli)' - [% logreq -%]\n");
|
|
$(avp(s:caller_cli_netprov)[*]) = $var(userprov_cli);
|
|
#$(avp(s:caller_domain_netprov)[*]) = $avp(s:caller_domain_userprov);
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_CHECK_CLI_ALLOWED);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_CHECK_CLI_ALLOWED);
|
|
}
|
|
}
|
|
########################################################################
|
|
# Request route 'invite-check-cli-allowed'
|
|
########################################################################
|
|
route[ROUTE_CHECK_CLI_ALLOWED]
|
|
{
|
|
xlog("L_INFO", "Checking $var(ccli_desc) against allowed CLIs - [% logreq -%]\n");
|
|
if(avp_check("$var(userprov_cli)", "fm/$avp(s:caller_allowed_clis)/g"))
|
|
{
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(userprov_cli)' accepted - [% logreq -%]\n");
|
|
}
|
|
else if($avp(s:caller_user_cli) != $null)
|
|
{
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(userprov_cli)' rejected, using provisioned user-provided CLI '$avp(s:caller_user_cli)' - [% logreq -%]\n");
|
|
$var(userprov_cli) = $avp(s:caller_user_cli);
|
|
$var(userprov_domain) = $avp(s:caller_domain_netprov);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "$var(ccli_desc) '$var(userprov_cli)' rejected, using network-provided CLI '$avp(s:caller_cli_netprov)' - [% logreq -%]\n");
|
|
$var(userprov_cli) = $avp(s:caller_cli_netprov);
|
|
$var(userprov_domain) = $avp(s:caller_domain_netprov);
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'invite-find-caller'
|
|
########################################################################
|
|
route[ROUTE_FIND_CALLER]
|
|
{
|
|
$(avp(s:tmpfaxgw)[*]) = 0;
|
|
if($fu == "sip:[% reminder.sip_fromuser %]@[% reminder.sip_fromdomain %]")
|
|
{
|
|
$(avp(s:tmpfaxgw)[*]) = 0; # reminder
|
|
}
|
|
else if($var(sendfax) == 1)
|
|
{
|
|
$(avp(s:tmpfaxgw)[*]) = 4; # faxserver
|
|
}
|
|
else
|
|
{
|
|
# only check for other faxserver if not coming from asterisk
|
|
# do extra check in query that call doesn't come from sems/click2dial
|
|
avp_db_query("select setid from dispatcher where setid=4 and destination='sip:$(avp(s:ip){s.escape.common}):$(avp(s:port){s.escape.common})'", "$avp(s:tmpfaxgw)");
|
|
}
|
|
$(avp(s:app_server_params)[*]) = $null;
|
|
if($var(proxylu_dst_callee) == 1)
|
|
{
|
|
$avp(s:caller_uuid) = "0";
|
|
$avp(s:caller_domain) = $fd;
|
|
xlog("L_INFO", "Call from other proxy - [% logreq -%]\n");
|
|
$var(noauth) = 1;
|
|
|
|
$(avp(s:first_caller_cli_userprov)[*]) = $(hdr(P-First-Caller-UPN){uri.user});
|
|
$(avp(s:first_caller_domain_userprov)[*]) = $(hdr(P-First-Caller-UPN){uri.domain});
|
|
$(avp(s:first_caller_cli_netprov)[*]) = $(hdr(P-First-Caller-NPN){uri.user});
|
|
$(avp(s:first_caller_domain_netprov)[*]) = $(hdr(P-First-Caller-NPN){uri.domain});
|
|
$(avp(s:forwarder_cli_userprov)[*]) = $(hdr(P-First-Forwarder-UPN){uri.user});
|
|
$(avp(s:forwarder_domain_userprov)[*]) = $(hdr(P-First-Forwarder-UPN){uri.domain});
|
|
$(avp(s:caller_cli_userprov)[*]) = $(hdr(P-Caller-UPN){uri.user});
|
|
$(avp(s:caller_domain_userprov)[*]) = $(hdr(P-Caller-UPN){uri.domain});
|
|
$(avp(s:caller_cli_netprov)[*]) = $(hdr(P-Caller-NPN){uri.user});
|
|
$(avp(s:caller_domain_netprov)[*]) = $(hdr(P-Caller-NPN){uri.domain});
|
|
$(avp(s:initial_caller_ipv46_for_rtpproxy)[*]) = $hdr(P-First-V46-RTP);
|
|
$(avp(s:first_caller_use_rtpproxy)[*]) = $hdr(P-First-RTP);
|
|
$(avp(s:caller_clir)[*]) = $hdr(P-Caller-CLIR);
|
|
|
|
$(avp(s:tmp)[*]) = $hdr(P-Caller-PeerInfo);
|
|
$(avp(s:caller_force_outbound_calls_to_peer)[*]) = $avp(s:tmp);
|
|
if(!avp_subst("$avp(s:caller_force_outbound_calls_to_peer)", "/^([0-1]).*$/\1/"))
|
|
{
|
|
$(avp(s:caller_force_outbound_calls_to_peer)[*]) = $null;
|
|
}
|
|
$(avp(s:caller_peer_auth_user)[*]) = $avp(s:tmp);
|
|
if(!avp_subst("$avp(s:caller_peer_auth_user)", "/^[0-1](;([^;]+);.*)?$/\2/"))
|
|
{
|
|
$(avp(s:caller_peer_auth_user)[*]) = $null;
|
|
}
|
|
$(avp(s:caller_peer_auth_realm)[*]) = $avp(s:tmp);
|
|
if(!avp_subst("$avp(s:caller_peer_auth_realm)", "/^[0-1](;[^;]+;([^;]+);.*)?$/\2/"))
|
|
{
|
|
$(avp(s:caller_peer_auth_realm)[*]) = $null;
|
|
}
|
|
$(avp(s:caller_peer_auth_pass)[*]) = $avp(s:tmp);
|
|
if(!avp_subst("$avp(s:caller_peer_auth_pass)", "/^[0-1](;[^;]+;[^;]+;([^;]+).*)?$/\2/"))
|
|
{
|
|
$(avp(s:caller_peer_auth_pass)[*]) = $null;
|
|
}
|
|
|
|
route(ROUTE_CLEAR_PROXYLU_HEADERS);
|
|
}
|
|
else if(from_any_gw($avp(s:ip), $avp(s:protoid)))
|
|
{
|
|
$(avp(s:caller_uuid)[*]) = "0";
|
|
|
|
xlog("L_INFO", "Call from PSTN - [% logreq -%]\n");
|
|
$var(noauth) = 1;
|
|
$(avp(s:from_pstn)[*]) = 1;
|
|
if($avp(s:lcr_flags) != $null && $avp(s:lcr_flags) != 0)
|
|
{
|
|
route(ROUTE_CLEAR_PEER_IN_PREF);
|
|
route(ROUTE_LOAD_PEER_IN_PREF);
|
|
}
|
|
}
|
|
else if(ds_is_from_list("3") && is_present_hf("P-CF-Depth"))
|
|
{
|
|
xlog("L_INFO", "Internal CF loop - [% logreq -%]\n");
|
|
$var(cf_loop) = 1;
|
|
$(avp(s:caller_uuid)[*]) = $hdr(P-Caller-UUID);
|
|
$(avp(s:first_caller_cli_userprov)[*]) = $hdr(P-First-Caller-UPN);
|
|
$(avp(s:first_caller_cli_netprov)[*]) = $hdr(P-First-Caller-NPN);
|
|
$(avp(s:first_caller_domain_userprov)[*]) = $hdr(P-First-Caller-UPD);
|
|
$(avp(s:first_caller_domain_netprov)[*]) = $hdr(P-First-Caller-NPD);
|
|
$(avp(s:acc_caller_user)[*]) = $hdr(P-Acc-Caller-User);
|
|
$(avp(s:acc_caller_domain)[*]) = $hdr(P-Acc-Caller-Domain);
|
|
$(avp(s:acc_state)[*]) = $hdr(P-Acc-State);
|
|
$(avp(s:cf_from_pstn)[*]) = $hdr(P-From-Peer);
|
|
$(avp(s:initial_caller_ipv46_for_rtpproxy)[*]) = $hdr(P-First-V46-RTP);
|
|
$(avp(s:first_caller_use_rtpproxy)[*]) = $hdr(P-First-RTP);
|
|
$(avp(s:caller_clir)[*]) = $hdr(P-Caller-CLIR);
|
|
$(avp(s:cf_depth)[*]) = $hdr(P-CF-Depth);
|
|
|
|
remove_hf("P-Caller-UUID");
|
|
remove_hf("P-First-Caller-UPN");
|
|
remove_hf("P-First-Caller-NPN");
|
|
remove_hf("P-First-Caller-UPD");
|
|
remove_hf("P-First-Caller-NPD");
|
|
remove_hf("P-Acc-Caller-User");
|
|
remove_hf("P-Acc-Caller-Domain");
|
|
remove_hf("P-Acc-State");
|
|
remove_hf("P-From-Peer");
|
|
remove_hf("P-First-V46-RTP");
|
|
remove_hf("P-First-RTP");
|
|
remove_hf("P-Caller-CLIR");
|
|
remove_hf("P-CF-Depth");
|
|
|
|
if($rd =~ "^.+\.local$")
|
|
{
|
|
# keep external and account ids on forward to fax2mail and voicemail
|
|
$(avp(s:callee_ext_subscriber_id)[*]) = $hdr(P-Callee-Ext-Subs-ID);
|
|
$(avp(s:callee_ext_contract_id)[*]) = $hdr(P-Callee-Ext-Contr-ID);
|
|
$(avp(s:callee_account_id)[*]) = $hdr(P-Callee-Account-ID);
|
|
remove_hf("P-Callee-Ext-Subs-ID");
|
|
remove_hf("P-Callee-Ext-Contr-ID");
|
|
remove_hf("P-Callee-Account-ID");
|
|
}
|
|
}
|
|
else if($avp(s:tmpfaxgw) == 4)
|
|
{
|
|
xlog("L_INFO", "Call from Faxserver - [% logreq -%]\n");
|
|
$var(noauth) = 1;
|
|
$(avp(s:from_faxserver)[*]) = 1;
|
|
$var(local_endpoint) = 1;
|
|
$(avp(s:tmp)[*]) = 0;
|
|
$(avp(s:tmp_domain)[*]) = 0;
|
|
|
|
if($var(sendfax) == 1)
|
|
{
|
|
# iaxmodem setup
|
|
$(avp(s:tmp)[*]) = $fn;
|
|
avp_subst("$avp(s:tmp)", "/^\"?([^\"]*)\"?$/\1/");
|
|
$var(fU) = $avp(s:tmp);
|
|
$(avp(s:tmp)[*]) = $null;
|
|
}
|
|
else
|
|
{
|
|
# dialogic/patton setup
|
|
$(avp(s:tmp)[*]) = $fU;
|
|
avp_subst("$avp(s:tmp)", "/^(\+|00)?(.+)$/\2/");
|
|
$var(fU) = $avp(s:tmp);
|
|
$(avp(s:tmp)[*]) = $null;
|
|
}
|
|
|
|
xlog("L_INFO", "Faxserver caller is '$var(fU)' - [% logreq -%]\n");
|
|
avp_db_query("select s.uuid, s.username, s.domain from subscriber s, dbaliases d where d.alias_username like concat(left('$(var(fU){s.escape.common})', 7), '%') and instr('$(var(fU){s.escape.common})', d.alias_username)=1 and d.username = s.username order by length(alias_username) desc limit 1", "$avp(s:caller_uuid);$avp(s:tmp);$avp(s:tmp_domain)");
|
|
if($avp(s:caller_uuid) == $null)
|
|
{
|
|
xlog("L_WARN", "Unknown caller in call from Faxserver - [% logreq -%]\n");
|
|
route(ROUTE_ACC_FAILURE);
|
|
t_reply("403", "Unknown Faxserver caller");
|
|
exit;
|
|
}
|
|
else
|
|
{
|
|
$avp(s:acc_caller_user) = $avp(s:tmp);
|
|
$avp(s:acc_caller_domain) = $avp(s:tmp_domain);
|
|
$rd = $avp(s:acc_caller_domain);
|
|
xlog("L_INFO", "Setting From info for Faxserver call to '$avp(s:tmp)@$avp(s:tmp_domain)' - [% logreq -%]\n");
|
|
}
|
|
|
|
#Dialog handling for incoming request from Faxserver
|
|
dlg_manage();
|
|
set_dlg_profile("total");
|
|
xlog("L_INFO", "Dialog set mark TOTAL - [% logreq -%]\n");
|
|
set_dlg_profile("peer","faxserver");
|
|
xlog("L_INFO", "Dialog set mark peer to faxserver - [% logreq -%]\n");
|
|
}
|
|
else if(ds_is_from_list("2"))
|
|
{
|
|
xlog("L_INFO", "Call from Voicebox - [% logreq -%]\n");
|
|
$var(noauth) = 1;
|
|
$avp(s:from_voicebox) = 1;
|
|
$var(local_endpoint) = 1;
|
|
if(subst_uri('/^sip:(.+)__AT__(.+)@.+$/sip:\1@\2/'))
|
|
{
|
|
xlog("L_INFO", "Replaced reminder uri and to - [% logreq -%]\n");
|
|
}
|
|
$(avp(s:tmp)[*]) = 0;
|
|
$var(fU) = $fU;
|
|
xlog("L_INFO", "Voicebox caller is '$var(fU)' - [% logreq -%]\n");
|
|
avp_db_query("select s.uuid, d.alias_username from subscriber s, dbaliases d where d.alias_username like concat(left('$(var(fU){s.escape.common})', 7), '%') and instr('$(var(fU){s.escape.common})', d.alias_username)=1 and d.username = s.username order by length(alias_username) desc limit 1", "$avp(s:caller_uuid);$avp(s:tmp)");
|
|
if($avp(s:caller_uuid) == $null)
|
|
{
|
|
xlog("L_INFO", "Unknown caller in call from Voicebox - [% logreq -%]\n");
|
|
$avp(s:caller_uuid) = "0";
|
|
}
|
|
#Dialog handling for incoming request from Voicemail server
|
|
dlg_manage();
|
|
set_dlg_profile("total");
|
|
xlog("L_INFO", "Dialog set mark TOTAL - [% logreq -%]\n");
|
|
set_dlg_profile("peer","voicebox");
|
|
xlog("L_INFO", "Dialog set mark peer to voicebox - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_AUTH);
|
|
#!ifdef ENABLE_AUTHCHECK
|
|
sl_send_reply("101", "Connecting");
|
|
#!endif
|
|
}
|
|
record_route();
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'emergency'
|
|
########################################################################
|
|
route[ROUTE_EMERGENCY]
|
|
{
|
|
xlog("L_INFO", "Emergency call detected - [% logreq -%]\n");
|
|
|
|
if($xavp(caller_real_prefs=>reject_emergency) == 1)
|
|
{
|
|
$var(announce_handle) = "emergency_unsupported";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Emergency Calls Not Supported";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
$(avp(s:em_call)[*]) = 1;
|
|
$(avp(s:callee_uuid)[*]) = 0;
|
|
$(avp(s:caller_clir)[*]) = 0;
|
|
|
|
# always use network-provided CLI for emergency calls
|
|
# TODO: make it configurable via usr-prefs once we have multi-selects
|
|
$(avp(s:caller_cli_userprov)[*]) = $avp(s:caller_cli_netprov);
|
|
$(avp(s:caller_domain_userprov)[*]) = $avp(s:caller_domain_netprov);
|
|
$(avp(s:first_caller_cli_userprov)[*]) = $avp(s:caller_cli_userprov);
|
|
$(avp(s:first_caller_domain_userprov)[*]) = $avp(s:caller_domain_userprov);
|
|
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$(avp(s:callee_user)[*]) = $avp(s:acc_callee_user_in);
|
|
$avp(s:acc_callee_user) = $rU;
|
|
$avp(s:acc_callee_domain) = $rd;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
$(avp(s:callee_uuid)[*]) = 0;
|
|
|
|
# Dialog handling for emergency call
|
|
set_dlg_profile("emergency");
|
|
xlog("L_INFO", "Dialog set mark emergency - [% logreq -%]\n");
|
|
|
|
route(ROUTE_PSTN);
|
|
exit;
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'invite-find-callee'
|
|
########################################################################
|
|
route[ROUTE_FIND_CALLEE]
|
|
{
|
|
xlog("L_INFO", "Searching for callee - [% logreq -%]\n");
|
|
# make sure to init it to 0 again if we come from a failure-route also
|
|
$var(loose_routed) = 0;
|
|
if($var(forward) == 1) # TODO: also for cf_loop?
|
|
{
|
|
xlog("L_INFO", "Setting network-provided info as user-provided info for call-forward - [% logreq -%]\n");
|
|
$(avp(s:caller_domain_userprov)[*]) = $avp(s:caller_domain_netprov);
|
|
$(avp(s:caller_cli_userprov)[*]) = $avp(s:caller_cli_netprov);
|
|
|
|
avp_delete("$avp(s:acc_callee_dialed)/g");
|
|
$avp(s:acc_callee_dialed) = $rU;
|
|
$var(no_auth) = 0;
|
|
}
|
|
|
|
if($var(no_auth) == 0 && uri =~ "^sip:\*[0-9]@" && $var(cf_loop) != 1)
|
|
{
|
|
if(sd_lookup("speed_dial"))
|
|
{
|
|
xlog("L_INFO", "Speed-Dial translation done - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Speed-Dial slot not found - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $rU;
|
|
$avp(s:acc_callee_domain) = $rd;
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
$avp(s:callee_uuid) = 0;
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "invalid_speeddial";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 484;
|
|
$(avp(s:announce_reason)[*]) = "Speed-Dial slot empty";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
|
|
if($var(no_auth) == 1 && $var(forward) != 1 && $var(cf_loop) != 1)
|
|
{
|
|
xlog("L_INFO", "Skipping internal services for unauthenticated call - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
# NOTE: we explicitely do rewrite forwards if caught by 3xx
|
|
|
|
# TODO: this block can be removed with new ossbss number normalization, keep it now for backwards compatibility.
|
|
if(($var(forward) == 1 || $var(cf_loop) == 1) && $var(redirected_forward) != 1 && $rU =~ "^\+[1-9][0-9]+$")
|
|
{
|
|
strip(1);
|
|
xlog("L_INFO", "Stripping leading '+' for forwarded call - [% logreq -%]\n");
|
|
}
|
|
else if(($var(forward) == 0 || $var(redirected_forward) == 1) && $var(cf_loop) != 1 && $avp(s:from_pstn) == 1 && $avp(s:pstn_dp_callee_in_id) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying callee-in peer rewrite rules using dpid '$avp(s:pstn_dp_callee_in_id)' - [% logreq -%]\n");
|
|
$var(dp_ru) = $null;
|
|
if(dp_translate("$avp(s:pstn_dp_callee_in_id)", "$rU/$var(dp_ru)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting callee '$rU' to '$var(dp_ru)' - [% logreq -%]\n");
|
|
$rU = $var(dp_ru);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$rU' found - [% logreq -%]\n");
|
|
}
|
|
}
|
|
else if(($var(forward) == 0 || $var(redirected_forward) == 1) && $var(cf_loop) != 1 && $avp(s:from_pstn) != 1 && $avp(s:caller_dp_dom_callee_in) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying callee-in domain rewrite rules using dpid '$avp(s:caller_dp_dom_callee_in)' - [% logreq -%]\n");
|
|
$var(dp_ru) = $null;
|
|
if(dp_translate("$avp(s:caller_dp_dom_callee_in)", "$rU/$var(dp_ru)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting callee '$rU' to '$var(dp_ru)' - [% logreq -%]\n");
|
|
$rU = $var(dp_ru);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$rU' found - [% logreq -%]\n");
|
|
}
|
|
}
|
|
|
|
if(uri =~ "^sip:emergency_")
|
|
{
|
|
route(ROUTE_EMERGENCY);
|
|
exit;
|
|
}
|
|
#apogrebennyk: forwarding to voicebox, conference and fax2mail should work even if the subscriber is locked for outgoing calls.
|
|
if((avp_check("$avp(s:caller_lock)", "eq/s:2") ||
|
|
avp_check("$avp(s:caller_lock)", "eq/s:3") ||
|
|
avp_check("$avp(s:caller_lock)", "eq/s:4")) &&
|
|
$var(forward) != 1 && !($rd =~ "^.+\.local$" && $var(cf_loop) == 1))
|
|
{
|
|
xlog("L_INFO", "Caller locked for outgoing with mode '$avp(s:caller_lock)' - [% logreq -%]\n");
|
|
if($avp(s:callee_uuid) == $null)
|
|
{
|
|
$avp(s:callee_uuid) = "0";
|
|
}
|
|
if($avp(s:callee_user) == $null)
|
|
{
|
|
$avp(s:callee_user) = $rU;
|
|
}
|
|
if($avp(s:callee_domain) == $null)
|
|
{
|
|
$avp(s:callee_domain) = $rd;
|
|
}
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "locked_out";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Caller locked";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
# Dialog count for caller. Need to check after emergency calls have been detected not to drop them.
|
|
# Dialog count caller subscriber/domain concurrent_max
|
|
if($xavp(caller_real_prefs=>concurrent_max) != $null && $xavp(caller_real_prefs=>concurrent_max) != 0)
|
|
{
|
|
if(get_profile_size("user","$avp(s:caller_uuid)","$avp(s:size)"))
|
|
{
|
|
if ($avp(s:size) > $xavp(caller_real_prefs=>concurrent_max))
|
|
{
|
|
xlog("L_INFO", "Concurrent_max calls exceeded for caller '$avp(s:caller_uuid)' - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "max_calls_out";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Maximum parallel calls exceeded";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
}
|
|
# Dialog count caller subscriber/domain concurrent_max_out
|
|
if($xavp(caller_real_prefs=>concurrent_max_out) != $null && $xavp(caller_real_prefs=>concurrent_max_out) != 0)
|
|
{
|
|
if(get_profile_size("userout","$avp(s:caller_uuid)","$avp(s:size)"))
|
|
{
|
|
if ($avp(s:size) > $xavp(caller_real_prefs=>concurrent_max_out))
|
|
{
|
|
xlog("L_INFO", "Concurrent_max outbound calls exceeded for caller '$avp(s:caller_uuid)' - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "max_calls_out";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Maximum parallel calls exceeded";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
# Dialog count caller subscriber/domain concurrent_max per account
|
|
if($xavp(caller_real_prefs=>concurrent_max_per_account) != $null && $xavp(caller_real_prefs=>concurrent_max_per_account) != 0)
|
|
{
|
|
if(get_profile_size("account","$avp(s:caller_account_id)","$avp(s:size)"))
|
|
{
|
|
if ($avp(s:size) > $xavp(caller_real_prefs=>concurrent_max_per_account))
|
|
{
|
|
xlog("L_INFO", "Concurrent_max calls per account exceeded for caller '$avp(s:caller_uuid)' in account '$avp(s:caller_account_id)' - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "max_calls_out";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Maximum parallel calls exceeded";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
}
|
|
# Dialog count caller subscriber/domain concurrent_max_out per account
|
|
if($xavp(caller_real_prefs=>concurrent_max_out_per_account) != $null && $xavp(caller_real_prefs=>concurrent_max_out_per_account) != 0)
|
|
{
|
|
if(get_profile_size("accountout","$avp(s:caller_account_id)","$avp(s:size)"))
|
|
{
|
|
if ($avp(s:size) > $xavp(caller_real_prefs=>concurrent_max_out_per_account))
|
|
{
|
|
xlog("L_INFO", "Concurrent_max outbound calls per account exceeded for caller '$avp(s:caller_uuid) in account '$avp(s:caller_account_id)' - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "max_calls_out";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Maximum parallel calls exceeded";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
# Dialog count caller peer concurrent_max
|
|
if($avp(s:from_pstn) == 1 && $xavp(caller_peer_prefs=>concurrent_max) != $null && $xavp(caller_peer_prefs=>concurrent_max) != 0)
|
|
{
|
|
if(get_profile_size("peer","$avp(s:lcr_flags)","$avp(s:size)"))
|
|
{
|
|
if ($avp(s:size) > $xavp(caller_peer_prefs=>concurrent_max))
|
|
{
|
|
xlog("L_INFO", "Concurrent_max calls exceeded for peer '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "max_calls_peer";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Maximum parallel calls exceeded";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
#!ifdef ENABLE_VSC
|
|
if(uri =~ "^sip:\*[0-9][0-9]\*.*@" || uri =~ "^sip:\%23[0-9][0-9](\%23)?.*@")
|
|
{
|
|
xlog("L_INFO", "VSC request - [% logreq -%]\n");
|
|
$rd="vsc.local";
|
|
if(is_present_hf("P-App-Name"))
|
|
{
|
|
remove_hf("P-App-Name");
|
|
}
|
|
append_hf("P-App-Name: sw_vsc\r\n");
|
|
t_on_failure("FAILURE_ROUTE_APPSRV");
|
|
route(ROUTE_TO_APPSRV);
|
|
exit;
|
|
}
|
|
#!endif
|
|
|
|
#!ifdef ENABLE_CONFERENCE
|
|
else if(uri =~ "@conference\.local$")
|
|
{
|
|
xlog("L_INFO", "Conference request - [% logreq -%]\n");
|
|
if(is_present_hf("P-App-Name"))
|
|
{
|
|
remove_hf("P-App-Name");
|
|
}
|
|
append_hf("P-App-Name: conference\r\n");
|
|
t_on_failure("FAILURE_ROUTE_APPSRV");
|
|
route(ROUTE_TO_APPSRV);
|
|
exit;
|
|
}
|
|
#!endif
|
|
|
|
#!ifdef ENABLE_VOICEMAIL
|
|
else if(uri =~ "@voicebox\.local$")
|
|
{
|
|
route(ROUTE_VOICEBOX);
|
|
}
|
|
#!endif
|
|
else if(uri =~ "@fax2mail\.local$")
|
|
{
|
|
route(ROUTE_FAXSERVER);
|
|
}
|
|
#!ifdef ENABLE_VOICEMAIL
|
|
else if(uri =~ "^sip:voicebox@" || uri =~ "^sip:[% sems.vsc.voicemail_number %]@")
|
|
{
|
|
$rU = $avp(s:caller_cli_netprov);
|
|
$rd = 'voicebox.local';
|
|
prefix("abc");
|
|
route(ROUTE_VOICEBOX);
|
|
|
|
exit;
|
|
}
|
|
else if(uri =~ "^sip:voiceboxpass@")
|
|
{
|
|
$rd = 'voicebox.local';
|
|
prefix("bcd");
|
|
route(ROUTE_VOICEBOX);
|
|
|
|
exit;
|
|
}
|
|
#!endif
|
|
|
|
}
|
|
|
|
avp_delete("$avp(s:callee_cli)/g");
|
|
$avp(s:callee_cli) = $rU;
|
|
|
|
if(!isflagset(FLAG_IN_FALLBACK))
|
|
{
|
|
$(avp(s:acc_callee_user_in)[*]) = $rU;
|
|
$(avp(s:acc_callee_domain_in)[*]) = $rd;
|
|
}
|
|
|
|
avp_delete("$avp(s:has_extension)/g");
|
|
avp_delete("$avp(s:callee_user)/g");
|
|
avp_delete("$avp(s:callee_base_user)/g");
|
|
avp_delete("$avp(s:callee_domain)/g");
|
|
avp_db_query("select username,domain,alias_username from dbaliases where alias_username like concat(left('$(rU{s.escape.common})', 7), '%') and instr('$(rU{s.escape.common})', alias_username)=1 order by length(alias_username) desc limit 1", "$avp(s:callee_user);$avp(s:callee_domain);$avp(s:callee_base_user)");
|
|
if($avp(s:callee_user) != $null && $avp(s:callee_domain) != $null)
|
|
{
|
|
$rU = $avp(s:callee_user);
|
|
$rd = $avp(s:callee_domain);
|
|
if($avp(s:acc_callee_user_in) != $avp(s:callee_base_user))
|
|
{
|
|
$avp(s:has_extension) = 1;
|
|
xlog("L_INFO", "Callee was aliased with extension '$avp(s:callee_base_user)' - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Callee was aliased with base '$avp(s:callee_base_user)' - [% logreq -%]\n");
|
|
}
|
|
}
|
|
else if ($xavp(caller_peer_prefs=>find_subscriber_by_uuid) == 1)
|
|
{
|
|
avp_delete("$avp(s:has_extension)/g");
|
|
avp_delete("$avp(s:callee_user)/g");
|
|
avp_delete("$avp(s:callee_base_user)/g");
|
|
avp_delete("$avp(s:callee_domain)/g");
|
|
|
|
if($(ru{uri.param,uuid}) != $null)
|
|
{
|
|
$var(tmpuuid) = $(ru{uri.param,uuid});
|
|
xlog("L_INFO", "Using ruri-uuid-param '$var(tmpuuid)' as uuid for subscriber lookup - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
$var(tmpuuid) = $rU;
|
|
xlog("L_INFO", "Using ruri-user '$var(tmpuuid)' as uuid for subscriber lookup - [% logreq -%]\n");
|
|
}
|
|
avp_db_query("select username, domain from usr_preferences where uuid='$(var(tmpuuid){s.escape.common})' limit 1", "$avp(s:callee_user);$avp(s:callee_domain)");
|
|
if($avp(s:callee_user) != $null && $avp(s:callee_domain) != $null)
|
|
{
|
|
$rU = $avp(s:callee_user);
|
|
$rd = $avp(s:callee_domain);
|
|
xlog("L_INFO", "Callee was found using uuid - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
$avp(s:callee_user) = $rU;
|
|
$avp(s:callee_domain) = $rd;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$avp(s:callee_user) = $rU;
|
|
$avp(s:callee_domain) = $rd;
|
|
}
|
|
|
|
route(ROUTE_CLEAR_CALLEE_PREF);
|
|
if($var(no_auth) == 0 && !is_domain_local("$rd"))
|
|
{
|
|
#TODO Handle dialog marks for foreign domains
|
|
$var(external_domain) = 1;
|
|
$avp(s:callee_uuid) = "0";
|
|
|
|
if($var(adm_block_override) == 1)
|
|
{
|
|
xlog("L_INFO", "Administrative NCOS overridden, skip - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Check Administrative NCOS level - [% logreq -%]\n");
|
|
$(avp(s:tmp_ncos_id)[*]) = $null;
|
|
avp_copy("$avp(s:caller_adm_ncos_id)", "$avp(s:tmp_ncos_id)");
|
|
route(ROUTE_NCOS);
|
|
}
|
|
|
|
if($var(block_override) == 1)
|
|
{
|
|
xlog("L_INFO", "NCOS overridden, skip - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Check User NCOS level - [% logreq -%]\n");
|
|
$(avp(s:tmp_ncos_id)[*]) = $null;
|
|
avp_copy("$avp(s:caller_ncos_id)", "$avp(s:tmp_ncos_id)");
|
|
route(ROUTE_NCOS);
|
|
}
|
|
|
|
route(ROUTE_BLOCK_OUT);
|
|
route(ROUTE_INVITE_TO_EXT);
|
|
}
|
|
avp_delete("$avp(s:callee_uuid)");
|
|
[% IF kamailio.proxy.ignore_auth_realm == "yes" %]
|
|
avp_db_query("select uuid from subscriber where username = '$(rU{s.escape.common})'", "$avp(s:callee_uuid)");
|
|
[% ELSE %]
|
|
avp_db_query("select uuid from subscriber where username = '$(rU{s.escape.common})' and domain = '$(rd{s.escape.common})'", "$avp(s:callee_uuid)");
|
|
[% END %]
|
|
if($avp(s:callee_uuid) != $null)
|
|
{
|
|
xlog("L_INFO", "Callee is local, uuid='$avp(s:callee_uuid)' - [% logreq -%]\n");
|
|
append_to_reply("P-Callee-Uuid: $avp(s:callee_uuid)\r\n");
|
|
if($var(cf_loop) == 1 && $avp(s:caller_uuid) == $avp(s:callee_uuid))
|
|
{
|
|
xlog("L_INFO", "Callee is forwarding to itself, reject call - [% logreq -%]\n");
|
|
$var(announce_handle) = "cf_loop";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 480;
|
|
$(avp(s:announce_reason)[*]) = "Unavailable";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
if($var(adm_block_override) == 1)
|
|
{
|
|
xlog("L_INFO", "Administrative NCOS overridden, skip - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Check Administrative NCOS level - [% logreq -%]\n");
|
|
$(avp(s:tmp_ncos_id)[*]) = $null;
|
|
avp_copy("$avp(s:caller_adm_ncos_id)", "$avp(s:tmp_ncos_id)");
|
|
route(ROUTE_NCOS);
|
|
}
|
|
|
|
if($var(block_override) == 1)
|
|
{
|
|
xlog("L_INFO", "NCOS overridden, skip - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Check User NCOS level - [% logreq -%]\n");
|
|
$(avp(s:tmp_ncos_id)[*]) = $null;
|
|
avp_copy("$avp(s:caller_ncos_id)", "$avp(s:tmp_ncos_id)");
|
|
route(ROUTE_NCOS);
|
|
}
|
|
|
|
# check block-out-list
|
|
route(ROUTE_BLOCK_OUT);
|
|
|
|
if($avp(s:caller_force_outbound_calls_to_peer) == 1)
|
|
{
|
|
if ($var(local_endpoint) == 0 && $avp(s:from_faxserver) == 0 && $avp(s:from_voicebox) == 0)
|
|
{
|
|
xlog("L_INFO", "Force on-net call to peer by caller's preference - [% logreq -%]\n");
|
|
route(ROUTE_LOAD_CALLEE_PREF);
|
|
route(ROUTE_INVITE_TO_EXT);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Keep call from local endpoint on-net, ignore caller's preference - [% logreq -%]\n");
|
|
route(ROUTE_LOAD_CALLEE_PREF);
|
|
route(ROUTE_INVITE_TO_INT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_LOAD_CALLEE_PREF);
|
|
route(ROUTE_INVITE_TO_INT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$avp(s:callee_uuid) = "0";
|
|
xlog("L_INFO", "Callee is not local - [% logreq -%]\n");
|
|
|
|
#!ifdef PROXY_LOOKUP
|
|
xlog("L_INFO", "Performing proxy lookup for callee - [% logreq -%]\n");
|
|
$var(proxylu_target) = "callee";
|
|
$var(proxylu_user) = $(rU{s.escape.common});
|
|
$var(proxylu_domain) = $(rd{s.escape.common});
|
|
$var(proxylu_cache_user) = $var(proxylu_user);
|
|
$var(proxylu_cache_domain) = $var(proxylu_domain);
|
|
route(ROUTE_PERFORM_PROXYLU);
|
|
#!endif
|
|
|
|
if($var(adm_block_override) == 1)
|
|
{
|
|
xlog("L_INFO", "Administrative NCOS overridden, skip - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Check Administrative NCOS level - [% logreq -%]\n");
|
|
$(avp(s:tmp_ncos_id)[*]) = $null;
|
|
avp_copy("$avp(s:caller_adm_ncos_id)", "$avp(s:tmp_ncos_id)");
|
|
route(ROUTE_NCOS);
|
|
}
|
|
|
|
if($var(block_override) == 1)
|
|
{
|
|
xlog("L_INFO", "NCOS overridden, skip - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Check User NCOS level - [% logreq -%]\n");
|
|
$(avp(s:tmp_ncos_id)[*]) = $null;
|
|
avp_copy("$avp(s:caller_ncos_id)", "$avp(s:tmp_ncos_id)");
|
|
route(ROUTE_NCOS);
|
|
}
|
|
|
|
# check block-out-list
|
|
route(ROUTE_BLOCK_OUT);
|
|
|
|
route(ROUTE_INVITE_TO_EXT);
|
|
}
|
|
exit;
|
|
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'invite-to-internal'
|
|
########################################################################
|
|
route[ROUTE_INVITE_TO_INT]
|
|
{
|
|
if($avp(s:callee_force_inbound_calls_to_peer) == 1)
|
|
{
|
|
xlog("L_INFO", "Callee forced to outbound peer by preference - [% logreq -%]\n");
|
|
route(ROUTE_INVITE_TO_EXT);
|
|
exit;
|
|
}
|
|
if($avp(s:callee_base_user) != $null)
|
|
{
|
|
$var(orig_ruri_user) = $rU;
|
|
#$rU = $avp(s:callee_base_user);
|
|
xlog("L_INFO", "Performing location lookup with main subscriber - [% logreq -%]\n");
|
|
}
|
|
|
|
#Dialog handle: Mark call type
|
|
#FIXME: Should this go after looku(location) block and avoid marks in case we have CF or EARLY_REJECT?
|
|
if($avp(s:from_pstn) == 1)
|
|
{
|
|
set_dlg_profile("type","incoming");
|
|
xlog("L_INFO", "Dialog set mark type to incoming - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
set_dlg_profile("type","local");
|
|
xlog("L_INFO", "Dialog set mark type to local - [% logreq -%]\n");
|
|
}
|
|
|
|
if(!lookup("location"))
|
|
{
|
|
if($avp(s:callee_base_user) != $null)
|
|
{
|
|
$rU = $var(orig_ruri_user);
|
|
}
|
|
|
|
xlog("L_INFO", "Local user offline - [% logreq -%]\n");
|
|
while($avp(s:callee_cfna) != $null)
|
|
{
|
|
$var(cf_id) = $(avp(s:callee_cfna)[0]);
|
|
xlog("L_INFO", "CFNA to CF map id '$var(cf_id)' found - [% logreq -%]\n");
|
|
route(ROUTE_LOAD_CF_MAP);
|
|
while($avp(s:cf_destinations) != $null && $(avp(s:cf_destinations)[0]) =~ "^sip:localuser@.+\.local$")
|
|
{
|
|
xlog("L_INFO", "CFNA breakout to local user skipped - [% logreq -%]\n");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
}
|
|
if($avp(s:cf_destinations) == $null)
|
|
{
|
|
xlog("L_INFO", "CFNA skipped due to forward destinations definitions - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_CHECK_CF_PERIOD);
|
|
if($rc == 1)
|
|
{
|
|
xlog("L_INFO", "CFNA to destination '$(avp(s:cf_destinations)[0])' with timeout '$(avp(s:cf_timeouts)[0])' activated - [% logreq -%]\n");
|
|
$ru = $(avp(s:cf_destinations)[0]);
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
$(avp(s:callee_fr_inv_timer)[*]) = $(avp(s:cf_timeouts)[0]) * 1000;
|
|
t_set_fr("$avp(s:callee_fr_inv_timer)");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_depth)[*]) = $(avp(s:cf_depth){s.int}) + 1;
|
|
route(ROUTE_ACC_CF);
|
|
$(avp(s:acc_state)[*]) = "cfna";
|
|
$(avp(s:acc_caller_user)[*]) = $avp(s:acc_callee_user);
|
|
$(avp(s:acc_caller_domain)[*]) = $avp(s:acc_callee_domain);
|
|
route(ROUTE_EXECUTE_CF_LOOP);
|
|
exit;
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "CFNA skipped due to time period definitions - [% logreq -%]\n");
|
|
}
|
|
}
|
|
$(avp(s:callee_cfna)[0]) = $null;
|
|
}
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
# TODO: need to care about changing reason in accounting from 404 to 480?
|
|
route(ROUTE_ACC_FAILURE);
|
|
$var(announce_handle) = "callee_offline";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 480;
|
|
$(avp(s:announce_reason)[*]) = "Offline";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_SET_RUSER);
|
|
t_on_failure("FAILURE_ROUTE_LOCAL");
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
exit;
|
|
|
|
}
|
|
|
|
########################################################################
|
|
# Handle special $rU assignments for calls to extensions/aliases
|
|
########################################################################
|
|
route[ROUTE_SET_RUSER]
|
|
{
|
|
if($avp(s:has_extension) == 1)
|
|
{
|
|
# if there's an extension, first send dialed number; on 404, send real user
|
|
$rU = $avp(s:acc_callee_user_in);
|
|
xlog("L_INFO", "Local user online, using full extensioned alias as user - [% logreq -%]\n");
|
|
}
|
|
else if($avp(s:callee_e164_to_ruri) == 1 && !isflagset(FLAG_IN_FALLBACK) && $xavp(caller_peer_prefs=>find_subscriber_by_uuid) != 1)
|
|
{
|
|
# send the dialed alias; on 404 send real user
|
|
$rU = $avp(s:callee_base_user);
|
|
xlog("L_INFO", "Local user online, using alias as user - [% logreq -%]\n");
|
|
}
|
|
else if($avp(s:callee_force_inbound_calls_to_peer) == 1)
|
|
{
|
|
$rU = $avp(s:callee_base_user);
|
|
xlog("L_INFO", "Local user is being relayed, using alias as user - [% logreq -%]\n");
|
|
}
|
|
else if($avp(s:callee_uuid)!="0")
|
|
{
|
|
xlog("L_INFO", "Local user online, using registered contact as user - [% logreq -%]\n");
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'invite-to-external'
|
|
########################################################################
|
|
route[ROUTE_INVITE_TO_EXT]
|
|
{
|
|
if($var(no_auth) == 1)
|
|
{
|
|
xlog("L_INFO", "Call to unknown local user from unauthenticated foreign domain - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $rU;
|
|
$avp(s:acc_callee_domain) = $rd;
|
|
route(ROUTE_ACC_FAILURE);
|
|
$var(announce_handle) = "callee_unknown";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 404;
|
|
$(avp(s:announce_reason)[*]) = "Not Found";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
if($var(external_domain) == 1)
|
|
{
|
|
xlog("L_INFO", "Call to foreign domain - [% logreq -%]\n");
|
|
$var(to_pstn) = 1;
|
|
|
|
#Dialog handle call type to foreign domain
|
|
set_dlg_profile("type","outgoing");
|
|
xlog("L_INFO", "Dialog set mark type to outgoing - [% logreq -%]\n");
|
|
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
|
|
#!ifdef USE_ENUM
|
|
route(ROUTE_LOOKUP_ENUM);
|
|
#!endif
|
|
route(ROUTE_SET_RUSER);
|
|
if($avp(s:from_pstn) != 1 || $var(forward) == 1 || $var(cf_loop) == 1 || $avp(s:caller_force_outbound_calls_to_peer) == 1)
|
|
{
|
|
route(ROUTE_PSTN);
|
|
}
|
|
|
|
#!ifdef PEER_RELAY
|
|
if ($avp(s:from_pstn) == 1)
|
|
{
|
|
xlog("L_INFO", "Performing peer relay - [% logreq -%]\n");
|
|
route(ROUTE_PSTN);
|
|
}
|
|
#!endif
|
|
|
|
|
|
xlog("L_INFO", "Call to unknown user - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $rU;
|
|
$avp(s:acc_callee_domain) = $rd;
|
|
route(ROUTE_ACC_FAILURE);
|
|
$var(announce_handle) = "callee_unknown";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 404;
|
|
$(avp(s:announce_reason)[*]) = "Not Found";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
########################################################################
|
|
# Request route to prepare headers for CF loop
|
|
########################################################################
|
|
route[ROUTE_EXECUTE_CF_LOOP]
|
|
{
|
|
remove_hf("P-Caller-UUID");
|
|
append_hf("P-Caller-UUID: $avp(s:callee_uuid)\r\n");
|
|
remove_hf("P-First-Caller-UPN");
|
|
append_hf("P-First-Caller-UPN: $avp(s:first_caller_cli_userprov)\r\n");
|
|
remove_hf("P-First-Caller-NPN");
|
|
append_hf("P-First-Caller-NPN: $avp(s:first_caller_cli_netprov)\r\n");
|
|
remove_hf("P-First-Caller-UPD");
|
|
append_hf("P-First-Caller-UPD: $avp(s:first_caller_domain_userprov)\r\n");
|
|
remove_hf("P-First-Caller-NPD");
|
|
append_hf("P-First-Caller-NPD: $avp(s:first_caller_domain_netprov)\r\n");
|
|
remove_hf("P-Acc-Caller-User");
|
|
append_hf("P-Acc-Caller-User: $avp(s:acc_caller_user)\r\n");
|
|
remove_hf("P-Acc-Caller-Domain");
|
|
append_hf("P-Acc-Caller-Domain: $avp(s:acc_caller_domain)\r\n");
|
|
remove_hf("P-Acc-State");
|
|
append_hf("P-Acc-State: $avp(s:acc_state)\r\n");
|
|
remove_hf("P-From-Peer");
|
|
# make sure to set P-From-Peer for direct calls from pstn and
|
|
# for CF loops originating from pstn
|
|
if($avp(s:from_pstn) == 1)
|
|
{
|
|
$(avp(s:cf_from_pstn)[*]) = 1;
|
|
}
|
|
append_hf("P-From-Peer: $avp(s:cf_from_pstn)\r\n");
|
|
remove_hf("P-First-V46-RTP");
|
|
append_hf("P-First-V46-RTP: $avp(s:initial_caller_ipv46_for_rtpproxy)\r\n");
|
|
remove_hf("P-First-RTP");
|
|
append_hf("P-First-RTP: $avp(s:first_caller_use_rtpproxy)\r\n");
|
|
remove_hf("P-Caller-CLIR");
|
|
append_hf("P-Caller-CLIR: $avp(s:caller_clir)\r\n");
|
|
remove_hf("P-CF-Depth");
|
|
append_hf("P-CF-Depth: $avp(s:cf_depth)\r\n");
|
|
|
|
remove_hf("P-Callee-Ext-Subs-ID");
|
|
append_hf("P-Callee-Ext-Subs-ID: $avp(s:callee_ext_subscriber_id)\r\n");
|
|
remove_hf("P-Callee-Ext-Contr-ID");
|
|
append_hf("P-Callee-Ext-Contr-ID: $avp(s:callee_ext_contract_id)\r\n");
|
|
remove_hf("P-Callee-Account-ID");
|
|
append_hf("P-Callee-Account-ID: $avp(s:callee_account_id)\r\n");
|
|
|
|
$du = "sip:[% sip_int_ips.0 %]:[% kamailio.proxy.port %]";
|
|
xlog("L_INFO", "Trigger CF loop to '$du' for call to '$ru' - [% logreq -%]\n");
|
|
t_on_failure("FAILURE_ROUTE_HUNT");
|
|
t_on_branch("BRANCH_ROUTE_FWD_LOOP");
|
|
t_relay_to("0x01");
|
|
exit;
|
|
}
|
|
|
|
#!ifdef USE_ENUM
|
|
########################################################################
|
|
# Request route 'lookup-enum'
|
|
########################################################################
|
|
route[ROUTE_LOOKUP_ENUM]
|
|
{
|
|
if(uri =~ "^sip:[1-9][0-9]+@")
|
|
{
|
|
$var(tmpuri) = $ru;
|
|
prefix("+");
|
|
if(enum_query("[% kamailio.proxy.enum_suffix %]"))
|
|
{
|
|
xlog("L_INFO", "ENUM query succeeded - [% logreq -%]\n");
|
|
if(avp_check("$avp(s:caller_lock)", "eq/s:1"))
|
|
{
|
|
xlog("L_INFO", "Caller locked for offnet with mode '$avp(s:caller_lock)' - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "locked_out";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Caller locked";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
$avp(s:callee_user) = $rU;
|
|
$avp(s:callee_domain) = $rd;
|
|
$var(to_pstn) = 1;
|
|
route(ROUTE_OUTBOUND);
|
|
|
|
exit;
|
|
}
|
|
else
|
|
{
|
|
|
|
xlog("L_INFO", "ENUM query failed - [% logreq -%]\n");
|
|
# ENUM query failed, revert $rU
|
|
$ru = $var(tmpuri);
|
|
}
|
|
}
|
|
}
|
|
#!endif
|
|
|
|
########################################################################
|
|
# Request route 'base-route-local'
|
|
########################################################################
|
|
route[ROUTE_LOCAL]
|
|
{
|
|
t_on_reply("REPLY_ROUTE_STD");
|
|
if(t_check_trans())
|
|
{
|
|
xlog("L_INFO", "Request leaving server via local route - [% logreq -%]\n");
|
|
if(!t_relay())
|
|
{
|
|
sl_reply_error();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Dropping mis-routed request - [% logreq -%]\n");
|
|
}
|
|
exit;
|
|
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'base-route-generic'
|
|
########################################################################
|
|
route[ROUTE_NOT_SUPPORTED]
|
|
{
|
|
xlog("L_INFO", "Method not supported - [% logreq -%]\n");
|
|
sl_send_reply("501", "Method Not Supported Here");
|
|
exit;
|
|
|
|
}
|
|
|
|
########################################################################
|
|
# Request route 'base-filter-failover'
|
|
########################################################################
|
|
route[ROUTE_FILTER_FAILOVER]
|
|
{
|
|
xlog("L_INFO", "Filter reply code - [% logreq -%]\n");
|
|
if(!t_check_status("408|500|503"))
|
|
{
|
|
xlog("L_INFO", "No failover routing needed for this response code - [% logreq -%]\n");
|
|
route(ROUTE_STOP_RTPPROXY_BRANCH);
|
|
exit;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
########################################################################
|
|
# Load sound file id for early media announcement and send to media srv
|
|
# Requires: $var(announce_handle), $var(announce_set),
|
|
# $avp(s:announce_code), $avp(s:announce_reason)
|
|
# Returns: never
|
|
########################################################################
|
|
route[ROUTE_EARLY_REJECT]
|
|
{
|
|
if($var(announce_set) == 0)
|
|
{
|
|
t_reply("$avp(s:announce_code)", "$avp(s:announce_reason)");
|
|
exit;
|
|
}
|
|
|
|
$(avp(s:announce_file_id)[*]) = $null;
|
|
$(avp(s:announce_loop)[*]) = $null;
|
|
|
|
avp_db_query("select vsf.id, vsf.loopplay from provisioning.voip_sound_files vsf, provisioning.voip_sound_sets vss, provisioning.voip_sound_handles vfh where vfh.name='$var(announce_handle)' and vss.id=$var(announce_set) and vsf.handle_id=vfh.id and vsf.set_id=vss.id","$avp(s:announce_file_id);$avp(s:announce_loop)");
|
|
|
|
if($avp(s:announce_file_id) == $null)
|
|
{
|
|
xlog("L_INFO", "No audio file for sound set id '$var(announce_set)' and handle '$var(announce_handle)' found - [% logreq -%]\n");
|
|
t_reply("$avp(s:announce_code)", "$avp(s:announce_reason)");
|
|
exit;
|
|
}
|
|
|
|
if($avp(s:announce_loop) == 1)
|
|
{
|
|
$(avp(s:announce_loop)[*]) = "yes";
|
|
}
|
|
else
|
|
{
|
|
$(avp(s:announce_loop)[*]) = "no";
|
|
}
|
|
|
|
if(is_present_hf("P-App-Param"))
|
|
{
|
|
remove_hf("P-App-Param");
|
|
}
|
|
append_hf("P-App-Param: audio_id=$avp(s:announce_file_id);play_looped=$avp(s:announce_loop);fr_code=$avp(s:announce_code);fr_reason=\"$avp(s:announce_reason)\"\r\n");
|
|
if(is_present_hf("P-App-Name"))
|
|
{
|
|
remove_hf("P-App-Name");
|
|
}
|
|
append_hf("P-App-Name: early_dbprompt\r\n");
|
|
$rU = "earlyannounce";
|
|
xlog("L_INFO", "Relaying request to media server with params 'audio_id=$avp(s:announce_file_id);play_looped=$avp(s:announce_loop);fr_code=$avp(s:announce_code);fr_reason=\"$avp(s:announce_reason)\"' - [% logreq -%]\n");
|
|
|
|
t_on_failure("FAILURE_ROUTE_EARLY_REJECT");
|
|
route(ROUTE_TO_APPSRV);
|
|
exit;
|
|
}
|
|
|
|
|
|
|
|
########################################################################
|
|
# Check outgoing block list
|
|
########################################################################
|
|
route[ROUTE_BLOCK_OUT]
|
|
{
|
|
# TODO: set correct sip code or reason for accounting
|
|
|
|
$var(announce_handle) = "block_out";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
|
|
$var(blockuri) = $rU + "@" + $rd;
|
|
#comment out the previous line and uncomment next to avoid accidental matching on numeric-only SIP usernames
|
|
#$var(blockuri) = "sip:" + $rU + "@" + $rd;
|
|
|
|
if($var(adm_block_override) == 1)
|
|
{
|
|
xlog("L_INFO", "Administrative Block Out overridden, skip - [% logreq -%]\n");
|
|
return;
|
|
}
|
|
|
|
xlog("L_INFO", "Checking URI '$var(blockuri)' and CLI '$avp(s:callee_cli)' against block out lists - [% logreq -%]\n");
|
|
if($avp(s:caller_adm_block_out_mode) == 1)
|
|
{
|
|
xlog("L_INFO", "Admin caller block mode is 'closed' - [% logreq -%]\n");
|
|
if(!avp_check("$var(blockuri)", "fm/$avp(s:caller_adm_block_out_list)/g") &&
|
|
!avp_check("$avp(s:callee_cli)", "fm/$avp(s:caller_adm_block_out_list)/g"))
|
|
{
|
|
xlog("L_INFO", "Callee blocked by Admin in 'closed' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Admin";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Admin caller block mode is 'open' - [% logreq -%]\n");
|
|
if(avp_check("$var(blockuri)", "fm/$avp(s:caller_adm_block_out_list)/g") ||
|
|
avp_check("$avp(s:callee_cli)", "fm/$avp(s:caller_adm_block_out_list)/g"))
|
|
{
|
|
xlog("L_INFO", "Callee blocked by Admin in 'open' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Admin";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
|
|
if($var(block_override) == 1)
|
|
{
|
|
xlog("L_INFO", "Block Out overridden, skip - [% logreq -%]\n");
|
|
return;
|
|
}
|
|
|
|
if($avp(s:caller_block_out_mode) == 1)
|
|
{
|
|
xlog("L_INFO", "Caller block mode is 'closed' - [% logreq -%]\n");
|
|
if(!avp_check("$var(blockuri)", "fm/$avp(s:caller_block_out_list)/g") &&
|
|
!avp_check("$avp(s:callee_cli)", "fm/$avp(s:caller_block_out_list)/g"))
|
|
{
|
|
xlog("L_INFO", "Callee blocked by caller in 'closed' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Caller";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Caller block mode is 'open' - [% logreq -%]\n");
|
|
if(avp_check("$var(blockuri)", "fm/$avp(s:caller_block_out_list)/g") ||
|
|
avp_check("$avp(s:callee_cli)", "fm/$avp(s:caller_block_out_list)/g"))
|
|
{
|
|
xlog("L_INFO", "Callee blocked by caller in 'open' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Caller";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Check incoming block list
|
|
########################################################################
|
|
route[ROUTE_BLOCK_IN]
|
|
{
|
|
# TODO: set correct sip code or reason for accounting
|
|
if($avp(s:from_faxserver) == 1 || $avp(s:from_voicebox) == 1)
|
|
{
|
|
return;
|
|
}
|
|
|
|
$var(announce_handle) = "block_in";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
|
|
xlog("L_INFO", "Checking UPN '$avp(s:caller_cli_userprov)' and NPN '$avp(s:caller_cli_netprov)' against block in lists - [% logreq -%]\n");
|
|
if($avp(s:callee_adm_block_in_mode) == 1)
|
|
{
|
|
xlog("L_INFO", "Admin callee block mode is 'closed' - [% logreq -%]\n");
|
|
if($avp(s:caller_clir) == 1 && $avp(s:callee_adm_block_in_clir) == 0)
|
|
{
|
|
# also block CLIR in whitelist-mode if block_in_clir is unset
|
|
xlog("L_INFO", "Anonymous caller blocked by Admin in 'closed' mode - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Admin";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
else if(!avp_check("$avp(s:caller_cli_userprov)", "fm/$avp(s:callee_adm_block_in_list)/g") &&
|
|
!avp_check("$avp(s:caller_cli_netprov)", "fm/$avp(s:callee_adm_block_in_list)/g") &&
|
|
$avp(s:caller_clir) != 1) # allow anonymous calls that passed callee_block_in_clir check
|
|
{
|
|
xlog("L_INFO", "Caller blocked by Admin in 'closed' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Admin";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Admin callee block mode is 'open' - [% logreq -%]\n");
|
|
if($avp(s:caller_clir) != 1 &&
|
|
(avp_check("$avp(s:caller_cli_userprov)", "fm/$avp(s:callee_adm_block_in_list)/g") ||
|
|
avp_check("$avp(s:caller_cli_netprov)", "fm/$avp(s:callee_adm_block_in_list)/g")))
|
|
{
|
|
xlog("L_INFO", "Caller blocked by Admin in 'open' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Admin";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
else if($avp(s:caller_clir) == 1 && $avp(s:callee_adm_block_in_clir) == 1)
|
|
{
|
|
xlog("L_INFO", "Anonymous caller blocked by Admin in 'open' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Admin";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
|
|
if($avp(s:callee_block_in_mode) == 1)
|
|
{
|
|
xlog("L_INFO", "Callee block mode is 'closed' - [% logreq -%]\n");
|
|
if($avp(s:caller_clir) == 1 && $avp(s:callee_block_in_clir) == 0)
|
|
{
|
|
# also block CLIR in whitelist-mode if block_in_clir is unset
|
|
xlog("L_INFO", "Anonymous caller blocked by callee in 'closed' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Callee";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
else if(!avp_check("$avp(s:caller_cli_userprov)", "fm/$avp(s:callee_block_in_list)/g") &&
|
|
!avp_check("$avp(s:caller_cli_netprov)", "fm/$avp(s:callee_block_in_list)/g") &&
|
|
$avp(s:caller_clir) != 1) # allow anonymous calls that passed callee_block_in_clir check
|
|
{
|
|
xlog("L_INFO", "Caller blocked by callee in 'closed' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Callee";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Callee block mode is 'open' - [% logreq -%]\n");
|
|
if($avp(s:caller_clir) != 1 &&
|
|
(avp_check("$avp(s:caller_cli_userprov)", "fm/$avp(s:callee_block_in_list)/g") ||
|
|
avp_check("$avp(s:caller_cli_netprov)", "fm/$avp(s:callee_block_in_list)/g")))
|
|
{
|
|
xlog("L_INFO", "Caller blocked by callee in 'open' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Callee";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
else if($avp(s:caller_clir) == 1 && $avp(s:callee_block_in_clir) == 1)
|
|
{
|
|
xlog("L_INFO", "Anonymous caller blocked by callee in 'open' mode - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by Callee";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Check NCOS levels
|
|
########################################################################
|
|
route[ROUTE_NCOS]
|
|
{
|
|
if($avp(s:tmp_ncos_id) != $null)
|
|
{
|
|
$var(announce_handle) = "block_ncos";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
|
|
xlog("L_INFO", "Check NCOS level id '$avp(s:tmp_ncos_id)' against callee '$avp(s:callee_cli)' - [% logreq -%]\n");
|
|
|
|
$(avp(s:ncos_local_ac)[*]) = $null;
|
|
$(avp(s:ncos_mode)[*]) = $null;
|
|
$(avp(s:ncos_result)[*]) = $null;
|
|
$(avp(s:tmp)[*]) = $xavp(caller_real_prefs=>cc) + $xavp(caller_real_prefs=>ac) + "*";
|
|
|
|
avp_db_query("select nl.local_ac, nl.mode, convert(if(nl.mode = 'whitelist', max('$(avp(s:callee_cli){s.escape.common})' regexp(nlp.pattern)), min('$(avp(s:callee_cli){s.escape.common})' not regexp(nlp.pattern))), char(255)) as result from billing.ncos_levels nl left join billing.ncos_pattern_list nlp on nlp.ncos_level_id = nl.id where nl.id = $avp(s:tmp_ncos_id) group by nl.local_ac","$avp(s:ncos_local_ac);$avp(s:ncos_mode);$avp(s:ncos_result)");
|
|
|
|
xlog("L_INFO", "NCOS level results: mode='$avp(s:ncos_mode)', result='$avp(s:ncos_result)', local_ac='$avp(s:ncos_local_ac)' - [% logreq -%]\n");
|
|
if($avp(s:ncos_mode) == 'whitelist')
|
|
{
|
|
# empty whitelist should block the call
|
|
if($avp(s:ncos_result) == $null)
|
|
{
|
|
$avp(s:ncos_result) = "0";
|
|
}
|
|
if($avp(s:ncos_result) == "1")
|
|
{
|
|
xlog("L_INFO", "NCOS result check ok, pass call - [% logreq -%]\n");
|
|
return;
|
|
}
|
|
if($avp(s:ncos_local_ac) == 1 && avp_check("$avp(s:callee_cli)", "fm/$avp(s:tmp)/g"))
|
|
{
|
|
xlog("L_INFO", "NCOS local ac check ok, pass call - [% logreq -%]\n");
|
|
return;
|
|
}
|
|
[% IF ossbss.provisioning.lnp_enable == "yes" %]
|
|
route(ROUTE_NCOS_LNP_CHECK);
|
|
if($rc == 1)
|
|
{
|
|
xlog("L_INFO", "NCOS LNP check ok, pass call - [% logreq -%]\n");
|
|
return;
|
|
}
|
|
[% END %]
|
|
xlog("L_INFO", "NCOS check failed, reject call - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by NCOS level";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
else
|
|
{
|
|
# empty blacklist should allow the call
|
|
if($avp(s:ncos_result) == $null)
|
|
{
|
|
$avp(s:ncos_result) = "1";
|
|
}
|
|
if($avp(s:ncos_result) == "0")
|
|
{
|
|
xlog("L_INFO", "NCOS result check failed, reject call - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by NCOS level";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
if($avp(s:ncos_local_ac) == 1 && avp_check("$avp(s:callee_cli)", "fm/$avp(s:tmp)/g"))
|
|
{
|
|
xlog("L_INFO", "NCOS local ac check failed, reject call - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by NCOS level";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
[% IF ossbss.provisioning.lnp_enable == "yes" %]
|
|
route(ROUTE_NCOS_LNP_CHECK);
|
|
if($rc == -1)
|
|
{
|
|
xlog("L_INFO", "NCOS LNP check failed, reject call - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$(avp(s:announce_reason)[*]) = "Blocked by NCOS level";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
[% END %]
|
|
xlog("L_INFO", "NCOS check ok, pass call - [% logreq -%]\n");
|
|
}
|
|
}
|
|
}
|
|
[% IF ossbss.provisioning.lnp_enable == "yes" %]
|
|
########################################################################
|
|
# Check for LNP in NCOS lists (-1 if blocked, 1 if passed)
|
|
########################################################################
|
|
route[ROUTE_NCOS_LNP_CHECK]
|
|
{
|
|
$(avp(s:ncos_lnp_provider_id)[*]) = $null;
|
|
$(avp(s:ncos_lnp_result)[*]) = $null;
|
|
avp_db_query("select ln.lnp_provider_id from billing.lnp_numbers ln where ln.number like concat(left('$(avp(s:callee_cli){s.escape.common})', 4), '%') and instr('$(avp(s:callee_cli){s.escape.common})', ln.number) = 1 and (ln.start <= now() or ln.start is null) and (ln.end > now() or ln.end is null) order by length(ln.number) desc, ln.lnp_provider_id desc limit 1","$avp(s:ncos_lnp_provider_id)");
|
|
xlog("L_INFO", "NCOS LNP provider id is '$avp(s:ncos_lnp_provider_id)' - [% logreq -%]\n");
|
|
if($avp(s:ncos_lnp_provider_id) == $null)
|
|
{
|
|
if($avp(s:ncos_mode) == 'whitelist')
|
|
{
|
|
xlog("L_INFO", "NCOS LNP check blocked for missing provider id in whitelist mode - [% logreq -%]\n");
|
|
return(-1);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "NCOS LNP check passed for missing provider id in blacklist mode - [% logreq -%]\n");
|
|
return(1);
|
|
}
|
|
}
|
|
avp_db_query("select if(nl.mode = 'whitelist', count(*), not count(*)) as result from billing.ncos_lnp_list nll, billing.ncos_levels nl where nll.lnp_provider_id=$avp(s:ncos_lnp_provider_id) and nl.id=$avp(s:tmp_ncos_id) and nll.ncos_level_id = nl.id","$avp(s:ncos_lnp_result)");
|
|
xlog("L_INFO", "NCOS LNP result is '$avp(s:ncos_lnp_result)' - [% logreq -%]\n");
|
|
if($avp(s:ncos_lnp_result) == 0)
|
|
{
|
|
xlog("L_INFO", "NCOS LNP check blocked - [% logreq -%]\n");
|
|
return(-1);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "NCOS LNP check passed - [% logreq -%]\n");
|
|
return(1);
|
|
}
|
|
}
|
|
[% END %]
|
|
########################################################################
|
|
# Route to PSTN
|
|
########################################################################
|
|
route[ROUTE_PSTN]
|
|
{
|
|
$var(allow_peer)=0;
|
|
if($avp(s:em_call) != 1 && avp_check("$avp(s:caller_lock)", "eq/s:1"))
|
|
{
|
|
xlog("L_INFO", "Caller locked for offnet with mode '$avp(s:caller_lock)' - [% logreq -%]\n");
|
|
$avp(s:acc_callee_user) = $avp(s:callee_user);
|
|
$avp(s:acc_callee_domain) = $avp(s:callee_domain);
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "locked_out";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 403;
|
|
$(avp(s:announce_reason)[*]) = "Caller locked";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
xlog("L_INFO", "Call to SIP Peering - [% logreq -%]\n");
|
|
|
|
setbflag(FLB_NATB);
|
|
$var(to_pstn) = 1;
|
|
|
|
#$avp(s:lcr_ruri_user) = $rU;
|
|
$var(lcr_match_content) = $avp(s:first_caller_cli_userprov) + "@" + $avp(s:caller_domain_netprov);
|
|
xlog("L_INFO", "Load gws matching calling part '$var(lcr_match_content)' and called part '$rU' - [% logreq -%]\n");
|
|
if(!load_gws("1", $rU, $var(lcr_match_content)))
|
|
{
|
|
xlog("L_ERR", "Error loading PSTN gateways - [% logreq -%]\n");
|
|
route(ROUTE_ACC_FAILURE);
|
|
$var(announce_handle) = "peering_unavailable";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 503;
|
|
$(avp(s:announce_reason)[*]) = "PSTN Termination Currently Unavailable";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
#!ifdef ENABLE_PEER_LCR
|
|
# re-order lcr list based on costs per peer-group
|
|
lcr_rate("$avp(s:caller_cli_userprov)@$avp(s:acc_caller_domain)", "$rU@$rd");
|
|
#!endif
|
|
|
|
#Dialog handle call type to pstn
|
|
|
|
#!ifdef PEER_RELAY
|
|
if ($avp(s:from_pstn) != 1)
|
|
{
|
|
set_dlg_profile("type","outgoing");
|
|
xlog("L_INFO", "Dialog set mark type to outgoing - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
#FIXME: We also have relay capabilities by using the preferences. Handle them or delete this one.
|
|
set_dlg_profile("type","relay");
|
|
xlog("L_INFO", "Dialog set mark type to relay - [% logreq -%]\n");
|
|
}
|
|
#!else
|
|
set_dlg_profile("type","outgoing");
|
|
xlog("L_INFO", "Dialog set mark type to outgoing - [% logreq -%]\n");
|
|
#!endif
|
|
|
|
while ($var(allow_peer) != 1)
|
|
{
|
|
$var(allow_peer) = 1;
|
|
if(!next_gw())
|
|
{
|
|
xlog("L_ERR", "No PSTN gateways available - [% logreq -%]\n");
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "peering_unavailable";
|
|
$var(announce_set) = $avp(s:caller_sound_set);
|
|
$(avp(s:announce_code)[*]) = 503;
|
|
$(avp(s:announce_reason)[*]) = "PSTN Termination Currently Unavailable";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
$avp(s:callee_domain) = $rd;
|
|
|
|
if($avp(s:lcr_flags) != $null && $avp(s:lcr_flags) != 0)
|
|
{
|
|
route(ROUTE_CLEAR_PEER_OUT_PREF);
|
|
route(ROUTE_LOAD_PEER_OUT_PREF);
|
|
}
|
|
|
|
#Dialog handle callee peer concurrent_max
|
|
if($xavp(callee_peer_prefs=>concurrent_max) != $null && $xavp(callee_peer_prefs=>concurrent_max) != 0 && $avp(s:em_call) != 1)
|
|
{
|
|
if(get_profile_size("peer","$avp(s:lcr_flags)","$avp(s:size)"))
|
|
{
|
|
#check greater or equal because the callee peer hasn't been marked yet
|
|
if ($avp(s:size) >= $xavp(callee_peer_prefs=>concurrent_max))
|
|
{
|
|
xlog("L_INFO", "Concurrent_max calls exceeded for peer '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
$var(allow_peer) = 0;
|
|
}
|
|
}
|
|
}
|
|
#Dialog handle callee peer concurrent_max_out
|
|
if($xavp(callee_peer_prefs=>concurrent_max_out) != $null && $xavp(callee_peer_prefs=>concurrent_max_out) != 0 && $avp(s:em_call) != 1)
|
|
{
|
|
if(get_profile_size("peerout","$avp(s:lcr_flags)","$avp(s:size)"))
|
|
{
|
|
#check greater or equal because the callee peerout hasn't been marked yet
|
|
if ($avp(s:size) >= $xavp(callee_peer_prefs=>concurrent_max_out))
|
|
{
|
|
xlog("L_INFO", "Concurrent_max_out calls exceeded for peer '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
$var(allow_peer) = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if($avp(s:em_call) != 1)
|
|
{
|
|
$avp(s:callee_user) = $rU;
|
|
}
|
|
|
|
#Dialog handle: Now that we know the peer to use mark call for this peer
|
|
set_dlg_profile("peer","$avp(s:lcr_flags)");
|
|
set_dlg_profile("peerout","$avp(s:lcr_flags)");
|
|
xlog("L_INFO", "Dialog set mark peer and peerout to '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
|
|
resetbflag(FLB_CALLEE_IPV6);
|
|
if($rd =~ "^\[[a-fA-F0-9\:\.]+\]$")
|
|
{
|
|
setbflag(FLB_CALLEE_IPV6);
|
|
}
|
|
|
|
t_on_failure("FAILURE_ROUTE_PSTN");
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
|
|
########################################################################
|
|
# Route to voicebox
|
|
########################################################################
|
|
route[ROUTE_VOICEBOX]
|
|
{
|
|
xlog("L_INFO", "Call to VoiceBox - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
$avp(s:to_voicebox) = 1;
|
|
$avp(s:callee_user) = $rU;
|
|
$rd = "voicebox.local";
|
|
$avp(s:callee_domain) = $rd;
|
|
|
|
$(avp(s:callee_uuid)[*]) = $avp(s:caller_uuid);
|
|
#$avp(s:lcr_ruri_user) = $rU;
|
|
$avp(s:lcr_dsp) = 2;
|
|
if(!ds_select_dst("$avp(s:lcr_dsp)", "4"))
|
|
{
|
|
xlog("L_ERR", "Error loading voicebox servers - [% logreq -%]\n");
|
|
route(ROUTE_ACC_FAILURE);
|
|
|
|
$var(announce_handle) = "voicebox_unavailable";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 503;
|
|
$(avp(s:announce_reason)[*]) = "VoiceBox Currently Unavailable";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
#Dialog handle for calls to voicebox
|
|
set_dlg_profile("type","local");
|
|
xlog("L_INFO", "Dialog set mark type to local - [% logreq -%]\n");
|
|
set_dlg_profile("peer","voicebox");
|
|
xlog("L_INFO", "Dialog set mark peer to voicebox - [% logreq -%]\n");
|
|
|
|
t_on_failure("FAILURE_ROUTE_VOICEBOX");
|
|
setbflag(FLB_NATB);
|
|
$var(local_endpoint) = 1;
|
|
$var(no_sbc) = 1;
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
|
|
########################################################################
|
|
# Route to Faxserver
|
|
########################################################################
|
|
route[ROUTE_FAXSERVER]
|
|
{
|
|
xlog("L_INFO", "Call to Faxserver - [% logreq -%]\n");
|
|
|
|
/*
|
|
if($avp(s:cf_depth) > 0)
|
|
{
|
|
xlog("L_INFO", "Using original callee '$avp(s:acc_callee_user_in)' - [% logreq -%]\n");
|
|
$avp(s:callee_user) = $avp(s:acc_callee_user_in);
|
|
$rU = $avp(s:callee_user);
|
|
}
|
|
else
|
|
{
|
|
$avp(s:callee_user) = $rU;
|
|
}
|
|
*/
|
|
|
|
$(avp(s:to_faxserver)[*]) = 1;
|
|
|
|
$avp(s:callee_user) = $rU;
|
|
$avp(s:callee_domain) = $rd;
|
|
$(avp(s:callee_uuid)[*]) = $avp(s:caller_uuid);
|
|
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
#$avp(s:lcr_ruri_user) = $rU;
|
|
$avp(s:lcr_dsp) = 4;
|
|
if(!ds_select_dst("$avp(s:lcr_dsp)", "4"))
|
|
{
|
|
xlog("L_ERR", "Error loading Faxserver gateways - [% logreq -%]\n");
|
|
route(ROUTE_ACC_FAILURE);
|
|
t_reply("503", "Faxserver Currently Unavailable");
|
|
exit;
|
|
}
|
|
|
|
#Dialog handle for calls to faxserver
|
|
set_dlg_profile("type","local");
|
|
xlog("L_INFO", "Dialog set mark type to local - [% logreq -%]\n");
|
|
set_dlg_profile("peer","faxserver");
|
|
xlog("L_INFO", "Dialog set mark peer to faxserver - [% logreq -%]\n");
|
|
|
|
t_on_failure("FAILURE_ROUTE_FAXSERVER");
|
|
setbflag(FLB_NATB);
|
|
$var(local_endpoint) = 1;
|
|
|
|
#manwe: Fax gws are not iaddress. we need sbc + lb to route faxes
|
|
if( $dd == "[% sip_int_ips.0 %]" )
|
|
{
|
|
$var(no_sbc) = 1;
|
|
}
|
|
else
|
|
{
|
|
$var(no_sbc) = 0;
|
|
}
|
|
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
|
|
|
|
########################################################################
|
|
# Route to Application Server
|
|
########################################################################
|
|
route[ROUTE_TO_APPSRV]
|
|
{
|
|
xlog("L_INFO", "Call to Application Server - [% logreq -%]\n");
|
|
|
|
$avp(s:acc_callee_user_in) = $rU;
|
|
$avp(s:acc_callee_domain_in) = $rd;
|
|
$rd = "app.local";
|
|
$avp(s:callee_uuid) = $avp(s:caller_uuid);
|
|
$avp(s:callee_user) = $rU;
|
|
$avp(s:callee_domain) = $rd;
|
|
|
|
route(ROUTE_LOAD_APPSRV);
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
|
|
########################################################################
|
|
# Load application server from the dispatcher table
|
|
########################################################################
|
|
route[ROUTE_LOAD_APPSRV]
|
|
{
|
|
#$avp(s:lcr_ruri_user) = $rU;
|
|
$avp(s:lcr_dsp) = 3;
|
|
if(!ds_select_dst("$avp(s:lcr_dsp)", "4"))
|
|
{
|
|
xlog("L_ERR", "Error loading Application Server - [% logreq -%]\n");
|
|
route(ROUTE_ACC_FAILURE);
|
|
if($avp(s:announce_code) != $null && $avp(s:announce_reason) != $null)
|
|
{
|
|
t_reply("$avp(s:announce_code)", "$avp(s:announce_reason)");
|
|
}
|
|
else
|
|
{
|
|
t_reply("503", "Application Server Currently Unavailable");
|
|
}
|
|
exit;
|
|
}
|
|
|
|
#Dialog handle for calls to appsrv
|
|
set_dlg_profile("type","local");
|
|
xlog("L_INFO", "Dialog set mark type to local - [% logreq -%]\n");
|
|
set_dlg_profile("peer","appsrv");
|
|
xlog("L_INFO", "Dialog set mark peer to appsrv - [% logreq -%]\n");
|
|
|
|
setbflag(FLB_NATB);
|
|
$var(local_endpoint) = 1;
|
|
$var(no_sbc) = 1;
|
|
}
|
|
|
|
########################################################################
|
|
# Remove any headers used for proxy lookup routing
|
|
########################################################################
|
|
route[ROUTE_CLEAR_PROXYLU_HEADERS]
|
|
{
|
|
|
|
remove_hf("P-First-Caller-UPN");
|
|
remove_hf("P-First-Caller-NPN");
|
|
remove_hf("P-First-Forwarder-UPN");
|
|
remove_hf("P-Caller-UPN");
|
|
remove_hf("P-Caller-NPN");
|
|
remove_hf("P-First-V46-RTP");
|
|
remove_hf("P-First-RTP");
|
|
remove_hf("P-Caller-CLIR");
|
|
remove_hf("P-Caller-PeerInfo");
|
|
}
|
|
|
|
########################################################################
|
|
# Set CLI from branch route
|
|
########################################################################
|
|
route[ROUTE_SET_CLI_CALLEE]
|
|
{
|
|
# denormalize
|
|
if($var(to_pstn) == 1)
|
|
{
|
|
if($avp(s:pstn_dp_callee_out_id) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying callee-out peer rewrite rules to called party using dpid '$avp(s:pstn_dp_callee_out_id)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:pstn_dp_callee_out_id)", "$rU/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting called party '$rU' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$rU = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$rU' found - [% logreq -%]\n");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if($avp(s:callee_dp_dom_callee_out) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying callee-out domain rewrite rules using dpid '$avp(s:callee_dp_dom_callee_out)' - [% logreq -%]\n");
|
|
$var(dp_ru) = $null;
|
|
if(dp_translate("$avp(s:callee_dp_dom_callee_out)", "$rU/$var(dp_ru)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting callee '$rU' to '$var(dp_ru)' - [% logreq -%]\n");
|
|
$rU = $var(dp_ru);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$rU' found - [% logreq -%]\n");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Prepare header elements for caller cli
|
|
# in: $var(ccli_selector)
|
|
# out: $var(ccli_user), $var(ccli_domain)
|
|
########################################################################
|
|
route[ROUTE_PREPARE_CLI_CALLER]
|
|
{
|
|
if($var(ccli_selector) == 0)
|
|
{
|
|
$var(ccli_selector) = "";
|
|
}
|
|
if($var(ccli_selector) =~ "^uprn$")
|
|
{
|
|
$var(ccli_user) = $avp(s:forwarder_cli_userprov);
|
|
$var(ccli_domain) = $avp(s:forwarder_domain_userprov);
|
|
xlog("L_INFO", "Setting forwarder_cli_userprov/forwarder_domain_userprov '$var(ccli_user)@$var(ccli_domain)' for uprn - [% logreq -%]\n");
|
|
return;
|
|
}
|
|
else if($var(ccli_selector) =~ "^uprn/")
|
|
{
|
|
if($avp(s:forwarder_cli_userprov) != $null)
|
|
{
|
|
$var(ccli_user) = $avp(s:forwarder_cli_userprov);
|
|
$var(ccli_domain) = $avp(s:forwarder_domain_userprov);
|
|
xlog("L_INFO", "Setting forwarder_cli_userprov/forwarder_domain_userprov '$var(ccli_user)@$var(ccli_domain)' for uprn - [% logreq -%]\n");
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
# fallback to second selector
|
|
$var(ccli_selector) = $(var(ccli_selector){s.select,1,/});
|
|
}
|
|
}
|
|
if($var(ccli_selector) == "npn")
|
|
{
|
|
$var(ccli_user) = $var(caller_cli_netprov);
|
|
$var(ccli_domain) = $var(caller_domain_netprov);
|
|
xlog("L_INFO", "Setting caller_cli_netprov/caller_domain_netprov '$var(ccli_user)@$var(ccli_domain)' for npn - [% logreq -%]\n");
|
|
}
|
|
else if($var(ccli_selector) == "upn")
|
|
{
|
|
$var(ccli_user) = $var(caller_cli_userprov);
|
|
$var(ccli_domain) = $var(caller_domain_userprov);
|
|
xlog("L_INFO", "Setting caller_cli_userprov/caller_domain_userprov '$var(ccli_user)@$var(ccli_domain)' for upn - [% logreq -%]\n");
|
|
}
|
|
else if($var(ccli_selector) == "rcv_display" && $fn != $null && $(fn{s.len}) > 0)
|
|
{
|
|
$var(ccli_user) = $fn;
|
|
# strip optional double-quotes
|
|
if($var(ccli_user) =~ "^\".+\"$")
|
|
{
|
|
#$var(ccli_user) = $(var(ccli_user){s.select,1,"});
|
|
# TODO: the above seems to break in unpredictable cases, use old/safe way for now
|
|
$(avp(s:tmp)[*]) = $var(ccli_user);
|
|
avp_subst("$avp(s:tmp)", "/^\"?([^\"]*)\"?$/\1/");
|
|
$var(ccli_user) = $avp(s:tmp);
|
|
$(avp(s:tmp)[*]) = $null;
|
|
}
|
|
$var(ccli_domain) = $var(caller_domain_userprov);
|
|
xlog("L_INFO", "Setting display-name/caller_domain_userprov '$var(ccli_user)@$var(ccli_domain)' for rcv_display - [% logreq -%]\n");
|
|
}
|
|
else if($var(ccli_selector) == "auth_user" && $au != $null)
|
|
{
|
|
$var(ccli_user) = $au;
|
|
$var(ccli_domain) = $var(caller_domain_userprov);
|
|
xlog("L_INFO", "Setting auth_user/caller_domain_userprov '$var(ccli_user)@$var(ccli_domain)' for auth_user - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
$var(ccli_user) = 0;
|
|
$var(ccli_domain) = 0;
|
|
xlog("L_INFO", "No selector set, not setting CLI - [% logreq -%]\n");
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Set CLI from branch route
|
|
########################################################################
|
|
route[ROUTE_SET_CLI_CALLER]
|
|
{
|
|
$var(caller_cli_userprov) = $avp(s:first_caller_cli_userprov);
|
|
$var(caller_cli_netprov) = $avp(s:first_caller_cli_netprov);
|
|
$var(caller_domain_netprov) = $avp(s:first_caller_domain_netprov);
|
|
|
|
# Onnet, to local subscriber
|
|
if($var(to_pstn) != 1 && $var(local_endpoint) != 1)
|
|
{
|
|
if($avp(s:caller_clir) != 1 && $avp(s:callee_dp_dom_caller_out) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying caller-out domain rewrite rules to first user-provided caller CLI using dpid '$avp(s:callee_dp_dom_caller_out)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:callee_dp_dom_caller_out)", "$var(caller_cli_userprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting first user-provided caller CLI '$var(caller_cli_userprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$var(caller_cli_userprov) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$var(caller_cli_userprov)' found - [% logreq -%]\n");
|
|
}
|
|
|
|
xlog("L_INFO", "Applying caller-out domain rewrite rules to first network-provided caller CLI using dpid '$avp(s:callee_dp_dom_caller_out)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:callee_dp_dom_caller_out)", "$var(caller_cli_netprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting first network-provided caller CLI '$var(caller_cli_netprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$var(caller_cli_netprov) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$var(caller_cli_netprov)' found - [% logreq -%]\n");
|
|
}
|
|
|
|
if($avp(s:forwarder_cli_userprov) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying caller-out domain rewrite rules to user-provided Redirecting CLI using dpid '$avp(s:callee_dp_dom_caller_out)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:callee_dp_dom_caller_out)", "$avp(s:forwarder_cli_userprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting user-provided Redirecting CLI '$avp(s:forwarder_cli_userprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$(avp(s:forwarder_cli_userprov)[*]) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$avp(s:forwarder_cli_userprov)' found - [% logreq -%]\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
xlog("L_INFO", "Setting userprovided caller domain - [% logreq -%]\n");
|
|
if($avp(s:from_pstn) == 1 || $avp(s:cf_from_pstn) == 1)
|
|
{
|
|
$var(caller_domain_userprov) = $avp(s:acc_callee_domain);
|
|
xlog("L_INFO", "Call from peer, use callee domain '$avp(s:acc_callee_domain)' - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
$var(caller_domain_userprov) = $avp(s:first_caller_domain_userprov);
|
|
xlog("L_INFO", "Use first userprov caller domain '$avp(s:first_caller_domain_userprov)' - [% logreq -%]\n");
|
|
}
|
|
|
|
}
|
|
|
|
# Offnet or local endpoint
|
|
else if($var(to_pstn) == 1 || $var(local_endpoint) == 1)
|
|
{
|
|
if($avp(s:pstn_dp_caller_out_id) != $null && $var(local_endpoint) != 1)
|
|
{
|
|
xlog("L_INFO", "Applying caller-out peer rewrite rules to first user-provided caller CLI using dpid '$avp(s:pstn_dp_caller_out_id)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:pstn_dp_caller_out_id)", "$var(caller_cli_userprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting first user-provided caller CLI '$var(caller_cli_userprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$var(caller_cli_userprov) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$var(caller_cli_userprov)' found - [% logreq -%]\n");
|
|
}
|
|
|
|
xlog("L_INFO", "Applying caller-out peer rewrite rules to first network-provided caller CLI using dpid '$avp(s:pstn_dp_caller_out_id)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:pstn_dp_caller_out_id)", "$var(caller_cli_netprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting first network-provided caller CLI '$var(caller_cli_netprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$var(caller_cli_netprov) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$var(caller_cli_netprov)' found - [% logreq -%]\n");
|
|
}
|
|
|
|
if($avp(s:forwarder_cli_userprov) != $null)
|
|
{
|
|
xlog("L_INFO", "Applying caller-out peer rewrite rules to user-provided Redirecting CLI using dpid '$avp(s:pstn_dp_caller_out_id)' - [% logreq -%]\n");
|
|
$var(dp_user) = $null;
|
|
if(dp_translate("$avp(s:pstn_dp_caller_out_id)", "$avp(s:forwarder_cli_userprov)/$var(dp_user)"))
|
|
{
|
|
xlog("L_INFO", "Rewriting user-provided Redirecting CLI '$avp(s:forwarder_cli_userprov)' to '$var(dp_user)' - [% logreq -%]\n");
|
|
$(avp(s:forwarder_cli_userprov)[*]) = $var(dp_user);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No matching rewrite rules for '$avp(s:forwarder_cli_userprov)' found - [% logreq -%]\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
$var(caller_domain_userprov) = $avp(s:first_caller_domain_userprov);
|
|
}
|
|
|
|
# set the From header
|
|
$var(ccli_selector) = $avp(s:callee_outbound_from_display);
|
|
xlog("L_INFO", "Prepare From display-name setting - [% logreq -%]\n");
|
|
route(ROUTE_PREPARE_CLI_CALLER);
|
|
$var(out_from_display) = $var(ccli_user);
|
|
if($var(to_pstn) == 1 && isbflagset(FLB_PEERAUTH))
|
|
{
|
|
$var(caller_uri) = "sip:" + $xavp(caller_peer_prefs=>peer_caller_auth_user) + "@" + $xavp(caller_peer_prefs=>peer_caller_auth_realm);
|
|
}
|
|
else
|
|
{
|
|
$var(ccli_selector) = $avp(s:callee_outbound_from_user);
|
|
xlog("L_INFO", "Prepare From username setting - [% logreq -%]\n");
|
|
route(ROUTE_PREPARE_CLI_CALLER);
|
|
if($var(ccli_user) == 0)
|
|
{
|
|
$var(ccli_user) = $var(caller_cli_netprov);
|
|
$var(ccli_domain) = $var(caller_domain_netprov);
|
|
}
|
|
$var(caller_uri) = "sip:" + $var(ccli_user) + "@" + $var(ccli_domain);
|
|
}
|
|
if($avp(s:caller_clir) == 1) # override previous settings in case of CLIR
|
|
{
|
|
xlog("L_INFO", "Anonymizing From display-name - [% logreq -%]\n");
|
|
$var(out_from_display) = "Anonymous";
|
|
if($var(to_pstn) != 1)
|
|
{
|
|
xlog("L_INFO", "Anonymizing From username - [% logreq -%]\n");
|
|
$var(caller_uri) = "sip:anonymous@anonymous.invalid";
|
|
}
|
|
append_hf("Privacy: id\r\n");
|
|
}
|
|
if($var(out_from_display) == 0)
|
|
{
|
|
xlog("L_INFO", "Setting From to '<$var(caller_uri)>' - [% logreq -%]\n");
|
|
uac_replace_from("", "$var(caller_uri)");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Setting From to '$var(out_from_display) <$var(caller_uri)>' - [% logreq -%]\n");
|
|
uac_replace_from("$var(out_from_display)", "$var(caller_uri)");
|
|
}
|
|
|
|
#Don't add PAI nor PPI if the callee is local and CLIR is set.
|
|
if($avp(s:caller_clir) != 1 || $var(to_pstn) == 1)
|
|
{
|
|
# set the PAI header
|
|
$var(ccli_selector) = $avp(s:callee_outbound_pai_user);
|
|
xlog("L_INFO", "Prepare PAI username setting - [% logreq -%]\n");
|
|
route(ROUTE_PREPARE_CLI_CALLER);
|
|
if($var(ccli_user) != 0)
|
|
{
|
|
$var(caller_uri) = "sip:" + $var(ccli_user) + "@" + $var(ccli_domain);
|
|
xlog("L_INFO", "Setting PAI to '<$var(caller_uri)>' - [% logreq -%]\n");
|
|
append_hf("P-Asserted-Identity: <$var(caller_uri)>\r\n");
|
|
}
|
|
|
|
# set the PPI header
|
|
$var(ccli_selector) = $avp(s:callee_outbound_ppi_user);
|
|
xlog("L_INFO", "Prepare PPI username setting - [% logreq -%]\n");
|
|
route(ROUTE_PREPARE_CLI_CALLER);
|
|
if($var(ccli_user) != 0)
|
|
{
|
|
$var(caller_uri) = "sip:" + $var(ccli_user) + "@" + $var(ccli_domain);
|
|
xlog("L_INFO", "Setting PPI to '<$var(caller_uri)>' - [% logreq -%]\n");
|
|
append_hf("P-Preferred-Identity: <$var(caller_uri)>\r\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "PAI and PPI skipped for onnet clir calls - [% logreq -%]\n");
|
|
}
|
|
|
|
# apogrebennyk: comment out check for FLAG in order to forward Diversion also when clir=1
|
|
if($avp(s:caller_clir) != 1)
|
|
{
|
|
# set the Diversion header
|
|
$var(ccli_selector) = $avp(s:callee_outbound_diversion);
|
|
xlog("L_INFO", "Prepare Diversion setting - [% logreq -%]\n");
|
|
route(ROUTE_PREPARE_CLI_CALLER);
|
|
if($var(ccli_user) != 0)
|
|
{
|
|
$var(diversion_uri) = "sip:" + $var(ccli_user) + "@" + $var(ccli_domain);
|
|
xlog("L_INFO", "Setting Diversion to '<$var(diversion_uri)>' - [% logreq -%]\n");
|
|
#append_hf("Diversion: <$var(diversion_uri)>;reason=unknown\r\n");
|
|
add_diversion("unknown", "$var(diversion_uri)");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
########################################################################
|
|
# Reply route 'base-standard-reply'
|
|
########################################################################
|
|
onreply_route[REPLY_ROUTE_STD] #Manwe: Maybe to dissapear. Left for local routes for now
|
|
{
|
|
xlog("L_INFO", "Reply - [% logres_init -%]\n");
|
|
|
|
if(has_body("application/sdp") && ($avp(s:from_faxserver) == 1 || $avp(s:to_faxserver) == 1))
|
|
{
|
|
# fix for T.38 to patton faxserver gateway, which chokes on upper-case
|
|
xlog("L_INFO", "Rewriting T.38 'UDPTL' to 'udptl' - [% logres -%]\n");
|
|
replace_body_all(" UDPTL ", " udptl ");
|
|
}
|
|
|
|
if($avp(s:reply_sock) != $null)
|
|
{
|
|
append_hf("P-Out-Socket: $avp(s:reply_sock)\r\n");
|
|
}
|
|
if(status == "408")
|
|
{
|
|
$var(ext_timeout) = 1;
|
|
}
|
|
exit;
|
|
|
|
}
|
|
|
|
########################################################################
|
|
# Reply route 'base-nat-reply'
|
|
########################################################################
|
|
onreply_route[REPLY_ROUTE_NAT]
|
|
{
|
|
xlog("L_INFO", "NAT-Reply - [% logres_init -%]\n");
|
|
force_rport();
|
|
|
|
if(has_body("application/sdp") && ($avp(s:from_faxserver) == 1 || $avp(s:to_faxserver) == 1))
|
|
{
|
|
# fix for T.38 to patton faxserver gateway, which chokes on upper-case
|
|
xlog("L_INFO", "Rewriting T.38 'UDPTL' to 'udptl' - [% logres -%]\n");
|
|
replace_body_all(" UDPTL ", " udptl ");
|
|
}
|
|
|
|
if(status=~"(180)|(183)|2[0-9][0-9]")
|
|
{
|
|
if(!search("^Content-Length:[ ]*0") && !t_is_canceled() &&
|
|
has_body("application/sdp") && isbflagset(FLB_RTPPROXY))
|
|
{
|
|
$var(ice_flags) = 0;
|
|
if (isflagset(FLAG_DOWNSTREAM))
|
|
{ #same direction as original request
|
|
if(isbflagset(FLB_ICE_CALLER_REPLACE))
|
|
{
|
|
xlog("L_INFO", "Replace existing ICE candidates (if any) for caller - [% logres -%]\n");
|
|
$var(ice_flags) = "+";
|
|
}
|
|
else if(isbflagset(FLB_ICE_CALLER_STRIP))
|
|
{
|
|
xlog("L_INFO", "Remove existing ICE candidates (if any) for caller - [% logres -%]\n");
|
|
$var(ice_flags) = "-";
|
|
}
|
|
else if(isbflagset(FLB_ICE_CALLER_ADD))
|
|
{
|
|
xlog("L_INFO", "Add mediaproxy as ICE candidate for caller - [% logres -%]\n");
|
|
}
|
|
}
|
|
else
|
|
{ #opposite direction to original request
|
|
if(isbflagset(FLB_ICE_CALLEE_REPLACE))
|
|
{
|
|
xlog("L_INFO", "Replace existing ICE candidates (if any) for callee with mediaproxy ICE canditate - [% logres -%]\n");
|
|
$var(ice_flags) = "+";
|
|
}
|
|
else if(isbflagset(FLB_ICE_CALLEE_STRIP))
|
|
{
|
|
xlog("L_INFO", "Remove existing ICE candidates (if any) for callee - [% logres -%]\n");
|
|
$var(ice_flags) = "-";
|
|
}
|
|
else if(isbflagset(FLB_ICE_CALLEE_ADD))
|
|
{
|
|
xlog("L_INFO", "Add mediaproxy as ICE candidate for callee - [% logres -%]\n");
|
|
}
|
|
}
|
|
# normally we do an rtpproxy lookup in the reply, unless
|
|
# we have 200/ACK negotiation
|
|
if(isbflagset(FLB_RTPPROXY_LOOKUP))
|
|
{
|
|
$var(rtpp_flags) = "FRWOC2";
|
|
xlog("L_INFO", "Use mediaproxy for backward direction - [% logres -%]\n");
|
|
if($var(ice_flags) != 0)
|
|
{
|
|
$var(rtpp_flags) = $var(rtpp_flags) + $var(ice_flags);
|
|
}
|
|
rtpproxy_answer($var(rtpp_flags));
|
|
}
|
|
else
|
|
{
|
|
$var(rtpp_flags) = "FRWOC";
|
|
if(isbflagset(FLB_CALLER_IPV6) && isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy offer for backward direction for IPv6/IPv6 - [% logres -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "EE2";
|
|
}
|
|
else if(isbflagset(FLB_CALLER_IPV6) && !isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy offer for backward direction for IPv6/IPv4 - [% logres -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "IE2";
|
|
}
|
|
# we need to switch ei/ie in case of 200/ACK negotiation
|
|
else if(!isbflagset(FLB_CALLER_IPV6) && isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy offer for backward direction for IPv4/IPv6 - [% logres -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "EI2";
|
|
}
|
|
else # if(!isbflagset(FLB_CALLER_IPV6) && !isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy offer for backward direction for IPv4/IPv4 - [% logres -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "II2";
|
|
}
|
|
if($var(ice_flags) != 0)
|
|
{
|
|
$var(rtpp_flags) = $var(rtpp_flags) + $var(ice_flags);
|
|
}
|
|
rtpproxy_offer($var(rtpp_flags));
|
|
}
|
|
}
|
|
}
|
|
if($avp(s:reply_sock) != $null)
|
|
{
|
|
append_hf("P-Out-Socket: $avp(s:reply_sock)\r\n");
|
|
}
|
|
if(status == "408")
|
|
{
|
|
$var(ext_timeout) = 1;
|
|
}
|
|
exit;
|
|
|
|
}
|
|
|
|
########################################################################
|
|
# Failure route for early rejects
|
|
########################################################################
|
|
failure_route[FAILURE_ROUTE_EARLY_REJECT]
|
|
{
|
|
xlog("L_INFO", "Failure route for early rejection, rs='$T_rpl($rs)', expected rs='$avp(s:announce_code)' - [% logreq -%]\n");
|
|
|
|
route(ROUTE_STOP_RTPPROXY_BRANCH);
|
|
if($T_rpl($rs) != $avp(s:announce_code) && $T_rpl($rs) != 487)
|
|
{
|
|
xlog("L_INFO", "Overriding reply code '$T_rpl($rs)' with '$avp(s:announce_code)' - [% logreq -%]\n");
|
|
t_reply("$avp(s:announce_code)", "$avp(s:announce_reason)");
|
|
}
|
|
exit;
|
|
}
|
|
|
|
########################################################################
|
|
# Failure route 'pstn-failover'
|
|
########################################################################
|
|
failure_route[FAILURE_ROUTE_PSTN]
|
|
{
|
|
# reset previous D-Uri, otherwise the wrong destination is
|
|
# used for cfb
|
|
$du = $null;
|
|
|
|
# initialise variables when entering failure route
|
|
$var(loose_routed) = 0;
|
|
$var(no_acc) = 0;
|
|
$var(allow_peer) = 0;
|
|
$var(to_pstn) = 1;
|
|
|
|
xlog("L_INFO", "Failure route for PSTN call - [% logreq -%]\n");
|
|
|
|
unset_dlg_profile("peer","$avp(s:lcr_flags)");
|
|
unset_dlg_profile("peerout","$avp(s:lcr_flags)");
|
|
xlog("L_INFO", "Unset dialog mark peer and peerout '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
|
|
route(ROUTE_FILTER_FAILOVER);
|
|
setbflag(FLB_NATB);
|
|
while($var(allow_peer) != 1)
|
|
{
|
|
$var(allow_peer) = 1;
|
|
if(!next_gw())
|
|
{
|
|
xlog("L_INFO", "No more peering servers found - [% logreq -%]\n");
|
|
route(ROUTE_STOP_RTPPROXY_BRANCH);
|
|
exit;
|
|
}
|
|
|
|
if($avp(s:lcr_flags) != $null && $avp(s:lcr_flags) != 0)
|
|
{
|
|
route(ROUTE_CLEAR_PEER_OUT_PREF);
|
|
route(ROUTE_LOAD_PEER_OUT_PREF);
|
|
}
|
|
|
|
if($xavp(callee_peer_prefs=>concurrent_max) != $null && $xavp(callee_peer_prefs=>concurrent_max) != 0 && $avp(s:em_call) != 1)
|
|
{
|
|
if(get_profile_size("peer","$avp(s:lcr_flags)","$avp(s:size)"))
|
|
{
|
|
if ($avp(s:size) >= $xavp(callee_peer_prefs=>concurrent_max))
|
|
{
|
|
xlog("L_INFO", "Concurrent_max calls exceeded for peer '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
$var(allow_peer) = 0;
|
|
}
|
|
}
|
|
}
|
|
if($xavp(callee_peer_prefs=>concurrent_max_out) != $null && $xavp(callee_peer_prefs=>concurrent_max_out) != 0 && $avp(s:em_call) != 1)
|
|
{
|
|
if(get_profile_size("peerout","$avp(s:lcr_flags)","$avp(s:size)"))
|
|
{
|
|
if ($avp(s:size) >= $xavp(callee_peer_prefs=>concurrent_max_out))
|
|
{
|
|
xlog("L_INFO", "Concurrent_max_out calls exceeded for peer '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
$var(allow_peer) = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
set_dlg_profile("peer","$avp(s:lcr_flags)");
|
|
set_dlg_profile("peerout","$avp(s:lcr_flags)");
|
|
xlog("L_INFO", "Dialog set mark peer and peerout '$avp(s:lcr_flags)' - [% logreq -%]\n");
|
|
|
|
resetbflag(FLB_CALLEE_IPV6);
|
|
if($rd =~ "^\[[a-fA-F0-9\:\.]+\]$")
|
|
{
|
|
setbflag(FLB_CALLEE_IPV6);
|
|
}
|
|
|
|
t_on_failure("FAILURE_ROUTE_PSTN");
|
|
# suppress writing records in outbound route
|
|
$var(no_acc) = 1;
|
|
# trigger rewrite of callee acc leg in branch route
|
|
# to reflect the current gw ip in destination domain of cdr
|
|
$var(reset_acc_callee) = 1;
|
|
#t_on_branch("BRANCH_ROUTE_SBC");
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
|
|
########################################################################
|
|
# Failure route for voicebox
|
|
########################################################################
|
|
failure_route[FAILURE_ROUTE_VOICEBOX]
|
|
{
|
|
route(ROUTE_FILTER_FAILOVER);
|
|
$var(local_endpoint) = 1;
|
|
setbflag(FLB_NATB);
|
|
if(!ds_next_dst())
|
|
{
|
|
xlog("L_ERR", "Failed to select next voicebox server - [% logreq -%]\n");
|
|
route(ROUTE_STOP_RTPPROXY_BRANCH);
|
|
exit;
|
|
}
|
|
|
|
t_on_failure("FAILURE_ROUTE_VOICEBOX");
|
|
$var(no_acc) = 1;
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
|
|
########################################################################
|
|
# Failure route for Faxserver
|
|
########################################################################
|
|
failure_route[FAILURE_ROUTE_FAXSERVER]
|
|
{
|
|
route(ROUTE_FILTER_FAILOVER);
|
|
$var(local_endpoint) = 1;
|
|
setbflag(FLB_NATB);
|
|
if(!ds_next_dst())
|
|
{
|
|
xlog("L_ERR", "Failed to select next Faxserver gateway - [% logreq -%]\n");
|
|
route(ROUTE_STOP_RTPPROXY_BRANCH);
|
|
exit;
|
|
}
|
|
|
|
t_on_failure("FAILURE_ROUTE_FAXSERVER");
|
|
$var(no_acc) = 1;
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
|
|
########################################################################
|
|
# Failure route for Application Server
|
|
########################################################################
|
|
failure_route[FAILURE_ROUTE_APPSRV]
|
|
{
|
|
xlog("L_INFO", "Failure route for Application Server call - [% logreq -%]\n");
|
|
|
|
route(ROUTE_FILTER_FAILOVER);
|
|
$var(local_endpoint) = 1;
|
|
setbflag(FLB_NATB);
|
|
if(!ds_next_dst())
|
|
{
|
|
xlog("L_ERR", "Failed to select next Application Server server - [% logreq -%]\n");
|
|
route(ROUTE_STOP_RTPPROXY_BRANCH);
|
|
exit;
|
|
}
|
|
|
|
t_on_failure("FAILURE_ROUTE_APPSRV");
|
|
$var(no_acc) = 1;
|
|
route(ROUTE_OUTBOUND);
|
|
}
|
|
|
|
########################################################################
|
|
# Failure route 'base-standard-failure'
|
|
########################################################################
|
|
failure_route[FAILURE_ROUTE_LOCAL]
|
|
{
|
|
xlog("L_INFO", "Failure route for local call - [% logreq -%]\n");
|
|
|
|
# reset previous D-Uri, otherwise the wrong destination is
|
|
# used for cfb
|
|
$du = $null;
|
|
|
|
# initialise variables when entering failure route
|
|
$var(loose_routed) = 0;
|
|
$var(no_acc) = 0;
|
|
$var(no_auth) = 0;
|
|
$var(forward) = 0;
|
|
$var(redirected_forward) = 0;
|
|
$var(external_domain) = 0;
|
|
$var(ext_timeout) = 0;
|
|
$var(noauth) = 0;
|
|
$var(from_trusted) = 0;
|
|
$var(to_pstn) = 0;
|
|
$var(reset_acc_callee) = 0;
|
|
$var(no_sbc) = 0;
|
|
$var(sendfax) = 0;
|
|
$var(local_endpoint) = 0;
|
|
route(ROUTE_STOP_RTPPROXY_BRANCH);
|
|
|
|
if(t_check_status("402|422|481|487") || t_is_canceled())
|
|
{
|
|
xlog("L_INFO", "Final reply - [% logreq -%]\n");
|
|
exit;
|
|
}
|
|
if(t_check_status("404") && ($avp(s:has_extension) == 1 || $avp(s:callee_e164_to_ruri) == 1) && !isflagset(FLAG_IN_FALLBACK))
|
|
{
|
|
$(avp(s:acc_state)[*]) = "cfu";
|
|
$(avp(s:acc_caller_user)[*]) = $avp(s:acc_callee_user);
|
|
$(avp(s:acc_caller_domain)[*]) = $avp(s:acc_callee_domain);
|
|
$rU = $avp(s:callee_user);
|
|
$rd = $avp(s:callee_domain);
|
|
setflag(FLAG_IN_FALLBACK);
|
|
append_branch();
|
|
|
|
if($avp(s:has_extension) == 1)
|
|
{
|
|
xlog("L_INFO", "Fallback from extension to user - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Fallback from E164 number to user - [% logreq -%]\n");
|
|
}
|
|
$var(forward) = 1;
|
|
# caller is the same user, skip loading caller's prefs
|
|
#route(ROUTE_LOAD_CALLER_PREF);
|
|
route(ROUTE_FIND_CALLEE);
|
|
}
|
|
if(t_check_status("301|302"))
|
|
{
|
|
$(avp(s:acc_state)[*]) = "cfb";
|
|
$(avp(s:acc_caller_user)[*]) = $avp(s:acc_callee_user);
|
|
$(avp(s:acc_caller_domain)[*]) = $avp(s:acc_callee_domain);
|
|
$(avp(s:caller_uuid)[*]) = $avp(s:callee_uuid);
|
|
$(avp(s:callee_uuid)[*]) = $null;
|
|
if(!get_redirects("1:1"))
|
|
{
|
|
|
|
xlog("L_ERROR", "Failed to fetch contact '$ct' from 301/302 - [% logreq -%]\n");
|
|
acc_db_request("480", "acc");
|
|
$var(announce_handle) = "callee_tmp_unavailable";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 480;
|
|
$(avp(s:announce_reason)[*]) = "Temporarily Unavailable";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
# get last URI from destination-set and set it as R-URI
|
|
avp_delete("$avp(s:tmp)/g");
|
|
$avp(s:tmp) = $ds;
|
|
avp_subst("$avp(s:tmp)", "/.*(sip:.+@[^:;>]+).*$/\1/");
|
|
avp_pushto("$ru", "$avp(s:tmp)");
|
|
append_branch();
|
|
|
|
#t_on_branch("BRANCH_ROUTE_SBC");
|
|
xlog("L_INFO", "Redirect from UAC intercepted - [% logreq -%]\n");
|
|
$var(forward) = 1;
|
|
$var(redirected_forward) = 1;
|
|
route(ROUTE_LOAD_CALLER_PREF);
|
|
route(ROUTE_FIND_CALLEE);
|
|
}
|
|
else if(t_check_status("486"))
|
|
{
|
|
while($avp(s:callee_cfb) != $null)
|
|
{
|
|
$var(cf_id) = $(avp(s:callee_cfb)[0]);
|
|
xlog("L_INFO", "CFB to CF map id '$var(cf_id)' found - [% logreq -%]\n");
|
|
route(ROUTE_LOAD_CF_MAP);
|
|
while($avp(s:cf_destinations) != $null && $(avp(s:cf_destinations)[0]) =~ "^sip:localuser@.+\.local$")
|
|
{
|
|
xlog("L_INFO", "CFB breakout to local user skipped - [% logreq -%]\n");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
}
|
|
if($avp(s:cf_destinations) == $null)
|
|
{
|
|
xlog("L_INFO", "CFB skipped due to forward destinations definitions - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_CHECK_CF_PERIOD);
|
|
if($rc == 1)
|
|
{
|
|
xlog("L_INFO", "CFB to destination '$(avp(s:cf_destinations)[0])' with timeout '$(avp(s:cf_timeouts)[0])' activated - [% logreq -%]\n");
|
|
$ru = $(avp(s:cf_destinations)[0]);
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
$(avp(s:callee_fr_inv_timer)[*]) = $(avp(s:cf_timeouts)[0]) * 1000;
|
|
t_set_fr("$avp(s:callee_fr_inv_timer)");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_depth)[*]) = $(avp(s:cf_depth){s.int}) + 1;
|
|
$(avp(s:acc_state)[*]) = "cfb";
|
|
$(avp(s:acc_caller_user)[*]) = $avp(s:acc_callee_user);
|
|
$(avp(s:acc_caller_domain)[*]) = $avp(s:acc_callee_domain);
|
|
append_branch();
|
|
route(ROUTE_EXECUTE_CF_LOOP);
|
|
exit;
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "CFB skipped due to time period definitions - [% logreq -%]\n");
|
|
}
|
|
}
|
|
$(avp(s:callee_cfb)[0]) = $null;
|
|
}
|
|
$var(announce_handle) = "callee_busy";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 486;
|
|
$(avp(s:announce_reason)[*]) = "Busy Here";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
else if(t_check_status("408") && $var(ext_timeout) != 1)
|
|
{
|
|
while($avp(s:callee_cft) != $null)
|
|
{
|
|
$var(cf_id) = $(avp(s:callee_cft)[0]);
|
|
xlog("L_INFO", "CFT to CF map id '$var(cf_id)' found - [% logreq -%]\n");
|
|
route(ROUTE_LOAD_CF_MAP);
|
|
while($avp(s:cf_destinations) != $null && $(avp(s:cf_destinations)[0]) =~ "^sip:localuser@.+\.local$")
|
|
{
|
|
xlog("L_INFO", "CFT breakout to local user skipped - [% logreq -%]\n");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
}
|
|
if($avp(s:cf_destinations) == $null)
|
|
{
|
|
xlog("L_INFO", "CFT skipped due to forward destinations definitions - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_CHECK_CF_PERIOD);
|
|
if($rc == 1)
|
|
{
|
|
xlog("L_INFO", "CFT to destination '$(avp(s:cf_destinations)[0])' with timeout '$(avp(s:cf_timeouts)[0])' activated - [% logreq -%]\n");
|
|
$ru = $(avp(s:cf_destinations)[0]);
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
$(avp(s:callee_fr_inv_timer)[*]) = $(avp(s:cf_timeouts)[0]) * 1000;
|
|
t_set_fr("$avp(s:callee_fr_inv_timer)");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_depth)[*]) = $(avp(s:cf_depth){s.int}) + 1;
|
|
$(avp(s:acc_state)[*]) = "cft";
|
|
$(avp(s:acc_caller_user)[*]) = $avp(s:acc_callee_user);
|
|
$(avp(s:acc_caller_domain)[*]) = $avp(s:acc_callee_domain);
|
|
append_branch();
|
|
route(ROUTE_EXECUTE_CF_LOOP);
|
|
exit;
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "CFT skipped due to time period definitions - [% logreq -%]\n");
|
|
}
|
|
}
|
|
$(avp(s:callee_cft)[0]) = $null;
|
|
}
|
|
$var(announce_handle) = "callee_tmp_unavailable";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = 408;
|
|
$(avp(s:announce_reason)[*]) = "Request Timeout";
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
while($avp(s:callee_cfna) != $null)
|
|
{
|
|
$var(cf_id) = $(avp(s:callee_cfna)[0]);
|
|
xlog("L_INFO", "CFNA to CF map id '$var(cf_id)' found - [% logreq -%]\n");
|
|
route(ROUTE_LOAD_CF_MAP);
|
|
while($avp(s:cf_destinations) != $null && $(avp(s:cf_destinations)[0]) =~ "^sip:localuser@.+\.local$")
|
|
{
|
|
xlog("L_INFO", "CFNA breakout to local user skipped - [% logreq -%]\n");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
}
|
|
if($avp(s:cf_destinations) == $null)
|
|
{
|
|
xlog("L_INFO", "CFNA skipped due to forward destinations definitions - [% logreq -%]\n");
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_CHECK_CF_PERIOD);
|
|
if($rc == 1)
|
|
{
|
|
xlog("L_INFO", "CFNA to destination '$(avp(s:cf_destinations)[0])' with timeout '$(avp(s:cf_timeouts)[0])' activated - [% logreq -%]\n");
|
|
$ru = $(avp(s:cf_destinations)[0]);
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
$(avp(s:callee_fr_inv_timer)[*]) = $(avp(s:cf_timeouts)[0]) * 1000;
|
|
t_set_fr("$avp(s:callee_fr_inv_timer)");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_depth)[*]) = $(avp(s:cf_depth){s.int}) + 1;
|
|
$(avp(s:acc_state)[*]) = "cfna";
|
|
$(avp(s:acc_caller_user)[*]) = $avp(s:acc_callee_user);
|
|
$(avp(s:acc_caller_domain)[*]) = $avp(s:acc_callee_domain);
|
|
append_branch();
|
|
route(ROUTE_EXECUTE_CF_LOOP);
|
|
exit;
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "CFNA skipped due to time period definitions - [% logreq -%]\n");
|
|
}
|
|
}
|
|
$(avp(s:callee_cfna)[0]) = $null;
|
|
}
|
|
|
|
$var(announce_handle) = "callee_tmp_unavailable";
|
|
$var(announce_set) = $avp(s:callee_sound_set);
|
|
$(avp(s:announce_code)[*]) = $T_rpl($rs);
|
|
$(avp(s:announce_reason)[*]) = $T_rpl($rr);
|
|
route(ROUTE_EARLY_REJECT);
|
|
}
|
|
|
|
########################################################################
|
|
# Failure route for serial call hunting
|
|
########################################################################
|
|
failure_route[FAILURE_ROUTE_HUNT]
|
|
{
|
|
xlog("L_INFO", "Failure route for hunt call - [% logreq -%]\n");
|
|
route(ROUTE_STOP_RTPPROXY_BRANCH);
|
|
if(t_check_status("402|422|481|487") || t_is_canceled())
|
|
{
|
|
xlog("L_INFO", "Final reply - [% logreq -%]\n");
|
|
exit;
|
|
}
|
|
|
|
# reset previous D-Uri, otherwise the wrong destination is
|
|
# used for cfb
|
|
$du = $null;
|
|
|
|
if($avp(s:acc_state) != "cfu")
|
|
{
|
|
while($avp(s:cf_destinations) != $null && $(avp(s:cf_destinations)[0]) =~ "^sip:localuser@.+\.local$")
|
|
{
|
|
xlog("L_INFO", "CF breakout to local user skipped - [% logreq -%]\n");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
}
|
|
}
|
|
if($avp(s:cf_destinations) != $null)
|
|
{
|
|
$ru = $(avp(s:cf_destinations)[0]);
|
|
|
|
if($ru =~ "^sip:localuser@.+\.local$")
|
|
{
|
|
t_reset_fr();
|
|
$(avp(s:cf_destinations)[*]) = $null;
|
|
$(avp(s:cf_timeouts)[*]) = $null;
|
|
$(avp(s:cf_periods)[*]) = $null;
|
|
$(avp(s:callee_cfu)[*]) = $null;
|
|
$ru = "sip:" + $avp(s:acc_callee_user) + "@" + $avp(s:acc_callee_domain);
|
|
xlog("L_INFO", "Stop hunting for CFU to own subscriber - [% logreq -%]\n");
|
|
$var(forward) = 1;
|
|
$(avp(s:nohunt)[*]) = 1;
|
|
append_branch();
|
|
# no need to load caller prefs as only the destination changes
|
|
route(ROUTE_FIND_CALLEE);
|
|
}
|
|
|
|
$(avp(s:cf_destinations)[0]) = $null;
|
|
$(avp(s:callee_fr_inv_timer)[*]) = $(avp(s:cf_timeouts)[0]) * 1000;
|
|
t_set_fr("$avp(s:callee_fr_inv_timer)");
|
|
$(avp(s:cf_timeouts)[0]) = $null;
|
|
$(avp(s:cf_depth)[*]) = $(avp(s:cf_depth){s.int}) + 1;
|
|
append_branch();
|
|
if($rd =~ "^.+\.local$")
|
|
{
|
|
avp_delete("$avp(s:caller_uuid)/g");
|
|
avp_copy("$avp(s:callee_uuid)", "$avp(s:caller_uuid)/d");
|
|
$(avp(s:acc_caller_user)[*]) = $avp(s:acc_callee_user);
|
|
$(avp(s:acc_caller_domain)[*]) = $avp(s:acc_callee_domain);
|
|
$var(forward) = 1;
|
|
route(ROUTE_LOAD_CALLER_PREF);
|
|
route(ROUTE_FIND_CALLEE);
|
|
exit;
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_EXECUTE_CF_LOOP);
|
|
exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Branch route for forwarding loop
|
|
########################################################################
|
|
branch_route[BRANCH_ROUTE_FWD_LOOP]
|
|
{
|
|
$(avp(s:app_server_params)[*]) = $null;
|
|
if(([% FOREACH ip IN sip_int_ips -%]$du != "sip:[% ip %]:[% kamailio.proxy.port %]" && [% END -%]is_domain_local("$rd")) ||
|
|
$dd =~ "\.local$" || ($du == $null && $rd =~ "\.local$"))
|
|
{
|
|
xlog("L_INFO", "Dropping local hunt branch - [% logreq -%]\n");
|
|
drop;
|
|
exit;
|
|
}
|
|
|
|
xlog("L_INFO", "Setting sbcprofile to cf - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";profile=ngcp_cf";
|
|
|
|
#Write sbc params
|
|
xlog("L_INFO", "Writing sbc parameters $avp(s:app_server_params) - [% logreq -%]\n");
|
|
append_hf("P-App-Param: $avp(s:app_server_params)\r\n");
|
|
if(is_present_hf("P-App-Param"))
|
|
{
|
|
remove_hf("P-App-Param");
|
|
}
|
|
|
|
if(is_present_hf("P-App-Name"))
|
|
{
|
|
remove_hf("P-App-Name");
|
|
}
|
|
append_hf("P-App-Name: sbc\r\n");
|
|
#Append P-D-URI
|
|
xlog("L_INFO", "Appending P-D-URI '$du' - [% logreq -%]\n");
|
|
remove_hf("P-D-Uri");
|
|
append_hf("P-D-Uri: $du\n");
|
|
|
|
$du = "sip:[% sip_int_ips.0 %]:[% sems.bindport %]";
|
|
xlog("L_INFO", "Forcing request via B2BUA '$du' - [% logreq -%]\n");
|
|
}
|
|
|
|
########################################################################
|
|
# Branch route for mediaproxy activation and a few typical functions -
|
|
# required calls going through sbc as well as calls to application servers
|
|
########################################################################
|
|
route[ROUTE_BRANCH_ACC_RTP]
|
|
{
|
|
if(is_domain_local("$rd") || $dd =~ "\.local$" || ($du == $null && $rd =~ "\.local$"))
|
|
{
|
|
xlog("L_INFO", "Dropping local branch - [% logreq -%]\n");
|
|
drop;
|
|
exit;
|
|
}
|
|
|
|
if($var(reset_acc_callee) == 1)
|
|
{
|
|
# rewrite callee acc leg to put in correct destination domain
|
|
$(avp(i:902)[*]) = $null;
|
|
$(avp(s:acc_callee_domain)[*]) = $null;
|
|
$avp(s:acc_callee_domain) = $rd;
|
|
route(ROUTE_ACC_CALLEE);
|
|
}
|
|
|
|
resetbflag(FLB_PEERAUTH);
|
|
|
|
# we still need to set the params in case of 200/ACK and later re-invite
|
|
|
|
if(isbflagset(FLB_CALLER_IPV6) && isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
add_rr_param(";mpd=ee");
|
|
}
|
|
else if(isbflagset(FLB_CALLER_IPV6) && !isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
add_rr_param(";mpd=ei");
|
|
}
|
|
else if(!isbflagset(FLB_CALLER_IPV6) && isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
add_rr_param(";mpd=ie");
|
|
}
|
|
else # if(!isbflagset(FLB_CALLER_IPV6) && !isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
add_rr_param(";mpd=ii");
|
|
}
|
|
|
|
if($avp(s:first_caller_use_rtpproxy) == "ice_replace_candidates")
|
|
{
|
|
add_rr_param(";ice_caller=replace");
|
|
setbflag(FLB_ICE_CALLER_REPLACE);
|
|
}
|
|
else if($avp(s:first_caller_use_rtpproxy) == "ice_add_candidates")
|
|
{
|
|
add_rr_param(";ice_caller=add");
|
|
setbflag(FLB_ICE_CALLER_ADD);
|
|
}
|
|
else #if($avp(s:first_caller_use_rtpproxy) == "ice_strip_candidates")
|
|
{
|
|
add_rr_param(";ice_caller=strip");
|
|
setbflag(FLB_ICE_CALLER_STRIP);
|
|
}
|
|
if($avp(s:callee_use_rtpproxy) == "ice_replace_candidates" || ($var(to_pstn) == 1 && $avp(s:peer_callee_use_rtpproxy) == "ice_replace_candidates"))
|
|
{
|
|
add_rr_param(";ice_callee=replace");
|
|
setbflag(FLB_ICE_CALLEE_REPLACE);
|
|
}
|
|
else if($avp(s:callee_use_rtpproxy) == "ice_add_candidates" || ($var(to_pstn) == 1 && $avp(s:peer_callee_use_rtpproxy) == "ice_add_candidates"))
|
|
{
|
|
add_rr_param(";ice_callee=add");
|
|
setbflag(FLB_ICE_CALLEE_ADD);
|
|
}
|
|
else #if($avp(s:callee_use_rtpproxy) == "ice_strip_candidates" || ($var(to_pstn) == 1 && $avp(s:peer_callee_use_rtpproxy) == "ice_strip_candidates"))
|
|
{
|
|
add_rr_param(";ice_callee=strip");
|
|
setbflag(FLB_ICE_CALLEE_STRIP);
|
|
}
|
|
|
|
if(has_body("application/sdp"))
|
|
{
|
|
if($avp(s:from_faxserver) == 1 || $avp(s:to_faxserver) == 1)
|
|
{
|
|
# fix for T.38 to patton faxserver gateway, which chokes on upper-case
|
|
xlog("L_INFO", "Rewriting T.38 'UDPTL' to 'udptl' - [% logreq -%]\n");
|
|
replace_body_all(" UDPTL ", " udptl ");
|
|
}
|
|
|
|
if(($avp(s:callee_use_rtpproxy) == "never" || $avp(s:first_caller_use_rtpproxy) == "never") && $var(local_endpoint) == 0)
|
|
{
|
|
xlog("L_INFO", "Usage of mediaproxy unforced by preference - [% logreq -%]\n");
|
|
resetbflag(FLB_RTPPROXY);
|
|
}
|
|
else if($var(proxylu_src) == 1)
|
|
{
|
|
xlog("L_INFO", "Usage of mediaproxy unforced on proxylu source - [% logreq -%]\n");
|
|
resetbflag(FLB_RTPPROXY);
|
|
}
|
|
else
|
|
{
|
|
$var(rtpp_flags) = "FRWOC";
|
|
|
|
if(!isbflagset(FLB_NATB))
|
|
{
|
|
xlog("L_INFO", "Usage of mediaproxy forced by preference - [% logreq -%]\n");
|
|
}
|
|
|
|
if($avp(s:initial_caller_ipv46_for_rtpproxy) == "force_ipv4")
|
|
{
|
|
xlog("L_INFO", "Force IPv4 in mediaproxy for initial caller - [% logreq -%]\n");
|
|
resetbflag(FLB_CALLER_IPV6);
|
|
}
|
|
else if($avp(s:initial_caller_ipv46_for_rtpproxy) == "force_ipv6")
|
|
{
|
|
xlog("L_INFO", "Force IPv6 in mediaproxy for initial caller - [% logreq -%]\n");
|
|
setbflag(FLB_CALLER_IPV6);
|
|
}
|
|
if(($var(to_pstn) == 1 && $avp(s:peer_callee_ipv46_for_rtpproxy) == "force_ipv4") || $avp(s:callee_ipv46_for_rtpproxy) == "force_ipv4")
|
|
{
|
|
xlog("L_INFO", "Force IPv4 in mediaproxy for callee - [% logreq -%]\n");
|
|
resetbflag(FLB_CALLEE_IPV6);
|
|
}
|
|
else if(($var(to_pstn) == 1 && $avp(s:peer_callee_ipv46_for_rtpproxy) == "force_ipv6") || $avp(s:callee_ipv46_for_rtpproxy) == "force_ipv6")
|
|
{
|
|
xlog("L_INFO", "Force IPv6 in mediaproxy for callee - [% logreq -%]\n");
|
|
setbflag(FLB_CALLEE_IPV6);
|
|
}
|
|
|
|
if(isbflagset(FLB_CALLER_IPV6) && isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy for forward direction for IPv6/IPv6 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "EE1";
|
|
}
|
|
else if(isbflagset(FLB_CALLER_IPV6) && !isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy for forward direction for IPv6/IPv4 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "EI1";
|
|
}
|
|
else if(!isbflagset(FLB_CALLER_IPV6) && isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy for forward direction for IPv4/IPv6 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "IE1";
|
|
}
|
|
else # if(!isbflagset(FLB_CALLER_IPV6) && !isbflagset(FLB_CALLEE_IPV6))
|
|
{
|
|
xlog("L_INFO", "Use mediaproxy for forward direction for IPv4/IPv4 - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "II1";
|
|
}
|
|
|
|
if(isflagset(FLAG_DOWNSTREAM))
|
|
{
|
|
if(isbflagset(FLB_ICE_CALLEE_REPLACE))
|
|
{
|
|
xlog("L_INFO", "Replace existing ICE candidates (if any) for callee with mediaproxy ICE canditate - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "+";
|
|
}
|
|
else if(isbflagset(FLB_ICE_CALLEE_STRIP))
|
|
{
|
|
xlog("L_INFO", "Remove existing ICE candidates (if any) for callee - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "-";
|
|
}
|
|
else if(isbflagset(FLB_ICE_CALLEE_ADD))
|
|
{
|
|
xlog("L_INFO", "Add mediaproxy as ICE candidate for callee - [% logreq -%]\n");
|
|
}
|
|
}
|
|
else if(isflagset(FLAG_UPSTREAM))
|
|
{
|
|
if(isbflagset(FLB_ICE_CALLER_REPLACE))
|
|
{
|
|
xlog("L_INFO", "Replace existing ICE candidates (if any) for caller with mediaproxy ICE canditate - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "+";
|
|
}
|
|
else if(isbflagset(FLB_ICE_CALLER_STRIP))
|
|
{
|
|
xlog("L_INFO", "Remove existing ICE candidates (if any) for caller - [% logreq -%]\n");
|
|
$var(rtpp_flags) = $var(rtpp_flags) + "-";
|
|
}
|
|
else if(isbflagset(FLB_ICE_CALLER_ADD))
|
|
{
|
|
xlog("L_INFO", "Add mediaproxy as ICE candidate for caller - [% logreq -%]\n");
|
|
}
|
|
}
|
|
rtpproxy_offer($var(rtpp_flags));
|
|
setbflag(FLB_RTPPROXY); # remember that we use rtpproxy
|
|
setbflag(FLB_RTPPROXY_LOOKUP); # force rtpproxy lookup in the reply (opposed to 200/ACK)
|
|
add_rr_param(";rtpprx=yes");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "No SDP found, skip mediaproxy for forward direction - [% logreq -%]\n");
|
|
resetbflag(FLB_RTPPROXY);
|
|
}
|
|
|
|
if($avp(s:caller_uuid) != $null && !is_present_hf("P-Caller-UUID"))
|
|
{
|
|
xlog("L_INFO", "Setting P-Caller-UUID to '$avp(s:caller_uuid)' - [% logreq -%]\n");
|
|
append_hf("P-Caller-UUID: $avp(s:caller_uuid)\r\n");
|
|
}
|
|
if($avp(s:callee_uuid) != $null && !is_present_hf("P-Callee-UUID"))
|
|
{
|
|
xlog("L_INFO", "Setting P-Callee-UUID to '$avp(s:callee_uuid)' - [% logreq -%]\n");
|
|
append_hf("P-Callee-UUID: $avp(s:callee_uuid)\r\n");
|
|
}
|
|
}
|
|
|
|
########################################################################
|
|
# Branch route 'no-sbc'
|
|
# Handle typical application server parameters (calling card, pbx etc)
|
|
########################################################################
|
|
branch_route[BRANCH_ROUTE_NO_SBC]
|
|
{
|
|
# Activate mediaproxy
|
|
route(ROUTE_BRANCH_ACC_RTP);
|
|
|
|
if($var(no_sbc) == 1)
|
|
{
|
|
if(uri =~ "^sip:mobilepush@app\.local$")
|
|
{
|
|
$(avp(s:app_server_params)[*]) = ";caller=" + $avp(s:caller_cli_userprov) + ";callee=" + $avp(s:acc_callee_user_in) + ";domain=" + $avp(s:callee_domain);
|
|
xlog("L_INFO", "Writing mobile_push params '$avp(s:app_server_params)' - [% logreq -%]\n");
|
|
if(is_present_hf("P-App-Param"))
|
|
{
|
|
remove_hf("P-App-Param");
|
|
}
|
|
append_hf("P-App-Param: $avp(s:app_server_params)\r\n");
|
|
|
|
if(is_present_hf("P-App-Name"))
|
|
{
|
|
remove_hf("P-App-Name");
|
|
}
|
|
append_hf("P-App-Name: mobile_push\r\n");
|
|
|
|
xlog("L_INFO", "Setting P-Called-Party-ID '<sip:$tU@$td>' - [% logreq -%]\n");
|
|
if(is_present_hf("P-Called-Party-ID"))
|
|
{
|
|
remove_hf("P-Called-Party-ID");
|
|
}
|
|
append_hf("P-Called-Party-ID: <sip:$tU@$td>\r\n");
|
|
|
|
xlog("L_INFO", "Setting P-Orig-Callee-User to '$avp(s:callee_user)' - [% logreq -%]\n");
|
|
if(is_present_hf("P-Orig-Callee-User"))
|
|
{
|
|
remove_hf("P-Orig-Callee-User");
|
|
}
|
|
append_hf("P-Orig-Callee-User: $avp(s:callee_user)\r\n");
|
|
#append_hf("P-Orig-Callee-Domain: $avp(s:callee_domain)\r\n");
|
|
}
|
|
route(ROUTE_SET_CLI_CALLER);
|
|
route(ROUTE_SET_CLI_CALLEE);
|
|
}
|
|
|
|
xlog("L_INFO", "Request leaving server, D-URI='$du' - [% logreq -%]\n");
|
|
}
|
|
|
|
########################################################################
|
|
# Branch route 'sbc'
|
|
# Handle sems sbc application parameters
|
|
########################################################################
|
|
branch_route[BRANCH_ROUTE_SBC]
|
|
{
|
|
$(avp(s:app_server_params)[*]) = $null;
|
|
|
|
# Activate mediaproxy
|
|
route(ROUTE_BRANCH_ACC_RTP);
|
|
# Activate prepaid
|
|
|
|
if($var(no_sbc) == 0)
|
|
{
|
|
#Auth credentials for caller (b2bua leg-b callee)
|
|
if($var(to_pstn) == 1)
|
|
{
|
|
if($avp(s:caller_peer_auth_user) != $null)
|
|
{
|
|
xlog("L_INFO", "Overruling peer auth user by caller value '$avp(s:caller_peer_auth_user)' - [% logreq -%]\n");
|
|
$(avp(s:peer_peer_caller_auth_user)[*]) = $avp(s:caller_peer_auth_user);
|
|
}
|
|
if($avp(s:caller_peer_auth_pass) != $null)
|
|
{
|
|
xlog("L_INFO", "Overruling peer auth pass by caller value '$avp(s:caller_peer_auth_pass)' - [% logreq -%]\n");
|
|
$(avp(s:peer_peer_caller_auth_pass)[*]) = $avp(s:caller_peer_auth_pass);
|
|
}
|
|
if($avp(s:caller_peer_auth_realm) != $null)
|
|
{
|
|
xlog("L_INFO", "Overruling peer auth realm by caller value '$avp(s:caller_peer_auth_realm)' - [% logreq -%]\n");
|
|
$(avp(s:peer_peer_caller_auth_realm)[*]) = $avp(s:caller_peer_auth_realm);
|
|
}
|
|
if($xavp(caller_peer_prefs=>peer_caller_auth_user) != $null && $xavp(caller_peer_prefs=>peer_caller_auth_pass) != $null && $xavp(caller_peer_prefs=>peer_caller_auth_realm) != $null)
|
|
{
|
|
xlog("L_INFO", "Adding peer authentication header P-App-Param with 'u=$xavp(caller_peer_prefs=>peer_caller_auth_user);d=$xavp(caller_peer_prefs=>peer_caller_auth_realm);p=$xavp(caller_peer_prefs=>peer_caller_auth_pass)' - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";u=" + $xavp(caller_peer_prefs=>peer_caller_auth_user) + ";d=" + $xavp(caller_peer_prefs=>peer_caller_auth_realm) + ";p=" + $xavp(caller_peer_prefs=>peer_caller_auth_pass);
|
|
setbflag(FLB_PEERAUTH);
|
|
}
|
|
}
|
|
|
|
# Auth credentials for callee (b2bua leg-a caller)
|
|
if($avp(s:from_pstn) == 1)
|
|
{
|
|
if($avp(s:callee_peer_auth_user) != $null)
|
|
{
|
|
xlog("L_INFO", "Overruling peer auth user by callee value '$avp(s:callee_peer_auth_user)' - [% logreq -%]\n");
|
|
$(avp(s:peer_peer_callee_auth_user)[*]) = $avp(s:callee_peer_auth_user);
|
|
}
|
|
if($avp(s:callee_peer_auth_pass) != $null)
|
|
{
|
|
xlog("L_INFO", "Overruling peer auth pass by callee value '$avp(s:callee_peer_auth_pass)' - [% logreq -%]\n");
|
|
$(avp(s:peer_peer_callee_auth_pass)[*]) = $avp(s:callee_peer_auth_pass);
|
|
}
|
|
if($avp(s:callee_peer_auth_realm) != $null)
|
|
{
|
|
xlog("L_INFO", "Overruling peer auth realm by callee value '$avp(s:callee_peer_auth_realm)' - [% logreq -%]\n");
|
|
$(avp(s:peer_peer_callee_auth_realm)[*]) = $avp(s:callee_peer_auth_realm);
|
|
}
|
|
if($avp(s:peer_peer_callee_auth_user) != $null && $avp(s:peer_peer_callee_auth_pass) != $null && $avp(s:peer_peer_callee_auth_realm) != $null)
|
|
{
|
|
xlog("L_INFO", "Adding peer authentication header P-App-Param with 'au=$avp(s:peer_peer_callee_auth_user);ad=$avp(s:peer_peer_callee_auth_realm);ap=$avp(s:peer_peer_callee_auth_pass)' - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";au=" + $avp(s:peer_peer_callee_auth_user) + ";ad=" + $avp(s:peer_peer_callee_auth_realm) + ";ap=" + $avp(s:peer_peer_callee_auth_pass);
|
|
setbflag(FLB_PEERAUTH);
|
|
}
|
|
}
|
|
|
|
#pass caller's settings as aleg_sst_*
|
|
if($avp(s:from_pstn) == 1)
|
|
{
|
|
if($avp(s:peer_caller_sst_enable) == "yes")
|
|
{
|
|
xlog("L_INFO", "Sessions Timers enabled for caller with interval $avp(s:peer_caller_sst_expires) and method $avp(s:peer_caller_sst_refresh_method) - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";aleg_sst_enable=yes" + ";aleg_sst_expires=" + $avp(s:peer_caller_sst_expires) +
|
|
";aleg_sst_min_timer=" + $avp(s:peer_caller_sst_min_timer) + ";aleg_sst_max_timer=" + $avp(s:peer_caller_sst_max_timer) +
|
|
";aleg_sst_refresh_method=" + $avp(s:peer_caller_sst_refresh_method);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Sessions Timers disabled for caller - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";aleg_sst_enable=no";
|
|
}
|
|
}
|
|
else if($avp(s:from_pstn) == 0)
|
|
{
|
|
if($avp(s:caller_sst_enable) == "yes" && $avp(s:from_faxserver) == 0 && $avp(s:from_voicebox) == 0)
|
|
{
|
|
xlog("L_INFO", "Sessions Timers enabled for caller with interval $avp(s:caller_sst_expires) and method $avp(s:caller_sst_refresh_method) - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";aleg_sst_enable=yes" + ";aleg_sst_expires=" + $avp(s:caller_sst_expires) +
|
|
";aleg_sst_min_timer=" + $avp(s:caller_sst_min_timer) + ";aleg_sst_max_timer=" + $avp(s:caller_sst_max_timer) +
|
|
";aleg_sst_refresh_method=" + $avp(s:caller_sst_refresh_method);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Sessions Timers disabled for caller - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";aleg_sst_enable=no";
|
|
}
|
|
}
|
|
#pass callee's settings as sst_*
|
|
if($var(to_pstn) == 1)
|
|
{
|
|
if($avp(s:peer_callee_sst_enable) == "yes")
|
|
{
|
|
xlog("L_INFO", "Sessions Timers enabled for callee with interval $avp(s:peer_callee_sst_expires) and method $avp(s:peer_callee_sst_refresh_method) - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";sst_enable=yes" + ";sst_expires=" + $avp(s:peer_callee_sst_expires) +
|
|
";sst_min_timer=" + $avp(s:peer_callee_sst_min_timer) + ";sst_max_timer=" + $avp(s:peer_callee_sst_max_timer) +
|
|
";sst_refresh_method=" + $avp(s:peer_callee_sst_refresh_method);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Sessions Timers disabled for callee - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";sst_enable=no";
|
|
}
|
|
}
|
|
else if($var(to_pstn) == 0)
|
|
{
|
|
if($avp(s:callee_sst_enable) == "yes")
|
|
{
|
|
xlog("L_INFO", "Sessions Timers enabled for callee with interval $avp(s:callee_sst_expires) and method $avp(s:callee_sst_refresh_method) - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";sst_enable=yes" +
|
|
";sst_expires=" + $avp(s:callee_sst_expires) + ";sst_min_timer=" + $avp(s:callee_sst_min_timer) +
|
|
";sst_max_timer=" + $avp(s:callee_sst_max_timer) + ";sst_refresh_method=" + $avp(s:callee_sst_refresh_method);
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Sessions Timers disabled for callee - [% logreq -%]\n");
|
|
$avp(s:app_server_params) = $avp(s:app_server_params) + ";sst_enable=no";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
# route below MUST be called after setbflag(FLB_PEERAUTH)
|
|
|
|
if(is_present_hf("P-Called-Party-ID"))
|
|
{
|
|
remove_hf("P-Called-Party-ID");
|
|
}
|
|
|
|
# if we're the source of a proxylu redirection, pass CLIs on in separate headers
|
|
# without any normalization
|
|
if($var(proxylu_src) == 1)
|
|
{
|
|
route(ROUTE_CLEAR_PROXYLU_HEADERS);
|
|
append_hf("P-First-Caller-UPN: sip:$avp(s:first_caller_cli_userprov)@$avp(s:first_caller_domain_userprov)\r\n");
|
|
append_hf("P-First-Caller-NPN: sip:$avp(s:first_caller_cli_netprov)@$avp(s:first_caller_domain_netprov)\r\n");
|
|
append_hf("P-First-Forwarder-UPN: sip:$avp(s:forwarder_cli_userprov)@$avp(s:forwarder_domain_userprov)\r\n");
|
|
append_hf("P-Caller-UPN: sip:$avp(s:caller_cli_userprov)@$avp(s:caller_domain_userprov)\r\n");
|
|
append_hf("P-Caller-NPN: sip:$avp(s:caller_cli_netprov)@$avp(s:caller_domain_netprov)\r\n");
|
|
append_hf("P-First-V46-RTP: $avp(s:initial_caller_ipv46_for_rtpproxy)\r\n");
|
|
append_hf("P-First-RTP: $avp(s:first_caller_use_rtpproxy)\r\n");
|
|
append_hf("P-Caller-CLIR: $avp(s:caller_clir)\r\n");
|
|
if($avp(s:caller_force_outbound_calls_to_peer) == 1)
|
|
{
|
|
$var(tmppinfo) = "1";
|
|
}
|
|
else
|
|
{
|
|
$var(tmppinfo) = "0";
|
|
}
|
|
if($avp(s:caller_peer_auth_user) != $null && $avp(s:caller_peer_auth_realm) != $null && $avp(s:caller_peer_auth_pass) != $null)
|
|
{
|
|
$var(tmppinfo) = $var(tmppinfo) + ";" + $avp(s:caller_peer_auth_user) + ";" + $avp(s:caller_peer_auth_realm) + ";" + $avp(s:caller_peer_auth_pass);
|
|
}
|
|
append_hf("P-Caller-PeerInfo: $var(tmppinfo)\r\n");
|
|
|
|
|
|
xlog("L_INFO", "Setting P-Called-Party-ID '<sip:$tU@$td>' - [% logreq -%]\n");
|
|
append_hf("P-Called-Party-ID: <sip:$tU@$td>\r\n");
|
|
}
|
|
else
|
|
{
|
|
route(ROUTE_SET_CLI_CALLER);
|
|
route(ROUTE_SET_CLI_CALLEE);
|
|
xlog("L_INFO", "Setting P-Called-Party-ID '<sip:$rU@$avp(s:callee_domain)>' - [% logreq -%]\n");
|
|
append_hf("P-Called-Party-ID: <sip:$rU@$avp(s:callee_domain)>\r\n");
|
|
}
|
|
|
|
#Write sbc params
|
|
xlog("L_INFO", "Writing sbc parameters $avp(s:app_server_params) - [% logreq -%]\n");
|
|
if(is_present_hf("P-App-Param"))
|
|
{
|
|
remove_hf("P-App-Param");
|
|
}
|
|
append_hf("P-App-Param: $avp(s:app_server_params)\r\n");
|
|
|
|
if(is_present_hf("P-App-Name"))
|
|
{
|
|
remove_hf("P-App-Name");
|
|
}
|
|
append_hf("P-App-Name: sbc\r\n");
|
|
|
|
if($xavp(caller_peer_prefs=>peer_caller_auth_realm) != $null)
|
|
{
|
|
xlog("L_INFO", "Setting R-URI using peer auth realm '$rU@$xavp(caller_peer_prefs=>peer_caller_auth_realm)' - [% logreq -%]\n");
|
|
$ru = "sip:" + $rU + "@" + $xavp(caller_peer_prefs=>peer_caller_auth_realm);
|
|
}
|
|
|
|
if($var(to_pstn) == 1 || $avp(s:to_faxserver) == 1)
|
|
{
|
|
# TODO: choose lbs from dispatcher list?
|
|
if($du == $null || $du == $ru)
|
|
{
|
|
xlog("L_INFO", "Setting 'sip:$rd:$rp' taken from R-URI as next hop after lb for PSTN call - [% logreq -%]\n");
|
|
if($var(foreign_dom) == 0)
|
|
{
|
|
if($(ru{uri.param,transport}) != $null)
|
|
{
|
|
$du = "sip:[% sip_lb_ips.0 %]:[% kamailio.lb.port %];received='sip:" + $rd + ":" + $rp + ";transport=" + $(ru{uri.param,transport}) + "'";
|
|
}
|
|
else
|
|
{
|
|
$du = "sip:[% sip_lb_ips.0 %]:[% kamailio.lb.port %];received=sip:" + $rd + ":" + $rp;
|
|
}
|
|
if($avp(s:peer_callee_outbound_socket) != $null)
|
|
{
|
|
xlog("L_INFO", "Forcing outbound socket '$avp(s:peer_callee_outbound_socket)' to peer - [% logreq -%]\n");
|
|
$du = $du + ";socket='" + $avp(s:peer_callee_outbound_socket) + "'";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
# for calls to foreign domains we don't set received param, as kamailio-lb
|
|
# is unable to do an SRV lookup for $du
|
|
if($(ru{uri.param,transport}) != $null)
|
|
{
|
|
$du = "sip:[% sip_lb_ips.0 %]:[% kamailio.lb.port %];transport=" + $(ru{uri.param,transport}) + "'";
|
|
}
|
|
else
|
|
{
|
|
$du = "sip:[% sip_lb_ips.0 %]:[% kamailio.lb.port %]";
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xlog("L_INFO", "Setting 'sip:$dd:$dp' taken from D-URI as next hop after lb for PSTN call - [% logreq -%]\n");
|
|
if($(du{uri.param,transport}) != $null)
|
|
{
|
|
$du = "sip:[% sip_lb_ips.0 %]:[% kamailio.lb.port %];received='sip:" + $dd + ":" + $dp + ";transport=" + $(du{uri.param,transport}) + "'";
|
|
}
|
|
else
|
|
{
|
|
$du = "sip:[% sip_lb_ips.0 %]:[% kamailio.lb.port %];received=sip:" + $dd + ":" + $dp;
|
|
}
|
|
if($avp(s:peer_callee_outbound_socket) != $null)
|
|
{
|
|
xlog("L_INFO", "Forcing outbound socket '$avp(s:peer_callee_outbound_socket)' to peer - [% logreq -%]\n");
|
|
$du = $du + ";socket='" + $avp(s:peer_callee_outbound_socket) + "'";
|
|
}
|
|
}
|
|
}
|
|
xlog("L_INFO", "Appending P-D-URI '$du' - [% logreq -%]\n");
|
|
remove_hf("P-D-Uri");
|
|
append_hf("P-D-Uri: $du\n");
|
|
|
|
$du = "sip:[% sip_int_ips.0 %]:[% sems.bindport %]";
|
|
xlog("L_INFO", "Forcing request via B2BUA '$du' - [% logreq -%]\n");
|
|
}
|
|
|
|
xlog("L_INFO", "Request leaving server, D-URI='$du' - [% logreq -%]\n");
|
|
}
|
|
|
|
|
|
# vim: ft=cfg
|