[sr-dev] git:pd/websocket: modules/websocket: added generic transmit functions to WebSocket module so Kamailio core can send WebSocket frames

Peter Dunkley peter.dunkley at crocodile-rcs.com
Sat Jun 23 20:10:44 CEST 2012


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

Author: Peter Dunkley <peter.dunkley at crocodile-rcs.com>
Committer: Peter Dunkley <peter.dunkley at crocodile-rcs.com>
Date:   Sat Jun 23 19:08:38 2012 +0100

modules/websocket: added generic transmit functions to WebSocket module so Kamailio core can send WebSocket frames

---

 modules/websocket/ws_frame.c |   69 ++++++++++++++++++++++++++++++++++++++++--
 modules/websocket/ws_frame.h |    3 +-
 modules/websocket/ws_mod.c   |   10 +++++-
 3 files changed, 76 insertions(+), 6 deletions(-)

diff --git a/modules/websocket/ws_frame.c b/modules/websocket/ws_frame.c
index f969119..6b565c3 100644
--- a/modules/websocket/ws_frame.c
+++ b/modules/websocket/ws_frame.c
@@ -23,6 +23,7 @@
 
 #include <limits.h>
 #include "../../receive.h"
+#include "../../stats.h"
 #include "../../str.h"
 #include "../../tcp_conn.h"
 #include "../../tcp_server.h"
@@ -119,6 +120,8 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close)
 	char *send_buf;
 	struct tcp_connection *con;
 	struct dest_info dst;
+	union sockaddr_union *from = NULL;
+	union sockaddr_union local_addr;
 
 	LM_DBG("encoding WebSocket frame\n");
 
@@ -227,8 +230,38 @@ static int encode_and_send_ws_frame(ws_frame_t *frame, conn_close_t conn_close)
 		}
 	}
 
-	if (tcp_send(&dst, NULL, send_buf, frame_length) < 0)
+	if (dst.proto == PROTO_TCP)
 	{
+		if (unlikely(tcp_disable))
+		{
+			STATS_TX_DROPS;
+			LM_WARN("TCP disabled\n");
+			return -1;
+		}		
+	}
+#ifdef USE_TLS
+	else if (dst.proto == PROTO_TLS)
+	{
+		if (unlikely(tls_disable))
+		{
+			STATS_TX_DROPS;
+			LM_WARN("TLS disabled\n");
+			return -1;
+		}		
+	}
+#endif /* USE_TLS */
+
+	if (unlikely((dst.send_flags.f & SND_F_FORCE_SOCKET)
+		&& dst.send_sock))
+	{
+		local_addr = dst.send_sock->su;
+		su_setport(&local_addr, 0);
+		from = &local_addr;
+	}
+
+	if (tcp_send(&dst, from, send_buf, frame_length) < 0)
+	{
+		STATS_TX_DROPS;
 		LM_ERR("sending WebSocket frame\n");
 		pkg_free(send_buf);
 		update_stat(ws_failed_connections, 1);
@@ -494,7 +527,12 @@ static int handle_ping(ws_frame_t *frame)
 
 	frame->opcode = OPCODE_PONG;
 	frame->mask = 0;
-	encode_and_send_ws_frame(frame, CONN_CLOSE_DONT);
+
+	if (encode_and_send_ws_frame(frame, CONN_CLOSE_DONT) < 0)
+	{
+		LM_ERR("sending Pong\n");
+		return -1;
+	}
 
 	return 0;
 }
@@ -510,7 +548,7 @@ static int handle_pong(ws_frame_t *frame)
 	return 0;
 }
 
-int ws_frame_received(void *data)
+int ws_frame_receive(void *data)
 {
 	ws_frame_t ws_frame;
 	tcp_event_info_t *tcpinfo = (tcp_event_info_t *) data;
@@ -547,6 +585,31 @@ int ws_frame_received(void *data)
 	return 0;
 }
 
+int ws_frame_transmit(void *data)
+{
+	ws_event_info_t *wsev = (ws_event_info_t *) data;
+	ws_frame_t frame;
+
+	memset(&frame, 0, sizeof(frame));
+	frame.fin = 1;
+	/* Can't be sure whether this message is UTF-8 or not so always send
+	   as binary */
+	frame.opcode = OPCODE_BINARY_FRAME;
+	frame.payload_len = wsev->len;
+	frame.payload_data = wsev->buf;
+	frame.wsc = wsconn_get(wsev->id);
+
+	if (encode_and_send_ws_frame(&frame, CONN_CLOSE_DONT) < 0)
+	{	
+		LM_ERR("sending SIP message\n");
+		if (wsev->buf) pkg_free(wsev->buf);
+		return -1;
+	}
+
+	if (wsev->buf) pkg_free(wsev->buf);
+	return 0;
+}
+
 static int ping_pong(ws_connection_t *wsc, int opcode)
 {
 	ws_frame_t frame;
diff --git a/modules/websocket/ws_frame.h b/modules/websocket/ws_frame.h
index 6cae2eb..6be9529 100644
--- a/modules/websocket/ws_frame.h
+++ b/modules/websocket/ws_frame.h
@@ -58,7 +58,8 @@ extern stat_var *ws_received_frames;
 extern stat_var *ws_remote_closed_connections;
 extern stat_var *ws_transmitted_frames;
 
-int ws_frame_received(void *data);
+int ws_frame_receive(void *data);
+int ws_frame_transmit(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);
 struct mi_root *ws_mi_pong(struct mi_root *cmd, void *param);
diff --git a/modules/websocket/ws_mod.c b/modules/websocket/ws_mod.c
index 67e15c1..ced58ee 100644
--- a/modules/websocket/ws_mod.c
+++ b/modules/websocket/ws_mod.c
@@ -140,9 +140,15 @@ static int mod_init(void)
 		goto error;
 	}
 
-	if (sr_event_register_cb(SREV_TCP_WS_FRAME, ws_frame_received) != 0)
+	if (sr_event_register_cb(SREV_TCP_WS_FRAME_IN, ws_frame_receive) != 0)
 	{
-		LM_ERR("registering WebSocket call-back\n");
+		LM_ERR("registering WebSocket receive call-back\n");
+		goto error;
+	}
+
+	if (sr_event_register_cb(SREV_TCP_WS_FRAME_OUT, ws_frame_transmit) != 0)
+	{
+		LM_ERR("registering WebSocket transmit call-back\n");
 		goto error;
 	}
 




More information about the sr-dev mailing list