Peter Dunkley, an active member of the Kamailio developer team, has integrated support for SIP over the
WebSocket
protocol into Kamailio. It will be part of the next release and exist
only in the developer code today. There are still some issues to sort
out to get a production-ready setup. SIP over Websockets, an IETF draft
composed by a number of members of the SER/Kamailio/SIP router community
– Iñaki Baz Castillo, Victor Pascual and José Luis Millán Villegas – is
still a moving target and hopefully on it’s way to become an RFC.
From the IETF draft abstract:
The WebSocket [RFC6455] protocol enables messages exchange between
clients and servers on top of a persistent TCP connection (optionally
secured with TLS [RFC5246]). The initial protocol handshake makes
use of HTTP [RFC2616] semantics, allowing the WebSocket protocol to
reuse existing HTTP infrastructure.
Modern web browsers include a WebSocket client stack complying with
The WebSocket API [WS-API] as specified by the W3C. It is expected
that other client applications (those running in personal computers
and devices such as smartphones) will also run a WebSocket client
stack. The specification in this document enables usage of the SIP
protocol in those new scenarios.
This specification defines a new WebSocket sub-protocol (section 1.9
in [RFC6455]) for transporting SIP messages between a WebSocket
client and server, a new reliable and message boundary transport for
the SIP protocol, new DNS NAPTR [RFC3403] service values and
procedures for SIP entities implementing the WebSocket transport.
Media transport is out of the scope of this document."
The Kamailio SIP over Websocket support
Some customisation of the websocket module is possible through
modparams, but for most users the defaults should be OK. The WebSocket
module uses
the xhttp and sl modules for the initial handshake, and (unless you
have both a Kamailio installation and WebSocket SIP client supporting
GRUU, Outbound[1], and Path[2]) nathelper for request routing and the
core force_rport() function for response routing (a new nat_uac_test()
has been added to detect whether a message has arrived on a WebSocket).
There is an example kamailio.cfg in the websocket module directory.
- [1] Kamailio does not currently support Outbound
- [2] I have not updated the Path module for WebSockets
I believe that, once Kamailio supports Outbound and WebSocket support
is added to the Path module (and you have a SIP over WebSocket client
that
supports this), it will be possible to use the websocket module
without the nathelper module and force_rport() and without needing to
change the websocket module or Kamailio core code.
If you want to use secure WebSockets (wss) as well as ordinary WebSockets just configure TLS and listen on an appropriate port.
I have added WebSocket support to some modules, but there are
definitely going to be others (modules/lcr,
modules/sipcapture, modules_k/nat_traversal, modules_k/path,
modules_k/seas, and modules_k/snmpstats, at least) that need updating
too. WebSockets is an unusual transport, so I have put a few notes
together for anyone who needs to use it in the code (including adding
support to additional modules):
- A WebSocket server cannot initiate a WebSocket connection. So
a WebSocket connection (over TCP or TLS) is like a TCP/TLS connection
coming from behind a NAT. This is why nathelper aliasing and
force_rport() is used for the routing, and “set_…_no_connect()” is
always used (it’s set within the websocket module).
- WebSocket (PROTO_WS) and secure WebSocket (PROTO_WSS) connections
are just upgraded TCP and TLS connections, so there are no listening
sockets for PROTO_WS and PROTO_WSS. This means that, when deciding on
what transport is being used, you need to look at the proto set in
the tcp_connection, receive_info, and/or dest_info structure for the
message -looking at the socket_info structure (that the message has
arrived on or will be sent on) will not give you the right answer.
- Although WebSocket (PROTO_WS) and secure WebSocket (PROTO_WSS)
are different internal protocols there is only one SIP transport type
for both ”;transport=ws” (WS and WSS are explicitly used in Via: headers
though). This means that you can’t tell whether the transport
parameter in an R-URI, Route/Record-Route, or Contact-URI is for
WebSockets or secure WebSockets. As long as the message makes it into
the WebSocket module everything will be OK as that module sorts it all
out, but it has led to slightly more complex checks being required in
some of the code relating to record-routing to handle this – and it may
have an effect on other modules too.
Please give the new module a go and let Peter know (by writing to the developer mailing list) about any issues you find!