/src/kamailio/src/core/events.c
Line | Count | Source (jump to first uncovered line) |
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 "fmsg.h" |
30 | | #include "events.h" |
31 | | |
32 | | static sr_event_cb_t _sr_events_list; |
33 | | static int _sr_events_inited = 0; |
34 | | |
35 | | typedef struct _sr_core_ert |
36 | | { |
37 | | int init_parse_error; |
38 | | } sr_core_ert_t; |
39 | | |
40 | | static sr_core_ert_t _sr_core_ert_list; |
41 | | |
42 | | /** |
43 | | * |
44 | | */ |
45 | | void sr_core_ert_init(void) |
46 | 0 | { |
47 | 0 | memset(&_sr_core_ert_list, 0, sizeof(sr_core_ert_t)); |
48 | | /* 0 - is not a valid index in event_route blocks list */ |
49 | 0 | _sr_core_ert_list.init_parse_error = |
50 | 0 | route_get(&event_rt, "core:receive-parse-error"); |
51 | 0 | if(_sr_core_ert_list.init_parse_error <= 0 |
52 | 0 | || event_rt.rlist[_sr_core_ert_list.init_parse_error] == NULL) { |
53 | 0 | _sr_core_ert_list.init_parse_error = -1; |
54 | 0 | } else { |
55 | 0 | LM_DBG("event_route[core:receive-parse-error] is defined\n"); |
56 | 0 | } |
57 | 0 | } |
58 | | |
59 | | /** |
60 | | * |
61 | | */ |
62 | | void sr_core_ert_run(sip_msg_t *msg, int e) |
63 | 0 | { |
64 | 0 | struct run_act_ctx ctx; |
65 | 0 | int rtb; |
66 | |
|
67 | 0 | switch(e) { |
68 | 0 | case SR_CORE_ERT_RECEIVE_PARSE_ERROR: |
69 | 0 | if(likely(_sr_core_ert_list.init_parse_error <= 0)) |
70 | 0 | return; |
71 | 0 | rtb = get_route_type(); |
72 | 0 | set_route_type(REQUEST_ROUTE); |
73 | 0 | init_run_actions_ctx(&ctx); |
74 | 0 | run_top_route(event_rt.rlist[_sr_core_ert_list.init_parse_error], |
75 | 0 | msg, &ctx); |
76 | 0 | set_route_type(rtb); |
77 | 0 | break; |
78 | 0 | } |
79 | 0 | } |
80 | | |
81 | | /** |
82 | | * |
83 | | */ |
84 | | int sr_core_ert_run_xname(char *evname) |
85 | 0 | { |
86 | 0 | struct run_act_ctx ctx; |
87 | 0 | int rtb; |
88 | 0 | int ridx; |
89 | 0 | sip_msg_t *fmsg; |
90 | |
|
91 | 0 | fmsg = faked_msg_get_next_clear(); |
92 | 0 | if(fmsg == NULL) { |
93 | 0 | LM_ERR("cannot create a fake message\n"); |
94 | 0 | return -1; |
95 | 0 | } |
96 | 0 | ridx = route_lookup(&event_rt, evname); |
97 | 0 | if(ridx <= 0 || event_rt.rlist[ridx] == NULL) { |
98 | 0 | LM_DBG("event_route[%s] not defined - skipping\n", evname); |
99 | 0 | return 0; |
100 | 0 | } |
101 | | |
102 | 0 | rtb = get_route_type(); |
103 | 0 | set_route_type(REQUEST_ROUTE); |
104 | 0 | init_run_actions_ctx(&ctx); |
105 | 0 | run_top_route(event_rt.rlist[ridx], fmsg, &ctx); |
106 | 0 | set_route_type(rtb); |
107 | |
|
108 | 0 | return 0; |
109 | 0 | } |
110 | | |
111 | | /** |
112 | | * |
113 | | */ |
114 | | void sr_event_cb_init(void) |
115 | 0 | { |
116 | 0 | if(_sr_events_inited == 0) { |
117 | 0 | memset(&_sr_events_list, 0, sizeof(sr_event_cb_t)); |
118 | 0 | _sr_events_inited = 1; |
119 | 0 | } |
120 | 0 | } |
121 | | |
122 | | /** |
123 | | * |
124 | | */ |
125 | | int sr_event_register_cb(int type, sr_event_cb_f f) |
126 | 0 | { |
127 | 0 | int i; |
128 | |
|
129 | 0 | sr_event_cb_init(); |
130 | 0 | switch(type) { |
131 | 0 | case SREV_NET_DATA_IN: |
132 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE; i++) { |
133 | 0 | if(_sr_events_list.net_data_in[i] == 0) { |
134 | 0 | _sr_events_list.net_data_in[i] = f; |
135 | 0 | break; |
136 | 0 | } |
137 | 0 | } |
138 | 0 | if(i == SREV_CB_LIST_SIZE) |
139 | 0 | return -1; |
140 | 0 | break; |
141 | 0 | case SREV_NET_DATA_OUT: |
142 | 0 | for(i = SREV_CB_LIST_SIZE - 1; i >= 0; i--) { |
143 | 0 | if(_sr_events_list.net_data_out[i] == 0) { |
144 | 0 | _sr_events_list.net_data_out[i] = f; |
145 | 0 | break; |
146 | 0 | } |
147 | 0 | } |
148 | 0 | if(i < 0) |
149 | 0 | return -1; |
150 | 0 | break; |
151 | 0 | case SREV_CORE_STATS: |
152 | 0 | if(_sr_events_list.core_stats == 0) |
153 | 0 | _sr_events_list.core_stats = f; |
154 | 0 | else |
155 | 0 | return -1; |
156 | 0 | break; |
157 | 0 | case SREV_CFG_RUN_ACTION: |
158 | 0 | if(_sr_events_list.run_action == 0) |
159 | 0 | _sr_events_list.run_action = f; |
160 | 0 | else |
161 | 0 | return -1; |
162 | 0 | break; |
163 | 0 | case SREV_PKG_UPDATE_STATS: |
164 | 0 | if(_sr_events_list.pkg_update_stats == 0) |
165 | 0 | _sr_events_list.pkg_update_stats = f; |
166 | 0 | else |
167 | 0 | return -1; |
168 | 0 | break; |
169 | 0 | case SREV_NET_DGRAM_IN: |
170 | 0 | if(_sr_events_list.net_dgram_in == 0) |
171 | 0 | _sr_events_list.net_dgram_in = f; |
172 | 0 | else |
173 | 0 | return -1; |
174 | 0 | break; |
175 | 0 | case SREV_TCP_HTTP_100C: |
176 | 0 | if(_sr_events_list.tcp_http_100c == 0) |
177 | 0 | _sr_events_list.tcp_http_100c = f; |
178 | 0 | else |
179 | 0 | return -1; |
180 | 0 | break; |
181 | 0 | case SREV_TCP_MSRP_FRAME: |
182 | 0 | if(_sr_events_list.tcp_msrp_frame == 0) |
183 | 0 | _sr_events_list.tcp_msrp_frame = f; |
184 | 0 | else |
185 | 0 | return -1; |
186 | 0 | break; |
187 | 0 | case SREV_TCP_WS_FRAME_IN: |
188 | 0 | if(_sr_events_list.tcp_ws_frame_in == 0) |
189 | 0 | _sr_events_list.tcp_ws_frame_in = f; |
190 | 0 | else |
191 | 0 | return -1; |
192 | 0 | break; |
193 | 0 | case SREV_TCP_WS_FRAME_OUT: |
194 | 0 | if(_sr_events_list.tcp_ws_frame_out == 0) |
195 | 0 | _sr_events_list.tcp_ws_frame_out = f; |
196 | 0 | else |
197 | 0 | return -1; |
198 | 0 | break; |
199 | 0 | case SREV_STUN_IN: |
200 | 0 | if(_sr_events_list.stun_in == 0) |
201 | 0 | _sr_events_list.stun_in = f; |
202 | 0 | else |
203 | 0 | return -1; |
204 | 0 | break; |
205 | 0 | case SREV_RCV_NOSIP: |
206 | 0 | if(_sr_events_list.rcv_nosip == 0) |
207 | 0 | _sr_events_list.rcv_nosip = f; |
208 | 0 | else |
209 | 0 | return -1; |
210 | 0 | break; |
211 | 0 | case SREV_TCP_CLOSED: |
212 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE; i++) { |
213 | 0 | if(_sr_events_list.tcp_closed[i] == 0) { |
214 | 0 | _sr_events_list.tcp_closed[i] = f; |
215 | 0 | break; |
216 | 0 | } |
217 | 0 | } |
218 | 0 | if(i == SREV_CB_LIST_SIZE) |
219 | 0 | return -1; |
220 | 0 | break; |
221 | 0 | case SREV_NET_DATA_RECV: |
222 | 0 | if(_sr_events_list.net_data_recv == 0) |
223 | 0 | _sr_events_list.net_data_recv = f; |
224 | 0 | else |
225 | 0 | return -1; |
226 | 0 | break; |
227 | 0 | case SREV_NET_DATA_SENT: |
228 | 0 | if(_sr_events_list.net_data_sent == 0) |
229 | 0 | _sr_events_list.net_data_sent = f; |
230 | 0 | else |
231 | 0 | return -1; |
232 | 0 | break; |
233 | 0 | case SREV_SIP_REPLY_OUT: |
234 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE; i++) { |
235 | 0 | if(_sr_events_list.sip_reply_out[i] == 0) { |
236 | 0 | _sr_events_list.sip_reply_out[i] = f; |
237 | 0 | break; |
238 | 0 | } |
239 | 0 | } |
240 | 0 | if(i == SREV_CB_LIST_SIZE) |
241 | 0 | return -1; |
242 | 0 | break; |
243 | 0 | case SREV_TCP_WS_CLOSE: |
244 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE; i++) { |
245 | 0 | if(_sr_events_list.tcp_ws_close[i] == 0) { |
246 | 0 | _sr_events_list.tcp_ws_close[i] = f; |
247 | 0 | break; |
248 | 0 | } |
249 | 0 | } |
250 | 0 | if(i == SREV_CB_LIST_SIZE) |
251 | 0 | return -1; |
252 | 0 | break; |
253 | 0 | default: |
254 | 0 | return -1; |
255 | 0 | } |
256 | 0 | return 0; |
257 | 0 | } |
258 | | |
259 | | /** |
260 | | * |
261 | | */ |
262 | | int sr_event_exec(int type, sr_event_param_t *evp) |
263 | 56.2k | { |
264 | 56.2k | int ret; |
265 | 56.2k | int i; |
266 | | #ifdef EXTRA_DEBUG |
267 | | str *p; |
268 | | #endif /* EXTRA_DEBUG */ |
269 | 56.2k | switch(type) { |
270 | 0 | case SREV_NET_DATA_IN: |
271 | 0 | if(unlikely(_sr_events_list.net_data_in[0] != 0)) { |
272 | | #ifdef EXTRA_DEBUG |
273 | | p = (str *)evp->data; |
274 | | LM_DBG("PRE-IN ++++++++++++++++++++++++++++++++\n" |
275 | | "%.*s\n+++++\n", |
276 | | p->len, p->s); |
277 | | #endif /* EXTRA_DEBUG */ |
278 | 0 | ret = 0; |
279 | 0 | for(i = 0; |
280 | 0 | i < SREV_CB_LIST_SIZE && _sr_events_list.net_data_in[i]; |
281 | 0 | i++) { |
282 | 0 | ret |= _sr_events_list.net_data_in[i](evp); |
283 | 0 | } |
284 | | #ifdef EXTRA_DEBUG |
285 | | LM_DBG("POST-IN ++++++++++++++++++++++++++++++++\n" |
286 | | "%.*s\n+++++\n", |
287 | | p->len, p->s); |
288 | | #endif /* EXTRA_DEBUG */ |
289 | 0 | return ret; |
290 | 0 | } else |
291 | 0 | return 1; |
292 | 0 | break; |
293 | 0 | case SREV_NET_DATA_OUT: |
294 | 0 | if(unlikely(_sr_events_list.net_data_out[SREV_CB_LIST_SIZE - 1] |
295 | 0 | != 0)) { |
296 | | #ifdef EXTRA_DEBUG |
297 | | p = (str *)evp->data; |
298 | | LM_DBG("PRE-OUT ++++++++++++++++++++\n" |
299 | | "%.*s\n+++++++++++++++++++\n", |
300 | | p->len, p->s); |
301 | | #endif /* EXTRA_DEBUG */ |
302 | 0 | ret = 0; |
303 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE; i++) { |
304 | 0 | if(_sr_events_list.net_data_out[i]) { |
305 | 0 | ret |= _sr_events_list.net_data_out[i](evp); |
306 | 0 | } |
307 | 0 | } |
308 | | #ifdef EXTRA_DEBUG |
309 | | LM_DBG("POST-OUT ++++++++++++++++++++\n" |
310 | | "%.*s\n+++++++++++++++++++\n", |
311 | | p->len, p->s); |
312 | | #endif /* EXTRA_DEBUG */ |
313 | 0 | return ret; |
314 | 0 | } else |
315 | 0 | return 1; |
316 | 0 | break; |
317 | 56.2k | case SREV_CORE_STATS: |
318 | 56.2k | if(unlikely(_sr_events_list.core_stats != 0)) { |
319 | 0 | ret = _sr_events_list.core_stats(evp); |
320 | 0 | return ret; |
321 | 0 | } else |
322 | 56.2k | return 1; |
323 | 0 | break; |
324 | 0 | case SREV_CFG_RUN_ACTION: |
325 | 0 | if(unlikely(_sr_events_list.run_action != 0)) { |
326 | 0 | ret = _sr_events_list.run_action(evp); |
327 | 0 | return ret; |
328 | 0 | } else |
329 | 0 | return 1; |
330 | 0 | case SREV_PKG_UPDATE_STATS: |
331 | 0 | if(unlikely(_sr_events_list.pkg_update_stats != 0)) { |
332 | 0 | ret = _sr_events_list.pkg_update_stats(evp); |
333 | 0 | return ret; |
334 | 0 | } else |
335 | 0 | return 1; |
336 | 0 | case SREV_NET_DGRAM_IN: |
337 | 0 | if(unlikely(_sr_events_list.net_dgram_in != 0)) { |
338 | 0 | ret = _sr_events_list.net_dgram_in(evp); |
339 | 0 | return ret; |
340 | 0 | } else |
341 | 0 | return 1; |
342 | 0 | case SREV_TCP_HTTP_100C: |
343 | 0 | if(unlikely(_sr_events_list.tcp_http_100c != 0)) { |
344 | 0 | ret = _sr_events_list.tcp_http_100c(evp); |
345 | 0 | return ret; |
346 | 0 | } else |
347 | 0 | return 1; |
348 | 0 | case SREV_TCP_MSRP_FRAME: |
349 | 0 | if(unlikely(_sr_events_list.tcp_msrp_frame != 0)) { |
350 | 0 | ret = _sr_events_list.tcp_msrp_frame(evp); |
351 | 0 | return ret; |
352 | 0 | } else |
353 | 0 | return 1; |
354 | 0 | case SREV_TCP_WS_FRAME_IN: |
355 | 0 | if(unlikely(_sr_events_list.tcp_ws_frame_in != 0)) { |
356 | 0 | ret = _sr_events_list.tcp_ws_frame_in(evp); |
357 | 0 | return ret; |
358 | 0 | } else |
359 | 0 | return 1; |
360 | 0 | case SREV_TCP_WS_FRAME_OUT: |
361 | 0 | if(unlikely(_sr_events_list.tcp_ws_frame_out != 0)) { |
362 | 0 | ret = _sr_events_list.tcp_ws_frame_out(evp); |
363 | 0 | return ret; |
364 | 0 | } else |
365 | 0 | return 1; |
366 | 0 | case SREV_STUN_IN: |
367 | 0 | if(unlikely(_sr_events_list.stun_in != 0)) { |
368 | 0 | ret = _sr_events_list.stun_in(evp); |
369 | 0 | return ret; |
370 | 0 | } else |
371 | 0 | return 1; |
372 | 0 | case SREV_RCV_NOSIP: |
373 | 0 | if(unlikely(_sr_events_list.rcv_nosip != 0)) { |
374 | 0 | ret = _sr_events_list.rcv_nosip(evp); |
375 | 0 | return ret; |
376 | 0 | } else |
377 | 0 | return 1; |
378 | 0 | case SREV_TCP_CLOSED: |
379 | 0 | if(unlikely(_sr_events_list.tcp_closed[0] != 0)) { |
380 | 0 | ret = 0; |
381 | 0 | for(i = 0; |
382 | 0 | i < SREV_CB_LIST_SIZE && _sr_events_list.tcp_closed[i]; |
383 | 0 | i++) { |
384 | 0 | ret |= _sr_events_list.tcp_closed[i](evp); |
385 | 0 | } |
386 | 0 | return ret; |
387 | 0 | } else |
388 | 0 | return 1; |
389 | 0 | case SREV_NET_DATA_RECV: |
390 | 0 | if(unlikely(_sr_events_list.net_data_recv != 0)) { |
391 | 0 | ret = _sr_events_list.net_data_recv(evp); |
392 | 0 | return ret; |
393 | 0 | } else |
394 | 0 | return 1; |
395 | 0 | case SREV_NET_DATA_SENT: |
396 | 0 | if(unlikely(_sr_events_list.net_data_sent != 0)) { |
397 | 0 | ret = _sr_events_list.net_data_sent(evp); |
398 | 0 | return ret; |
399 | 0 | } else |
400 | 0 | return 1; |
401 | 0 | case SREV_SIP_REPLY_OUT: |
402 | 0 | if(unlikely(_sr_events_list.sip_reply_out[0] != 0)) { |
403 | 0 | ret = 0; |
404 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE |
405 | 0 | && _sr_events_list.sip_reply_out[i]; |
406 | 0 | i++) { |
407 | 0 | ret |= _sr_events_list.sip_reply_out[i](evp); |
408 | 0 | } |
409 | 0 | return ret; |
410 | 0 | } else |
411 | 0 | return 1; |
412 | 0 | case SREV_TCP_WS_CLOSE: |
413 | 0 | if(unlikely(_sr_events_list.tcp_ws_close[0] != 0)) { |
414 | 0 | ret = 0; |
415 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE |
416 | 0 | && _sr_events_list.tcp_ws_close[i]; |
417 | 0 | i++) { |
418 | 0 | ret = _sr_events_list.tcp_ws_close[i](evp); |
419 | 0 | } |
420 | 0 | return ret; |
421 | 0 | } else |
422 | 0 | return 1; |
423 | 0 | default: |
424 | 0 | return -1; |
425 | 56.2k | } |
426 | 56.2k | } |
427 | | |
428 | | /** |
429 | | * |
430 | | */ |
431 | | int sr_event_enabled(int type) |
432 | 0 | { |
433 | 0 | switch(type) { |
434 | 0 | case SREV_NET_DATA_IN: |
435 | 0 | return (_sr_events_list.net_data_in[0] != 0) ? 1 : 0; |
436 | 0 | case SREV_NET_DATA_OUT: |
437 | 0 | return (_sr_events_list.net_data_out[SREV_CB_LIST_SIZE - 1] != 0) |
438 | 0 | ? 1 |
439 | 0 | : 0; |
440 | 0 | case SREV_CORE_STATS: |
441 | 0 | return (_sr_events_list.core_stats != 0) ? 1 : 0; |
442 | 0 | case SREV_CFG_RUN_ACTION: |
443 | 0 | return (_sr_events_list.run_action != 0) ? 1 : 0; |
444 | 0 | case SREV_PKG_UPDATE_STATS: |
445 | 0 | return (_sr_events_list.pkg_update_stats != 0) ? 1 : 0; |
446 | 0 | case SREV_NET_DGRAM_IN: |
447 | 0 | return (_sr_events_list.net_dgram_in != 0) ? 1 : 0; |
448 | 0 | case SREV_TCP_HTTP_100C: |
449 | 0 | return (_sr_events_list.tcp_http_100c != 0) ? 1 : 0; |
450 | 0 | case SREV_TCP_MSRP_FRAME: |
451 | 0 | return (_sr_events_list.tcp_msrp_frame != 0) ? 1 : 0; |
452 | 0 | case SREV_TCP_WS_FRAME_IN: |
453 | 0 | return (_sr_events_list.tcp_ws_frame_in != 0) ? 1 : 0; |
454 | 0 | case SREV_TCP_WS_FRAME_OUT: |
455 | 0 | return (_sr_events_list.tcp_ws_frame_out != 0) ? 1 : 0; |
456 | 0 | case SREV_STUN_IN: |
457 | 0 | return (_sr_events_list.stun_in != 0) ? 1 : 0; |
458 | 0 | case SREV_RCV_NOSIP: |
459 | 0 | return (_sr_events_list.rcv_nosip != 0) ? 1 : 0; |
460 | 0 | case SREV_TCP_CLOSED: |
461 | 0 | return (_sr_events_list.tcp_closed[0] != 0) ? 1 : 0; |
462 | 0 | case SREV_NET_DATA_RECV: |
463 | 0 | return (_sr_events_list.net_data_recv != 0) ? 1 : 0; |
464 | 0 | case SREV_NET_DATA_SENT: |
465 | 0 | return (_sr_events_list.net_data_sent != 0) ? 1 : 0; |
466 | 0 | case SREV_SIP_REPLY_OUT: |
467 | 0 | return (_sr_events_list.sip_reply_out[0] != 0) ? 1 : 0; |
468 | 0 | case SREV_TCP_WS_CLOSE: |
469 | 0 | return (_sr_events_list.tcp_ws_close[0] != 0) ? 1 : 0; |
470 | 0 | } |
471 | 0 | return 0; |
472 | 0 | } |
473 | | |
474 | | |
475 | | /** |
476 | | * |
477 | | */ |
478 | | static sr_corecb_t _ksr_corecb = {0}; |
479 | | |
480 | | /** |
481 | | * |
482 | | */ |
483 | | sr_corecb_t *sr_corecb_get(void) |
484 | 0 | { |
485 | 0 | return &_ksr_corecb; |
486 | 0 | } |