core: safety protection on handing incoming messages without setting local socket
[sip-router] / 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 /** Receive message
221  *  WARNING: buf must be 0 terminated (buf[len]=0) or some things might
222  * break (e.g.: modules/textops)
223  */
224 int receive_msg(char *buf, unsigned int len, receive_info_t *rcv_info)
225 {
226         struct sip_msg *msg;
227         struct run_act_ctx ctx;
228         struct run_act_ctx *bctx;
229         int ret;
230         struct timeval tvb, tve;
231         struct timezone tz;
232         unsigned int diff = 0;
233         str inb;
234         sr_net_info_t netinfo;
235         sr_kemi_eng_t *keng = NULL;
236         sr_event_param_t evp = {0};
237         unsigned int cidlockidx = 0;
238         unsigned int cidlockset = 0;
239         int errsipmsg = 0;
240         int exectime = 0;
241
242         if(rcv_info->bind_address==NULL) {
243                 LM_ERR("critical - incoming message without local socket [%.*s ...]\n",
244                                 (len>128)?128:len, buf);
245                 return -1;
246         }
247
248         if(ksr_evrt_received_mode!=0) {
249                 if(ksr_evrt_received(buf, len, rcv_info)<0) {
250                         LM_DBG("dropping the received message\n");
251                         goto error00;
252                 }
253         }
254         if(sr_event_enabled(SREV_NET_DATA_RECV)) {
255                 if(sip_check_fline(buf, len) == 0) {
256                         memset(&netinfo, 0, sizeof(sr_net_info_t));
257                         netinfo.data.s = buf;
258                         netinfo.data.len = len;
259                         netinfo.rcv = rcv_info;
260                         evp.data = (void *)&netinfo;
261                         sr_event_exec(SREV_NET_DATA_RECV, &evp);
262                 }
263         }
264
265         inb.s = buf;
266         inb.len = len;
267         evp.data = (void *)&inb;
268         evp.rcv = rcv_info;
269         sr_event_exec(SREV_NET_DATA_IN, &evp);
270         len = inb.len;
271
272         msg = pkg_malloc(sizeof(struct sip_msg));
273         if(unlikely(msg == 0)) {
274                 PKG_MEM_ERROR;
275                 goto error00;
276         }
277         msg_no++;
278         /* number of vias parsed -- good for diagnostic info in replies */
279         via_cnt = 0;
280
281         memset(msg, 0, sizeof(struct sip_msg)); /* init everything to 0 */
282         /* fill in msg */
283         msg->buf = buf;
284         msg->len = len;
285         /* zero termination (termination of orig message below not that
286          * useful as most of the work is done with scratch-pad; -jiri  */
287         /* buf[len]=0; */ /* WARNING: zero term removed! */
288         msg->rcv = *rcv_info;
289         msg->id = msg_no;
290         msg->pid = my_pid();
291         msg->set_global_address = default_global_address;
292         msg->set_global_port = default_global_port;
293
294         if(likely(sr_msg_time == 1))
295                 msg_set_time(msg);
296
297         if(parse_msg(buf, len, msg) != 0) {
298                 errsipmsg = 1;
299                 evp.data = (void *)msg;
300                 if((ret = sr_event_exec(SREV_RCV_NOSIP, &evp)) < NONSIP_MSG_DROP) {
301                         LM_DBG("attempt of nonsip message processing failed\n");
302                 } else if(ret == NONSIP_MSG_DROP) {
303                         LM_DBG("nonsip message processing completed\n");
304                         goto error02;
305                 }
306         }
307         if(errsipmsg==1) {
308                 LOG(cfg_get(core, core_cfg, corelog),
309                                 "core parsing of SIP message failed (%s:%d/%d)\n",
310                                 ip_addr2a(&msg->rcv.src_ip), (int)msg->rcv.src_port,
311                                 (int)msg->rcv.proto);
312                 sr_core_ert_run(msg, SR_CORE_ERT_RECEIVE_PARSE_ERROR);
313                 goto error02;
314         }
315
316         if(unlikely(parse_headers(msg, HDR_FROM_F | HDR_TO_F | HDR_CALLID_F | HDR_CSEQ_F, 0)
317                         < 0)) {
318                 LM_WARN("parsing relevant headers failed\n");
319         }
320         LM_DBG("--- received sip message - %s - call-id: [%.*s] - cseq: [%.*s]\n",
321                         (msg->first_line.type == SIP_REQUEST) ? "request" : "reply",
322                         (msg->callid && msg->callid->body.s) ? msg->callid->body.len : 0,
323                         (msg->callid && msg->callid->body.s) ? msg->callid->body.s : "",
324                         (msg->cseq && msg->cseq->body.s) ? msg->cseq->body.len : 0,
325                         (msg->cseq && msg->cseq->body.s) ? msg->cseq->body.s : "");
326
327         /* set log prefix */
328         log_prefix_set(msg);
329
330         /* ... clear branches from previous message */
331         clear_branches();
332
333         if(unlikely(ksr_route_locks_set!=NULL && msg->callid && msg->callid->body.s
334                         && msg->callid->body.len >0)) {
335                 cidlockidx = get_hash1_raw(msg->callid->body.s, msg->callid->body.len);
336                 cidlockidx = cidlockidx % ksr_route_locks_set->size;
337                 cidlockset = 1;
338         }
339
340
341         if(is_printable(cfg_get(core, core_cfg, latency_cfg_log))) {
342                 exectime = 1;
343         }
344
345         if(msg->first_line.type == SIP_REQUEST) {
346                 ruri_mark_new(); /* ruri is usable for forking (not consumed yet) */
347                 if(!IS_SIP(msg)) {
348                         if((ret = nonsip_msg_run_hooks(msg)) != NONSIP_MSG_ACCEPT) {
349                                 if(unlikely(ret == NONSIP_MSG_ERROR))
350                                         goto error03;
351                                 goto end; /* drop the message */
352                         }
353                 }
354                 /* sanity checks */
355                 if(unlikely((msg->via1 == 0) || (msg->via1->error != PARSE_OK))) {
356                         /* no via, send back error ? */
357                         LM_ERR("no via found in request\n");
358                         STATS_BAD_MSG();
359                         goto error02;
360                 }
361 /* check if necessary to add receive?->moved to forward_req */
362 /* check for the alias stuff */
363 #ifdef USE_TCP
364                 if(msg->via1->alias && cfg_get(tcp, tcp_cfg, accept_aliases)
365                                 && (((rcv_info->proto == PROTO_TCP) && !tcp_disable)
366 #ifdef USE_TLS
367                                                    || ((rcv_info->proto == PROTO_TLS) && !tls_disable)
368 #endif
369                                                                    )) {
370                         if(tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
371                                            rcv_info->proto)
372                                         != 0) {
373                                 LM_ERR("tcp alias failed\n");
374                                 /* continue */
375                         }
376                 }
377 #endif
378
379                 /*      skip: */
380                 LM_DBG("preparing to run routing scripts...\n");
381                 if(exectime) {
382                         gettimeofday(&tvb, &tz);
383                 }
384                 /* execute pre-script callbacks, if any; -jiri */
385                 /* if some of the callbacks said not to continue with
386                  * script processing, don't do so
387                  * if we are here basic sanity checks are already done
388                  * (like presence of at least one via), so you can count
389                  * on via1 being parsed in a pre-script callback --andrei
390                 */
391                 if(exec_pre_script_cb(msg, REQUEST_CB_TYPE) == 0) {
392                         STATS_REQ_FWD_DROP();
393                         goto end; /* drop the request */
394                 }
395
396                 set_route_type(REQUEST_ROUTE);
397                 /* exec the routing script */
398                 if(unlikely(main_rt.rlist[DEFAULT_RT] == NULL)) {
399                         keng = sr_kemi_eng_get();
400                         if(keng == NULL) {
401                                 LM_ERR("no request_route {...} and no other config routing"
402                                                 " engine registered\n");
403                                 goto error_req;
404                         }
405                         if(unlikely(cidlockset)) {
406                                 rec_lock_set_get(ksr_route_locks_set, cidlockidx);
407                                 if(sr_kemi_route(keng, msg, REQUEST_ROUTE, NULL, NULL) < 0)
408                                         LM_NOTICE("negative return code from engine function\n");
409                                 rec_lock_set_release(ksr_route_locks_set, cidlockidx);
410                         } else {
411                                 if(sr_kemi_route(keng, msg, REQUEST_ROUTE, NULL, NULL) < 0)
412                                         LM_NOTICE("negative return code from engine function\n");
413                         }
414                 } else {
415                         if(unlikely(cidlockset)) {
416                                 rec_lock_set_get(ksr_route_locks_set, cidlockidx);
417                                 if(run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0) < 0) {
418                                         rec_lock_set_release(ksr_route_locks_set, cidlockidx);
419                                         LM_WARN("error while trying script\n");
420                                         goto error_req;
421                                 }
422                                 rec_lock_set_release(ksr_route_locks_set, cidlockidx);
423                         } else {
424                                 if(run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0) < 0) {
425                                         LM_WARN("error while trying script\n");
426                                         goto error_req;
427                                 }
428                         }
429                 }
430
431                 if(exectime) {
432                         gettimeofday(&tve, &tz);
433                         diff = (tve.tv_sec - tvb.tv_sec) * 1000000
434                                    + (tve.tv_usec - tvb.tv_usec);
435                         if (cfg_get(core, core_cfg, latency_limit_cfg) == 0
436                                         || cfg_get(core, core_cfg, latency_limit_cfg) <= diff) {
437                                 LOG(cfg_get(core, core_cfg, latency_cfg_log),
438                                                 "request-route executed in: %d usec\n", diff);
439                         }
440                 }
441
442                 /* execute post request-script callbacks */
443                 exec_post_script_cb(msg, REQUEST_CB_TYPE);
444         } else if(msg->first_line.type == SIP_REPLY) {
445                 /* sanity checks */
446                 if((msg->via1 == 0) || (msg->via1->error != PARSE_OK)) {
447                         /* no via, send back error ? */
448                         LM_ERR("no via found in reply\n");
449                         STATS_BAD_RPL();
450                         goto error02;
451                 }
452
453                 if(exectime) {
454                         gettimeofday(&tvb, &tz);
455                 }
456
457                 /* execute pre-script callbacks, if any; -jiri */
458                 /* if some of the callbacks said not to continue with
459                  * script processing, don't do so
460                  * if we are here basic sanity checks are already done
461                  * (like presence of at least one via), so you can count
462                  * on via1 being parsed in a pre-script callback --andrei
463                 */
464                 if(exec_pre_script_cb(msg, ONREPLY_CB_TYPE) == 0) {
465                         STATS_RPL_FWD_DROP();
466                         goto end; /* drop the reply */
467                 }
468
469                 /* exec the onreply routing script */
470                 if(kemi_reply_route_callback.len>0) {
471                         keng = sr_kemi_eng_get();
472                 }
473                 if(onreply_rt.rlist[DEFAULT_RT] != NULL || keng != NULL) {
474                         set_route_type(CORE_ONREPLY_ROUTE);
475                         ret = 1;
476                         if(unlikely(keng != NULL)) {
477                                 bctx = sr_kemi_act_ctx_get();
478                                 init_run_actions_ctx(&ctx);
479                                 sr_kemi_act_ctx_set(&ctx);
480                                 if(unlikely(cidlockset)) {
481                                         rec_lock_set_get(ksr_route_locks_set, cidlockidx);
482                                         ret = sr_kemi_route(keng, msg, CORE_ONREPLY_ROUTE, NULL, NULL);
483                                         rec_lock_set_release(ksr_route_locks_set, cidlockidx);
484                                 } else {
485                                         ret = sr_kemi_route(keng, msg, CORE_ONREPLY_ROUTE, NULL, NULL);
486                                 }
487                                 sr_kemi_act_ctx_set(bctx);
488                         } else {
489                                 if(unlikely(cidlockset)) {
490                                         rec_lock_set_get(ksr_route_locks_set, cidlockidx);
491                                         ret = run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
492                                         rec_lock_set_release(ksr_route_locks_set, cidlockidx);
493                                 } else  {
494                                         ret = run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
495                                 }
496                         }
497 #ifndef NO_ONREPLY_ROUTE_ERROR
498                         if(unlikely(ret < 0)) {
499                                 LM_WARN("error while trying onreply script\n");
500                                 goto error_rpl;
501                         } else
502 #endif /* NO_ONREPLY_ROUTE_ERROR */
503                                 if(unlikely(ret == 0 || (ctx.run_flags & DROP_R_F))) {
504                                         STATS_RPL_FWD_DROP();
505                                         LM_DBG("drop flag set - skip forwarding the reply\n");
506                                         goto skip_send_reply; /* drop the message, no error */
507                                 }
508                 }
509                 /* send the msg */
510                 forward_reply(msg);
511         skip_send_reply:
512                 if(exectime) {
513                         gettimeofday(&tve, &tz);
514                         diff = (tve.tv_sec - tvb.tv_sec) * 1000000
515                                    + (tve.tv_usec - tvb.tv_usec);
516                         if (cfg_get(core, core_cfg, latency_limit_cfg) == 0
517                                         || cfg_get(core, core_cfg, latency_limit_cfg) <= diff) {
518                                 LOG(cfg_get(core, core_cfg, latency_cfg_log),
519                                                 "reply-route executed in: %d usec\n", diff);
520                         }
521                 }
522
523                 /* execute post reply-script callbacks */
524                 exec_post_script_cb(msg, ONREPLY_CB_TYPE);
525         }
526
527 end:
528         ksr_msg_env_reset();
529         LM_DBG("cleaning up\n");
530         free_sip_msg(msg);
531         pkg_free(msg);
532         /* reset log prefix */
533         log_prefix_set(NULL);
534         return 0;
535
536 #ifndef NO_ONREPLY_ROUTE_ERROR
537 error_rpl:
538         /* execute post reply-script callbacks */
539         exec_post_script_cb(msg, ONREPLY_CB_TYPE);
540         goto error02;
541 #endif /* NO_ONREPLY_ROUTE_ERROR */
542 error_req:
543         LM_DBG("error:...\n");
544         /* execute post request-script callbacks */
545         exec_post_script_cb(msg, REQUEST_CB_TYPE);
546 error03:
547 error02:
548         free_sip_msg(msg);
549         pkg_free(msg);
550 error00:
551         ksr_msg_env_reset();
552         /* reset log prefix */
553         log_prefix_set(NULL);
554         return -1;
555 }
556
557 /**
558  * clean up msg environment, such as avp and xavp lists
559  */
560 void ksr_msg_env_reset(void)
561 {
562         reset_avps();
563         xavp_reset_list();
564 }