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