Ver código fonte

- ipv6 support (-DUSE_IPV6)
- changed all the sockaddr/ip addr structures
- added gethostbyname/addr wrappers (resolve.h)

Andrei Pelinescu-Onciul 23 anos atrás
pai
commit
4e2fdd790c
28 arquivos alterados com 891 adições e 328 exclusões
  1. 10 9
      Makefile.defs
  2. 18 21
      action.c
  3. 8 2
      cfg.lex
  4. 88 31
      cfg.y
  5. 4 1
      dprint.h
  6. 1 1
      flags.h
  7. 39 37
      forward.c
  8. 2 1
      forward.h
  9. 5 4
      globals.h
  10. 126 0
      ip_addr.c
  11. 336 0
      ip_addr.h
  12. 26 19
      main.c
  13. 3 0
      mem/shm_mem.c
  14. 26 68
      msg_translator.c
  15. 1 3
      parser/msg_parser.c
  16. 3 2
      parser/msg_parser.h
  17. 1 2
      parser/parse_via.c
  18. 11 7
      proxy.c
  19. 2 1
      proxy.h
  20. 5 3
      receive.c
  21. 3 1
      receive.h
  22. 42 0
      resolve.h
  23. 18 11
      route.c
  24. 3 39
      route_struct.c
  25. 0 6
      route_struct.h
  26. 84 0
      test/resolver.txt
  27. 22 57
      udp_server.c
  28. 4 2
      udp_server.h

+ 10 - 9
Makefile.defs

@@ -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
 

+ 18 - 21
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++;

+ 8 - 2
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; }
 

+ 88 - 31
cfg.y

@@ -13,12 +13,14 @@
 #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,

+ 4 - 1
dprint.h

@@ -8,7 +8,6 @@
 
 #include <syslog.h>
 
-#include "globals.h"
 
 #define L_ALERT -3
 #define L_CRIT  -2
@@ -18,6 +17,10 @@
 #define L_INFO   3
 #define L_DBG    4
 
+/* vars:*/
+
+extern int debug;
+extern int log_stderr;
 
 
 #define DPRINT_LEV	1

+ 1 - 1
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 )
 

+ 39 - 37
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;

+ 2 - 1
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

+ 5 - 4
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;

+ 126 - 0
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);
+}

+ 336 - 0
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

+ 26 - 19
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"
@@ -31,9 +32,10 @@
 #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

+ 3 - 0
mem/shm_mem.c

@@ -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> */

+ 26 - 68
msg_translator.c

@@ -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"
 
 
 
@@ -40,88 +43,35 @@
 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;

+ 1 - 3
parser/msg_parser.c

@@ -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;
 }
 

+ 3 - 2
parser/msg_parser.h

@@ -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 */

+ 1 - 2
parser/parse_via.c

@@ -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;

+ 11 - 7
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;
 

+ 2 - 1
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);
 
 

+ 5 - 3
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);

+ 3 - 1
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

+ 42 - 0
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

+ 18 - 11
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} */

+ 3 - 39
route_struct.c

@@ -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);

+ 0 - 6
route_struct.h

@@ -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);
 

+ 84 - 0
test/resolver.txt

@@ -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 */
+};
+

+ 22 - 57
udp_server.c

@@ -12,10 +12,12 @@
 
 
 #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;

+ 4 - 2
udp_server.h

@@ -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();