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