[sr-dev] git:pd/websocket: modules/websocket: WS module registering for WS messages and basic handler implementation

Peter Dunkley peter.dunkley at crocodile-rcs.com
Sat Jun 16 18:07:59 CEST 2012


Module: sip-router
Branch: pd/websocket
Commit: 6d93ce1b8a752e2b3fdb0ff7a3cbef0c7bc44787
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=6d93ce1b8a752e2b3fdb0ff7a3cbef0c7bc44787

Author: Peter Dunkley <peter.dunkley at crocodile-rcs.com>
Committer: Peter Dunkley <peter.dunkley at crocodile-rcs.com>
Date:   Sat Jun 16 17:05:54 2012 +0100

modules/websocket: WS module registering for WS messages and basic handler implementation

---

 modules/websocket/ws_frame.c     |   28 ++++++++++++++++++++++++++++
 modules/websocket/ws_frame.h     |    1 +
 modules/websocket/ws_handshake.c |   33 +++++++++++++++++++++++++++------
 modules/websocket/ws_mod.c       |    7 +++++++
 4 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/modules/websocket/ws_frame.c b/modules/websocket/ws_frame.c
index 50c8d68..ed7943b 100644
--- a/modules/websocket/ws_frame.c
+++ b/modules/websocket/ws_frame.c
@@ -21,10 +21,38 @@
  *
  */
 
+#include "../../tcp_conn.h"
 #include "../../lib/kmi/tree.h"
 #include "ws_frame.h"
 #include "ws_mod.h"
 
+#define FRAME_BUF_SIZE 1024
+static char frame_buf[FRAME_BUF_SIZE];
+
+int ws_frame_received(void *data)
+{
+	int printed;
+	str output;
+	tcp_event_info_t *tev = (tcp_event_info_t *) data;
+
+	if (tev == NULL || tev->buf == NULL || tev->len <= 0)
+	{
+		LM_WARN("received bad frame\n");
+		return -1;
+	}
+
+	output.len = 0;
+	output.s = frame_buf;
+
+	for (printed = 0; printed < tev->len && output.len < FRAME_BUF_SIZE - 3;
+			printed++)
+		output.len += sprintf(output.s + output.len, "%02x ",
+				(unsigned char) tev->buf[printed]);
+	LM_INFO("Rx: %.*s\n", output.len, output.s);
+
+	return 0;
+}
+
 struct mi_root *ws_mi_close(struct mi_root *cmd, void *param)
 {
 	/* TODO close specified or all connections */
diff --git a/modules/websocket/ws_frame.h b/modules/websocket/ws_frame.h
index c777a15..782367f 100644
--- a/modules/websocket/ws_frame.h
+++ b/modules/websocket/ws_frame.h
@@ -27,6 +27,7 @@
 #include "../../sr_module.h"
 #include "../../lib/kmi/tree.h"
 
+int ws_frame_received(void *data);
 struct mi_root *ws_mi_close(struct mi_root *cmd, void *param);
 struct mi_root *ws_mi_ping(struct mi_root *cmd, void *param);
 
diff --git a/modules/websocket/ws_handshake.c b/modules/websocket/ws_handshake.c
index 721b2aa..3a2174a 100644
--- a/modules/websocket/ws_handshake.c
+++ b/modules/websocket/ws_handshake.c
@@ -27,11 +27,13 @@
 #include "../../data_lump_rpl.h"
 #include "../../dprint.h"
 #include "../../locking.h"
+#include "../../tcp_conn.h"
 #include "../../lib/kcore/kstats_wrapper.h"
 #include "../../lib/kcore/cmpapi.h"
 #include "../../lib/kmi/tree.h"
 #include "../../parser/msg_parser.h"
 #include "../sl/sl.h"
+#include "../tls/tls_cfg.h"
 #include "ws_handshake.h"
 #include "ws_mod.h"
 
@@ -120,16 +122,31 @@ int ws_handle_handshake(struct sip_msg *msg)
 	str key = {0, 0}, headers = {0, 0}, reply_key = {0, 0};
 	unsigned char sha1[20];
 	unsigned int hdr_flags = 0;
-	int version;
+	int lifetime = 0, version;
 	struct hdr_field *hdr = msg->headers;
 
 	if (*ws_enabled == 0)
 	{
 		LM_INFO("disabled: bouncing handshake\n");
-		ws_send_reply(msg, 503, &str_status_service_unavailable, NULL);
+		ws_send_reply(msg, 503, &str_status_internal_server_error,
+				NULL);
+		return 0;
+	}
+
+	/* Check the protocol the request arrived over */
+	switch (msg->rcv.proto)
+	{
+	case PROTO_TCP:
+	case PROTO_TLS:
+		lifetime = cfg_get(tcp, tcp_cfg, con_lifetime);
+		break;
+	default:
+		LM_WARN("websocket handshake on unsupported protocol\n");
+		ws_send_reply(msg, 500, &str_status_service_unavailable, NULL);
 		return 0;
 	}
 
+	/* Process HTTP headers */
 	while (hdr != NULL)
 	{
 		/* Decode and validate Connection */
@@ -289,11 +306,15 @@ int ws_handle_handshake(struct sip_msg *msg)
 			str_hdr_sec_websocket_protocol.s, str_sip.len,
 			str_sip.s);
 
-	/* TODO: make sure Kamailio core sends future requests on this
-		 connection directly to this module */
-
 	/* Send reply */
-	ws_send_reply(msg, 101, &str_status_switching_protocols, &headers);
+	if (ws_send_reply(msg, 101,
+				&str_status_switching_protocols, &headers) < 0)
+		return 0;
+
+	/* Make sure Kamailio core sends future requests on this connection
+	   directly to this module */
+	tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0, lifetime)->flags
+		|= F_CONN_WS;
 
 	return 0;
 }
diff --git a/modules/websocket/ws_mod.c b/modules/websocket/ws_mod.c
index 23d3f7a..4ca1758 100644
--- a/modules/websocket/ws_mod.c
+++ b/modules/websocket/ws_mod.c
@@ -22,6 +22,7 @@
  */
 
 #include "../../dprint.h"
+#include "../../events.h"
 #include "../../locking.h"
 #include "../../sr_module.h"
 #include "../../lib/kcore/kstats_wrapper.h"
@@ -117,6 +118,12 @@ static int mod_init(void)
 		return -1;
 	}
 
+	if (sr_event_register_cb(SREV_TCP_WS_FRAME, ws_frame_received) != 0)
+	{
+		LM_ERR("registering WebSocket call-back\n");
+		return -1;
+	}
+
 	if (register_module_stats(exports.name, stats) != 0)
 	{
 		LM_ERR("registering core statistics\n");




More information about the sr-dev mailing list