/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 | if(_sr_events_list.tcp_closed == 0) |
213 | 0 | _sr_events_list.tcp_closed = f; |
214 | 0 | else |
215 | 0 | return -1; |
216 | 0 | break; |
217 | 0 | case SREV_NET_DATA_RECV: |
218 | 0 | if(_sr_events_list.net_data_recv == 0) |
219 | 0 | _sr_events_list.net_data_recv = f; |
220 | 0 | else |
221 | 0 | return -1; |
222 | 0 | break; |
223 | 0 | case SREV_NET_DATA_SENT: |
224 | 0 | if(_sr_events_list.net_data_sent == 0) |
225 | 0 | _sr_events_list.net_data_sent = f; |
226 | 0 | else |
227 | 0 | return -1; |
228 | 0 | break; |
229 | 0 | case SREV_SIP_REPLY_OUT: |
230 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE; i++) { |
231 | 0 | if(_sr_events_list.sip_reply_out[i] == 0) { |
232 | 0 | _sr_events_list.sip_reply_out[i] = f; |
233 | 0 | break; |
234 | 0 | } |
235 | 0 | } |
236 | 0 | if(i == SREV_CB_LIST_SIZE) |
237 | 0 | return -1; |
238 | 0 | break; |
239 | 0 | case SREV_TCP_WS_CLOSE: |
240 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE; i++) { |
241 | 0 | if(_sr_events_list.tcp_ws_close[i] == 0) { |
242 | 0 | _sr_events_list.tcp_ws_close[i] = f; |
243 | 0 | break; |
244 | 0 | } |
245 | 0 | } |
246 | 0 | if(i == SREV_CB_LIST_SIZE) |
247 | 0 | return -1; |
248 | 0 | break; |
249 | 0 | default: |
250 | 0 | return -1; |
251 | 0 | } |
252 | 0 | return 0; |
253 | 0 | } |
254 | | |
255 | | /** |
256 | | * |
257 | | */ |
258 | | int sr_event_exec(int type, sr_event_param_t *evp) |
259 | 56.1k | { |
260 | 56.1k | int ret; |
261 | 56.1k | int i; |
262 | | #ifdef EXTRA_DEBUG |
263 | | str *p; |
264 | | #endif /* EXTRA_DEBUG */ |
265 | 56.1k | switch(type) { |
266 | 0 | case SREV_NET_DATA_IN: |
267 | 0 | if(unlikely(_sr_events_list.net_data_in[0] != 0)) { |
268 | | #ifdef EXTRA_DEBUG |
269 | | p = (str *)evp->data; |
270 | | LM_DBG("PRE-IN ++++++++++++++++++++++++++++++++\n" |
271 | | "%.*s\n+++++\n", |
272 | | p->len, p->s); |
273 | | #endif /* EXTRA_DEBUG */ |
274 | 0 | ret = 0; |
275 | 0 | for(i = 0; |
276 | 0 | i < SREV_CB_LIST_SIZE && _sr_events_list.net_data_in[i]; |
277 | 0 | i++) { |
278 | 0 | ret |= _sr_events_list.net_data_in[i](evp); |
279 | 0 | } |
280 | | #ifdef EXTRA_DEBUG |
281 | | LM_DBG("POST-IN ++++++++++++++++++++++++++++++++\n" |
282 | | "%.*s\n+++++\n", |
283 | | p->len, p->s); |
284 | | #endif /* EXTRA_DEBUG */ |
285 | 0 | return ret; |
286 | 0 | } else |
287 | 0 | return 1; |
288 | 0 | break; |
289 | 0 | case SREV_NET_DATA_OUT: |
290 | 0 | if(unlikely(_sr_events_list.net_data_out[SREV_CB_LIST_SIZE - 1] |
291 | 0 | != 0)) { |
292 | | #ifdef EXTRA_DEBUG |
293 | | p = (str *)evp->data; |
294 | | LM_DBG("PRE-OUT ++++++++++++++++++++\n" |
295 | | "%.*s\n+++++++++++++++++++\n", |
296 | | p->len, p->s); |
297 | | #endif /* EXTRA_DEBUG */ |
298 | 0 | ret = 0; |
299 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE; i++) { |
300 | 0 | if(_sr_events_list.net_data_out[i]) { |
301 | 0 | ret |= _sr_events_list.net_data_out[i](evp); |
302 | 0 | } |
303 | 0 | } |
304 | | #ifdef EXTRA_DEBUG |
305 | | LM_DBG("POST-OUT ++++++++++++++++++++\n" |
306 | | "%.*s\n+++++++++++++++++++\n", |
307 | | p->len, p->s); |
308 | | #endif /* EXTRA_DEBUG */ |
309 | 0 | return ret; |
310 | 0 | } else |
311 | 0 | return 1; |
312 | 0 | break; |
313 | 56.1k | case SREV_CORE_STATS: |
314 | 56.1k | if(unlikely(_sr_events_list.core_stats != 0)) { |
315 | 0 | ret = _sr_events_list.core_stats(evp); |
316 | 0 | return ret; |
317 | 0 | } else |
318 | 56.1k | return 1; |
319 | 0 | break; |
320 | 0 | case SREV_CFG_RUN_ACTION: |
321 | 0 | if(unlikely(_sr_events_list.run_action != 0)) { |
322 | 0 | ret = _sr_events_list.run_action(evp); |
323 | 0 | return ret; |
324 | 0 | } else |
325 | 0 | return 1; |
326 | 0 | case SREV_PKG_UPDATE_STATS: |
327 | 0 | if(unlikely(_sr_events_list.pkg_update_stats != 0)) { |
328 | 0 | ret = _sr_events_list.pkg_update_stats(evp); |
329 | 0 | return ret; |
330 | 0 | } else |
331 | 0 | return 1; |
332 | 0 | case SREV_NET_DGRAM_IN: |
333 | 0 | if(unlikely(_sr_events_list.net_dgram_in != 0)) { |
334 | 0 | ret = _sr_events_list.net_dgram_in(evp); |
335 | 0 | return ret; |
336 | 0 | } else |
337 | 0 | return 1; |
338 | 0 | case SREV_TCP_HTTP_100C: |
339 | 0 | if(unlikely(_sr_events_list.tcp_http_100c != 0)) { |
340 | 0 | ret = _sr_events_list.tcp_http_100c(evp); |
341 | 0 | return ret; |
342 | 0 | } else |
343 | 0 | return 1; |
344 | 0 | case SREV_TCP_MSRP_FRAME: |
345 | 0 | if(unlikely(_sr_events_list.tcp_msrp_frame != 0)) { |
346 | 0 | ret = _sr_events_list.tcp_msrp_frame(evp); |
347 | 0 | return ret; |
348 | 0 | } else |
349 | 0 | return 1; |
350 | 0 | case SREV_TCP_WS_FRAME_IN: |
351 | 0 | if(unlikely(_sr_events_list.tcp_ws_frame_in != 0)) { |
352 | 0 | ret = _sr_events_list.tcp_ws_frame_in(evp); |
353 | 0 | return ret; |
354 | 0 | } else |
355 | 0 | return 1; |
356 | 0 | case SREV_TCP_WS_FRAME_OUT: |
357 | 0 | if(unlikely(_sr_events_list.tcp_ws_frame_out != 0)) { |
358 | 0 | ret = _sr_events_list.tcp_ws_frame_out(evp); |
359 | 0 | return ret; |
360 | 0 | } else |
361 | 0 | return 1; |
362 | 0 | case SREV_STUN_IN: |
363 | 0 | if(unlikely(_sr_events_list.stun_in != 0)) { |
364 | 0 | ret = _sr_events_list.stun_in(evp); |
365 | 0 | return ret; |
366 | 0 | } else |
367 | 0 | return 1; |
368 | 0 | case SREV_RCV_NOSIP: |
369 | 0 | if(unlikely(_sr_events_list.rcv_nosip != 0)) { |
370 | 0 | ret = _sr_events_list.rcv_nosip(evp); |
371 | 0 | return ret; |
372 | 0 | } else |
373 | 0 | return 1; |
374 | 0 | case SREV_TCP_CLOSED: |
375 | 0 | if(unlikely(_sr_events_list.tcp_closed != 0)) { |
376 | 0 | ret = _sr_events_list.tcp_closed(evp); |
377 | 0 | return ret; |
378 | 0 | } else |
379 | 0 | return 1; |
380 | 0 | case SREV_NET_DATA_RECV: |
381 | 0 | if(unlikely(_sr_events_list.net_data_recv != 0)) { |
382 | 0 | ret = _sr_events_list.net_data_recv(evp); |
383 | 0 | return ret; |
384 | 0 | } else |
385 | 0 | return 1; |
386 | 0 | case SREV_NET_DATA_SENT: |
387 | 0 | if(unlikely(_sr_events_list.net_data_sent != 0)) { |
388 | 0 | ret = _sr_events_list.net_data_sent(evp); |
389 | 0 | return ret; |
390 | 0 | } else |
391 | 0 | return 1; |
392 | 0 | case SREV_SIP_REPLY_OUT: |
393 | 0 | if(unlikely(_sr_events_list.sip_reply_out[0] != 0)) { |
394 | 0 | ret = 0; |
395 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE |
396 | 0 | && _sr_events_list.sip_reply_out[i]; |
397 | 0 | i++) { |
398 | 0 | ret |= _sr_events_list.sip_reply_out[i](evp); |
399 | 0 | } |
400 | 0 | return ret; |
401 | 0 | } else |
402 | 0 | return 1; |
403 | 0 | case SREV_TCP_WS_CLOSE: |
404 | 0 | if(unlikely(_sr_events_list.tcp_ws_close[0] != 0)) { |
405 | 0 | ret = 0; |
406 | 0 | for(i = 0; i < SREV_CB_LIST_SIZE |
407 | 0 | && _sr_events_list.tcp_ws_close[i]; |
408 | 0 | i++) { |
409 | 0 | ret = _sr_events_list.tcp_ws_close[i](evp); |
410 | 0 | } |
411 | 0 | return ret; |
412 | 0 | } else |
413 | 0 | return 1; |
414 | 0 | default: |
415 | 0 | return -1; |
416 | 56.1k | } |
417 | 56.1k | } |
418 | | |
419 | | /** |
420 | | * |
421 | | */ |
422 | | int sr_event_enabled(int type) |
423 | 0 | { |
424 | 0 | switch(type) { |
425 | 0 | case SREV_NET_DATA_IN: |
426 | 0 | return (_sr_events_list.net_data_in[0] != 0) ? 1 : 0; |
427 | 0 | case SREV_NET_DATA_OUT: |
428 | 0 | return (_sr_events_list.net_data_out[SREV_CB_LIST_SIZE - 1] != 0) |
429 | 0 | ? 1 |
430 | 0 | : 0; |
431 | 0 | case SREV_CORE_STATS: |
432 | 0 | return (_sr_events_list.core_stats != 0) ? 1 : 0; |
433 | 0 | case SREV_CFG_RUN_ACTION: |
434 | 0 | return (_sr_events_list.run_action != 0) ? 1 : 0; |
435 | 0 | case SREV_PKG_UPDATE_STATS: |
436 | 0 | return (_sr_events_list.pkg_update_stats != 0) ? 1 : 0; |
437 | 0 | case SREV_NET_DGRAM_IN: |
438 | 0 | return (_sr_events_list.net_dgram_in != 0) ? 1 : 0; |
439 | 0 | case SREV_TCP_HTTP_100C: |
440 | 0 | return (_sr_events_list.tcp_http_100c != 0) ? 1 : 0; |
441 | 0 | case SREV_TCP_MSRP_FRAME: |
442 | 0 | return (_sr_events_list.tcp_msrp_frame != 0) ? 1 : 0; |
443 | 0 | case SREV_TCP_WS_FRAME_IN: |
444 | 0 | return (_sr_events_list.tcp_ws_frame_in != 0) ? 1 : 0; |
445 | 0 | case SREV_TCP_WS_FRAME_OUT: |
446 | 0 | return (_sr_events_list.tcp_ws_frame_out != 0) ? 1 : 0; |
447 | 0 | case SREV_STUN_IN: |
448 | 0 | return (_sr_events_list.stun_in != 0) ? 1 : 0; |
449 | 0 | case SREV_RCV_NOSIP: |
450 | 0 | return (_sr_events_list.rcv_nosip != 0) ? 1 : 0; |
451 | 0 | case SREV_TCP_CLOSED: |
452 | 0 | return (_sr_events_list.tcp_closed != 0) ? 1 : 0; |
453 | 0 | case SREV_NET_DATA_RECV: |
454 | 0 | return (_sr_events_list.net_data_recv != 0) ? 1 : 0; |
455 | 0 | case SREV_NET_DATA_SENT: |
456 | 0 | return (_sr_events_list.net_data_sent != 0) ? 1 : 0; |
457 | 0 | case SREV_SIP_REPLY_OUT: |
458 | 0 | return (_sr_events_list.sip_reply_out[0] != 0) ? 1 : 0; |
459 | 0 | case SREV_TCP_WS_CLOSE: |
460 | 0 | return (_sr_events_list.tcp_ws_close[0] != 0) ? 1 : 0; |
461 | 0 | } |
462 | 0 | return 0; |
463 | 0 | } |
464 | | |
465 | | |
466 | | /** |
467 | | * |
468 | | */ |
469 | | static sr_corecb_t _ksr_corecb = {0}; |
470 | | |
471 | | /** |
472 | | * |
473 | | */ |
474 | | sr_corecb_t *sr_corecb_get(void) |
475 | 0 | { |
476 | 0 | return &_ksr_corecb; |
477 | 0 | } |