- ipv6 support (-DUSE_IPV6)
[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         su2ip_addr(&msg->src_ip, src_su);
46         msg->dst_ip=*bind_address; /* won't work if listening on 0.0.0.0 */
47         msg->id=msg_no;
48         /* make a copy of the message */
49         msg->orig=(char*) pkg_malloc(len+1);
50         if (msg->orig==0){
51                 LOG(L_ERR, "ERROR:receive_msg: memory allocation failure\n");
52                 goto error1;
53         }
54         memcpy(msg->orig, buf, len);
55         msg->orig[len]=0; /* null terminate it,good for using str* functions
56                                                  on it*/
57         
58         if (parse_msg(buf,len, msg)!=0){
59                 goto error;
60         }
61         DBG("After parse_msg...\n");
62         if (msg->first_line.type==SIP_REQUEST){
63                 /* sanity checks */
64                 if ((msg->via1==0) || (msg->via1->error!=VIA_PARSE_OK)){
65                         /* no via, send back error ? */
66                         LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
67                         goto error;
68                 }
69                 /* check if neccesarry to add receive?->moved to forward_req */
70
71                 /* loop checks */
72                 if (loop_checks) {
73                         DBG("WARNING: receive_msg: Placeholder for loop check."
74                                 " NOT implemented yet.\n");
75                 }
76                 
77                 /* exec routing script */
78                 DBG("preparing to run routing scripts...\n");
79 #ifdef  STATS
80                 gettimeofday( & tvb, &tz );
81 #endif
82                 if (run_actions(rlist[0], msg)<0){
83                         LOG(L_WARN, "WARNING: receive_msg: "
84                                         "error while trying script\n");
85                         goto error;
86                 }
87 #ifdef STATS
88                 gettimeofday( & tve, &tz );
89                 diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
90                 stats->processed_requests++;
91                 stats->acc_req_time += diff;
92                 DBG("succesfully ran routing scripts...(%d usec)\n", diff);
93                 STATS_RX_REQUEST( msg->first_line.u.request.method_value );
94 #endif
95         }else if (msg->first_line.type==SIP_REPLY){
96                 /* sanity checks */
97                 if ((msg->via1==0) || (msg->via1->error!=VIA_PARSE_OK)){
98                         /* no via, send back error ? */
99                         LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
100                         goto error;
101                 }
102 #if 0
103                 if ((msg->via2==0) || (msg->via2->error!=VIA_PARSE_OK)){
104                         /* no second via => error? */
105                         LOG(L_ERR, "ERROR: receive_msg: no 2nd via found in reply\n");
106                         goto error;
107                 }
108 #endif
109                 /* check if via1 == us */
110
111 #ifdef STATS
112                 gettimeofday( & tvb, &tz );
113                 STATS_RX_RESPONSE ( msg->first_line.u.reply.statuscode / 100 );
114 #endif
115                 
116                 /* send the msg */
117                 forward_reply(msg);
118
119 #ifdef STATS
120                 gettimeofday( & tve, &tz );
121                 diff = (tve.tv_sec-tvb.tv_sec)*1000000+(tve.tv_usec-tvb.tv_usec);
122                 stats->processed_responses++;
123                 stats->acc_res_time+=diff;
124                 DBG("succesfully ran reply processing...(%d usec)\n", diff);
125 #endif
126         }
127 #ifdef STATS
128         skipped = 0;
129 #endif
130 /* jku: skip no more used
131 skip:
132         DBG("skip:...\n");
133 */
134         DBG("receive_msg: cleaning up\n");
135         free_sip_msg(msg);
136         pkg_free(msg);
137 #ifdef STATS
138         if (skipped) STATS_RX_DROPS;
139 #endif
140         return 0;
141 error:
142         DBG("error:...\n");
143         free_sip_msg(msg);
144         pkg_free(msg);
145         STATS_RX_DROPS;
146         return -1;
147 error1:
148         if (msg) pkg_free(msg);
149         pkg_free(buf);
150         STATS_RX_DROPS;
151         return -1;
152 }
153