{"id":624,"date":"2014-06-04T11:08:33","date_gmt":"2014-06-04T09:08:33","guid":{"rendered":""},"modified":"2018-11-15T14:08:25","modified_gmt":"2018-11-15T13:08:25","slug":"configuring-kamailio-4x-websocket","status":"publish","type":"post","link":"https:\/\/nil.uniza.sk\/en\/configuring-kamailio-4x-websocket\/","title":{"rendered":"Configuring Kamailio 4.x for WebSocket"},"content":{"rendered":"<p>Author: Patrik Formanek 2014<\/p>\n<hr \/>\n<p>This tutorial instruct how to add the WebSocket support for your kamailio SIP server. As the prerequisities we need to have successfully installed and working kamailio server (described within several tutorials in this site, for example <a href=\"https:\/\/nil.uniza.sk\/en\/sip\/kamailio\/installing-kamailio-31-debian-lenny\/\">Installing Kamailio 3.1<\/a> within <a href=\"https:\/\/nil.uniza.sk\/en\/sip\/kamailio\/\">SIP\/Kamailio<\/a> section of this site).<\/p>\n<p>As the first step we need to install websocket modules:<\/p>\n<pre>apt-get update\r\napt-get install kamailio-websocket-modules<\/pre>\n<p>Then we have to edit the kamailio.cfg file which is located at <em>etc\/kamailio\/kamailio.cfg<\/em><\/p>\n<p>In section with defined values add lines:<\/p>\n<pre>#!substdef \"!MY_IP_ADDR!&lt;SERVER_IP&gt;!g\"\r\n#!substdef \"!MY_DOMAIN!&lt;SERVER_IP&gt;!g\"\r\n#!substdef \"!MY_WS_PORT!8080!g\"\r\n#!substdef \"!MY_WSS_PORT!4443!g\"\r\n#!substdef \"!MY_WS_ADDR!tcp:MY_IP_ADDR:MY_WS_PORT!g\"\r\n#!substdef \"!MY_WSS_ADDR!tls:MY_IP_ADDR:MY_WSS_PORT!g\"\r\n\r\n#!define WITH_WEBSOCKETS<\/pre>\n<p>Where we have to rewrite values :<\/p>\n<ul>\n<li>&lt;SERVER_IP&gt; : IP address of your server (e.i.\u00a0 #!substdef &#8222;!MY_IP_ADDR!192.168.1.13!g&#8220;)<\/li>\n<li>MY_WS_PORT : port on which will be kamailio listening for ws connections (default is 8080 )<\/li>\n<\/ul>\n<p>In section global parameters add lines:<\/p>\n<pre>listen=MY_IP_ADDR\r\n#!ifdef WITH_WEBSOCKETS\r\nlisten=MY_WS_ADDR\r\n#!ifdef WITH_TLS\r\nlisten=MY_WSS_ADDR\r\n#!endif\r\n#!endif\r\n\r\ntcp_connection_lifetime=3604\r\ntcp_accept_no_cl=yes\r\ntcp_rd_buf_size=16384\r\nAnd comment line:\r\n#tcp_connection_lifetime=3605<\/pre>\n<p>Within modules section we load modules needed by the websocket:<\/p>\n<pre>#!ifdef WITH_WEBSOCKETS\r\nloadmodule \"xhttp.so\"\r\nloadmodule \"websocket.so\"\r\nloadmodule \"nathelper.so\"\r\n#!endif<\/pre>\n<p>In section setting module-specific parameters we will add :<\/p>\n<pre>#!ifdef WITH_WEBSOCKETS\r\n# ----- nathelper params -----\r\nmodparam(\"nathelper|registrar\", \"received_avp\", \"$avp(RECEIVED)\")\r\n# Note: leaving NAT pings turned off here as nathelper is _only_ being used for\r\n#       WebSocket connections.  NAT pings are not needed as WebSockets have\r\n#       their own keep-alives.\r\n#!endif<\/pre>\n<p>&nbsp;<\/p>\n<p>In section <em>routing-logic <\/em>in block <em>request_route<\/em> we add lines like this:<\/p>\n<pre>request_route {\r\n\r\n# per request initial checks\r\nroute(REQINIT);\r\n\r\n#!ifdef WITH_WEBSOCKETS\r\nif (nat_uac_test(64)) {\r\n  # Do NAT traversal stuff for requests from a WebSocket\r\n  # connection - even if it is not behind a NAT!\r\n  # This won't be needed in the future if Kamailio and the\r\n  # WebSocket client support Outbound and Path.\r\n  force_rport();\r\n  if (is_method(\"REGISTER\")) {\r\n   fix_nated_register();\r\n  } else {\r\n   fix_nated_contact();\r\n   if (!add_contact_alias()) {\r\n    xlog(\"L_ERR\", \"Error aliasing contact &lt;$ct&gt;\\n\");\r\n    sl_send_reply(\"400\", \"Bad Request\");\r\n    exit;\r\n   }\r\n  }\r\n}\r\n#!endif\r\n....<\/pre>\n<p>&nbsp;<\/p>\n<p>We add some lines in <strong><em>route[WITHINDLG]<\/em><\/strong> and it should looks like this:<\/p>\n<pre>route[WITHINDLG] {\r\nif (has_totag()) {\r\n  # sequential request withing a dialog should\r\n  # take the path determined by record-routing\r\n  if (loose_route()) {\r\n#!ifdef WITH_WEBSOCKETS\r\n   if ($du == \"\") {\r\n    if (!handle_ruri_alias()) {\r\n     xlog(\"L_ERR\", \"Bad alias &lt;$ru&gt;\\n\");\r\n     sl_send_reply(\"400\", \"Bad Request\");\r\n     exit;\r\n    }\r\n   }\r\n#!endif\r\n....<\/pre>\n<p>At the end of config file we add:<\/p>\n<pre>#!ifdef WITH_WEBSOCKETS\r\nonreply_route {\r\nif ((($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT)\r\n  &amp;&amp; !(proto == WS || proto == WSS))) {\r\n  xlog(\"L_WARN\", \"SIP response received on $Rp\\n\");\r\n  drop;\r\n  exit;\r\n}\r\n\r\nif (nat_uac_test(64)) {\r\n  # Do NAT traversal stuff for replies to a WebSocket connection\r\n  # - even if it is not behind a NAT!\r\n  # This won't be needed in the future if Kamailio and the\r\n  # WebSocket client support Outbound and Path.\r\n  add_contact_alias();\r\n}\r\n}\r\n\r\nevent_route[xhttp:request] {\r\nset_reply_close();\r\nset_reply_no_connect();\r\n\r\nif ($Rp != MY_WS_PORT\r\n#!ifdef WITH_TLS\r\n     &amp;&amp; $Rp != MY_WSS_PORT\r\n#!endif\r\n) {\r\n  xlog(\"L_WARN\", \"HTTP request received on $Rp\\n\");\r\n  xhttp_reply(\"403\", \"Forbidden\", \"\", \"\");\r\n  exit;\r\n}\r\n\r\nxlog(\"L_DBG\", \"HTTP Request Received\\n\");\r\n\r\nif ($hdr(Upgrade)=~\"websocket\"\r\n   &amp;&amp; $hdr(Connection)=~\"Upgrade\"\r\n   &amp;&amp; $rm=~\"GET\") {\r\n\r\n  # Validate Host - make sure the client is using the correct\r\n  # alias for WebSockets\r\n  if ($hdr(Host) == $null || !is_myself(\"sip:\" + $hdr(Host))) {\r\n   xlog(\"L_WARN\", \"Bad host $hdr(Host)\\n\");\r\n   xhttp_reply(\"403\", \"Forbidden\", \"\", \"\");\r\n   exit;\r\n  }\r\n\r\n  # Optional... validate Origin - make sure the client is from an\r\n  # authorised website.  For example,\r\n  #\r\n  # if ($hdr(Origin) != \"http:\/\/communicator.MY_DOMAIN\"\r\n  #     &amp;&amp; $hdr(Origin) != \"https:\/\/communicator.MY_DOMAIN\") {\r\n  # xlog(\"L_WARN\", \"Unauthorised client $hdr(Origin)\\n\");\r\n  # xhttp_reply(\"403\", \"Forbidden\", \"\", \"\");\r\n  # exit;\r\n  # }\r\n\r\n  # Optional... perform HTTP authentication\r\n\r\n  # ws_handle_handshake() exits (no further configuration file\r\n  # processing of the request) when complete.\r\n  if (ws_handle_handshake())\r\n  {\r\n   # Optional... cache some information about the\r\n   # successful connection\r\n   exit;\r\n  }\r\n}\r\n\r\nxhttp_reply(\"404\", \"Not Found\", \"\", \"\");\r\n}\r\n\r\nevent_route[websocket:closed] {\r\nxlog(\"L_INFO\", \"WebSocket connection from $si:$sp has closed\\n\");\r\n}\r\n#!endif<\/pre>\n<p>&nbsp;<\/p>\n<p>Save and exit config file. Now you should use command to check for erros:<\/p>\n<pre>kamailio -c kamailio.cfg<\/pre>\n<p>If is everything ok and no errors are shown you can restart server with<br \/>\nservice kamailio restart<\/p>\n<p>You should see something like this:<\/p>\n<pre>Listening on\r\nudp: 192.168.1.13:5060\r\n  tcp: 192.168.1.13:5060\r\n  tcp: 192.168.1.13:8080\r\nAliases:\r\n  tcp: debi.local:8080\r\n  tcp: debi.local:5060\r\n  udp: debi.local:5060<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>","protected":false},"excerpt":{"rendered":"<p>\n\tAuthor: Patrik Formanek 2014<\/p>\n<hr \/>\n<p>\n\tThis tutorial instruct how to add the WebSocket support for your kamailio SIP server. As the prerequisities we need to have successfully installed and working kamailio server (described within several tutorials in this site, for example <a href=\"https:\/\/nil-test.kis.fri.uniza.sk\/sip\/kamailio\/installing-kamailio-31-debian-lenny\">Installing Kamailio 3.1<\/a> within <a href=\"https:\/\/nil-test.kis.fri.uniza.sk\/sip\/kamailio\">SIP\/Kamailio<\/a> section of this site).<\/p>\n<p>\n\t<br \/>\n\tAs the first step we need to install websocket modules:<\/p>","protected":false},"author":7,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":"","_seopress_titles_desc":"","_seopress_robots_index":"","_kad_blocks_custom_css":"","_kad_blocks_head_custom_js":"","_kad_blocks_body_custom_js":"","_kad_blocks_footer_custom_js":"","_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"categories":[781],"tags":[935,937],"class_list":["post-624","post","type-post","status-publish","format-standard","hentry","category-kamailio-en","tag-kamailio","tag-websocket"],"taxonomy_info":{"category":[{"value":781,"label":"Kamailio"}],"post_tag":[{"value":935,"label":"kamailio"},{"value":937,"label":"websocket"}]},"featured_image_src_large":false,"author_info":{"display_name":"admin","author_link":"https:\/\/nil.uniza.sk\/en\/author\/admin\/"},"comment_info":11,"category_info":[{"term_id":781,"name":"Kamailio","slug":"kamailio-en","term_group":0,"term_taxonomy_id":779,"taxonomy":"category","description":"","parent":771,"count":29,"filter":"raw","cat_ID":781,"category_count":29,"category_description":"","cat_name":"Kamailio","category_nicename":"kamailio-en","category_parent":771}],"tag_info":[{"term_id":935,"name":"kamailio","slug":"kamailio","term_group":0,"term_taxonomy_id":933,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"},{"term_id":937,"name":"websocket","slug":"websocket","term_group":0,"term_taxonomy_id":935,"taxonomy":"post_tag","description":"","parent":0,"count":1,"filter":"raw"}],"_links":{"self":[{"href":"https:\/\/nil.uniza.sk\/en\/wp-json\/wp\/v2\/posts\/624","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nil.uniza.sk\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nil.uniza.sk\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nil.uniza.sk\/en\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/nil.uniza.sk\/en\/wp-json\/wp\/v2\/comments?post=624"}],"version-history":[{"count":0,"href":"https:\/\/nil.uniza.sk\/en\/wp-json\/wp\/v2\/posts\/624\/revisions"}],"wp:attachment":[{"href":"https:\/\/nil.uniza.sk\/en\/wp-json\/wp\/v2\/media?parent=624"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nil.uniza.sk\/en\/wp-json\/wp\/v2\/categories?post=624"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nil.uniza.sk\/en\/wp-json\/wp\/v2\/tags?post=624"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}