|
|
######## Kamailio mqueue module ########
|
|
loadmodule "mqueue.so"
|
|
|
|
######## Kamailio outbound module ########
|
|
loadmodule "outbound.so"
|
|
|
|
######## Kamailio stun module ########
|
|
loadmodule "stun.so"
|
|
|
|
######## Kamailio path module ########
|
|
loadmodule "path.so"
|
|
|
|
######## Kamailio control connector module ########
|
|
loadmodule "ctl.so"
|
|
modparam("ctl", "binrpc_buffer_size", 4096)
|
|
loadmodule "cfg_rpc.so"
|
|
|
|
######## Kamailio config utils module ########
|
|
loadmodule "cfgutils.so"
|
|
modparam("cfgutils", "lock_set_size", 4)
|
|
|
|
######## Kamailio corex module ########
|
|
loadmodule "corex.so"
|
|
|
|
######## Kamailio uuid module ########
|
|
loadmodule "uuid.so"
|
|
|
|
######## Kamailio core extensions module ########
|
|
loadmodule "kex.so"
|
|
|
|
######## Transaction (stateful) module ########
|
|
loadmodule "tm.so"
|
|
loadmodule "tmx.so"
|
|
modparam("tm", "auto_inv_100", 1)
|
|
modparam("tm", "auto_inv_100_reason", "Attempting to connect your call")
|
|
modparam("tm", "cancel_b_method", 2)
|
|
modparam("tm", "ruri_matching", 0)
|
|
modparam("tm", "failure_reply_mode", 3)
|
|
modparam("tm", "failure_exec_mode", 1)
|
|
modparam("tm", "reparse_on_dns_failover", 0)
|
|
|
|
|
|
# modparam("tm", "fr_timer", 30000)
|
|
# modparam("tm", "fr_inv_timer", 120000)
|
|
|
|
######## Stateless replier module ########
|
|
loadmodule "sl.so"
|
|
|
|
######## Record-Route and Route module ########
|
|
loadmodule "rr.so"
|
|
modparam("rr", "enable_full_lr", RR_FULL_LR)
|
|
modparam("rr", "enable_double_rr", RR_DOUBLE_RR)
|
|
modparam("rr", "force_send_socket", RR_FORCE_SOCKET)
|
|
modparam("rr", "ignore_sips", 1)
|
|
|
|
######## Max-Forward processor module ########
|
|
loadmodule "maxfwd.so"
|
|
modparam("maxfwd", "max_limit", 50)
|
|
|
|
######## SIP utilities [requires sl] ########
|
|
loadmodule "siputils.so"
|
|
|
|
######## Text operations module ########
|
|
loadmodule "textopsx.so"
|
|
|
|
######## sdp operations module ########
|
|
loadmodule "sdpops.so"
|
|
|
|
######## Generic Hash Table container in shared memory ########
|
|
loadmodule "htable.so"
|
|
modparam("htable", "htable", "associations=>size=16;autoexpire=7200")
|
|
modparam("htable", "db_url", "KAZOO_DB_URL")
|
|
|
|
####### RTIMER module ##########
|
|
loadmodule "rtimer.so"
|
|
|
|
####### evrexec module ##########
|
|
loadmodule "evrexec.so"
|
|
modparam("evrexec", "exec", "name=evrexec:DEFERRED_INIT;wait=20000000;workers=1;")
|
|
|
|
######## Advanced logger module ########
|
|
loadmodule "xlog.so"
|
|
|
|
######## UAC ########
|
|
loadmodule "uac.so"
|
|
|
|
######## AVP's ########
|
|
loadmodule "avp.so"
|
|
loadmodule "avpops.so"
|
|
|
|
######## UAC Redirection module ########
|
|
loadmodule "uac_redirect.so"
|
|
|
|
#### json rpc ####
|
|
loadmodule "jsonrpcs.so"
|
|
|
|
####### SQL OPS module ##########
|
|
loadmodule "sqlops.so"
|
|
modparam("sqlops","sqlcon", "cb=>KAZOO_DB_URL")
|
|
modparam("sqlops","sqlcon", "exec=>KAZOO_DB_URL")
|
|
|
|
####### DEBUG ######
|
|
loadmodule "debugger.so"
|
|
modparam("debugger", "mod_hash_size", 5)
|
|
modparam("debugger", "mod_level_mode", 1)
|
|
modparam("debugger", "mod_level", "core=1")
|
|
modparam("debugger", "mod_level", "tm=0")
|
|
|
|
####### STATISTICS ######
|
|
loadmodule "statistics.so"
|
|
|
|
####### DATABASE module ##########
|
|
include_file "db_KAMAILIO_DBMS.cfg"
|
|
|
|
###### kazoo bindings ######
|
|
include_file "kazoo-bindings.cfg"
|
|
|
|
####### Role Configurations ##########
|
|
#!ifdef DISPATCHER_ROLE
|
|
include_file "dispatcher-role-MAJOR.cfg"
|
|
#!endif
|
|
#!ifdef REGISTRAR_ROLE
|
|
include_file "registrar-role.cfg"
|
|
#!endif
|
|
#!ifdef PRESENCE_ROLE
|
|
include_file "presence-role.cfg"
|
|
#!endif
|
|
#!ifdef MESSAGE_ROLE
|
|
include_file "message-role.cfg"
|
|
#!endif
|
|
#!ifdef NAT_TRAVERSAL_ROLE
|
|
include_file "nat-traversal-role.cfg"
|
|
#!endif
|
|
#!ifdef WEBSOCKETS_ROLE
|
|
include_file "websockets-role.cfg"
|
|
#!endif
|
|
#!ifdef TLS_ROLE
|
|
include_file "tls-role.cfg"
|
|
#!endif
|
|
#!ifdef ACCOUNTING_ROLE
|
|
include_file "accounting-role.cfg"
|
|
#!endif
|
|
#!ifdef ANTIFLOOD_ROLE
|
|
include_file "antiflood-role.cfg"
|
|
#!endif
|
|
#!ifdef TRAFFIC_FILTER_ROLE
|
|
include_file "traffic-filter-role.cfg"
|
|
#!endif
|
|
#!ifdef ACL_ROLE
|
|
include_file "acl-role.cfg"
|
|
#!endif
|
|
#!ifdef RATE_LIMITER_ROLE
|
|
include_file "rate-limiter-role.cfg"
|
|
#!endif
|
|
#!ifdef PUSHER_ROLE
|
|
include_file "pusher-role.cfg"
|
|
#!endif
|
|
#!ifdef RESPONDER_ROLE
|
|
include_file "responder-role.cfg"
|
|
#!endif
|
|
#!ifdef NODES_ROLE
|
|
include_file "nodes-role.cfg"
|
|
#!endif
|
|
#!ifdef SIP_TRACE_ROLE
|
|
include_file "sip_trace-role.cfg"
|
|
#!endif
|
|
#!ifdef SIP_TRACE_ALL_ROLE
|
|
include_file "sip_trace_all-role.cfg"
|
|
#!endif
|
|
#!ifdef BLOCKER_ROLE
|
|
include_file "blocker-role.cfg"
|
|
#!endif
|
|
|
|
## sanity ##
|
|
include_file "sanity.cfg"
|
|
|
|
## auth ##
|
|
include_file "trusted.cfg"
|
|
include_file "authorization.cfg"
|
|
|
|
###### local route ######
|
|
tcp_children = 5
|
|
listen=tcp:127.0.0.1:5090
|
|
|
|
####### Routing Logic ########
|
|
route
|
|
{
|
|
route(LOCAL_REQUEST);
|
|
|
|
route(SANITY_CHECK);
|
|
|
|
route(CHECK_RETRANS);
|
|
|
|
#!ifdef ANTIFLOOD_ROLE
|
|
route(ANTIFLOOD_LIMIT);
|
|
#!endif
|
|
|
|
#!ifdef TRAFFIC_FILTER_ROLE
|
|
route(FILTER_REQUEST);
|
|
#!endif
|
|
|
|
#!ifdef ACL_ROLE
|
|
route(ACL_CHECK);
|
|
#!endif
|
|
|
|
#!ifdef RATE_LIMITER_ROLE
|
|
route(DOS_PREVENTION);
|
|
#!endif
|
|
|
|
route(LOG_REQUEST);
|
|
|
|
route(CLASSIFY_SOURCE);
|
|
|
|
#!ifdef NAT_TRAVERSAL_ROLE
|
|
route(NAT_DETECT);
|
|
#!endif
|
|
|
|
route(HANDLE_OPTIONS);
|
|
|
|
#!ifdef SIP_TRACE_ROLE
|
|
route(SIP_TRACE);
|
|
#!endif
|
|
|
|
route(HANDLE_NOTIFY);
|
|
|
|
#!ifdef REGISTRAR_ROLE
|
|
route(HANDLE_REGISTER);
|
|
#!endif
|
|
|
|
route_if_exists("CUSTOM_START_ROUTES");
|
|
|
|
#!ifdef RESPONDER_ROLE
|
|
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
|
|
route(HANDLE_RESPOND);
|
|
}
|
|
#!endif
|
|
|
|
if (!t_newtran()) {
|
|
xlog("L_ERROR", "$ci|log|failed to create transaction\n");
|
|
drop;
|
|
exit;
|
|
}
|
|
|
|
route(HANDLE_AUTHORIZATION);
|
|
|
|
}
|
|
|
|
route[MAIN]
|
|
{
|
|
route(AUTHORIZATION);
|
|
|
|
#!ifdef MESSAGE_ROLE
|
|
route(HANDLE_MESSAGE);
|
|
#!else
|
|
if (is_method("MESSAGE")) {
|
|
sl_send_reply("405", "Method Not Allowed");
|
|
exit;
|
|
}
|
|
#!endif
|
|
|
|
#!ifdef PRESENCE_ROLE
|
|
route(HANDLE_SUBSCRIBE);
|
|
route(HANDLE_PUBLISH);
|
|
#!endif
|
|
|
|
route(HANDLE_REFER);
|
|
|
|
route(HANDLE_IN_DIALOG_REQUESTS);
|
|
|
|
route(PREPARE_INITIAL_REQUESTS);
|
|
|
|
#!ifdef PUSHER_ROLE
|
|
route(PUSHER_ROUTE);
|
|
#!endif
|
|
|
|
route(SETUP);
|
|
}
|
|
|
|
#!trydef KZ_LOG_REQUEST_OPTIONS 0
|
|
kazoo.log_request_options = KZ_LOG_REQUEST_OPTIONS descr "log OPTIONS requests, default is 0 for preserving log size"
|
|
|
|
route[LOG_REQUEST]
|
|
{
|
|
if($sel(cfg_get.kazoo.log_request_options) == 0 && is_method("OPTIONS")) {
|
|
$var(log_request_level) = L_DBG;
|
|
} else {
|
|
$var(log_request_level) = L_INFO;
|
|
}
|
|
|
|
# log the basic info regarding this call
|
|
xlog("$var(log_request_level)", "$ci|start|received $pr request $rm $ou\n");
|
|
xlog("$var(log_request_level)", "$ci|log|source $si:$sp -> $RAi:$RAp\n");
|
|
xlog("$var(log_request_level)", "$ci|log|from $fu\n");
|
|
xlog("$var(log_request_level)", "$ci|log|to $tu\n");
|
|
}
|
|
|
|
route[CHECK_RETRANS]
|
|
{
|
|
# handle retransmissions
|
|
if (!is_method("ACK")) {
|
|
if(t_precheck_trans()) {
|
|
t_check_trans();
|
|
exit;
|
|
}
|
|
t_check_trans();
|
|
}
|
|
}
|
|
|
|
route[CLASSIFY_SOURCE]
|
|
{
|
|
if (allow_source_address()) {
|
|
xlog("$var(log_request_level)", "$ci|log|request from trusted IP\n");
|
|
setflag(FLAG_TRUSTED_SOURCE);
|
|
return;
|
|
}
|
|
|
|
#!ifdef DISPATCHER_ROLE
|
|
route(DISPATCHER_CLASSIFY_SOURCE);
|
|
#!endif
|
|
|
|
}
|
|
|
|
route[HANDLE_OPTIONS]
|
|
{
|
|
if (!is_method("OPTIONS")) {
|
|
return;
|
|
}
|
|
|
|
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
|
|
route(INTERNAL_TO_EXTERNAL_RELAY);
|
|
} else {
|
|
#!ifdef TRAFFIC_FILTER_ROLE
|
|
if (!isflagset(FLAG_TRUSTED_SOURCE)) {
|
|
route(FILTER_REQUEST_DOMAIN);
|
|
}
|
|
#!endif
|
|
|
|
sl_send_reply("200", "Rawr!!");
|
|
|
|
#!ifdef KEEPALIVE_ROLE
|
|
route(KEEPALIVE_ON_OPTIONS);
|
|
#!endif
|
|
}
|
|
exit;
|
|
}
|
|
|
|
route[HANDLE_NOTIFY]
|
|
{
|
|
if (!is_method("NOTIFY")) return;
|
|
|
|
if (has_totag()) return;
|
|
|
|
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
|
|
if (loose_route()) {
|
|
xlog("L_INFO", "$ci|log|Able to loose-route. Cool beans!\n");
|
|
}
|
|
|
|
#!ifdef REGISTRAR_ROLE
|
|
if (registered("location")) {
|
|
lookup("location");
|
|
xlog("L_INFO", "$ci|log|routing to $ruid\n");
|
|
}
|
|
#!endif
|
|
|
|
## verify we're not routing to ourselves
|
|
if(is_myself($du)) {
|
|
xlog("L_INFO", "$ci|log|notify from internal to invalid destination $ruid\n");
|
|
sl_send_reply("200", "Rawr!!");
|
|
exit;
|
|
}
|
|
|
|
route(INTERNAL_TO_EXTERNAL_RELAY);
|
|
} else {
|
|
#!ifdef TRAFFIC_FILTER_ROLE
|
|
if (!isflagset(FLAG_TRUSTED_SOURCE)) {
|
|
route(FILTER_REQUEST_DOMAIN);
|
|
}
|
|
#!endif
|
|
|
|
if($hdr(Event) == "keep-alive") {
|
|
xlog("L_INFO", "$ci|stop|replying to keep alive\n");
|
|
sl_send_reply("405", "Stay Alive / Method Not Allowed");
|
|
} else {
|
|
xlog("L_INFO", "$ci|stop|consuming event $hdr(Event)\n");
|
|
sl_send_reply("200", "Rawr!!");
|
|
}
|
|
|
|
}
|
|
exit;
|
|
}
|
|
|
|
route[HANDLE_REFER]
|
|
{
|
|
if (!is_method("REFER")) {
|
|
return;
|
|
}
|
|
|
|
if(is_present_hf("Referred-By")) {
|
|
$var(referred_by) = $hdr(Referred-By);
|
|
} else {
|
|
$var(referred_by) = $_s(<sip:$Au>;created=true);
|
|
}
|
|
|
|
if(!isflagset(FLAG_INTERNALLY_SOURCED)) {
|
|
if(isflagset(FLAG_REGISTERED_ENDPOINT)) {
|
|
$var(referred_by) = $_s($var(referred_by);endpoint_id=$(xavp(ulattrs=>token){re.subst,/(.*)@(.*)/\1/});account_id=$(xavp(ulattrs=>token){re.subst,/(.*)@(.*)/\2/}));
|
|
}
|
|
} else {
|
|
record_route();
|
|
}
|
|
|
|
remove_hf_re("^Referred-By");
|
|
append_hf("Referred-By: $var(referred_by)\r\n");
|
|
|
|
}
|
|
|
|
route[HANDLE_IN_DIALOG_REQUESTS]
|
|
{
|
|
if (!has_totag()) return;
|
|
|
|
if (is_method("INVITE")) {
|
|
setflag(FLAG_SESSION_PROGRESS);
|
|
record_route();
|
|
}
|
|
|
|
if (loose_route()) {
|
|
|
|
#!ifdef NAT_TRAVERSAL_ROLE
|
|
if(!isdsturiset()) {
|
|
handle_ruri_alias();
|
|
}
|
|
if ( is_method("ACK") ) {
|
|
# ACK is forwarded statelessly
|
|
route(NAT_MANAGE);
|
|
}
|
|
#!endif
|
|
|
|
#!ifdef ACCOUNTING_ROLE
|
|
if (is_method("BYE")) {
|
|
setflag(FLAG_ACC);
|
|
setflag(FLAG_ACCFAILED);
|
|
}
|
|
#!endif
|
|
|
|
xlog("L_INFO", "$ci|log|loose_route in-dialog message\n");
|
|
# Called on in-dialog requests
|
|
# If the request in an Invite for on hold from external to internal,
|
|
# associate the contact with the media server
|
|
# if Invite for on hold, we need to associate the contact URI with the next hop
|
|
if (is_method("INVITE") && !isflagset(FLAG_INTERNALLY_SOURCED) && is_audio_on_hold()) {
|
|
setflag(FLAG_ASSOCIATE_USER);
|
|
}
|
|
|
|
# If the request in an Invite for t38 from internal,
|
|
# mark the request with FLT_T38
|
|
if (is_method("INVITE") && isflagset(FLAG_INTERNALLY_SOURCED) && sdp_with_media("image")) {
|
|
xlog("L_DEBUG", "$ci|log|T38 RE-INVITE\n");
|
|
setflag(FLT_T38);
|
|
}
|
|
|
|
if ( is_method("NOTIFY") ) {
|
|
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
|
|
record_route();
|
|
}
|
|
route(RELAY);
|
|
} else if (isflagset(FLAG_INTERNALLY_SOURCED)) {
|
|
xlog("L_INFO", "$ci|log|relay internally sourced in-dialog message without loose_route\n");
|
|
route(RELAY);
|
|
} else if (t_check_trans()) {
|
|
xlog("L_INFO", "$ci|log|allow message for a known transaction\n");
|
|
if ( is_method("NOTIFY") ) {
|
|
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
|
|
record_route();
|
|
}
|
|
route(RELAY);
|
|
} else {
|
|
xlog("L_INFO", "$ci|log|message had a to-tag but can't be loose routed\n");
|
|
sl_send_reply("481", "Call Leg/Transaction Does Not Exist");
|
|
}
|
|
exit();
|
|
}
|
|
|
|
route[PREPARE_INITIAL_REQUESTS]
|
|
{
|
|
if (is_method("CANCEL")) {
|
|
if (t_check_trans()) {
|
|
route(RELAY);
|
|
} else {
|
|
sl_send_reply("481", "Call leg/transaction does not exist");
|
|
}
|
|
exit();
|
|
} else if (is_method("ACK")) {
|
|
if (t_check_trans()) {
|
|
route(RELAY);
|
|
}
|
|
exit();
|
|
}
|
|
|
|
if (is_method("UPDATE")) {
|
|
xlog("L_WARN", "$ci|end|update outside dialog not allowed\n");
|
|
send_reply("403", "Dialog does not exist");
|
|
break;
|
|
}
|
|
|
|
if (is_method("BYE|PRACK")) {
|
|
xlog("L_WARN", "$ci|end|originating subsequent requests outside dialog not allowed\n");
|
|
send_reply("403", "Dialog does not exist");
|
|
break;
|
|
}
|
|
|
|
loose_route();
|
|
|
|
if(!isflagset(FLAG_INTERNALLY_SOURCED)) {
|
|
record_route();
|
|
}
|
|
|
|
}
|
|
|
|
route[SETUP]
|
|
{
|
|
|
|
#!ifdef DISPATCHER_ROLE
|
|
if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
|
|
route(DISPATCHER_FIND_ROUTES);
|
|
} else {
|
|
route(ROUTE_TO_AOR);
|
|
}
|
|
#!endif
|
|
|
|
route(RELAY);
|
|
}
|
|
|
|
route[BRANCH_HEADERS]
|
|
{
|
|
if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
|
|
route(AUTH_HEADERS);
|
|
} else {
|
|
remove_hf_re("^X-");
|
|
}
|
|
}
|
|
|
|
# Manage outgoing branches
|
|
branch_route[MANAGE_BRANCH] {
|
|
xlog("L_INFO", "$ci|branch|new branch [$T_branch_idx] to $ru\n");
|
|
#!ifdef NAT_TRAVERSAL_ROLE
|
|
route(NAT_MANAGE);
|
|
#!endif
|
|
|
|
route(BRANCH_HEADERS);
|
|
route_if_exists("CUSTOM_BRANCH_HEADERS");
|
|
}
|
|
|
|
route[RELAY]
|
|
{
|
|
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE|NOTIFY|CANCEL")) {
|
|
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
|
|
}
|
|
|
|
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
|
|
xlog("L_DEBUG", "$ci|relay|internal to external\n");
|
|
if(!isflagset(FLAG_RECORD_ROUTE_ADDED) && !has_totag()) {
|
|
xlog("L_DEBUG", "$ci|relay|adding record route\n");
|
|
record_route();
|
|
}
|
|
route(INTERNAL_TO_EXTERNAL_RELAY);
|
|
} else {
|
|
xlog("L_DEBUG", "$ci|relay|external to internal\n");
|
|
route(EXTERNAL_TO_INTERNAL_RELAY);
|
|
}
|
|
|
|
exit();
|
|
}
|
|
|
|
route[INTERNAL_TO_EXTERNAL_RELAY]
|
|
{
|
|
#!ifdef ACCOUNTING_ROLE
|
|
if (is_method("INVITE")) {
|
|
setflag(FLAG_ACC);
|
|
setflag(FLAG_ACCFAILED);
|
|
}
|
|
#!endif
|
|
|
|
route_if_exists("CUSTOM_INTERNAL_TO_EXTERNAL_RELAY");
|
|
|
|
t_on_reply("EXTERNAL_REPLY");
|
|
t_on_failure("EXTERNAL_FAULT");
|
|
|
|
if($sel(cfg_get.kazoo.use_progressive_timers) == 1) {
|
|
t_set_fr(0, $sel(cfg_get.kazoo.to_external_no_response_initial_timer));
|
|
} else {
|
|
t_set_fr(0, $sel(cfg_get.kazoo.to_external_no_response_timer));
|
|
}
|
|
|
|
t_relay();
|
|
}
|
|
|
|
route[EXTERNAL_TO_INTERNAL_RELAY]
|
|
{
|
|
#!ifdef ACCOUNTING_ROLE
|
|
if (is_method("INVITE") && is_present_hf("Proxy-Authorization")) {
|
|
setflag(FLAG_ACC);
|
|
setflag(FLAG_ACCFAILED);
|
|
}
|
|
#!endif
|
|
|
|
t_on_reply("INTERNAL_REPLY");
|
|
t_on_failure("INTERNAL_FAULT");
|
|
|
|
if($sel(cfg_get.kazoo.use_progressive_timers) == 1) {
|
|
t_set_fr(0, $sel(cfg_get.kazoo.to_internal_no_response_initial_timer));
|
|
} else {
|
|
t_set_fr(0, $sel(cfg_get.kazoo.to_internal_no_response_timer));
|
|
}
|
|
|
|
#!ifdef WITH_INTERNAL_LISTENER
|
|
xlog("L_DEBUG", "$ci|route|routing to internal thru PORT_PROTO_INTERNAL_LISTENER\n");
|
|
force_send_socket(PORT_PROTO_INTERNAL_LISTENER);
|
|
#!endif
|
|
|
|
t_relay();
|
|
}
|
|
|
|
onreply_route[EXTERNAL_REPLY]
|
|
{
|
|
if ($rs < 300) {
|
|
xlog("L_INFO", "$ci|log|external reply $T_reply_code $T_reply_reason\n");
|
|
}
|
|
|
|
if($rs == 100) {
|
|
if($sel(cfg_get.kazoo.use_progressive_timers) == 1) {
|
|
t_set_fr(0, $sel(cfg_get.kazoo.to_external_no_response_100_timer));
|
|
}
|
|
} else if(status=~"[1][8][0-9]") {
|
|
if($sel(cfg_get.kazoo.use_progressive_timers) == 1) {
|
|
t_set_fr(0, $sel(cfg_get.kazoo.to_external_no_response_18X_timer));
|
|
}
|
|
}
|
|
|
|
#!ifdef NAT_TRAVERSAL_ROLE
|
|
route(NAT_MANAGE);
|
|
#!endif
|
|
|
|
#!ifdef ACL_ROLE
|
|
setflag(FLAG_IS_REPLY);
|
|
route(ACL_CHECK);
|
|
#!endif
|
|
|
|
#!ifdef RATE_LIMITER_ROLE
|
|
setflag(FLAG_IS_REPLY);
|
|
route(DOS_PREVENTION);
|
|
#!endif
|
|
|
|
}
|
|
|
|
failure_route[EXTERNAL_FAULT]
|
|
{
|
|
# this branch handles failures (>=300) to external
|
|
|
|
route_if_exists("CUSTOM_EXTERNAL_FAULT");
|
|
|
|
# if the failure cause was due to the transaction being
|
|
# cancelled then we are complete
|
|
if (t_is_canceled()) {
|
|
xlog("L_INFO", "$ci|log|transaction was cancelled\n");
|
|
exit;
|
|
}
|
|
|
|
xlog("L_INFO", "$ci|failure|external reply $T_reply_code $T_reply_reason\n");
|
|
}
|
|
|
|
|
|
onreply_route[INTERNAL_REPLY]
|
|
{
|
|
# this route handles replies that are comming from our media server
|
|
if ($rs < 300) {
|
|
xlog("L_INFO", "$ci|log|internal reply $T_reply_code $T_reply_reason\n");
|
|
}
|
|
|
|
if($rs == 100) {
|
|
if($sel(cfg_get.kazoo.use_progressive_timers) == 1) {
|
|
t_set_fr(0, $sel(cfg_get.kazoo.to_internal_no_response_100_timer));
|
|
}
|
|
} else if(status=~"[1][8][0-9]") {
|
|
if($sel(cfg_get.kazoo.use_progressive_timers) == 1) {
|
|
t_set_fr(0, $sel(cfg_get.kazoo.to_internal_no_response_18X_timer));
|
|
}
|
|
}
|
|
|
|
#!ifdef NAT_TRAVERSAL_ROLE
|
|
route(NAT_MANAGE);
|
|
#!endif
|
|
|
|
#!ifdef ACL_ROLE
|
|
setflag(FLAG_IS_REPLY);
|
|
route(ACL_CHECK);
|
|
#!endif
|
|
|
|
#!ifdef RATE_LIMITER_ROLE
|
|
setflag(FLAG_IS_REPLY);
|
|
route(DOS_PREVENTION);
|
|
#!endif
|
|
|
|
if (is_method("INVITE") && t_check_status("(180)|(183)|(200)")) {
|
|
xlog("L_INFO", "$ci|log|call setup, now ignoring abnormal termination\n");
|
|
setflag(FLAG_SESSION_PROGRESS);
|
|
}
|
|
|
|
}
|
|
|
|
failure_route[INTERNAL_FAULT]
|
|
{
|
|
# this branch handles failures (>=300) to our media servers,
|
|
# which we can sometimes overcome by routing to another server
|
|
|
|
# if the failure cause was due to the transaction being
|
|
# cancelled then we are complete
|
|
if (t_is_canceled()) {
|
|
xlog("L_INFO", "$ci|log|transaction was cancelled\n");
|
|
exit;
|
|
}
|
|
|
|
if (!is_method("INVITE") || has_totag()) {
|
|
xlog("L_INFO", "$ci|failure|internal reply $T_reply_code $T_reply_reason\n");
|
|
return;
|
|
}
|
|
|
|
# Handle redirects
|
|
if (t_check_status("302") && $T_rpl($hdr(X-Redirect-Server)) != $null) {
|
|
route(INTERNAL_REDIRECT);
|
|
}
|
|
|
|
remove_hf_re("^X-.*");
|
|
|
|
# change 6xx to 4xx
|
|
if (t_check_status("6[0-9][0-9]") && !t_check_status("600|603|604|606")) {
|
|
$var(new_code) = "4" + $(T_reply_code{s.substr,1,0});
|
|
xlog("L_INFO", "$ci|failure|sending $T_reply_code reply as $var(new_code) $T_reply_reason\n");
|
|
t_reply("$(var(new_code){s.int})", "$T_reply_reason");
|
|
|
|
# if the failure case was something that we should recover
|
|
# from then try to find a new media server
|
|
} else if ($T_reply_reason =~ "call barred") {
|
|
xlog("L_INFO", "$ci|failure|ignoring call barred\n");
|
|
} else if (isflagset(FLAG_SESSION_PROGRESS)) {
|
|
xlog("L_INFO", "$ci|failure|ignoring failure after session progress\n");
|
|
if (t_check_status("480")) {
|
|
xlog("L_INFO", "$ci|failure|overriding reply code 480 with 486\n");
|
|
send_reply("486", "Endpoint Not Available");
|
|
}
|
|
} else if (t_check_status("403") && $T_reply_reason=="Forbidden") {
|
|
xlog("L_WARNING", "$ci|failure|Failed auth from IP $si\n");
|
|
} else if (t_check_status("(401)|(486)")) {
|
|
xlog("L_INFO", "$ci|failure|auth reply $T_reply_code $T_reply_reason\n");
|
|
} else if (t_check_status("402")) {
|
|
xlog("L_INFO", "$ci|failure|overriding reply code 402 with 486\n");
|
|
send_reply("486", "Insufficient Funds");
|
|
} else if (t_check_status("(4[0-9][0-9])|(5[0-9][0-9])")) {
|
|
xlog("L_INFO", "$ci|failure|internal reply $T_reply_code $T_reply_reason\n");
|
|
|
|
#!ifdef DISPATCHER_ROLE
|
|
route(DISPATCHER_NEXT_ROUTE);
|
|
#!endif
|
|
|
|
send_reply("486", "Unable to Comply");
|
|
|
|
} else {
|
|
xlog("L_INFO", "$ci|failure|internal reply $T_reply_code $T_reply_reason\n");
|
|
send_reply("$T_reply_code", "$T_reply_reason");
|
|
}
|
|
}
|
|
|
|
route[INTERNAL_REDIRECT]
|
|
{
|
|
xlog("L_INFO", "$ci|log|redirect to $T_rpl($hdr(X-Redirect-Server))\n");
|
|
$du = $T_rpl($hdr(X-Redirect-Server));
|
|
t_on_branch("MANAGE_BRANCH");
|
|
t_on_reply("INTERNAL_REPLY");
|
|
t_on_failure("INTERNAL_FAULT");
|
|
t_set_fr(0, 1000);
|
|
t_relay();
|
|
exit();
|
|
}
|
|
|
|
|
|
onsend_route {
|
|
if (isflagset(FLAG_ASSOCIATE_USER) && is_request()) {
|
|
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
|
|
xlog("L_INFO", "$ci|log|associate traffic from $var(user_source) with media server sip:$sndto(ip):$sndto(port)\n");
|
|
$sht(associations=>$var(user_source))= "sip:" + $sndto(ip) + ":" + $sndto(port);
|
|
}
|
|
|
|
#!ifdef SIP_TRACE_ROLE
|
|
if (is_method("ACK") && isflagset(FLAG_SIP_TRACE) && is_request()) {
|
|
sip_trace();
|
|
}
|
|
#!endif
|
|
|
|
if(!isflagset(FLAG_LOCAL_ROUTE)) {
|
|
xlog("L_INFO", "$ci|pass|$snd(sproto)|$sndfrom(ip):$sndfrom(port) -> $sndto(ip):$sndto(port)\n");
|
|
}
|
|
}
|
|
|
|
#!trydef AOR_NOT_SUBSCRIBED_APPEND_REASON
|
|
#!trydef AOR_NOT_SUBSCRIBED_REASON Reason: Q.850; cause=20;text="Subscriber Absent"
|
|
|
|
route[ROUTE_TO_AOR]
|
|
{
|
|
if ($hdr(X-KAZOO-AOR) == $null) {
|
|
xlog("L_DEBUG", "$ci|aor|not aor\n");
|
|
return;
|
|
}
|
|
|
|
xlog("L_INFO", "$ci|log|using AOR $hdr(X-KAZOO-AOR)\n");
|
|
if ($hdr(X-KAZOO-INVITE-FORMAT) == "contact") {
|
|
if(lookup("location", "$hdr(X-KAZOO-AOR)") > 0){
|
|
xlog("L_INFO", "$ci|end|routing to contact $ru\n");
|
|
$avp(aor) = $hdr(X-KAZOO-AOR);
|
|
handle_ruri_alias();
|
|
} else {
|
|
xlog("L_INFO", "$ci|end|lookup for AOR $hdr(X-KAZOO-AOR) failed\n");
|
|
append_to_reply("$def(AOR_NOT_SUBSCRIBED_REASON)\r\n");
|
|
send_reply("480", "Not registered");
|
|
exit;
|
|
}
|
|
} else if (reg_fetch_contacts("location", "$hdr(X-KAZOO-AOR)", "callee")) {
|
|
$du = $(ulc(callee=>received));
|
|
$fs = $(ulc(callee=>socket));
|
|
$bf = $bf | $(ulc(callee=>cflags));
|
|
xlog("L_INFO", "$ci|log|routing $hdr(X-KAZOO-AOR) to $du via $fs\n");
|
|
$avp(aor) = $hdr(X-KAZOO-AOR);
|
|
} else {
|
|
xlog("L_INFO", "$ci|end|user is not registered\n");
|
|
append_to_reply("$def(AOR_NOT_SUBSCRIBED_REASON)\r\n");
|
|
send_reply("410", "Not registered");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
event_route[tm:local-request]
|
|
{
|
|
setflag(FLAG_LOCAL_REQUEST);
|
|
xlog("L_DEBUG", "$ci|local|start $pr request $rm $ou\n");
|
|
xlog("L_DEBUG", "$ci|local|source $si:$sp -> $dd:$dp\n");
|
|
xlog("L_DEBUG", "$ci|local|from $fu\n");
|
|
xlog("L_DEBUG", "$ci|local|to $tu\n");
|
|
|
|
#!ifdef SIP_TRACE_ROLE
|
|
route(SIP_TRACE);
|
|
#!endif
|
|
|
|
#!ifdef PRESENCE_ROLE
|
|
route(PRESENCE_LOCAL_REQUEST);
|
|
#!endif
|
|
|
|
}
|
|
|
|
event_route[evrexec:DEFERRED_INIT]
|
|
{
|
|
xlog("L_INFO", "processing deferred init\n");
|
|
|
|
#!ifdef PRESENCE_ROLE
|
|
route(PRESENCE_DEFERRED_INIT);
|
|
#!endif
|
|
|
|
#!import_file "custom-init.cfg"
|
|
|
|
}
|
|
|
|
route[LOCAL_REQUEST]
|
|
{
|
|
if(src_ip != myself || $hdr(X-TM-Local) == $null) {
|
|
return;
|
|
}
|
|
|
|
xlog("L_DEBUG", "internal route $hdr(X-TM-Local)\n");
|
|
|
|
setflag(FLAG_LOCAL_ROUTE);
|
|
|
|
#!ifdef SIP_TRACE_ROLE
|
|
route(SIP_TRACE);
|
|
#!endif
|
|
|
|
$var(LocalRoute) = $hdr(X-TM-Local);
|
|
remove_hf_re("^X-TM-Local");
|
|
route_if_exists("$var(LocalRoute)");
|
|
exit;
|
|
}
|
|
|
|
#!import_file "custom-routes.cfg"
|
|
|
|
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
|