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