You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

121 lines
3.9 KiB

tcp_accept_no_cl=yes
listen=TCP_WS
#!ifdef TLS_ROLE
listen=TLS_WSS
#!endif
######## NAT Traversal module - signaling functions ########
#!ifndef NATHELPER_LOADED
#!trydef NATHELPER_LOADED
loadmodule "nathelper.so"
#!endif
######## Generic Hash Table container in shared memory ########
modparam("htable", "htable", "websockets=>size=16;initval=0")
######## Basic HTTP request handling ########
loadmodule "xhttp.so"
#!trydef WS_KEEPALIVE_MECHANISM 1
#!trydef WS_KEEPALIVE_TIMEOUT 30
#!trydef WS_KEEPALIVE_PROCESSES 3
#!trydef WS_KEEPALIVE_INTERVAL 1
#!trydef WS_KEEPALIVE_DATA "Kazoo encourages you to keep alive"
#!trydef WS_MAX_CONNECTIONS_PER_IP 50
######## Websocket module ########
loadmodule "websocket.so"
modparam("websocket", "keepalive_mechanism", WS_KEEPALIVE_MECHANISM)
modparam("websocket", "keepalive_timeout", WS_KEEPALIVE_TIMEOUT)
modparam("websocket", "keepalive_processes", WS_KEEPALIVE_PROCESSES)
modparam("websocket", "keepalive_interval", WS_KEEPALIVE_INTERVAL)
modparam("websocket", "ping_application_data", WS_KEEPALIVE_DATA)
modparam("websocket", "sub_protocols", 1)
####### Websocket Logic ########
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.
return();
}
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.
return();
}
event_route[xhttp:request]
{
set_reply_close();
set_reply_no_connect();
if (!($rm =~ "GET")) {
xlog("L_INFO", "websocket|log|rejecting HTTP request $rm from $si:$sp\n");
xhttp_reply("405", "Method Not Allowed", "", "");
exit;
}
if (!($hdr(Connection) =~ "Upgrade")) {
xlog("L_INFO", "websocket|log|rejecting HTTP connection $hdr(Connection) request from $si:$sp\n");
xhttp_reply("400", "Bad Request", "", "");
exit;
}
if (!($hdr(Upgrade) =~ "websocket")) {
xlog("L_INFO", "websocket|log|rejecting HTTP upgrade $hdr(Upgrade) request from $si:$sp\n");
xhttp_reply("400", "Bad Request", "", "");
exit;
}
if (!($hdr(Sec-WebSocket-Protocol) =~ "sip")) {
xlog("L_INFO", "websocket|log|rejecting request for websocket protocol $hdr(Sec-WebSocket-Protocol) from $si:$sp\n");
xhttp_reply("400", "Bad Request", "", "");
exit;
}
#!ifdef MY_WEBSOCKET_DOMAIN
if (!($hdr(Origin) =~ "MY_WEBSOCKET_DOMAIN")) {
xlog("L_INFO", "websocket|log|rejecting HTTP request with unauthorized origin $hdr(Origin) from $si:$sp, allowed origin is MY_WEBSOCKET_DOMAIN\n");
xhttp_reply("400", "Bad Request", "", "");
exit;
}
#!endif
if($sht(websockets=>$si::count) > WS_MAX_CONNECTIONS_PER_IP) {
xlog("L_WARN", "websocket|log|$si:$sp is at the maximum $def(WS_MAX_CONNECTIONS_PER_IP) allowable sockets per IP, rejecting request for another websocket\n");
xhttp_reply("403", "Forbidden", "", "");
exit;
}
if (ws_handle_handshake()) {
$var(count) = $shtinc(websockets=>$si::count);
xlog("L_INFO", "websocket|log|opened websocket $var(count) of $def(WS_MAX_CONNECTIONS_PER_IP) for $si:$sp\n");
exit;
}
xlog("L_INFO", "websocket|log|unhandled HTTP request $rm from $si:$sp\n");
xhttp_reply("404", "Not Found", "", "");
}
event_route[websocket:closed] {
$var(count) = $shtdec(websockets=>$si::count);
if ($var(count) < 1) {
xlog("L_INFO", "websocket|log|$si:$sp closed last websocket to that IP\n");
$sht(websockets=>$si::count) = $null;
} else {
xlog("L_INFO", "websocket|log|closed websocket from $si:$sp, $var(count) remaining from that IP\n");
}
}