Browse code

core: Added WS support/events to Kamailio core

Peter Dunkley authored on 16/06/2012 16:06:33
Showing 4 changed files
... ...
@@ -96,6 +96,11 @@ int sr_event_register_cb(int type, sr_event_cb_f f)
96 96
 					_sr_events_list.tcp_msrp_frame = f;
97 97
 				else return -1;
98 98
 			break;
99
+		case SREV_TCP_WS_FRAME:
100
+				if(_sr_events_list.tcp_ws_frame==0)
101
+					_sr_events_list.tcp_ws_frame = f;
102
+				else return -1;
103
+			break;
99 104
 		default:
100 105
 			return -1;
101 106
 	}
... ...
@@ -187,6 +192,12 @@ int sr_event_exec(int type, void *data)
187 187
 					ret = _sr_events_list.tcp_msrp_frame(data);
188 188
 					return ret;
189 189
 				} else return 1;
190
+		case SREV_TCP_WS_FRAME:
191
+				if(unlikely(_sr_events_list.tcp_ws_frame!=0))
192
+				{
193
+					ret = _sr_events_list.tcp_ws_frame(data);
194
+					return ret;
195
+				} else return 1;
190 196
 		default:
191 197
 			return -1;
192 198
 	}
... ...
@@ -216,6 +227,8 @@ int sr_event_enabled(int type)
216 216
 				return (_sr_events_list.tcp_http_100c!=0)?1:0;
217 217
 		case SREV_TCP_MSRP_FRAME:
218 218
 				return (_sr_events_list.tcp_msrp_frame!=0)?1:0;
219
+		case SREV_TCP_WS_FRAME:
220
+				return (_sr_events_list.tcp_ws_frame!=0)?1:0;
219 221
 	}
220 222
 	return 0;
221 223
 }
... ...
@@ -32,6 +32,7 @@
32 32
 #define SREV_NET_DGRAM_IN		7
33 33
 #define SREV_TCP_HTTP_100C		8
34 34
 #define SREV_TCP_MSRP_FRAME		9
35
+#define SREV_TCP_WS_FRAME		10
35 36
 
36 37
 
37 38
 typedef int (*sr_event_cb_f)(void *data);
... ...
@@ -46,6 +47,7 @@ typedef struct sr_event_cb {
46 46
 	sr_event_cb_f net_dgram_in;
47 47
 	sr_event_cb_f tcp_http_100c;
48 48
 	sr_event_cb_f tcp_msrp_frame;
49
+	sr_event_cb_f tcp_ws_frame;
49 50
 } sr_event_cb_t;
50 51
 
51 52
 void sr_event_cb_init(void);
... ...
@@ -75,6 +75,7 @@
75 75
 #define F_CONN_WANTS_RD  4096  /* conn. should be watched for READ */
76 76
 #define F_CONN_WANTS_WR  8192  /* conn. should be watched for WRITE */
77 77
 #define F_CONN_PASSIVE  16384 /* conn. created via accept() and not connect()*/
78
+#define F_CONN_WS	32768 /* conn. is a websocket */
78 79
 
79 80
 #ifndef NO_READ_HTTP11
80 81
 #define READ_HTTP11
... ...
@@ -84,6 +85,10 @@
84 84
 #define READ_MSRP
85 85
 #endif
86 86
 
87
+#ifndef NO_READ_WS
88
+#define READ_WS
89
+#endif
90
+
87 91
 enum tcp_req_errors {	TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
88 92
 						TCP_REQ_OVERRUN, TCP_REQ_BAD_LEN };
89 93
 enum tcp_req_states {	H_SKIP_EMPTY, H_SKIP_EMPTY_CR_FOUND,
... ...
@@ -110,6 +110,11 @@ int is_msg_complete(struct tcp_req* r);
110 110
 #define HTTP11CONTINUE_LEN	(sizeof(HTTP11CONTINUE)-1)
111 111
 #endif
112 112
 
113
+#ifdef READ_WS
114
+static int ws_process_msg(char* tcpbuf, unsigned int len,
115
+		struct receive_info* rcv_info, struct tcp_connection* con);
116
+#endif
117
+
113 118
 #define TCPCONN_TIMEOUT_MIN_RUN  1 /* run the timers each new tick */
114 119
 
115 120
 /* types used in io_wait* */
... ...
@@ -439,7 +444,11 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
439 439
 		if (bytes<=0) return bytes;
440 440
 	}
441 441
 	p=r->parsed;
442
-	
442
+#ifdef READ_WS
443
+	if (c->flags & F_CONN_WS)
444
+		return ws_process_msg(p, bytes, &c->rcv, c);
445
+#endif
446
+
443 447
 	while(p<r->pos && r->error==TCP_REQ_OK){
444 448
 		switch((unsigned char)r->state){
445 449
 			case H_BODY: /* read the body*/
... ...
@@ -1015,6 +1024,30 @@ int msrp_process_msg(char* tcpbuf, unsigned int len,
1015 1015
 }
1016 1016
 #endif
1017 1017
 
1018
+#ifdef READ_WS
1019
+static int ws_process_msg(char* tcpbuf, unsigned int len,
1020
+		struct receive_info* rcv_info, struct tcp_connection* con)
1021
+{
1022
+	int ret;
1023
+	tcp_event_info_t tev;
1024
+
1025
+	ret = 0;
1026
+	LM_DBG("WebSocket Message: [[>>>\n%.*s<<<]]\n", len, tcpbuf);
1027
+	if(likely(sr_event_enabled(SREV_TCP_WS_FRAME))) {
1028
+		memset(&tev, 0, sizeof(tcp_event_info_t));
1029
+		tev.type = SREV_TCP_WS_FRAME;
1030
+		tev.buf = tcpbuf;
1031
+		tev.len = len;
1032
+		tev.rcv = rcv_info;
1033
+		tev.con = con;
1034
+		ret = sr_event_exec(SREV_TCP_WS_FRAME, (void*)(&tev));
1035
+	} else {
1036
+		LM_DBG("no callback registering for handling WebSockets - dropping!\n");
1037
+	}
1038
+	return ret;
1039
+}
1040
+#endif
1041
+
1018 1042
 /**
1019 1043
  * @brief wrapper around receive_msg() to clone the tcpbuf content
1020 1044
  *