First working release
[sip-router] / forward.c
index 4f9c6b9..1342656 100644 (file)
--- a/forward.c
+++ b/forward.c
@@ -4,17 +4,19 @@
 
 
 #include <string.h>
+#include <netdb.h>
+#include <netinet/in.h>
 
 #include "forward.h"
+#include "config.h"
 #include "msg_parser.h"
 #include "route.h"
 #include "dprint.h"
+#include "udp_server.h"
 
 #define MAX_VIA_LINE_SIZE      240
 #define MAX_RECEIVED_SIZE  57
 
-#define our_address "dorian.fokus.gmd.de"
-#define our_port 1234
 
 
 int forward_request(char * orig, char* buf, 
@@ -27,12 +29,12 @@ int forward_request(char * orig, char* buf,
        char received_buf[MAX_RECEIVED_SIZE];
        char* new_buf;
        int offset, s_offset, size;
+       struct sockaddr_in to;
 
        received_len=0;
-       printf("0\n");
 
        via_len=snprintf(line_buf, MAX_VIA_LINE_SIZE, "Via: SIP/2.0/UDP %s:%d\r\n",
-                                               our_address, our_port);
+                                               our_name, our_port);
        /* check if received needs to be added */
        /* if check_address(source_ip, msg->via1.host) */
        received_len=snprintf(received_buf, MAX_RECEIVED_SIZE, ";received=%s",
@@ -42,49 +44,67 @@ int forward_request(char * orig, char* buf,
        new_buf=(char*)malloc(new_len+1);
        if (new_buf==0){
                DPrint("ERROR: forward_request: out of memory\n");
-               goto error;
+               goto error1;
        }
-       printf("1\n");
- /* copy msg till first via */
-       offset=s_offset=0;
-       size=msg->via1.hdr-buf;
-       memcpy(new_buf, orig, size);
+/* copy msg till first via */
+       offset=s_offset=0;
+       size=msg->via1.hdr-buf;
+       memcpy(new_buf, orig, size);
        offset+=size;
        s_offset+=size;
-       printf("2\n");
  /* add our via */
-       memcpy(new_buf+offset, line_buf, via_len);
+       memcpy(new_buf+offset, line_buf, via_len);
        offset+=via_len;
-       printf("3\n");
  /* modify original via if neccesarry (received=...)*/
-       if (received_len){
+       if (received_len){
                if (msg->via1.params){
                                size= msg->via1.params-msg->via1.hdr-1; /*compensate for ';' */
                }else{
                                size= msg->via1.host-msg->via1.hdr+strlen(msg->via1.host);
                                if (msg->via1.port!=0){
-                                       size+=strlen(msg->via1.hdr+size+1);
+                                       size+=strlen(msg->via1.hdr+size+1)+1; /* +1 for ':'*/
                                }
                }
                memcpy(new_buf+offset, orig+s_offset, 
                                                                size);
                offset+=size;
                s_offset+=size;
-               printf("4\n");
                memcpy(new_buf+offset, received_buf, received_len);
-               printf("5\n");
                offset+=received_len;
        }
        /* copy the rest of the msg */
        memcpy(new_buf+offset, orig+s_offset, len-s_offset);
-       printf("6\n");
        new_buf[new_len]=0;
 
         /* send it! */
-        printf("Sending:\n%s.\n", new_buf);
-        
+       printf("Sending:\n%s.\n", new_buf);
+       printf("orig. len=%d, new_len=%d, via_len=%d, received_len=%d\n",
+                       len, new_len, via_len, received_len);
+
+       to.sin_family = AF_INET;
+       to.sin_port = (re->port)?htons(re->port):htons(SIP_PORT);
+       /* if error try next ip address if possible */
+       if (re->ok==0){
+               if (re->host.h_addr_list[re->current_addr_idx+1])
+                       re->current_addr_idx++;
+               re->ok=1;
+       }
+       /* ? not 64bit clean?*/
+       to.sin_addr.s_addr=*((long*)re->host.h_addr_list[re->current_addr_idx]);
+
+       re->tx++;
+       re->tx_bytes+=new_len;
+       if (udp_send(new_buf, new_len, &to, sizeof(to))==-1){
+                       re->errors++;
+                       re->ok=0;
+                       goto error;
+       }
+
+       free(new_buf);
        return 0;
 error:
+       free(new_buf);
+error1:
        return -1;
 
 }
@@ -101,37 +121,51 @@ int forward_reply(char * orig, char* buf,
        unsigned int new_len, via_len;
        char* new_buf;
        int offset, s_offset, size;
+       struct hostent* he;
+       struct sockaddr_in to;
 
 
-       /* we must remove first via */
+       /* we must remove the first via */
        via_len=msg->via1.size;
        size=msg->via1.hdr-buf;
        if (msg->via1.next){
-               via_len-=strlen(msg->via1.hdr)+1; /* +1 from ':' */
+               /* keep hdr =substract hdr size +1 (hdr':') and add
+                */
+               via_len-=strlen(msg->via1.hdr)+1;
                size+=strlen(msg->via1.hdr)+1;
        }
        new_len=len-size;
-       printf("r1\n");
        new_buf=(char*)malloc(new_len);
        if (new_buf==0){
                DPrint("ERROR: forward_reply: out of memory\n");
                goto error;
        }
-       printf("r2\n");
        memcpy(new_buf, orig, size);
        offset=size;
        s_offset=size+via_len;
-       printf("r3\n");
        memcpy(new_buf+offset,orig+s_offset, len-s_offset);
-       printf("r4\n");
         /* send it! */
        printf("Sending: to %s:%d, \n%s.\n",
                        msg->via2.host, 
                        (unsigned short)msg->via2.port,
                        new_buf);
+       /* fork? gethostbyname will probably block... */
+       he=gethostbyname(msg->via2.host);
+       if (he==0){
+               DPrint("ERROR:forward_reply:gethostbyname failure\n");
+               goto error;
+       }
+       to.sin_family = AF_INET;
+       to.sin_port = (msg->via2.port)?htons(msg->via2.port):htons(SIP_PORT);
+       to.sin_addr.s_addr=*((long*)he->h_addr_list[0]);
+       
+       if (udp_send(new_buf,new_len, &to, sizeof(to))==-1)
+               goto error;
        
+       free(new_buf);
        return 0;
 
 error:
+       if (new_buf) free(new_buf);
        return -1;
 }