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