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