Hello,
I have merged the pd/websocket branch into Kamailio master. This means that you can now connect SIP over WebSocket (draft-ibc-sipcore-sip-websocket-02) clients to Kamailio using the "ws://" and "wss://" protocols.
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 me know about any issues you find,
Peter
Hi,
I have been using this client for testing: http://www.sipml5.org/
There is a live demo online, but you can also download the HTML and JavaScript (http://code.google.com/p/sipml5/), set it up on a local web-server, and point it at Kamailio. To do this override "i_port" and "s_proxy" after line 300 in "call.htm" to point to the address and port for WebSockets on Kamailio.
You also need a browser that supports RTCWeb to make calls. Google Chrome Canary (Windows and Mac) and Google Chrome Unstable (Linux) have both worked for me (although the Chrome tab running the client does crash/hang occasionally). Once you have installed Chrome you need to enable the RTCWeb feature by navigating to "chrome://flags/", enabling "Enable PeerConnection", and re-launching Chrome.
Peter
Peter Dunkley
Please give the new module a go and let me know about any issues you find.
peter,
thanks for adding websocket module to kamailio. any pointers for clients supporting websocket transport so that we can give it a go?
-- juha
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
I forgot to add the online demo for this client uses the client author's own WebSockets gateway not Kamailio.
Hi,
I have been using this client for testing: http://www.sipml5.org/
There is a live demo online, but you can also download the HTML and JavaScript (http://code.google.com/p/sipml5/), set it up on a local web-server, and point it at Kamailio. To do this override "i_port" and "s_proxy" after line 300 in "call.htm" to point to the address and port for WebSockets on Kamailio.
You also need a browser that supports RTCWeb to make calls. Google Chrome Canary (Windows and Mac) and Google Chrome Unstable (Linux) have both worked for me (although the Chrome tab running the client does crash/hang occasionally). Once you have installed Chrome you need to enable the RTCWeb feature by navigating to "chrome://flags/", enabling "Enable PeerConnection", and re-launching Chrome.
Peter
Peter Dunkley
Please give the new module a go and let me know about any issues you find.
peter,
thanks for adding websocket module to kamailio. any pointers for clients supporting websocket transport so that we can give it a go?
-- juha
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
-- Peter Dunkley Technical Director Crocodile RCS Ltd
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
peter,
in your example config, you have
modparam("registrar", "gruu_enabled", 0)
if you enable it and if client supports gruu, then you would not need any of the nathelper stuff when handling non-register requests.
why do you write that in addition to gruu also outbound and path support would be needed?
-- juha
I put that because that is what the ietf-draft for SIP over WebSockets says is required.
The nathelper stuff works for me, and is useful if your client doesn't support the various extensions.
Peter
On 9 Jul 2012, at 08:06, Juha Heinanen jh@tutpro.com wrote:
peter,
in your example config, you have
modparam("registrar", "gruu_enabled", 0)
if you enable it and if client supports gruu, then you would not need any of the nathelper stuff when handling non-register requests.
why do you write that in addition to gruu also outbound and path support would be needed?
-- juha
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
Peter Dunkley writes:
The nathelper stuff works for me, and is useful if your client doesn't support the various extensions.
ok, i'll check if sipml5 supports gruu once i manage to make it send register request. currently initial GET fails like this:
Jul 9 11:29:43 siika /usr/sbin/sip-proxy[9153]: ERROR: <core> [tcp_read.c:1292]: ERROR: tcp_read_req: bad request, state=7, error=4 buf:#012GET / HTTP/1.1#015#012Upgrade: websocket#015#012Connection: Upgrade#015#012Host: 192.98.103.10#015#012Origin: https://localhost#015#012Sec-WebSocket-Protocol: sip#015#012Sec-WebSocket-Key: 3uCSAAgsydjW9+RD857uXg==#015#012Sec-WebSocket-Version: 13#015#012Sec-WebSocket-Extensions: x-webkit-deflate-frame#015#012#015#012#012parsed:#012GET / HTTP/1.1#015#012Upgrade: websocket#015#012Connection: Upgrade#015#012Host: 192.98.103.10#015#012Origin: https://localhost#015#012Sec-WebSocket-Protocol: sip#015#012Sec-WebSocket-Key: 3uCSAAgsydjW9+RD857uXg==#015#012Sec-WebSocket-Version: 13#015#012Sec-WebSocket-Extensions: x-webkit-deflate-frame#015#012#015#012
i'm not sure if this error is generated before event_route[xhttp:request] is executed.
-- juha
Hi,
That is before the event_route is executed.
It might be worth trying to increase the size of tcp_rd_buf_size.
Regards,
Peter
On Mon, 2012-07-09 at 12:27 +0300, Juha Heinanen wrote:
Peter Dunkley writes:
The nathelper stuff works for me, and is useful if your client doesn't support the various extensions.
ok, i'll check if sipml5 supports gruu once i manage to make it send register request. currently initial GET fails like this:
Jul 9 11:29:43 siika /usr/sbin/sip-proxy[9153]: ERROR: <core> [tcp_read.c:1292]: ERROR: tcp_read_req: bad request, state=7, error=4 buf:#012GET / HTTP/1.1#015#012Upgrade: websocket#015#012Connection: Upgrade#015#012Host: 192.98.103.10#015#012Origin: https://localhost#015#012Sec-WebSocket-Protocol: sip#015#012Sec-WebSocket-Key: 3uCSAAgsydjW9+RD857uXg==#015#012Sec-WebSocket-Version: 13#015#012Sec-WebSocket-Extensions: x-webkit-deflate-frame#015#012#015#012#012parsed:#012GET / HTTP/1.1#015#012Upgrade: websocket#015#012Connection: Upgrade#015#012Host: 192.98.103.10#015#012Origin: https://localhost#015#012Sec-WebSocket-Protocol: sip#015#012Sec-WebSocket-Key: 3uCSAAgsydjW9+RD857uXg==#015#012Sec-WebSocket-Version: 13#015#012Sec-WebSocket-Extensions: x-webkit-deflate-frame#015#012#015#012
i'm not sure if this error is generated before event_route[xhttp:request] is executed.
-- juha
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
Also, make sure tcp_accept_no_cl=yes is in your kamailio.cfg.
From the xhttp module README:
SIP requires a Content-Length header for TCP transport. But most HTTP clients do not set the content length for normal GET requests. Therefore, the core must be configured to allow incoming requests without content length header:
tcp_accept_no_cl=yes
Regards,
Peter
On Mon, 2012-07-09 at 10:42 +0100, Peter Dunkley wrote:
Hi,
That is before the event_route is executed.
It might be worth trying to increase the size of tcp_rd_buf_size.
Regards,
Peter
On Mon, 2012-07-09 at 12:27 +0300, Juha Heinanen wrote:
Peter Dunkley writes:
The nathelper stuff works for me, and is useful if your client doesn't support the various extensions.
ok, i'll check if sipml5 supports gruu once i manage to make it send register request. currently initial GET fails like this:
Jul 9 11:29:43 siika /usr/sbin/sip-proxy[9153]: ERROR: <core> [tcp_read.c:1292]: ERROR: tcp_read_req: bad request, state=7, error=4 buf:#012GET / HTTP/1.1#015#012Upgrade: websocket#015#012Connection: Upgrade#015#012Host: 192.98.103.10#015#012Origin: https://localhost#015#012Sec-WebSocket-Protocol: sip#015#012Sec-WebSocket-Key: 3uCSAAgsydjW9+RD857uXg==#015#012Sec-WebSocket-Version: 13#015#012Sec-WebSocket-Extensions: x-webkit-deflate-frame#015#012#015#012#012parsed:#012GET / HTTP/1.1#015#012Upgrade: websocket#015#012Connection: Upgrade#015#012Host: 192.98.103.10#015#012Origin: https://localhost#015#012Sec-WebSocket-Protocol: sip#015#012Sec-WebSocket-Key: 3uCSAAgsydjW9+RD857uXg==#015#012Sec-WebSocket-Version: 13#015#012Sec-WebSocket-Extensions: x-webkit-deflate-frame#015#012#015#012
i'm not sure if this error is generated before event_route[xhttp:request] is executed.
-- juha
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
Peter Dunkley writes:
Also, make sure tcp_accept_no_cl=yes is in your kamailio.cfg.
that got me further. register request now works ok, but when i send invite, it fails in this test:
if (msg:len >= 4096) { xlog("L_NOTICE", "Message $rm to <$ru> is too big\n"); send_reply("513", "Message too big"); exit; };
is it so that msg:len test cannot be used when tcp_accept_no_cl=yes? if so, what is alternative test to make sure that message is not too big?
-- juha
Hi Juha,
The tcp_accept_no_cl=yes is just to enable Kamailio to accept TCP/TLS messages without a Content-Length: header. Some bad SIP clients send these, and it is not always used in HTTP GETs either - and you need to handle an HTTP GET as part of the WebSocket handshake.
I have no idea about the specifics of that test. It's not something I've ever used. But, the sipML5 client does send quite large INVITEs, so I wouldn't be at all surprised if they were larger than 4096 bytes.
Regards,
Peter
On Mon, 2012-07-09 at 17:21 +0300, Juha Heinanen wrote:
Peter Dunkley writes:
Also, make sure tcp_accept_no_cl=yes is in your kamailio.cfg.
that got me further. register request now works ok, but when i send invite, it fails in this test:
if (msg:len >= 4096) { xlog("L_NOTICE", "Message $rm to <$ru> is too big\n"); send_reply("513", "Message too big"); exit; };
is it so that msg:len test cannot be used when tcp_accept_no_cl=yes? if so, what is alternative test to make sure that message is not too big?
-- juha
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
Peter Dunkley writes:
I have no idea about the specifics of that test. It's not something I've ever used. But, the sipML5 client does send quite large INVITEs, so I wouldn't be at all surprised if they were larger than 4096 bytes.
when i tried to print the invite message using $mb pseudo variable, i got
Jul 9 18:30:34 siika /usr/sbin/sip-proxy[25265]: ERROR: <core> [pvapi.c:1252]: no more space for spec value Jul 9 18:30:34 siika /usr/sbin/sip-proxy[25265]: ERROR: <core> [pvapi.c:1261]: buffer overflow -- increase the buffer size...
i then tried to see the invite message using wireshark, i don't see decrypted requests, but only replies. have you managed to make sipML5 to use http instead of https?
-- juha
Hi,
sipML5 is using HTTP by default, not HTTPS.
All WebSocket frames from clients (so from a browser to Kamailio) are masked and you can't just read them. I believe that there is code in the Wireshark repo to de-mask WebSocket frames - but it hasn't made it into a release yet.
All WebSocket frames from servers (so from Kamailio to a browser) are unmasked, so you can read them in Wireshark (but they don't get decoded as SIP).
Regards,
Peter
On Mon, 2012-07-09 at 18:48 +0300, Juha Heinanen wrote:
Peter Dunkley writes:
I have no idea about the specifics of that test. It's not something I've ever used. But, the sipML5 client does send quite large INVITEs, so I wouldn't be at all surprised if they were larger than 4096 bytes.
when i tried to print the invite message using $mb pseudo variable, i got
Jul 9 18:30:34 siika /usr/sbin/sip-proxy[25265]: ERROR: <core> [pvapi.c:1252]: no more space for spec value Jul 9 18:30:34 siika /usr/sbin/sip-proxy[25265]: ERROR: <core> [pvapi.c:1261]: buffer overflow -- increase the buffer size...
i then tried to see the invite message using wireshark, i don't see decrypted requests, but only replies. have you managed to make sipML5 to use http instead of https?
-- juha
sr-dev mailing list sr-dev@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
Peter Dunkley writes:
sipML5 is using HTTP by default, not HTTPS.
All WebSocket frames from clients (so from a browser to Kamailio) are masked and you can't just read them. I believe that there is code in the Wireshark repo to de-mask WebSocket frames - but it hasn't made it into a release yet.
All WebSocket frames from servers (so from Kamailio to a browser) are unmasked, so you can read them in Wireshark (but they don't get decoded as SIP).
thanks for the explanation. it was weird to see replies in clear, but not the requests.
-- juha
Peter Dunkley writes:
I have no idea about the specifics of that test. It's not something I've ever used. But, the sipML5 client does send quite large INVITEs, so I wouldn't be at all surprised if they were larger than 4096 bytes.
yes, it turned out that the invite sent by sipml5 was 4432 bytes long due to large sdp.
it also turned out that sipml5 is using RTP/SAVPF audio that is not supported e.g. by sems:
Media Description, name and address (m): audio 39469 RTP/SAVPF 103 104 0 8 106 105 13 126
i wonder if any common sip clients support RTP/SAVPF?
-- juha
9 jul 2012 kl. 18:08 skrev Juha Heinanen:
Peter Dunkley writes:
I have no idea about the specifics of that test. It's not something I've ever used. But, the sipML5 client does send quite large INVITEs, so I wouldn't be at all surprised if they were larger than 4096 bytes.
yes, it turned out that the invite sent by sipml5 was 4432 bytes long due to large sdp.
it also turned out that sipml5 is using RTP/SAVPF audio that is not supported e.g. by sems:
Media Description, name and address (m): audio 39469 RTP/SAVPF 103 104 0 8 106 105 13 126
i wonder if any common sip clients support RTP/SAVPF?
Haven't seen that, but it's a requirement for WebRTC. I don't like that they are moving away from basic interoperability with SIP devices on the media plane, but it's happening slowly. All of us need to be on the WebRTC mailing lists and discuss this :-)
Cheers, /O
it turned out that sipml5 does not support gruu. register request that it send does not include Supported: gruu nor +sip.instance in contact.
-- juha
Hello,
thanks for this contribution! Please send the announcement to sr-users mailing lists as well.
Just few words about such 'new-feature' announcements for general devel audience/archive.
Traditionally for each new major feature we notify the users community to know about it -- one of the goals being to get more people start testing it before the next release. People on developers' mailing list get also the git commits, being pretty much up to date with what is new, but the announcement should to be cc-ed here as it should provide eventually more details about use cases, how to use, etc.
Cheers, Daniel
On 7/7/12 7:29 PM, Peter Dunkley wrote:
Hello,
I have merged the pd/websocket branch into Kamailio master. This means that you can now connect SIP over WebSocket (draft-ibc-sipcore-sip-websocket-02) clients to Kamailio using the "ws://" and "wss://" protocols.
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 me know about any issues you find,
Peter