02036f626ae41f4090d80db1b092dc069b152bb9
[sip-router] / forward.c
1 /*
2  * $Id$
3  */
4
5
6 #include <string.h>
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <netdb.h>
10 #include <netinet/in.h>
11
12 #include "forward.h"
13 #include "config.h"
14 #include "msg_parser.h"
15 #include "route.h"
16 #include "dprint.h"
17 #include "udp_server.h"
18
19 #define MAX_VIA_LINE_SIZE      240
20 #define MAX_RECEIVED_SIZE  57
21
22
23
24 int forward_request(char * orig, char* buf, 
25                                          unsigned int len,
26                                          struct sip_msg* msg,
27                                          struct route_elem* re)
28 {
29         unsigned int new_len, via_len, received_len;
30         char line_buf[MAX_VIA_LINE_SIZE];
31         char received_buf[MAX_RECEIVED_SIZE];
32         char* new_buf;
33         int offset, s_offset, size;
34         struct sockaddr_in to;
35
36         received_len=0;
37
38         via_len=snprintf(line_buf, MAX_VIA_LINE_SIZE, "Via: SIP/2.0/UDP %s:%d\r\n",
39                                                 our_name, our_port);
40         /* check if received needs to be added */
41         /* if check_address(source_ip, msg->via1.host) */
42         received_len=snprintf(received_buf, MAX_RECEIVED_SIZE, ";received=%s",
43                                                         "10.11.12.13");
44         
45         new_len=len+via_len+received_len;
46         new_buf=(char*)malloc(new_len+1);
47         if (new_buf==0){
48                 DPrint("ERROR: forward_request: out of memory\n");
49                 goto error1;
50         }
51 /* copy msg till first via */
52         offset=s_offset=0;
53         size=msg->via1.hdr-buf;
54         memcpy(new_buf, orig, size);
55         offset+=size;
56         s_offset+=size;
57  /* add our via */
58         memcpy(new_buf+offset, line_buf, via_len);
59         offset+=via_len;
60  /* modify original via if neccesarry (received=...)*/
61         if (received_len){
62                 if (msg->via1.params){
63                                 size= msg->via1.params-msg->via1.hdr-1; /*compensate for ';' */
64                 }else{
65                                 size= msg->via1.host-msg->via1.hdr+strlen(msg->via1.host);
66                                 if (msg->via1.port!=0){
67                                         size+=strlen(msg->via1.hdr+size+1)+1; /* +1 for ':'*/
68                                 }
69                 }
70                 memcpy(new_buf+offset, orig+s_offset, 
71                                                                 size);
72                 offset+=size;
73                 s_offset+=size;
74                 memcpy(new_buf+offset, received_buf, received_len);
75                 offset+=received_len;
76         }
77         /* copy the rest of the msg */
78         memcpy(new_buf+offset, orig+s_offset, len-s_offset);
79         new_buf[new_len]=0;
80
81          /* send it! */
82         printf("Sending:\n%s.\n", new_buf);
83         printf("orig. len=%d, new_len=%d, via_len=%d, received_len=%d\n",
84                         len, new_len, via_len, received_len);
85
86         to.sin_family = AF_INET;
87         to.sin_port = (re->port)?htons(re->port):htons(SIP_PORT);
88         /* if error try next ip address if possible */
89         if (re->ok==0){
90                 if (re->host.h_addr_list[re->current_addr_idx+1])
91                         re->current_addr_idx++;
92                 re->ok=1;
93         }
94         /* ? not 64bit clean?*/
95         to.sin_addr.s_addr=*((long*)re->host.h_addr_list[re->current_addr_idx]);
96
97         re->tx++;
98         re->tx_bytes+=new_len;
99         if (udp_send(new_buf, new_len, &to, sizeof(to))==-1){
100                         re->errors++;
101                         re->ok=0;
102                         goto error;
103         }
104
105         free(new_buf);
106         return 0;
107 error:
108         free(new_buf);
109 error1:
110         return -1;
111
112 }
113
114
115
116 /* removes first via & sends msg to the second */
117 int forward_reply(char * orig, char* buf, 
118                                          unsigned int len,
119                                          struct sip_msg* msg)
120 {
121
122
123         unsigned int new_len, via_len;
124         char* new_buf;
125         int offset, s_offset, size;
126         struct hostent* he;
127         struct sockaddr_in to;
128
129
130         /* we must remove the first via */
131         via_len=msg->via1.size;
132         size=msg->via1.hdr-buf;
133         if (msg->via1.next){
134                 /* keep hdr =substract hdr size +1 (hdr':') and add
135                  */
136                 via_len-=strlen(msg->via1.hdr)+1;
137                 size+=strlen(msg->via1.hdr)+1;
138         }
139         new_len=len-size;
140         new_buf=(char*)malloc(new_len);
141         if (new_buf==0){
142                 DPrint("ERROR: forward_reply: out of memory\n");
143                 goto error;
144         }
145         memcpy(new_buf, orig, size);
146         offset=size;
147         s_offset=size+via_len;
148         memcpy(new_buf+offset,orig+s_offset, len-s_offset);
149          /* send it! */
150         printf("Sending: to %s:%d, \n%s.\n",
151                         msg->via2.host, 
152                         (unsigned short)msg->via2.port,
153                         new_buf);
154         /* fork? gethostbyname will probably block... */
155         he=gethostbyname(msg->via2.host);
156         if (he==0){
157                 DPrint("ERROR:forward_reply:gethostbyname failure\n");
158                 goto error;
159         }
160         to.sin_family = AF_INET;
161         to.sin_port = (msg->via2.port)?htons(msg->via2.port):htons(SIP_PORT);
162         to.sin_addr.s_addr=*((long*)he->h_addr_list[0]);
163         
164         if (udp_send(new_buf,new_len, &to, sizeof(to))==-1)
165                 goto error;
166         
167         free(new_buf);
168         return 0;
169
170 error:
171         if (new_buf) free(new_buf);
172         return -1;
173 }