## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ## ####### Flags ####### flags FLAG_INTERNALLY_SOURCED: 1, FLAG_ASSOCIATE_SERVER: 2, FLAG_SKIP_NAT_CORRECTION: 3, FLAG_ASSOCIATE_USER: 4, FLAG_TRUSTED_SOURCE: 5, FLAG_SESSION_PROGRESS: 6, FLAG_IS_REPLY: 7, FLAG_SIP_TRACE: 8; ####### Global Parameters ######### fork = yes children = CHILDREN server_signature = no server_header = "Server: Kazoo" user_agent_header = "User-Agent: Kazoo" shm_force_alloc = yes mlock_pages = yes phone2tel = 1 max_while_loops = MAX_WHILE_LOOPS pv_buffer_size=65536 mem_join=1 ####### Logging Parameters ######### debug = KAZOO_LOG_LEVEL memdbg = 10 memlog = L_INFO corelog = L_ERR mem_summary = 12 log_stderror = no log_facility = LOG_LOCAL0 log_name="kamailio" ####### Alias Parameters ######### auto_aliases = yes ####### Binding Parameters ######### tos = IPTOS_LOWDELAY ####### TCP Parameters ######### tcp_children = TCP_CHILDREN disable_tcp = no tcp_max_connections = 4096 tcp_connection_lifetime = 3605 tcp_accept_aliases = no tcp_async = yes tcp_connect_timeout = 10 tcp_conn_wq_max = 65536 tcp_crlf_ping = yes tcp_delayed_ack = yes tcp_fd_cache = yes tcp_keepalive = yes tcp_keepcnt = 3 tcp_keepidle = 30 tcp_keepintvl = 10 tcp_linger2 = 30 tcp_rd_buf_size = 80000 tcp_send_timeout = 10 tcp_wq_blk_size = 2100 tcp_wq_max = 10485760 ####### UDP Parameters ######### udp4_raw = 0 #udp4_raw_mtu = 800 # # pmtu_discovery = no #udp_mtu = 800 # #udp_mtu_try_proto = TCP ####### DNS Parameters ######### dns = no rev_dns = no dns_try_ipv6 = no use_dns_cache = on dns_cache_del_nonexp = yes dns_cache_flags = 1 dns_cache_gc_interval = 120 dns_cache_init = 0 dns_cache_mem = 1000 dns_cache_negative_ttl = 60 dns_try_naptr = no use_dns_failover = off dns_srv_lb = off ####### SCTP Parameters ######### disable_sctp = yes ######## 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 ipops module ######## loadmodule "ipops.so" ######## Kamailio control connector module ######## loadmodule "ctl.so" modparam("ctl", "binrpc_buffer_size", 4096) loadmodule "cfg_rpc.so" loadmodule "cfgutils.so" 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", "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", 1) modparam("rr", "enable_double_rr", 1) ######## Max-Forward processor module ######## loadmodule "maxfwd.so" modparam("maxfwd", "max_limit", 50) ######## SIP utilities [requires sl] ######## loadmodule "siputils.so" ######## SIP message formatting sanity checks [requires sl] ######## loadmodule "sanity.so" modparam("sanity", "default_checks", 1511) modparam("sanity", "uri_checks", 7) modparam("sanity", "autodrop", 0) ######## Text operations module ######## loadmodule "textops.so" loadmodule "textopsx.so" ######## Generic Hash Table container in shared memory ######## loadmodule "htable.so" modparam("htable", "htable", "associations=>size=16;autoexpire=7200") modparam("htable", "htable", "redirects=>size=16;autoexpire=5") ######## Pseudo-Variables module ######## loadmodule "pv.so" ######## 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") ####### DATABASE module ########## loadmodule "db_KAMAILIO_DBMS.so" ####### Kazoo Integration module ########## loadmodule "kazoo.so" modparam("kazoo", "pua_mode", MY_AMQP_PUA_MODE) modparam("kazoo", "amqp_primary_zone", "MY_AMQP_ZONE") modparam("kazoo", "amqp_query_timeout_avp", "$avp(kz_timeout)") modparam("kazoo", "node_hostname", "MY_HOSTNAME") modparam("kazoo", "amqp_heartbeats", MY_AMQP_HEARTBEATS) modparam("kazoo", "amqp_max_channels", MY_AMQP_MAX_CHANNELS) modparam("kazoo", "amqp_consumer_processes", MY_AMQP_CONSUMER_PROCESSES) modparam("kazoo", "amqp_consumer_workers", MY_AMQP_CONSUMER_WORKERS) ## amqp connections modparam("kazoo", "amqp_connection", "MY_AMQP_URL") #!ifdef MY_AMQP_SECONDARY_URL modparam("kazoo", "amqp_connection", "MY_AMQP_SECONDARY_URL") #!endif #!ifdef MY_AMQP_TERTIARY_URL modparam("kazoo", "amqp_connection", "MY_AMQP_TERTIARY_URL") #!endif #!ifdef MY_AMQP_QUATERNARY_URL modparam("kazoo", "amqp_connection", "MY_AMQP_QUATERNARY_URL") #!endif #!ifdef MY_AMQP_QUINARY_URL modparam("kazoo", "amqp_connection", "MY_AMQP_QUINARY_URL") #!endif #!ifdef MY_AMQP_SENARY_URL modparam("kazoo", "amqp_connection", "MY_AMQP_SENARY_URL") #!endif #!ifdef MY_AMQP_SEPTENARY_URL modparam("kazoo", "amqp_connection", "MY_AMQP_SEPTENARY_URL") #!endif #!ifdef MY_AMQP_OCTONARY_URL modparam("kazoo", "amqp_connection", "MY_AMQP_OCTONARY_URL") #!endif #!ifdef MY_AMQP_NONARY_URL modparam("kazoo", "amqp_connection", "MY_AMQP_NONARY_URL") #!endif #!ifdef MY_AMQP_DENARY_URL modparam("kazoo", "amqp_connection", "MY_AMQP_DENARY_URL") #!endif ###### kazoo bindings ###### include_file "kazoo-bindings.cfg" ####### Role Configurations ########## #!ifdef DISPATCHER_ROLE include_file "dispatcher-role.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 ####### Permissions module ########## loadmodule "permissions.so" modparam("permissions", "db_url", "KAZOO_DB_URL") modparam("permissions", "db_mode", 1) ####### DEBUG ###### loadmodule "debugger.so" modparam("debugger", "mod_hash_size", 5) modparam("debugger", "mod_level_mode", 1) ####### Routing Logic ######## route { route(SANITY_CHECK); route(CHECK_RETRANS); # log the basic info regarding this call xlog("L_INFO", "$ci|start|received $pr request $rm $ou\n"); xlog("L_INFO", "$ci|log|source $si:$sp -> $Ri:$Rp\n"); xlog("L_INFO", "$ci|log|from $fu\n"); xlog("L_INFO", "$ci|log|to $tu\n"); route(CLASSIFY_SOURCE); #!ifdef ANTIFLOOD_ROLE route(ANTIFLOOD_RATE_LIMIT); route(ANITFLOOD_AUTH_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 #!ifdef WEBSOCKETS_ROLE route(HANDLE_WEBSOCKETS); #!endif route(HANDLE_OPTIONS); route(HANDLE_NOTIFY); #!ifdef AUTHORIZATION_ROLE route(AUTHORIZATION_CHECK); #!endif route(HANDLE_MESSAGE); #!ifdef PRESENCE_ROLE route(HANDLE_SUBSCRIBE); route(HANDLE_PUBLISH); #!endif #!ifdef REGISTRAR_ROLE route(HANDLE_REGISTER); #!endif route(HANDLE_IN_DIALOG_REQUESTS); route(PREPARE_INITIAL_REQUESTS); #!ifdef PUSHER_ROLE route(PUSHER_ROUTE); #!endif #!ifdef RESPONDER_ROLE if (isflagset(FLAG_INTERNALLY_SOURCED)) { route(HANDLE_RESPOND); } #!endif #!ifdef DISPATCHER_ROLE if (!isflagset(FLAG_INTERNALLY_SOURCED)) { route(DISPATCHER_FIND_ROUTES); } #!endif route(RELAY); } route[CHECK_RETRANS] { # handle retransmissions if (!is_method("ACK")) { if(t_precheck_trans()) { t_check_trans(); exit; } t_check_trans(); } } route[SANITY_CHECK] { ## CVE-2018-14767 if($(hdr(To)[1]) != $null) { xlog("second To header not null - dropping message"); drop; } if (!sanity_check()) { xlog("L_WARN", "$ci|end|message from $si:$sp is insane\n"); exit; } if (!mf_process_maxfwd_header("10")) { xlog("L_WARN", "$ci|end|too much hops, not enough barley from $si:$sp\n"); send_reply("483", "Too Many Hops"); exit; } if ($ua == "friendly-scanner" || $ua == "sundayddr" || $ua == "pplsip" || $ua =~ "NiceGuy" || $ua =~ "PortSIP" || $ua =~ "sipcli" ) { xlog("L_WARN", "$ci|end|dropping message with user-agent $ua from $si:$sp\n"); exit; } } route[CLASSIFY_SOURCE] { #!ifdef DISPATCHER_ROLE route(DISPATCHER_CLASSIFY_SOURCE); #!endif if (isflagset(FLAG_INTERNALLY_SOURCED) || allow_source_address(TRUSTED_ADR_GROUP) || is_myself($si)) { xlog("L_INFO", "$ci|log|request from trusted IP\n"); setflag(FLAG_TRUSTED_SOURCE); } } route[HANDLE_OPTIONS] { if (is_method("OPTIONS")) { 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 #!ifdef NAT_TRAVERSAL_ROLE route(NAT_TEST_AND_CORRECT); #!endif sl_send_reply("200", "Rawr!!"); } exit; } } route[HANDLE_NOTIFY] { if (has_totag()) return; if (is_method("NOTIFY")) { 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 route(INTERNAL_TO_EXTERNAL_RELAY); } else { #!ifdef TRAFFIC_FILTER_ROLE if (!isflagset(FLAG_TRUSTED_SOURCE)) { route(FILTER_REQUEST_DOMAIN); } #!endif #!ifdef WEBSOCKETS_ROLE route(NAT_WEBSOCKETS_CORRECT); #!endif #!ifdef NAT_TRAVERSAL_ROLE route(NAT_TEST_AND_CORRECT); #!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_MESSAGE] { #!ifdef MESSAGE_ROLE if (is_method("MESSAGE")) { xlog("L_INFO", "$ci|MESSAGE from $fu to $tu\n"); if (isflagset(FLAG_INTERNALLY_SOURCED) || src_ip == myself) { xlog("L_INFO", "$ci| routing MESSAGE to external from $fu to $tu\n"); if (registered("location")) { lookup("location"); xlog("L_INFO", "$ci|log|routing to $ruid\n"); } #!ifdef TRAFFIC_FILTER_ROLE } else if (!isflagset(FLAG_TRUSTED_SOURCE) && $rd =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}") { xlog("L_WARN", "$ci|end|dropping MESSAGE request with IP domain\n"); exit(); #!endif } else { xlog("L_WARN", "$ci|end|MESSAGE $(hdr(Content-Type))\n"); if( $hdr(Content-Type) == "application/im-iscomposing+xml" ) { xlog("L_WARN", "$ci|end|dropping MESSAGE application/im-iscomposing+xml\n"); sl_send_reply("200", "OK"); } else if( $hdr(Content-Type) == "message/imdn+xml" ) { xlog("L_WARN", "$ci|end|dropping MESSAGE message/imdn+xml\n"); sl_send_reply("202", "Accepted"); } else { route(DISPATCHER_FIND_ROUTES); } } route(RELAY); } #!else if (is_method("MESSAGE")) { if (!isflagset(FLAG_INTERNALLY_SOURCED)) { sl_send_reply("202", "delivered to /dev/null"); exit(); } route(RELAY); } #!endif } route[HANDLE_IN_DIALOG_REQUESTS] { if (has_totag()) { if (is_method("INVITE")) { setflag(FLAG_SESSION_PROGRESS); record_route(); } if (loose_route()) { #!ifdef ACCOUNTING_ROLE if (is_method("BYE")) { setflag(FLAG_ACC); setflag(FLAG_ACCFAILED); } #!endif #!ifdef NAT_TRAVERSAL_ROLE if(!isdsturiset()) { handle_ruri_alias(); } #!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 ( 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"); 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; } if (loose_route()) { #!ifdef REGISTRAR_ROLE $xavp(regcfg=>match_received) = $su; if(registered("location", "$rz:$Au", 2) == 1) { xlog("L_INFO", "$ci|log|allowing initial route-set for $Au\n"); } else { #!endif xlog("L_WARN", "$ci|end|dropping initial request with route-set\n"); sl_send_reply("403", "No pre-loaded routes"); exit(); #!ifdef REGISTRAR_ROLE } #!endif } record_route(); } route[RELAY] { #!ifdef SIP_TRACE_ROLE route(SEND_SIP_TRACE); #!endif if (isflagset(FLAG_INTERNALLY_SOURCED)) { route(INTERNAL_TO_EXTERNAL_RELAY); #!ifdef MESSAGE_ROLE } else if (is_method("MESSAGE") && src_ip == myself) { route(INTERNAL_TO_EXTERNAL_RELAY); #!endif } else { 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 #!ifdef REGISTRAR_ROLE if ($hdr(X-KAZOO-AOR) != $null) { 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"); } else { xlog("L_INFO", "$ci|end|lookup for AOR $hdr(X-KAZOO-AOR) failed\n"); sl_send_reply("410", "Not registered"); exit; } } else if (reg_fetch_contacts("location", "$hdr(X-KAZOO-AOR)", "callee")) { $du = $(ulc(callee=>received)); $fs = $(ulc(callee=>socket)); xlog("L_INFO", "$ci|log|routing $hdr(X-KAZOO-AOR) to $du via $fs\n"); } else { xlog("L_INFO", "$ci|end|user is not registered\n"); sl_send_reply("410", "Not registered"); exit; } } #!endif remove_hf_re("^X-.*"); t_on_reply("EXTERNAL_REPLY"); t_set_fr(0, 10000); 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 #!ifdef NAT_TRAVERSAL_ROLE if (!isflagset(FLAG_INTERNALLY_SOURCED)) { route(NAT_TEST_AND_CORRECT); } #!endif remove_hf_re("^X-.*"); append_hf("X-AUTH-IP: $si\r\n"); append_hf("X-AUTH-PORT: $sp\r\n"); #!ifdef REGISTRAR_ROLE route(ADD_AUTHORIZATION_HEADERS); #!endif t_on_reply("INTERNAL_REPLY"); t_on_failure("INTERNAL_FAULT"); t_set_fr(0, 1000); t_relay(); } onreply_route[EXTERNAL_REPLY] { xlog("L_INFO", "$ci|log|external reply $T_reply_code\n"); #!ifdef WEBSOCKETS_ROLE route(NAT_WEBSOCKETS_CORRECT); #!endif #!ifdef NAT_TRAVERSAL_ROLE route(NAT_TEST_AND_CORRECT); #!endif #!ifdef ACL_ROLE setflag(FLAG_IS_REPLY); route(ACL_CHECK); #!endif #!ifdef RATE_LIMITER_ROLE setflag(FLAG_IS_REPLY); route(DOS_PREVENTION); #!endif #!ifdef MESSAGE_ROLE if (is_method("MESSAGE")) { route(MESSAGE_REPLY); } #!endif } onreply_route[INTERNAL_REPLY] { # this route handles replies that are comming from our media server xlog("L_INFO", "$ci|start|received internal reply $T_reply_code $rr\n"); xlog("L_INFO", "$ci|log|source $si:$sp\n"); #!ifdef WEBSOCKETS_ROLE route(NAT_WEBSOCKETS_CORRECT); #!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") && !isflagset(FLAG_SESSION_PROGRESS) && t_check_status("(180)|(183)|(200)") ) { if ($avp(AVP_REDIRECT_KEY) != $null && $sht(redirects=>$avp(AVP_REDIRECT_KEY)) != $null ) { xlog("L_INFO", "$ci|log|removing redirect mapping $avp(AVP_REDIRECT_KEY)\n"); $sht(redirects=>$avp(AVP_REDIRECT_KEY)) = $null; } xlog("L_INFO", "$ci|log|call setup, now ignoring abnormal termination\n"); setflag(FLAG_SESSION_PROGRESS); } if ($rs < 300) { xlog("L_INFO", "$ci|pass|$T_req($si):$T_req($sp)\n"); } $var(reply_reason) = $rr; } 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; } # Handle redirects if (t_check_status("302")) { $var(redirect) = @from.uri.user + "@" + @from.uri.host + "->" + $T_rpl($(ct{tobody.user})) + "@" + $T_rpl($(ct{tobody.host})); if($T_rpl($hdr(X-Redirect-Server)) != $null) { $sht(redirects=>$var(redirect)) = $T_rpl($hdr(X-Redirect-Server)); xlog("L_INFO", "$ci|log|stored redirect mapping $var(redirect) to $T_rpl($hdr(X-Redirect-Server))\n"); } route(INTERNAL_REDIRECT); } else if (!t_check_status("407") && $avp(AVP_REDIRECT_KEY) != $null && $sht(redirects=>$avp(AVP_REDIRECT_KEY)) != $null ) { xlog("L_INFO", "$ci|log|removing redirect mapping $avp(AVP_REDIRECT_KEY)\n"); $sht(redirects=>$avp(AVP_REDIRECT_KEY)) = $null; } 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|log|sending 6XX reply as $var(new_code) $var(reply_reason)\n"); t_reply("$(var(new_code){s.int})", "$var(reply_reason)"); # if the failure case was something that we should recover # from then try to find a new media server } else if ($var(reply_reason) =~ "call barred") { xlog("L_INFO", "$ci|log|failure route ignoring call barred\n"); } else if (isflagset(FLAG_SESSION_PROGRESS)) { xlog("L_INFO", "$ci|log|failure route ignoring failure after session progress\n"); } else if (t_check_status("403") && $var(reply_reason)=="Forbidden") { xlog("L_WARNING", "$ci|log|failure route ignoring. Failed auth from IP $si\n"); } else if (t_check_status("(401)|(407)|(486)|(403)")) { xlog("L_INFO", "$ci|log|failure route ignoring auth reply $T_reply_code $var(reply_reason)\n"); } else if (t_check_status("402")) { xlog("L_INFO", "$ci|log|failure route 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|start|received failure reply $T_reply_code $rr\n"); #!ifdef DISPATCHER_ROLE route(DISPATCHER_NEXT_ROUTE); #!endif send_reply("486", "Unable to Comply"); } else { xlog("L_INFO", "$ci|log|failure route ignoring reply $T_reply_code $rr\n"); } xlog("L_INFO", "$ci|pass|$si:$sp\n"); } route[INTERNAL_REDIRECT] { $var(ds_group) = 1; $var(contact_uri) = $(ct{tobody.user}) + "@" + $(ct{tobody.host}); $var(redirect) = @from.uri.user + "@" + @from.uri.host + "->" + @ruri.user + "@" + @ruri.host; if ($sht(redirects=>$var(redirect)) != $null) { $var(prefered_route) = $sht(redirects=>$var(redirect)); xlog("L_INFO", "$ci|log|found redirect for $var(redirect) : $var(prefered_route)\n"); $du = $var(prefered_route); $avp(AVP_REDIRECT_KEY) = $var(redirect); 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)) { $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); } xlog("L_INFO", "$ci|pass|$sndfrom(ip):$sndfrom(port) -> $sndto(ip):$sndto(port)\n"); } #!ifdef REGISTRAR_ROLE route[ADD_AUTHORIZATION_HEADERS] { if (!is_method("INVITE|MESSAGE|REFER")) { return; } $xavp(regcfg=>match_received) = $su; if (registered("location","$fu", 2, 1) == 1) { if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}{s.len}) > 0) append_hf("X-ecallmgr_Account-ID: $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID})\r\n"); if($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type}{s.len}) > 0) append_hf("X-ecallmgr_Authorizing-Type: $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type})\r\n"); if($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID}{s.len}) > 0) append_hf("X-ecallmgr_Authorizing-ID: $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID})\r\n"); if($(xavp(ulattrs=>custom_channel_vars){kz.json,Username}{s.len}) > 0) append_hf("X-ecallmgr_Username: $(xavp(ulattrs=>custom_channel_vars){kz.json,Username})\r\n"); if($(xavp(ulattrs=>custom_channel_vars){kz.json,Realm}{s.len}) > 0) append_hf("X-ecallmgr_Realm: $(xavp(ulattrs=>custom_channel_vars){kz.json,Realm})\r\n"); if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Realm}{s.len}) > 0) append_hf("X-ecallmgr_Account-Realm: $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Realm})\r\n"); if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Name}{s.len}) > 0) append_hf("X-ecallmgr_Account-Name: $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Name})\r\n"); if($(xavp(ulattrs=>custom_channel_vars){kz.json,Presence-ID}{s.len}) > 0) append_hf("X-ecallmgr_Presence-ID: $(xavp(ulattrs=>custom_channel_vars){kz.json,Presence-ID})\r\n"); if($(xavp(ulattrs=>custom_channel_vars){kz.json,Owner-ID}{s.len}) > 0) append_hf("X-ecallmgr_Owner-ID: $(xavp(ulattrs=>custom_channel_vars){kz.json,Owner-ID})\r\n"); } } #!endif #!ifdef PRESENCE_NOTIFY_INIT event_route[tm:local-request] { route(PRESENCE_LOCAL_NOTIFY); } #!endif # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab