Module: sip-router Branch: pd/websocket Commit: 50d20ecde5503d11358b86cbd23456e2a302c9be URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=50d20ecd...
Author: Peter Dunkley peter.dunkley@crocodile-rcs.com Committer: Peter Dunkley peter.dunkley@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; }