From 38aa1e5c1f04829fa30ec269503ed864070018f9 Mon Sep 17 00:00:00 2001 From: karl anderson Date: Tue, 25 Mar 2014 14:01:32 -0400 Subject: [PATCH] added websockets role and fix double AMQP binding if the example config.ini is used --- config.ini | 28 +++++++------ kamailio/default.cfg | 64 +++++++++++++++++------------- kamailio/dispatcher-role.cfg | 10 ++--- kamailio/local.cfg | 6 ++- kamailio/roles.cfg | 1 + kamailio/websockets-role.cfg | 77 ++++++++++++++++++++++++++++++++++++ rabbitmq/rabbitmq.config | 4 +- 7 files changed, 142 insertions(+), 48 deletions(-) create mode 100644 kamailio/websockets-role.cfg diff --git a/config.ini b/config.ini index 298cbcd..c052afa 100644 --- a/config.ini +++ b/config.ini @@ -11,8 +11,8 @@ compact_automatically = true cookie = change_me ip = "127.0.0.1" port = 15984 -; username = "kazoo" -; password = "supermegaexcellenttelephonyplatform" +;username = "kazoo" +;password = "supermegaexcellenttelephonyplatform" admin_port = 15986 ; Define your AMQPs and zones here @@ -20,29 +20,31 @@ admin_port = 15986 name = zone_1 amqp_uri = "amqp://guest:guest@127.0.0.1:5672" -[zone] -name = zone_2 -amqp_uri = "amqp://guest:guest@127.0.0.2:5672" +;[zone] +;name = zone_2 +;amqp_uri = "amqp://guest:guest@127.0.0.2:5672" ; Define your whistles here [whistle_apps] +;host = apps001.2600hz.com zone = zone_1 cookie = change_me -[whistle_apps] -host = apps002.2600hz.com -zone = zone_2 -cookie = change_me +;[whistle_apps] +;host = apps002.2600hz.com +;zone = zone_2 +;cookie = change_me ; Define your ecallmgr's here [ecallmgr] +;host = apps001.2600hz.com zone = zone_1 cookie = change_me -[ecallmgr] -host = apps002.2600hz.com -zone = zone_2 -cookie = change_me +;[ecallmgr] +;host = apps002.2600hz.com +;zone = zone_2 +;cookie = change_me [log] syslog = debug diff --git a/kamailio/default.cfg b/kamailio/default.cfg index 0d5ca9a..ea7f28d 100644 --- a/kamailio/default.cfg +++ b/kamailio/default.cfg @@ -98,9 +98,6 @@ dns_try_naptr = no use_dns_failover = off dns_srv_lb = off -####### TLS Parameters ######### -enable_tls = yes - ####### SCTP Parameters ######### disable_sctp = yes @@ -130,7 +127,7 @@ loadmodule "sl.so" ######## Record-Route and Route module ######## loadmodule "rr.so" modparam("rr", "enable_full_lr", 1) -modparam("rr", "enable_double_rr", 0) +modparam("rr", "enable_double_rr", 1) ######## Max-Forward processor module ######## loadmodule "maxfwd.so" @@ -185,6 +182,9 @@ include_file "presence-role.cfg" #!ifdef NAT-TRAVERSAL-ROLE include_file "nat-traversal-role.cfg" #!endif +#!ifdef WEBSOCKETS-ROLE +include_file "websockets-role.cfg" +#!endif ####### Kazoo Integration module ########## #!ifdef INCLUDE-DB-KAZOO @@ -221,6 +221,10 @@ route route(DOS_PREVENTION); #!endif + #!ifdef WEBSOCKETS-ROLE + route(HANDLE_WEBSOCKETS); + #!endif + route(HANDLE_OPTIONS); route(HANDLE_NOTIFY); @@ -254,7 +258,7 @@ route route(EXTERNAL_TO_INTERNAL_RELAY); } -route[SANITY_CHECK] +route[SANITY_CHECK] { if (!mf_process_maxfwd_header("10")) { xlog("L_WARN", "$ci|end|too much hops, not enough barley"); @@ -262,12 +266,6 @@ route[SANITY_CHECK] exit; } - if ( msg:len > 6144 ) { - xlog("L_WARN", "$ci|end|message too large"); - send_reply("513", "Message too large"); - exit; - } - if (!sanity_check()) { xlog("L_WARN", "$ci|end|message is insane"); exit; @@ -281,7 +279,7 @@ route[SANITY_CHECK] } } -route[HANDLE_OPTIONS] +route[HANDLE_OPTIONS] { if (is_method("OPTIONS")) { if (isflagset(FLAG_INTERNALLY_SOURCED)) { @@ -298,7 +296,7 @@ route[HANDLE_OPTIONS] } } -route[HANDLE_NOTIFY] +route[HANDLE_NOTIFY] { if (is_method("NOTIFY")) { if (isflagset(FLAG_INTERNALLY_SOURCED)) { @@ -344,13 +342,18 @@ route[HANDLE_MOVE_REQUEST] } } -route[HANDLE_IN_DIALOG_REQUESTS] +route[HANDLE_IN_DIALOG_REQUESTS] { if (has_totag()) { if (is_method("INVITE")) { record_route(); } if (loose_route()) { + if (isdsturiset() && !handle_ruri_alias()) { + xlog("L_INFO", "$ci|stop|Bad alias <$ru>\n"); + sl_send_reply("400", "Bad Request"); + exit; + } 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, @@ -374,7 +377,7 @@ route[HANDLE_IN_DIALOG_REQUESTS] } } -route[PREPARE_INITIAL_REQUESTS] +route[PREPARE_INITIAL_REQUESTS] { if (is_method("CANCEL")) { if (t_check_trans()) { @@ -403,7 +406,7 @@ route[PREPARE_INITIAL_REQUESTS] } } -route[RELAY] +route[RELAY] { if (isflagset(FLAG_INTERNALLY_SOURCED)) { route(INTERNAL_TO_EXTERNAL_RELAY); @@ -414,7 +417,7 @@ route[RELAY] exit(); } -route[INTERNAL_TO_EXTERNAL_RELAY] +route[INTERNAL_TO_EXTERNAL_RELAY] { remove_hf_re("X-.*"); @@ -425,7 +428,7 @@ route[INTERNAL_TO_EXTERNAL_RELAY] t_relay(); } -route[EXTERNAL_TO_INTERNAL_RELAY] +route[EXTERNAL_TO_INTERNAL_RELAY] { #!ifdef NAT-TRAVERSAL-ROLE if (!isflagset(FLAG_INTERNALLY_SOURCED)) { @@ -454,14 +457,14 @@ route[DOS_PREVENTION] } # drop requests with no To domain or IP To domain (friendly-scanner) - if (is_method("REGISTER|SUBSCRIBE|OPTIONS") && + if (is_method("REGISTER|SUBSCRIBE|OPTIONS") && ($td == $null || $td=~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}")) { xlog("L_WARN", "$ci|log|dropping request with IP domain in To header"); exit; } # drop Invite with IP auth realm - if (is_method("INVITE") && is_present_hf("Proxy-Authorization") && + if (is_method("INVITE") && is_present_hf("Proxy-Authorization") && $ar =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}" ) { xlog("L_WARN", "$ci|log|dropping request with IP domain in Proxy-Authorization header"); exit; @@ -477,10 +480,14 @@ route[DOS_PREVENTION] } } -onreply_route[EXTERNAL_REPLY] +onreply_route[EXTERNAL_REPLY] { xlog("L_INFO", "$ci|log|external reply $T_reply_code"); + #!ifdef WEBSOCKETS-ROLE + route(NAT_WEBSOCKETS_CORRECT); + #!endif + #!ifdef NAT-TRAVERSAL-ROLE route(NAT_TEST_AND_CORRECT); #!endif @@ -492,11 +499,15 @@ onreply_route[INTERNAL_REPLY] xlog("L_INFO", "$ci|start|recieved internal reply $T_reply_code $rr"); xlog("L_INFO", "$ci|log|source $si:$sp"); + #!ifdef WEBSOCKETS-ROLE + route(NAT_WEBSOCKETS_CORRECT); + #!endif + if (is_method("INVITE") && !isflagset(FLAG_SESSION_PROGRESS) && t_check_status("(180)|(183)|(200)") ) { - if ($avp(AVP_REDIRECT_KEY) != $null && + 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)"); @@ -513,8 +524,7 @@ onreply_route[INTERNAL_REPLY] $var(reply_reason) = $rr; } - -failure_route[INTERNAL_FAULT] +failure_route[INTERNAL_FAULT] { # this branch handles failures (>=300) to our media servers, # which we can sometimes overcome by routing to another server @@ -529,7 +539,7 @@ failure_route[INTERNAL_FAULT] # Handle redirects if (t_check_status("302")) { - $var(redirect) = @from.uri.user + "@" + @from.uri.host + "->" + $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)); @@ -564,11 +574,11 @@ failure_route[INTERNAL_FAULT] 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"); - + #!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"); diff --git a/kamailio/dispatcher-role.cfg b/kamailio/dispatcher-role.cfg index a91788e..57423df 100644 --- a/kamailio/dispatcher-role.cfg +++ b/kamailio/dispatcher-role.cfg @@ -78,7 +78,7 @@ route[DISPATCHER_FIND_ROUTES] sl_send_reply("480", "All servers busy"); exit; } - } + } $var(contact_uri) = $(ct{tobody.user}) + "@" + $(ct{tobody.host}); $var(redirect) = @from.uri.user + "@" + @from.uri.host + "->" @@ -98,7 +98,7 @@ route[DISPATCHER_FIND_ROUTES] } } -route[DISPATCHER_REORDER_ROUTES] +route[DISPATCHER_REORDER_ROUTES] { $var(i) = 0; $var(found) = 0; @@ -111,7 +111,7 @@ route[DISPATCHER_REORDER_ROUTES] $var(i) = $var(i) + 1; } - + if (!$var(found) && $var(ds_group) == 1 && ds_select_dst("2", "0")) { $var(i) = 0; while($(avp(ds_dst)[$var(i)]) != $null) { @@ -121,9 +121,9 @@ route[DISPATCHER_REORDER_ROUTES] break; } $var(i) = $var(i) + 1; - } + } } - + if ($var(found)) { xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to maintain association with $var(prefered_route)"); diff --git a/kamailio/local.cfg b/kamailio/local.cfg index 243c07c..adfba55 100644 --- a/kamailio/local.cfg +++ b/kamailio/local.cfg @@ -6,7 +6,7 @@ debug = L_INFO ####### UDP Parameters ######### ## NOTE: You must MATCH this to your network adapter!! -## If they do not match, all UDP packets over +## 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 @@ -17,6 +17,10 @@ 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 +#!ifdef WEBSOCKETS-ROLE +listen = udp:127.0.0.1:8080 +listen = tcp:127.0.0.1:8080 +#!endif ####### Dispatcher module ######## #!ifdef DISPATCHER-ROLE diff --git a/kamailio/roles.cfg b/kamailio/roles.cfg index a073084..c0fa138 100644 --- a/kamailio/roles.cfg +++ b/kamailio/roles.cfg @@ -4,5 +4,6 @@ #!trydef REGISTRAR-ROLE #!trydef PRESENCE-ROLE # # #!trydef TRAFFIC-FILTER-ROLE +# # #!trydef WEBSOCKETS-ROLE ## vim:set tabstop=4 softtabstop=4 shiftwidth=4 expandtab diff --git a/kamailio/websockets-role.cfg b/kamailio/websockets-role.cfg new file mode 100644 index 0000000..2a0ad5c --- /dev/null +++ b/kamailio/websockets-role.cfg @@ -0,0 +1,77 @@ +######## Websocket module ######## +tcp_accept_no_cl=yes + +######## Basic HTTP request handling ######## +loadmodule "xhttp.so" + +######## Websocket module ######## +loadmodule "websocket.so" +modparam("websocket", "keepalive_mechanism", 1) +modparam("websocket", "keepalive_timeout", 30) +modparam("websocket", "keepalive_processes", 1) +modparam("websocket", "keepalive_interval", 1) +modparam("websocket", "ping_application_data", "Kazoo encourages you to keep alive") +modparam("websocket", "sub_protocols", 1) + +route[HANDLE_WEBSOCKETS] +{ + # Do NAT traversal stuff for requests from a WebSocket + # connection - even if it is not behind a NAT! + # This won't be needed in the future if Kamailio and the + # WebSocket client support Outbound and Path. + if (nat_uac_test(64)) { + xlog("L_INFO", "$ci|log|this is a websocket request\n"); + force_rport(); + if (is_method("REGISTER")) { + fix_nated_register(); + } else { + if (!add_contact_alias()) { + xlog("L_INFO", "$ci|stop|error aliasing contact <$ct>\n"); + sl_send_reply("400", "Bad Request"); + exit; + } + } + } +} + +route[NAT_WEBSOCKETS_CORRECT] +{ + # Do NAT traversal stuff for replies to a WebSocket connection + # - even if it is not behind a NAT! + # This won't be needed in the future if Kamailio and the + # WebSocket client support Outbound and Path. + if (nat_uac_test(64)) { + xlog("L_INFO", "$ci|log|this is a websocket request\n"); + add_contact_alias(); + } +} + +event_route[xhttp:request] +{ + xlog("L_INFO", "HTTP Request Received\n"); + set_reply_close(); + set_reply_no_connect(); + + if ($hdr(Upgrade) =~ "websocket" && $hdr(Connection) =~ "Upgrade" && $rm =~ "GET") { + xlog("L_INFO", "websocket request from $si:$sp received\n"); + + # Validate Host - make sure the client is using the correct + # alias for WebSockets + if ($hdr(Host) == $null || !is_myself("sip:" + $hdr(Host))) { + xlog("L_WARN", "websocket request had bad host $hdr(Host)\n"); + xhttp_reply("403", "Forbidden", "", ""); + exit; + } + + # ws_handle_handshake() exits (no further configuration file + # processing of the request) when complete. + if (ws_handle_handshake()) { + exit; + } + } + xhttp_reply("404", "Not Found", "", ""); +} + +event_route[websocket:closed] { + xlog("L_INFO", "websocket connection from $si:$sp has closed\n"); +} diff --git a/rabbitmq/rabbitmq.config b/rabbitmq/rabbitmq.config index b264553..e7fb61b 100644 --- a/rabbitmq/rabbitmq.config +++ b/rabbitmq/rabbitmq.config @@ -1,5 +1,5 @@ -[ -{rabbit, [{disk_free_limit, 5242880} +[{rabbit, [{disk_free_limit, 5242880} ,{vm_memory_high_watermark, 0.8} + ,{hipe_compile, true} ]} ].