1 /**
2  * Copyright (C) 2009 SIP-Router.org
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*!
20  * \file
21  * \brief Kamailio core :: event handling
22  * \ingroup core
23  * Module: \ref core
24  */
25 
26 #include "dprint.h"
27 #include "mem/mem.h"
28 #include "route.h"
29 #include "events.h"
30 
31 static sr_event_cb_t _sr_events_list;
32 static int _sr_events_inited = 0;
33 
34 typedef struct _sr_core_ert {
35 	int init_parse_error;
36 } sr_core_ert_t;
37 
38 static sr_core_ert_t _sr_core_ert_list;
39 
40 /**
41  *
42  */
sr_core_ert_init(void)43 void sr_core_ert_init(void)
44 {
45 	memset(&_sr_core_ert_list, 0, sizeof(sr_core_ert_t));
46 	/* 0 - is not a valid index in event_route blocks list */
47 	_sr_core_ert_list.init_parse_error = route_get(&event_rt,
48 											"core:receive-parse-error");
49 	if(_sr_core_ert_list.init_parse_error<=0
50 				|| event_rt.rlist[_sr_core_ert_list.init_parse_error]==NULL) {
51 		_sr_core_ert_list.init_parse_error = -1;
52 	} else {
53 		LM_DBG("event_route[core:receive-parse-error] is defined\n");
54 	}
55 }
56 
57 /**
58  *
59  */
sr_core_ert_run(sip_msg_t * msg,int e)60 void sr_core_ert_run(sip_msg_t *msg, int e)
61 {
62 	struct run_act_ctx ctx;
63 	int rtb;
64 
65 	switch(e) {
66 		case SR_CORE_ERT_RECEIVE_PARSE_ERROR:
67 			if(likely(_sr_core_ert_list.init_parse_error<=0))
68 				return;
69 			rtb = get_route_type();
70 			set_route_type(REQUEST_ROUTE);
71 			init_run_actions_ctx(&ctx);
72 			run_top_route(event_rt.rlist[_sr_core_ert_list.init_parse_error],
73 					msg, &ctx);
74 			set_route_type(rtb);
75 		break;
76 	}
77 }
78 
79 /**
80  *
81  */
sr_event_cb_init(void)82 void sr_event_cb_init(void)
83 {
84 	if(_sr_events_inited == 0)
85 	{
86 		memset(&_sr_events_list, 0, sizeof(sr_event_cb_t));
87 		_sr_events_inited = 1;
88 	}
89 }
90 
91 /**
92  *
93  */
sr_event_register_cb(int type,sr_event_cb_f f)94 int sr_event_register_cb(int type, sr_event_cb_f f)
95 {
96 	int i;
97 
98 	sr_event_cb_init();
99 	switch(type) {
100 		case SREV_NET_DATA_IN:
101 				for(i=0; i<SREV_CB_LIST_SIZE; i++) {
102 					if(_sr_events_list.net_data_in[i]==0) {
103 						_sr_events_list.net_data_in[i] = f;
104 						break;
105 					}
106 				}
107 				if(i==SREV_CB_LIST_SIZE) return -1;
108 			break;
109 		case SREV_NET_DATA_OUT:
110 				for(i=SREV_CB_LIST_SIZE-1; i>=0; i--) {
111 					if(_sr_events_list.net_data_out[i]==0) {
112 						_sr_events_list.net_data_out[i] = f;
113 						break;
114 					}
115 				}
116 				if(i<0) return -1;
117 			break;
118 		case SREV_CORE_STATS:
119 				if(_sr_events_list.core_stats==0)
120 					_sr_events_list.core_stats = f;
121 				else return -1;
122 			break;
123 		case SREV_CFG_RUN_ACTION:
124 				if(_sr_events_list.run_action==0)
125 					_sr_events_list.run_action = f;
126 				else return -1;
127 			break;
128 		case SREV_PKG_UPDATE_STATS:
129 				if(_sr_events_list.pkg_update_stats==0)
130 					_sr_events_list.pkg_update_stats = f;
131 				else return -1;
132 			break;
133 		case SREV_NET_DGRAM_IN:
134 				if(_sr_events_list.net_dgram_in==0)
135 					_sr_events_list.net_dgram_in = f;
136 				else return -1;
137 			break;
138 		case SREV_TCP_HTTP_100C:
139 				if(_sr_events_list.tcp_http_100c==0)
140 					_sr_events_list.tcp_http_100c = f;
141 				else return -1;
142 			break;
143 		case SREV_TCP_MSRP_FRAME:
144 				if(_sr_events_list.tcp_msrp_frame==0)
145 					_sr_events_list.tcp_msrp_frame = f;
146 				else return -1;
147 			break;
148 		case SREV_TCP_WS_FRAME_IN:
149 				if(_sr_events_list.tcp_ws_frame_in==0)
150 					_sr_events_list.tcp_ws_frame_in = f;
151 				else return -1;
152 			break;
153 		case SREV_TCP_WS_FRAME_OUT:
154 				if(_sr_events_list.tcp_ws_frame_out==0)
155 					_sr_events_list.tcp_ws_frame_out = f;
156 				else return -1;
157 			break;
158 		case SREV_STUN_IN:
159 				if(_sr_events_list.stun_in==0)
160 					_sr_events_list.stun_in = f;
161 				else return -1;
162 			break;
163 		case SREV_RCV_NOSIP:
164 				if(_sr_events_list.rcv_nosip==0)
165 					_sr_events_list.rcv_nosip = f;
166 				else return -1;
167 			break;
168 		case SREV_TCP_CLOSED:
169 				if(_sr_events_list.tcp_closed==0)
170 					_sr_events_list.tcp_closed = f;
171 				else return -1;
172 			break;
173 		case SREV_NET_DATA_RECV:
174 				if(_sr_events_list.net_data_recv==0)
175 					_sr_events_list.net_data_recv = f;
176 				else return -1;
177 			break;
178 		case SREV_NET_DATA_SENT:
179 				if(_sr_events_list.net_data_sent==0)
180 					_sr_events_list.net_data_sent = f;
181 				else return -1;
182 			break;
183 		case SREV_SIP_REPLY_OUT:
184 				for(i=0; i<SREV_CB_LIST_SIZE; i++) {
185 					if(_sr_events_list.sip_reply_out[i]==0) {
186 						_sr_events_list.sip_reply_out[i] = f;
187 						break;
188 					}
189 				}
190 				if(i==SREV_CB_LIST_SIZE) return -1;
191 			break;
192 		default:
193 			return -1;
194 	}
195 	return 0;
196 }
197 
198 /**
199  *
200  */
sr_event_exec(int type,sr_event_param_t * evp)201 int sr_event_exec(int type, sr_event_param_t *evp)
202 {
203 	int ret;
204 	int i;
205 #ifdef EXTRA_DEBUG
206 	str *p;
207 #endif /* EXTRA_DEBUG */
208 	switch(type) {
209 		case SREV_NET_DATA_IN:
210 				if(unlikely(_sr_events_list.net_data_in[0]!=0))
211 				{
212 #ifdef EXTRA_DEBUG
213 					p = (str*)evp->data;
214 					LM_DBG("PRE-IN ++++++++++++++++++++++++++++++++\n"
215 							"%.*s\n+++++\n", p->len, p->s);
216 #endif /* EXTRA_DEBUG */
217 					ret = 0;
218 					for(i=0; i<SREV_CB_LIST_SIZE
219 							&& _sr_events_list.net_data_in[i]; i++) {
220 						ret |= _sr_events_list.net_data_in[i](evp);
221 					}
222 #ifdef EXTRA_DEBUG
223 					LM_DBG("POST-IN ++++++++++++++++++++++++++++++++\n"
224 							"%.*s\n+++++\n", p->len, p->s);
225 #endif /* EXTRA_DEBUG */
226 					return ret;
227 				} else return 1;
228 			break;
229 		case SREV_NET_DATA_OUT:
230 				if(unlikely(_sr_events_list.net_data_out[SREV_CB_LIST_SIZE-1]!=0))
231 				{
232 #ifdef EXTRA_DEBUG
233 					p = (str*)evp->data;
234 					LM_DBG("PRE-OUT ++++++++++++++++++++\n"
235 							"%.*s\n+++++++++++++++++++\n", p->len, p->s);
236 #endif /* EXTRA_DEBUG */
237 					ret = 0;
238 					for(i=0; i<SREV_CB_LIST_SIZE; i++) {
239 						if(_sr_events_list.net_data_out[i]) {
240 							ret |= _sr_events_list.net_data_out[i](evp);
241 						}
242 					}
243 #ifdef EXTRA_DEBUG
244 					LM_DBG("POST-OUT ++++++++++++++++++++\n"
245 							"%.*s\n+++++++++++++++++++\n", p->len, p->s);
246 #endif /* EXTRA_DEBUG */
247 					return ret;
248 				} else return 1;
249 			break;
250 		case SREV_CORE_STATS:
251 				if(unlikely(_sr_events_list.core_stats!=0))
252 				{
253 					ret = _sr_events_list.core_stats(evp);
254 					return ret;
255 				} else return 1;
256 			break;
257 		case SREV_CFG_RUN_ACTION:
258 				if(unlikely(_sr_events_list.run_action!=0))
259 				{
260 					ret = _sr_events_list.run_action(evp);
261 					return ret;
262 				} else return 1;
263 		case SREV_PKG_UPDATE_STATS:
264 				if(unlikely(_sr_events_list.pkg_update_stats!=0))
265 				{
266 					ret = _sr_events_list.pkg_update_stats(evp);
267 					return ret;
268 				} else return 1;
269 		case SREV_NET_DGRAM_IN:
270 				if(unlikely(_sr_events_list.net_dgram_in!=0))
271 				{
272 					ret = _sr_events_list.net_dgram_in(evp);
273 					return ret;
274 				} else return 1;
275 		case SREV_TCP_HTTP_100C:
276 				if(unlikely(_sr_events_list.tcp_http_100c!=0))
277 				{
278 					ret = _sr_events_list.tcp_http_100c(evp);
279 					return ret;
280 				} else return 1;
281 		case SREV_TCP_MSRP_FRAME:
282 				if(unlikely(_sr_events_list.tcp_msrp_frame!=0))
283 				{
284 					ret = _sr_events_list.tcp_msrp_frame(evp);
285 					return ret;
286 				} else return 1;
287 		case SREV_TCP_WS_FRAME_IN:
288 				if(unlikely(_sr_events_list.tcp_ws_frame_in!=0))
289 				{
290 					ret = _sr_events_list.tcp_ws_frame_in(evp);
291 					return ret;
292 				} else return 1;
293 		case SREV_TCP_WS_FRAME_OUT:
294 				if(unlikely(_sr_events_list.tcp_ws_frame_out!=0))
295 				{
296 					ret = _sr_events_list.tcp_ws_frame_out(evp);
297 					return ret;
298 				} else return 1;
299 		case SREV_STUN_IN:
300 				if(unlikely(_sr_events_list.stun_in!=0))
301 				{
302 					ret = _sr_events_list.stun_in(evp);
303 					return ret;
304 				} else return 1;
305 		case SREV_RCV_NOSIP:
306 				if(unlikely(_sr_events_list.rcv_nosip!=0))
307 				{
308 					ret = _sr_events_list.rcv_nosip(evp);
309 					return ret;
310 				} else return 1;
311 		case SREV_TCP_CLOSED:
312 				if(unlikely(_sr_events_list.tcp_closed!=0))
313 				{
314 					ret = _sr_events_list.tcp_closed(evp);
315 					return ret;
316 				} else return 1;
317 		case SREV_NET_DATA_RECV:
318 				if(unlikely(_sr_events_list.net_data_recv!=0))
319 				{
320 					ret = _sr_events_list.net_data_recv(evp);
321 					return ret;
322 				} else return 1;
323 		case SREV_NET_DATA_SENT:
324 				if(unlikely(_sr_events_list.net_data_sent!=0))
325 				{
326 					ret = _sr_events_list.net_data_sent(evp);
327 					return ret;
328 				} else return 1;
329 		case SREV_SIP_REPLY_OUT:
330 				if(unlikely(_sr_events_list.sip_reply_out[0]!=0))
331 				{
332 					ret = 0;
333 					for(i=0; i<SREV_CB_LIST_SIZE
334 							&& _sr_events_list.sip_reply_out[i]; i++) {
335 						ret |= _sr_events_list.sip_reply_out[i](evp);
336 					}
337 					return ret;
338 				} else return 1;
339 		default:
340 			return -1;
341 	}
342 }
343 
344 /**
345  *
346  */
sr_event_enabled(int type)347 int sr_event_enabled(int type)
348 {
349 	switch(type) {
350 		case SREV_NET_DATA_IN:
351 				return (_sr_events_list.net_data_in[0]!=0)?1:0;
352 		case SREV_NET_DATA_OUT:
353 				return (_sr_events_list.net_data_out[SREV_CB_LIST_SIZE-1]!=0)?1:0;
354 		case SREV_CORE_STATS:
355 				return (_sr_events_list.core_stats!=0)?1:0;
356 		case SREV_CFG_RUN_ACTION:
357 				return (_sr_events_list.run_action!=0)?1:0;
358 		case SREV_PKG_UPDATE_STATS:
359 				return (_sr_events_list.pkg_update_stats!=0)?1:0;
360 		case SREV_NET_DGRAM_IN:
361 				return (_sr_events_list.net_dgram_in!=0)?1:0;
362 		case SREV_TCP_HTTP_100C:
363 				return (_sr_events_list.tcp_http_100c!=0)?1:0;
364 		case SREV_TCP_MSRP_FRAME:
365 				return (_sr_events_list.tcp_msrp_frame!=0)?1:0;
366 		case SREV_TCP_WS_FRAME_IN:
367 				return (_sr_events_list.tcp_ws_frame_in!=0)?1:0;
368 		case SREV_TCP_WS_FRAME_OUT:
369 				return (_sr_events_list.tcp_ws_frame_out!=0)?1:0;
370 		case SREV_STUN_IN:
371 				return (_sr_events_list.stun_in!=0)?1:0;
372 		case SREV_RCV_NOSIP:
373 				return (_sr_events_list.rcv_nosip!=0)?1:0;
374 		case SREV_TCP_CLOSED:
375 				return (_sr_events_list.tcp_closed!=0)?1:0;
376 		case SREV_NET_DATA_RECV:
377 				return (_sr_events_list.net_data_recv!=0)?1:0;
378 		case SREV_NET_DATA_SENT:
379 				return (_sr_events_list.net_data_sent!=0)?1:0;
380 		case SREV_SIP_REPLY_OUT:
381 				return (_sr_events_list.sip_reply_out[0]!=0)?1:0;
382 	}
383 	return 0;
384 }
385 
386 
387 /**
388  *
389  */
390 static sr_corecb_t _ksr_corecb = {0};
391 
392 /**
393  *
394  */
sr_corecb_get(void)395 sr_corecb_t *sr_corecb_get(void)
396 {
397 	return &_ksr_corecb;
398 }
399