WebRTC сокеты Kamailio и FreeSwitch
В этом мануале попробуем дать описание, как добавить поддержку WebSocket для нашего высокопроизводительного SIP сервера – Kamailio. Будем считать что у нас SER router (Kamailio) уже установлен и функционирует.
Редактируем наш файл конфигурации kamailio.cfg, у меня он расположен в /usr/local/etc/kamailio. В разделе Defined Values добавляем строки:
#!substdef "!MY_IP_ADDR!<SERVER_IP>!g" #!substdef "!MY_DOMAIN!<SERVER_IP>!g" #!substdef "!MY_WS_PORT!8080!g" #!substdef "!MY_WSS_PORT!4443!g" #!substdef "!MY_WS_ADDR!tcp:MY_IP_ADDR:MY_WS_PORT!g" #!substdef "!MY_WSS_ADDR!tls:MY_IP_ADDR:MY_WSS_PORT!g" #!define WITH_WEBSOCKETS
Где мы должны вписать наши значения:
<SERVER_IP> : IP-адрес вашего сервера (#!substdef "!MY_IP_ADDR!192.168.1.13!g")
MY_WS_PORT : порт, на котором kamailio будет прослушивает ws соединений (по умолчанию: 8080 )
В разделе global parameters добавить строки:
listen=MY_IP_ADDR #!ifdef WITH_WEBSOCKETS listen=MY_WS_ADDR #!ifdef WITH_TLS listen=MY_WSS_ADDR #!endif #!endif tcp_connection_lifetime=3604 tcp_accept_no_cl=yes tcp_rd_buf_size=16384 And comment line: #tcp_connection_lifetime=3605
В разделе Modules Section загружаем необходимые модули для работы websocket:
#!ifdef WITH_WEBSOCKETS loadmodule "xhttp.so" loadmodule "websocket.so" loadmodule "nathelper.so" #!endif
В разделе setting module-specific parameters (настройка конкретных параметров модулей) мы добавим:
#!ifdef WITH_WEBSOCKETS # ----- nathelper params ----- modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)") # Note: leaving NAT pings turned off here as nathelper is _only_ being used for # WebSocket connections. NAT pings are not needed as WebSockets have # their own keep-alives. #!endif
В разделе маршрутизации логики routing-logic в блоке request_route мы добавляем строки вроде этих:
request_route { # per request initial checks route(REQINIT); #!ifdef WITH_WEBSOCKETS if (nat_uac_test(64)) { # 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 <a href="http://voiplab.by/wiki/kamailio-openser/27-kamailio-sip-router" >Kamailio</a> and the # WebSocket client support Outbound and Path. force_rport(); if (is_method("REGISTER")) { fix_nated_register(); } else { fix_nated_contact(); if (!add_contact_alias()) { xlog("L_ERR", "Error aliasing contact <$ct>\n"); sl_send_reply("400", "Bad Request"); exit; } } } #!endif
Мы добавим несколько строк в маршрут route[WITHINDLG] и должен получиться следующим образом:
route[WITHINDLG] { if (has_totag()) { # sequential request withing a dialog should # take the path determined by record-routing if (loose_route()) { #!ifdef WITH_WEBSOCKETS if ($du == "") { if (!handle_ruri_alias()) { xlog("L_ERR", "Bad alias <$ru>\n"); sl_send_reply("400", "Bad Request"); exit; } } #!endif
В конце конфигурационного файла, мы добавляем:
#!ifdef WITH_WEBSOCKETS onreply_route { if ((($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS))) { xlog("L_WARN", "SIP response received on $Rp\n"); drop; exit; } if (nat_uac_test(64)) { # 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 <a href="http://voiplab.by/wiki/kamailio-openser/27-kamailio-sip-router" >Kamailio</a> and the # WebSocket client support Outbound and Path. add_contact_alias(); } } event_route[xhttp:request] { set_reply_close(); set_reply_no_connect(); if ($Rp != MY_WS_PORT #!ifdef WITH_TLS && $Rp != MY_WSS_PORT #!endif ) { xlog("L_WARN", "HTTP request received on $Rp\n"); xhttp_reply("403", "Forbidden", "", ""); exit; } xlog("L_DBG", "HTTP Request Received\n"); if ($hdr(Upgrade)=~"websocket" && $hdr(Connection)=~"Upgrade" && $rm=~"GET") { # 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", "Bad host $hdr(Host)\n"); xhttp_reply("403", "Forbidden", "", ""); exit; } # Optional... validate Origin - make sure the client is from an # authorised website. For example, # # if ($hdr(Origin) != "http://communicator.MY_DOMAIN" # && $hdr(Origin) != "https://communicator.MY_DOMAIN") { # xlog("L_WARN", "Unauthorised client $hdr(Origin)\n"); # xhttp_reply("403", "Forbidden", "", ""); # exit; # } # Optional... perform HTTP authentication # ws_handle_handshake() exits (no further configuration file # processing of the request) when complete. if (ws_handle_handshake()) { # Optional... cache some information about the # successful connection exit; } } xhttp_reply("404", "Not Found", "", ""); } event_route[websocket:closed] { xlog("L_INFO", "WebSocket connection from $si:$sp has closed\n"); } #!endif
Сохраняем конфиг и рестартуем наш Kamailio.
Коментарии: