- ipv6 support (-DUSE_IPV6)
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Sun, 26 May 2002 13:50:48 +0000 (13:50 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Sun, 26 May 2002 13:50:48 +0000 (13:50 +0000)
- changed all the sockaddr/ip addr structures
- added gethostbyname/addr wrappers (resolve.h)

28 files changed:
Makefile.defs
action.c
cfg.lex
cfg.y
dprint.h
flags.h
forward.c
forward.h
globals.h
ip_addr.c [new file with mode: 0644]
ip_addr.h [new file with mode: 0644]
main.c
mem/shm_mem.c
msg_translator.c
parser/msg_parser.c
parser/msg_parser.h
parser/parse_via.c
proxy.c
proxy.h
receive.c
receive.h
resolve.h [new file with mode: 0644]
route.c
route_struct.c
route_struct.h
test/resolver.txt [new file with mode: 0644]
udp_server.c
udp_server.h

index 81f32b5..e8311e7 100644 (file)
@@ -7,8 +7,8 @@
 #version number
 VERSION = 0
 PATCHLEVEL = 8
-SUBLEVEL = 7
-EXTRAVERSION = -7-ipaq-viadbg
+SUBLEVEL = 8
+EXTRAVERSION = -1-ipv6
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s)
@@ -74,9 +74,11 @@ ARCH = $(shell uname -m |sed -e s/i.86/i386/ -e s/sun4u/sparc64/ )
 # -DNEW_HNAME
 #              32-bit header name parsing; turn off for lower speed ;-) or debugging;
 #              to become non-optional if fast and stable
-# -SILENT_FR
+# -DSILENT_FR
 #              if defined, when FR timer hits (in tm) cancel is sent only if forking
 #              if used; otherwise, just delete the transaction without doing anything
+# -DUSE_IPV6
+#              compiles ipv6 support
 
 DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
         -DOS='"$(OS)"' -DCOMPILER='"$(CC_VER)"'\
@@ -85,10 +87,9 @@ DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
         -DSHM_MEM  -DSHM_MMAP \
         -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 \
         -DWAIT -DNEW_HNAME \
-        -DNOISY_REPLIES \
-        -DVERY_NOISY_REPLIES\
-        -DSILENT_FR \
-        #-DUSE_SYNONIM\
+        -DUSE_IPV6 \
+        #-DVERY_NOISY_REPLIES\
+        #-DSILENT_FR \
         #-DNO_DEBUG \
         #-DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=0 \
         #-DNOSMP \
@@ -102,8 +103,8 @@ DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
 
 
 #PROFILE=  -pg #set this if you want profiling
-mode = debug
-#mode = release
+#mode = debug
+mode = release
 
 # platform dependent settings
 
index 55638e4..475a2f7 100644 (file)
--- a/action.c
+++ b/action.c
@@ -37,7 +37,7 @@ int do_action(struct action* a, struct sip_msg* msg)
 {
        int ret;
        int v;
-       struct sockaddr_in* to;
+       union sockaddr_union* to;
        struct proxy_l* p;
        char* tmp;
        char *new_uri, *end, *crt;
@@ -77,8 +77,8 @@ int do_action(struct action* a, struct sip_msg* msg)
                                                                                /*if ((end)&&(*end)){*/
                                                                                if (err){
                                                                                        LOG(L_ERR, "ERROR: do_action: "
-                                                                                                       "forward: bad port in "
-                                                                                                       "uri: <%s>\n", uri.port.s);
+                                                                                               "forward: bad port in "
+                                                                                               "uri: <%s>\n", uri.port.s);
                                                                                        ret=E_UNSPEC;
                                                                                        goto error_fwd_uri;
                                                                                }
@@ -116,24 +116,22 @@ int do_action(struct action* a, struct sip_msg* msg)
                        }
                        break;
                case SEND_T:
-                       to=(struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
-                       if (to==0){
-                               LOG(L_ERR, "ERROR: do_action: "
-                                                       "memory allocation failure\n");
-                               ret=E_OUT_OF_MEM;
-                               break;
-                       }
                        if ((a->p1_type!= PROXY_ST)|(a->p2_type!=NUMBER_ST)){
                                LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
                                                a->p1_type, a->p2_type);
                                ret=E_BUG;
                                break;
                        }
+                       to=(union sockaddr_union*) malloc(sizeof(union sockaddr_union));
+                       if (to==0){
+                               LOG(L_ERR, "ERROR: do_action: "
+                                                       "memory allocation failure\n");
+                               ret=E_OUT_OF_MEM;
+                               break;
+                       }
                        
                        p=(struct proxy_l*)a->p1.data;
                        
-                       to->sin_family = AF_INET;
-                       to->sin_port=(p->port)?htons(p->port):htons(SIP_PORT);
                        if (p->ok==0){
                                if (p->host.h_addr_list[p->addr_idx+1])
                                        p->addr_idx++;
@@ -141,15 +139,14 @@ int do_action(struct action* a, struct sip_msg* msg)
                                        p->addr_idx=0;
                                p->ok=1;
                        }
-                       memcpy(&(to->sin_addr.s_addr), p->host.h_addr_list[p->addr_idx],
-                                       sizeof(to->sin_addr.s_addr));
-                       /*
-                       to->sin_addr.s_addr=*((long*)p->host.h_addr_list[p->addr_idx]);
-                       */
-                       p->tx++;
-                       p->tx_bytes+=msg->len;
-                       ret=udp_send(msg->orig, msg->len, (struct sockaddr*)to,
-                                       sizeof(struct sockaddr_in));
+                       ret=hostent2su( to, &p->host, p->addr_idx,
+                                               (p->port)?htons(p->port):htons(SIP_PORT) );
+                       if (ret==0){
+                               p->tx++;
+                               p->tx_bytes+=msg->len;
+                               ret=udp_send(msg->orig, msg->len, to,
+                                                               sizeof(union sockaddr_union));
+                       }
                        free(to);
                        if (ret<0){
                                p->errors++;
diff --git a/cfg.lex b/cfg.lex
index 36812bb..0d24ec6 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -8,6 +8,7 @@
 %{
        #include "cfg.tab.h"
        #include "dprint.h"
+       #include "globals.h"
        #include <string.h>
        #include <stdlib.h>
 
@@ -107,6 +108,9 @@ DIGIT               [0-9]
 ALPHANUM       {LETTER}|{DIGIT}|[_]
 NUMBER         {DIGIT}+
 ID                     {LETTER}{ALPHANUM}*
+HEX                    [0-9a-fA-F]
+HEX4           {HEX}{1,4}
+IPV6ADDR       ({HEX4}":"){7}{HEX4}|({HEX4}":"){1,7}(":"{HEX4}){1,7}|":"(":"{HEX4}){1,7}|({HEX4}":"){1,7}":"|"::"
 QUOTES         \"
 TICK           \'
 SLASH          "/"
@@ -188,8 +192,10 @@ EAT_ABLE   [\ \t\b\r]
 <INITIAL>{AND}         { count(); return AND; }
 <INITIAL>{OR}          { count(); return OR;  }
 
-<INITIAL>{NUMBER}              { count(); yylval.intval=atoi(yytext);
-                                                       return NUMBER; }
+
+
+<INITIAL>{IPV6ADDR}            { count(); yylval.strval=yytext; return IPV6ADDR; }
+<INITIAL>{NUMBER}              { count(); yylval.intval=atoi(yytext);return NUMBER; }
 <INITIAL>{YES}                 { count(); yylval.intval=1; return NUMBER; }
 <INITIAL>{NO}                  { count(); yylval.intval=0; return NUMBER; }
 
diff --git a/cfg.y b/cfg.y
index cabd842..6b7a2e9 100644 (file)
--- a/cfg.y
+++ b/cfg.y
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <string.h>
+#include <errno.h>
 #include "route_struct.h"
 #include "globals.h"
 #include "route.h"
 #include "dprint.h"
 #include "sr_module.h"
 #include "modparam.h"
+#include "ip_addr.h"
 
 #include "config.h"
 
@@ -40,7 +42,8 @@ void* f_tmp;
        char* strval;
        struct expr* expr;
        struct action* action;
-       struct net* net;
+       struct net* ipnet;
+       struct ip_addr* ipaddr;
 }
 
 /* terminals */
@@ -106,6 +109,7 @@ void* f_tmp;
 %token <intval> NUMBER
 %token <strval> ID
 %token <strval> STRING
+%token <strval> IPV6ADDR
 
 /* other */
 %token COMMA
@@ -124,8 +128,8 @@ void* f_tmp;
 /*non-terminals */
 %type <expr> exp, exp_elem /*, condition*/
 %type <action> action, actions, cmd, if_cmd, stm
-%type <uval> ipv4
-%type <net> net4
+%type <ipaddr> ipv4, ipv6, ip
+%type <ipnet> ipnet
 %type <strval> host
 /*%type <route_el> rules;
   %type <route_el> rule;
@@ -175,18 +179,25 @@ assign_stm:       DEBUG EQUAL NUMBER { debug=$3; }
                | CHECK_VIA EQUAL error { yyerror("boolean value expected"); }
                | LOOP_CHECKS EQUAL NUMBER { loop_checks=$3; }
                | LOOP_CHECKS EQUAL error { yyerror("boolean value expected"); }
-               | LISTEN EQUAL ipv4  {
+               | LISTEN EQUAL ip  {
                                                                if (addresses_no < MAX_LISTEN){
-                                                                       tmp=inet_ntoa(*(struct in_addr*)&$3);
-                                                                       names[addresses_no]=
-                                                                                               (char*)malloc(strlen(tmp)+1);
-                                                                       if (names[addresses_no]==0){
+                                                                       tmp=ip_addr2a($3);
+                                                               /*      tmp=inet_ntoa(*(struct in_addr*)&$3);*/
+                                                                       if (tmp==0){
                                                                                LOG(L_CRIT, "ERROR: cfg. parser: "
-                                                                                                               "out of memory.\n");
+                                                                                       " bad ip address: %s\n",
+                                                                                       strerror(errno));
                                                                        }else{
-                                                                               strncpy(names[addresses_no], tmp,
-                                                                                               strlen(tmp)+1);
-                                                                               addresses_no++;
+                                                                               names[addresses_no]=
+                                                                                               (char*)malloc(strlen(tmp)+1);
+                                                                               if (names[addresses_no]==0){
+                                                                                       LOG(L_CRIT, "ERROR: cfg. parser: "
+                                                                                                               "out of memory.\n");
+                                                                               }else{
+                                                                                       strncpy(names[addresses_no], tmp,
+                                                                                                       strlen(tmp)+1);
+                                                                                       addresses_no++;
+                                                                               }
                                                                        }
                                                                }else{
                                                                        LOG(L_CRIT, "ERROR: cfg. parser:"
@@ -255,21 +266,63 @@ module_stm:       LOADMODULE STRING       { DBG("loading module %s\n", $2);
                 ;
 
 
+ip:             ipv4  { $$=$1; }
+               |ipv6  { $$=$1; }
+               ;
+
 ipv4:  NUMBER DOT NUMBER DOT NUMBER DOT NUMBER { 
-                                                                                       if (($1>255) || ($1<0) ||
-                                                                                               ($3>255) || ($3<0) ||
-                                                                                               ($5>255) || ($5<0) ||
-                                                                                               ($7>255) || ($7<0)){
-                                                                                               yyerror("invalid ipv4"
-                                                                                                               "address");
-                                                                                               $$=0;
+                                                                                       $$=malloc(sizeof(struct ip_addr));
+                                                                                       if ($$==0){
+                                                                                               LOG(L_CRIT, "ERROR: cfg. "
+                                                                                                       "parser: out of memory.\n"
+                                                                                                       );
                                                                                        }else{
-                                                                                               $$=htonl( ($1<<24)|
+                                                                                               memset($$, 0, 
+                                                                                                       sizeof(struct ip_addr));
+                                                                                               $$->af=AF_INET;
+                                                                                               $$->len=4;
+                                                                                               if (($1>255) || ($1<0) ||
+                                                                                                       ($3>255) || ($3<0) ||
+                                                                                                       ($5>255) || ($5<0) ||
+                                                                                                       ($7>255) || ($7<0)){
+                                                                                                       yyerror("invalid ipv4"
+                                                                                                                       "address");
+                                                                                                       $$->u.addr32[0]=0;
+                                                                                                       /* $$=0; */
+                                                                                               }else{
+                                                                                                       $$->u.addr[0]=$1;
+                                                                                                       $$->u.addr[1]=$3;
+                                                                                                       $$->u.addr[2]=$5;
+                                                                                                       $$->u.addr[3]=$7;
+                                                                                                       /*
+                                                                                                       $$=htonl( ($1<<24)|
                                                                                                        ($3<<16)| ($5<<8)|$7 );
+                                                                                                       */
+                                                                                               }
                                                                                        }
                                                                                                }
        ;
 
+ipv6:  IPV6ADDR {
+                                       $$=malloc(sizeof(struct ip_addr));
+                                       if ($$==0){
+                                               LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
+                                       }else{
+                                               memset($$, 0, sizeof(struct ip_addr));
+                                               $$->af=AF_INET6;
+                                               $$->len=16;
+                                       #ifndef USE_IPV6
+                                               yyerror("ipv6 address & no ipv6 support compiled in");
+                                               YYABORT;
+                                       #endif
+                                               if (inet_pton(AF_INET6, $1, $$->u.addr)<=0){
+                                                       yyerror("bad ipv6 address");
+                                               }
+                                       }
+                               }
+       ;
+
+
 route_stm:     ROUTE LBRACE actions RBRACE { push($3, &rlist[DEFAULT_RT]); }
 
                | ROUTE LBRACK NUMBER RBRACK LBRACE actions RBRACE { 
@@ -343,7 +396,7 @@ exp_elem:   METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP, STRING_ST,
                | URI error     { $$=0; yyerror("invalid operator,"
                                                                        " == or =~ expected");
                                        }
-               | SRCIP EQUAL_T net4    { $$=mk_elem(   EQUAL_OP, NET_ST,
+               | SRCIP EQUAL_T ipnet   { $$=mk_elem(   EQUAL_OP, NET_ST,
                                                                                                SRCIP_O, $3);
                                                                }
                | SRCIP EQUAL_T STRING  { $$=mk_elem(   EQUAL_OP, STRING_ST,
@@ -363,7 +416,7 @@ exp_elem:   METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP, STRING_ST,
                | SRCIP MATCH error  { $$=0; yyerror( "hostname expected"); }
                | SRCIP error  { $$=0; 
                                                 yyerror("invalid operator, == or =~ expected");}
-               | DSTIP EQUAL_T net4    { $$=mk_elem(   EQUAL_OP, NET_ST,
+               | DSTIP EQUAL_T ipnet   { $$=mk_elem(   EQUAL_OP, NET_ST,
                                                                                                DSTIP_O, $3);
                                                                }
                | DSTIP EQUAL_T STRING  { $$=mk_elem(   EQUAL_OP, STRING_ST,
@@ -387,18 +440,22 @@ exp_elem: METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP, STRING_ST,
                | NUMBER                {$$=mk_elem( NO_OP, NUMBER_ST, NUMBER_O, (void*)$1 ); }
        ;
 
-net4:  ipv4 SLASH ipv4 { $$=mk_net($1, $3); } 
-       | ipv4 SLASH NUMBER {   if (($3>32)|($3<0)){
+ipnet: ip SLASH ip     { $$=mk_net($1, $3); } 
+       | ip SLASH NUMBER       {       if (($3<0) || ($3>$1->len*8)){
                                                                yyerror("invalid bit number in netmask");
                                                                $$=0;
                                                        }else{
+                                                               $$=mk_net_bitlen($1, $3);
+                                                       /*
                                                                $$=mk_net($1, 
                                                                                htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
+                                                       */
                                                        }
                                                }
-       | ipv4                          { $$=mk_net($1, 0xffffffff); }
-       | ipv4 SLASH error { $$=0;
-                                                yyerror("netmask (eg:255.0.0.0 or 8) expected");}
+       | ip                            { $$=mk_net_bitlen($1, $1->len*8); }
+       | ip SLASH error        { $$=0;
+                                                yyerror("netmask (eg:255.0.0.0 or 8) expected");
+                                               }
        ;
 
 host:  ID                              { $$=$1; }
@@ -462,7 +519,7 @@ cmd:                FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
                                                                                                                $3,
                                                                                                                0);
                                                                                }
-               | FORWARD LPAREN ipv4 RPAREN    { $$=mk_action( FORWARD_T,
+               | FORWARD LPAREN ip RPAREN      { $$=mk_action( FORWARD_T,
                                                                                                                IP_ST,
                                                                                                                NUMBER_ST,
                                                                                                                (void*)$3,
@@ -480,7 +537,7 @@ cmd:                FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
                                                                                                                                $3,
                                                                                                                                (void*)$5);
                                                                                                        }
-               | FORWARD LPAREN ipv4 COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T,
+               | FORWARD LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_T,
                                                                                                                                 IP_ST,
                                                                                                                                 NUMBER_ST,
                                                                                                                                 (void*)$3,
@@ -524,7 +581,7 @@ cmd:                FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
                                                                                                        $3,
                                                                                                        0);
                                                                        }
-               | SEND LPAREN ipv4 RPAREN       { $$=mk_action( SEND_T,
+               | SEND LPAREN ip RPAREN         { $$=mk_action( SEND_T,
                                                                                                        IP_ST,
                                                                                                        NUMBER_ST,
                                                                                                        (void*)$3,
@@ -542,7 +599,7 @@ cmd:                FORWARD LPAREN host RPAREN      { $$=mk_action( FORWARD_T,
                                                                                                                                $3,
                                                                                                                                (void*)$5);
                                                                                                }
-               | SEND LPAREN ipv4 COMMA NUMBER RPAREN { $$=mk_action(  SEND_T,
+               | SEND LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(    SEND_T,
                                                                                                                                IP_ST,
                                                                                                                                NUMBER_ST,
                                                                                                                                (void*)$3,
index 8d36e2e..6a4bc16 100644 (file)
--- a/dprint.h
+++ b/dprint.h
@@ -8,7 +8,6 @@
 
 #include <syslog.h>
 
-#include "globals.h"
 
 #define L_ALERT -3
 #define L_CRIT  -2
 #define L_INFO   3
 #define L_DBG    4
 
+/* vars:*/
+
+extern int debug;
+extern int log_stderr;
 
 
 #define DPRINT_LEV     1
diff --git a/flags.h b/flags.h
index 5975c28..cf0411c 100644 (file)
--- a/flags.h
+++ b/flags.h
@@ -9,7 +9,7 @@
 enum { FL_WHITE=1, FL_YELLOW, FL_GREEN, FL_RED, FL_BLUE, FL_MAGENTA,
           FL_BROWN, FL_BLACK, FL_ACC, FL_MAX };
 
-typedef unsigned long flag_t;
+typedef unsigned int flag_t;
 
 #define MAX_FLAG  ( sizeof(flag_t) * CHAR_BIT - 1 )
 
index 8c26f85..b4e6b13 100644 (file)
--- a/forward.c
+++ b/forward.c
@@ -25,6 +25,8 @@
 #include "msg_translator.h"
 #include "sr_module.h"
 #include "stats.h"
+#include "ip_addr.h"
+#include "resolve.h"
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
@@ -36,7 +38,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
 {
        unsigned int len;
        char* buf;
-       struct sockaddr_in* to;
+       union sockaddr_union* to;
 
        to=0;
        buf = build_req_buf_from_sip_req( msg, &len);
@@ -45,7 +47,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
                goto error;
        }
 
-       to=(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
+       to=(union sockaddr_union*)malloc(sizeof(union sockaddr_union));
        if (to==0){
                LOG(L_ERR, "ERROR: forward_request: out of memory\n");
                goto error;
@@ -55,26 +57,20 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
        DBG("Sending:\n%s.\n", buf);
        DBG("orig. len=%d, new_len=%d\n", msg->len, len );
 
-       to->sin_family = AF_INET;
-       to->sin_port = (p->port)?htons(p->port):htons(SIP_PORT);
        /* if error try next ip address if possible */
        if (p->ok==0){
                if (p->host.h_addr_list[p->addr_idx+1])
                        p->addr_idx++;
+               else p->addr_idx=0;
                p->ok=1;
        }
-       
-       memcpy(&(to->sin_addr.s_addr), p->host.h_addr_list[p->addr_idx],
-                       sizeof(to->sin_addr.s_addr));
-       /* 
-       to->sin_addr.s_addr=*((long*)p->host.h_addr_list[p->addr_idx]);
-       */
 
+       hostent2su(to, &p->host, p->addr_idx, 
+                               (p->port)?htons(p->port):htons(SIP_PORT));
        p->tx++;
        p->tx_bytes+=len;
 
-       if (udp_send( buf, len, (struct sockaddr*) to,
-                               sizeof(struct sockaddr_in))==-1){
+       if (udp_send( buf, len,  to, sizeof(union sockaddr_union))==-1){
                        p->errors++;
                        p->ok=0;
                        STATS_TX_DROPS;
@@ -93,43 +89,50 @@ error:
 }
 
 
-int update_sock_struct_from_via( struct sockaddr_in* to,  struct via_body* via )
+int update_sock_struct_from_via( union sockaddr_union* to,  
+                                                                struct via_body* via )
 {
        int err;
        struct hostent* he;
+       unsigned int ip;
        char *host_copy;
 
-       to->sin_family = AF_INET;
-       to->sin_port = (via->port)?htons(via->port): htons(SIP_PORT);
 
 #ifdef DNS_IP_HACK
-       to->sin_addr.s_addr=str2ip((unsigned char*)via->host.s,via->host.len,&err);
-       if (err)
+       ip=str2ip((unsigned char*)via->host.s,via->host.len,&err);
+       if (err==0){
+               to->sin.sin_family=AF_INET;
+               to->sin.sin_port=(via->port)?htons(via->port): htons(SIP_PORT);
+               memcpy(&to->sin.sin_addr, (char*)&ip, 4);
+       }else
 #endif
        {
-               /* fork? gethostbyname will probably block... */
                /* we do now a malloc/memcpy because gethostbyname loves \0-terminated 
-                  strings; -jiri */
-               if (!(host_copy=pkg_malloc( via->host.len+1 ))) {
-                       LOG(L_NOTICE, "ERROR: update_sock_struct_from_via: not enough memory\n");
-                       return -1;
+                  strings; -jiri 
+                  but only if host is not null terminated
+                  (host.s[len] will always be ok for a via)
+           BTW: when is via->host.s non null terminated? tm copy?
+                  - andrei 
+               */
+               if (via->host.s[via->host.len]){
+                       if (!(host_copy=pkg_malloc( via->host.len+1 ))) {
+                               LOG(L_NOTICE, "ERROR: update_sock_struct_from_via: not enough memory\n");
+                               return -1;
+                       }
+                       memcpy(host_copy, via->host.s, via->host.len );
+                       host_copy[via->host.len]=0;
+                       he=resolvehost(host_copy);
+                       pkg_free( host_copy );
+               }else{
+                       he=resolvehost(via->host.s);
                }
-               memcpy(host_copy, via->host.s, via->host.len );
-               host_copy[via->host.len]=0;
-               he=gethostbyname(host_copy);
-               /* he=gethostbyname(via->host.s); */
-               pkg_free( host_copy );
 
                if (he==0){
                        LOG(L_NOTICE, "ERROR:forward_reply:gethostbyname(%s) failure\n",
                                        via->host.s);
                        return -1;
                }
-               memcpy(&(to->sin_addr.s_addr), he->h_addr_list[0], 
-                               sizeof(to->sin_addr.s_addr));
-               /*
-               to->sin_addr.s_addr=*((long*)he->h_addr_list[0]);
-               */
+               hostent2su(to, he, 0, (via->port)?htons(via->port): htons(SIP_PORT));
        }
        return 1;
 }
@@ -140,7 +143,7 @@ int forward_reply(struct sip_msg* msg)
 {
        int  r;
        char* new_buf;
-       struct sockaddr_in* to;
+       union sockaddr_union* to;
        unsigned int new_len;
        struct sr_module *mod;
        
@@ -158,7 +161,6 @@ int forward_reply(struct sip_msg* msg)
                }
        }
 
-       /* here will be called the T Module !!!!!!  */
        /* quick hack, slower for mutliple modules*/
        for (mod=modules;mod;mod=mod->next){
                if ((mod->exports) && (mod->exports->response_f)){
@@ -176,7 +178,7 @@ int forward_reply(struct sip_msg* msg)
                goto error;
        }
 
-       to=(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
+       to=(union sockaddr_union*)malloc(sizeof(union sockaddr_union));
        if (to==0){
                LOG(L_ERR, "ERROR: forward_reply: out of memory\n");
                goto error;
@@ -190,8 +192,8 @@ int forward_reply(struct sip_msg* msg)
 
        if (update_sock_struct_from_via( to, msg->via2 )==-1) goto error;
 
-       if (udp_send(new_buf,new_len, (struct sockaddr*) to,
-                                       sizeof(struct sockaddr_in))==-1)
+       if (udp_send(new_buf,new_len,  to,
+                               sizeof(union sockaddr_union))==-1)
        {
                STATS_TX_DROPS;
                goto error;
index ec1e390..aa7e52d 100644 (file)
--- a/forward.h
+++ b/forward.h
@@ -12,7 +12,8 @@
 
 
 int forward_request( struct sip_msg* msg,  struct proxy_l* p);
-int update_sock_struct_from_via( struct sockaddr_in* to,  struct via_body* via );
+int update_sock_struct_from_via( union sockaddr_union* to,
+                                                               struct via_body* via );
 int forward_reply( struct sip_msg* msg);
 
 #endif
index 776f858..15056c4 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -10,6 +10,7 @@
 #define globals_h
 
 #include "types.h"
+#include "ip_addr.h"
 
 #define NO_DNS     0
 #define DO_DNS     1
@@ -24,17 +25,17 @@ extern int port_no_str_len;
 extern unsigned int maxbuffer;
 extern char * names[];
 extern int names_len[];
-extern unsigned int addresses[];
+extern struct ip_addr addresses[];
 extern int addresses_no;
-extern unsigned int bind_address;
+extern struct ip_addr* bind_address;
 extern int children_no;
-extern int debug;
 extern int dont_fork;
-extern int log_stderr;
 extern int check_via;
 extern int received_dns;
 extern int loop_checks;
 extern int process_no;
+/*
+ * debug & log_stderr moved to dprint.h*/
 
 extern process_bm_t process_bit;
 extern int *pids;
diff --git a/ip_addr.c b/ip_addr.c
new file mode 100644 (file)
index 0000000..b8fc86e
--- /dev/null
+++ b/ip_addr.c
@@ -0,0 +1,126 @@
+/*
+ * $Id$
+ *
+ *
+ * ip address & address family related functions
+ */
+
+#include <stdio.h>
+
+#include "ip_addr.h"
+#include "dprint.h"
+
+
+struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask)
+{
+       struct net* n;
+       
+       if ((ip->af != mask->af) || (ip->len != mask->len)){
+               LOG(L_CRIT, "ERROR: mk_net: trying to use a different mask family"
+                               " (eg. ipv4/ipv6mask or ipv6/ipv4mask)\n");
+               goto error;
+       }
+       n=(struct net*)malloc(sizeof(struct net));
+       if (n==0){ 
+               LOG(L_CRIT, "ERROR: mk_net: memory allocation failure\n");
+               goto error;
+       }
+       n->ip=*ip;
+       n->mask=*mask;
+       return n;
+error:
+       return 0;
+}
+
+
+
+struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
+{
+       struct net* n;
+       int r;
+       
+       if (bitlen>ip->len*8){
+               LOG(L_CRIT, "ERROR: mk_net_bitlen: bad bitlen number %d\n", bitlen);
+               goto error;
+       }
+       n=(struct net*)malloc(sizeof(struct net));
+       if (n==0){
+               LOG(L_CRIT, "ERROR: mk_net_bitlen: memory allocation failure\n"); 
+               goto error;
+       }
+       memset(n,0, sizeof(struct net));
+       n->ip=*ip;
+       for (r=0;r<bitlen/8;r++) n->mask.u.addr[r]=0xff;
+       if (bitlen%8) n->mask.u.addr[r]=  ~((1<<(8-(bitlen%8)))-1);
+       n->mask.af=ip->af;
+       n->mask.len=ip->len;
+       
+       return n;
+error:
+       return 0;
+}
+
+
+
+void print_ip(struct ip_addr* ip)
+{
+       switch(ip->af){
+               case AF_INET:
+                       DBG("%d.%d.%d.%d",      ip->u.addr[0],
+                                                               ip->u.addr[1],
+                                                               ip->u.addr[2],
+                                                               ip->u.addr[3]);
+                       break;
+               case AF_INET6:
+                       DBG("%x:%x:%x:%x:%x:%x:%x:%x",  htons(ip->u.addr16[0]),
+                                                                                       htons(ip->u.addr16[1]),
+                                                                                       htons(ip->u.addr16[2]),
+                                                                                       htons(ip->u.addr16[3]),
+                                                                                       htons(ip->u.addr16[4]),
+                                                                                       htons(ip->u.addr16[5]),
+                                                                                       htons(ip->u.addr16[6]),
+                                                                                       htons(ip->u.addr16[7])
+                               );
+                       break;
+               default:
+                       DBG("print_ip: warning unknown adress family %d\n", ip->af);
+       }
+}
+
+
+
+void stdout_print_ip(struct ip_addr* ip)
+{
+       switch(ip->af){
+               case AF_INET:
+                       printf("%d.%d.%d.%d",   ip->u.addr[0],
+                                                               ip->u.addr[1],
+                                                               ip->u.addr[2],
+                                                               ip->u.addr[3]);
+                       break;
+               case AF_INET6:
+                       printf("%x:%x:%x:%x:%x:%x:%x:%x",       htons(ip->u.addr16[0]),
+                                                                                       htons(ip->u.addr16[1]),
+                                                                                       htons(ip->u.addr16[2]),
+                                                                                       htons(ip->u.addr16[3]),
+                                                                                       htons(ip->u.addr16[4]),
+                                                                                       htons(ip->u.addr16[5]),
+                                                                                       htons(ip->u.addr16[6]),
+                                                                                       htons(ip->u.addr16[7])
+                               );
+                       break;
+               default:
+                       DBG("print_ip: warning unknown adress family %d\n", ip->af);
+       }
+}
+
+
+
+void print_net(struct net* net)
+{
+       if (net==0){
+               LOG(L_WARN, "ERROR: print net: null pointer\n");
+               return;
+       }
+       print_ip(&net->ip); DBG("/"); print_ip(&net->mask);
+}
diff --git a/ip_addr.h b/ip_addr.h
new file mode 100644 (file)
index 0000000..d9628c6
--- /dev/null
+++ b/ip_addr.h
@@ -0,0 +1,336 @@
+/* $Id$
+ *
+ * ip address family realted structures
+ */
+
+#ifndef ip_addr_h
+#define ip_addr_h
+
+#include <string.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#ifdef USE_IPV6
+       #ifdef FreeBSD                  /* freebsd is brain damaged and needs a different
+                                                          include */
+#include <netinet6/in6.h>
+       #endif
+#endif
+
+#include "dprint.h"
+
+
+
+struct ip_addr{
+       unsigned int af; /* address family: AF_INET6 or AF_INET */
+       unsigned int len;    /* address len, 16 or 4 */
+       
+       /* 64 bits alligned address */
+       union {
+               unsigned int   addr32[4];
+               unsigned short addr16[8];
+               unsigned char  addr[16];
+       }u;
+};
+
+
+
+struct net{
+       struct ip_addr ip;
+       struct ip_addr mask;
+};
+
+union sockaddr_union{
+               struct sockaddr     s;
+               struct sockaddr_in  sin;
+       #ifdef USE_IPV6
+               struct sockaddr_in6 sin6;
+       #endif
+};
+
+
+
+
+/* inits an ip_addr with the addr. info from a hostent structure
+ * ip = struct ip_addr*
+ * he= struct hostent*
+ */
+#define hostent2ip_addr(ip, he, addr_no) \
+       do{ \
+               (ip)->af=(he)->h_addrtype; \
+               (ip)->len=(he)->h_length;  \
+               memcpy((ip)->u.addr, (he)->h_addr_list[(addr_no)], (ip)->len); \
+       }while(0)
+       
+
+
+
+/* gets the protocol family corresponding to a specific address family
+ * ( PF_INET - AF_INET, PF_INET6 - AF_INET6, af for others)
+ */
+#ifdef USE_IPV6
+#define AF2PF(af)   (((af)==AF_INET)?PF_INET:((af)==AF_INET6)?PF_INET6:(af))
+#else
+#define AF2PF(af)   (((af)==AF_INET)?PF_INET:(af))
+#endif
+
+
+
+
+struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask);
+struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
+
+void print_ip(struct ip_addr* ip);
+void stdout_print_ip(struct ip_addr* ip);
+void print_net(struct net* net);
+
+
+
+
+/* returns 1 if ip & net.mask == net.ip ; 0 otherwise & -1 on error 
+       [ diff. adress fams ]) */
+inline static int matchnet(struct ip_addr* ip, struct net* net)
+{
+       int r;
+       int ret;
+       
+       ret=-1;
+       if (ip->af == net->ip.af){
+               for(r=0; r<ip->len/4; r++){ /* ipv4 & ipv6 addresses are
+                                                                          all multiple of 4*/
+                       if ((ip->u.addr32[r]&net->mask.u.addr32[r])!=
+                                                                                                                net->ip.u.addr32[r]){
+                               return 0;
+                       }
+               }
+               return 1;
+       };
+       return -1;
+}
+
+
+
+/* inits an ip_addr pointer from a sockaddr_union ip address */
+static inline void su2ip_addr(struct ip_addr* ip, union sockaddr_union* su)
+{
+       switch(su->s.sa_family){
+       case AF_INET: 
+                                       ip->af=AF_INET;
+                                       ip->len=4;
+                                       memcpy(ip->u.addr, &su->sin.sin_addr, 4);
+                                       break;
+#ifdef USE_IPV6
+       case AF_INET6:
+                                       ip->af=AF_INET6;
+                                       ip->len=16;
+                                       memcpy(ip->u.addr, &su->sin6.sin6_addr, 16);
+                                       break;
+#endif
+       default:
+                                       LOG(L_CRIT,"su2ip_addr: BUG: unknown address family %d\n",
+                                                       su->s.sa_family);
+       }
+}
+
+
+
+/* inits a struct sockaddr_union from a struct ip_addr and a port no 
+ * returns 0 if ok, -1 on error (unknown address family) */
+static inline int init_su( union sockaddr_union* su,
+                                                       struct ip_addr* ip,
+                                                       unsigned short   port ) 
+{
+       su->s.sa_family=ip->af;
+       switch(ip->af){
+#ifdef USE_IPV6
+       case    AF_INET6:
+               memcpy(&su->sin6.sin6_addr, ip->u.addr, ip->len); 
+               #ifdef FreeBSD
+                       su->sin6.sin6_len=sizeof(struct sockaddr_in6);
+               #endif
+               su->sin6.sin6_port=port;
+               break;
+#endif
+       case AF_INET:
+               memcpy(&su->sin.sin_addr, ip->u.addr, ip->len);
+               #ifdef FreeBSD
+                       su->sin.sin_len=sizeof(struct sockaddr_in);
+               #endif
+               su->sin.sin_port=port;
+               break;
+       default:
+               LOG(L_CRIT, "init_ss: BUG: unknown address family %d\n", ip->af);
+               return -1;
+       }
+       return 0;
+}
+
+
+
+/* inits a struct sockaddr_union from a struct hostent, an address index int
+ * the hostent structure and a port no.
+ * WARNING: no index overflow  checks!
+ * returns 0 if ok, -1 on error (unknown address family) */
+static inline int hostent2su( union sockaddr_union* su,
+                                                               struct hostent* he,
+                                                               unsigned int idx,
+                                                               unsigned short   port ) 
+{
+       su->s.sa_family=he->h_addrtype;
+       switch(he->h_addrtype){
+#ifdef USE_IPV6
+       case    AF_INET6:
+               memcpy(&su->sin6.sin6_addr, he->h_addr_list[idx], he->h_length);
+               #ifdef FreeBSD
+                       su->sin6.sin6_len=sizeof(struct sockaddr_in6);
+               #endif
+               su->sin6.sin6_port=port;
+               break;
+#endif
+       case AF_INET:
+               memcpy(&su->sin.sin_addr, he->h_addr_list[idx], he->h_length);
+               #ifdef FreeBSD
+                       su->sin.sin_len=sizeof(struct sockaddr_in);
+               #endif
+               su->sin.sin_port=port;
+               break;
+       default:
+               LOG(L_CRIT, "hostent2su: BUG: unknown address family %d\n", 
+                               he->h_addrtype);
+               return -1;
+       }
+       return 0;
+}
+
+
+
+/* fast ip_addr -> string convertor;
+ * it uses an internal buffer
+ */
+static inline char* ip_addr2a(struct ip_addr* ip)
+{
+
+       static char buff[40];/* 1234:5678:9012:3456:7890:1234:5678:9012\0 */
+       int offset;
+       register unsigned char a,b,c;
+#ifdef USE_IPV6
+       register unsigned char d;
+#endif
+       int r;
+       #define HEXDIG(x) (((x)>=10)?(x)-10+'A':(x)+'0')
+       
+       
+       offset=0;
+       switch(ip->af){
+       #ifdef USE_IPV6
+               case AF_INET6:
+                       for(r=0;r<7;r++){
+                               a=ip->u.addr16[r]>>12;
+                               b=(ip->u.addr16[r]>>8)&0xf;
+                               c=(ip->u.addr16[r]>>4)&0xf;
+                               d=ip->u.addr16[r]&0xf;
+                               if (a){
+                                       buff[offset]=HEXDIG(a);
+                                       buff[offset+1]=HEXDIG(b);
+                                       buff[offset+2]=HEXDIG(c);
+                                       buff[offset+3]=HEXDIG(d);
+                                       buff[offset+4]=':';
+                                       offset+=5;
+                               }else if(b){
+                                       buff[offset]=HEXDIG(b);
+                                       buff[offset+1]=HEXDIG(c);
+                                       buff[offset+2]=HEXDIG(d);
+                                       buff[offset+3]=':';
+                                       offset+=4;
+                               }else if(c){
+                                       buff[offset]=HEXDIG(c);
+                                       buff[offset+1]=HEXDIG(d);
+                                       buff[offset+2]=':';
+                                       offset+=3;
+                               }else{
+                                       buff[offset]=HEXDIG(d);
+                                       buff[offset+1]=':';
+                                       offset+=2;
+                               }
+                       }
+                       /* last int16*/
+                       a=ip->u.addr16[r]>>12;
+                       b=(ip->u.addr16[r]>>8)&0xf;
+                       c=(ip->u.addr16[r]>>4)&0xf;
+                       d=ip->u.addr16[r]&0xf;
+                       if (a){
+                               buff[offset]=HEXDIG(a);
+                               buff[offset+1]=HEXDIG(b);
+                               buff[offset+2]=HEXDIG(c);
+                               buff[offset+3]=HEXDIG(d);
+                               buff[offset+4]=0;
+                       }else if(b){
+                               buff[offset]=HEXDIG(b);
+                               buff[offset+1]=HEXDIG(c);
+                               buff[offset+2]=HEXDIG(d);
+                               buff[offset+3]=0;
+                       }else if(c){
+                               buff[offset]=HEXDIG(c);
+                               buff[offset+1]=HEXDIG(d);
+                               buff[offset+2]=0;
+                       }else{
+                               buff[offset]=HEXDIG(d);
+                               buff[offset+1]=0;
+                       }
+                       break;
+       #endif
+               case AF_INET:
+                       for(r=0;r<3;r++){
+                               a=ip->u.addr[r]/100;
+                               c=ip->u.addr[r]%10;
+                               b=ip->u.addr[r]%100/10;
+                               if (a){
+                                       buff[offset]=a+'0';
+                                       buff[offset+1]=b+'0';
+                                       buff[offset+2]=c+'0';
+                                       buff[offset+3]='.';
+                                       offset+=4;
+                               }else if (b){
+                                       buff[offset]=b+'0';
+                                       buff[offset+1]=c+'0';
+                                       buff[offset+2]='.';
+                                       offset+=3;
+                               }else{
+                                       buff[offset]=c+'0';
+                                       buff[offset+1]='.';
+                                       offset+=2;
+                               }
+                       }
+                       /* last number */
+                       a=ip->u.addr[r]/100;
+                       c=ip->u.addr[r]%10;
+                       b=ip->u.addr[r]%100/10;
+                       if (a){
+                               buff[offset]=a+'0';
+                               buff[offset+1]=b+'0';
+                               buff[offset+2]=c+'0';
+                               buff[offset+3]=0;
+                       }else if (b){
+                               buff[offset]=b+'0';
+                               buff[offset+1]=c+'0';
+                               buff[offset+2]=0;
+                       }else{
+                               buff[offset]=c+'0';
+                               buff[offset+1]=0;
+                       }
+                       break;
+               
+               default:
+                       LOG(L_CRIT, "BUG: ip_addr2a: unknown address family %d\n",
+                                       ip->af);
+                       return 0;
+       }
+       
+       return buff;
+}
+
+
+
+
+
+#endif
diff --git a/main.c b/main.c
index 5c0200a..d573dd9 100644 (file)
--- a/main.c
+++ b/main.c
@@ -18,6 +18,7 @@
 #include <sys/fcntl.h>
 #include <sys/time.h>
 #include <sys/wait.h>
+#include <signal.h>
 
 #include "config.h"
 #include "dprint.h"
 #include "sr_module.h"
 #include "timer.h"
 #include "parser/msg_parser.h"
+#include "ip_addr.h"
+#include "resolve.h"
 
 
-#include <signal.h>
 
 #include "stats.h"
 
@@ -51,6 +53,9 @@ static char flags[]=
 #else
 "Off"
 #endif
+#ifdef USE_IPV6
+", USE_IPV6"
+#endif
 #ifdef NO_DEBUG
 ", NO_DEBUG"
 #endif
@@ -142,7 +147,7 @@ Options:\n\
     -h           This help message\n\
     -b nr        Maximum receive buffer size which will not be exceeded by\n\
                  auto-probing procedure even if  OS allows\n\
-       -m nr        Size of shared memory allocated in Megabytes\n\
+    -m nr        Size of shared memory allocated in Megabytes\n\
     -w  dir      change the working directory to \"dir\" (default \"/\")\n\
     -t  dir      chroot to \"dir\"\n\
     -u uid       change uid \n\
@@ -193,12 +198,13 @@ char* cfg_file = 0;
 unsigned short port_no = 0; /* port on which we listen */
 char port_no_str[MAX_PORT_LEN];
 int port_no_str_len=0;
-unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do not want to exceed
-                                               durig the auto-probing procedure; may be
-                                               re-configured */
-int children_no = 0;           /* number of children processing requests */
-int *pids=0;                  /*array with childrens pids, 0= main proc,
-                               alloc'ed in shared mem if possible*/
+unsigned int maxbuffer = MAX_RECV_BUFFER_SIZE; /* maximum buffer size we do
+                                                                                                 not want to exceed durig the
+                                                                                                 auto-probing procedure; may 
+                                                                                                 be re-configured */
+int children_no = 0;                   /* number of children processing requests */
+int *pids=0;                                   /*array with childrens pids, 0= main proc,
+                                                                       alloc'ed in shared mem if possible*/
 int debug = 0;
 int dont_fork = 0;
 int log_stderr = 0;
@@ -213,9 +219,9 @@ int gid = 0;
 
 char* names[MAX_LISTEN];              /* our names */
 int names_len[MAX_LISTEN];            /* lengths of the names*/
-unsigned int addresses[MAX_LISTEN];   /* our ips */
+struct ip_addr addresses[MAX_LISTEN]; /* our ips */
 int addresses_no=0;                   /* number of names/ips */
-unsigned int bind_address=0;          /* listen address of the crt. process */
+struct ip_addr* bind_address;        /* listen address of the crt. process */
 
 /* ipc related globals */
 int process_no = 0;
@@ -373,7 +379,7 @@ int main_loop()
                setstats( 0 );
 #endif
                /* only one address */
-               if (udp_init(addresses[0],port_no)==-1) goto error;
+               if (udp_init(&addresses[0],port_no)==-1) goto error;
 
                /* we need another process to act as the timer*/
                if (timer_list){
@@ -414,7 +420,7 @@ int main_loop()
        }else{
                for(r=0;r<addresses_no;r++){
                        /* create the listening socket (for each address)*/
-                       if (udp_init(addresses[r], port_no)==-1) goto error;
+                       if (udp_init(&addresses[r], port_no)==-1) goto error;
                        for(i=0;i<children_no;i++){
                                if ((pid=fork())<0){
                                        LOG(L_CRIT,  "main_loop: Cannot fork\n");
@@ -784,8 +790,8 @@ int main(int argc, char** argv)
                fprintf(stderr, "ERROR: bad port number: %d\n", port_no);
                goto error;
        }
-       /* on some system snprintf return really strange things if it does not have
-        * enough space */
+       /* on some system snprintf return really strange things if it does not 
+          have  enough space */
        port_no_str_len=
                                (port_no_str_len<MAX_PORT_LEN)?port_no_str_len:MAX_PORT_LEN;
 
@@ -836,16 +842,17 @@ int main(int argc, char** argv)
        /* get ips */
        printf("Listening on ");
        for (r=0; r<addresses_no;r++){
-               he=gethostbyname(names[r]);
+               he=resolvehost(names[r]);
                if (he==0){
                        DPrint("ERROR: could not resolve %s\n", names[r]);
                        goto error;
                }
-               memcpy(&addresses[r], he->h_addr_list[0], sizeof(int));
+               hostent2ip_addr(&addresses[r], he, 0); /*convert to ip_addr format*/
+               /*memcpy(&addresses[r], he->h_addr_list[0], sizeof(int));*/
                /*addresses[r]=*((long*)he->h_addr_list[0]);*/
-               printf("%s [%s] : %d\n",names[r],
-                               inet_ntoa(*(struct in_addr*)&addresses[r]),
-                               (unsigned short)port_no);
+               printf("%s [",names[r]);
+               stdout_print_ip(&addresses[r]);
+               printf("]:%d\n", (unsigned short)port_no);
        }
 
 #ifdef STATS
index b887bbd..90cfaea 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "shm_mem.h"
 #include "../config.h"
+#include "../globals.h"
 
 #ifdef  SHM_MMAP
 
@@ -23,6 +24,8 @@
 #endif
 
 
+
+
 /* define semun */
 #if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
        /* union semun is defined by including <sys/sem.h> */
index db332eb..36d64d4 100644 (file)
@@ -9,11 +9,14 @@
 #include <stdio.h>
 
 #include "msg_translator.h"
+#include "globals.h"
 #include "mem/mem.h"
 #include "dprint.h"
 #include "config.h"
 #include "md5utils.h"
 #include "data_lump_rpl.h"
+#include "ip_addr.h"
+#include "resolve.h"
 
 
 
 extern char version[];
 extern int version_len;
 
-/* faster than inet_ntoa */
-static inline char* q_inet_itoa(unsigned long ip)
-{
-       static char q_inet_itoa_buf[16]; /* 123.567.901.345\0 */
-       unsigned char* p;
-       unsigned char a,b,c;  /* abc.def.ghi.jkl */
-       int offset;
-       int r;
-       p=(unsigned char*)&ip;
-
-       offset=0;
-       /* unrolled loops (faster)*/
-       for(r=0;r<3;r++){
-               a=p[r]/100;
-               c=p[r]%10;
-               b=p[r]%100/10;
-               if (a){
-                       q_inet_itoa_buf[offset]=a+'0';
-                       q_inet_itoa_buf[offset+1]=b+'0';
-                       q_inet_itoa_buf[offset+2]=c+'0';
-                       q_inet_itoa_buf[offset+3]='.';
-                       offset+=4;
-               }else if (b){
-                       q_inet_itoa_buf[offset]=b+'0';
-                       q_inet_itoa_buf[offset+1]=c+'0';
-                       q_inet_itoa_buf[offset+2]='.';
-                       offset+=3;
-               }else{
-                       q_inet_itoa_buf[offset]=c+'0';
-                       q_inet_itoa_buf[offset+1]='.';
-                       offset+=2;
-               }
-       }
-       /* last number */
-       a=p[r]/100;
-       c=p[r]%10;
-       b=p[r]%100/10;
-       if (a){
-               q_inet_itoa_buf[offset]=a+'0';
-               q_inet_itoa_buf[offset+1]=b+'0';
-               q_inet_itoa_buf[offset+2]=c+'0';
-               q_inet_itoa_buf[offset+3]=0;
-       }else if (b){
-               q_inet_itoa_buf[offset]=b+'0';
-               q_inet_itoa_buf[offset+1]=c+'0';
-               q_inet_itoa_buf[offset+2]=0;
-       }else{
-               q_inet_itoa_buf[offset]=c+'0';
-               q_inet_itoa_buf[offset+1]=0;
-       }
-
-       return q_inet_itoa_buf;
-}
-
-
 
 
 /* checks if ip is in host(name) and ?host(ip)=name?
  * ip must be in network byte order!
  *  resolver = DO_DNS | DO_REV_DNS; if 0 no dns check is made
  * return 0 if equal */
-int check_address(unsigned long ip, char *name, int resolver)
+int check_address(struct ip_addr* ip, char *name, int resolver)
 {
        struct hostent* he;
        int i;
 
        /* maybe we are lucky and name it's an ip */
-       if (strcmp(name, q_inet_itoa(ip))==0)
+       if (strcmp(name, ip_addr2a(ip))==0)
                return 0;
        if (resolver&DO_DNS){
                DBG("check_address: doing dns lookup\n");
                /* try all names ips */
-               he=gethostbyname(name);
-               for(i=0;he && he->h_addr_list[i];i++){
-                       if (*(unsigned long*)he->h_addr_list[i]==ip)
-                               return 0;
+               he=resolvehost(name);
+               if (ip->af==he->h_addrtype){
+                       for(i=0;he && he->h_addr_list[i];i++){
+                               if ( memcmp(&he->h_addr_list[i], ip->u.addr, ip->len)==0)
+                                       return 0;
+                       }
                }
        }
        if (resolver&DO_REV_DNS){
                DBG("check_address: doing rev. dns lookup\n");
                /* try reverse dns */
-               he=gethostbyaddr((char*)&ip, sizeof(ip), AF_INET);
+               he=rev_resolvehost(ip);
                if (he && (strcmp(he->h_name, name)==0))
                        return 0;
                for (i=0; he && he->h_aliases[i];i++){
@@ -241,7 +191,7 @@ char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
        /*adding src_ip*/
        if (p-buf+26+2>=MAX_WARNING_LEN)
                goto done;
-       p += sprintf(p,"req_src_ip=%s",q_inet_itoa(msg->src_ip));
+       p += sprintf(p,"req_src_ip=%s",ip_addr2a(&msg->src_ip));
        *(p++)=' ';
 
        /*adding in_uri*/
@@ -274,7 +224,7 @@ done:
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
                                                                unsigned int *returned_len)
 {
-       unsigned int len, new_len, received_len, uri_len, via_len;
+       unsigned int len, new_len, received_len, uri_len, via_len, extra_len;
        char* line_buf;
        char* received_buf;
        char* tmp;
@@ -284,7 +234,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
        char* buf;
        char  backup;
        unsigned int offset, s_offset, size;
-       unsigned long source_ip;
+       struct ip_addr* source_ip;
        struct lump *t,*r;
        struct lump* anchor;
 
@@ -292,10 +242,11 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
        orig=msg->orig;
        buf=msg->buf;
        len=msg->len;
-       source_ip=msg->src_ip;
+       source_ip=&msg->src_ip;
        received_len=0;
        new_buf=0;
        received_buf=0;
+       extra_len=0;
 
 
        line_buf = via_builder( msg, &via_len );
@@ -318,10 +269,17 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
                                                                inet_ntoa(*(struct in_addr *)&source_ip));
                */
                memcpy(received_buf, RECEIVED, RECEIVED_LEN);
-               tmp=q_inet_itoa( /* *(struct in_addr *)& */source_ip);
+               tmp=ip_addr2a(source_ip);
                tmp_len=strlen(tmp);
                received_len=RECEIVED_LEN+tmp_len;
-               memcpy(received_buf+RECEIVED_LEN, tmp, tmp_len);
+               if(source_ip->af==AF_INET6){
+                       received_len+=2;
+                       received_buf[RECEIVED_LEN]='[';
+                       received_buf[RECEIVED_LEN+tmp_len+1]=']';
+                       extra_len=1;
+               }
+               
+               memcpy(received_buf+RECEIVED_LEN+extra_len, tmp, tmp_len);
                received_buf[received_len]=0; /*null terminate it */
        }
        msg->via1->host.s[msg->via1->host.len] = backup;
index 816869f..38328da 100644 (file)
@@ -777,9 +777,7 @@ int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
        
 error:
        /* more debugging, msg->orig is/should be null terminated*/
-       LOG(L_ERR, "ERROR: parse_msg: ip source=%x dest=%x; message=<%s>\n",
-                       msg->src_ip, msg->dst_ip,
-                       msg->orig);
+       LOG(L_ERR, "ERROR: parse_msg: message=<%s>\n", msg->orig);
        return -1;
 }
 
index 09326a0..e90f5bd 100644 (file)
@@ -8,6 +8,7 @@
 #include "../str.h"
 #include "../data_lump.h"
 #include "../flags.h"
+#include "../ip_addr.h"
 
 #define SIP_REQUEST 1
 #define SIP_REPLY   2
@@ -209,8 +210,8 @@ struct sip_msg{
        char* eoh; /* pointer to the end of header (if found) or null */
        char* unparsed; /* here we stopped parsing*/
 
-       unsigned int src_ip;
-       unsigned int dst_ip;
+       struct ip_addr src_ip;
+       struct ip_addr dst_ip;
        char* orig; /* original message copy */
        char* buf;  /* scratch pad, holds a modfied message,
                                   via, etc. point into it */
index ff5dbe2..28815b6 100644 (file)
@@ -1284,8 +1284,7 @@ main_via:
                                                        " no host found\n");
                                                goto error;
                                        case P_IP6HOST:
-                                               LOG(L_ERR, "ERROR:parse_via: bad ipv6 reference\n");
-                                               goto error;
+                                               break;
                                        case P_HOST:
                                                *tmp=0; /*mark  end of host*/
                                                vb->host.len=tmp-vb->host.s;
diff --git a/proxy.c b/proxy.c
index a748765..b31cf1e 100644 (file)
--- a/proxy.c
+++ b/proxy.c
@@ -18,6 +18,9 @@
 #include "ut.h"
 #endif
 
+#include "resolve.h"
+#include "ip_addr.h"
+
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
 #endif
@@ -174,6 +177,7 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
        p->name=name;
        p->port=port;
 #ifdef DNS_IP_HACK
+       /* fast ipv4 string to address conversion*/
        len=strlen(name);
        ip=str2ip((unsigned char*)name, len, &err);
        if (err==0){
@@ -210,7 +214,7 @@ struct proxy_l* mk_proxy(char* name, unsigned short port)
 #endif
        /* fail over to normal lookup */
 
-       he=gethostbyname(name);
+       he=resolvehost(name);
        if (he==0){
                LOG(L_CRIT, "ERROR: mk_proxy: could not resolve hostname:"
                                        " \"%s\"\n", name);
@@ -230,7 +234,7 @@ error:
 
 
 /* same as mk_proxy, but get the host as an ip*/
-struct proxy_l* mk_proxy_from_ip(unsigned int ip, unsigned short port)
+struct proxy_l* mk_proxy_from_ip(struct ip_addr* ip, unsigned short port)
 {
        struct proxy_l* p;
 
@@ -242,19 +246,19 @@ struct proxy_l* mk_proxy_from_ip(unsigned int ip, unsigned short port)
        memset(p,0,sizeof(struct proxy_l));
 
        p->port=port;
-       p->host.h_addrtype=AF_INET;
-       p->host.h_length=4;
+       p->host.h_addrtype=ip->af;
+       p->host.h_length=ip->len;
        p->host.h_addr_list=malloc(2*sizeof(char*));
        if (p->host.h_addr_list==0) goto error;
        p->host.h_addr_list[1]=0;
-       p->host.h_addr_list[0]=malloc(5);
+       p->host.h_addr_list[0]=malloc(ip->len+1);
        if (p->host.h_addr_list[0]==0){
                free(p->host.h_addr_list);
                goto error;
        }
 
-       memcpy(p->host.h_addr_list[0], (char*)&ip, 4);
-       p->host.h_addr_list[0][4]=0;
+       memcpy(p->host.h_addr_list[0], ip->u.addr, ip->len);
+       p->host.h_addr_list[0][ip->len]=0;
 
        return p;
 
diff --git a/proxy.h b/proxy.h
index b92836b..b9c7792 100644 (file)
--- a/proxy.h
+++ b/proxy.h
@@ -7,6 +7,7 @@
 #define proxy_h
 
 #include <netdb.h>
+#include "ip_addr.h"
 
 struct proxy_l{
        struct proxy_l* next;
@@ -29,7 +30,7 @@ extern struct proxy_l* proxies;
 
 struct proxy_l* add_proxy(char* name, unsigned short port);
 struct proxy_l* mk_proxy(char* name, unsigned short port);
-struct proxy_l* mk_proxy_from_ip(unsigned int ip, unsigned short port);
+struct proxy_l* mk_proxy_from_ip(struct ip_addr* ip, unsigned short port);
 void free_proxy(struct proxy_l* p);
 
 
index 2e43a9d..5b1af6b 100644 (file)
--- a/receive.c
+++ b/receive.c
@@ -7,6 +7,7 @@
 #include <sys/time.h>
 
 #include "receive.h"
+#include "globals.h"
 #include "dprint.h"
 #include "route.h"
 #include "parser/msg_parser.h"
@@ -14,6 +15,7 @@
 #include "action.h"
 #include "mem/mem.h"
 #include "stats.h"
+#include "ip_addr.h"
 
 
 #ifdef DEBUG_DMALLOC
@@ -22,7 +24,7 @@
 
 unsigned int msg_no=0;
 
-int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
+int receive_msg(char* buf, unsigned int len, union sockaddr_union* src_su)
 {
        struct sip_msg* msg;
 #ifdef STATS
@@ -40,8 +42,8 @@ int receive_msg(char* buf, unsigned int len, unsigned long src_ip)
        /* fill in msg */
        msg->buf=buf;
        msg->len=len;
-       msg->src_ip=src_ip;
-       msg->dst_ip=bind_address; /* won't work if listening on 0.0.0.0 */
+       su2ip_addr(&msg->src_ip, src_su);
+       msg->dst_ip=*bind_address; /* won't work if listening on 0.0.0.0 */
        msg->id=msg_no;
        /* make a copy of the message */
        msg->orig=(char*) pkg_malloc(len+1);
index c4d5367..f641500 100644 (file)
--- a/receive.h
+++ b/receive.h
@@ -6,7 +6,9 @@
 #ifndef receive_h
 #define receive_h
 
-int receive_msg(char* buf, unsigned int len, unsigned long src_ip);
+#include "ip_addr.h"
+
+int receive_msg(char* buf, unsigned int len, union sockaddr_union *src_su);
 
 
 #endif
diff --git a/resolve.h b/resolve.h
new file mode 100644 (file)
index 0000000..f4e2c9f
--- /dev/null
+++ b/resolve.h
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * resolver related functions
+ */
+
+
+#ifndef resolve_h
+#define resolve_h
+
+#include <netdb.h>
+
+
+/* gethostbyname wrappers
+ * use this, someday htey will use a local cache */
+
+
+
+static inline struct hostent* resolvehost(const char* name)
+{
+       struct hostent* he;
+       
+#ifdef DNS_IP_HACK
+#endif
+
+       he=gethostbyname(name); /*ipv4*/
+
+#ifdef USE_IPV6
+       if(he==0){
+               /*try ipv6*/
+               he=gethostbyname2(name, AF_INET6);
+       }
+#endif
+       return he;
+}
+
+
+
+#define rev_resolvehost(ip) gethostbyaddr((ip)->u.addr, (ip)->len, (ip)->af);
+
+
+#endif
diff --git a/route.c b/route.c
index 845b0e6..9066aeb 100644 (file)
--- a/route.c
+++ b/route.c
@@ -20,6 +20,8 @@
 #include "proxy.h"
 #include "action.h"
 #include "sr_module.h"
+#include "ip_addr.h"
+#include "resolve.h"
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
@@ -117,10 +119,9 @@ static int fix_actions(struct action* a)
                        case FORWARD_T:
                        case SEND_T:
                                        switch(t->p1_type){
-                                               case NUMBER_ST:
-                                               case IP_ST: /* for now ip_st==number_st*/
-                                                       tmp=strdup(inet_ntoa(
-                                                                               *(struct in_addr*)&t->p1.number));
+                                               case IP_ST: 
+                                                       tmp=strdup(ip_addr2a(
+                                                                               (struct ip_addr*)t->p1.data));
                                                        if (tmp==0){
                                                                LOG(L_CRIT, "ERROR: fix_actions:"
                                                                                "memory allocation failure\n");
@@ -234,7 +235,7 @@ error:
 
 
 /* eval_elem helping function, returns a op param */
-static int comp_ip(unsigned a, void* param, int op, int subtype)
+static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype)
 {
        struct hostent* he;
        char ** h;
@@ -243,22 +244,28 @@ static int comp_ip(unsigned a, void* param, int op, int subtype)
        ret=-1;
        switch(subtype){
                case NET_ST:
-                       ret=(a&((struct net*)param)->mask)==((struct net*)param)->ip;
+                       ret=matchnet(ip, (struct net*) param);
+                       /*ret=(a&((struct net*)param)->mask)==((struct net*)param)->ip;*/
                        break;
                case STRING_ST:
                case RE_ST:
                        /* 1: compare with ip2str*/
+               /* !!!??? review reminder ( resolve(name) & compare w/ all ips? */
+#if 0
                        ret=comp_str(inet_ntoa(*(struct in_addr*)&a), param, op,
                                                subtype);
                        if (ret==1) break;
+#endif
                        /* 2: (slow) rev dns the address
                         * and compare with all the aliases */
-                       he=gethostbyaddr((char*)&a, sizeof(a), AF_INET);
+                       he=rev_resolvehost(ip);
                        if (he==0){
-                               LOG(L_DBG, "comp_ip: could not rev_resolve %x\n", a);
+                               DBG( "comp_ip: could not rev_resolve ip address: ");
+                               print_ip(ip);
+                               DBG("\n");
                                ret=0;
                        }else{
-                               /*  compare with primayry host name */
+                               /*  compare with primary host name */
                                ret=comp_str(he->h_name, param, op, subtype);
                                /* compare with all the aliases */
                                for(h=he->h_aliases; (ret!=1) && (*h); h++){
@@ -303,10 +310,10 @@ static int eval_elem(struct expr* e, struct sip_msg* msg)
                                }
                                break;
                case SRCIP_O:
-                               ret=comp_ip(msg->src_ip, e->r.param, e->op, e->subtype);
+                               ret=comp_ip(&msg->src_ip, e->r.param, e->op, e->subtype);
                                break;
                case DSTIP_O:
-                               ret=comp_ip(msg->dst_ip, e->r.param, e->op, e->subtype);
+                               ret=comp_ip(&msg->dst_ip, e->r.param, e->op, e->subtype);
                                break;
                case NUMBER_O:
                                ret=!(!e->r.intval); /* !! to transform it in {0,1} */
index 61857b8..1a8e579 100644 (file)
@@ -14,6 +14,7 @@
 #include <string.h>
 
 #include "dprint.h"
+#include "ip_addr.h"
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
@@ -102,43 +103,6 @@ struct action* append_action(struct action* a, struct action* b)
 
 
 
-struct net* mk_net(unsigned long ip, unsigned long mask)
-{
-       struct net* n;
-
-       n=(struct net*)malloc(sizeof(struct net));
-       if (n==0) goto error;
-       n->ip=ip;
-       n->mask=mask;
-       return n;
-error:
-       LOG(L_CRIT, "ERROR: mk_net_mask: memory allocation failure\n");
-       return 0;
-}
-
-       
-       
-
-void print_ip(unsigned ip)
-{
-       DBG("%d.%d.%d.%d", ((unsigned char*)&ip)[0],
-                                                 ((unsigned char*)&ip)[1],
-                                                 ((unsigned char*)&ip)[2],
-                                                 ((unsigned char*)&ip)[3]);
-}
-
-
-void print_net(struct net* net)
-{
-       if (net==0){
-               LOG(L_WARN, "ERROR: print net: null pointer\n");
-               return;
-       }
-       print_ip(net->ip); DBG("/"); print_ip(net->mask);
-}
-
-
-
 void print_expr(struct expr* exp)
 {
        if (exp==0){
@@ -190,7 +154,7 @@ void print_expr(struct expr* exp)
                                        print_net((struct net*)exp->r.param);
                                        break;
                        case IP_ST:
-                                       print_ip(exp->r.intval);
+                                       print_ip((struct ip_addr*)exp->r.param);
                                        break;
                        case ACTIONS_ST:
                                        print_action((struct action*)exp->r.param);
@@ -295,7 +259,7 @@ void print_action(struct action* a)
                                        DBG("%d",t->p1.number);
                                        break;
                        case IP_ST:
-                                       print_ip(t->p1.number);
+                                       print_ip((struct ip_addr*)t->p1.data);
                                        break;
                        case EXPR_ST:
                                        print_expr((struct expr*)t->p1.data);
index 6b4faec..1c53a6b 100644 (file)
@@ -63,10 +63,6 @@ struct action{
 };
 
 
-struct net{
-       unsigned long ip;
-       unsigned long mask;
-};
 
 struct expr* mk_exp(int op, struct expr* left, struct expr* right);
 struct expr* mk_elem(int op, int subtype, int operand, void* param);
@@ -77,8 +73,6 @@ struct action* mk_action3(int type, int p1_type, int p2_type, int p3_type,
 struct action* append_action(struct action* a, struct action* b);
 
 
-struct net* mk_net(unsigned long ip, unsigned long mask);
-
 void print_action(struct action* a);
 void print_expr(struct expr* exp);
 
diff --git a/test/resolver.txt b/test/resolver.txt
new file mode 100644 (file)
index 0000000..2d95abe
--- /dev/null
@@ -0,0 +1,84 @@
+
+
+
+                                Linux          FreeBSD         Solaris         Cygwin
+gethostbyname          y                       y                       y                       y
+gethostbyname_r                n                       n                       y                       -
+gethostbyname2         y                       y                       y(*)            -
+getaddrinfo                    y                       y                       y                       -
+res_search (res_*)     y                       y                       y                       -
+
+Linux, Solaris, Cygwin:
+
+struct sockaddr_in{
+       sa_family_t     sin_family;
+       in_port_t       sin_port;
+       struct  in_addr sin_addr;
+       /* ...*/
+}; 
+
+FreeBSD:
+struct sockaddr_in {
+        u_char  sin_len;
+        u_char  sin_family;
+        u_short sin_port;
+        struct  in_addr sin_addr;
+        char    sin_zero[8];
+};
+
+
+Linux, Solaris, Cygwin:
+struct sockaddr_in6 {
+        sa_family_t     sin6_family;
+        in_port_t       sin6_port;
+        uint32_t        sin6_flowinfo;
+        struct in6_addr sin6_addr;
+               /*...*/
+};
+
+
+FreeBSD:
+struct sockaddr_in6 {
+        u_int8_t        sin6_len;       /* length of this struct(sa_family_t)*/
+        u_int8_t        sin6_family;    /* AF_INET6 (sa_family_t) */
+        u_int16_t       sin6_port;      /* Transport layer port # (in_port_t)*/
+        u_int32_t       sin6_flowinfo;  /* IP6 flow information */
+        struct in6_addr sin6_addr;      /* IP6 address */
+        u_int32_t       sin6_scope_id;  /* intface scope id */
+};
+
+
+
+                               sockaddr_in                                     sockaddr_in6
+Linux  <netinet/in.h> or <linux/in.h>  <netinet/in.h> or <linux/in6.h> (*)
+FreeBSD                        <netinet/in.h>                          <netinet6/in6.h>
+Solaris                        <netinet/in.h>                          <netinet/in.h>
+Cygwin <netinet/in.h> or <cywin/in.h>  <netinet/in.h> or <cygwin/in.h>
+
+(*) - on linux netinet/in.h -> from GNU libc, linux/in*.h from the kernel.
+
+
+
+
+struct sockaddr:
+
+Linux:
+(sa_family_t= unsigned short)
+
+struct sockaddr {
+        sa_family_t     sa_family;      /* address family, AF_xxx       */
+        char            sa_data[14];    /* 14 bytes of protocol address */
+};
+
+
+
+FreeBSD:
+
+(sa_family_t = u_char)
+
+struct sockaddr {
+        u_char          sa_len;         /* total length */
+        sa_family_t     sa_family;      /* address family */
+        char            sa_data[14];    /* actually longer; address value */
+};
+
index bd442dc..37a8e56 100644 (file)
 
 
 #include "udp_server.h"
+#include "globals.h"
 #include "config.h"
 #include "dprint.h"
 #include "receive.h"
 #include "mem/mem.h"
+#include "ip_addr.h"
 
 #ifdef DEBUG_DMALLOC
 #include <mem/dmalloc.h>
@@ -105,23 +107,30 @@ int probe_max_receive_buffer( int udp_sock )
        /* EoJKU */
 }
 
-int udp_init(unsigned long ip, unsigned short port)
+int udp_init(struct ip_addr* ip, unsigned short port)
 {
-       struct sockaddr_in* addr;
+       union sockaddr_union* addr;
        int optval;
 
 
-       addr=(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
+       addr=(union sockaddr_union*)malloc(sizeof(union sockaddr_union));
        if (addr==0){
                LOG(L_ERR, "ERROR: udp_init: out of memory\n");
                goto error;
        }
+       
+       if (init_su(addr, ip, htons(port)<0){
+               LOG(L_ERR, "ERROR: udp_init: could not init sockaddr_union\n");
+               goto error;
+       }
+       /*
        addr->sin_family=AF_INET;
        addr->sin_port=htons(port);
        addr->sin_addr.s_addr=ip;
+       */
 
        
-       udp_sock = socket(PF_INET, SOCK_DGRAM, 0);
+       udp_sock = socket(AF2PF(addr->s.sa_family), SOCK_DGRAM, 0);
        if (udp_sock==-1){
                LOG(L_ERR, "ERROR: udp_init: socket: %s\n", strerror(errno));
                goto error;
@@ -138,7 +147,7 @@ int udp_init(unsigned long ip, unsigned short port)
        if ( probe_max_receive_buffer(udp_sock)==-1) goto error;
        bind_address=ip;
 
-       if (bind(udp_sock, (struct sockaddr*) addr, sizeof(struct sockaddr))==-1){
+       if (bind(udp_sock,  &addr->s, sizeof(union sockaddr_union))==-1){
                LOG(L_ERR, "ERROR: udp_init: bind: %s\n", strerror(errno));
                goto error;
        }
@@ -162,11 +171,11 @@ int udp_rcv_loop()
        static char buf [BUF_SIZE+1];
 #endif
 
-       struct sockaddr_in* from;
+       union sockaddr_union* from;
        unsigned int fromlen;
 
 
-       from=(struct sockaddr_in*) malloc(sizeof(struct sockaddr_in));
+       from=(union sockaddr_union*) malloc(sizeof(union sockaddr_union));
        if (from==0){
                LOG(L_ERR, "ERROR: udp_rcv_loop: out of memory\n");
                goto error;
@@ -181,8 +190,8 @@ int udp_rcv_loop()
                        goto error;
                }
 #endif
-               fromlen=sizeof(struct sockaddr_in);
-               len=recvfrom(udp_sock, buf, BUF_SIZE, 0, (struct sockaddr*)from,
+               fromlen=sizeof(union sockaddr_union);
+               len=recvfrom(udp_sock, buf, BUF_SIZE, 0, &from->s,
                                                &fromlen);
                if (len==-1){
                        LOG(L_ERR, "ERROR: udp_rcv_loop:recvfrom:[%d] %s\n",
@@ -195,7 +204,7 @@ int udp_rcv_loop()
                buf[len+1]=0;
                
                /* receive_msg must free buf too!*/
-               receive_msg(buf, len, from->sin_addr.s_addr);
+               receive_msg(buf, len, from);
                
        /* skip: do other stuff */
                
@@ -213,56 +222,15 @@ error:
 
 
 /* which socket to use? main socket or new one? */
-int udp_send(char *buf, unsigned len, struct sockaddr*  to, unsigned tolen)
+int udp_send(char *buf, unsigned len, union sockaddr_union*  to,
+                               unsigned tolen)
 {
 
        int n;
 
-/*     struct sockaddr_in a2;*/
-#ifndef NO_DEBUG
-#define MAX_IP_LENGTH 18
-       char ip_txt[MAX_IP_LENGTH];
-       char *c;
-       struct sockaddr_in* a;
-       unsigned short p;
-
-       a=(struct sockaddr_in*) to;
-       memset(ip_txt, 0, MAX_IP_LENGTH);
-       c=inet_ntoa(a->sin_addr);
-       strncpy( ip_txt, c, MAX_IP_LENGTH - 1 );
-       p=ntohs(a->sin_port);
-
-       if (tolen < sizeof(struct sockaddr_in))
-               DBG("DEBUG: udp_send: tolen small\n");
-       if (a->sin_family && a->sin_family != AF_INET)
-               DBG("DEBUG: udp_send: to not INET\n");
-       if (a->sin_port == 0)
-               DBG("DEBUG: udp_send: no port\n");
-
-#ifdef EXTRA_DEBUG
-       if ( tolen < sizeof(struct sockaddr_in) ||
-       a->sin_family && a->sin_family != AF_INET || a->sin_port == 0 )
-               abort();
-       /* every message must be terminated by CRLF */
-       if (memcmp(buf+len-CRLF_LEN, CRLF, CRLF_LEN)!=0) {
-               LOG(L_CRIT, "ERROR: this is ugly -- we are sending a packet"
-                       " not terminated by CRLF\n");
-               abort();
-       }
-#endif
-
-       DBG("DEBUG: udp_send destination: IP=%s, port=%u;\n", ip_txt, p);
-#endif
-/*
-       memset(&a2, 0, sizeof(struct sockaddr_in));
-       a2.sin_family = a->sin_family;
-       a2.sin_port = a->sin_port;
-       a2.sin_addr.s_addr = a->sin_addr.s_addr;
-*/
 
 again:
-       n=sendto(udp_sock, buf, len, 0, to, tolen);
-/*     n=sendto(udp_sock, buf, len, 0, &a2, sizeof(struct sockaddr_in) );*/
+       n=sendto(udp_sock, buf, len, 0, &to->s, tolen);
        if (n==-1){
                LOG(L_ERR, "ERROR: udp_send: sendto(sock,%p,%d,0,%p,%d): %s(%d)\n",
                                buf,len,to,tolen,
@@ -272,9 +240,6 @@ again:
                        LOG(L_CRIT,"CRITICAL: invalid sendtoparameters\n"
                        "one possible reason is the server is bound to localhost and\n"
                        "attempts to send to the net\n");
-#                      ifdef EXTRA_DEBUG
-                       abort();
-#                      endif
                }
        }
        return n;
index 671694c..109b1a0 100644 (file)
@@ -7,14 +7,16 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include "ip_addr.h"
 
 #define MAX_RECV_BUFFER_SIZE   256*1024
 #define BUFFER_INCREMENT       2048
 
 extern int udp_sock;
 
-int udp_init(unsigned long ip, unsigned short port);
-int udp_send(char *buf, unsigned len, struct sockaddr*  to, unsigned tolen);
+int udp_init(struct ip_addr* ip, unsigned short port);
+int udp_send(char *buf, unsigned len, union sockaddr_union*  to,
+                               unsigned tolen);
 int udp_rcv_loop();