Coverage Report

Created: 2025-06-09 06:27

/src/kamailio/src/core/receive.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2001-2003 FhG Fokus
3
 *
4
 * This file is part of Kamailio, a free SIP server.
5
 *
6
 * SPDX-License-Identifier: GPL-2.0-or-later
7
 *
8
 * Kamailio is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version
12
 *
13
 * Kamailio is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
 *
22
 */
23
24
/*!
25
 * \file
26
 * \brief Kamailio core ::
27
 * \ingroup core
28
 * Module: \ref core
29
 */
30
31
32
#include <string.h>
33
#include <stdlib.h>
34
#include <sys/time.h>
35
36
#include "receive.h"
37
#include "globals.h"
38
#include "dprint.h"
39
#include "route.h"
40
#include "parser/msg_parser.h"
41
#include "forward.h"
42
#include "action.h"
43
#include "mem/mem.h"
44
#include "ip_addr.h"
45
#include "script_cb.h"
46
#include "nonsip_hooks.h"
47
#include "dset.h"
48
#include "fmsg.h"
49
#include "usr_avp.h"
50
#include "xavp.h"
51
#include "select_buf.h"
52
#include "locking.h"
53
54
#include "tcp_server.h"  /* for tcpconn_add_alias */
55
#include "tcp_options.h" /* for access to tcp_accept_aliases*/
56
#include "cfg/cfg.h"
57
#include "core_stats.h"
58
#include "kemi.h"
59
60
#ifdef DEBUG_DMALLOC
61
#include <mem/dmalloc.h>
62
#endif
63
64
int _sr_ip_free_bind = 0;
65
66
unsigned int msg_no = 0;
67
/* address preset vars */
68
str default_global_address = {0, 0};
69
str default_global_port = {0, 0};
70
str default_via_address = {0, 0};
71
str default_via_port = {0, 0};
72
73
int ksr_route_locks_size = 0;
74
static rec_lock_set_t *ksr_route_locks_set = NULL;
75
76
int ksr_route_locks_set_init(void)
77
0
{
78
0
  if(ksr_route_locks_set != NULL || ksr_route_locks_size <= 0)
79
0
    return 0;
80
81
0
  ksr_route_locks_set = rec_lock_set_alloc(ksr_route_locks_size);
82
0
  if(ksr_route_locks_set == NULL) {
83
0
    LM_ERR("failed to allocate route locks set\n");
84
0
    return -1;
85
0
  }
86
0
  if(rec_lock_set_init(ksr_route_locks_set) == NULL) {
87
0
    LM_ERR("failed to init route locks set\n");
88
0
    return -1;
89
0
  }
90
0
  return 0;
91
0
}
92
93
void ksr_route_locks_set_destroy(void)
94
0
{
95
0
  if(ksr_route_locks_set == NULL)
96
0
    return;
97
98
0
  rec_lock_set_destroy(ksr_route_locks_set);
99
0
  rec_lock_set_dealloc(ksr_route_locks_set);
100
0
  ksr_route_locks_set = NULL;
101
0
}
102
103
/**
104
 * increment msg_no and return the new value
105
 */
106
unsigned int inc_msg_no(void)
107
0
{
108
0
  return ++msg_no;
109
0
}
110
111
/**
112
 *
113
 */
114
int sip_check_fline(char *buf, unsigned int len)
115
0
{
116
0
  char *p;
117
0
  int m;
118
119
0
  m = 0;
120
0
  for(p = buf; p < buf + len; p++) {
121
    /* first check if is a reply - starts with SIP/2.0 */
122
0
    if(m == 0) {
123
0
      if(*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
124
0
        continue;
125
0
      if(buf + len - p < 10)
126
0
        return -1;
127
0
      if(strncmp(p, "SIP/2.0 ", 8) == 0) {
128
0
        LM_DBG("first line indicates a SIP reply\n");
129
0
        return 0;
130
0
      }
131
0
      m = 1;
132
0
    } else {
133
      /* check if a request - before end of first line is SIP/2.0 */
134
0
      if(*p != '\r' && *p != '\n')
135
0
        continue;
136
0
      if(p - 10 >= buf) {
137
0
        if(strncmp(p - 8, " SIP/2.0", 8) == 0) {
138
0
          LM_DBG("first line indicates a SIP request\n");
139
0
          return 0;
140
0
        }
141
0
      }
142
0
      return -1;
143
0
    }
144
0
  }
145
0
  return -1;
146
0
}
147
148
/**
149
 *
150
 */
151
static sr_net_info_t *ksr_evrt_rcvnetinfo = NULL;
152
int ksr_evrt_received_mode = 0;
153
str kemi_received_route_callback = STR_NULL;
154
155
/**
156
 *
157
 */
158
sr_net_info_t *ksr_evrt_rcvnetinfo_get(void)
159
0
{
160
0
  return ksr_evrt_rcvnetinfo;
161
0
}
162
163
/**
164
 *
165
 */
166
int ksr_evrt_received(char *buf, unsigned int *len, receive_info_t *rcv_info)
167
0
{
168
0
  sr_kemi_eng_t *keng = NULL;
169
0
  sr_net_info_t netinfo;
170
0
  int ret = 0;
171
0
  int rt = -1;
172
0
  run_act_ctx_t ra_ctx;
173
0
  run_act_ctx_t *bctx = NULL;
174
0
  sip_msg_t *fmsg = NULL;
175
0
  str evname = str_init("core:msg-received");
176
177
0
  if(len == 0 || rcv_info == NULL || buf == NULL) {
178
0
    LM_ERR("required parameters are not available\n");
179
0
    return -1;
180
0
  }
181
182
0
  if(kemi_received_route_callback.len > 0) {
183
0
    keng = sr_kemi_eng_get();
184
0
    if(keng == NULL) {
185
0
      LM_DBG("kemi enabled with no core:msg-receive event route "
186
0
           "callback\n");
187
0
      return 0;
188
0
    }
189
0
  } else {
190
0
    rt = route_lookup(&event_rt, evname.s);
191
0
    if(rt < 0 || event_rt.rlist[rt] == NULL) {
192
0
      LM_DBG("event route core:msg-received not defined\n");
193
0
      return 0;
194
0
    }
195
0
  }
196
0
  memset(&netinfo, 0, sizeof(sr_net_info_t));
197
0
  netinfo.data.s = buf;
198
0
  netinfo.data.len = *len;
199
0
  netinfo.bufsize = BUF_SIZE;
200
0
  netinfo.rcv = rcv_info;
201
202
0
  ksr_evrt_rcvnetinfo = &netinfo;
203
0
  set_route_type(REQUEST_ROUTE);
204
0
  fmsg = faked_msg_get_next();
205
0
  init_run_actions_ctx(&ra_ctx);
206
0
  if(keng) {
207
0
    bctx = sr_kemi_act_ctx_get();
208
0
    sr_kemi_act_ctx_set(&ra_ctx);
209
0
    ret = sr_kemi_route(
210
0
        keng, fmsg, REQUEST_ROUTE, &kemi_received_route_callback, NULL);
211
0
    sr_kemi_act_ctx_set(bctx);
212
0
  } else {
213
0
    ret = run_actions(&ra_ctx, event_rt.rlist[rt], fmsg);
214
0
  }
215
0
  if(ra_ctx.run_flags & DROP_R_F) {
216
0
    LM_DBG("dropping received message\n");
217
0
    ret = -1;
218
0
  }
219
0
  *len = netinfo.data.len;
220
0
  ksr_evrt_rcvnetinfo = NULL;
221
222
0
  return ret;
223
0
}
224
225
226
static int ksr_evrt_pre_routing_idx = -1;
227
str kemi_pre_routing_callback = STR_NULL;
228
229
230
/**
231
 *
232
 */
233
int ksr_evrt_pre_routing(sip_msg_t *msg)
234
0
{
235
0
  int ret = 0;
236
0
  int rt = -1;
237
0
  run_act_ctx_t ra_ctx;
238
0
  run_act_ctx_t *bctx = NULL;
239
0
  sr_kemi_eng_t *keng = NULL;
240
0
  str evname = str_init("core:pre-routing");
241
0
  recv_flags_t brflags;
242
243
0
  if(msg->rcv.rflags & RECV_F_INTERNAL) {
244
0
    DBG("skip internal routed message\n");
245
0
    return 0;
246
0
  }
247
248
0
  if(kemi_pre_routing_callback.len > 0) {
249
0
    keng = sr_kemi_eng_get();
250
0
    if(keng == NULL) {
251
0
      LM_DBG("kemi enabled with no core:pre-routing event route "
252
0
           "callback\n");
253
0
      return 0;
254
0
    }
255
0
  } else {
256
0
    if(ksr_evrt_pre_routing_idx == -1) {
257
0
      rt = route_lookup(&event_rt, evname.s);
258
0
      if(rt < 0 || event_rt.rlist[rt] == NULL) {
259
0
        ksr_evrt_pre_routing_idx = -2;
260
0
      }
261
0
    } else {
262
0
      rt = ksr_evrt_pre_routing_idx;
263
0
    }
264
0
    if(rt < 0 || event_rt.rlist[rt] == NULL) {
265
0
      LM_DBG("event route core:pre-routing not defined\n");
266
0
      return 0;
267
0
    }
268
0
  }
269
270
0
  set_route_type(REQUEST_ROUTE);
271
0
  init_run_actions_ctx(&ra_ctx);
272
0
  brflags = msg->rcv.rflags;
273
0
  msg->rcv.rflags |= RECV_F_PREROUTING;
274
0
  if(keng) {
275
0
    bctx = sr_kemi_act_ctx_get();
276
0
    sr_kemi_act_ctx_set(&ra_ctx);
277
0
    ret = sr_kemi_route(
278
0
        keng, msg, REQUEST_ROUTE, &kemi_pre_routing_callback, &evname);
279
0
    sr_kemi_act_ctx_set(bctx);
280
0
  } else {
281
0
    ret = run_actions(&ra_ctx, event_rt.rlist[rt], msg);
282
0
  }
283
0
  msg->rcv.rflags = brflags;
284
0
  if(ra_ctx.run_flags & DROP_R_F) {
285
0
    LM_DBG("drop was used\n");
286
0
    return 1;
287
0
  }
288
0
  LM_DBG("execution returned %d\n", ret);
289
290
0
  return 0;
291
0
}
292
293
/** Receive message
294
 *  WARNING: buf must be 0 terminated (buf[len]=0) or some things might
295
 * break (e.g.: modules/textops)
296
 */
297
int receive_msg(char *buf, unsigned int len, receive_info_t *rcv_info)
298
0
{
299
0
  struct sip_msg *msg = NULL;
300
0
  struct run_act_ctx ctx;
301
0
  struct run_act_ctx *bctx = NULL;
302
0
  int ret = -1;
303
0
  struct timeval tvb = {0}, tve = {0};
304
0
  unsigned int diff = 0;
305
0
  str inb = STR_NULL;
306
0
  sr_net_info_t netinfo = {0};
307
0
  sr_kemi_eng_t *keng = NULL;
308
0
  sr_event_param_t evp = {0};
309
0
  unsigned int cidlockidx = 0;
310
0
  unsigned int cidlockset = 0;
311
0
  int errsipmsg = 0;
312
0
  int exectime = 0;
313
314
0
  if(rcv_info->bind_address == NULL) {
315
0
    LM_ERR("critical - incoming message without local socket [%.*s ...]\n",
316
0
        (len > 128) ? 128 : len, buf);
317
0
    return -1;
318
0
  }
319
320
0
  if(ksr_evrt_received_mode != 0) {
321
0
    if(ksr_evrt_received(buf, &len, rcv_info) < 0) {
322
0
      LM_DBG("dropping the received message\n");
323
0
      goto error00;
324
0
    }
325
0
  }
326
0
  if(sr_event_enabled(SREV_NET_DATA_RECV)) {
327
0
    if(sip_check_fline(buf, len) == 0) {
328
0
      memset(&netinfo, 0, sizeof(sr_net_info_t));
329
0
      netinfo.data.s = buf;
330
0
      netinfo.data.len = len;
331
0
      netinfo.rcv = rcv_info;
332
0
      evp.data = (void *)&netinfo;
333
0
      sr_event_exec(SREV_NET_DATA_RECV, &evp);
334
0
    }
335
0
  }
336
337
0
  inb.s = buf;
338
0
  inb.len = len;
339
0
  evp.data = (void *)&inb;
340
0
  evp.rcv = rcv_info;
341
0
  sr_event_exec(SREV_NET_DATA_IN, &evp);
342
0
  len = inb.len;
343
344
0
  msg = pkg_malloc(sizeof(struct sip_msg));
345
0
  if(unlikely(msg == 0)) {
346
0
    PKG_MEM_ERROR;
347
0
    goto error00;
348
0
  }
349
0
  msg_no++;
350
  /* number of vias parsed -- good for diagnostic info in replies */
351
0
  via_cnt = 0;
352
353
0
  memset(msg, 0, sizeof(struct sip_msg)); /* init everything to 0 */
354
  /* fill in msg */
355
0
  msg->buf = buf;
356
0
  msg->len = len;
357
  /* zero termination (termination of orig message below not that
358
   * useful as most of the work is done with scratch-pad; -jiri  */
359
  /* buf[len]=0; */ /* WARNING: zero term removed! */
360
0
  msg->rcv = *rcv_info;
361
0
  msg->id = msg_no;
362
0
  msg->pid = my_pid();
363
0
  msg->set_global_address = default_global_address;
364
0
  msg->set_global_port = default_global_port;
365
366
0
  if(likely(sr_msg_time == 1))
367
0
    msg_set_time(msg);
368
369
0
  if(parse_msg(buf, len, msg) != 0) {
370
0
    errsipmsg = 1;
371
0
    evp.data = (void *)msg;
372
0
    if((ret = sr_event_exec(SREV_RCV_NOSIP, &evp)) < NONSIP_MSG_DROP) {
373
0
      LM_DBG("attempt of nonsip message processing failed\n");
374
0
    } else if(ret == NONSIP_MSG_DROP) {
375
0
      LM_DBG("nonsip message processing completed\n");
376
0
      goto end;
377
0
    }
378
0
  }
379
0
  if(errsipmsg == 1) {
380
0
    LOG(cfg_get(core, core_cfg, sip_parser_log),
381
0
        "core parsing of SIP message failed (%s:%d/%d)\n",
382
0
        ip_addr2a(&msg->rcv.src_ip), (int)msg->rcv.src_port,
383
0
        (int)msg->rcv.proto);
384
0
    sr_core_ert_run(msg, SR_CORE_ERT_RECEIVE_PARSE_ERROR);
385
0
    goto error02;
386
0
  }
387
388
0
  if(unlikely(parse_headers(msg,
389
0
            HDR_FROM_F | HDR_TO_F | HDR_CALLID_F | HDR_CSEQ_F, 0)
390
0
        < 0)) {
391
0
    LOG(cfg_get(core, core_cfg, sip_parser_log),
392
0
        "parsing relevant headers failed\n");
393
0
  }
394
0
  LM_DBG("--- received sip message - %s - call-id: [%.*s] - cseq: [%.*s]\n",
395
0
      (msg->first_line.type == SIP_REQUEST) ? "request" : "reply",
396
0
      (msg->callid && msg->callid->body.s) ? msg->callid->body.len : 0,
397
0
      (msg->callid && msg->callid->body.s) ? msg->callid->body.s : "",
398
0
      (msg->cseq && msg->cseq->body.s) ? msg->cseq->body.len : 0,
399
0
      (msg->cseq && msg->cseq->body.s) ? msg->cseq->body.s : "");
400
401
  /* set log prefix */
402
0
  log_prefix_set(msg);
403
404
  /* ... clear branches from previous message */
405
0
  clear_branches();
406
407
0
  ret = ksr_evrt_pre_routing(msg);
408
0
  if(ret < 0) {
409
0
    goto error02;
410
0
  }
411
0
  if(ret == 1) {
412
    /* finished */
413
0
    goto end;
414
0
  }
415
416
0
  if(unlikely(ksr_route_locks_set != NULL && msg->callid
417
0
        && msg->callid->body.s && msg->callid->body.len > 0)) {
418
0
    cidlockidx = get_hash1_raw(msg->callid->body.s, msg->callid->body.len);
419
0
    cidlockidx = cidlockidx % ksr_route_locks_set->size;
420
0
    cidlockset = 1;
421
0
  }
422
423
424
0
  if(is_printable(cfg_get(core, core_cfg, latency_cfg_log))) {
425
0
    exectime = 1;
426
0
  }
427
428
0
  if(msg->first_line.type == SIP_REQUEST) {
429
0
    ruri_mark_new(); /* ruri is usable for forking (not consumed yet) */
430
0
    if(!IS_SIP(msg)) {
431
0
      LM_DBG("handling non-sip request message\n");
432
0
      if((ret = nonsip_msg_run_hooks(msg)) != NONSIP_MSG_ACCEPT) {
433
0
        if(unlikely(ret == NONSIP_MSG_ERROR)) {
434
0
          LM_DBG("failed handling non-sip request message\n");
435
0
          goto error03;
436
0
        }
437
0
        LM_DBG("finished handling non-sip request message\n");
438
0
        goto end; /* drop the message */
439
0
      }
440
0
    }
441
    /* sanity checks */
442
0
    if(unlikely((msg->via1 == 0) || (msg->via1->error != PARSE_OK))) {
443
      /* no via, send back error ? */
444
0
      LOG(cfg_get(core, core_cfg, sip_parser_log),
445
0
          "no via found in request\n");
446
0
      STATS_BAD_MSG();
447
0
      goto error02;
448
0
    }
449
0
    if(unlikely((msg->callid == 0) || (msg->cseq == 0) || (msg->from == 0)
450
0
          || (msg->to == 0))) {
451
      /* no required headers -- send back error ? */
452
0
      LOG(cfg_get(core, core_cfg, sip_parser_log),
453
0
          "required headers not found in request\n");
454
0
      STATS_BAD_MSG();
455
0
      goto error02;
456
0
    }
457
/* check if necessary to add receive?->moved to forward_req */
458
/* check for the alias stuff */
459
0
#ifdef USE_TCP
460
0
    if(msg->via1->alias && cfg_get(tcp, tcp_cfg, accept_aliases)
461
0
        && (((rcv_info->proto == PROTO_TCP) && !tcp_disable)
462
0
#ifdef USE_TLS
463
0
            || ((rcv_info->proto == PROTO_TLS) && !tls_disable)
464
0
#endif
465
0
                )) {
466
0
      if(tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
467
0
             rcv_info->proto)
468
0
          != 0) {
469
0
        LM_ERR("tcp alias failed\n");
470
        /* continue */
471
0
      }
472
0
    }
473
0
#endif
474
475
    /*  skip: */
476
0
    LM_DBG("preparing to run routing scripts...\n");
477
0
    if(exectime) {
478
0
      gettimeofday(&tvb, NULL);
479
0
    }
480
    /* execute pre-script callbacks, if any; -jiri */
481
    /* if some of the callbacks said not to continue with
482
     * script processing, don't do so
483
     * if we are here basic sanity checks are already done
484
     * (like presence of at least one via), so you can count
485
     * on via1 being parsed in a pre-script callback --andrei
486
    */
487
0
    if(exec_pre_script_cb(msg, REQUEST_CB_TYPE) == 0) {
488
0
      STATS_REQ_FWD_DROP();
489
0
      goto end; /* drop the request */
490
0
    }
491
492
0
    set_route_type(REQUEST_ROUTE);
493
    /* exec the routing script */
494
0
    if(unlikely(main_rt.rlist[DEFAULT_RT] == NULL)) {
495
0
      keng = sr_kemi_eng_get();
496
0
      if(keng == NULL) {
497
0
        LM_ERR("no request_route {...} and no other config routing"
498
0
             " engine registered\n");
499
0
        goto error_req;
500
0
      }
501
0
      if(unlikely(cidlockset)) {
502
0
        rec_lock_set_get(ksr_route_locks_set, cidlockidx);
503
0
        if(sr_kemi_route(keng, msg, REQUEST_ROUTE, NULL, NULL) < 0)
504
0
          LM_NOTICE("negative return code from engine function\n");
505
0
        rec_lock_set_release(ksr_route_locks_set, cidlockidx);
506
0
      } else {
507
0
        if(sr_kemi_route(keng, msg, REQUEST_ROUTE, NULL, NULL) < 0)
508
0
          LM_NOTICE("negative return code from engine function\n");
509
0
      }
510
0
    } else {
511
0
      if(unlikely(cidlockset)) {
512
0
        rec_lock_set_get(ksr_route_locks_set, cidlockidx);
513
0
        if(run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0) < 0) {
514
0
          rec_lock_set_release(ksr_route_locks_set, cidlockidx);
515
0
          LM_WARN("error while trying script\n");
516
0
          goto error_req;
517
0
        }
518
0
        rec_lock_set_release(ksr_route_locks_set, cidlockidx);
519
0
      } else {
520
0
        if(run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0) < 0) {
521
0
          LM_WARN("error while trying script\n");
522
0
          goto error_req;
523
0
        }
524
0
      }
525
0
    }
526
527
0
    if(exectime) {
528
0
      gettimeofday(&tve, NULL);
529
0
      diff = (tve.tv_sec - tvb.tv_sec) * 1000000
530
0
           + (tve.tv_usec - tvb.tv_usec);
531
0
      if(cfg_get(core, core_cfg, latency_limit_cfg) == 0
532
0
          || cfg_get(core, core_cfg, latency_limit_cfg) <= diff) {
533
0
        LOG(cfg_get(core, core_cfg, latency_cfg_log),
534
0
            "request-route executed in: %d usec\n", diff);
535
0
      }
536
0
    }
537
538
    /* execute post request-script callbacks */
539
0
    exec_post_script_cb(msg, REQUEST_CB_TYPE);
540
0
  } else if(msg->first_line.type == SIP_REPLY) {
541
    /* sanity checks */
542
0
    if((msg->via1 == 0) || (msg->via1->error != PARSE_OK)) {
543
      /* no via, send back error ? */
544
0
      LM_ERR("no via found in reply\n");
545
0
      STATS_BAD_RPL();
546
0
      goto error02;
547
0
    }
548
0
    if(unlikely((msg->callid == 0) || (msg->cseq == 0) || (msg->from == 0)
549
0
          || (msg->to == 0))) {
550
      /* no required headers -- send back error ? */
551
0
      LOG(cfg_get(core, core_cfg, sip_parser_log),
552
0
          "required headers not found in reply\n");
553
0
      STATS_BAD_RPL();
554
0
      goto error02;
555
0
    }
556
557
0
    if(exectime) {
558
0
      gettimeofday(&tvb, NULL);
559
0
    }
560
561
    /* execute pre-script callbacks, if any; -jiri */
562
    /* if some of the callbacks said not to continue with
563
     * script processing, don't do so
564
     * if we are here basic sanity checks are already done
565
     * (like presence of at least one via), so you can count
566
     * on via1 being parsed in a pre-script callback --andrei
567
    */
568
0
    if(exec_pre_script_cb(msg, ONREPLY_CB_TYPE) == 0) {
569
0
      STATS_RPL_FWD_DROP();
570
0
      goto end; /* drop the reply */
571
0
    }
572
573
    /* exec the onreply routing script */
574
0
    if(kemi_reply_route_callback.len > 0) {
575
0
      keng = sr_kemi_eng_get();
576
0
    }
577
0
    if(onreply_rt.rlist[DEFAULT_RT] != NULL || keng != NULL) {
578
0
      set_route_type(CORE_ONREPLY_ROUTE);
579
0
      ret = 1;
580
0
      if(unlikely(keng != NULL)) {
581
0
        bctx = sr_kemi_act_ctx_get();
582
0
        init_run_actions_ctx(&ctx);
583
0
        sr_kemi_act_ctx_set(&ctx);
584
0
        if(unlikely(cidlockset)) {
585
0
          rec_lock_set_get(ksr_route_locks_set, cidlockidx);
586
0
          ret = sr_kemi_route(
587
0
              keng, msg, CORE_ONREPLY_ROUTE, NULL, NULL);
588
0
          rec_lock_set_release(ksr_route_locks_set, cidlockidx);
589
0
        } else {
590
0
          ret = sr_kemi_route(
591
0
              keng, msg, CORE_ONREPLY_ROUTE, NULL, NULL);
592
0
        }
593
0
        sr_kemi_act_ctx_set(bctx);
594
0
      } else {
595
0
        if(unlikely(cidlockset)) {
596
0
          rec_lock_set_get(ksr_route_locks_set, cidlockidx);
597
0
          ret = run_top_route(
598
0
              onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
599
0
          rec_lock_set_release(ksr_route_locks_set, cidlockidx);
600
0
        } else {
601
0
          ret = run_top_route(
602
0
              onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
603
0
        }
604
0
      }
605
0
#ifndef NO_ONREPLY_ROUTE_ERROR
606
0
      if(unlikely(ret < 0)) {
607
0
        LM_WARN("error while trying onreply script\n");
608
0
        goto error_rpl;
609
0
      } else
610
0
#endif /* NO_ONREPLY_ROUTE_ERROR */
611
0
        if(unlikely(ret == 0 || (ctx.run_flags & DROP_R_F))) {
612
0
          STATS_RPL_FWD_DROP();
613
0
          LM_DBG("drop flag set - skip forwarding the reply\n");
614
0
          goto skip_send_reply; /* drop the message, no error */
615
0
        }
616
0
    }
617
    /* send the msg */
618
0
    forward_reply(msg);
619
0
  skip_send_reply:
620
0
    if(exectime) {
621
0
      gettimeofday(&tve, NULL);
622
0
      diff = (tve.tv_sec - tvb.tv_sec) * 1000000
623
0
           + (tve.tv_usec - tvb.tv_usec);
624
0
      if(cfg_get(core, core_cfg, latency_limit_cfg) == 0
625
0
          || cfg_get(core, core_cfg, latency_limit_cfg) <= diff) {
626
0
        LOG(cfg_get(core, core_cfg, latency_cfg_log),
627
0
            "reply-route executed in: %d usec\n", diff);
628
0
      }
629
0
    }
630
631
    /* execute post reply-script callbacks */
632
0
    exec_post_script_cb(msg, ONREPLY_CB_TYPE);
633
0
  }
634
635
0
end:
636
0
  ksr_msg_env_reset();
637
0
  LM_DBG("cleaning up\n");
638
0
  free_sip_msg(msg);
639
0
  pkg_free(msg);
640
  /* reset log prefix */
641
0
  log_prefix_set(NULL);
642
0
  return 0;
643
644
0
#ifndef NO_ONREPLY_ROUTE_ERROR
645
0
error_rpl:
646
  /* execute post reply-script callbacks */
647
0
  exec_post_script_cb(msg, ONREPLY_CB_TYPE);
648
0
  goto error02;
649
0
#endif /* NO_ONREPLY_ROUTE_ERROR */
650
0
error_req:
651
0
  LM_DBG("error:...\n");
652
  /* execute post request-script callbacks */
653
0
  exec_post_script_cb(msg, REQUEST_CB_TYPE);
654
0
error03:
655
0
error02:
656
0
  free_sip_msg(msg);
657
0
  pkg_free(msg);
658
0
error00:
659
0
  ksr_msg_env_reset();
660
  /* reset log prefix */
661
0
  log_prefix_set(NULL);
662
0
  return -1;
663
0
}
664
665
/**
666
 * clean up msg environment, such as avp, xavp and xavu lists
667
 */
668
void ksr_msg_env_reset(void)
669
0
{
670
0
  reset_avps();
671
0
  xavp_reset_list();
672
0
  xavu_reset_list();
673
0
  xavi_reset_list();
674
0
}