diff --git a/kamailio/default.cfg b/kamailio/default.cfg new file mode 100644 index 0000000..87136b5 --- /dev/null +++ b/kamailio/default.cfg @@ -0,0 +1,469 @@ +## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ## + +#### Preprocessor Directives ######### +#!define L_ALERT -5 +#!define L_BUG -4 +#!define L_CRIT2 -3 +#!define L_CRIT -2 +#!define L_ERR -1 +#!define L_WARN 0 +#!define L_NOTICE 1 +#!define L_INFO 2 +#!define L_DBG 3 + +#!define AVP_RECV_PARAM "recv_param" +#!define AVP_LOG_LEVEL "log_level" +#!define AVP_ROUTE_CNT "route_cnt" +#!define AVP_ASSOCIATED_SERVER "associated_server" +#!define AVP_ASSOCIATE_CONTACT "associate_contact" + +####### Flags ####### +flags + FLAG_INTERNALLY_SOURCED: 1, + FLAG_ASSOCIATE_SERVER: 2, + FLAG_SKIP_NAT_CORRECTION: 3, + FLAG_ASSOCIATE_USER: 4; + +#!define FLB_NATB 1 +#!define FLB_NATSIPPING 2 +#!define FLB_UAC_REDIRECT 3 + +####### Global Parameters ######### +fork = yes +children = 25 +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 = 500 + +####### Logging Parameters ######### +debug = L_INFO +memdbg = 10 +memlog = 10 +corelog = L_ERR +log_stderror = no +log_facility = LOG_LOCAL0 +log_name="kamailio" + +####### Alias Parameters ######### +auto_aliases = yes + +####### Binding Parameters ######### +tos = IPTOS_LOWDELAY + +####### TCP Parameters ######### +tcp_children = 25 +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 = 4096 +tcp_send_timeout = 10 +tcp_wq_blk_size = 2100 +tcp_wq_max = 10485760 + +####### UDP Parameters ######### +udp4_raw = -1 + +####### DNS Parameters ######### +dns = no +rev_dns = no +dns_try_ipv6 = no +use_dns_cache = on +dns_cache_del_nonexp = no +dns_cache_flags = 1 +dns_cache_gc_interval = 120 +dns_cache_init = 1 +dns_cache_mem = 1000 +dns_cache_negative_ttl = 60 +dns_try_naptr = no +use_dns_failover = off +dns_srv_lb = off + +####### TLS Parameters ######### +enable_tls = yes + +####### SCTP Parameters ######### +disable_sctp = yes + +####### Custom Parameters ######### + + +####### Modules Section ######## +mpath="/usr/lib64/kamailio/modules/" + +######## 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", 0) + +######## Max-Forward processor module ######## +loadmodule "maxfwd.so" + +######## SIP utilities [requires sl] ######## +loadmodule "siputils.so" + +######## SIP message formatting sanity checks [requires sl] ######## +loadmodule "sanity.so" +# sip_version, scheme, req_headers, cseq_method/value +# content_length, parse_uri, digest +modparam("sanity", "default_checks", 3303) +modparam("sanity", "uri_checks", 3) +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") + +######## Pseudo-Variables module ######## +loadmodule "pv.so" + +######## Advanced logger module ######## +loadmodule "xlog.so" + +####### FIFO support for Management Interface ######## +loadmodule "mi_fifo.so" +modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo") + +######## UAC Redirection module ######## +loadmodule "uac_redirect.so" + +####### 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 NAT-TRAVERSAL-ROLE +include_file "nat-traversal-role.cfg" +#!endif + +####### Kazoo Integration module ########## +#!ifdef INCLUDE-DB-KAZOO +loadmodule "db_kazoo.so" +#!endif + +####### Routing Logic ######## +route +{ + # log the basic info regarding this call + xlog("L_INFO", "$ci|start|recieved $oP request $rm $ou"); + xlog("L_INFO", "$ci|log|source $si:$sp"); + xlog("L_INFO", "$ci|log|from $fu"); + xlog("L_INFO", "$ci|log|to $tu"); + + route(SANITY_CHECK); + + #!ifdef DISPATCHER-ROLE + route(DISPATCHER_CLASSIFY_SOURCE); + #!endif + + route(HANDLE_OPTIONS); + + route(HANDLE_MOVE_REQUEST); + + #!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); + + if (isflagset(FLAG_INTERNALLY_SOURCED)) { + route(INTERNAL_TO_EXTERNAL_RELAY); + exit(); + } + + #!ifdef DISPATCHER-ROLE + route(DISPATCHER_FIND_ROUTES); + #!endif + + route(EXTERNAL_TO_INTERNAL_RELAY); +} + +route[SANITY_CHECK] +{ + if (!mf_process_maxfwd_header("10")) { + xlog("L_WARN", "$ci|end|Too much hops, not enough barley"); + sl_send_reply("483", "Too Many Hops"); + exit; + } + + if (!sanity_check()) { + xlog("L_WARN", "$ci|end|message is insane"); + exit; + } +} + +route[HANDLE_OPTIONS] +{ + if (is_method("OPTIONS")) { + if (isflagset(FLAG_INTERNALLY_SOURCED)) { + route(INTERNAL_TO_EXTERNAL_RELAY); + } else { + sl_send_reply("200", "Rawr!!"); + } + exit; + } +} + +route[HANDLE_MOVE_REQUEST] +{ + if (is_method("INVITE") && $rU == "*6683*") { + $var(contact_uri) = $(ct{tobody.user}) + "@" + $(ct{tobody.host}); + $var(from_uri) = @from.uri.user + "@" + @from.uri.host; + + if ($sht(associations=>$var(contact_uri)) != $null) { + $sht(associations=>$var(contact_uri)) = $null; + xlog("L_INFO", "$ci|log|removed contact association for $var(contact_uri) + with media server $sht(associations=>$var(contact_uri))\n"); + } + + if ($sht(associations=>$var(from_uri)) != $null) { + $sht(associations=>$var(from_uri)) = $null; + xlog("L_INFO", "$ci|log|removed from association for $var(from_uri) + with media server $sht(associations=>$var(from_uri))\n"); + } + + send_reply("503", "Removed association"); + + exit; + } +} + +route[HANDLE_IN_DIALOG_REQUESTS] +{ + if (has_totag()) { + if (loose_route()) { + xlog("L_INFO", "$ci|log|loose_route in-dialog message"); + # 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); + } + route(RELAY); + } else if (isflagset(FLAG_INTERNALLY_SOURCED)) { + xlog("L_INFO", "$ci|log|relay internally sourced in-dialog message without loose_route"); + route(RELAY); + } else if (t_check_trans()) { + xlog("L_INFO", "$ci|log|allow message for a known transaction"); + route(RELAY); + } else { + xlog("L_INFO", "$ci|log|message had a to-tag but can't be loose routed"); + 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(); + } + + t_check_trans(); + + if (loose_route()) { + sl_send_reply("403", "No pre-loaded routes"); + exit(); + } + + if (!is_method("MESSAGE")) { + record_route(); + } +} + +route[RELAY] +{ + if (isflagset(FLAG_INTERNALLY_SOURCED)) { + route(INTERNAL_TO_EXTERNAL_RELAY); + } else { + route(EXTERNAL_TO_INTERNAL_RELAY); + } + + exit(); +} + +route[INTERNAL_TO_EXTERNAL_RELAY] +{ + remove_hf("X-AUTH-IP"); + + t_on_reply("EXTERNAL_REPLY"); + + t_set_fr(0, 10000); + + t_relay(); +} + +route[EXTERNAL_TO_INTERNAL_RELAY] +{ + #!ifdef NAT-TRAVERSAL-ROLE + if (!isflagset(FLAG_INTERNALLY_SOURCED)) { + route(NAT_TEST_AND_CORRECT); + } + #!endif + + remove_hf("X-AUTH-IP"); + append_hf("X-AUTH-IP: $si\r\n"); + + 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"); + + #!ifdef NAT-TRAVERSAL-ROLE + route(NAT_TEST_AND_CORRECT); + #!endif +} + +onreply_route[INTERNAL_REPLY] +{ + # this route handles replies that are comming from our media server + xlog("L_INFO", "$ci|start|recieved internal reply $T_reply_code $rr"); + xlog("L_INFO", "$ci|log|source $si:$sp"); + + if ($rs < 300) { + xlog("L_INFO", "$ci|pass|$T_req($si):$T_req($sp)"); + } + + # change 6xx to 4xx + if (t_check_status("6[0-9][0-9]")) { + $var(new_code) = "4" + $(T_reply_code{s.substr,1,0}); + change_reply_status("$var(new_code)", "$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"); + + exit; + } + + # if the failure case was something that we should recover + # from then try to find a new media server + if (t_check_status("302")) { + ## TODO - test this + ## get_redirects("*"); + + if($T_rpl($hdr(X-Redirect-Server)) != $null) { + $var(contact_uri) = @from.uri.user + "@" + @from.uri.host; + + $sht(associations=>$var(contact_uri)) = $T_rpl($hdr(X-Redirect-Server)); + + xlog("L_INFO", "$ci|log|stored redirect mapping for $var(contact_uri) to $T_rpl($hdr(X-Redirect-Server))"); + + remove_hf("X-Redirect-Server"); + } + } else if (t_check_status("(401)|(407)")) { + xlog("L_INFO", "$ci|log|failure route ignoring auth reply $T_reply_code $rr"); + + exit; + } else if (t_check_status("402")) { + xlog("L_INFO", "$ci|log|failure route overriding reply code 402 with 486"); + + xlog("L_INFO", "$ci|pass|$si:$sp"); + + send_reply("486", "Insufficient Funds"); + + exit; + } 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"); + + #!ifdef DISPATCHER-ROLE + route(DISPATCHER_NEXT_ROUTE); + #!endif + + send_reply("486", "Unable to Comply"); + + exit; + } else { + xlog("L_INFO", "$ci|log|failure route ignoring reply $T_reply_code $rr"); + + exit; + } +} + +onsend_route { + if (isflagset(FLAG_ASSOCIATE_USER)) { + $var(contact_uri) = $(ct{tobody.user}) + "@" + $(ct{tobody.host}); + xlog("L_INFO", "$ci|log|associate user $var(contact_uri) with media server sip:$sndto(ip):$sndto(port)\n"); + $sht(associations=>$var(contact_uri))= "sip:" + $sndto(ip) + ":" + $sndto(port); + } + + xlog("L_INFO", "$ci|pass|$sndfrom(ip):$sndfrom(port) -> $sndto(ip):$sndto(port)"); +} + +## vim:set tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/dispatcher-role.cfg b/kamailio/dispatcher-role.cfg new file mode 100644 index 0000000..8a5ed0f --- /dev/null +++ b/kamailio/dispatcher-role.cfg @@ -0,0 +1,142 @@ +######## Generic Hash Table container in shared memory ######## +modparam("htable", "htable", "failover=>size=16;autoexpire=120") + +####### Dispatcher module ######## +loadmodule "dispatcher.so" +modparam("dispatcher", "list_file", "/etc/kazoo/kamailio/dispatcher.list") +modparam("dispatcher", "flags", 2) +modparam("dispatcher", "use_default", 0) +modparam("dispatcher", "force_dst", 1) +modparam("dispatcher", "dst_avp", "$avp(ds_dst)") +modparam("dispatcher", "attrs_avp", "$avp(ds_attrs)") +modparam("dispatcher", "grp_avp", "$avp(ds_grp)") +modparam("dispatcher", "cnt_avp", "$avp(ds_cnt)") +modparam("dispatcher", "hash_pvar", "$avp(ds_grp)") +# modparam("dispatcher", "setid_pvar", "$var(setid)") +modparam("dispatcher", "ds_ping_method", "OPTIONS") +modparam("dispatcher", "ds_ping_interval", 10) +modparam("dispatcher", "ds_probing_threshhold", 3) +modparam("dispatcher", "ds_probing_mode", 1) +modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200") + +####### Dispatcher Logic ######## +route[DISPATCHER_CLASSIFY_SOURCE] +{ + if (ds_is_from_list("1", "1") || ds_is_from_list("3", "1")) { + xlog("L_INFO", "$ci|log|originated from internal sources"); + + setflag(FLAG_INTERNALLY_SOURCED); + } else { + xlog("L_INFO", "$ci|log|originated from external sources"); + } +} + +# Take the routes from dispatcher - hash over callid +# If prefered route defined, reorder the destionations +route[DISPATCHER_FIND_ROUTES] +{ + if ($sht(failover=>$ci::current) != $null) { + $du = $sht(failover=>$ci::current); + return; + } + + if (!ds_select_dst("1", "0")) { + xlog("L_ERR", "$ci|end|no servers avaliable"); + + sl_send_reply("480", "All servers busy"); + + exit; + } + + $var(contact_uri) = $(ct{tobody.user}) + "@" + $(ct{tobody.host}); + $var(from_uri) = @from.uri.user + "@" + @from.uri.host; + if ($sht(associations=>$var(from_uri)) != $null) { + $var(association) = $var(from_uri); + route(DISPATCHER_REORDER_ROUTES); + } else if ($sht(associations=>$var(contact_uri)) != $null) { + $var(association) = $var(contact_uri); + route(DISPATCHER_REORDER_ROUTES); + } +} + +route[DISPATCHER_REORDER_ROUTES] +{ + $var(i) = 0; + $var(found) = 0; + while($(avp(ds_dst)[$var(i)]) != $null) { + if($(avp(ds_dst)[$var(i)]) != $var(prefered_route)) { + $avp(tmp_ds_dst) = $(avp(ds_dst)[$var(i)]); + } else { + $var(found) = 1; + } + + $var(i) = $var(i) + 1; + } + + if ($var(found)) { + xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to keep associated server first"); + + $(avp(ds_dst)[*]) = $null; + + $var(i) = 0; + while($(avp(tmp_ds_dst)[$var(i)]) != $null) { + $avp(ds_dst) = $(avp(tmp_ds_dst)[$var(i)]); + + $var(i) = $var(i) + 1; + } + $avp(ds_dst) = $var(prefered_route); + $du = $var(prefered_route); + + $(avp(tmp_ds_dst)[*]) = $null; + } else { + xlog("L_INFO", "$ci|log|associated media server is inactive, moving to $rd"); + + $sht(associations=>$var(contact_uri)) = $null; + } +} + +route[DISPATCHER_NEXT_ROUTE] +{ + $var(failover_count) = $sht(failover=>$ci::counts); + + if ($sht(failover=>$ci::counts) == $null) { + $var(i) = 0; + while($(avp(ds_dst)[$var(i)]) != $null) { + $sht(failover=>$ci[$var(i)]) = $(avp(ds_dst)[$var(i)]); + $var(i) = $var(i) + 1; + if ($var(i) >= 3) { + break; + } + } + $sht(failover=>$ci::counts) = $var(i); + $var(failover_count) = $var(i); + } + + # try to find a new media server to send the call to + if ($var(failover_count) > 1) { + $var(failover_count) = $var(failover_count) - 1; + + $du = $sht(failover=>$ci[$var(failover_count)]); + $sht(failover=>$ci::counts) = $var(failover_count); + $sht(failover=>$ci::current) = $du; + + xlog("L_INFO", "$ci|log|remaining failed retry attempts: $var(failover_count)"); + xlog("L_INFO", "$ci|log|routing call to next media server $du"); + + setflag(FLAG_SKIP_NAT_CORRECTION); + + # reset the final reply timer + $avp(final_reply_timer) = 3; + + t_on_reply("INTERNAL_REPLY"); + + t_on_failure("INTERNAL_FAULT"); + + # relay the request to the new media server + route(EXTERNAL_TO_INTERNAL_RELAY); + + exit(); + } +} + +## vim:set tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/kamailio.cfg b/kamailio/kamailio.cfg index 1d99c91..7dffb54 100644 --- a/kamailio/kamailio.cfg +++ b/kamailio/kamailio.cfg @@ -1,723 +1,12 @@ -#### Preprocessor Directives ######### -#!define L_ALERT -5 -#!define L_BUG -4 -#!define L_CRIT2 -3 -#!define L_CRIT -2 -#!define L_ERR -1 -#!define L_WARN 0 -#!define L_NOTICE 1 -#!define L_INFO 2 -#!define L_DBG 3 +## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ## -#!define AVP_RECV_PARAM "recv_param" -#!define AVP_LOG_LEVEL "log_level" -#!define AVP_ROUTE_CNT "route_cnt" -#!define AVP_ASSOCIATED_SERVER "associated_server" -#!define AVP_ASSOCIATE_CONTACT "associate_contact" +####### Roles Configuration ###### +include_file "roles.cfg" -####### Global Parameters ######### -fork = yes -children = 25 -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 = 500 +####### Default Configuration ###### +include_file "default.cfg" -####### Logging Parameters ######### -debug = L_INFO -memdbg = 10 -memlog = 10 -corelog = L_ERR -log_stderror = no -log_facility = LOG_LOCAL0 -log_name="kamailio" - -####### Alias Parameters ######### -auto_aliases = yes -# alias = "mydomain.net" - -####### Binding Parameters ######### -listen = tcp:127.0.0.1:5060 -listen = udp:127.0.0.1:5060 -listen = tcp:127.0.0.1:5080 -listen = udp:127.0.0.1:5080 -listen = tcp:127.0.0.1:7000 -listen = udp:127.0.0.1:7000 -tos = IPTOS_LOWDELAY -## NOTE: Uncomment on a multihomed host -# mhomed = 1 - -####### TCP Parameters ######### -tcp_children = 25 -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 = 4096 -tcp_send_timeout = 10 -tcp_wq_blk_size = 2100 -tcp_wq_max = 10485760 - -####### UDP Parameters ######### -udp4_raw = -1 -## NOTE: You must MATCH this to your network adapter!! -## If they do not match, all UDP packets over -## this limit WILL FAIL! -## E.g.: Add MTU=1472 to the /etc/sysconfig/network-scripts/XXX -# udp4_raw_mtu = 1472 - -####### DNS Parameters ######### -dns = no -rev_dns = no -dns_try_ipv6 = no -use_dns_cache = on -dns_cache_del_nonexp = no -dns_cache_flags = 1 -dns_cache_gc_interval = 120 -dns_cache_init = 1 -dns_cache_mem = 1000 -dns_cache_negative_ttl = 60 -dns_try_naptr = no -use_dns_failover = off -dns_srv_lb = off - -####### TLS Parameters ######### -enable_tls = yes - -####### SCTP Parameters ######### -disable_sctp = yes - -####### Custom Parameters ######### - - -####### Modules Section ######## -mpath="/usr/lib64/kamailio/modules/" - -####### Flags ####### -flags - FLAG_INTERNALLY_SOURCED: 1, - FLAG_ASSOCIATE_SERVER: 2, - FLAG_SKIP_NAT_CORRECTION: 3, - FLAG_ASSOCIATE_USER: 4; - -#!define FLB_NATB 1 -#!define FLB_NATSIPPING 2 -#!define FLB_UAC_REDIRECT 3 - -######## 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) - -######## Max-Forward processor module ######## -loadmodule "maxfwd.so" - -######## SIP utilities [requires sl] ######## -loadmodule "siputils.so" - -######## SIP message formatting sanity checks [requires sl] ######## -loadmodule "sanity.so" -# sip_version, scheme, req_headers, cseq_method/value -# content_length, parse_uri, digest -modparam("sanity", "default_checks", 3303) -modparam("sanity", "uri_checks", 3) -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=10;") -modparam("htable", "htable", "auth_cache=>size=10;") -modparam("htable", "htable", "dbkp=>size=4;autoexpire=7200") - -######## Pseudo-Variables module ######## -loadmodule "pv.so" - -######## Advanced logger module ######## -loadmodule "xlog.so" - -####### FIFO support for Management Interface ######## -loadmodule "mi_fifo.so" -modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo") - -####### Dispatcher module ######## -loadmodule "dispatcher.so" -modparam("dispatcher", "list_file", "/etc/kazoo/kamailio/dispatcher.list") -modparam("dispatcher", "flags", 2) -modparam("dispatcher", "use_default", 0) -modparam("dispatcher", "force_dst", 1) -modparam("dispatcher", "dst_avp", "$avp(ds_dst)") -modparam("dispatcher", "attrs_avp", "$avp(ds_attrs)") -modparam("dispatcher", "grp_avp", "$avp(ds_grp)") -modparam("dispatcher", "cnt_avp", "$avp(ds_cnt)") -modparam("dispatcher", "hash_pvar", "$avp(ds_grp)") -# modparam("dispatcher", "setid_pvar", "$var(setid)") -modparam("dispatcher", "ds_ping_method", "OPTIONS") -modparam("dispatcher", "ds_ping_from", "sip:sipcheck@127.0.0.1") -modparam("dispatcher", "ds_ping_interval", 10) -# modparam("dispatcher", "ds_ping_sock", "udp:{{SIP_IP}}:{{SIP_PORT}}") -modparam("dispatcher", "ds_probing_threshhold", 3) -modparam("dispatcher", "ds_probing_mode", 1) -modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200") - -######## UAC Redirection module ######## -loadmodule "uac_redirect.so" - -####### Authentication Interface module ########## -loadmodule "auth.so" -loadmodule "auth_db.so" -modparam("auth_db", "use_domain", 1) -modparam("auth_db", "version_table", 0) -modparam("auth_db", "calculate_ha1", 1) -modparam("auth_db", "password_column", "password") -modparam("auth_db", "load_credentials", "$avp(password)=password") - -####### User Location Implementation module ########## -loadmodule "usrloc.so" -modparam("usrloc", "db_mode", 1) -modparam("usrloc", "db_update_as_insert", 1) -modparam("usrloc", "use_domain", 1) -modparam("usrloc", "nat_bflag", FLB_NATB) - -####### SIP Registrar implementation module ########## -loadmodule "registrar.so" - -######## NAT Traversal module - signaling functions ######## -loadmodule "nathelper.so" -modparam("nathelper|registrar", "received_avp", "$avp(AVP_RECV_PARAM)") -modparam("nathelper", "natping_interval", 30) -modparam("nathelper", "ping_nated_only", 1) -modparam("nathelper", "natping_processes", 5) -modparam("nathelper", "sipping_bflag", FLB_NATSIPPING) -modparam("nathelper", "sipping_from", "sip:sipcheck@127.0.0.1") -# modparam("nathelper", "natping_socket", "127.0.0.1:5060") - -######## Presence User Agent module ######## -loadmodule "pua_dialoginfo.so" -modparam("pua_dialoginfo", "library_mode", 1) - -######## Presence server module ######## -loadmodule "presence.so" -loadmodule "presence_dialoginfo.so" -modparam("presence", "subs_db_mode", 1) -modparam("presence", "expires_offset", 60) -modparam("presence", "publ_cache", 0) - -####### Kazoo Integration module ########## -loadmodule "db_kazoo.so" -# NOTE: The hostname that should be advertised to Kazoo -modparam("db_kazoo", "node_hostname", "kamailio.2600hz.com") -# If you want a certain fs_path to be sent Kazoo, uncomment the next line and set the right value -# modparam("db_kazoo", "register_fs_path", "127.0.0.1:5060") - -####### Common Module Parameters ########## -modparam("auth_db|usrloc", "db_url", "kazoo://guest:guest@127.0.0.1:5672/callmgr") -modparam("presence", "db_url", "kazoo://guest:guest@127.0.0.1:5672/dialoginfo") - -####### Routing Logic ######## -route -{ - # log the basic info regarding this call - xlog("L_INFO", "$ci|start|recieved $oP request $rm $ou"); - xlog("L_INFO", "$ci|log|source $si:$sp"); - xlog("L_INFO", "$ci|log|from $fu"); - xlog("L_INFO", "$ci|log|to $tu"); - - route(SANITY_CHECK); - - route(CLASSIFY_SOURCE); - - route(HANDLE_OPTIONS); - - route(HANDLE_PRESENCE); - - route(HANDLE_IN_DIALOG_REQUESTS); - - route(PREPARE_INITIAL_REQUESTS); - - if (isflagset(FLAG_INTERNALLY_SOURCED)) { - route(INTERNAL_TO_EXTERNAL_RELAY); - exit(); - } - - route(HANDLE_MOVE_REQUEST); - - route(FIND_ROUTES); - - $avp(route_attempts) = 1; - route(EXTERNAL_TO_INTERNAL_RELAY); -} - -route[SANITY_CHECK] -{ - if (!mf_process_maxfwd_header("10")) { - xlog("L_WARN", "$ci|end|max-forward limit reached"); - sl_send_reply("483", "Too Many Hops"); - exit; - } - - if (!sanity_check()) { - xlog("L_WARN", "$ci|end|message is insane"); - exit; - } -} - -route[CLASSIFY_SOURCE] -{ - if (ds_is_from_list("1", "1") || ds_is_from_list("3", "1")) { - xlog("L_INFO", "$ci|log|originated from internal sources"); - - setflag(FLAG_INTERNALLY_SOURCED); - } else { - xlog("L_INFO", "$ci|log|originated from external sources"); - } -} - -route[HANDLE_OPTIONS] -{ - if (is_method("OPTIONS")) { - if (isflagset(FLAG_INTERNALLY_SOURCED)) { - route(INTERNAL_TO_EXTERNAL_RELAY); - } else { - sl_send_reply("200", "Rawr!!"); - } - exit; - } -} - -route[HANDLE_PRESENCE] -{ - if (is_method("SUBSCRIBE")) { - if (!t_newtran()) { - sl_reply_error(); - exit; - } - handle_subscribe(); - t_release(); - exit; - } - - if (is_method("PUBLISH")) { - if (!t_newtran()) { - sl_reply_error(); - exit; - } - handle_publish(); - t_release(); - exit; - } -} - -route[HANDLE_IN_DIALOG_REQUESTS] -{ - if (has_totag()) { - if (loose_route()) { - xlog("L_INFO", "$ci|log|loose_route in-dialog message"); - # 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); - } - route(RELAY); - } else if (isflagset(FLAG_INTERNALLY_SOURCED)) { - xlog("L_INFO", "$ci|log|relay internally sourced in-dialog message without loose_route"); - route(RELAY); - } else if (t_check_trans()) { - xlog("L_INFO", "$ci|log|allow message for a known transaction"); - route(RELAY); - } else { - xlog("L_INFO", "$ci|log|message had a to-tag but can't be loose routed"); - 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(); - } - - t_check_trans(); - - if (loose_route()) { - sl_send_reply("403", "No pre-loaded routes"); - exit(); - } - - if (is_method("REGISTER")) { - if (nat_uac_test("3")) { - xlog("L_INFO", "$ci|log|Correcting NATed contact in registration\n"); - force_rport(); - - setbflag(FLB_NATB); - setbflag(FLB_NATSIPPING); - - fix_nated_register(); - } - - if (is_present_hf("Authorization")) { - if ($sht(auth_cache=>$Au) != $null && pv_auth_check("$fd", "$sht(auth_cache=>$Au)", "0", "0")) { - xlog("L_INFO", "$ci|log|Authenticated $Au via cached SIP creds\n"); - } else { - ## RABBITMQ - Credentials fetch - if (!auth_check("$fd", "subscriber", "1")) { - auth_challenge("$fd", "0"); - xlog("L_INFO", "$ci|log|Issued new auth challenge to failed registration attempt\n"); - exit; - } else { - xlog("L_INFO", "$ci|log|Caching SIP credentials for $Au\n"); - $sht(auth_cache=>$Au) = $avp(password); - } - } - } else { - auth_challenge("$fd", "0"); - xlog("L_INFO", "$ci|log|Issued new auth challenge to new registration attempt\n"); - exit; - } - - # user authenticated - remove auth header - consume_credentials(); - - save("location"); - exit; - } else if (!is_method("MESSAGE")) { - record_route(); - } -} - -# Take the routes from dispatcher - hash over callid -# If prefered route defined, reorder the destionations -route[FIND_ROUTES] -{ - # alg 0 = hash(Callid) - if (!ds_select_dst("1", "0")) { - xlog("L_ERR", "$ci|end|no servers avaliable"); - - sl_send_reply("480", "All servers busy"); - - exit; - } - - # Handle the case when a prefered route is set - $var(contact_uri) = $(ct{tobody.user}) + "@" + $(ct{tobody.host}); - if ($sht(associations=>$var(contact_uri)) != $null) { - $var(prefered_route) = $sht(associations=>$var(contact_uri)); - - xlog("L_INFO", "$ci|log|should route to $var(prefered_route)"); - - route(REORDER_ROUTES); - } -} - -route[REORDER_ROUTES] -{ - $var(i) = 0; - $var(found) = 0; - while($(avp(ds_dst)[$var(i)]) != $null) { - if($(avp(ds_dst)[$var(i)]) != $var(prefered_route)) { - $avp(tmp_ds_dst) = $(avp(ds_dst)[$var(i)]); - } else { - $var(found) = 1; - } - - $var(i) = $var(i) + 1; - } - - if ($var(found)) { - xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to keep associated server first"); - - $(avp(ds_dst)[*]) = $null; - - $var(i) = 0; - while($(avp(tmp_ds_dst)[$var(i)]) != $null) { - $avp(ds_dst) = $(avp(tmp_ds_dst)[$var(i)]); - - $var(i) = $var(i) + 1; - } - $avp(ds_dst) = $var(prefered_route); - $du = $var(prefered_route); - - $(avp(tmp_ds_dst)[*]) = $null; - } else { - xlog("L_INFO", "$ci|log|associated media server is inactive, moving to $rd"); - - $sht(associations=>$var(contact_uri)) = $null; - } -} - -route[HANDLE_MOVE_REQUEST] -{ - if (is_method("INVITE") && $rU == "*6683*") { - $var(contact_uri) = @from.uri.user + "@" + @from.uri.host; - - if ($sht(associations=>$var(contact_uri)) != $null) { - xlog("L_INFO", "$ci|log|remove association for user $var(contact_uri) - with media server $sht(associations=>$var(contact_uri))\n"); - - $sht(associations=>$var(contact_uri)) = $null; - } - - send_reply("503", "Removed association"); - - xlog("L_INFO", "$ci|log|removed association for user $var(contact_uri) - with media server $sht(associations=>$var(contact_uri))\n"); - - exit; - } -} - -route[RELAY] -{ - if (isflagset(FLAG_INTERNALLY_SOURCED)) { - route(INTERNAL_TO_EXTERNAL_RELAY); - } else { - route(EXTERNAL_TO_INTERNAL_RELAY); - } - - exit(); -} - -route[INTERNAL_TO_EXTERNAL_RELAY] -{ - remove_hf("X-AUTH-IP"); - - t_on_reply("EXTERNAL_REPLY"); - - t_set_fr(0, 10000); - - t_relay(); -} - -route[EXTERNAL_TO_INTERNAL_RELAY] -{ - if (!isflagset(FLAG_INTERNALLY_SOURCED)) { - route(NAT_TEST_AND_CORRECT); - } - - remove_hf("X-AUTH-IP"); - append_hf("X-AUTH-IP: $si\r\n"); - - t_on_reply("INTERNAL_REPLY"); - t_on_failure("INTERNAL_FAULT"); - - t_set_fr(0, 1000); - - t_relay(); -} - -route[LOG_DESTINATION] -{ - if (isdsturiset()) { - $var(port) = $dp; - $var(domain) = $dd; - } else { - $var(port) = $rp; - $var(domain) = $rd; - } - - if ($(var(port){s.len}) <= 0) { - $var(port) = "5060"; - } - - xlog("L_INFO", "$ci|pass|$var(domain):$var(port)"); -} - -route[NAT_TEST_AND_CORRECT] -{ - if (is_present_hf("Record-Route")) { - $var(i) = $rr_count; - while($var(i) > 0) { - $var(i) = $var(i) - 1; - $var(rr) = $(hdr(Record-Route)[$var(i)]); - if (!is_myself("$(var(rr){nameaddr.uri})")) { - setflag(FLAG_SKIP_NAT_CORRECTION); - } - } - } else if ($Rp == "5080") { - setflag(FLAG_SKIP_NAT_CORRECTION); - } - - if (isflagset(FLAG_SKIP_NAT_CORRECTION)) { - return(); - } - - if (nat_uac_test("3")) { - force_rport(); - fix_nated_contact(); - } - - if (has_body("application/sdp") && nat_uac_test("8")) { - fix_nated_sdp("10"); - } -} - -onreply_route[EXTERNAL_REPLY] -{ - xlog("L_INFO", "$ci|log|external reply $T_reply_code"); - - route(NAT_TEST_AND_CORRECT); -} - -onreply_route[INTERNAL_REPLY] -{ - # this route handles replies that are comming from our media server - xlog("L_INFO", "$ci|start|recieved internal reply $T_reply_code $rr"); - xlog("L_INFO", "$ci|log|source $si:$sp"); - - if ($rs < 300) { - xlog("L_INFO", "$ci|pass|$T_req($si):$T_req($sp)"); - } - - # change 6xx to 4xx - if (t_check_status("6[0-9][0-9]")) { - $var(new_code) = "4" + $(T_reply_code{s.substr,1,0}); - change_reply_status("$var(new_code)", "$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"); - - exit; - } - - # if the failure case was something that we should recover - # from then try to find a new media server - if (t_check_status("(401)|(407)")) { - xlog("L_INFO", "$ci|log|failure route ignoring auth reply $T_reply_code $rr"); - - exit; - } else if (t_check_status("403")) { - xlog("L_INFO", "$ci|log|failure route overriding reply code 403 with 503"); - - xlog("L_INFO", "$ci|pass|$si:$sp"); - - send_reply("503", "Error: Services Unavailable. Try Later"); - - exit; - } else if (t_check_status("402")) { - xlog("L_INFO", "$ci|log|failure route overriding reply code 402 with 486"); - - xlog("L_INFO", "$ci|pass|$si:$sp"); - - send_reply("486", "Insufficient Funds"); - - exit; - } 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"); - - # try to find a new media server to send the call to - if ($avp(route_attempts) < 3 && ds_next_domain()) { - xlog("L_INFO", "$ci|log|attempting retry $avp(route_attempts) of failed request"); - xlog("L_INFO", "$ci|log|routing call to next media server $rd:$rp"); - - # reset the final reply timer - $avp(final_reply_timer) = 3; - - t_on_reply("INTERNAL_REPLY"); - - t_on_failure("INTERNAL_FAULT"); - - # relay the request to the new media server - route(EXTERNAL_TO_INTERNAL_RELAY); - - $avp(route_attempts) = $avp(route_attempts) + 1; - } else if (t_check_status("404")) { - xlog("L_ERR", "$ci|log|no other media servers avaliable, sending 486"); - - send_reply("486", "Not found"); - - exit; - } else { - xlog("L_ERR", "$ci|log|no other media servers avaliable"); - - exit; - } - } else if (t_check_status("302")) { - ## TODO - test this - ## get_redirects("*"); - - if($T_rpl($hdr(X-Redirect-Server)) != $null) { - $var(contact_uri) = @from.uri.user + "@" + @from.uri.host; - - $sht(associations=>$var(contact_uri)) = $T_rpl($hdr(X-Redirect-Server)); - - xlog("L_INFO", "$ci|log|stored redirect mapping for $var(contact_uri) to $T_rpl($hdr(X-Redirect-Server))"); - - remove_hf("X-Redirect-Server"); - } - } else { - xlog("L_INFO", "$ci|log|failure route ignoring reply $T_reply_code $rr"); - - exit; - } - - route(LOG_DESTINATION); -} - -onsend_route { - if (isflagset(FLAG_ASSOCIATE_USER)) { - $var(contact_uri) = $(ct{tobody.user}) + "@" + $(ct{tobody.host}); - xlog("L_INFO", "$ci|log|associate user $var(contact_uri) with media server sip:$sndto(ip):$sndto(port)\n"); - $sht(associations=>$var(contact_uri))= "sip:" + $sndto(ip) + ":" + $sndto(port); - } - - xlog("L_INFO", "$ci|pass|$sndfrom(ip):$sndfrom(port) -> $sndto(ip):$sndto(port)"); -} +####### Local Configuration ######## +include_file "local.cfg" ## vim:set tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/local.cfg b/kamailio/local.cfg new file mode 100644 index 0000000..1b68c0b --- /dev/null +++ b/kamailio/local.cfg @@ -0,0 +1,50 @@ +####### Logging Parameters ######### +debug = L_INFO + +####### Alias Parameters ######### +# alias = "mydomain.net" + +####### UDP Parameters ######### +## NOTE: You must MATCH this to your network adapter!! +## If they do not match, all UDP packets over +## this limit WILL FAIL! +## E.g.: Add MTU=1472 to the /etc/sysconfig/network-scripts/XXX +# udp4_raw_mtu = 1472 + +####### Binding Parameters ######### +# mhomed=1 +listen = tcp:127.0.0.1:5060 +listen = udp:127.0.0.1:5060 +listen = tcp:127.0.0.1:7000 +listen = udp:127.0.0.1:7000 + +####### Dispatcher module ######## +#!ifdef DISPATCHER-ROLE +modparam("dispatcher", "ds_ping_from", "sip:sipcheck@127.0.0.1") +# modparam("dispatcher", "ds_ping_sock", "udp:127.0.0.1:5060") +#!endif + +######## NAT Traversal module - signaling functions ######## +#!ifdef NAT-TRAVERSAL-ROLE +modparam("nathelper", "sipping_from", "sip:sipcheck@127.0.0.1") +# modparam("nathelper", "natping_socket", "127.0.0.1:5060") +#!endif + +####### Kazoo Integration module ########## +#!ifdef INCLUDE-DB-KAZOO +## NOTE: The hostname that should be advertised to Kazoo +modparam("db_kazoo", "node_hostname", "kamailio.2600hz.com") +## NOTE: If you want a certain fs_path to be sent Kazoo, +## uncomment the next line and set the right value +# modparam("db_kazoo", "register_fs_path", "127.0.0.1:5060") +#!endif + +####### Common Module Parameters ########## +#!ifdef REGISTRAR-ROLE +modparam("auth_db|usrloc", "db_url", "kazoo://guest:guest@127.0.0.1:5672/callmgr") +#!endif +#!ifdef PRESENCE-ROLE +modparam("presence", "db_url", "kazoo://guest:guest@127.0.0.1:5672/dialoginfo") +#!endif + +## vim:set tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/nat-traversal-role.cfg b/kamailio/nat-traversal-role.cfg new file mode 100644 index 0000000..b8a03b6 --- /dev/null +++ b/kamailio/nat-traversal-role.cfg @@ -0,0 +1,41 @@ +######## NAT Traversal module - signaling functions ######## +#!ifndef NATHELPER-LOADED +loadmodule "nathelper.so" +#!endif +modparam("nathelper", "received_avp", "$avp(AVP_RECV_PARAM)") +modparam("nathelper", "natping_interval", 30) +modparam("nathelper", "ping_nated_only", 1) +modparam("nathelper", "natping_processes", 5) +modparam("nathelper", "sipping_bflag", FLB_NATSIPPING) + +####### NAT Traversal Logic ######## +route[NAT_TEST_AND_CORRECT] +{ + if (is_present_hf("Record-Route")) { + $var(i) = $rr_count; + while($var(i) > 0) { + $var(i) = $var(i) - 1; + $var(rr) = $(hdr(Record-Route)[$var(i)]); + if (!is_myself("$(var(rr){nameaddr.uri})")) { + setflag(FLAG_SKIP_NAT_CORRECTION); + } + } + } else if ($Rp == "5080") { + setflag(FLAG_SKIP_NAT_CORRECTION); + } + + if (isflagset(FLAG_SKIP_NAT_CORRECTION)) { + return(); + } + + if (nat_uac_test("3")) { + force_rport(); + fix_nated_contact(); + } + + if (has_body("application/sdp") && nat_uac_test("8")) { + fix_nated_sdp("10"); + } +} + +## vim:set tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/presence-role.cfg b/kamailio/presence-role.cfg new file mode 100644 index 0000000..10f54dc --- /dev/null +++ b/kamailio/presence-role.cfg @@ -0,0 +1,48 @@ +#!trydef INCLUDE-DB-KAZOO + +######## Generic Hash Table container in shared memory ######## +modparam("htable", "htable", "dbkp=>size=16;autoexpire=7200") + +######## Presence User Agent module ######## +loadmodule "pua_dialoginfo.so" +modparam("pua_dialoginfo", "library_mode", 1) + +######## Presence server module ######## +loadmodule "presence.so" +loadmodule "presence_dialoginfo.so" +modparam("presence", "subs_db_mode", 1) +modparam("presence", "expires_offset", 60) +modparam("presence", "publ_cache", 0) + +####### Presence Logic ######## +route[HANDLE_SUBSCRIBE] +{ + if (is_method("SUBSCRIBE")) { + #!ifdef NAT-TRAVERSAL-ROLE + route(NAT_TEST_AND_CORRECT); + #!endif + + if (!t_newtran()) { + sl_reply_error(); + exit; + } + handle_subscribe(); + t_release(); + exit; + } +} + +route[HANDLE_PUBLISH] +{ + if (is_method("PUBLISH")) { + if (!t_newtran()) { + sl_reply_error(); + exit; + } + handle_publish(); + t_release(); + exit; + } +} + +## vim:set tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/registrar-role.cfg b/kamailio/registrar-role.cfg new file mode 100644 index 0000000..9d853a0 --- /dev/null +++ b/kamailio/registrar-role.cfg @@ -0,0 +1,76 @@ +#!trydef INCLUDE-DB-KAZOO + +######## Generic Hash Table container in shared memory ######## +modparam("htable", "htable", "auth_cache=>size=16;autoexpire=7200") + +####### Authentication Interface module ########## +loadmodule "auth.so" +loadmodule "auth_db.so" +modparam("auth_db", "use_domain", 1) +modparam("auth_db", "version_table", 0) +modparam("auth_db", "calculate_ha1", 1) +modparam("auth_db", "password_column", "password") +modparam("auth_db", "load_credentials", "$avp(password)=password") + +####### User Location Implementation module ########## +loadmodule "usrloc.so" +modparam("usrloc", "db_mode", 1) +modparam("usrloc", "db_update_as_insert", 1) +modparam("usrloc", "use_domain", 1) +modparam("usrloc", "nat_bflag", FLB_NATB) + +######## NAT Traversal module - signaling functions ######## +#!ifdef NAT-TRAVERSAL-ROLE +#!trydef NATHELPER-LOADED +loadmodule "nathelper.so" +#!endif + +####### SIP Registrar implementation module ########## +loadmodule "registrar.so" +modparam("registrar", "received_avp", "$avp(AVP_RECV_PARAM)") + +####### Registrar Logic ######## +route[HANDLE_REGISTER] +{ + if (is_method("REGISTER")) { + #!ifdef NAT-TRAVERSAL-ROLE + if (nat_uac_test("3")) { + xlog("L_INFO", "$ci|log|Correcting NATed contact in registration\n"); + force_rport(); + + setbflag(FLB_NATB); + setbflag(FLB_NATSIPPING); + + fix_nated_register(); + } + #!endif + + if (is_present_hf("Authorization")) { + if ($sht(auth_cache=>$Au) != $null && pv_auth_check("$fd", "$sht(auth_cache=>$Au)", "0", "0")) { + xlog("L_INFO", "$ci|log|Authenticated $Au via cached SIP creds\n"); + } else { + ## RABBITMQ - Credentials fetch + if (!auth_check("$fd", "subscriber", "1")) { + auth_challenge("$fd", "0"); + xlog("L_INFO", "$ci|log|Issued new auth challenge to failed registration attempt\n"); + exit; + } else { + xlog("L_INFO", "$ci|log|Caching SIP credentials for $Au\n"); + $sht(auth_cache=>$Au) = $avp(password); + } + } + } else { + auth_challenge("$fd", "0"); + xlog("L_INFO", "$ci|log|Issued new auth challenge to new registration attempt\n"); + exit; + } + + # user authenticated - remove auth header + consume_credentials(); + + save("location"); + exit; + } +} + +## vim:set tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/roles.cfg b/kamailio/roles.cfg new file mode 100644 index 0000000..fd4b71a --- /dev/null +++ b/kamailio/roles.cfg @@ -0,0 +1,7 @@ +####### Roles ######## +#!trydef DISPATCHER-ROLE +#!trydef NAT-TRAVERSAL-ROLE +#!trydef REGISTRAR-ROLE +#!trydef PRESENCE-ROLE + +## vim:set tabstop=4 softtabstop=4 shiftwidth=4 expandtab