Module: sip-router
Branch: pd/websocket
Commit: 3ec469611f9f6c57d593c000614f461488b760a3
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=3ec4696…
Author: Peter Dunkley <peter.dunkley(a)crocodile-rcs.com>
Committer: Peter Dunkley <peter.dunkley(a)crocodile-rcs.com>
Date: Sat Jun 16 17:06:33 2012 +0100
core: Added WS support/events to Kamailio core
---
events.c | 13 +++++++++++++
events.h | 2 ++
tcp_conn.h | 5 +++++
tcp_read.c | 35 ++++++++++++++++++++++++++++++++++-
4 files changed, 54 insertions(+), 1 deletions(-)
diff --git a/events.c b/events.c
index 5ad2b44..d4a24f8 100644
--- a/events.c
+++ b/events.c
@@ -96,6 +96,11 @@ int sr_event_register_cb(int type, sr_event_cb_f f)
_sr_events_list.tcp_msrp_frame = f;
else return -1;
break;
+ case SREV_TCP_WS_FRAME:
+ if(_sr_events_list.tcp_ws_frame==0)
+ _sr_events_list.tcp_ws_frame = f;
+ else return -1;
+ break;
default:
return -1;
}
@@ -187,6 +192,12 @@ int sr_event_exec(int type, void *data)
ret = _sr_events_list.tcp_msrp_frame(data);
return ret;
} else return 1;
+ case SREV_TCP_WS_FRAME:
+ if(unlikely(_sr_events_list.tcp_ws_frame!=0))
+ {
+ ret = _sr_events_list.tcp_ws_frame(data);
+ return ret;
+ } else return 1;
default:
return -1;
}
@@ -216,6 +227,8 @@ int sr_event_enabled(int type)
return (_sr_events_list.tcp_http_100c!=0)?1:0;
case SREV_TCP_MSRP_FRAME:
return (_sr_events_list.tcp_msrp_frame!=0)?1:0;
+ case SREV_TCP_WS_FRAME:
+ return (_sr_events_list.tcp_ws_frame!=0)?1:0;
}
return 0;
}
diff --git a/events.h b/events.h
index 1a4c5e0..f919a00 100644
--- a/events.h
+++ b/events.h
@@ -32,6 +32,7 @@
#define SREV_NET_DGRAM_IN 7
#define SREV_TCP_HTTP_100C 8
#define SREV_TCP_MSRP_FRAME 9
+#define SREV_TCP_WS_FRAME 10
typedef int (*sr_event_cb_f)(void *data);
@@ -46,6 +47,7 @@ typedef struct sr_event_cb {
sr_event_cb_f net_dgram_in;
sr_event_cb_f tcp_http_100c;
sr_event_cb_f tcp_msrp_frame;
+ sr_event_cb_f tcp_ws_frame;
} sr_event_cb_t;
void sr_event_cb_init(void);
diff --git a/tcp_conn.h b/tcp_conn.h
index a8a7e04..3b3f546 100644
--- a/tcp_conn.h
+++ b/tcp_conn.h
@@ -75,6 +75,7 @@
#define F_CONN_WANTS_RD 4096 /* conn. should be watched for READ */
#define F_CONN_WANTS_WR 8192 /* conn. should be watched for WRITE */
#define F_CONN_PASSIVE 16384 /* conn. created via accept() and not connect()*/
+#define F_CONN_WS 32768 /* conn. is a websocket */
#ifndef NO_READ_HTTP11
#define READ_HTTP11
@@ -84,6 +85,10 @@
#define READ_MSRP
#endif
+#ifndef NO_READ_WS
+#define READ_WS
+#endif
+
enum tcp_req_errors { TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
TCP_REQ_OVERRUN, TCP_REQ_BAD_LEN };
enum tcp_req_states { H_SKIP_EMPTY, H_SKIP_EMPTY_CR_FOUND,
diff --git a/tcp_read.c b/tcp_read.c
index f73a239..c68dbdd 100644
--- a/tcp_read.c
+++ b/tcp_read.c
@@ -110,6 +110,11 @@ int is_msg_complete(struct tcp_req* r);
#define HTTP11CONTINUE_LEN (sizeof(HTTP11CONTINUE)-1)
#endif
+#ifdef READ_WS
+static int ws_process_msg(char* tcpbuf, unsigned int len,
+ struct receive_info* rcv_info, struct tcp_connection* con);
+#endif
+
#define TCPCONN_TIMEOUT_MIN_RUN 1 /* run the timers each new tick */
/* types used in io_wait* */
@@ -439,7 +444,11 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
if (bytes<=0) return bytes;
}
p=r->parsed;
-
+#ifdef READ_WS
+ if (c->flags & F_CONN_WS)
+ return ws_process_msg(p, bytes, &c->rcv, c);
+#endif
+
while(p<r->pos && r->error==TCP_REQ_OK){
switch((unsigned char)r->state){
case H_BODY: /* read the body*/
@@ -1015,6 +1024,30 @@ int msrp_process_msg(char* tcpbuf, unsigned int len,
}
#endif
+#ifdef READ_WS
+static int ws_process_msg(char* tcpbuf, unsigned int len,
+ struct receive_info* rcv_info, struct tcp_connection* con)
+{
+ int ret;
+ tcp_event_info_t tev;
+
+ ret = 0;
+ LM_DBG("WebSocket Message: [[>>>\n%.*s<<<]]\n", len,
tcpbuf);
+ if(likely(sr_event_enabled(SREV_TCP_WS_FRAME))) {
+ memset(&tev, 0, sizeof(tcp_event_info_t));
+ tev.type = SREV_TCP_WS_FRAME;
+ tev.buf = tcpbuf;
+ tev.len = len;
+ tev.rcv = rcv_info;
+ tev.con = con;
+ ret = sr_event_exec(SREV_TCP_WS_FRAME, (void*)(&tev));
+ } else {
+ LM_DBG("no callback registering for handling WebSockets - dropping!\n");
+ }
+ return ret;
+}
+#endif
+
/**
* @brief wrapper around receive_msg() to clone the tcpbuf content
*