[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