various small fixes
[sip-router] / receive.c
1 /* 
2  *$Id$
3  */
4
5 #include <string.h>
6 #include <stdlib.h>
7 #include <sys/time.h>
8
9 #include "receive.h"
10 #include "globals.h"
11 #include "dprint.h"
12 #include "route.h"
13 #include "parser/msg_parser.h"
14 #include "forward.h"
15 #include "action.h"
16 #include "mem/mem.h"
17 #include "stats.h"
18 #include "ip_addr.h"
19
20
21 #ifdef DEBUG_DMALLOC
22 #include <mem/dmalloc.h>
23 #endif
24
25 unsigned int msg_no=0;
26
27 int receive_msg(char* buf, unsigned int len, union sockaddr_union* src_su)
28 {
29         struct sip_msg* msg;
30 #ifdef STATS
31         int skipped = 1;
32         struct timeval tvb, tve;        
33         struct timezone tz;
34         unsigned int diff;
35 #endif
36
37         msg=pkg_malloc(sizeof(struct sip_msg));
38         if (msg==0) goto error1;
39         msg_no++;
40
41         memset(msg,0, sizeof(struct sip_msg)); /* init everything to 0 */
42         /* fill in msg */
43         msg->buf=buf;
44         msg->len=len;
45         /* zero termination (termination of orig message bellow not that
46            useful as most of the work is done with scrath-pad; -jiri  */
47         buf[len]=0;
48         su2ip_addr(&msg->src_ip, src_su);
49         msg->dst_ip=bind_address->address; /* won't work if listening on 0.0.0.0 */
50         msg->id=msg_no;
51         /* make a copy of the message */
52         msg->orig=(char*) pkg_malloc(len+1);
53         if (msg->orig==0){
54                 LOG(L_ERR, "ERROR:receive_msg: memory allocation failure\n");
55                 goto error1;
56         }
57         memcpy(msg->orig, buf, len);
58         msg->orig[len]=0; /* null terminate it,good for using str* functions
59                                                  on it*/
60         
61         if (parse_msg(buf,len, msg)!=0){
62                 goto error;
63         }
64         DBG("After parse_msg...\n");
65         if (msg->first_line.type==SIP_REQUEST){
66                 /* sanity checks */
67                 if ((msg->via1==0) || (msg->via1->error!=VIA_PARSE_OK)){
68                         /* no via, send back error ? */
69                         LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
70                         goto error;
71                 }
72                 /* check if neccesarry to add receive?->moved to forward_req */
73
74                 /* loop checks */
75                 if (loop_checks) {
76                         DBG("WARNING: receive_msg: Placeholder for loop check."
77                                 " NOT implemented yet.\n");
78                 }
79                 
80                 /* exec routing script */
81                 DBG("preparing to run routing scripts...\n");
82 #ifdef  STATS
83                 gettimeofday( & tvb, &tz );
84 #endif
85                 if (run_actions(rlist[0], msg)<0){
86                         LOG(L_WARN, "WARNING: receive_msg: "
87                                         "error while trying script\n");
88                         goto error;
89                 }
90 #ifdef STATS
91                 gettimeofday( & tve, &tz );
92                 diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
93                 stats->processed_requests++;
94                 stats->acc_req_time += diff;
95                 DBG("succesfully ran routing scripts...(%d usec)\n", diff);
96                 STATS_RX_REQUEST( msg->first_line.u.request.method_value );
97 #endif
98         }else if (msg->first_line.type==SIP_REPLY){
99                 /* sanity checks */
100                 if ((msg->via1==0) || (msg->via1->error!=VIA_PARSE_OK)){
101                         /* no via, send back error ? */
102                         LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
103                         goto error;
104                 }
105 #if 0
106                 if ((msg->via2==0) || (msg->via2->error!=VIA_PARSE_OK)){
107                         /* no second via => error? */
108                         LOG(L_ERR, "ERROR: receive_msg: no 2nd via found in reply\n");
109                         goto error;
110                 }
111 #endif
112                 /* check if via1 == us */
113
114 #ifdef STATS
115                 gettimeofday( & tvb, &tz );
116                 STATS_RX_RESPONSE ( msg->first_line.u.reply.statuscode / 100 );
117 #endif
118                 
119                 /* send the msg */
120                 forward_reply(msg);
121
122 #ifdef STATS
123                 gettimeofday( & tve, &tz );
124                 diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
125                 stats->processed_responses++;
126                 stats->acc_res_time+=diff;
127                 DBG("succesfully ran reply processing...(%d usec)\n", diff);
128 #endif
129         }
130 #ifdef STATS
131         skipped = 0;
132 #endif
133 /* jku: skip no more used
134 skip:
135         DBG("skip:...\n");
136 */
137         DBG("receive_msg: cleaning up\n");
138         free_sip_msg(msg);
139         pkg_free(msg);
140 #ifdef STATS
141         if (skipped) STATS_RX_DROPS;
142 #endif
143         return 0;
144 error:
145         DBG("error:...\n");
146         free_sip_msg(msg);
147         pkg_free(msg);
148         STATS_RX_DROPS;
149         return -1;
150 error1:
151         if (msg) pkg_free(msg);
152         pkg_free(buf);
153         STATS_RX_DROPS;
154         return -1;
155 }
156