Coverage Report

Created: 2025-04-11 06:11

/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
}