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