8 #include <sys/socket.h>
10 #include <netinet/in.h>
14 #include "msg_parser.h"
17 #include "udp_server.h"
19 #define MAX_VIA_LINE_SIZE 240
20 #define MAX_RECEIVED_SIZE 57
24 int forward_request(char * orig, char* buf,
27 struct route_elem* re)
29 unsigned int new_len, via_len, received_len;
30 char line_buf[MAX_VIA_LINE_SIZE];
31 char received_buf[MAX_RECEIVED_SIZE];
33 int offset, s_offset, size;
34 struct sockaddr_in to;
38 via_len=snprintf(line_buf, MAX_VIA_LINE_SIZE, "Via: SIP/2.0/UDP %s:%d\r\n",
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",
45 new_len=len+via_len+received_len;
46 new_buf=(char*)malloc(new_len+1);
48 DPrint("ERROR: forward_request: out of memory\n");
51 /* copy msg till first via */
53 size=msg->via1.hdr-buf;
54 memcpy(new_buf, orig, size);
58 memcpy(new_buf+offset, line_buf, via_len);
60 /* modify original via if neccesarry (received=...)*/
62 if (msg->via1.params){
63 size= msg->via1.params-msg->via1.hdr-1; /*compensate for ';' */
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 ':'*/
70 memcpy(new_buf+offset, orig+s_offset,
74 memcpy(new_buf+offset, received_buf, received_len);
77 /* copy the rest of the msg */
78 memcpy(new_buf+offset, orig+s_offset, len-s_offset);
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);
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 */
90 if (re->host.h_addr_list[re->current_addr_idx+1])
91 re->current_addr_idx++;
94 /* ? not 64bit clean?*/
95 to.sin_addr.s_addr=*((long*)re->host.h_addr_list[re->current_addr_idx]);
98 re->tx_bytes+=new_len;
99 if (udp_send(new_buf, new_len, &to, sizeof(to))==-1){
116 /* removes first via & sends msg to the second */
117 int forward_reply(char * orig, char* buf,
123 unsigned int new_len, via_len;
125 int offset, s_offset, size;
127 struct sockaddr_in to;
130 /* we must remove the first via */
131 via_len=msg->via1.size;
132 size=msg->via1.hdr-buf;
134 /* keep hdr =substract hdr size +1 (hdr':') and add
136 via_len-=strlen(msg->via1.hdr)+1;
137 size+=strlen(msg->via1.hdr)+1;
140 new_buf=(char*)malloc(new_len);
142 DPrint("ERROR: forward_reply: out of memory\n");
145 memcpy(new_buf, orig, size);
147 s_offset=size+via_len;
148 memcpy(new_buf+offset,orig+s_offset, len-s_offset);
150 printf("Sending: to %s:%d, \n%s.\n",
152 (unsigned short)msg->via2.port,
154 /* fork? gethostbyname will probably block... */
155 he=gethostbyname(msg->via2.host);
157 DPrint("ERROR:forward_reply:gethostbyname failure\n");
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]);
164 if (udp_send(new_buf,new_len, &to, sizeof(to))==-1)
171 if (new_buf) free(new_buf);