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