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 <[email protected]>
Committer: Peter Dunkley <[email protected]>
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;
        }
 


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to