Coverage Report

Created: 2025-06-09 06:27

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