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