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