Hello Guys!
Good news about my tests here! I found some configurations relative to Outbound proxy and I get this working. Now, I can have two outbound proxies, one registrar and one database. I can register one user in the Outbound Proxy1 and one user in Outbound Proxy 2 and place a call between these users.
But now I'm facing another problem! The ACK messages are not being delivered, so the session is being dropped after a few seconds. I think that the problem is in the Contact field. Trying to investigate it now!
I'm not sure about how to change the message to deliver the ACK. Did someone had this problem before?
In anycase, here is the routing configuration that I'm using in my Oubound proxy:
request_route { if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) { xlog("L_WARN", "SIP request received on $Rp\n"); sl_send_reply("403", "Forbidden"); exit; }
route(REQINIT);
if (is_method("CANCEL")) { if (t_check_trans()) { route(RELAY); } exit; }
route(WITHINDLG);
t_check_trans();
if (is_method("REGISTER")) { remove_hf("Route"); add_path(); $du = "sip:REGISTRAR_IP:REGISTRAR_PORT"; } else { if (is_method("INVITE|SUBSCRIBE|ACK")) record_route();
if (@via[2] == "") { # From client so route to registrar...
if ($rU == $null) { sl_send_reply("484", "Address Incomplete"); exit; } remove_hf("Route"); $du = "sip:REGISTRAR_IP:REGISTRAR_PORT"; } else { # From registrar so route using "Route:" headers...
if (!loose_route()) { switch($rc) { case -2: sl_send_reply("403", "Forbidden"); exit; default: xlog("L_ERR", "in request_route\n"); sl_reply_error(); exit; } }
t_on_failure("FAIL_OUTBOUND"); } }
route(RELAY); }
route[RELAY] { if (!t_relay()) { sl_reply_error(); } exit; }
route[REQINIT] { if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; }
if(!sanity_check("1511", "7")) { xlog("Malformed SIP message from $si:$sp\n"); exit; } }
route[WITHINDLG] { if (has_totag()) { if (!loose_route()) { switch($rc) { case -2: sl_send_reply("403", "Forbidden"); exit; default: if (is_method("ACK")) { if ( t_check_trans() ) { record_route(); route(RELAY); exit; } else { exit; } } sl_send_reply("404","Not Found"); } } else { if (is_method("NOTIFY")) { record_route(); } route(RELAY); } exit; } }
onreply_route { if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) { xlog("L_WARN", "SIP response received on $Rp\n"); drop; }
if (!t_check_trans()) { drop; }
if ($rm == "REGISTER" && $rs >= 200 && $rs <= 299) { remove_hf("Flow-Timer"); if ($(hdr(Require)[*])=~"outbound") insert_hf("Flow-Timer: FLOW_TIMER\r\n", "Call-ID"); } }
failure_route[FAIL_OUTBOUND] { if (t_branch_timeout() || !t_branch_replied()) { send_reply("430", "Flow Failed"); } }
event_route[xhttp:request] { set_reply_close(); set_reply_no_connect();
if ($Rp != MY_WS_PORT #!ifdef WITH_TLS && $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" && $hdr(Connection)=~"Upgrade" && $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" # && $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"); }
Thanks again!!!
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-22 12:40 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hi, Daniel and Frank!
Thanks for your support! Now, I changed my scenario just a lil bit to make it easy to understand and deploy. I'm doing the following:
- Created a server using the "Outbound" module configuration example,
but add WebSocket support in it. (IP Address 192.168.1.16) 2. Created a server running as Proxy and Registrar with WebSockets support. (IP Address 192.168.1.15) 3. Registered two users (bob and alice@enterprise.com) using WebRTC. These users sent they Register requests to the Oubount server (192.168.1.16). 4. I'm also using an external postgres database to store the user informations. In my proxy/registrar server, I've configurated "modparam("usrloc", "db_mode", 3)", so it will not store data in memory.
After register the users in my scenario, I can see the following information stored in my database (output of kamctl db show location):
id | ruid | username | domain | contact | received | path | expires | q | callid | cseq | last_modified | flags | cflags | user_agent | socket | methods | instance | reg_id
-----+----------------------+----------+----------------+------------------------------------------------+-----------------------+------+---------------------+----+------------------------+------+---------------------+-------+--------+-------------------+---------------------+---------+-------------------------------------------------+-------- 277 | uloc-54203f71-10bd-2 | alice | enterprise.com | sip:v4s0prah@o35ctmdnnruv.invalid;transport=ws | sip:192.168.1.16:5060 | | 2014-09-22 15:31:21 | -1 | udb4shpe4dnm1jsl6016s5 | 82 | 2014-09-22 15:26:21 | 0 | 0 | JsSIP 0.4.0-devel | udp: 192.168.1.15:80 | 783 | urn:uuid:75c837d1-740a-4c62-baa0-56a06149699e | 1 278 | uloc-54203f71-10bc-2 | bob | enterprise.com | sip:lr78s270@0mkf6fgtprlh.invalid;transport=ws | sip:192.168.1.16:5060 | | 2014-09-22 15:34:02 | -1 | 5mpl9q4bkuqsnpk8r316j5 | 82 | 2014-09-22 15:29:02 | 0 | 0 | JsSIP 0.4.0-devel | udp: 192.168.1.15:80 | 783 | urn:uuid:e92ef911-1ae4-45b1-bfc9-b5752b0f2fe1 | 1
So, I can assume that both users are registered and ready to start sessions.
Now, when I try to start a new session between then (let's say bob calling alice) what I get in the endpoint is the following message:
SIP/2.0 500 I'm terribly sorry, server error occurred (1/SL) Via: SIP/2.0/WS 0mkf6fgtprlh.invalid;rport=33154;received=192.168.1.11;branch=z9hG4bK7711221 To: sip:alice@enterprise.com;tag=94c1b96a0e6eb467885b5057e1e49f9e.1970 From: sip:bob@enterprise.com;tag=on056iipql Call-ID: 5e1pmj2fppbgg13doi4k CSeq: 3989 INVITE Server: kamailio (4.1.5 (x86_64/linux)) Content-Length: 0
What I understood about this problem is that the Proxy server is trying to forward the INVITE to the Outbound server and this server does not know that to do with this message - like forward it to alice.
I'm stucked in this step.
Here you can find the configuration files that I'm using:
Outbound Server: https://mega.co.nz/#!Wlw2RL7S!G2YOP-1QbSCeNQddaAe3kyQMqz8yteZlZsAUpjZX4v4
Proxy Server: https://mega.co.nz/#!qxAXTbbb!4zBjRtmADdl3rPCN2Yidd3xnZEjFahW3GSMb00w41xc
Thanks again!
Bruno Emer
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-18 18:04 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Ok, Daniel!
I am trying exactly what you said, but for some reason the proxy server can't forward the message back to the WebSocket server. I am getting "487 Unresolvable destination". Appears that my Proxy Server can't get data from usrloc.
When I register an user using WebRTC I can see that the system stores the information in kamailio database and in the field "contact" it puts a string. The Proxy server is looking in database and just find this information. Actually, I'm trying to understand the entire process that envolves passing information from an Edge Server to a Proxy server that sends the Register information to another Registrar server (as I described before). The database is shared between all the servers, and they are in the same network.
I just read the information in another topic, as you said, but I think that my case is a lil bit different from it. I you agree, I can post my configuration files here. Maybe this can help another users with the same problem!
Thanks again!!!
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-17 9:13 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hello!
I am relatively new to Kamailio and I'm trying to create a new enviroment using it in my company. I am thinking about use Amazon to host the servers and use OpsWorks to automatically escalate then if necessary. To accomplish this, my idea is to separate the servers, using one dedicated server to run as WebSocket, one to run as proxy and one as a Registrar. I'll be using just one database to store informations to all of my servers. With this, if I need more resources later, I can just create new servers with the specific roles (WebSockets, Proxy, Registrar).
By now, the idea is clear, but the point is that I don't know how to separate the WebSockets server from the proxy server. Actually, I can do this, but when I have one agent using a regular softphone and one agent using WebSockets (with JSSIP) they are not able to establish a session if the softphone user starts it. Now, I want to know if is there a way to use two websockets servers, register users using both of then and start sessions between then, with a separated proxy and registrar.
Has anyone done this before? Is possible to use kamailio like this?
Thanks.
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
Hello,
I haven't time to look at the traces and code, but be sure that you don't do any fixing to contact address when receiving traffic from the other proxy. The first proxy should do that.
Cheers, Daniel
On 23/09/14 23:07, Bruno Emer wrote:
Hello Guys!
Good news about my tests here! I found some configurations relative to Outbound proxy and I get this working. Now, I can have two outbound proxies, one registrar and one database. I can register one user in the Outbound Proxy1 and one user in Outbound Proxy 2 and place a call between these users.
But now I'm facing another problem! The ACK messages are not being delivered, so the session is being dropped after a few seconds. I think that the problem is in the Contact field. Trying to investigate it now!
I'm not sure about how to change the message to deliver the ACK. Did someone had this problem before?
In anycase, here is the routing configuration that I'm using in my Oubound proxy:
request_route { if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) { xlog("L_WARN", "SIP request received on $Rp\n"); sl_send_reply("403", "Forbidden"); exit; }
route(REQINIT);
if (is_method("CANCEL")) { if (t_check_trans()) { route(RELAY); } exit; }
route(WITHINDLG);
t_check_trans();
if (is_method("REGISTER")) { remove_hf("Route"); add_path(); $du = "sip:REGISTRAR_IP:REGISTRAR_PORT"; } else { if (is_method("INVITE|SUBSCRIBE|ACK")) record_route();
if (@via[2] == "") { # From client so route to registrar...
if ($rU == $null) { sl_send_reply("484", "Address Incomplete"); exit; } remove_hf("Route"); $du = "sip:REGISTRAR_IP:REGISTRAR_PORT"; } else { # From registrar so route using "Route:" headers...
if (!loose_route()) { switch($rc) { case -2: sl_send_reply("403", "Forbidden"); exit; default: xlog("L_ERR", "in request_route\n"); sl_reply_error(); exit; } }
t_on_failure("FAIL_OUTBOUND"); } }
route(RELAY); }
route[RELAY] { if (!t_relay()) { sl_reply_error(); } exit; }
route[REQINIT] { if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; }
if(!sanity_check("1511", "7")) { xlog("Malformed SIP message from $si:$sp\n"); exit; } }
route[WITHINDLG] { if (has_totag()) { if (!loose_route()) { switch($rc) { case -2: sl_send_reply("403", "Forbidden"); exit; default: if (is_method("ACK")) { if ( t_check_trans() ) { record_route(); route(RELAY); exit; } else { exit; } } sl_send_reply("404","Not Found"); } } else { if (is_method("NOTIFY")) { record_route(); } route(RELAY); } exit; } }
onreply_route { if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) { xlog("L_WARN", "SIP response received on $Rp\n"); drop; }
if (!t_check_trans()) { drop; }
if ($rm == "REGISTER" && $rs >= 200 && $rs <= 299) { remove_hf("Flow-Timer"); if ($(hdr(Require)[*])=~"outbound") insert_hf("Flow-Timer: FLOW_TIMER\r\n", "Call-ID"); } }
failure_route[FAIL_OUTBOUND] { if (t_branch_timeout() || !t_branch_replied()) { send_reply("430", "Flow Failed"); } }
event_route[xhttp:request] { set_reply_close(); set_reply_no_connect();
if ($Rp != MY_WS_PORT #!ifdef WITH_TLS && $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" && $hdr(Connection)=~"Upgrade" && $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" # && $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"); }
Thanks again!!!
*_ _* *_ _* *_Bruno Emer_*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com mailto:brunoemer@gmail.com https://www.facebook.com/bruno.emer.5https://www.linkedin.com/profile/view?id=86461237&trk=spm_pichttps://twitter.com/brunoemer_https://www.flickr.com/photos/122070309@N03/http://google.com/+BrunoEmerhttp://instagram.com/brunoemer_
2014-09-22 12:40 GMT-03:00 Bruno Emer <brunoemer@gmail.com mailto:brunoemer@gmail.com>:
Hi, Daniel and Frank! Thanks for your support! Now, I changed my scenario just a lil bit to make it easy to understand and deploy. I'm doing the following: 1. Created a server using the "Outbound" module configuration example, but add WebSocket support in it. (IP Address 192.168.1.16) 2. Created a server running as Proxy and Registrar with WebSockets support. (IP Address 192.168.1.15) 3. Registered two users (bob and alice@enterprise.com <mailto:alice@enterprise.com>) using WebRTC. These users sent they Register requests to the Oubount server (192.168.1.16). 4. I'm also using an external postgres database to store the user informations. In my proxy/registrar server, I've configurated "modparam("usrloc", "db_mode", 3)", so it will not store data in memory. After register the users in my scenario, I can see the following information stored in my database (output of kamctl db show location): id | ruid | username | domain | contact | received | path | expires | q | callid | cseq | last_modified | flags | cflags | user_agent | socket | methods | instance | reg_id -----+----------------------+----------+----------------+------------------------------------------------+-----------------------+------+---------------------+----+------------------------+------+---------------------+-------+--------+-------------------+---------------------+---------+-------------------------------------------------+-------- 277 | uloc-54203f71-10bd-2 | alice | enterprise.com <http://enterprise.com> | sip:v4s0prah@o35ctmdnnruv.invalid;transport=ws | sip:192.168.1.16:5060 <http://192.168.1.16:5060> | | 2014-09-22 15:31:21 | -1 | udb4shpe4dnm1jsl6016s5 | 82 | 2014-09-22 15:26:21 | 0 | 0 | JsSIP 0.4.0-devel | udp:192.168.1.15:80 <http://192.168.1.15:80> | 783 | <urn:uuid:75c837d1-740a-4c62-baa0-56a06149699e> | 1 278 | uloc-54203f71-10bc-2 | bob | enterprise.com <http://enterprise.com> | sip:lr78s270@0mkf6fgtprlh.invalid;transport=ws | sip:192.168.1.16:5060 <http://192.168.1.16:5060> | | 2014-09-22 15:34:02 | -1 | 5mpl9q4bkuqsnpk8r316j5 | 82 | 2014-09-22 15:29:02 | 0 | 0 | JsSIP 0.4.0-devel | udp:192.168.1.15:80 <http://192.168.1.15:80> | 783 | <urn:uuid:e92ef911-1ae4-45b1-bfc9-b5752b0f2fe1> | 1 So, I can assume that both users are registered and ready to start sessions. Now, when I try to start a new session between then (let's say bob calling alice) what I get in the endpoint is the following message: SIP/2.0 500 I'm terribly sorry, server error occurred (1/SL) Via: SIP/2.0/WS 0mkf6fgtprlh.invalid;rport=33154;received=192.168.1.11;branch=z9hG4bK7711221 To: <sip:alice@enterprise.com <mailto:sip%3Aalice@enterprise.com>>;tag=94c1b96a0e6eb467885b5057e1e49f9e.1970 From: <sip:bob@enterprise.com <mailto:sip%3Abob@enterprise.com>>;tag=on056iipql Call-ID: 5e1pmj2fppbgg13doi4k CSeq: 3989 INVITE Server: kamailio (4.1.5 (x86_64/linux)) Content-Length: 0 What I understood about this problem is that the Proxy server is trying to forward the INVITE to the Outbound server and this server does not know that to do with this message - like forward it to alice. I'm stucked in this step. Here you can find the configuration files that I'm using: Outbound Server: https://mega.co.nz/#!Wlw2RL7S!G2YOP-1QbSCeNQddaAe3kyQMqz8yteZlZsAUpjZX4v4 <https://mega.co.nz/#%21Wlw2RL7S%21G2YOP-1QbSCeNQddaAe3kyQMqz8yteZlZsAUpjZX4v4> Proxy Server: https://mega.co.nz/#!qxAXTbbb!4zBjRtmADdl3rPCN2Yidd3xnZEjFahW3GSMb00w41xc <https://mega.co.nz/#%21qxAXTbbb%214zBjRtmADdl3rPCN2Yidd3xnZEjFahW3GSMb00w41xc> Thanks again! Bruno Emer *_ _* *_ _* *_Bruno Emer_* Mobile: +55 11 96540-0044 <tel:%2B55%2011%2096540-0044> email: brunoemer@gmail.com <mailto:brunoemer@gmail.com> <https://www.facebook.com/bruno.emer.5><https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic><https://twitter.com/brunoemer_><https://www.flickr.com/photos/122070309@N03/><http://google.com/+BrunoEmer><http://instagram.com/brunoemer_> 2014-09-18 18:04 GMT-03:00 Bruno Emer <brunoemer@gmail.com <mailto:brunoemer@gmail.com>>: Ok, Daniel! I am trying exactly what you said, but for some reason the proxy server can't forward the message back to the WebSocket server. I am getting "487 Unresolvable destination". Appears that my Proxy Server can't get data from usrloc. When I register an user using WebRTC I can see that the system stores the information in kamailio database and in the field "contact" it puts a string. The Proxy server is looking in database and just find this information. Actually, I'm trying to understand the entire process that envolves passing information from an Edge Server to a Proxy server that sends the Register information to another Registrar server (as I described before). The database is shared between all the servers, and they are in the same network. I just read the information in another topic, as you said, but I think that my case is a lil bit different from it. I you agree, I can post my configuration files here. Maybe this can help another users with the same problem! Thanks again!!! *_ _* *_ _* *_Bruno Emer_* Mobile: +55 11 96540-0044 <tel:%2B55%2011%2096540-0044> email: brunoemer@gmail.com <mailto:brunoemer@gmail.com> <https://www.facebook.com/bruno.emer.5><https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic><https://twitter.com/brunoemer_><https://www.flickr.com/photos/122070309@N03/><http://google.com/+BrunoEmer><http://instagram.com/brunoemer_> 2014-09-17 9:13 GMT-03:00 Bruno Emer <brunoemer@gmail.com <mailto:brunoemer@gmail.com>>: Hello! I am relatively new to Kamailio and I'm trying to create a new enviroment using it in my company. I am thinking about use Amazon to host the servers and use OpsWorks to automatically escalate then if necessary. To accomplish this, my idea is to separate the servers, using one dedicated server to run as WebSocket, one to run as proxy and one as a Registrar. I'll be using just one database to store informations to all of my servers. With this, if I need more resources later, I can just create new servers with the specific roles (WebSockets, Proxy, Registrar). By now, the idea is clear, but the point is that I don't know how to separate the WebSockets server from the proxy server. Actually, I can do this, but when I have one agent using a regular softphone and one agent using WebSockets (with JSSIP) they are not able to establish a session if the softphone user starts it. Now, I want to know if is there a way to use two websockets servers, register users using both of then and start sessions between then, with a separated proxy and registrar. Has anyone done this before? Is possible to use kamailio like this? Thanks. *_ _* *_ _* *_Bruno Emer_* Mobile: +55 11 96540-0044 <tel:%2B55%2011%2096540-0044> email: brunoemer@gmail.com <mailto:brunoemer@gmail.com> <https://www.facebook.com/bruno.emer.5><https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic><https://twitter.com/brunoemer_><https://www.flickr.com/photos/122070309@N03/><http://google.com/+BrunoEmer><http://instagram.com/brunoemer_>
SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list sr-users@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users
Thanks again for your help, Daniel!
Now my scenario is working! I have two Edge Proxies and a single Registrar server pointing to a external PostgreSQL database.
My two users (alice and bob) are authenticated each one in a Edge Proxy and I can start a session between then using WebSockets. I'm using WebRTC (JSSIP) as a client to start the calls.
:-)
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-23 18:07 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hello Guys!
Good news about my tests here! I found some configurations relative to Outbound proxy and I get this working. Now, I can have two outbound proxies, one registrar and one database. I can register one user in the Outbound Proxy1 and one user in Outbound Proxy 2 and place a call between these users.
But now I'm facing another problem! The ACK messages are not being delivered, so the session is being dropped after a few seconds. I think that the problem is in the Contact field. Trying to investigate it now!
I'm not sure about how to change the message to deliver the ACK. Did someone had this problem before?
In anycase, here is the routing configuration that I'm using in my Oubound proxy:
request_route { if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) { xlog("L_WARN", "SIP request received on $Rp\n"); sl_send_reply("403", "Forbidden"); exit; }
route(REQINIT);
if (is_method("CANCEL")) { if (t_check_trans()) { route(RELAY); } exit; }
route(WITHINDLG);
t_check_trans();
if (is_method("REGISTER")) { remove_hf("Route"); add_path(); $du = "sip:REGISTRAR_IP:REGISTRAR_PORT"; } else { if (is_method("INVITE|SUBSCRIBE|ACK")) record_route();
if (@via[2] == "") { # From client so route to registrar...
if ($rU == $null) { sl_send_reply("484", "Address Incomplete"); exit; } remove_hf("Route"); $du = "sip:REGISTRAR_IP:REGISTRAR_PORT"; } else { # From registrar so route using "Route:" headers...
if (!loose_route()) { switch($rc) { case -2: sl_send_reply("403", "Forbidden"); exit; default: xlog("L_ERR", "in request_route\n"); sl_reply_error(); exit; } }
t_on_failure("FAIL_OUTBOUND"); } }
route(RELAY); }
route[RELAY] { if (!t_relay()) { sl_reply_error(); } exit; }
route[REQINIT] { if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; }
if(!sanity_check("1511", "7")) { xlog("Malformed SIP message from $si:$sp\n"); exit; } }
route[WITHINDLG] { if (has_totag()) { if (!loose_route()) { switch($rc) { case -2: sl_send_reply("403", "Forbidden"); exit; default: if (is_method("ACK")) { if ( t_check_trans() ) { record_route(); route(RELAY); exit; } else { exit; } } sl_send_reply("404","Not Found"); } } else { if (is_method("NOTIFY")) { record_route(); } route(RELAY); } exit; } }
onreply_route { if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) { xlog("L_WARN", "SIP response received on $Rp\n"); drop; }
if (!t_check_trans()) { drop; }
if ($rm == "REGISTER" && $rs >= 200 && $rs <= 299) { remove_hf("Flow-Timer"); if ($(hdr(Require)[*])=~"outbound") insert_hf("Flow-Timer: FLOW_TIMER\r\n", "Call-ID"); } }
failure_route[FAIL_OUTBOUND] { if (t_branch_timeout() || !t_branch_replied()) { send_reply("430", "Flow Failed"); } }
event_route[xhttp:request] { set_reply_close(); set_reply_no_connect();
if ($Rp != MY_WS_PORT #!ifdef WITH_TLS && $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" && $hdr(Connection)=~"Upgrade" && $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" # && $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"); }
Thanks again!!!
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-22 12:40 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hi, Daniel and Frank!
Thanks for your support! Now, I changed my scenario just a lil bit to make it easy to understand and deploy. I'm doing the following:
- Created a server using the "Outbound" module configuration example,
but add WebSocket support in it. (IP Address 192.168.1.16) 2. Created a server running as Proxy and Registrar with WebSockets support. (IP Address 192.168.1.15) 3. Registered two users (bob and alice@enterprise.com) using WebRTC. These users sent they Register requests to the Oubount server (192.168.1.16). 4. I'm also using an external postgres database to store the user informations. In my proxy/registrar server, I've configurated "modparam("usrloc", "db_mode", 3)", so it will not store data in memory.
After register the users in my scenario, I can see the following information stored in my database (output of kamctl db show location):
id | ruid | username | domain | contact | received | path | expires | q | callid | cseq | last_modified | flags | cflags | user_agent | socket | methods | instance | reg_id
-----+----------------------+----------+----------------+------------------------------------------------+-----------------------+------+---------------------+----+------------------------+------+---------------------+-------+--------+-------------------+---------------------+---------+-------------------------------------------------+-------- 277 | uloc-54203f71-10bd-2 | alice | enterprise.com | sip:v4s0prah@o35ctmdnnruv.invalid;transport=ws | sip:192.168.1.16:5060 | | 2014-09-22 15:31:21 | -1 | udb4shpe4dnm1jsl6016s5 | 82 | 2014-09-22 15:26:21 | 0 | 0 | JsSIP 0.4.0-devel | udp: 192.168.1.15:80 | 783 | urn:uuid:75c837d1-740a-4c62-baa0-56a06149699e | 1 278 | uloc-54203f71-10bc-2 | bob | enterprise.com | sip:lr78s270@0mkf6fgtprlh.invalid;transport=ws | sip:192.168.1.16:5060 | | 2014-09-22 15:34:02 | -1 | 5mpl9q4bkuqsnpk8r316j5 | 82 | 2014-09-22 15:29:02 | 0 | 0 | JsSIP 0.4.0-devel | udp: 192.168.1.15:80 | 783 | urn:uuid:e92ef911-1ae4-45b1-bfc9-b5752b0f2fe1 | 1
So, I can assume that both users are registered and ready to start sessions.
Now, when I try to start a new session between then (let's say bob calling alice) what I get in the endpoint is the following message:
SIP/2.0 500 I'm terribly sorry, server error occurred (1/SL) Via: SIP/2.0/WS 0mkf6fgtprlh.invalid;rport=33154;received=192.168.1.11;branch=z9hG4bK7711221 To: sip:alice@enterprise.com;tag=94c1b96a0e6eb467885b5057e1e49f9e.1970 From: sip:bob@enterprise.com;tag=on056iipql Call-ID: 5e1pmj2fppbgg13doi4k CSeq: 3989 INVITE Server: kamailio (4.1.5 (x86_64/linux)) Content-Length: 0
What I understood about this problem is that the Proxy server is trying to forward the INVITE to the Outbound server and this server does not know that to do with this message - like forward it to alice.
I'm stucked in this step.
Here you can find the configuration files that I'm using:
Outbound Server: https://mega.co.nz/#!Wlw2RL7S!G2YOP-1QbSCeNQddaAe3kyQMqz8yteZlZsAUpjZX4v4
Proxy Server: https://mega.co.nz/#!qxAXTbbb!4zBjRtmADdl3rPCN2Yidd3xnZEjFahW3GSMb00w41xc
Thanks again!
Bruno Emer
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-18 18:04 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Ok, Daniel!
I am trying exactly what you said, but for some reason the proxy server can't forward the message back to the WebSocket server. I am getting "487 Unresolvable destination". Appears that my Proxy Server can't get data from usrloc.
When I register an user using WebRTC I can see that the system stores the information in kamailio database and in the field "contact" it puts a string. The Proxy server is looking in database and just find this information. Actually, I'm trying to understand the entire process that envolves passing information from an Edge Server to a Proxy server that sends the Register information to another Registrar server (as I described before). The database is shared between all the servers, and they are in the same network.
I just read the information in another topic, as you said, but I think that my case is a lil bit different from it. I you agree, I can post my configuration files here. Maybe this can help another users with the same problem!
Thanks again!!!
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-17 9:13 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hello!
I am relatively new to Kamailio and I'm trying to create a new enviroment using it in my company. I am thinking about use Amazon to host the servers and use OpsWorks to automatically escalate then if necessary. To accomplish this, my idea is to separate the servers, using one dedicated server to run as WebSocket, one to run as proxy and one as a Registrar. I'll be using just one database to store informations to all of my servers. With this, if I need more resources later, I can just create new servers with the specific roles (WebSockets, Proxy, Registrar).
By now, the idea is clear, but the point is that I don't know how to separate the WebSockets server from the proxy server. Actually, I can do this, but when I have one agent using a regular softphone and one agent using WebSockets (with JSSIP) they are not able to establish a session if the softphone user starts it. Now, I want to know if is there a way to use two websockets servers, register users using both of then and start sessions between then, with a separated proxy and registrar.
Has anyone done this before? Is possible to use kamailio like this?
Thanks.
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
Hello Bruno, happy to hear you got it working. We are also working on a similar setup. Can you please share the documents online that helped you get the web socketc/webrtc/ kamailio environment up.
Kind Regards,
Nick.
Hello Nick!
I'm still learning more about Kamailio and how it works. This is being a lil bit hard to me because I don't understand too much about programming and all those "if's" and "else's", but I'll be happy to help you and provide you the information that I used to have y scenario working fine.
I spent a lot of time to have this scenario up and running in the way that I need, but here are the main documentation which I used:
This link here explain how to have Registrar and Proxy in different servers. It helped me a lot to understand the message flow between the servers: http://www.kamailio.org/dokuwiki/doku.php/tutorials:openser-modular-install
This here, shows how to enable the websockets in Kamailio. I think that is a good point to start: http://nil.uniza.sk/sip/kamailio/configuring-kamailio-4x-websocket
Here I found a good example that shows how to have an Edge Proxy with websockets support: https://github.com/kamailio/kamailio/blob/master/examples/outbound/edge_webs...
So, I got a mix of information and a lot of attempts and errors.
BTW, many thanks to Daniel and Frank Carmickle that helped me a lot with my questions!
If you need more help, please let me know!
:-)
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-24 10:52 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Thanks again for your help, Daniel!
Now my scenario is working! I have two Edge Proxies and a single Registrar server pointing to a external PostgreSQL database.
My two users (alice and bob) are authenticated each one in a Edge Proxy and I can start a session between then using WebSockets. I'm using WebRTC (JSSIP) as a client to start the calls.
:-)
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-23 18:07 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hello Guys!
Good news about my tests here! I found some configurations relative to Outbound proxy and I get this working. Now, I can have two outbound proxies, one registrar and one database. I can register one user in the Outbound Proxy1 and one user in Outbound Proxy 2 and place a call between these users.
But now I'm facing another problem! The ACK messages are not being delivered, so the session is being dropped after a few seconds. I think that the problem is in the Contact field. Trying to investigate it now!
I'm not sure about how to change the message to deliver the ACK. Did someone had this problem before?
In anycase, here is the routing configuration that I'm using in my Oubound proxy:
request_route { if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) { xlog("L_WARN", "SIP request received on $Rp\n"); sl_send_reply("403", "Forbidden"); exit; }
route(REQINIT);
if (is_method("CANCEL")) { if (t_check_trans()) { route(RELAY); } exit; }
route(WITHINDLG);
t_check_trans();
if (is_method("REGISTER")) { remove_hf("Route"); add_path(); $du = "sip:REGISTRAR_IP:REGISTRAR_PORT"; } else { if (is_method("INVITE|SUBSCRIBE|ACK")) record_route();
if (@via[2] == "") { # From client so route to registrar...
if ($rU == $null) { sl_send_reply("484", "Address Incomplete"); exit; } remove_hf("Route"); $du = "sip:REGISTRAR_IP:REGISTRAR_PORT"; } else { # From registrar so route using "Route:" headers...
if (!loose_route()) { switch($rc) { case -2: sl_send_reply("403", "Forbidden"); exit; default: xlog("L_ERR", "in request_route\n"); sl_reply_error(); exit; } }
t_on_failure("FAIL_OUTBOUND"); } }
route(RELAY); }
route[RELAY] { if (!t_relay()) { sl_reply_error(); } exit; }
route[REQINIT] { if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; }
if(!sanity_check("1511", "7")) { xlog("Malformed SIP message from $si:$sp\n"); exit; } }
route[WITHINDLG] { if (has_totag()) { if (!loose_route()) { switch($rc) { case -2: sl_send_reply("403", "Forbidden"); exit; default: if (is_method("ACK")) { if ( t_check_trans() ) { record_route(); route(RELAY); exit; } else { exit; } } sl_send_reply("404","Not Found"); } } else { if (is_method("NOTIFY")) { record_route(); } route(RELAY); } exit; } }
onreply_route { if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) { xlog("L_WARN", "SIP response received on $Rp\n"); drop; }
if (!t_check_trans()) { drop; }
if ($rm == "REGISTER" && $rs >= 200 && $rs <= 299) { remove_hf("Flow-Timer"); if ($(hdr(Require)[*])=~"outbound") insert_hf("Flow-Timer: FLOW_TIMER\r\n", "Call-ID"); } }
failure_route[FAIL_OUTBOUND] { if (t_branch_timeout() || !t_branch_replied()) { send_reply("430", "Flow Failed"); } }
event_route[xhttp:request] { set_reply_close(); set_reply_no_connect();
if ($Rp != MY_WS_PORT #!ifdef WITH_TLS && $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" && $hdr(Connection)=~"Upgrade" && $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" # && $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"); }
Thanks again!!!
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-22 12:40 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hi, Daniel and Frank!
Thanks for your support! Now, I changed my scenario just a lil bit to make it easy to understand and deploy. I'm doing the following:
- Created a server using the "Outbound" module configuration
example, but add WebSocket support in it. (IP Address 192.168.1.16) 2. Created a server running as Proxy and Registrar with WebSockets support. (IP Address 192.168.1.15) 3. Registered two users (bob and alice@enterprise.com) using WebRTC. These users sent they Register requests to the Oubount server (192.168.1.16). 4. I'm also using an external postgres database to store the user informations. In my proxy/registrar server, I've configurated "modparam("usrloc", "db_mode", 3)", so it will not store data in memory.
After register the users in my scenario, I can see the following information stored in my database (output of kamctl db show location):
id | ruid | username | domain | contact | received | path | expires | q | callid | cseq | last_modified | flags | cflags | user_agent | socket | methods | instance | reg_id
-----+----------------------+----------+----------------+------------------------------------------------+-----------------------+------+---------------------+----+------------------------+------+---------------------+-------+--------+-------------------+---------------------+---------+-------------------------------------------------+-------- 277 | uloc-54203f71-10bd-2 | alice | enterprise.com | sip:v4s0prah@o35ctmdnnruv.invalid;transport=ws | sip:192.168.1.16:5060 | | 2014-09-22 15:31:21 | -1 | udb4shpe4dnm1jsl6016s5 | 82 | 2014-09-22 15:26:21 | 0 | 0 | JsSIP 0.4.0-devel | udp: 192.168.1.15:80 | 783 | urn:uuid:75c837d1-740a-4c62-baa0-56a06149699e | 1 278 | uloc-54203f71-10bc-2 | bob | enterprise.com | sip:lr78s270@0mkf6fgtprlh.invalid;transport=ws | sip:192.168.1.16:5060 | | 2014-09-22 15:34:02 | -1 | 5mpl9q4bkuqsnpk8r316j5 | 82 | 2014-09-22 15:29:02 | 0 | 0 | JsSIP 0.4.0-devel | udp: 192.168.1.15:80 | 783 | urn:uuid:e92ef911-1ae4-45b1-bfc9-b5752b0f2fe1 | 1
So, I can assume that both users are registered and ready to start sessions.
Now, when I try to start a new session between then (let's say bob calling alice) what I get in the endpoint is the following message:
SIP/2.0 500 I'm terribly sorry, server error occurred (1/SL) Via: SIP/2.0/WS 0mkf6fgtprlh.invalid;rport=33154;received=192.168.1.11;branch=z9hG4bK7711221 To: sip:alice@enterprise.com;tag=94c1b96a0e6eb467885b5057e1e49f9e.1970 From: sip:bob@enterprise.com;tag=on056iipql Call-ID: 5e1pmj2fppbgg13doi4k CSeq: 3989 INVITE Server: kamailio (4.1.5 (x86_64/linux)) Content-Length: 0
What I understood about this problem is that the Proxy server is trying to forward the INVITE to the Outbound server and this server does not know that to do with this message - like forward it to alice.
I'm stucked in this step.
Here you can find the configuration files that I'm using:
Outbound Server: https://mega.co.nz/#!Wlw2RL7S!G2YOP-1QbSCeNQddaAe3kyQMqz8yteZlZsAUpjZX4v4
Proxy Server: https://mega.co.nz/#!qxAXTbbb!4zBjRtmADdl3rPCN2Yidd3xnZEjFahW3GSMb00w41xc
Thanks again!
Bruno Emer
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-18 18:04 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Ok, Daniel!
I am trying exactly what you said, but for some reason the proxy server can't forward the message back to the WebSocket server. I am getting "487 Unresolvable destination". Appears that my Proxy Server can't get data from usrloc.
When I register an user using WebRTC I can see that the system stores the information in kamailio database and in the field "contact" it puts a string. The Proxy server is looking in database and just find this information. Actually, I'm trying to understand the entire process that envolves passing information from an Edge Server to a Proxy server that sends the Register information to another Registrar server (as I described before). The database is shared between all the servers, and they are in the same network.
I just read the information in another topic, as you said, but I think that my case is a lil bit different from it. I you agree, I can post my configuration files here. Maybe this can help another users with the same problem!
Thanks again!!!
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-17 9:13 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hello!
I am relatively new to Kamailio and I'm trying to create a new enviroment using it in my company. I am thinking about use Amazon to host the servers and use OpsWorks to automatically escalate then if necessary. To accomplish this, my idea is to separate the servers, using one dedicated server to run as WebSocket, one to run as proxy and one as a Registrar. I'll be using just one database to store informations to all of my servers. With this, if I need more resources later, I can just create new servers with the specific roles (WebSockets, Proxy, Registrar).
By now, the idea is clear, but the point is that I don't know how to separate the WebSockets server from the proxy server. Actually, I can do this, but when I have one agent using a regular softphone and one agent using WebSockets (with JSSIP) they are not able to establish a session if the softphone user starts it. Now, I want to know if is there a way to use two websockets servers, register users using both of then and start sessions between then, with a separated proxy and registrar.
Has anyone done this before? Is possible to use kamailio like this?
Thanks.
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
Dude, thank you. I'll go through the documentation and will send you an email as I progress. PS I am pretty strong with Kamailio+Media/RTPProxy, perl, ifs and elses, so I may be able to help you there if needed
Excellent, Nick!
And if you need some help or stuck in some point, don't hesitate on contact me! I have done a lot of work to get websockets working, and maybe I can share my experience with you as well.
:-)
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-24 14:46 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hello Nick!
I'm still learning more about Kamailio and how it works. This is being a lil bit hard to me because I don't understand too much about programming and all those "if's" and "else's", but I'll be happy to help you and provide you the information that I used to have y scenario working fine.
I spent a lot of time to have this scenario up and running in the way that I need, but here are the main documentation which I used:
This link here explain how to have Registrar and Proxy in different servers. It helped me a lot to understand the message flow between the servers: http://www.kamailio.org/dokuwiki/doku.php/tutorials:openser-modular-install
This here, shows how to enable the websockets in Kamailio. I think that is a good point to start: http://nil.uniza.sk/sip/kamailio/configuring-kamailio-4x-websocket
Here I found a good example that shows how to have an Edge Proxy with websockets support:
https://github.com/kamailio/kamailio/blob/master/examples/outbound/edge_webs...
So, I got a mix of information and a lot of attempts and errors.
BTW, many thanks to Daniel and Frank Carmickle that helped me a lot with my questions!
If you need more help, please let me know!
:-)
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-24 10:52 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Thanks again for your help, Daniel!
Now my scenario is working! I have two Edge Proxies and a single Registrar server pointing to a external PostgreSQL database.
My two users (alice and bob) are authenticated each one in a Edge Proxy and I can start a session between then using WebSockets. I'm using WebRTC (JSSIP) as a client to start the calls.
:-)
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-23 18:07 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hello Guys!
Good news about my tests here! I found some configurations relative to Outbound proxy and I get this working. Now, I can have two outbound proxies, one registrar and one database. I can register one user in the Outbound Proxy1 and one user in Outbound Proxy 2 and place a call between these users.
But now I'm facing another problem! The ACK messages are not being delivered, so the session is being dropped after a few seconds. I think that the problem is in the Contact field. Trying to investigate it now!
I'm not sure about how to change the message to deliver the ACK. Did someone had this problem before?
In anycase, here is the routing configuration that I'm using in my Oubound proxy:
request_route { if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) { xlog("L_WARN", "SIP request received on $Rp\n"); sl_send_reply("403", "Forbidden"); exit; }
route(REQINIT);
if (is_method("CANCEL")) { if (t_check_trans()) { route(RELAY); } exit; }
route(WITHINDLG);
t_check_trans();
if (is_method("REGISTER")) { remove_hf("Route"); add_path(); $du = "sip:REGISTRAR_IP:REGISTRAR_PORT"; } else { if (is_method("INVITE|SUBSCRIBE|ACK")) record_route();
if (@via[2] == "") { # From client so route to registrar...
if ($rU == $null) { sl_send_reply("484", "Address Incomplete"); exit; } remove_hf("Route"); $du = "sip:REGISTRAR_IP:REGISTRAR_PORT"; } else { # From registrar so route using "Route:" headers...
if (!loose_route()) { switch($rc) { case -2: sl_send_reply("403", "Forbidden"); exit; default: xlog("L_ERR", "in request_route\n"); sl_reply_error(); exit; } }
t_on_failure("FAIL_OUTBOUND"); } }
route(RELAY); }
route[RELAY] { if (!t_relay()) { sl_reply_error(); } exit; }
route[REQINIT] { if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); exit; }
if(!sanity_check("1511", "7")) { xlog("Malformed SIP message from $si:$sp\n"); exit; } }
route[WITHINDLG] { if (has_totag()) { if (!loose_route()) { switch($rc) { case -2: sl_send_reply("403", "Forbidden"); exit; default: if (is_method("ACK")) { if ( t_check_trans() ) { record_route(); route(RELAY); exit; } else { exit; } } sl_send_reply("404","Not Found"); } } else { if (is_method("NOTIFY")) { record_route(); } route(RELAY); } exit; } }
onreply_route { if (($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) && !(proto == WS || proto == WSS)) { xlog("L_WARN", "SIP response received on $Rp\n"); drop; }
if (!t_check_trans()) { drop; }
if ($rm == "REGISTER" && $rs >= 200 && $rs <= 299) { remove_hf("Flow-Timer"); if ($(hdr(Require)[*])=~"outbound") insert_hf("Flow-Timer: FLOW_TIMER\r\n", "Call-ID"); } }
failure_route[FAIL_OUTBOUND] { if (t_branch_timeout() || !t_branch_replied()) { send_reply("430", "Flow Failed"); } }
event_route[xhttp:request] { set_reply_close(); set_reply_no_connect();
if ($Rp != MY_WS_PORT #!ifdef WITH_TLS && $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" && $hdr(Connection)=~"Upgrade" && $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" # && $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"); }
Thanks again!!!
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-22 12:40 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hi, Daniel and Frank!
Thanks for your support! Now, I changed my scenario just a lil bit to make it easy to understand and deploy. I'm doing the following:
- Created a server using the "Outbound" module configuration
example, but add WebSocket support in it. (IP Address 192.168.1.16) 2. Created a server running as Proxy and Registrar with WebSockets support. (IP Address 192.168.1.15) 3. Registered two users (bob and alice@enterprise.com) using WebRTC. These users sent they Register requests to the Oubount server (192.168.1.16). 4. I'm also using an external postgres database to store the user informations. In my proxy/registrar server, I've configurated "modparam("usrloc", "db_mode", 3)", so it will not store data in memory.
After register the users in my scenario, I can see the following information stored in my database (output of kamctl db show location):
id | ruid | username | domain | contact | received | path | expires | q | callid | cseq | last_modified | flags | cflags | user_agent | socket | methods | instance | reg_id
-----+----------------------+----------+----------------+------------------------------------------------+-----------------------+------+---------------------+----+------------------------+------+---------------------+-------+--------+-------------------+---------------------+---------+-------------------------------------------------+-------- 277 | uloc-54203f71-10bd-2 | alice | enterprise.com | sip:v4s0prah@o35ctmdnnruv.invalid;transport=ws | sip:192.168.1.16:5060 | | 2014-09-22 15:31:21 | -1 | udb4shpe4dnm1jsl6016s5 | 82 | 2014-09-22 15:26:21 | 0 | 0 | JsSIP 0.4.0-devel | udp: 192.168.1.15:80 | 783 | urn:uuid:75c837d1-740a-4c62-baa0-56a06149699e | 1 278 | uloc-54203f71-10bc-2 | bob | enterprise.com | sip:lr78s270@0mkf6fgtprlh.invalid;transport=ws | sip:192.168.1.16:5060 | | 2014-09-22 15:34:02 | -1 | 5mpl9q4bkuqsnpk8r316j5 | 82 | 2014-09-22 15:29:02 | 0 | 0 | JsSIP 0.4.0-devel | udp: 192.168.1.15:80 | 783 | urn:uuid:e92ef911-1ae4-45b1-bfc9-b5752b0f2fe1 | 1
So, I can assume that both users are registered and ready to start sessions.
Now, when I try to start a new session between then (let's say bob calling alice) what I get in the endpoint is the following message:
SIP/2.0 500 I'm terribly sorry, server error occurred (1/SL) Via: SIP/2.0/WS 0mkf6fgtprlh.invalid;rport=33154;received=192.168.1.11;branch=z9hG4bK7711221 To: <sip:alice@enterprise.com
;tag=94c1b96a0e6eb467885b5057e1e49f9e.1970
From: sip:bob@enterprise.com;tag=on056iipql Call-ID: 5e1pmj2fppbgg13doi4k CSeq: 3989 INVITE Server: kamailio (4.1.5 (x86_64/linux)) Content-Length: 0
What I understood about this problem is that the Proxy server is trying to forward the INVITE to the Outbound server and this server does not know that to do with this message - like forward it to alice.
I'm stucked in this step.
Here you can find the configuration files that I'm using:
Outbound Server:
https://mega.co.nz/#!Wlw2RL7S!G2YOP-1QbSCeNQddaAe3kyQMqz8yteZlZsAUpjZX4v4
Proxy Server:
https://mega.co.nz/#!qxAXTbbb!4zBjRtmADdl3rPCN2Yidd3xnZEjFahW3GSMb00w41xc
Thanks again!
Bruno Emer
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-18 18:04 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Ok, Daniel!
I am trying exactly what you said, but for some reason the proxy server can't forward the message back to the WebSocket server. I am getting "487 Unresolvable destination". Appears that my Proxy Server can't get data from usrloc.
When I register an user using WebRTC I can see that the system stores the information in kamailio database and in the field "contact" it puts a string. The Proxy server is looking in database and just find this information. Actually, I'm trying to understand the entire process that envolves passing information from an Edge Server to a Proxy server that sends the Register information to another Registrar server (as I described before). The database is shared between all the servers, and they are in the same network.
I just read the information in another topic, as you said, but I think that my case is a lil bit different from it. I you agree, I can post my configuration files here. Maybe this can help another users with the same problem!
Thanks again!!!
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_
2014-09-17 9:13 GMT-03:00 Bruno Emer brunoemer@gmail.com:
Hello!
I am relatively new to Kamailio and I'm trying to create a new enviroment using it in my company. I am thinking about use Amazon to host the servers and use OpsWorks to automatically escalate then if necessary. To accomplish this, my idea is to separate the servers, using one dedicated server to run as WebSocket, one to run as proxy and one as a Registrar. I'll be using just one database to store informations to all of my servers. With this, if I need more resources later, I can just create new servers with the specific roles (WebSockets, Proxy, Registrar).
By now, the idea is clear, but the point is that I don't know how to separate the WebSockets server from the proxy server. Actually, I can do this, but when I have one agent using a regular softphone and one agent using WebSockets (with JSSIP) they are not able to establish a session if the softphone user starts it. Now, I want to know if is there a way to use two websockets servers, register users using both of then and start sessions between then, with a separated proxy and registrar.
Has anyone done this before? Is possible to use kamailio like this?
Thanks.
*Bruno Emer*
Mobile: +55 11 96540-0044 email: brunoemer@gmail.com https://www.facebook.com/bruno.emer.5 https://www.linkedin.com/profile/view?id=86461237&trk=spm_pic https://twitter.com/brunoemer_ https://www.flickr.com/photos/122070309@N03/ http://google.com/+BrunoEmer http://instagram.com/brunoemer_