WebRTC сокеты Kamailio и FreeSwitch

Опубликовано в Kamailio

WebRTC

В этом мануале попробуем дать описание, как добавить поддержку 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)
  &amp;&amp; !(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
     &amp;&amp; $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"
   &amp;&amp; $hdr(Connection)=~"Upgrade"
   &amp;&amp; $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"
  #     &amp;&amp; $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.

Коментарии: