[sr-dev] git:master: examples: added WebSocket edge proxy example using outbound for NAT traversal

Peter Dunkley peter.dunkley at crocodile-rcs.com
Wed Apr 24 22:07:44 CEST 2013


Module: sip-router
Branch: master
Commit: 96a1af2f261085db695d8a3b23c1a16f39b393fa
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=96a1af2f261085db695d8a3b23c1a16f39b393fa

Author: Peter Dunkley <peter.dunkley at crocodile-rcs.com>
Committer: Peter Dunkley <peter.dunkley at crocodile-rcs.com>
Date:   Wed Apr 24 21:07:07 2013 +0100

examples: added WebSocket edge proxy example using outbound for NAT traversal

---

 examples/outbound/edge_websocket.cfg |  293 ++++++++++++++++++++++++++++++++++
 1 files changed, 293 insertions(+), 0 deletions(-)

diff --git a/examples/outbound/edge_websocket.cfg b/examples/outbound/edge_websocket.cfg
new file mode 100644
index 0000000..843ec20
--- /dev/null
+++ b/examples/outbound/edge_websocket.cfg
@@ -0,0 +1,293 @@
+#!KAMAILIO
+#
+# Edge proxy configuration with SIP over WebSocket support
+#
+
+#!substdef "!DBURL!sqlite:///etc/kamailio/db.sqlite!g"
+#!substdef "!MY_IP_ADDR!a.b.c.d!g"
+#!substdef "!MY_DOMAIN!example.com!g"
+#!substdef "!MY_WS_PORT!80!g"
+#!substdef "!MY_WSS_PORT!443!g"
+#!substdef "!MY_WS_ADDR!tcp:MY_IP_ADDR:MY_WS_PORT!g"
+#!substdef "!MY_WSS_ADDR!tls:MY_IP_ADDR:MY_WSS_PORT!g"
+
+#!substdef "!REGISTRAR_IP!e.f.g.h!g"
+#!substdef "!REGISTRAR_PORT!5060!g"
+#!substdef "!FLOW_TIMER!20!g"
+
+#!define WITH_TLS
+#!define WITH_WEBSOCKETS
+
+
+####### Global Parameters #########
+
+debug=2
+log_stderror=no
+log_facility=LOG_LOCAL0
+fork=yes
+children=4
+mpath="/usr/lib64/kamailio/modules/"
+force_rport=yes
+
+#!ifdef WITH_TLS
+enable_tls=1
+#!endif
+
+listen=MY_IP_ADDR
+#!ifdef WITH_WEBSOCKETS
+listen=MY_WS_ADDR
+#!ifdef WITH_TLS
+listen=MY_WSS_ADDR
+#!endif
+#!endif
+
+tcp_connection_lifetime=30 # FLOW_TIMER + 10
+tcp_accept_no_cl=yes
+tcp_rd_buf_size=16384
+
+
+####### Modules Section ########
+
+loadmodule "tm.so"
+loadmodule "sl.so"
+loadmodule "outbound.so"
+loadmodule "rr.so"
+loadmodule "path.so"
+loadmodule "pv.so"
+loadmodule "maxfwd.so"
+loadmodule "xlog.so"
+loadmodule "sanity.so"
+loadmodule "ctl.so"
+loadmodule "mi_rpc.so"
+loadmodule "mi_fifo.so"
+loadmodule "textops.so"
+loadmodule "siputils.so"
+loadmodule "stun.so"
+loadmodule "kex.so"
+loadmodule "corex.so"
+#!ifdef WITH_TLS
+loadmodule "tls.so"
+#!endif
+#!ifdef WITH_WEBSOCKETS
+loadmodule "xhttp.so"
+loadmodule "websocket.so"
+#!endif
+
+# ----------------- setting module-specific parameters ---------------
+
+# ----- mi_fifo params -----
+modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
+
+# ----- tm params -----
+modparam("tm", "failure_reply_mode", 3)
+
+# ----- rr params -----
+modparam("rr", "append_fromtag", 0)
+
+# ----- corex params -----
+modparam("corex", "alias_subdomains", "MY_DOMAIN")
+
+#!ifdef WITH_TLS
+# ----- tls params -----
+modparam("tls", "tls_method", "SSLv23")
+modparam("tls", "certificate", "/etc/pki/CA/ser1_cert.pem")
+modparam("tls", "private_key", "/etc/pki/CA/privkey.pem")
+modparam("tls", "ca_list", "/etc/pki/CA/calist.pem")
+#!endif
+
+#!ifdef WITH_WEBSOCKETS
+# ----- websocket params -----
+modparam("websocket", "keepalive_timeout", 25) # FLOW_TIMER + 5
+#!endif
+
+
+####### Routing Logic ########
+
+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"))
+			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() ) {
+						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");
+}




More information about the sr-dev mailing list