<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
<META NAME="GENERATOR" CONTENT="GtkHTML/4.4.4">
</HEAD>
<BODY>
Hello,<BR>
<BR>
I found an issue with checking the Host: header when you are using a non-default port (that is not 80 or 443) for WebSockets.<BR>
<BR>
I have updated the WebSockets example kamailio.cfg in git master with a fix.<BR>
<BR>
Regards,<BR>
<BR>
Peter<BR>
<BR>
On Fri, 2012-09-14 at 11:55 +0200, Jesús Pérez Rubio wrote:<BR>
<BLOCKQUOTE TYPE=CITE>
Hi, I had the same problem and I solve it changing this line on my kamailio.cfg:<BR>
<BR>
# DIRTY WORKARROUND :P <BR>
#if ($hdr(Host) == $null || !is_myself($hdr(Host))) { <BR>
if ($hdr(Host) == $null) {<BR>
xlog("L_WARN", "Bad host $hdr(Host)\n");<BR>
xhttp_reply("403", "Forbidden", "", "");<BR>
exit;<BR>
}<BR>
<BR>
Could anybode confirm me if this solution is correct (and secure) please?<BR>
<BR>
Thanks in advance :).<BR>
<BR>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
2012/8/8 Carlos Ruiz Díaz <<A HREF="mailto:carlos.ruizdiaz@gmail.com">carlos.ruizdiaz@gmail.com</A>><BR>
<BLOCKQUOTE>
Thank you for your time Peter.
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
I'll setup a VM with Windows to continue with my tests and I'll come back later with more feedback.
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
Regards.
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<FONT COLOR="#888888">Carlos.</FONT>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
On Wed, Aug 8, 2012 at 12:22 PM, Peter Dunkley <<A HREF="mailto:peter.dunkley@crocodile-rcs.com">peter.dunkley@crocodile-rcs.com</A>> wrote:<BR>
<BLOCKQUOTE>
Hi,<BR>
<BR>
I have added some comments in-line below.<BR>
<BR>
Regards,<BR>
<BR>
Peter
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<BR>
> 1. After setting up the proxy ip:port in the call.htm file (of sipml5) to<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> *<BR>
> 127.0.0.1:5060* the client started to work but kamailio script refused to
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> establish my connection because the following condition was not satisfied:<BR>
><BR>
><BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> *if ($Rp != MY_WS_PORT && $Rp != MY_WSS_PORT) {*<BR>
> * xlog("L_WARN", "HTTP request received on $Rp\n");*<BR>
> * xhttp_reply("403", "Forbidden", "", "");*<BR>
> * exit;*<BR>
> *}*<BR>
><BR>
> *MY_WS_PORT* and *MY_WSS_PORT *are set to 80 and 443 respectively, as the
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> default config example of websocket module says so.<BR>
><BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> Then, I decided to change the ip:port to *127.0.0.1:80*, always in the
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> call.htm file and afterwards the condition was satisfied but sipml5 dies<BR>
> with<BR>
><BR>
> SIP stack start: proxy='<A HREF="http://127.0.0.1:80">127.0.0.1:80</A>', realm='<sip:127.0.0.1>',<BR>
> impi='2000', impu='<<A HREF="mailto:sip%3A2000@127.0.0.1">sip:2000@127.0.0.1</A>>'<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> tsk_utils.js:97<<A HREF="http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5">http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5</A>>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> Connecting to 'ws://<A HREF="http://127.0.0.1:80">127.0.0.1:80</A>'<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> tsk_utils.js:97<<A HREF="http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5">http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5</A>><BR>
> Stack starting<BR>
> tsk_utils.js:97<<A HREF="http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5">http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5</A>><BR>
> Unexpected response code: 200 :1 <<A HREF="http://127.0.0.1/">http://127.0.0.1/</A>><BR>
> __tsip_transport_ws_onerror<BR>
> tsk_utils.js:97<<A HREF="http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5">http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5</A>><BR>
> __tsip_transport_ws_onclose<BR>
> tsk_utils.js:97<<A HREF="http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5">http://127.0.0.1/sipml5/src/tinySAK/src/tsk_utils.js?svn=5</A>>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> Failed to connet to the server<BR>
><BR>
> Finally, I ended up commenting the condition block and restored the<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> original values of ip:port to *127.0.0.1:5060* .
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
><BR>
> Having done that, I tried again and another error was thrown but this<BR>
> time,<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> in the next condition block: * if ($hdr(Host) == $null ||<BR>
> !is_myself($hdr(Host))) *
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
><BR>
> <script>: WebSocket<BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <script>:<BR>
> Host:<BR>
> <A HREF="http://127.0.0.1:5060">127.0.0.1:5060</A><BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <script>:<BR>
> Origin: <A HREF="http://127.0.0.1">http://127.0.0.1</A><BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core><BR>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==9 && [<BR>
> <A HREF="http://127.0.0.1:5060">127.0.0.1:5060</A>] == [127.0.0.1]<BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core><BR>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==9 && [<BR>
> <A HREF="http://127.0.0.1:5060">127.0.0.1:5060</A>] == [127.0.0.2]<BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core><BR>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==13 && [<BR>
> <A HREF="http://127.0.0.1:5060">127.0.0.1:5060</A>] == [192.168.10.95]<BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core><BR>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==13 && [<BR>
> <A HREF="http://127.0.0.1:5060">127.0.0.1:5060</A>] == [192.168.10.55]<BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core><BR>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==9 && [<BR>
> <A HREF="http://127.0.0.1:5060">127.0.0.1:5060</A>] == [127.0.0.1]<BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core><BR>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==9 && [<BR>
> <A HREF="http://127.0.0.1:5060">127.0.0.1:5060</A>] == [127.0.0.2]<BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core><BR>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==13 && [<BR>
> <A HREF="http://127.0.0.1:5060">127.0.0.1:5060</A>] == [192.168.10.95]<BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core><BR>
> [socket_info.c:589]: grep_sock_info - checking if host==us: 14==13 && [<BR>
> <A HREF="http://127.0.0.1:5060">127.0.0.1:5060</A>] == [192.168.10.55]<BR>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: DEBUG: <core><BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> [forward.c:462]: *check_self: host != me*
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> Aug 8 11:30:53 carlosrdcnx-laptop kamailio[16238]: WARNING: <script>: Bad<BR>
> host <A HREF="http://127.0.0.1:5060">127.0.0.1:5060</A><BR>
><BR>
> I commented the block too and only then sipml5 was able to register<BR>
> itself.<BR>
><BR>
> What am I doing wrong here?<BR>
><BR>
<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
When I tested this I was hosting sipml5 on a web-server on a separate<BR>
machine from Kamailio, and my web-browser was on a separate machine from<BR>
both Kamailio and the web-server. The example configuration works for<BR>
that scenario (which is likely to be the way it would be deployed in a<BR>
real system). I suspect that the Kamailio listen directives (or something<BR>
else related) aren't set-up quite right for your environment.<BR>
<BR>
Host: is a required header when establishing a WebSocket connection. The<BR>
Host: header added by the client should indicate the name of the server<BR>
the client is trying to connect to as indicated in the WebSocket URI (so<BR>
if you put an IP address in the URI that will be in the Host: header, if<BR>
you put a hostname in the URI then it will be in the Host: header). The<BR>
WebSocket server (in this case Kamailio) should check that this header<BR>
matches what it believes it's externally visible name is before accepting<BR>
the connection.<BR>
<BR>
This check needs to be performed in kamailio.cfg instead of the WebSocket<BR>
module in order for the check to be flexible. The check in the example<BR>
kamailio.cfg is:<BR>
- Making sure the Host: header is present<BR>
- Making sure the name in the Host: header is an IP address (as defined in<BR>
the listen directives) or alias (for example a domain name) that the<BR>
Kamailio instance believes it is authoritative for.<BR>
<BR>
As the WebSocket stack in a web-browser will add the Host: header<BR>
automatically, any problem with this suggests that the WebSocket URI set<BR>
in sipml5 and the listen/alias directives in kamailio.cfg don't match -<BR>
which would be consistent with the first part your connection<BR>
establishment problem too.<BR>
<BR>
I would suggest that you should re-instate these lines as, by commenting<BR>
them out (rather than fixing the underlying problems in the test set-up),<BR>
you may be moving the issues down-stream.
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<BR>
> 2. I registered a legacy softphone (twinkle) to attempt to initiate a call<BR>
> in both ways, but the was something wrong with the signaling, probably<BR>
> some<BR>
> frame decoding garbage in the buffer of the SIP message. Perhaps these<BR>
> bytes are part of the frame control header but since I haven't read the<BR>
> RFC<BR>
> (yet) I am mentioning it anyway.<BR>
><BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> tcp_send: buf=*#012�~#003�*INVITE
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
> sip:2000@df7jal23ls0d.invalid;transport=ws<BR>
> SIP/2.0#015#012Record-Route:<BR>
> <sip:127.0.0.1;transport=ws;r2=on;lr=on>#015#012Record-Route:<BR>
> <sip:127.0.0.1;r2=on;lr=on>#015#012Via: SIP/2.0/WS<BR>
> 127.0.0.1;branch=z9hG4bK90a8.b1a7035e13ed19880dd12a1f4c86adbb.0#015#012Via:<BR>
> SIP/2.0/UDP<BR>
> 127.0.0.1:5062;rport=5062;branch=z9hG4bKimixlbyp#015#012Max-Forwards:<BR>
> 69#015#012To: <<A HREF="mailto:sip%3A2000@127.0.0.1">sip:2000@127.0.0.1</A>>#015#012From: "1000"<BR>
> <<A HREF="mailto:sip%3A1000@127.0.0.1">sip:1000@127.0.0.1</A>>;tag=lrtfz#015#012Call-ID:<BR>
> gxsqobolphfchfq@carlosrdcnx-laptop.site#015#012CSeq: 654<BR>
> INVITE#015#012Contact: <<A HREF="http://sip:1000@127.0.0.1:5062">sip:1000@127.0.0.1:5062</A>>#015#012Content-Type:<BR>
> application/sdp#015#012Allow:<BR>
> INVITE,ACK,BYE,CANCEL,OPTIONS,PRACK,REFER,NOTIFY,SUBSCRIBE,INFO,MESSAGE#015#012Supported:<BR>
> replaces,norefersub,100rel#015#012User-Agent:<BR>
> Twinkle/1.4.2#015#012Content-Length:<BR>
> 302#015#012#015#012v=0#015#012o=twinkle 391470222 1383232165 IN IP4<BR>
> 127.0.0.1#015#012s=-#015#012c=IN IP4 127.0.0.1#015#012t=0 0#015#012m=audio<BR>
> 8008 RTP/AVP <A HREF="tel:98%2097%208%200%203%20101%23015%23">98 97 8 0 3 101#015#</A>012a=rtpmap:98<BR>
> speex/16000#015#012a=rtpmap:97 speex/8000#015#012a=rtpmap:8<BR>
> PCMA/8000#015#012a=rtpmap:0 PCMU/8000#015#012a=rtpmap:3<BR>
> GSM/8000#015#012a=rtpmap:101 telephone-event/8000#015#012a=fmtp:101<BR>
> 0-15#015#012a=ptime:20#015#012<BR>
><BR>
<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
That INVITE is for a call towards sipml5 on a WebSocket connection. So<BR>
this isn't a SIP message over TCP, it is a SIP message over WebSockets<BR>
over TCP - and those are not the same thing. The stuff at the start of<BR>
the TCP buffer is the WebSocket framing and it is meant to be there.<BR>
<BR>
The WebSocket framing will not be present on the connection to Twinkle.
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<BR>
> 3. Does Twinkle support the minimum media requirements for testing? If<BR>
> not,<BR>
> what (Linux) softphone is suitable for this purpose?<BR>
><BR>
<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BLOCKQUOTE>
When using an up-to-date Google Chrome you need to use a client that<BR>
supports RTP/SAVPF. Boghe (from Doubango) is a Windows client that<BR>
supports this. I don't know which (if any) Linux clients support this<BR>
feature.<BR>
<BR>
<FONT COLOR="#888888">--</FONT><BR>
<FONT COLOR="#888888">Peter Dunkley</FONT><BR>
<FONT COLOR="#888888">Technical Director</FONT><BR>
<FONT COLOR="#888888">Crocodile RCS Ltd</FONT><BR>
<BR>
<BR>
<FONT COLOR="#888888">_______________________________________________</FONT><BR>
<FONT COLOR="#888888">sr-dev mailing list</FONT><BR>
<FONT COLOR="#888888"><A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A></FONT><BR>
<FONT COLOR="#888888"><A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A></FONT>
</BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BLOCKQUOTE>
<BR>
_______________________________________________<BR>
sr-dev mailing list<BR>
<A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A><BR>
<A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A><BR>
<BR>
</BLOCKQUOTE>
</BLOCKQUOTE>
<BLOCKQUOTE TYPE=CITE>
<BR>
<BR>
<BR>
-- <BR>
Jesús Pérez<BR>
VoIP Engineer at Quobis<BR>
<BR>
Fixed: +34 902 999 465<BR>
Site: <A HREF="http://www.quobis.com/">http://www.quobis.com</A><BR>
<BR>
<PRE>
_______________________________________________
sr-dev mailing list
<A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A>
<A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A>
</PRE>
</BLOCKQUOTE>
<BR>
<TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<PRE>
--
Peter Dunkley
Technical Director
Crocodile RCS Ltd
</PRE>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>