- switched to new via & header parsing
[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
15
16 #ifdef DEBUG_DMALLOC
17 #include <dmalloc.h>
18 #endif
19
20 #ifdef STATS
21 #include "stats.h"
22 #endif
23
24 unsigned int msg_no=0;
25
26 int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
27 {
28         struct sip_msg msg;
29
30         msg_no++;
31 #ifdef STATS
32         skipped = 1;
33 #endif
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*) 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 on it*/
49         
50         if (parse_msg(buf,len, &msg)!=0){
51                 goto error;
52         }
53         DBG("After parse_msg...\n");
54         if (msg.first_line.type==SIP_REQUEST){
55                 DBG("msg= request\n");
56                 /* sanity checks */
57                 if ((msg.via1==0) || (msg.via1->error!=VIA_PARSE_OK)){
58                         /* no via, send back error ? */
59                         LOG(L_ERR, "ERROR: receive_msg: no via found in request\n");
60                         goto error;
61                 }
62                 /* check if neccesarry to add receive?->moved to forward_req */
63                 
64                 /* exec routing script */
65                 DBG("preparing to run routing scripts...\n");
66                 if (run_actions(rlist[0], &msg)<0){
67                         LOG(L_WARN, "WARNING: receive_msg: "
68                                         "error while trying script\n");
69                         goto error;
70                 }
71 #ifdef STATS
72                 /* jku -- update request statistics  */
73                 else update_received_request(  msg.first_line.u.request.method_value );
74 #endif
75         }else if (msg.first_line.type==SIP_REPLY){
76                 DBG("msg= reply\n");
77                 /* sanity checks */
78                 if ((msg.via1==0) || (msg.via1->error!=VIA_PARSE_OK)){
79                         /* no via, send back error ? */
80                         LOG(L_ERR, "ERROR: receive_msg: no via found in reply\n");
81                         goto error;
82                 }
83                 if ((msg.via2==0) || (msg.via2->error!=VIA_PARSE_OK)){
84                         /* no second via => error? */
85                         LOG(L_ERR, "ERROR: receive_msg: no 2nd via found in reply\n");
86                         goto error;
87                 }
88                 /* check if via1 == us */
89
90 #ifdef STATS
91                 /* jku -- update statistics  */
92                 update_received_response(  msg.first_line.u.reply.statusclass );
93 #endif
94                 
95                 /* send the msg */
96                 if (forward_reply(&msg)==0){
97                         DBG(" reply forwarded to %s:%d\n", 
98                                                 msg.via2->host.s,
99                                                 (unsigned short) msg.via2->port);
100                 }
101         }
102 #ifdef STATS
103         skipped = 0;
104 #endif
105 skip:
106         DBG("skip:...\n");
107         if (msg.new_uri.s) { free(msg.new_uri.s); msg.new_uri.len=0; }
108         if (msg.headers) free_hdr_field_lst(msg.headers);
109         if (msg.add_rm) free_lump_list(msg.add_rm);
110         if (msg.repl_add_rm) free_lump_list(msg.repl_add_rm);
111         free(msg.orig);
112 #ifdef STATS
113         if (skipped) update_received_drops;
114 #endif
115         return 0;
116 error:
117         DBG("error:...\n");
118         if (msg.new_uri.s) free(msg.new_uri.s);
119         if (msg.headers) free_hdr_field_lst(msg.headers);
120         if (msg.add_rm) free_lump_list(msg.add_rm);
121         if (msg.repl_add_rm) free_lump_list(msg.repl_add_rm);
122         free(msg.orig);
123 error1:
124 #ifdef STATS
125         update_received_drops;
126 #endif
127         return -1;
128 }
129