core: receive.c coherent indentation
[sip-router] / 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 "stats.h"
43 #include "ip_addr.h"
44 #include "script_cb.h"
45 #include "nonsip_hooks.h"
46 #include "dset.h"
47 #include "usr_avp.h"
48 #ifdef WITH_XAVP
49 #include "xavp.h"
50 #endif
51 #include "select_buf.h"
52
53 #include "tcp_server.h" /* for tcpconn_add_alias */
54 #include "tcp_options.h" /* for access to tcp_accept_aliases*/
55 #include "cfg/cfg.h"
56 #include "core_stats.h"
57
58 #ifdef DEBUG_DMALLOC
59 #include <mem/dmalloc.h>
60 #endif
61
62 unsigned int msg_no=0;
63 /* address preset vars */
64 str default_global_address={0,0};
65 str default_global_port={0,0};
66 str default_via_address={0,0};
67 str default_via_port={0,0};
68
69 /**
70  * increment msg_no and return the new value
71  */
72 unsigned int inc_msg_no(void)
73 {
74         return ++msg_no;
75 }
76
77 /**
78  *
79  */
80 int sip_check_fline(char* buf, unsigned int len)
81 {
82         char *p;
83         int m;
84
85         m = 0;
86         for(p=buf; p<buf+len; p++) {
87                 /* first check if is a reply - starts with SIP/2.0 */
88                 if(m==0) {
89                         if(*p==' ' || *p=='\t' || *p=='\r' || *p=='\n') continue;
90                         if(buf+len-p<10) return -1;
91                         if(strncmp(p, "SIP/2.0 ", 8)==0) {
92                                 LM_DBG("first line indicates a SIP reply\n");
93                                 return 0;
94                         }
95                         m=1;
96                 } else {
97                         /* check if a request - before end of first line is SIP/2.0 */
98                         if(*p!='\r' && *p!='\n') continue;
99                         if(p-10>=buf) {
100                                 if(strncmp(p-8, " SIP/2.0", 8)==0) {
101                                         LM_DBG("first line indicates a SIP request\n");
102                                         return 0;
103                                 }
104                         }
105                         return -1;
106                 }
107         }
108         return -1;
109 }
110
111 /** Receive message
112  *  WARNING: buf must be 0 terminated (buf[len]=0) or some things might
113  * break (e.g.: modules/textops)
114  */
115 int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
116 {
117         struct sip_msg* msg;
118         struct run_act_ctx ctx;
119         int ret;
120 #ifdef STATS
121         int skipped = 1;
122         struct timeval tvb, tve;
123         struct timezone tz;
124         unsigned int diff;
125 #endif
126         str inb;
127         sr_net_info_t netinfo;
128
129         if(sr_event_enabled(SREV_NET_DATA_RECV)) {
130                 if(sip_check_fline(buf, len)==0) {
131                         memset(&netinfo, 0, sizeof(sr_net_info_t));
132                         netinfo.data.s = buf;
133                         netinfo.data.len = len;
134                         netinfo.rcv = rcv_info;
135                         sr_event_exec(SREV_NET_DATA_RECV, (void*)&netinfo);
136                 }
137         }
138
139         inb.s = buf;
140         inb.len = len;
141         sr_event_exec(SREV_NET_DATA_IN, (void*)&inb);
142         len = inb.len;
143
144         msg=pkg_malloc(sizeof(struct sip_msg));
145         if (msg==0) {
146                 LM_ERR("no mem for sip_msg\n");
147                 goto error00;
148         }
149         msg_no++;
150         /* number of vias parsed -- good for diagnostic info in replies */
151         via_cnt=0;
152
153         memset(msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
154         /* fill in msg */
155         msg->buf=buf;
156         msg->len=len;
157         /* zero termination (termination of orig message bellow not that
158          * useful as most of the work is done with scratch-pad; -jiri  */
159         /* buf[len]=0; */ /* WARNING: zero term removed! */
160         msg->rcv=*rcv_info;
161         msg->id=msg_no;
162         msg->pid=my_pid();
163         msg->set_global_address=default_global_address;
164         msg->set_global_port=default_global_port;
165
166         if(likely(sr_msg_time==1)) msg_set_time(msg);
167
168         if (parse_msg(buf,len, msg)!=0){
169                 if(sr_event_exec(SREV_RCV_NOSIP, (void*)msg)!=0) {
170                         LOG(cfg_get(core, core_cfg, corelog),
171                                 "core parsing of SIP message failed (%s:%d/%d)\n",
172                                 ip_addr2a(&msg->rcv.src_ip), (int)msg->rcv.src_port,
173                                 (int)msg->rcv.proto);
174                         sr_core_ert_run(msg, SR_CORE_ERT_RECEIVE_PARSE_ERROR);
175                 }
176                 goto error02;
177         }
178         LM_DBG("After parse_msg...\n");
179
180         /* set log prefix */
181         log_prefix_set(msg);
182
183         /* ... clear branches from previous message */
184         clear_branches();
185
186         if (msg->first_line.type==SIP_REQUEST){
187                 ruri_mark_new(); /* ruri is usable for forking (not consumed yet) */
188                 if (!IS_SIP(msg)){
189                         if ((ret=nonsip_msg_run_hooks(msg))!=NONSIP_MSG_ACCEPT){
190                                 if (unlikely(ret==NONSIP_MSG_ERROR))
191                                         goto error03;
192                                 goto end; /* drop the message */
193                         }
194                 }
195                 /* sanity checks */
196                 if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
197                         /* no via, send back error ? */
198                         LM_ERR("no via found in request\n");
199                         STATS_BAD_MSG();
200                         goto error02;
201                 }
202                 /* check if necessary to add receive?->moved to forward_req */
203                 /* check for the alias stuff */
204 #ifdef USE_TCP
205                 if (msg->via1->alias && cfg_get(tcp, tcp_cfg, accept_aliases) &&
206                                 (((rcv_info->proto==PROTO_TCP) && !tcp_disable)
207 #ifdef USE_TLS
208                                         || ((rcv_info->proto==PROTO_TLS) && !tls_disable)
209 #endif
210                                 )
211                         ){
212                         if (tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
213                                                                         rcv_info->proto)!=0){
214                                 LM_ERR("tcp alias failed\n");
215                                 /* continue */
216                         }
217                 }
218 #endif
219
220         /*      skip: */
221                 LM_DBG("preparing to run routing scripts...\n");
222 #ifdef  STATS
223                 gettimeofday( & tvb, &tz );
224 #endif
225                 /* execute pre-script callbacks, if any; -jiri */
226                 /* if some of the callbacks said not to continue with
227                  * script processing, don't do so
228                  * if we are here basic sanity checks are already done
229                  * (like presence of at least one via), so you can count
230                  * on via1 being parsed in a pre-script callback --andrei
231                 */
232                 if (exec_pre_script_cb(msg, REQUEST_CB_TYPE)==0 )
233                 {
234                         STATS_REQ_FWD_DROP();
235                         goto end; /* drop the request */
236                 }
237
238                 set_route_type(REQUEST_ROUTE);
239                 /* exec the routing script */
240                 if (run_top_route(main_rt.rlist[DEFAULT_RT], msg, 0)<0){
241                         LM_WARN("error while trying script\n");
242                         goto error_req;
243                 }
244
245 #ifdef STATS
246                 gettimeofday( & tve, &tz );
247                 diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
248                 stats->processed_requests++;
249                 stats->acc_req_time += diff;
250                 LM_DBG("successfully ran routing scripts...(%d usec)\n", diff);
251                 STATS_RX_REQUEST( msg->first_line.u.request.method_value );
252 #endif
253
254                 /* execute post request-script callbacks */
255                 exec_post_script_cb(msg, REQUEST_CB_TYPE);
256         }else if (msg->first_line.type==SIP_REPLY){
257                 /* sanity checks */
258                 if ((msg->via1==0) || (msg->via1->error!=PARSE_OK)){
259                         /* no via, send back error ? */
260                         LM_ERR("no via found in reply\n");
261                         STATS_BAD_RPL();
262                         goto error02;
263                 }
264
265 #ifdef STATS
266                 gettimeofday( & tvb, &tz );
267                 STATS_RX_RESPONSE ( msg->first_line.u.reply.statuscode / 100 );
268 #endif
269
270                 /* execute pre-script callbacks, if any; -jiri */
271                 /* if some of the callbacks said not to continue with
272                  * script processing, don't do so
273                  * if we are here basic sanity checks are already done
274                  * (like presence of at least one via), so you can count
275                  * on via1 being parsed in a pre-script callback --andrei
276                 */
277                 if (exec_pre_script_cb(msg, ONREPLY_CB_TYPE)==0 )
278                 {
279                         STATS_RPL_FWD_DROP();
280                         goto end; /* drop the reply */
281                 }
282
283                 /* exec the onreply routing script */
284                 if (onreply_rt.rlist[DEFAULT_RT]){
285                         set_route_type(CORE_ONREPLY_ROUTE);
286                         ret=run_top_route(onreply_rt.rlist[DEFAULT_RT], msg, &ctx);
287 #ifndef NO_ONREPLY_ROUTE_ERROR
288                         if (unlikely(ret<0)){
289                                 LM_WARN("error while trying onreply script\n");
290                                 goto error_rpl;
291                         }else
292 #endif /* NO_ONREPLY_ROUTE_ERROR */
293                         if (unlikely(ret==0 || (ctx.run_flags&DROP_R_F))){
294                                 STATS_RPL_FWD_DROP();
295                                 goto skip_send_reply; /* drop the message, no error */
296                         }
297                 }
298                 /* send the msg */
299                 forward_reply(msg);
300         skip_send_reply:
301 #ifdef STATS
302                 gettimeofday( & tve, &tz );
303                 diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
304                 stats->processed_responses++;
305                 stats->acc_res_time+=diff;
306                 LM_DBG("successfully ran reply processing...(%d usec)\n", diff);
307 #endif
308
309                 /* execute post reply-script callbacks */
310                 exec_post_script_cb(msg, ONREPLY_CB_TYPE);
311         }
312
313 end:
314 #ifdef STATS
315         skipped = 0;
316 #endif
317         /* free possible loaded avps -bogdan */
318         reset_avps();
319 #ifdef WITH_XAVP
320         xavp_reset_list();
321 #endif
322         LM_DBG("cleaning up\n");
323         free_sip_msg(msg);
324         pkg_free(msg);
325 #ifdef STATS
326         if (skipped) STATS_RX_DROPS;
327 #endif
328         /* reset log prefix */
329         log_prefix_set(NULL);
330         return 0;
331
332 #ifndef NO_ONREPLY_ROUTE_ERROR
333 error_rpl:
334         /* execute post reply-script callbacks */
335         exec_post_script_cb(msg, ONREPLY_CB_TYPE);
336         reset_avps();
337 #ifdef WITH_XAVP
338         xavp_reset_list();
339 #endif
340         goto error02;
341 #endif /* NO_ONREPLY_ROUTE_ERROR */
342 error_req:
343         LM_DBG("error:...\n");
344         /* execute post request-script callbacks */
345         exec_post_script_cb(msg, REQUEST_CB_TYPE);
346 error03:
347         /* free possible loaded avps -bogdan */
348         reset_avps();
349 #ifdef WITH_XAVP
350         xavp_reset_list();
351 #endif
352 error02:
353         free_sip_msg(msg);
354         pkg_free(msg);
355 error00:
356         STATS_RX_DROPS;
357         /* reset log prefix */
358         log_prefix_set(NULL);
359         return -1;
360 }
361