diff --git a/freeswitch/sip_profiles/sipinterface_1.xml b/freeswitch/sip_profiles/sipinterface_1.xml index 0bb23cc..16b3f1c 100644 --- a/freeswitch/sip_profiles/sipinterface_1.xml +++ b/freeswitch/sip_profiles/sipinterface_1.xml @@ -14,13 +14,15 @@ + + + - diff --git a/kamailio/antiflood-role.cfg b/kamailio/antiflood-role.cfg index 8c71172..29284d8 100644 --- a/kamailio/antiflood-role.cfg +++ b/kamailio/antiflood-role.cfg @@ -5,10 +5,6 @@ #!trydef ANTIFLOOD_FAILED_AUTH_WINDOW 300 #!trydef ANTIFLOOD_FAILED_AUTH_DENSITY 4 -#!ifndef ANTIFLOOD_CACHE_PERIOD -#!substdef "!ANTIFLOOD_CACHE_PERIOD!600!g" -#!endif - ######## Flood Prevention Hash Tables ######## modparam("htable", "htable", "antiflood=>size=16;autoexpire=ANTIFLOOD_CACHE_PERIOD;initval=0") diff --git a/kamailio/dbtext/dispatcher b/kamailio/dbtext/dispatcher index 12a5db7..0ac0866 100644 --- a/kamailio/dbtext/dispatcher +++ b/kamailio/dbtext/dispatcher @@ -1,9 +1 @@ -### Dispatcher Set IDs: -### 1 - Primary media servers -### 2 - Backup media servers -### 3 - Alternate media server IPs (used only for classification) -### 10 - Presence servers (if not locally handled) -### 20 - Registrar servers (if not locally handled) - -# setid(integer) destination(sip uri) flags (integer, optional) -1 sip:127.0.0.1:11000 0 +id(int,auto) setid(int) destination(string) flags(int) priority(int) attrs(string) description(string) diff --git a/kamailio/dbtext/version b/kamailio/dbtext/version index d467039..65f94d8 100644 --- a/kamailio/dbtext/version +++ b/kamailio/dbtext/version @@ -1,8 +1,67 @@ -table_name(string) table_version(int) -address:6 -trusted:5 -pua:7 +table_name(string) table_version(int) +acc:5 +acc_cdrs:1 active_watchers:11 +address:6 +aliases:6 +carrier_name:1 +carrierfailureroute:2 +carrierroute:3 +cpl:1 +dbaliases:1 +dialog:7 +dialog_vars:1 +dialplan:2 +dispatcher:4 +domain:2 +domain_attrs:1 +domain_name:1 +domainpolicy:2 +dr_gateways:3 +dr_groups:2 +dr_gw_lists:1 +dr_rules:3 +globalblacklist:1 +grp:2 +htable:2 +imc_members:1 +imc_rooms:1 +lcr_gw:3 +lcr_rule:2 +lcr_rule_target:1 +location:8 +location_attrs:1 +matrix:1 +missed_calls:4 +mohqcalls:1 +mohqueues:1 +mtree:1 +mtrees:2 +pdt:1 +pl_pipes:1 presentity:4 +pua:7 +purplemap:1 +re_grp:1 +rls_presentity:1 +rls_watchers:3 +rtpproxy:1 +sca_subscriptions:1 +silo:7 +sip_trace:3 +speed_dial:2 +subscriber:6 +trusted:5 +uacreg:1 +uid_credentials:7 +uid_domain:2 +uid_domain_attrs:1 +uid_global_attrs:1 +uid_uri:3 +uid_uri_attrs:2 +uid_user_attrs:3 +uri:1 +userblacklist:1 +usr_preferences:2 watchers:3 -location:8 +xcap:4 diff --git a/kamailio/default.cfg b/kamailio/default.cfg index f40b2f7..5fe1a8b 100644 --- a/kamailio/default.cfg +++ b/kamailio/default.cfg @@ -19,7 +19,7 @@ user_agent_header = "User-Agent: Kazoo" shm_force_alloc = yes mlock_pages = yes phone2tel = 1 -max_while_loops = 500 +max_while_loops = MAX_WHILE_LOOPS ####### Logging Parameters ######### debug = L_INFO @@ -83,9 +83,21 @@ disable_sctp = yes ####### Modules Section ######## mpath="/usr/lib64/kamailio/modules/" +######## Kamailio stun module ######## +loadmodule "stun.so" + +######## Kamailio outbound module ######## +loadmodule "outbound.so" + +######## Kamailio path module ######## +loadmodule "path.so" + ######## Kamailio control connector module ######## loadmodule "ctl.so" +######## Kamailio uuid module ######## +loadmodule "uuid.so" + ######## Kamailio core extensions module ######## loadmodule "kex.so" @@ -167,6 +179,9 @@ modparam("kazoo", "amqp_max_channels", MY_AMQP_MAX_CHANNELS) modparam("kazoo", "amqp_max_channels", 100) #!endif modparam("kazoo", "amqp_query_timeout_avp", "$avp(kz_timeout)"); +modparam("kazoo", "amqp_consumer_processes", 4); +modparam("kazoo", "amqp_consumer_workers", 16); +modparam("kazoo", "amqp_heartbeats", 5); ####### Role Configurations ########## #!ifdef DISPATCHER-ROLE @@ -220,16 +235,28 @@ include_file "registrar-sync-role.cfg" #!ifdef FAST_PICKUP-ROLE include_file "fast-pickup-role.cfg" #!endif +#!ifdef PRESENCE_SYNC-ROLE +include_file "presence_sync-role.cfg" +#!endif +#!ifdef PRESENCE_QUERY-ROLE +include_file "presence_query-role.cfg" +#!endif +#!ifdef PRESENCE_NOTIFY_SYNC-ROLE +include_file "presence_notify_sync-role.cfg" +#!endif + ####### Permissions module ########## loadmodule "permissions.so" -modparam("permissions", "db_url", "text:///etc/kazoo/kamailio/dbtext") +modparam("permissions", "db_url", "KAZOO_DB_URL") modparam("permissions", "db_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"); @@ -264,6 +291,10 @@ route route(HANDLE_NOTIFY); + #!ifdef AUTHORIZATION-ROLE + route(AUTHORIZATION_CHECK); + #!endif + route(HANDLE_MESSAGE); #!ifdef PRESENCE-ROLE @@ -279,6 +310,10 @@ route route(PREPARE_INITIAL_REQUESTS); + #!ifdef PUSHER-ROLE + route(PUSHER_ROUTE); + #!endif + if (isflagset(FLAG_INTERNALLY_SOURCED)) { #!ifdef RESPONDER-ROLE route(HANDLE_RESPOND); @@ -294,6 +329,15 @@ route route(EXTERNAL_TO_INTERNAL_RELAY); } +route[CHECK_RETRANS] +{ + # handle retransmissions + if(t_precheck_trans()) { + t_check_trans(); + exit; + } +} + route[SANITY_CHECK] { if (!sanity_check()) { @@ -444,29 +488,15 @@ route[HANDLE_IN_DIALOG_REQUESTS] } #!endif - #!ifdef WEBSOCKETS-ROLE - if ($du == $null) { + if(!isdsturiset()) { handle_ruri_alias(); - switch ($rc) { - case -1: - xlog("L_ERR", "$ci|stop|failed to handle alias of R-URI $ru\n"); - send_reply("400", "Bad request"); - exit; - case 1: - xlog("L_INFO", "$ci|log|loose_route in-dialog message with alias $du"); - break; - case 2: - xlog("L_INFO", "$ci|log|loose_route in-dialog message with alias $du"); - break; - } } - #!endif 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 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); } @@ -501,9 +531,6 @@ route[PREPARE_INITIAL_REQUESTS] exit(); } - # handle re-transmissions - t_check_trans(); - if (is_method("UPDATE")) { xlog("L_WARN", "$ci|end|update outside dialog not allowed"); send_reply("403", "Dialog does not exist"); @@ -518,8 +545,7 @@ route[PREPARE_INITIAL_REQUESTS] if (loose_route()) { $xavp(regcfg=>match_received) = $su; - $xavp(regcfg[0]=>match_contact) = $(ct{nameaddr.uri}); - if(registered("location", "$rz:$Au", 6) == 1) { + if(registered("location", "$rz:$Au", 2) == 1) { xlog("L_INFO", "$ci|log|allowing initial route-set for $Au"); } else { xlog("L_WARN", "$ci|end|dropping initial request with route-set"); @@ -528,9 +554,13 @@ route[PREPARE_INITIAL_REQUESTS] } } - if (!is_method("MESSAGE")) { - record_route(); - } + if ( is_method("INVITE|MESSAGE|NOTIFY") && isflagset(FLAG_INTERNALLY_SOURCED) && $hdr(X-KAZOO-AOR) != $null && registered("location", "$hdr(X-KAZOO-AOR)")) + { + $avp(kazoo_aor) = $hdr(X-KAZOO-AOR); + xlog("L_INFO", "$ci|end|setting aor avp : AOR : $hdr(X-KAZOO-AOR)"); + }; + + record_route(); } route[RELAY] @@ -553,11 +583,14 @@ route[INTERNAL_TO_EXTERNAL_RELAY] } #!endif - #!ifdef PUSHER-ROLE - route(INTERNAL_TO_EXTERNAL_PUSH); - #!endif - remove_hf_re("^X-.*"); + + if( $avp(kazoo_aor) != $null) + { + lookup("location", "$avp(kazoo_aor)"); + xlog("L_INFO", "$ci|end|routing to $ruid : AOR : $avp(kazoo_aor)"); + } + t_on_reply("EXTERNAL_REPLY"); @@ -588,6 +621,8 @@ route[EXTERNAL_TO_INTERNAL_RELAY] remove_hf_re("^X-.*"); append_hf("X-AUTH-IP: $si\r\n"); append_hf("X-AUTH-PORT: $sp\r\n"); + + route(ADD_AUTHORIZATION_HEADERS); t_on_reply("INTERNAL_REPLY"); t_on_failure("INTERNAL_FAULT"); @@ -685,6 +720,7 @@ failure_route[INTERNAL_FAULT] $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))"); } + route(DISPATCHER_REDIRECT); } else if (!t_check_status("407") && $avp(AVP_REDIRECT_KEY) != $null && $sht(redirects=>$avp(AVP_REDIRECT_KEY)) != $null @@ -770,16 +806,37 @@ event_route[kazoo:mod-init] #!endif - #!ifdef REGISTRAR-ROLE + #!ifdef DISPATCHER-ROLE - $var(payload) = "{ 'exchange' : 'callmgr' , 'type' : 'topic', 'queue' : 'MSG-FLUSH-MY_HOSTNAME', 'routing' : 'registration.flush.*', 'auto_delete' : 1, 'durable' : 0, 'no_ack' : 1, 'wait_for_consumer_ack' : 0 }"; + $var(payload) = "{ 'exchange' : 'registrar' , 'type' : 'topic', 'queue' : 'MSG-FLUSH-MY_HOSTNAME', 'routing' : 'registration.flush.*', 'auto_delete' : 1, 'durable' : 0, 'no_ack' : 1, 'wait_for_consumer_ack' : 0 }"; kazoo_subscribe("$var(payload)"); #!endif #!ifdef REGISTRAR_SYNC-ROLE - $var(payload) = "{ 'exchange' : 'callmgr' , 'type' : 'topic', 'queue' : 'REGISTRAR-SYNC-QUEUE-MY_HOSTNAME', 'routing' : 'registration.sync', 'auto_delete' : 1, 'durable' : 0, 'no_ack' : 1, 'wait_for_consumer_ack' : 0 }"; + $var(payload) = "{ 'exchange' : 'registrar' , 'type' : 'topic', 'queue' : 'REGISTRAR-SYNC-QUEUE-MY_HOSTNAME', 'routing' : 'registration.sync', 'auto_delete' : 1, 'durable' : 0, 'no_ack' : 1, 'wait_for_consumer_ack' : 0 }"; + kazoo_subscribe("$var(payload)"); + + #!endif + + #!ifdef PRESENCE_SYNC-ROLE + + $var(payload) = "{ 'exchange' : 'presence' , 'type' : 'topic', 'queue' : 'PRESENCE-QUEUE-MY_HOSTNAME', 'routing' : 'sync', 'auto_delete' : 1, 'durable' : 0, 'no_ack' : 1, 'wait_for_consumer_ack' : 0 }"; + kazoo_subscribe("$var(payload)"); + + #!endif + + #!ifdef PRESENCE_QUERY-ROLE + + $var(payload) = "{ 'exchange' : 'omnipresence' , 'type' : 'topic', 'routing' : 'presence.search_req.*', 'federate' : 1 }"; + kazoo_subscribe("$var(payload)"); + + #!endif + + #!ifdef NODES_SYNC-ROLE + + $var(payload) = "{ 'exchange' : 'nodes' , 'type' : 'fanout', 'queue' : 'NODES-MY_HOSTNAME', 'federate' : 1}"; kazoo_subscribe("$var(payload)"); #!endif @@ -801,5 +858,48 @@ event_route[kazoo:consumer-event-connection-closed] xlog("L_INFO","connection to $(kzE{kz.json,host}) closed"); } +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"); + } +} + +#!ifdef PRESENCE_NOTIFY_SYNC-ROLE +event_route[tm:local-request] +{ + route(PRESENCE_LOCAL_NOTIFY); +} +#!endif # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/defs.cfg b/kamailio/defs.cfg new file mode 100644 index 0000000..24ca823 --- /dev/null +++ b/kamailio/defs.cfg @@ -0,0 +1,27 @@ +## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ## + + +####### defs ######## + +#!ifndef KAZOO_DB_URL +#!substdef "!KAZOO_DB_URL!text:///etc/kazoo/kamailio/dbtext!g" +#!endif + +#!ifndef MAX_WHILE_LOOPS +#!substdef "!MAX_WHILE_LOOPS!500!g" +#!endif + +#!ifndef OPENBTS_AUTH_SECRET +#!substdef "!OPENBTS_AUTH_SECRET!b3a54fa8317c7d9cb1d89d8970947b30eda273124d97fc3a079ccc98ecc2569b!g" +#!endif + +#!ifndef KZ_USE_DISPATCHER_LIST +#!trydef KZ_USE_DISPATCHER_TABLE +#!endif + +#!ifndef ANTIFLOOD_CACHE_PERIOD +#!substdef "!ANTIFLOOD_CACHE_PERIOD!600!g" +#!endif + + +# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/dispatcher-role.cfg b/kamailio/dispatcher-role.cfg index 930dcc8..14c647d 100644 --- a/kamailio/dispatcher-role.cfg +++ b/kamailio/dispatcher-role.cfg @@ -3,7 +3,11 @@ modparam("htable", "htable", "failover=>size=16;autoexpire=120") ####### Dispatcher module ######## loadmodule "dispatcher.so" +#!ifdef KZ_USE_DISPATCHER_TABLE +modparam("dispatcher", "db_url", "KAZOO_DB_URL") +#!else modparam("dispatcher", "list_file", "/etc/kazoo/kamailio/dbtext/dispatcher") +#!endif modparam("dispatcher", "flags", 2) modparam("dispatcher", "use_default", 0) modparam("dispatcher", "force_dst", 1) @@ -18,8 +22,7 @@ modparam("dispatcher", "ds_ping_interval", 10) modparam("dispatcher", "ds_probing_threshold", 3) modparam("dispatcher", "ds_probing_mode", 1) modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200") -modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_IP_ADDRESS") -# modparam("dispatcher", "ds_ping_sock", "udp:MY_IP_ADDRESS:5060") +modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_HOSTNAME") ## Dispatcher Groups: @@ -109,6 +112,22 @@ route[DISPATCHER_FIND_ROUTES] } } +route[DISPATCHER_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)"); + $du = $var(prefered_route); + $avp(AVP_REDIRECT_KEY) = $var(redirect); + route(EXTERNAL_TO_INTERNAL_RELAY); + exit(); + } +} + route[DISPATCHER_REORDER_ROUTES] { $var(i) = 0; diff --git a/kamailio/fast-pickup-role.cfg b/kamailio/fast-pickup-role.cfg index 797722b..8005898 100644 --- a/kamailio/fast-pickup-role.cfg +++ b/kamailio/fast-pickup-role.cfg @@ -85,13 +85,13 @@ route[FAST_PICKUP_INIT] { $var(AppName) = $(kzE{kz.json,App-Name}); if($var(AppName) == "park") { - $var(Pickup) = ";kazoo-pickup=true"; + $var(Pickup) = ";a-leg=true"; } else { $var(Pickup) = ""; } $sht(fp=>$(kzE{kz.json,Call-Cookie})::Switch-URI) = $(kzE{kz.json,Switch-URI}); - $sht(fp=>$(kzE{kz.json,Call-Cookie})::Call-ID) = $(kzE{kz.json,Target-Call-ID}); - $sht(fp=>$(kzE{kz.json,Call-Cookie})::URI) = "sip:" + $(kzE{kz.json,From-User}) + "@" + $(kzE{kz.json,To-Realm}) + $var(Pickup); + $sht(fp=>$(kzE{kz.json,Call-Cookie})::Call-ID) = $(kzE{kz.json,Target-Call-ID}) + $var(Pickup); + $sht(fp=>$(kzE{kz.json,Call-Cookie})::URI) = "sip:" + $(kzE{kz.json,From-User}) + "@" + $(kzE{kz.json,To-Realm}) ; } # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/kamailio.cfg b/kamailio/kamailio.cfg index cc4ea79..2749fbf 100644 --- a/kamailio/kamailio.cfg +++ b/kamailio/kamailio.cfg @@ -26,6 +26,9 @@ ####### Local Configuration ######## include_file "local.cfg" +####### defaults not configured in local ######## +include_file "defs.cfg" + ####### Default Configuration ###### include_file "default.cfg" diff --git a/kamailio/local.cfg b/kamailio/local.cfg index 1f8f058..4693d15 100644 --- a/kamailio/local.cfg +++ b/kamailio/local.cfg @@ -14,6 +14,7 @@ debug = L_INFO #!trydef RESPONDER-ROLE #!trydef NODES-ROLE #!trydef FAST_PICKUP-ROLE +#!trydef PRESENCE_QUERY-ROLE ## Disabled Roles - remove all but the last '#' to enable # # #!trydef TRAFFIC_FILTER-ROLE @@ -25,6 +26,8 @@ debug = L_INFO # # #!trydef MESSAGE-ROLE # # #!trydef PUSHER-ROLE # # #!trydef REGISTRAR_SYNC-ROLE +# # #!trydef PRESENCE_SYNC-ROLE +# # #!trydef PRESENCE_NOTIFY_SYNC-ROLE ################################################################################ ## SERVER INFORMATION @@ -50,6 +53,26 @@ debug = L_INFO ## it completely the validation will be disabled. #!substdef "!MY_WEBSOCKET_DOMAIN!2600hz.com!g" +################################################################################ +## DISPATCHER FORMAT INFORMATION +################################################################################ +## dispatcher list changed the default storage type from list to table +## this will allow the management of dispatched servers in the DB +## +## if you're using dbtext and can't start kamailio because of dispatcher +## check the format of /etc/kazoo/kamailio/dbtext/dispatcher +## +## # setid(integer) destination(sip uri) flags (integer, optional) +## 1 sip:192.168.16.131:11000 0 +## should converted to +## id(int,auto) setid(int) destination(string) flags(int) priority(int) attrs(string) description(string) +## 1:1:sip\:192.168.16.131\:11000:0:1: : (there is a space at end) +## +## uncommenting this param will allow to continue using dispatcher list +# # #!trydef KZ_USE_DISPATCHER_LIST + + + ################################################################################ ## UDP PARAMETERS ################################################################################ diff --git a/kamailio/message-role.cfg b/kamailio/message-role.cfg index ddf5ae5..ebf8855 100644 --- a/kamailio/message-role.cfg +++ b/kamailio/message-role.cfg @@ -17,7 +17,7 @@ event_route[kazoo:consumer-event-message-route] $sht(msg=>$(kzE{kz.json,Call-ID})) = $kzE; $uac_req(method)="MESSAGE"; $uac_req(body)= $(kzE{kz.json,Body}); - $uac_req(hdrs)="Content-Type: text/plain\r\n"; + $uac_req(hdrs)="X-KAZOO-AOR: " + $var(to_uri)+ "\r\nContent-Type: text/plain\r\n"; $uac_req(turi) = $var(to_uri); $uac_req(ruri) = $var(to_uri); $uac_req(furi) = $var(from_uri); diff --git a/kamailio/nat-traversal-role.cfg b/kamailio/nat-traversal-role.cfg index da71273..be00b29 100644 --- a/kamailio/nat-traversal-role.cfg +++ b/kamailio/nat-traversal-role.cfg @@ -3,8 +3,7 @@ loadmodule "nathelper.so" #!endif modparam("nathelper", "received_avp", "$avp(AVP_RECV_PARAM)") -modparam("nathelper", "sipping_from", "sip:sipcheck@MY_IP_ADDRESS") -# modparam("nathelper", "natping_socket", "MY_IP_ADDRESS:5060") +modparam("nathelper", "sipping_from", "sip:sipcheck@MY_HOSTNAME") ####### NAT Traversal Logic ######## route[NAT_TEST_AND_CORRECT] diff --git a/kamailio/presence-role.cfg b/kamailio/presence-role.cfg index 42b9585..aa01535 100644 --- a/kamailio/presence-role.cfg +++ b/kamailio/presence-role.cfg @@ -24,9 +24,9 @@ modparam("presence", "max_expires", PRESENCE_MAX_EXPIRES) modparam("presence", "sip_uri_match", 1) modparam("presence", "waitn_time", 1) modparam("presence", "notifier_processes", 5) -modparam("presence", "db_url", "text:///etc/kazoo/kamailio/dbtext") +modparam("presence", "db_url", "KAZOO_DB_URL") -modparam("kazoo", "db_url", "text:///etc/kazoo/kamailio/dbtext") +modparam("kazoo", "db_url", "KAZOO_DB_URL") modparam("kazoo", "pua_mode", 1) ####### Presence Logic ######## @@ -76,7 +76,7 @@ route[HANDLE_SUBSCRIBE] $var(fs_contact) = $var(fs_contact) + ";" + $(ct{tobody.params}); } - $var(amqp_payload_request) = '{"Event-Category" : "presence", "Event-Name" : "subscription", "Event-Package" : "$hdr(event)", "Expires" : "$var(Expires)", "Queue" : "BLF-MY_HOSTNAME", "Server-ID" : "BLF-MY_HOSTNAME" , "Contact" : "$(ct{s.escape.common})", "Call-ID" : "$ci", "From" : "$fu", "User" : "$tu", "User-Agent" : "$(ua{s.escape.common})" }'; + $var(amqp_payload_request) = '{"Event-Category" : "presence", "Event-Name" : "subscription", "Event-Package" : "$hdr(event)", "Expires" : "$var(Expires)", "Queue" : "BLF-MY_HOSTNAME", "Server-ID" : "BLF-MY_HOSTNAME" , "Contact" : "$(ct{s.escape.common})", "Call-ID" : "$ci", "From" : "$fu", "User" : "$subs(uri)", "User-Agent" : "$(ua{s.escape.common})" }'; kazoo_publish("dialoginfo_subs", "dialoginfo_subs", $var(amqp_payload_request)); diff --git a/kamailio/presence_notify_sync-role.cfg b/kamailio/presence_notify_sync-role.cfg new file mode 100644 index 0000000..270f531 --- /dev/null +++ b/kamailio/presence_notify_sync-role.cfg @@ -0,0 +1,28 @@ +######## Presence notify sync ######## +## send notify sync back to kazoo + +route[PRESENCE_LOCAL_NOTIFY] +{ + if($rm != "NOTIFY") { + return; + } + $avp(notify_body) = $rb; + $avp(notify_event) = $hdr(Event); + t_on_reply("PRESENCE_NOTIFY_REPLY"); + t_on_failure("PRESENCE_NOTIFY_FAULT"); +} + +onreply_route[PRESENCE_NOTIFY_REPLY] +{ + $var(amqp_payload_request) = '{"Event-Category" : "presence", "Event-Name" : "notify", "Event-Package" : "$avp(notify_event)", "Call-ID" : "$ci", "From" : "$fu", "To" : "$tu", "Body" : "$(avp(notify_body){s.escape.common})", "Sequence" : $cs, "Reply" : $T_reply_code }'; + $var(rk) = "notify." + $td + "." + $tU; + kazoo_publish("dialoginfo_subs", "$var(rk)", $var(amqp_payload_request)); + xlog("L_INFO", "$ci|log|event $avp(notify_event)"); +} + +onreply_route[PRESENCE_NOTIFY_FAULT] +{ + $var(amqp_payload_request) = '{"Event-Category" : "presence", "Event-Name" : "notify", "Event-Package" : "$avp(notify_event)", "Call-ID" : "$ci", "From" : "$fu", "To" : "$tu", "Body" : "$(avp(notify_body){s.escape.common})", "Sequence" : $cs, "Reply" : $T_reply_code }'; + $var(rk) = "notify." + $td + "." + $tU; + kazoo_publish("dialoginfo_subs", "$var(rk)", $var(amqp_payload_request)); +} diff --git a/kamailio/presence_query-role.cfg b/kamailio/presence_query-role.cfg new file mode 100644 index 0000000..063686c --- /dev/null +++ b/kamailio/presence_query-role.cfg @@ -0,0 +1,62 @@ +######## Presence query server module ######## + +####### SQL OPS module ########## +#!ifndef SQLOPS-LOADED +loadmodule "sqlops.so" +modparam("sqlops","sqlcon", "cb=>KAZOO_DB_URL") +#!trydef SQLOPS-LOADED +#!endif + +event_route[kazoo:consumer-event-presence-search-req] +{ + xlog("L_INFO", "received presence search_req $kzE"); + $var(Queue) = $(kzE{kz.json,Server-ID}); + $var(Event) = $(kzE{kz.json,Event-Package}); + $var(Domain) = $(kzE{kz.json,Realm}); + $var(Username) = $(kzE{kz.json,Username}); + $var(Now) = $TS; + $var(Items) = ""; + $var(Query) = $_s(select * from presentity where domain = "$var(Domain)"); + if($var(Event) != "") { + $var(Query) = $var(Query) + $_s( and event = "$var(Event)"); + } + if($var(Username) != "") { + $var(Query) = $var(Query) + $_s( and username = "$var(Username)"); + } + $var(Query) = $var(Query) + " order by username, event, id"; + xlog("L_INFO", "$ci| QUERY $var(Query)"); + + if (sql_xquery("cb", "$var(Query)", "ra") == 1) + { + while($xavp(ra) != $null) { + $var(Username) = $xavp(ra=>username); + $var(Sep2)=""; + $var(Evt)=""; + while($xavp(ra) != $null && $var(Username) == $xavp(ra=>username)) + { + $var(Event) = $xavp(ra=>event); + $var(Sep3)=""; + $var(Sub)=""; + while($xavp(ra) != $null && $var(Username) == $xavp(ra=>username) && $var(Event) == $xavp(ra=>event)) + { + $var(Sub) = $var(Sub) + $_s($var(Sep3)"$xavp(ra=>id)" : {"etag" : "$xavp(ra=>etag)", "body" : "$(xavp(ra=>body){s.escape.common})" }); + $var(Sep3)=", "; + pv_unset("$xavp(ra)"); + } + $var(Evt) = $var(Evt) + $var(Sep2) + $_s("$var(Event)") + " : { " + $var(Sub) + "}"; + $var(Sep2)=", "; + } + $var(Usr) = $_s("$var(Username)") + " : { " + $var(Evt) + " }"; + xlog("L_INFO", "$ci| RESULT \"Subscriptions\" : { $var(Usr) }"); + $var(amqp_payload_request) = '{"Event-Category" : "presence", "Event-Name" : "search_partial_resp", "Msg-ID" : "$(kzE{kz.json,Msg-ID})", "Subscriptions" : { $var(Usr) } }'; + kazoo_publish("targeted", "$var(Queue)", $var(amqp_payload_request)); + } + } + + $var(amqp_payload_request) = '{"Event-Category" : "presence", "Event-Name" : "search_resp", "Msg-ID" : "$(kzE{kz.json,Msg-ID})" }'; + kazoo_publish("targeted", "$var(Queue)", $var(amqp_payload_request)); + +} + +# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab + diff --git a/kamailio/presence_sync-role.cfg b/kamailio/presence_sync-role.cfg new file mode 100644 index 0000000..c6b334f --- /dev/null +++ b/kamailio/presence_sync-role.cfg @@ -0,0 +1,42 @@ +######## Presence sync server module ######## + +####### SQL OPS module ########## +#!ifndef SQLOPS-LOADED +loadmodule "sqlops.so" +modparam("sqlops","sqlcon", "cb=>KAZOO_DB_URL") +#!trydef SQLOPS-LOADED +#!endif + +event_route[kazoo:consumer-event-presence-sync] +{ + xlog("L_INFO", "received SYNC $kzE"); + $var(Queue) = $(kzE{kz.json,Server-ID}); + $var(Now) = $TS; + ######## SEND BACK START ######## + $var(amqp_payload_request) = '{"Event-Category" : "presence", "Event-Name" : "sync", "Action" : "Start" }'; + kazoo_publish("targeted", "$var(Queue)", $var(amqp_payload_request)); + + if (sql_xquery("cb", "select * from active_watchers where expires > $var(Now)", "ra") == 1) + { + while($xavp(ra) != $null) + { + $var(runloop) = 1; + while($xavp(ra) != $null && $var(runloop) < MAX_WHILE_LOOPS ) { + xlog("L_INFO", "[id, presentity, watcher] = [$xavp(ra=>id), $xavp(ra=>presentity_uri), $xavp(ra=>watcher_username)]"); + $var(Expires) = $xavp(ra=>expires) - $var(Now); + xlog("L_INFO", "EXPIRES $var(Expires) , $xavp(ra=>expires) , $var(Now)"); + $var(amqp_payload_request) = '{"Event-Category" : "presence", "Event-Name" : "subscription", "Event-Package" : "$xavp(ra=>event)", "Expires" : $var(Expires), "Server-ID" : "BLF-MY_HOSTNAME" , "Contact" : "$xavp(ra=>contact)", "Call-ID" : "$xavp(ra=>callid)", "From" : "sip:$xavp(ra=>watcher_username)@$xavp(ra=>watcher_domain)", "User" : "$xavp(ra=>presentity_uri)" }"'; + kazoo_publish("targeted", "$var(Queue)", $var(amqp_payload_request)); + pv_unset("$xavp(ra)"); + $var(runloop) = $var(runloop) + 1; + } + } + } + + ######## SEND BACK END ######## + $var(amqp_payload_request) = '{"Event-Category" : "presence", "Event-Name" : "sync", "Action" : "End" }'; + kazoo_publish("targeted", "$var(Queue)", $var(amqp_payload_request)); + +} + +# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab \ No newline at end of file diff --git a/kamailio/pusher-role.cfg b/kamailio/pusher-role.cfg index a414c31..a8a01dc 100644 --- a/kamailio/pusher-role.cfg +++ b/kamailio/pusher-role.cfg @@ -1,36 +1,53 @@ ## PUSHER ROLE -route[INTERNAL_TO_EXTERNAL_PUSH] +####### SQL OPS module ########## +#!ifndef TSILO-LOADED +loadmodule "tsilo.so" +#!trydef TSILO-LOADED +#!endif + +route[PUSHER_ROUTE] { - if (is_method("INVITE") && $hdr(X-KAZOO-PUSHER-Token-ID) != $null) - { - if(!registered("location", "$hdr(X-KAZOO-AOR)")) { - sl_send_reply(180, "waking the dead guy"); - $var(TokenID) = $hdr(X-KAZOO-PUSHER-Token-ID); - $var(TokenType) = $hdr(X-KAZOO-PUSHER-Token-Type); - $var(TokenApp) = $hdr(X-KAZOO-PUSHER-Token-App); - $var(rp) = $hdr(Remote-Party-ID); - $var(from) = $(var(rp){tobody.user}) + " - " + $(var(rp){tobody.display}{s.escape.common}); - $var(Payload) = '{ "Event-Category" : "notification", "Event-Name" : "push_req", "Call-ID" : "$ci", "Token-ID" : "$var(TokenID)", "Token-Type" : "$var(TokenType)", "Token-App" : "$var(TokenApp)", "Alert-Body" : "$var(from)" }'; - $var(RoutingKey) = "notification.push." + $var(TokenType) + "." + $var(TokenID); - $var(exchange) = "pushes"; - $avp(kz_timeout) = 20000; - sl_send_reply("100", "Attempting K query"); - kazoo_query($var(exchange), $var(RoutingKey), $var(Payload)); - } + if ( (!is_method("INVITE")) || (!isflagset(FLAG_INTERNALLY_SOURCED)) || $hdr(X-KAZOO-PUSHER-Token-ID) == $null) + return; + + if(registered("location")) { + return; + } + + xlog("L_INFO", "$ci| pusher received request to wakeup $tu"); + sl_send_reply(180, "waking the dead guy"); + if (t_newtran()) { + route(SEND_PUSH_NOTIFICATION); + t_on_reply("EXTERNAL_REPLY"); + t_set_fr(0, 10000); + remove_hf_re("^X-.*"); + t_save_lumps(); + ts_store(); + t_release(); + } else { + sl_send_reply(500, "error creating transaction for waking the dead guy"); + } + exit; +} - if(registered("location", "$hdr(X-KAZOO-AOR)")) - { - lookup("location", "$hdr(X-KAZOO-AOR)"); - xlog("L_INFO", "$ci|end|routing to $ruid"); - remove_hf_re("^X-.*"); - t_on_reply("EXTERNAL_REPLY"); - t_set_fr(0, 10000); - t_relay(); - } else { - send_reply(480, "No Answer"); - }; - exit; - } +route[SEND_PUSH_NOTIFICATION] +{ + $var(TokenID) = $hdr(X-KAZOO-PUSHER-Token-ID); + $var(TokenType) = $hdr(X-KAZOO-PUSHER-Token-Type); + $var(TokenApp) = $hdr(X-KAZOO-PUSHER-Token-App); + $var(rp) = $hdr(Remote-Party-ID); + $var(from) = $(var(rp){tobody.user}) + " - " + $(var(rp){tobody.display}{s.escape.common}); + $var(Payload) = '{ "Event-Category" : "notification", "Event-Name" : "push_req", "Call-ID" : "$ci", "Token-ID" : "$var(TokenID)", "Token-Type" : "$var(TokenType)", "Token-App" : "$var(TokenApp)", "Alert-Body" : "$var(from)" }'; + $var(RoutingKey) = "notification.push." + $var(TokenType) + "." + $var(TokenID); + $var(exchange) = "pushes"; + kazoo_publish($var(exchange), $var(RoutingKey), $var(Payload)); } +route[PUSHER_ON_REGISTRATION] +{ + if($(xavp(ulattrs=>custom_channel_vars){kz.json,Pusher-Application}{s.len}) > 0 && $var(Status) == "Registered") { + xlog("L_INFO", "$ci| pusher ON_REGISTRATION - $(xavp(ulattrs=>custom_channel_vars){kz.json,Pusher-Application})"); + ts_append("location", "$tu"); + } +} diff --git a/kamailio/registrar-role.cfg b/kamailio/registrar-role.cfg index 3b22e3e..3b95ce8 100644 --- a/kamailio/registrar-role.cfg +++ b/kamailio/registrar-role.cfg @@ -9,13 +9,20 @@ modparam("htable", "htable", "auth_cache=>size=16;autoexpire=7200;") ####### Authentication Interface module ########## loadmodule "auth.so" +#!ifdef OPENBTS_AUTH-ROLE +loadmodule "auth_openbts.so" +modparam("auth", "qop", "") +modparam("auth", "secret", "OPENBTS_AUTH_SECRET") +modparam("auth_openbts", "challenge_attr", "$avp(digest_challenge)") +#!endif + ####### User Location Implementation module ########## loadmodule "usrloc.so" modparam("usrloc", "db_update_as_insert", 0) modparam("usrloc", "use_domain", 1) modparam("usrloc", "nat_bflag", FLB_NATB) -modparam("usrloc", "db_url", "text:///etc/kazoo/kamailio/dbtext") -modparam("usrloc", "db_mode", 0) +modparam("usrloc", "db_url", "KAZOO_DB_URL") +modparam("usrloc", "db_mode", 1) modparam("usrloc", "handle_lost_tcp", 1) modparam("usrloc", "xavp_contact", "ulattrs") modparam("usrloc", "db_check_update", 1) @@ -39,7 +46,13 @@ modparam("registrar", "received_avp", "$avp(AVP_RECV_PARAM)") modparam("registrar", "min_expires", REGISTRAR_MIN_EXPIRES) modparam("registrar", "max_expires", REGISTRAR_MAX_EXPIRES) modparam("registrar", "xavp_cfg", "regcfg") - +modparam("registrar", "gruu_enabled", 1) +modparam("registrar", "outbound_mode", 1) +modparam("registrar", "regid_mode", 1) +modparam("registrar", "path_mode", 1) +modparam("registrar", "use_path", 1) +modparam("registrar", "received_param", "") +modparam("registrar", "xavp_rcd", "ulrcd") ####### Registrar Logic ######## route[HANDLE_REGISTER] @@ -54,50 +67,147 @@ route[HANDLE_REGISTER] } ## KAZOO-1846: Cisco SPA8000 freaks out on options pings - if (!($ua =~ "Linksys/SPA8000")) { + if (!($ua =~ "Linksys/SPA8000" + || $ua =~ "OpenBTS" + || $ua =~ "SIPp" + || (af==INET6) + )) { setbflag(FLB_NATB); setbflag(FLB_NATSIPPING); } #!endif - if (is_present_hf("Authorization")) { - route(ATTEMPT_AUTHORIZATION); - } else { - auth_challenge("$fd", "0"); - xlog("L_INFO", "$ci|end|issued auth challenge to new registration for $fu $si:$sp"); - exit; - } + route(ATTEMPT_AUTHORIZATION); + + } +} + +route[AUTHORIZATION_CHECK] +{ + if (!is_method("MESSAGE|NOTIFY|SUBSCRIBE|PUBLISH")) + return; + + if(has_totag()) + return; + + if (isflagset(FLAG_INTERNALLY_SOURCED)) + return; + + if (isflagset(FLAG_TRUSTED_SOURCE)) + return; + + $xavp(regcfg=>match_received) = $su; + if(!(registered("location", "$fu", 2, 1) == 1 && $(xavp(ulattrs=>custom_channel_vars){s.len}) > 1)) { + xlog("L_INFO", "$ci|log|not authorized $fu from $si:$sp"); + send_reply("500", "Not Registered"); + exit; +# route(ATTEMPT_AUTHORIZATION); } } route[ATTEMPT_AUTHORIZATION] { + + $var(nonce) = $(uuid(g){s.rm,-}); + #!ifdef OPENBTS_AUTH-ROLE + if($ua =~ "OpenBTS" && $sht(auth_cache=>$Au::nonce) != $null ) { + $var(nonce) = $sht(auth_cache=>$Au::nonce); + } + #!endif + $xavp(regcfg=>match_received) = $su; - if ($sht(auth_cache=>$Au) != $null && registered("location", "$rz:$Au", 2, 1) == 1) { - xlog("L_INFO", "$ci|log|authenticating $fu via cached SIP creds"); + if($sht(auth_cache=>$Au) != $null && registered("location", "$rz:$Au", 2, 1) == 1 && $(xavp(ulattrs=>custom_channel_vars){s.len}) > 1) { $var(password) = $sht(auth_cache=>$Au); + route(CHECK_AUTHORIZATION); + } + + if( is_present_hf("Authorization")) { + route(KAZOO_AUTHORIZATION); + } + + #!ifdef OPENBTS_AUTH-ROLE + if($ua =~ "OpenBTS") { + openbts_auth_challenge("$fd", "$var(nonce)"); } else { - $var(amqp_payload_request) = "{'Event-Category' : 'directory' , 'Event-Name' : 'authn_req', 'Method' : 'REGISTER', 'Auth-Realm' : '" + $fd + "', 'Auth-User' : '" + $fU + "', 'From' : '" + $fu + "', 'To' : '" + $tu +"' }"; - $var(amqp_routing_key) = "authn.req." + $(fd{kz.encode}); - sl_send_reply("100", "Attempting K query"); - if(kazoo_query("callmgr", $var(amqp_routing_key), $var(amqp_payload_request))) { - $var(password) = $(kzR{kz.json,Auth-Password}); - $xavp(ulattrs=>custom_channel_vars) = $(kzR{kz.json,Custom-Channel-Vars}); - xlog("L_INFO", "$ci|log|authenticating $Au via Kazoo query response"); - } else { - xlog("L_INFO", "$ci|log|failed to query Kazoo for authentication credentials for $Au $si:$sp"); - append_to_reply("Retry-After: 60\r\n"); - sl_send_reply("500", "Retry Later"); + #!endif + auth_challenge("$fd", "0"); + #!ifdef OPENBTS_AUTH-ROLE + } + #!endif + xlog("L_INFO", "$ci|end|issued auth challenge to new registration for $fu $si:$sp"); + exit; +} + + +route[KAZOO_AUTHORIZATION] +{ + $var(nonce) = $adn; + $var(amqp_payload_request) = '{"Event-Category" : "directory" , "Event-Name" : "authn_req", "Method" : "REGISTER", "Auth-Nonce" : "$adn", "Auth-Realm" : "$fd", "Auth-User" : "$fU", "From" : "$fu", "To" : "$tu" }'; + $var(amqp_routing_key) = "authn.req." + $(fd{kz.encode}); + $avp(kz_timeout) = 2500; + if (!t_newtran()) { + sl_reply_error(); + exit(); + } + if(kazoo_async_query("callmgr", $var(amqp_routing_key), $var(amqp_payload_request), "KAZOO_AUTHORIZATION_OK", "KAZOO_AUTHORIZATION_ERROR") != 1) { + xlog("L_INFO", "$ci|log|failed to send Kazoo query for authentication credentials for $Au $si:$sp"); + append_to_reply("Retry-After: 60\r\n"); + send_reply("500", "Retry Later"); + exit; + } +} + +route[KAZOO_AUTHORIZATION_OK] +{ + $var(password) = $(kzR{kz.json,Auth-Password}); + $var(nonce) = $adn; + #!ifdef OPENBTS_AUTH-ROLE + if( $(kzR{kz.json,Auth-Nonce}) != "" && $var(nonce) != $(kzR{kz.json,Auth-Nonce})) { + xlog("L_INFO", "$ci|log|nonce replace $var(nonce) with $(kzR{kz.json,Auth-Nonce})"); + $var(nonce) = $(kzR{kz.json,Auth-Nonce}); + $sht(auth_cache=>$Au::nonce) = $var(nonce); + } + #!endif + $xavp(ulattrs=>custom_channel_vars) = $(kzR{kz.json,Custom-Channel-Vars}); + xlog("L_INFO", "$ci|log|authenticating $Au via Kazoo query response"); + route(CHECK_AUTHORIZATION); +} + +route[KAZOO_AUTHORIZATION_ERROR] +{ + xlog("L_INFO", "$ci|log|failed to query Kazoo for authentication credentials for $Au $si:$sp"); + append_to_reply("Retry-After: 60\r\n"); + send_reply("500", "Retry Later"); + exit; +} + +route[CHECK_AUTHORIZATION] +{ + + #!ifdef OPENBTS_AUTH-ROLE + if($ua =~ "OpenBTS") { + if($var(password) == $null) { + openbts_auth_challenge("$fd", "$var(nonce)"); + xlog("L_INFO", "$ci|end|issued auth challenge to registration attempt for $Au $si:$sp"); exit; } - } + if (!openbts_auth_check("$fd", "$var(password)")) { + #!ifdef ANTIFLOOD-ROLE + route(ANITFLOOD_FAILED_AUTH); + #!endif + openbts_auth_challenge("$fd", "$var(nonce)"); + xlog("L_INFO", "$ci|end|issued auth challenge to failed registration attempt for $Au $si:$sp"); + exit; + } + } else { + #!endif if($var(password) == $null) { auth_challenge("$fd", "0"); xlog("L_INFO", "$ci|end|issued auth challenge to registration attempt for $Au $si:$sp"); exit; } - + if (!pv_auth_check("$fd", "$var(password)", "0", "0")) { #!ifdef ANTIFLOOD-ROLE route(ANITFLOOD_FAILED_AUTH); @@ -108,6 +218,12 @@ route[ATTEMPT_AUTHORIZATION] exit; } + #!ifdef OPENBTS_AUTH-ROLE + } + #!endif + + + #!ifdef ANTIFLOOD-ROLE route(ANTIFLOOD_SUCCESSFUL_AUTH); #!endif @@ -115,12 +231,21 @@ route[ATTEMPT_AUTHORIZATION] if ($sht(auth_cache=>$Au) == $null) { xlog("L_INFO", "$ci|log|caching SIP credentials for $Au"); $sht(auth_cache=>$Au) = $var(password); + #!ifdef OPENBTS_AUTH-ROLE + if($ua =~ "OpenBTS") { + $sht(auth_cache=>$Au::nonce) = $var(nonce); + } + #!endif } # user authenticated - remove auth header consume_credentials(); + route(SAVE_LOCATION); +} - $var(save_result) = save("location", "0x04"); +route[SAVE_LOCATION] +{ + $var(save_result) = save("location"); if($var(save_result) == -1) { auth_challenge("$fd", "0"); xlog("L_INFO", "$ci|end|issued auth challenge after failed attempt to save contact for $Au $si:$sp"); @@ -144,52 +269,32 @@ route[ATTEMPT_AUTHORIZATION] } if($var(expires) == 0) { - xlog("L_INFO", "$ci|end|unregister request from $Au $si:$sp"); - exit; - } else if($var(expires) < REGISTRAR_MIN_EXPIRES) { - $var(expires) = REGISTRAR_MIN_EXPIRES; - } else if($var(expires) > REGISTRAR_MAX_EXPIRES) { - $var(expires) = REGISTRAR_MAX_EXPIRES; - } - - ## Fix for wss websockets. - ## RFC 7118 says transport MUST be "ws" not "wss" - ## http://tools.ietf.org/html/rfc7118#section-5.2 - if ($(proto{s.tolower}) == 'wss') { - $var(transport) = "ws"; + xlog("L_INFO", "$ci|end|unregister request from $Au $si:$sp"); + $var(Status) = "Unregistered"; } else { - $var(transport) = $(proto{s.tolower}); + $var(Status) = "Registered"; + if($var(Expires) < REGISTRAR_MIN_EXPIRES) { + $var(Expires) = REGISTRAR_MIN_EXPIRES; + } else if($var(Expires) > REGISTRAR_MAX_EXPIRES) { + $var(Expires) = REGISTRAR_MAX_EXPIRES; + } } - if($var(transport) == "udp" ||$var(transport) == "tcp" || $var(transport) == "tls") { - $var(return_port) = $Rp; - } else { - $var(return_port) = "5060"; + $var(ip) = $Ri; + if(af==INET6) { + $var(ip) = "[" + $Ri + "]"; } - $var(params) = "fs_path="; - - ## TODO: fix escaping, some phones send us -- reg-id=1;+sip.instance="urn:uuid:9b8bd513-0e6e-4660-ad5e-5e35d88cc68f"; - ## and if we can store it but not use it because it looses the escapes (that weren't there...) - #if($(ct{tobody.params}) != $null) { - # $var(params) = $(ct{tobody.params}{s.escape.common}) + ";" + $var(params); - #} - - if ($avp(AVP_RECV_PARAM) == $null) { - $var(fs_contact) = "<" + $(ct{tobody.uri}) + ";" + $var(params) + ">"; - } else { - $var(fs_contact) = ""; - } - - $var(register_contants) = ' "Presence-Hosts" : "n/a", "Profile-Name" : "sipinterface_1", "Status" : "Registered", "Event-Timestamp" : "' + $TS + '", "Expires" : ' + $var(expires); - - $var(amqp_payload_request) = '{"Event-Category" : "directory", "Event-Name" : "reg_success", "First-Registration" : $var(new_reg), "Contact" : "$var(fs_contact)", "Call-ID" : "$ci", "Realm" : "$fd", "Username" : "$fU", "From-User" : "$fU", "From-Host" : "$fd", "To-User" : "$tU", "To-Host" : "$td", "User-Agent" : "$ua" , "Custom-Channel-Vars" : $xavp(ulattrs=>custom_channel_vars), $var(register_contants) }'; - + $var(amqp_payload_request) = '{"Event-Category" : "directory", "Event-Name" : "reg_success", "Status" : "$var(Status)", "Event-Timestamp" : $TS, "Expires" : $(var(expires){s.int}), "First-Registration" : $var(new_reg), "Contact" : "$(ct{s.escape.common})", "Call-ID" : "$ci", "Realm" : "$fd", "Username" : "$fU", "From-User" : "$fU", "From-Host" : "$fd", "To-User" : "$tU", "To-Host" : "$td", "User-Agent" : "$(ua{s.escape.common})" , "Custom-Channel-Vars" : $xavp(ulattrs=>custom_channel_vars), "Proxy-Path" : "sip:$var(ip)", "RUID" : "$xavp(ulrcd=>ruid)" }'; $var(amqp_routing_key) = "registration.success." + $(fd{kz.encode}) + "." + $(fU{kz.encode}); - kazoo_publish("registrar", $var(amqp_routing_key), $var(amqp_payload_request)); - xlog("L_INFO", "$ci|end|successful registration with contact $var(fs_contact)"); + xlog("L_INFO", "$ci|end|successful $(var(Status){s.tolower}) with contact $ct"); + + #!ifdef PUSHER-ROLE + route(PUSHER_ON_REGISTRATION); + #!endif + exit; } @@ -206,7 +311,6 @@ event_route[kazoo:consumer-event-directory-reg-flush] #!ifdef ANTIFLOOD-ROLE route(ANTIFLOOD_RESET_AUTH); #!endif - } # vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/registrar-sync-role.cfg b/kamailio/registrar-sync-role.cfg index de3b04b..cbac62e 100644 --- a/kamailio/registrar-sync-role.cfg +++ b/kamailio/registrar-sync-role.cfg @@ -3,7 +3,7 @@ ####### SQL OPS module ########## #!ifndef SQLOPS-LOADED loadmodule "sqlops.so" -modparam("sqlops","sqlcon", KAZOO_SQLOPS_DB_URL) +modparam("sqlops","sqlcon", "cb=>KAZOO_DB_URL") #!trydef SQLOPS-LOADED #!endif @@ -12,11 +12,11 @@ event_route[kazoo:consumer-event-directory-reg-sync] $var(Server) = $(kzE{kz.json,Server-ID}); xlog("L_INFO", "received registrar sync from $var(Server) : $kzE"); - if (sql_xquery("cb", "location", "ra") == 1) + if (sql_xquery("cb", "select * from location", "ra") == 1) { while($xavp(ra) != $null) { $var(runloop) = 1; - while($xavp(ra) != $null && $var(runloop) < 500 ) { + while($xavp(ra) != $null && $var(runloop) < MAX_WHILE_LOOPS ) { if(registered("location", "sip:$xavp(ra=>username)@$xavp(ra=>domain)", 0, 1)) { xlog("L_INFO", "[id, username, domain] = [$xavp(ra=>id), $xavp(ra=>username), $xavp(ra=>domain)]"); $var(Expires) = $xavp(ra=>expires) - $TS; @@ -30,8 +30,3 @@ event_route[kazoo:consumer-event-directory-reg-sync] } } - - -# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab - - diff --git a/kamailio/websockets-role.cfg b/kamailio/websockets-role.cfg index fa43ea3..a3801a4 100644 --- a/kamailio/websockets-role.cfg +++ b/kamailio/websockets-role.cfg @@ -14,7 +14,7 @@ loadmodule "nathelper.so" #!endif ######## Generic Hash Table container in shared memory ######## -modparam("htable", "htable", "websockets=>size=16;autoexpire=7200") +modparam("htable", "htable", "websockets=>size=16;autoexpire=7200;initval=0") ######## Basic HTTP request handling ######## loadmodule "xhttp.so" @@ -99,20 +99,14 @@ event_route[xhttp:request] } #!endif - if($sht(websockets=>$si::count) == $null) { - $var(count) = 1; - } else { - $var(count) = $sht(websockets=>$si::count) + 1; - } - - if($var(count) > 50) { + if($sht(websockets=>$si::count) > 50) { xlog("L_WARN", "websocket|log|$si:$sp is at the maximum allowable sockets per IP, rejecting request for another websocket\n"); xhttp_reply("403", "Forbidden", "", ""); exit; } if (ws_handle_handshake()) { - $sht(websockets=>$si::count) = $var(count); + $shtinc(websockets=>$si::count); xlog("L_INFO", "websocket|log|opened websocket $var(count) of 50 for $si:$sp\n"); exit; } @@ -122,18 +116,11 @@ event_route[xhttp:request] } event_route[websocket:closed] { - if($sht(websockets=>$si::count) == $null) { - xlog("L_INFO", "websocket|log|closed websocket from $si:$sp\n"); - exit(); - } - - $var(count) = $sht(websockets=>$si::count) - 1; - - if ($var(count) < 1) { + $shtdec(websockets=>$si::count); + if ($sht(websockets=>$si::count) < 1) { xlog("L_INFO", "websocket|log|$si:$sp closed last websocket to that IP\n"); - $sht(websockets=>$si::count) = $null; + sht_rm_name_re(websockets=>$(si{re.subst,/\\./\\\\./g})::.*); } else { - $sht(websockets=>$si::count) = $var(count); xlog("L_INFO", "websocket|log|closed websocket from $si:$sp, $var(count) remaining from that IP\n"); } }