Index: apache13/README.v6
diff -c /dev/null apache13/README.v6:1.22
*** /dev/null	Tue Feb  8 12:32:04 2000
--- apache13/README.v6	Wed Jan 26 21:38:02 2000
***************
*** 0 ****
--- 1,160 ----
+ IPv6-ready apache 1.3.x
+ KAME Project
+ $Id: README.v6,v 1.22 2000/01/26 12:38:02 itojun Exp $
+ 
+ This patchkit enables apache 1.3.x to perform HTTP connection over IPv6.
+ Most of optional modules are left unchanged, i.e. it won't support IPv6,
+ and it may not compile.
+ 
+ Basically you can write IPv6 address where IPv4 address fits.
+ 
+ extra command-line argument:
+ 	-4	Assume IPv4 address on ambiguous directives
+ 	-6	Assume IPv6 address on ambiguous directives (default)
+ 
+ 	The above two can be used, for example, to disambiguate
+ 	"BindAddress *".
+ 
+ base commands:
+     Listen
+ 	Listen is expanded to take one or two arguments.
+ 		Listen port
+ 		Listen address:port
+ 		Listen address port
+ 	This is to let you specify "Listen :: 80", since "Listen :::80"
+ 	won't work.
+ 
+ mod_access:
+     deny from
+     allow from
+ 	"deny from" and "allow from" supports IPv6 addresses, under the
+ 	following forms:
+ 		{deny,allow} from v6addr
+ 		{deny,allow} from v6addr/v6mask
+ 		{deny,allow} from v6addr/prefixlen
+ 	Also, wildcard ("*") and string hostname matches IPv6 hosts as well.
+ 
+ mod_proxy:
+     ProxyRequests on
+ 	http/ftp proxying for both IPv4 and IPv6 is possible.
+ 	Access control functions (NoProxy) are not updated yet.
+ 
+ 	NOTE: for security reasons, we recommend you to filter out
+ 	outsider's access to your proxy, by directives like below:
+ 		<Directory proxy:*>
+ 		order deny,allow
+ 		deny from all
+ 		allow from 10.0.0.0/8
+ 		allow from 3ffe:9999:8888:7777::/64
+ 		</Directory>
+ 
+ virtual host:
+     NameVirtualHost
+ 	NameVirtualHost is expanded to take one more two arguments.
+ 		NameVirtualHost address
+ 		NameVirtualHost address:port
+ 		NameVirtualHost address port
+ 	This is to let you specify IPv6 address into address part.
+ 
+ 	Note that, if colon is found in the specified address string,
+ 	the code will to resolve the address in the following way:
+ 	1. try to resolve as address:port (most of IPv6 address fails)
+ 	2. if (1) is failed, try to resolve as address only
+ 	If there's ambiguity, i.e. 3ffe:0501::1:2, the address may not be
+ 	parsed as you expect (3ffe:0501::1 with port 2, or 3ffe:0501::1:2
+ 	with default port).  To get the right effect you are encouraged
+ 	to specify it without ambiguity.  In IPv6 case "address port"
+ 	(specify address and port separated by a space) is the safest way.
+ 
+     <VirtualHost host:port [host:port ...]>
+ 	If you would like to specify IPv6 numeric address in host part,
+ 	use bracketed format like below:
+ 		<VirtualHost [::1]:80>
+ 	Note: Now we DO NOT handle old non-bracketed format, 
+ 		<VirtualHost 0:0:0:0:0:0:0:1:80>
+ 	      so configuration file must be updated.
+ 	Note: The following is bad example to specify host ::1 port 80.
+ 	      This will treated as host ::1:80.
+ 		<VirtualHost ::1:80>
+ 
+ logresolve (src/support)
+ 	error statistics in nameserver cache code is omitted.
+ 
+ mod_unique_id
+ 	Originally mod_unique_id used IPv4 address as a seed for UNIQUE_ID,
+ 	and took IPv4 address registered onto DNS for the hostname (UNIX
+ 	hostname taken by gethostname(3)).  Therefore, this does not work
+ 	for IPv6-only hosts as they do not have IPv4 address for them.
+ 
+ 	Now, UNIQUE_ID can be generated using IPv6 address.  IPv6 address can
+ 	be used as the seed for UNIQUE_ID.
+ 	Because of this, UNIQUE_ID will be longer than normal apache.  This
+ 	may cause problem with some of the CGI scripts.
+ 	The preference of the addresses is based on the order returned
+ 	by getaddrinfo().  If your getaddrinfo() returns IPv4 address, IPv4
+ 	adderss will be used as a seed.
+ 	Note that some of IPv6 addresses are "scoped"; If you happened to use
+ 	link-local or site-local address as a seed, the UNIQUE_ID may not be
+ 	worldwide unique.
+ 
+ 	If longer UNIQUE_ID causes a problem, define SHORT_UNIQUE_ID in
+ 	mod_unique_id.c.  In this case, length of UNIQUE_ID will be kept the
+ 	same.  However, for IPv6 addresses mod_unique_id.c will use the last
+ 	32bit (not the whole 128bit) as the seed.  Therefore, there can be
+ 	collision in UNIQUE_ID.
+ 
+ 	The behavior should be improved in the near future; we welcome your
+ 	inputs.
+ 
+ Modules known to be incompatible with IPv6
+ 	(please report us)
+ 
+ configure
+ 	Configure has extra option, --enable-rule=INET6.  if the option
+ 	is specified, IPv6 code will be enabled.
+ 
+ This kit assumes that you have working(*) getaddrinfo() and getnameinfo()
+ library functions.  Even if you don't have one, don't panic.  We have
+ included last-resort version (which support IPv4 only) into the kit.
+ For more complete implementation you might want to check BIND 8.2.
+ (*) NOTE: we have noticed that some of IPv6 stack is shipped with broken
+ getaddrinfo().  In such cases, you should get and install BIND 8.2.
+ 
+ When compiling this kit onto IPv6, you may need to specify some additional
+ library paths or cpp defs (like -linet6 or -DINET6).
+ Now you don't have to specify --enable-rule=INET6.  The "configure" script
+ will give you some warnings if the IPv6 stack is not known to the 
+ "configure" script.  Currently, the following IPv6 stacks are supported:
+ - KAME IPv6 stack, http://www.kame.net/
+ 	use configure.v6 for convenience,
+ - Linux IPv6 stack, http://www.linux.org/
+ 	use configure.v6 for convenience.
+ - Solaris 7 IPv6 stack, http://www.sun.com/
+ 	use configure.v6 for convenience.
+ To disable IPv6 support, specify --disable-rule=INET6 to the "configure"
+ script.
+ 
+ CAVEAT: This patchkit may change some of apache module API, to avoid
+ IPv4-dependent structure member variable.  Please let us know if there's
+ any troubles as we know very little about the apache module API.
+ 
+ Acknowledgements
+ 	Thanks to all people submitted patches/fixes for this patch kit,
+ 	including:
+ 		"Chris P. Ross" <cross@eng.us.uu.net>
+ 
+ Author contacts
+ 	Jun-ichiro itojun Hagino, KAME project
+ 	 http://www.kame.net/
+ 	 mailto:core@kame.net
+ Linux Port
+ 	Arkadiusz Miskiewicz, Polish Linux Distribution project (IPv6)
+ 	 http://www.pld.org.pl/
+ 	 mailto:pld-list@pld.org.pl
+ 	Satoshi SHIDA and Hideaki YOSHIFUJI, Linux IPv6 Users Group JP
+ 	 http://www.v6.linux.or.jp/
+ 	NOTES:
+ 	- Linux users should use glibc 2.1.1 or later because struct
+ 	  sockaddr_storage is missing in older versions.
+ 	- Recently (tagged 19991013a and later), we have support for
+ 	  system not having struct sockaddr_storage.
Index: apache13/configure.v6
diff -c /dev/null apache13/configure.v6:1.8
*** /dev/null	Tue Feb  8 12:32:04 2000
--- apache13/configure.v6	Wed Jan 26 22:09:13 2000
***************
*** 0 ****
--- 1,3 ----
+ #! /bin/sh
+ 
+ ./configure --enable-rule=INET6 --enable-module=proxy $*
Index: apache13/conf/httpd.conf-dist
diff -c apache13/conf/httpd.conf-dist:1.1.1.6 apache13/conf/httpd.conf-dist:1.8
*** apache13/conf/httpd.conf-dist:1.1.1.6	Wed Jan 26 21:13:14 2000
--- apache13/conf/httpd.conf-dist	Wed Jan 26 21:38:04 2000
***************
*** 176,181 ****
--- 176,186 ----
  #Listen 3000
  #Listen 12.34.56.78:80
  
+ # Listen can take two arguments.
+ # (this is an extension for supporting IPv6 addresses)
+ #Listen :: 80
+ #Listen 0.0.0.0 80
+ 
  #
  # BindAddress: You can support virtual hosts with this option. This directive
  # is used to tell the server which IP address to listen to. It can either
Index: apache13/src/Configuration.tmpl
diff -c apache13/src/Configuration.tmpl:1.1.1.3 apache13/src/Configuration.tmpl:1.8
*** apache13/src/Configuration.tmpl:1.1.1.3	Tue Aug 24 13:20:13 1999
--- apache13/src/Configuration.tmpl	Wed Jan 26 21:38:05 2000
***************
*** 166,171 ****
--- 166,174 ----
  #  directory is present. This rule will always be interpreted as "no"
  #  if the directory is not present.
  #
+ # INET6:
+ #  IPv6 support.
+ #
  
  Rule SOCKS4=no
  Rule SOCKS5=no
***************
*** 173,178 ****
--- 176,182 ----
  Rule IRIXN32=yes
  Rule PARANOID=no
  Rule EXPAT=default
+ Rule INET6=no
  
  # DEV_RANDOM:
  #  Note: this rule is only used when compiling mod_auth_digest.
Index: apache13/src/Configure
diff -c apache13/src/Configure:1.1.1.6 apache13/src/Configure:1.10
*** apache13/src/Configure:1.1.1.6	Wed Jan 26 21:12:42 2000
--- apache13/src/Configure	Wed Jan 26 21:38:06 2000
***************
*** 232,237 ****
--- 232,238 ----
  RULE_EXPAT=`./helpers/CutRule EXPAT $file`
  RULE_SHARED_CORE=`./helpers/CutRule SHARED_CORE $file`
  RULE_SHARED_CHAIN=`./helpers/CutRule SHARED_CHAIN $file`
+ RULE_INET6=`./helpers/CutRule INET6 $file`
  
  ####################################################################
  ## Rule SHARED_CORE implies required DSO support
***************
*** 1552,1557 ****
--- 1553,1676 ----
      esac
  fi
  
+ # INET6 support.
+ if [ "$RULE_INET6" = "yes" ]; then
+     echo " + enabling INET6 support"
+     CFLAGS="$CFLAGS -DINET6"
+     CFLAGS="$CFLAGS -Dss_family=__ss_family -Dss_len=__ss_len"
+     IPV6_STACKTYPE="UNKNOWN"
+     for i in KAME Linux Solaris; do
+ 	case "$i" in
+ 	KAME)
+ 	    if [ -f /usr/include/netinet6/in6.h -a "x`egrep '__KAME__' /usr/include/netinet6/in6.h 2>/dev/null`" != "x" ]; then
+ 		IPV6_STACKTYPE=$i
+ 	    fi
+ 	    ;;
+ 	Linux)
+ 	    if [ /usr/include/netinet/ip6.h -a -d /usr/include/linux ]; then
+ 		IPV6_STACKTYPE=$i
+ 	    fi
+ 	    ;;
+ 	Solaris)
+ 	    SOL_VERSION=`(uname -v) 2>/dev/null` || SOL_VERSION="unknown"
+ 	    case "${PLAT}-${SOL_VERSION}" in
+ 		*-solaris2.27*-*IPv6*)
+ 		    if [ -f /etc/hostname -o -f /etc/hostname.[a-z]*[0-9] ]; then
+ 			IPV6_STACKTYPE="Solaris 7 (${SOL_VERSION})"
+ 		    fi
+ 		    ;;
+ 	    esac
+ 	    ;;
+ 	esac
+ 	if [ "$IPV6_STACKTYPE" != "UNKNOWN" ]; then
+ 	    break
+ 	fi
+     done
+     if [ "$IPV6_STACKTYPE" != "UNKNOWN" ]; then
+ 	echo " + You seem to be using $IPV6_STACKTYPE stack"
+ 	if ./helpers/TestCompile func getaddrinfo; then
+ 	    echo "   - Assuming you have working getaddrinfo in libc" 
+ 	else
+ 	    if [ -f /usr/local/v6/lib/libinet6.a -a "x`egrep '^EXTRA_L' Makefile.config | grep linet6`" = "x" ]; then
+ 		LIBS="$LIBS -L/usr/local/v6/lib -linet6"
+ 		echo "   - using getaddrinfo in libinet6" 
+ 	    elif [ -f /usr/local/lib/libinet6.a -a "x`egrep '^EXTRA_L' Makefile.config | grep linet6`" = "x" ]; then
+ 		LIBS="$LIBS -L/usr/local/lib -linet6"
+ 		echo "   - using getaddrinfo in libinet6"
+ 	    elif [ -f /usr/inet6/lib/libinet6.a -a "x`egrep '^EXTRA_L' Makefile.config | grep linet6`" = "x" ]; then
+ 		echo "   - using getaddrinfo in libinet6"
+ 	    else
+ 		echo "** WARNING: No getaddrinfo found, linkage may fail" 
+ 	    fi
+ 	fi
+     else
+ 	echo ""
+ 	echo "** WARNING: We have no explicit knowledge about the IPv6"
+ 	echo "** implementation on this host.  You may need to specify"
+ 	echo "** EXTRA_LIBS so that we can find getaddrinfo() and"
+ 	echo "** getnameinfo() library functions."
+ 	echo ""
+     fi
+     case $PLAT in
+ 	*-solaris2* )
+ 	    LIBS="$LIBS -lresolv"
+ 	    ;;
+     esac
+ else
+     CFLAGS="$CFLAGS -DNEED_GETADDRINFO -DNEED_GETNAMEINFO"
+     if [ -f /usr/include/netdb.h -a "x`egrep 'addrinfo' /usr/include/netdb.h`" = "x" ]; then
+ 	CFLAGS="$CFLAGS -DNEED_ADDRINFO"
+     fi
+ fi
+ 
+ echo '#include <sys/types.h>' >testfunc.c
+ echo '#include <sys/socket.h>' >>testfunc.c
+ echo 'int testfunc(){ struct sockaddr sa; int i = sa.sa_len; };' >>testfunc.c
+ rm -f testfunc.o
+ eval "${MAKE-make} -f Makefile.config testfunc.o >/dev/null 2>/dev/null"
+ if [ -f testfunc.o ]; then
+     echo " + you have sa_len in struct sockaddr."
+     CFLAGS="$CFLAGS -DHAVE_SOCKADDR_LEN"
+ else
+     echo " + you don't have sa_len in struct sockaddr."
+ fi
+ rm -f testfunc.c testfunc.o
+ 
+ echo '#include <sys/types.h>' >testfunc.c
+ echo '#include <sys/socket.h>' >>testfunc.c
+ echo 'struct sockaddr_storage sockaddr_storage;' >>testfunc.c
+ rm -f testfunc.o
+ eval "${MAKE-make} -f Makefile.config testfunc.o >/dev/null 2>/dev/null"
+ if [ -f testfunc.o ]; then
+     echo " + assuming you have struct sockaddr_storage"
+ else
+     CFLAGS="$CFLAGS -DNEED_SOCKADDR_STORAGE"
+     echo " + you need struct sockaddr_storage"
+ fi
+ rm -f testfunc.c testfunc.o
+ 
+ echo '#include <sys/types.h>' >testfunc.c
+ echo '#include <sys/socket.h>' >>testfunc.c
+ echo 'int testfunc(){ socklen_t t; }' >>testfunc.c
+ rm -f testfunc.o
+ eval "${MAKE-make} -f Makefile.config testfunc.o >/dev/null 2>/dev/null"
+ if [ ! -f testfunc.o ]; then
+     CFLAGS="$CFLAGS -Dsocklen_t=int"
+ fi
+ rm -f testfunc.c testfunc.o
+ 
+ echo '#include <sys/types.h>' >testfunc.c
+ echo '#include <sys/socket.h>' >>testfunc.c
+ echo 'struct sockaddr_in sin;' >>testfunc.c
+ echo 'int main(){ int i = sin.sin_len; }' >>testfunc.c
+ rm -f testfunc.o
+ eval "${MAKE-make} -f Makefile.config testfunc.o >/dev/null 2>/dev/null"
+ if [ -f testfunc.o ]; then
+     CFLAGS="$CFLAGS -DSIN_LEN"
+ fi
+ rm -f testfunc.c testfunc.o
+ 
+ 
  ####################################################################
  ## Find out what modules we want and try and configure things for them
  ## Module lines can look like this:
***************
*** 2064,2069 ****
--- 2183,2220 ----
  echo "#ifndef AP_LONGEST_LONG" >>$AP_CONFIG_AUTO_H
  echo "#define AP_LONGEST_LONG $AP_LONGEST_LONG" >>$AP_CONFIG_AUTO_H
  echo "#endif" >>$AP_CONFIG_AUTO_H
+ 
+ if [ x`./helpers/TestCompile -r sizeof 'uint32_t'` != x"" ]; then
+     echo "" >>$AP_CONFIG_AUTO_H
+     echo "/* determine: use uint32_t as 32bit unsigned int */" >>$AP_CONFIG_AUTO_H
+     echo "#ifndef ap_uint32_t" >>$AP_CONFIG_AUTO_H
+     echo "#define ap_uint32_t uint32_t" >>$AP_CONFIG_AUTO_H
+     echo "#endif" >>$AP_CONFIG_AUTO_H
+     echo "   - use uint32_t as 32bit unsigned int"
+ elif [ x`./helpers/TestCompile -r sizeof 'u_int32_t'` != x"" ]; then
+     echo "" >>$AP_CONFIG_AUTO_H
+     echo "/* determine: use u_int32_t as 32bit unsigned int */" >>$AP_CONFIG_AUTO_H
+     echo "#ifndef ap_uint32_t" >>$AP_CONFIG_AUTO_H
+     echo "#define ap_uint32_t u_int32_t" >>$AP_CONFIG_AUTO_H
+     echo "#endif" >>$AP_CONFIG_AUTO_H
+     echo "   - use u_int32_t as 32bit unsigned int"
+ elif [ x`./helpers/TestCompile -r sizeof 'unsigned int'` = x"4" ]; then
+     echo "" >>$AP_CONFIG_AUTO_H
+     echo "/* determine: use unsigned int as 32bit unsigned int */" >>$AP_CONFIG_AUTO_H
+     echo "#ifndef ap_uint32_t" >>$AP_CONFIG_AUTO_H
+     echo "#define ap_uint32_t unsigned int" >>$AP_CONFIG_AUTO_H
+     echo "#endif" >>$AP_CONFIG_AUTO_H
+     echo "   - use unsigned int as 32bit unsigned int"
+ elif [ x`./helpers/TestCompile -r sizeof 'unsigned long int'` = x"4" ]; then
+     echo "" >>$AP_CONFIG_AUTO_H
+     echo "/* determine: use unsigned long int as 32bit unsigned int */" >>$AP_CONFIG_AUTO_H
+     echo "#ifndef uint32_t" >>$AP_CONFIG_AUTO_H
+     echo "#define uint32_t unsigned long int" >>$AP_CONFIG_AUTO_H
+     echo "#endif" >>$AP_CONFIG_AUTO_H
+     echo "   - use unsigned long int as 32bit unsigned int"
+ else
+     echo "  - Warning: cannot determine what type should we use as 32bit unsigned int"
+ fi
  
  ####################################################################
  ## More building ap_config_auto.h
Index: apache13/src/ap/ap_snprintf.c
diff -c apache13/src/ap/ap_snprintf.c:1.1.1.4 apache13/src/ap/ap_snprintf.c:1.8
*** apache13/src/ap/ap_snprintf.c:1.1.1.4	Wed Jan 26 21:12:44 2000
--- apache13/src/ap/ap_snprintf.c	Wed Jan 26 21:38:07 2000
***************
*** 69,74 ****
--- 69,75 ----
  #include <string.h>
  #include <stdlib.h>
  #include <math.h>
+ #include "sa_len.h"
  
  typedef enum {
      NO = 0, YES = 1
***************
*** 497,502 ****
--- 498,537 ----
  
  
  
+ #ifdef INET6
+ static char *conv_sockaddr(struct sockaddr *sa, char *buf_end, int *len)
+ {
+     char *p = buf_end;
+     char hostnamebuf[MAXHOSTNAMELEN];
+     char portnamebuf[MAXHOSTNAMELEN];
+     char *q;
+     int salen;
+ 
+ #ifndef SIN6_LEN
+     salen = SA_LEN(sa);
+ #else
+     salen = sa->sa_len;
+ #endif
+     if (getnameinfo(sa, salen, hostnamebuf, sizeof(hostnamebuf),
+ 	    portnamebuf, sizeof(portnamebuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
+ 	strcpy(hostnamebuf, "???");
+ 	strcpy(portnamebuf, "???");
+     }
+     q = portnamebuf + strlen(portnamebuf);
+     while (portnamebuf < q)
+ 	*--p = *--q;
+     *--p = ':';
+     q = hostnamebuf + strlen(hostnamebuf);
+     while (hostnamebuf < q)
+ 	*--p = *--q;
+ 
+     *len = buf_end - p;
+     return (p);
+ }
+ #endif /*INET6*/
+ 
+ 
+ 
  /*
   * Convert a floating point number to a string formats 'f', 'e' or 'E'.
   * The result is placed in buf, and len denotes the length of the string
***************
*** 1032,1037 ****
--- 1067,1073 ----
  		    /* print a struct sockaddr_in as a.b.c.d:port */
  		case 'I':
  		    {
+ #ifndef INET6
  			struct sockaddr_in *si;
  
  			si = va_arg(ap, struct sockaddr_in *);
***************
*** 1040,1045 ****
--- 1076,1091 ----
  			    if (adjust_precision && precision < s_len)
  				s_len = precision;
  			}
+ #else
+ 			struct sockaddr *sa;
+ 
+ 			sa = va_arg(ap, struct sockaddr *);
+ 			if (sa != NULL) {
+ 			    s = conv_sockaddr(sa, &num_buf[NUM_BUF_SIZE], &s_len);
+ 			    if (adjust_precision && precision < s_len)
+ 				s_len = precision;
+ 			}
+ #endif
  			else {
  			    s = S_NULL;
  			    s_len = S_NULL_LEN;
Index: apache13/src/include/ap.h
diff -c apache13/src/include/ap.h:1.1.1.4 apache13/src/include/ap.h:1.6
*** apache13/src/include/ap.h:1.1.1.4	Wed Jan 26 21:12:49 2000
--- apache13/src/include/ap.h	Wed Jan 26 21:38:07 2000
***************
*** 87,93 ****
   * with some extensions.  The extensions are:
   *
   * %pA	takes a struct in_addr *, and prints it as a.b.c.d
!  * %pI	takes a struct sockaddr_in * and prints it as a.b.c.d:port
   * %pp  takes a void * and outputs it in hex
   *
   * The %p hacks are to force gcc's printf warning code to skip
--- 87,94 ----
   * with some extensions.  The extensions are:
   *
   * %pA	takes a struct in_addr *, and prints it as a.b.c.d
!  * %pI	takes a struct sockaddr * and prints it as a.b.c.d:port, or
!  *	ipv6-numeric-addr:port
   * %pp  takes a void * and outputs it in hex
   *
   * The %p hacks are to force gcc's printf warning code to skip
Index: apache13/src/include/ap_config.h
diff -c apache13/src/include/ap_config.h:1.1.1.6 apache13/src/include/ap_config.h:1.12
*** apache13/src/include/ap_config.h:1.1.1.6	Wed Jan 26 21:12:49 2000
--- apache13/src/include/ap_config.h	Wed Jan 26 21:38:08 2000
***************
*** 387,392 ****
--- 387,396 ----
  #endif
  #ifndef S_IWOTH
  #define S_IWOTH 000002
+ #ifndef rlim_t
+ typedef int rlim_t;
+ #endif
+ typedef u_long n_long;
  #endif
  
  #define STDIN_FILENO  0
***************
*** 1434,1439 ****
--- 1438,1507 ----
  
  #ifndef ap_wait_t
  #define ap_wait_t int
+ #endif
+ 
+ #ifndef INET6
+ #define sockaddr_storage	sockaddr
+ #define ss_family		sa_family
+ #define ss_len			sa_len
+ #else
+ #include "sockaddr_storage.h"	/* sshida@st.rim.or.jp */
+ #endif
+ 
+ #ifndef INET6_ADDRSTRLEN
+ #define INET6_ADDRSTRLEN	46
+ #endif
+ #ifndef INET_ADDRSTRLEN
+ #define INET_ADDRSTRLEN		16
+ #endif
+ #ifndef NI_MAXHOST
+ #define NI_MAXHOST		1025
+ #endif
+ #ifndef NI_MAXSERV
+ #define	NI_MAXSERV		32
+ #endif
+ 
+ #if defined(NEED_GETADDRINFO) || defined(NEED_GETNAMEINFO)
+ /*
+  * minimal definitions for fake getaddrinfo()/getnameinfo().
+  */
+ #ifndef EAI_NODATA
+ #define EAI_NODATA	1
+ #define EAI_MEMORY	2
+ #endif
+ 
+ #ifndef AI_PASSIVE
+ #define AI_PASSIVE	1
+ #define AI_CANONNAME	2
+ #define AI_NUMERICHOST	4
+ #define NI_NUMERICHOST	8
+ #define NI_NAMEREQD	16
+ #define NI_NUMERICSERV	32
+ #endif
+ #endif
+ 
+ #ifdef NEED_GETADDRINFO
+ #ifdef NEED_ADDRINFO
+ struct addrinfo {
+ 	int	ai_flags;	/* AI_PASSIVE, AI_CANONNAME */
+ 	int	ai_family;	/* PF_xxx */
+ 	int	ai_socktype;	/* SOCK_xxx */
+ 	int	ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ 	size_t	ai_addrlen;	/* length of ai_addr */
+ 	char	*ai_canonname;	/* canonical name for hostname */
+ 	struct sockaddr *ai_addr;	/* binary address */
+ 	struct addrinfo *ai_next;	/* next structure in linked list */
+ };
+ #endif
+ extern char *gai_strerror(int ecode);
+ extern void freeaddrinfo(struct addrinfo *ai);
+ extern int getaddrinfo(const char *hostname, const char *servname,
+ 	const struct addrinfo *hints, struct addrinfo **res);
+ #endif
+ #ifdef NEED_GETNAMEINFO
+ extern int getnameinfo(const struct sockaddr *sa, size_t salen,
+ 	char *host, size_t hostlen, char *serv, size_t servlen,
+ 	int flag);
  #endif
  
  #ifdef __cplusplus
Index: apache13/src/include/http_conf_globals.h
diff -c apache13/src/include/http_conf_globals.h:1.1.1.4 apache13/src/include/http_conf_globals.h:1.6
*** apache13/src/include/http_conf_globals.h:1.1.1.4	Wed Jan 26 21:12:50 2000
--- apache13/src/include/http_conf_globals.h	Wed Jan 26 21:38:08 2000
***************
*** 81,87 ****
  extern int ap_max_requests_per_child;
  extern int ap_threads_per_child;
  extern int ap_excess_requests_per_child;
! extern struct in_addr ap_bind_address;
  extern listen_rec *ap_listeners;
  extern int ap_daemons_to_start;
  extern int ap_daemons_min_free;
--- 81,88 ----
  extern int ap_max_requests_per_child;
  extern int ap_threads_per_child;
  extern int ap_excess_requests_per_child;
! extern struct sockaddr_storage ap_bind_address;
! extern int ap_default_family;
  extern listen_rec *ap_listeners;
  extern int ap_daemons_to_start;
  extern int ap_daemons_min_free;
Index: apache13/src/include/http_vhost.h
diff -c apache13/src/include/http_vhost.h:1.1.1.2 apache13/src/include/http_vhost.h:1.2
*** apache13/src/include/http_vhost.h:1.1.1.2	Tue Jan 12 13:34:08 1999
--- apache13/src/include/http_vhost.h	Wed Jan 27 13:58:19 1999
***************
*** 72,78 ****
  const char *ap_parse_vhost_addrs(pool *p, const char *hostname, server_rec *s);
  
  /* handle NameVirtualHost directive */
! const char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg);
  
  /* given an ip address only, give our best guess as to what vhost it is */
  void ap_update_vhost_given_ip(conn_rec *conn);
--- 72,78 ----
  const char *ap_parse_vhost_addrs(pool *p, const char *hostname, server_rec *s);
  
  /* handle NameVirtualHost directive */
! const char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *h, char *p);
  
  /* given an ip address only, give our best guess as to what vhost it is */
  void ap_update_vhost_given_ip(conn_rec *conn);
Index: apache13/src/include/httpd.h
diff -c apache13/src/include/httpd.h:1.1.1.6 apache13/src/include/httpd.h:1.8
*** apache13/src/include/httpd.h:1.1.1.6	Wed Jan 26 21:12:51 2000
--- apache13/src/include/httpd.h	Wed Jan 26 21:38:08 2000
***************
*** 833,840 ****
  
      /* Who is the client? */
  
!     struct sockaddr_in local_addr;	/* local address */
!     struct sockaddr_in remote_addr;	/* remote address */
      char *remote_ip;		/* Client's IP address */
      char *remote_host;		/* Client's DNS name, if known.
  				 * NULL if DNS hasn't been checked,
--- 833,840 ----
  
      /* Who is the client? */
  
!     struct sockaddr_storage local_addr;	/* local address */
!     struct sockaddr_storage remote_addr; /* remote address */
      char *remote_ip;		/* Client's IP address */
      char *remote_host;		/* Client's DNS name, if known.
  				 * NULL if DNS hasn't been checked,
***************
*** 873,880 ****
  typedef struct server_addr_rec server_addr_rec;
  struct server_addr_rec {
      server_addr_rec *next;
!     struct in_addr host_addr;	/* The bound address, for this server */
!     unsigned short host_port;	/* The bound port, for this server */
      char *virthost;		/* The name given in <VirtualHost> */
  };
  
--- 873,880 ----
  typedef struct server_addr_rec server_addr_rec;
  struct server_addr_rec {
      server_addr_rec *next;
!     struct sockaddr_storage host_addr;	/* The bound address, for this server */
!     unsigned short host_port;	/* The bound port, for this server XXX */
      char *virthost;		/* The name given in <VirtualHost> */
  };
  
***************
*** 938,944 ****
  /* These are more like real hosts than virtual hosts */
  struct listen_rec {
      listen_rec *next;
!     struct sockaddr_in local_addr;	/* local IP address and port */
      int fd;
      int used;			/* Only used during restart */        
  /* more stuff here, like which protocol is bound to the port */
--- 938,944 ----
  /* These are more like real hosts than virtual hosts */
  struct listen_rec {
      listen_rec *next;
!     struct sockaddr_storage local_addr;	/* local IP address and port */
      int fd;
      int used;			/* Only used during restart */        
  /* more stuff here, like which protocol is bound to the port */
***************
*** 1091,1097 ****
  #endif /* _OSD_POSIX */
  
  char *ap_get_local_host(pool *);
! unsigned long ap_get_virthost_addr(char *hostname, unsigned short *port);
  
  extern API_VAR_EXPORT time_t ap_restart_time;
  
--- 1091,1097 ----
  #endif /* _OSD_POSIX */
  
  char *ap_get_local_host(pool *);
! struct sockaddr *ap_get_virthost_addr(char *hostname, unsigned short *port);
  
  extern API_VAR_EXPORT time_t ap_restart_time;
  
Index: apache13/src/include/sa_len.h
diff -c /dev/null apache13/src/include/sa_len.h:1.3
*** /dev/null	Tue Feb  8 12:32:10 2000
--- apache13/src/include/sa_len.h	Wed Jan 26 21:38:08 2000
***************
*** 0 ****
--- 1,41 ----
+ /* sa_len.h : tiny version of SA_LEN (written by <yoshfuji@ecei.tohoku.ac.jp>) */
+  
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <sys/un.h>
+ 
+ #ifndef HAVE_SOCKADDR_LEN
+ #ifndef SA_LEN
+ #define SA_LEN(s_)	ap_sa_len((s_)->sa_family)
+ 
+ static ap_inline socklen_t ap_sa_len (sa_family_t af)
+ {
+     switch (af){
+ #if defined(AF_INET)
+     case AF_INET:
+ 	return (sizeof(struct sockaddr_in));
+ #endif /* AF_INET */
+ #if defined(AF_INET6)
+     case AF_INET6:
+ 	return (sizeof(struct sockaddr_in6));
+ #endif
+ #ifdef AF_LOCAL
+     case AF_LOCAL:
+ #endif /* AF_LOCAL */
+ #if defined(AF_UNIX) && (AF_UNIX != AF_LOCAL)
+     case AF_UNIX:
+ #endif /* AF_UNIX */
+ #if defined(AF_FILE) && (AF_FILE != AF_LOCAL || AF_FILE != AF_UNIX)
+     case AF_FILE:
+ #endif /* AF_FILE */
+ #if defined(AF_LOCAL) || defined(AF_UNIX) || defined(AF_FILE)
+ 	return (sizeof(struct sockaddr_un));
+ #endif /* defined(AF_LOCAL) || defined(AF_UNIX) || defined(AF_FILE) */
+     default:
+ 	return 0;
+     }
+     return 0;
+ }
+ #endif /* SA_LEN */
+ #endif /* HAVE_SOCKADDR_LEN */
Index: apache13/src/include/sockaddr_storage.h
diff -c /dev/null apache13/src/include/sockaddr_storage.h:1.2
*** /dev/null	Tue Feb  8 12:32:11 2000
--- apache13/src/include/sockaddr_storage.h	Wed Jan 26 21:38:08 2000
***************
*** 0 ****
--- 1,53 ----
+ /*
+ struct sockaddr_storage
+ 
+    RFC2553 proposes struct sockaddr_storage.
+    This is a placeholder for all sockaddr-variant structures. This is
+    implemented like follows:
+ 
+    You should use this structure to hold any of sockaddr-variant
+    structures.
+ */
+ #ifdef NEED_SOCKADDR_STORAGE
+ 
+ struct sockaddr_storage {
+ #ifdef HAVE_SOCKADDR_LEN
+ 	u_char ss_len;
+ 	u_char ss_family;
+ #else
+ 	u_short ss_family;
+ #endif
+ 	u_char __padding[128 - 2];
+ };
+ 
+ /*
+ union sockunion
+ 
+    Alternatively, you may want to implement sockunion.h, with the
+    following content:
+ 
+    NOTE: For better portability, struct sockaddr_storage should be used.
+    union sockunion is okay, but is not really portable enough.
+ */
+ union sockunion {
+ 	struct sockinet {
+ #ifdef HAVE_SOCKADDR_LEN
+ 		u_char si_len;
+ 		u_char si_family;
+ #else
+ 		u_short si_family;
+ #endif
+ 		u_short si_port;
+ 	} su_si;
+ 	struct sockaddr_in  su_sin;
+ #ifdef INET6
+ 	struct sockaddr_in6 su_sin6;
+ #endif
+ };
+ #ifdef HAVE_SOCKADDR_LEN
+ #define su_len		su_si.si_len
+ #endif
+ #define su_family	su_si.si_family
+ #define su_port		su_si.si_port
+ 
+ #endif /* NEED_SOCKADDR_STORAGE */
Index: apache13/src/main/getaddrinfo.c
diff -c /dev/null apache13/src/main/getaddrinfo.c:1.4
*** /dev/null	Tue Feb  8 12:32:11 2000
--- apache13/src/main/getaddrinfo.c	Wed Jan 26 21:38:10 2000
***************
*** 0 ****
--- 1,150 ----
+ /*
+  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. Neither the name of the project nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ /*
+  * fake library for ssh v6 enabler patch
+  *
+  * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
+  * These funtions are defined in rfc2133.
+  *
+  * But these functions are not implemented correctly. The minimum subset
+  * is implemented for ssh use only. For exapmle, this routine assumes
+  * that ai_family is AF_INET. Don't use it for another purpose.
+  * 
+  * In the case not using 'configure --enable-ipv6', this getaddrinfo.c
+  * will be used if you have broken getaddrinfo or no getaddrinfo.
+  */
+ 
+ #if 0
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include "gai.h"
+ #endif
+ 
+ static struct addrinfo *
+ malloc_ai(port, addr)
+ int port;
+ u_long addr;
+ {
+   struct addrinfo *ai;
+ 
+   if (ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) +
+ 				     sizeof(struct sockaddr_in))) {
+     memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
+     ai->ai_addr = (struct sockaddr *)(ai + 1);
+ #if defined(HAVE_SOCKADDR_LEN)
+     ai->ai_addr->sa_len = 
+ #endif
+       ai->ai_addrlen = sizeof(struct sockaddr_in);
+     ai->ai_addr->sa_family = ai->ai_family = AF_INET;
+     ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
+     ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
+     return ai;
+   } else {
+     return NULL;
+   }
+ }
+ 
+ char *
+ gai_strerror(ecode)
+ int ecode;
+ {
+   switch (ecode) {
+   case EAI_NODATA:
+     return "no address associated with hostname.";
+   case EAI_MEMORY:
+     return "memory allocation failure.";
+   default:
+     return "unknown error.";
+   }
+ }    
+ 
+ void
+ freeaddrinfo(ai)
+ struct addrinfo *ai;
+ {
+   struct addrinfo *next;
+   
+   do {
+     next = ai->ai_next;
+     free(ai);
+   } while (ai = next);
+ }
+ 
+ int
+ getaddrinfo(hostname, servname, hints, res)
+ const char *hostname, *servname;
+ const struct addrinfo *hints;
+ struct addrinfo **res;
+ {
+   struct addrinfo *cur, *prev = NULL;
+   struct hostent *hp;
+   int i, port;
+   
+   if (servname)
+     port = htons(atoi(servname));
+   else
+     port = 0;
+   if (hints && hints->ai_flags & AI_PASSIVE)
+     if (*res = malloc_ai(port, htonl(0x00000000)))
+       return 0;
+     else
+       return EAI_MEMORY;
+   if (!hostname)
+     if (*res = malloc_ai(port, htonl(0x7f000001)))
+       return 0;
+     else
+       return EAI_MEMORY;
+   if (inet_addr(hostname) != -1)
+     if (*res = malloc_ai(port, inet_addr(hostname)))
+       return 0;
+     else
+       return EAI_MEMORY;
+   if ((hp = gethostbyname(hostname)) &&
+       hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
+     for (i = 0; hp->h_addr_list[i]; i++)
+       if (cur = malloc_ai(port,
+ 			  ((struct in_addr *)hp->h_addr_list[i])->s_addr)) {
+ 	if (prev)
+ 	  prev->ai_next = cur;
+ 	else
+ 	  *res = cur;
+ 	prev = cur;
+       } else {
+ 	if (*res)
+ 	  freeaddrinfo(*res);
+ 	return EAI_MEMORY;
+       }
+     return 0;
+   }
+   return EAI_NODATA;
+ }
Index: apache13/src/main/getnameinfo.c
diff -c /dev/null apache13/src/main/getnameinfo.c:1.2
*** /dev/null	Tue Feb  8 12:32:12 2000
--- apache13/src/main/getnameinfo.c	Thu Apr 15 20:32:53 1999
***************
*** 0 ****
--- 1,95 ----
+ /*
+  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+  * All rights reserved.
+  * 
+  * Redistribution and use in source and binary forms, with or without
+  * modification, are permitted provided that the following conditions
+  * are met:
+  * 1. Redistributions of source code must retain the above copyright
+  *    notice, this list of conditions and the following disclaimer.
+  * 2. Redistributions in binary form must reproduce the above copyright
+  *    notice, this list of conditions and the following disclaimer in the
+  *    documentation and/or other materials provided with the distribution.
+  * 3. Neither the name of the project nor the names of its contributors
+  *    may be used to endorse or promote products derived from this software
+  *    without specific prior written permission.
+  * 
+  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+  * SUCH DAMAGE.
+  */
+ /*
+  * fake library for ssh v6 enabler patch
+  *
+  * This file includes getnameinfo().
+  * These funtions are defined in rfc2133.
+  *
+  * But these functions are not implemented correctly. The minimum subset
+  * is implemented for ssh use only. For exapmle, this routine assumes
+  * that ai_family is AF_INET. Don't use it for another purpose.
+  * 
+  * In the case not using 'configure --enable-ipv6', this getnameinfo.c
+  * will be used if you have broken getnameinfo or no getnameinfo.
+  */
+ 
+ #if 0
+ #include <stdlib.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <netdb.h>
+ #include <string.h>
+ #include "gai.h"
+ #endif
+ 
+ int
+ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
+ const struct sockaddr *sa;
+ size_t salen;
+ char *host;
+ size_t hostlen;
+ char *serv;
+ size_t servlen;
+ int flags;
+ {
+   struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+   struct hostent *hp;
+   char tmpserv[16];
+   
+   if (serv) {
+     sprintf(tmpserv, "%d", ntohs(sin->sin_port));
+     if (strlen(tmpserv) > servlen)
+       return EAI_MEMORY;
+     else
+       strcpy(serv, tmpserv);
+   }
+   if (host)
+     if (flags & NI_NUMERICHOST)
+       if (strlen(inet_ntoa(sin->sin_addr)) > hostlen)
+ 	return EAI_MEMORY;
+       else {
+ 	strcpy(host, inet_ntoa(sin->sin_addr));
+ 	return 0;
+       }
+     else
+       if (hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr),
+ 			     AF_INET))
+ 	if (strlen(hp->h_name) > hostlen)
+ 	  return EAI_MEMORY;
+ 	else {
+ 	  strcpy(host, hp->h_name);
+ 	  return 0;
+ 	}
+       else
+ 	return EAI_NODATA;
+   return 0;
+ }
Index: apache13/src/main/http_config.c
diff -c apache13/src/main/http_config.c:1.1.1.6 apache13/src/main/http_config.c:1.10
*** apache13/src/main/http_config.c:1.1.1.6	Wed Jan 26 21:12:53 2000
--- apache13/src/main/http_config.c	Wed Jan 26 21:38:10 2000
***************
*** 1404,1410 ****
      ap_scoreboard_fname = DEFAULT_SCOREBOARD;
      ap_lock_fname = DEFAULT_LOCKFILE;
      ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
-     ap_bind_address.s_addr = htonl(INADDR_ANY);
      ap_listeners = NULL;
      ap_listenbacklog = DEFAULT_LISTENBACKLOG;
      ap_extended_status = 0;
--- 1404,1409 ----
***************
*** 1437,1443 ****
      s->next = NULL;
      s->addrs = ap_pcalloc(p, sizeof(server_addr_rec));
      /* NOT virtual host; don't match any real network interface */
!     s->addrs->host_addr.s_addr = htonl(INADDR_ANY);
      s->addrs->host_port = 0;	/* matches any port */
      s->addrs->virthost = "";	/* must be non-NULL */
      s->names = s->wild_names = NULL;
--- 1436,1446 ----
      s->next = NULL;
      s->addrs = ap_pcalloc(p, sizeof(server_addr_rec));
      /* NOT virtual host; don't match any real network interface */
!     memset(&s->addrs->host_addr, 0, sizeof(s->addrs->host_addr));
!     s->addrs->host_addr.ss_family = ap_default_family; /* XXX: needed ? */
! #ifdef HAVE_SOCKADDR_LEN
!     s->addrs->host_addr.ss_len = sizeof(s->addrs->host_addr); /* XXX: needed ? */
! #endif
      s->addrs->host_port = 0;	/* matches any port */
      s->addrs->virthost = "";	/* must be non-NULL */
      s->names = s->wild_names = NULL;
***************
*** 1452,1470 ****
  static void default_listeners(pool *p, server_rec *s)
  {
      listen_rec *new;
  
      if (ap_listeners != NULL) {
  	return;
      }
      /* allocate a default listener */
      new = ap_pcalloc(p, sizeof(listen_rec));
!     new->local_addr.sin_family = AF_INET;
!     new->local_addr.sin_addr = ap_bind_address;
!     new->local_addr.sin_port = htons(s->port ? s->port : DEFAULT_HTTP_PORT);
      new->fd = -1;
      new->used = 0;
      new->next = NULL;
      ap_listeners = new;
  }
  
  
--- 1455,1487 ----
  static void default_listeners(pool *p, server_rec *s)
  {
      listen_rec *new;
+     struct addrinfo hints, *res0, *res;
+     int gai;
+     char servbuf[NI_MAXSERV];
  
      if (ap_listeners != NULL) {
  	return;
      }
+     snprintf(servbuf, sizeof(servbuf), "%d", s->port ? s->port : DEFAULT_HTTP_PORT);
+     memset (&hints, 0, sizeof(hints));
+     hints.ai_family = ap_default_family;
+     hints.ai_socktype = SOCK_STREAM;
+     hints.ai_flags = AI_PASSIVE;
+     gai = getaddrinfo(NULL, servbuf, &hints, &res0);
+     if (gai){
+ 	fprintf(stderr, "default_listeners(): getaddrinfo(PASSIVE) for family %u: %s\n",
+ 		gai_strerror(gai), ap_default_family);
+ 	exit (1);
+     }
      /* allocate a default listener */
      new = ap_pcalloc(p, sizeof(listen_rec));
!     memcpy(&new->local_addr, res0->ai_addr, res0->ai_addrlen);
      new->fd = -1;
      new->used = 0;
      new->next = NULL;
      ap_listeners = new;
+ 
+     freeaddrinfo(res0);
  }
  
  
Index: apache13/src/main/http_core.c
diff -c apache13/src/main/http_core.c:1.1.1.6 apache13/src/main/http_core.c:1.20
*** apache13/src/main/http_core.c:1.1.1.6	Wed Jan 26 21:12:53 2000
--- apache13/src/main/http_core.c	Wed Jan 26 21:38:11 2000
***************
*** 69,74 ****
--- 69,75 ----
  #include "util_md5.h"
  #include "scoreboard.h"
  #include "fnmatch.h"
+ #include "sa_len.h"
  
  #ifdef USE_MMAP_FILES
  #include <sys/mman.h>
***************
*** 546,552 ****
  /* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
  static ap_inline void do_double_reverse (conn_rec *conn)
  {
!     struct hostent *hptr;
  
      if (conn->double_reverse) {
  	/* already done */
--- 547,555 ----
  /* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
  static ap_inline void do_double_reverse (conn_rec *conn)
  {
!     struct addrinfo hints, *res, *res0;
!     char hostbuf1[128], hostbuf2[128]; /* INET6_ADDRSTRLEN(=46) is enough */
!     int ok = 0;
  
      if (conn->double_reverse) {
  	/* already done */
***************
*** 557,584 ****
  	conn->double_reverse = -1;
  	return;
      }
!     hptr = gethostbyname(conn->remote_host);
!     if (hptr) {
! 	char **haddr;
! 
! 	for (haddr = hptr->h_addr_list; *haddr; haddr++) {
! 	    if (((struct in_addr *)(*haddr))->s_addr
! 		== conn->remote_addr.sin_addr.s_addr) {
! 		conn->double_reverse = 1;
! 		return;
! 	    }
  	}
      }
!     conn->double_reverse = -1;
  }
  
  API_EXPORT(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
  					    int type)
  {
-     struct in_addr *iaddr;
-     struct hostent *hptr;
      int hostname_lookups;
      int old_stat = SERVER_DEAD;	/* we shouldn't ever be in this state */
  
      /* If we haven't checked the host name, and we want to */
      if (dir_config) {
--- 560,610 ----
  	conn->double_reverse = -1;
  	return;
      }
!     memset(&hints, 0, sizeof(hints));
!     hints.ai_family = PF_UNSPEC;
!     hints.ai_socktype = SOCK_STREAM;
!     if (getaddrinfo(conn->remote_host, NULL, &hints, &res0)) {
! 	conn->double_reverse = -1;
! 	return;
!     }
!     for (res = res0; res; res = res->ai_next) {
! 	if (res->ai_addr->sa_family != conn->remote_addr.ss_family ||
! 	    !(res->ai_family == AF_INET 
! #ifdef INET6
! 	      || res->ai_family == AF_INET6
! #endif
! 	      )
! 	    )
! 	    continue;
! #ifndef HAVE_SOCKADDR_LEN
! 	if (res->ai_addrlen != SA_LEN((struct sockaddr *)&conn->remote_addr))
! #else
! 	if (res->ai_addr->sa_len != conn->remote_addr.ss_len)
! #endif
! 	    continue;
! 	if (getnameinfo(res->ai_addr, res->ai_addrlen,
!             hostbuf1, sizeof(hostbuf1), NULL, 0,
!             NI_NUMERICHOST))
! 	    continue;
! 	if (getnameinfo(((struct sockaddr *)&conn->remote_addr), res->ai_addrlen,
!             hostbuf2, sizeof(hostbuf2), NULL, 0,
!             NI_NUMERICHOST))
! 	    continue;
! 	if (strcmp(hostbuf1, hostbuf2) == 0){
! 	    ok = 1;
! 	    break;
  	}
      }
!     conn->double_reverse = ok ? 1 : -1;
!     freeaddrinfo(res0);
  }
  
  API_EXPORT(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
  					    int type)
  {
      int hostname_lookups;
      int old_stat = SERVER_DEAD;	/* we shouldn't ever be in this state */
+     char hostnamebuf[MAXHOSTNAMELEN];
  
      /* If we haven't checked the host name, and we want to */
      if (dir_config) {
***************
*** 600,609 ****
  	    || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
  	old_stat = ap_update_child_status(conn->child_num, SERVER_BUSY_DNS,
  					  (request_rec*)NULL);
! 	iaddr = &(conn->remote_addr.sin_addr);
! 	hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
! 	if (hptr != NULL) {
! 	    conn->remote_host = ap_pstrdup(conn->pool, (void *)hptr->h_name);
  	    ap_str_tolower(conn->remote_host);
  	   
  	    if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
--- 626,639 ----
  	    || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
  	old_stat = ap_update_child_status(conn->child_num, SERVER_BUSY_DNS,
  					  (request_rec*)NULL);
! 	if (!getnameinfo((struct sockaddr *)&conn->remote_addr,
! #ifndef SIN6_LEN
! 		SA_LEN((struct sockaddr *)&conn->remote_addr),
! #else
! 		conn->remote_addr.ss_len,
! #endif
! 		hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0)) {
! 	    conn->remote_host = ap_pstrdup(conn->pool, (void *)hostnamebuf);
  	    ap_str_tolower(conn->remote_host);
  	   
  	    if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
***************
*** 684,689 ****
--- 714,720 ----
  {
      conn_rec *conn = r->connection;
      core_dir_config *d;
+     char hbuf[MAXHOSTNAMELEN];
  
      d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
  						&core_module);
***************
*** 693,715 ****
      }
      if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
          if (conn->local_host == NULL) {
- 	    struct in_addr *iaddr;
- 	    struct hostent *hptr;
              int old_stat;
  	    old_stat = ap_update_child_status(conn->child_num,
  					      SERVER_BUSY_DNS, r);
! 	    iaddr = &(conn->local_addr.sin_addr);
! 	    hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr),
! 				 AF_INET);
! 	    if (hptr != NULL) {
! 	        conn->local_host = ap_pstrdup(conn->pool,
! 					      (void *)hptr->h_name);
! 		ap_str_tolower(conn->local_host);
! 	    }
! 	    else {
! 	        conn->local_host = ap_pstrdup(conn->pool,
! 					      r->server->server_hostname);
  	    }
  	    (void) ap_update_child_status(conn->child_num, old_stat, r);
  	}
  	return conn->local_host;
--- 724,745 ----
      }
      if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
          if (conn->local_host == NULL) {
              int old_stat;
  	    old_stat = ap_update_child_status(conn->child_num,
  					      SERVER_BUSY_DNS, r);
! 	    if (getnameinfo((struct sockaddr *)&conn->local_addr,
! #ifndef SIN6_LEN
! 		    SA_LEN((struct sockaddr *)&conn->local_addr),
! #else
! 		    conn->local_addr.ss_len,
! #endif
! 		    hbuf, sizeof(hbuf), NULL, 0, 0) == 0) {
! 		conn->local_host = ap_pstrdup(conn->pool, hbuf);
! 	    } else {
! 		conn->local_host = ap_pstrdup(conn->pool,
! 		    r->server->server_hostname);
  	    }
+ 	    ap_str_tolower(conn->local_host);
  	    (void) ap_update_child_status(conn->child_num, old_stat, r);
  	}
  	return conn->local_host;
***************
*** 728,738 ****
  
      if (d->use_canonical_name == USE_CANONICAL_NAME_OFF
  	|| d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
!         return r->hostname ? ntohs(r->connection->local_addr.sin_port)
! 			   : port;
!     }
!     /* default */
!     return port;
  }
  
  API_EXPORT(char *) ap_construct_url(pool *p, const char *uri,
--- 758,770 ----
  
      if (d->use_canonical_name == USE_CANONICAL_NAME_OFF
  	|| d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
!         return r->hostname
! 	    ?  ntohs(((struct sockaddr_in *)&r->connection->local_addr)->sin_port)
! 	    : port;
!     }
!     return r->hostname
! 	? ntohs(((struct sockaddr_in *)&r->connection->local_addr)->sin_port)
! 	: port;
  }
  
  API_EXPORT(char *) ap_construct_url(pool *p, const char *uri,
***************
*** 2383,2394 ****
  
  static const char *set_bind_address(cmd_parms *cmd, void *dummy, char *arg) 
  {
      const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
      if (err != NULL) {
          return err;
      }
  
!     ap_bind_address.s_addr = ap_get_virthost_addr(arg, NULL);
      return NULL;
  }
  
--- 2415,2439 ----
  
  static const char *set_bind_address(cmd_parms *cmd, void *dummy, char *arg) 
  {
+     struct addrinfo hints, *res;
+     struct sockaddr *sa;
+     size_t sa_len;
+     int error;
      const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
      if (err != NULL) {
          return err;
      }
+ 
+     if (strcmp(arg, "*") == 0)
+       arg = NULL;
  
!     sa = ap_get_virthost_addr(arg, NULL);
! #ifdef HAVE_SOCKADDR_LEN
!     sa_len = sa->sa_len;
! #else
!     sa_len = SA_LEN(sa);
! #endif
!     memcpy(&ap_bind_address, &sa, sa_len);
      return NULL;
  }
  
***************
*** 2405,2448 ****
  }
  #endif
  
! static const char *set_listener(cmd_parms *cmd, void *dummy, char *ips)
  {
      listen_rec *new;
!     char *ports;
!     unsigned short port;
      
      const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
      if (err != NULL) {
          return err;
      }
  
!     ports = strchr(ips, ':');
!     if (ports != NULL) {
! 	if (ports == ips) {
! 	    return "Missing IP address";
! 	}
! 	else if (ports[1] == '\0') {
! 	    return "Address must end in :<port-number>";
  	}
! 	*(ports++) = '\0';
!     }
!     else {
! 	ports = ips;
      }
  
!     new=ap_pcalloc(cmd->pool, sizeof(listen_rec));
!     new->local_addr.sin_family = AF_INET;
!     if (ports == ips) { /* no address */
! 	new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
!     }
!     else {
! 	new->local_addr.sin_addr.s_addr = ap_get_virthost_addr(ips, NULL);
!     }
!     port = atoi(ports);
!     if (!port) {
! 	return "Port must be numeric";
      }
!     new->local_addr.sin_port = htons(port);
      new->fd = -1;
      new->used = 0;
      new->next = ap_listeners;
--- 2450,2519 ----
  }
  #endif
  
! static const char *set_listener(cmd_parms *cmd, void *dummy, char *h, char *p)
  {
      listen_rec *new;
!     char *host, *port;
!     struct addrinfo hints, *res;
!     int error;
      
      const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
      if (err != NULL) {
          return err;
      }
  
!     host = port = NULL;
!     if (!p) {
! 	port = strrchr(h, ':');
! 	if (port != NULL) {
! 	    if (port == h) {
! 		return "Missing IP address";
! 	    }
! 	    else if (port[1] == '\0') {
! 		return "Address must end in :<port-number>";
! 	    }
! 	    *(port++) = '\0';
! 	    if (*h)
! 		host = h;
! 	} else {
! 	    host = NULL;
! 	    port = h;
  	}
!     } else {
! 	host = h;
! 	port = p;
      }
  
!     if (host && strcmp(host, "*") == 0)
! 	host = NULL;
!     
!     new = ap_pcalloc(cmd->pool, sizeof(listen_rec));
! 
!     memset(&hints, 0, sizeof(hints));
!     hints.ai_family = host ? PF_UNSPEC : ap_default_family;
!     hints.ai_flags = AI_PASSIVE;
!     hints.ai_socktype = SOCK_STREAM;
!     error = getaddrinfo(host, port, &hints, &res);
!     if (error || !res) {
! 	fprintf(stderr, "could not resolve ");
! 	if (host)
! 	    fprintf(stderr, "host \"%s\" ", host);
! 	if (port)
! 	    fprintf(stderr, "port \"%s\" ", port);
! 	fprintf(stderr, "--- %s\n", gai_strerror(error));
! 	exit(1);
!     }
!     if (res->ai_next) {
!         if (host)
! 	    fprintf(stderr, "host \"%s\" ", host);
! 	if (port)
! 	    fprintf(stderr, "port \"%s\" ", port);
! 	fprintf(stderr, "resolved to multiple addresses, ambiguous.\n");
! 	exit(1);
      }
! 
!     memcpy(&new->local_addr, res->ai_addr, res->ai_addrlen);
! 
      new->fd = -1;
      new->used = 0;
      new->next = ap_listeners;
***************
*** 2900,2906 ****
  { "ThreadStackSize", set_threadstacksize, NULL, RSRC_CONF, TAKE1,
    "Stack size each created thread will use."},
  #endif
! { "Listen", set_listener, NULL, RSRC_CONF, TAKE1,
    "A port number or a numeric IP address and a port number"},
  { "SendBufferSize", set_send_buffer_size, NULL, RSRC_CONF, TAKE1,
    "Send buffer size in bytes"},
--- 2971,2977 ----
  { "ThreadStackSize", set_threadstacksize, NULL, RSRC_CONF, TAKE1,
    "Stack size each created thread will use."},
  #endif
! { "Listen", set_listener, NULL, RSRC_CONF, TAKE12,
    "A port number or a numeric IP address and a port number"},
  { "SendBufferSize", set_send_buffer_size, NULL, RSRC_CONF, TAKE1,
    "Send buffer size in bytes"},
***************
*** 2921,2927 ****
    "Name of the config file to be included" },
  { "LogLevel", set_loglevel, NULL, RSRC_CONF, TAKE1,
    "Level of verbosity in error logging" },
! { "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE1,
    "A numeric IP address:port, or the name of a host" },
  #ifdef _OSD_POSIX
  { "BS2000Account", set_bs2000_account, NULL, RSRC_CONF, TAKE1,
--- 2992,2998 ----
    "Name of the config file to be included" },
  { "LogLevel", set_loglevel, NULL, RSRC_CONF, TAKE1,
    "Level of verbosity in error logging" },
! { "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE12,
    "A numeric IP address:port, or the name of a host" },
  #ifdef _OSD_POSIX
  { "BS2000Account", set_bs2000_account, NULL, RSRC_CONF, TAKE1,
Index: apache13/src/main/http_main.c
diff -c apache13/src/main/http_main.c:1.1.1.6 apache13/src/main/http_main.c:1.15
*** apache13/src/main/http_main.c:1.1.1.6	Wed Jan 26 21:12:53 2000
--- apache13/src/main/http_main.c	Wed Jan 26 21:38:11 2000
***************
*** 123,128 ****
--- 123,130 ----
  #include <bstring.h>		/* for IRIX, FD_SET calls bzero() */
  #endif
  
+ #include "sa_len.h"
+ 
  #ifdef MULTITHREAD
  /* special debug stuff -- PCS */
  
***************
*** 249,261 ****
  char *ap_scoreboard_fname=NULL;
  char *ap_lock_fname;
  char *ap_server_argv0=NULL;
! struct in_addr ap_bind_address;
  int ap_daemons_to_start=0;
  int ap_daemons_min_free=0;
  int ap_daemons_max_free=0;
  int ap_daemons_limit=0;
  time_t ap_restart_time=0;
! int ap_suexec_enabled = 0;
  int ap_listenbacklog;
  int ap_dump_settings = 0;
  API_VAR_EXPORT int ap_extended_status = 0;
--- 251,268 ----
  char *ap_scoreboard_fname=NULL;
  char *ap_lock_fname;
  char *ap_server_argv0=NULL;
! #ifdef INET6
! int ap_default_family = AF_INET6;
! #else
! int ap_default_family = AF_INET;
! #endif
! struct sockaddr_storage ap_bind_address;
  int ap_daemons_to_start=0;
  int ap_daemons_min_free=0;
  int ap_daemons_max_free=0;
  int ap_daemons_limit=0;
  time_t ap_restart_time=0;
! int ap_suexec_enabled=0;
  int ap_listenbacklog;
  int ap_dump_settings = 0;
  API_VAR_EXPORT int ap_extended_status = 0;
***************
*** 1048,1054 ****
      fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin);
  #endif
      fprintf(stderr, "       %s [-C \"directive\"] [-c \"directive\"]\n", pad);
!     fprintf(stderr, "       %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]\n", pad);
  #ifdef WIN32
      fprintf(stderr, "       %s [-n service] [-k signal] [-i] [-u]\n", pad);
  #endif
--- 1055,1065 ----
      fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin);
  #endif
      fprintf(stderr, "       %s [-C \"directive\"] [-c \"directive\"]\n", pad);
!     fprintf(stderr, "       %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]"
! #ifdef INET6
! 			" [-46]"
! #endif
! 			"\n", pad);
  #ifdef WIN32
      fprintf(stderr, "       %s [-n service] [-k signal] [-i] [-u]\n", pad);
  #endif
***************
*** 1069,1074 ****
--- 1080,1089 ----
      fprintf(stderr, "  -S               : show parsed settings (currently only vhost settings)\n");
      fprintf(stderr, "  -t               : run syntax check for config files (with docroot check)\n");
      fprintf(stderr, "  -T               : run syntax check for config files (without docroot check)\n");
+ #ifdef INET6
+     fprintf(stderr, "  -4               : assume IPv4 on parsing configuration file\n");
+     fprintf(stderr, "  -6               : assume IPv6 on parsing configuration file\n");
+ #endif
  #ifdef WIN32
      fprintf(stderr, "  -n name          : set service name and use its ServerConfigFile\n");
      fprintf(stderr, "  -k shutdown      : tell running Apache to shutdown\n");
***************
*** 3184,3194 ****
  
  
  static conn_rec *new_connection(pool *p, server_rec *server, BUFF *inout,
! 			     const struct sockaddr_in *remaddr,
! 			     const struct sockaddr_in *saddr,
  			     int child_num)
  {
      conn_rec *conn = (conn_rec *) ap_pcalloc(p, sizeof(conn_rec));
  
      /* Got a connection structure, so initialize what fields we can
       * (the rest are zeroed out by pcalloc).
--- 3199,3211 ----
  
  
  static conn_rec *new_connection(pool *p, server_rec *server, BUFF *inout,
! 			     const struct sockaddr *remaddr,
! 			     const struct sockaddr *saddr,
  			     int child_num)
  {
      conn_rec *conn = (conn_rec *) ap_pcalloc(p, sizeof(conn_rec));
+     char hostnamebuf[MAXHOSTNAMELEN];
+     size_t addr_len;
  
      /* Got a connection structure, so initialize what fields we can
       * (the rest are zeroed out by pcalloc).
***************
*** 3197,3213 ****
      conn->child_num = child_num;
  
      conn->pool = p;
!     conn->local_addr = *saddr;
!     conn->local_ip = ap_pstrdup(conn->pool,
! 				inet_ntoa(conn->local_addr.sin_addr));
      conn->server = server; /* just a guess for now */
      ap_update_vhost_given_ip(conn);
      conn->base_server = conn->server;
      conn->client = inout;
  
!     conn->remote_addr = *remaddr;
!     conn->remote_ip = ap_pstrdup(conn->pool,
! 			      inet_ntoa(conn->remote_addr.sin_addr));
  
      return conn;
  }
--- 3214,3242 ----
      conn->child_num = child_num;
  
      conn->pool = p;
! #ifndef SIN6_LEN
!     addr_len = SA_LEN(saddr);
! #else
!     addr_len = saddr->sa_len;
! #endif
!     memcpy(&conn->local_addr, saddr, addr_len);
!     getnameinfo((struct sockaddr *)&conn->local_addr, addr_len,
! 	hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
!     conn->local_ip = ap_pstrdup(conn->pool, hostnamebuf);
      conn->server = server; /* just a guess for now */
      ap_update_vhost_given_ip(conn);
      conn->base_server = conn->server;
      conn->client = inout;
  
! #ifndef SIN6_LEN
!     addr_len = SA_LEN(remaddr);
! #else
!     addr_len = remaddr->sa_len;
! #endif
!     memcpy(&conn->remote_addr, remaddr, addr_len);
!     getnameinfo((struct sockaddr *)&conn->remote_addr, addr_len,
! 	hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
!     conn->remote_ip = ap_pstrdup(conn->pool, hostnamebuf);
  
      return conn;
  }
***************
*** 3240,3260 ****
  #define sock_disable_nagle(s)	/* NOOP */
  #endif
  
! static int make_sock(pool *p, const struct sockaddr_in *server)
  {
      int s;
      int one = 1;
!     char addr[512];
  
!     if (server->sin_addr.s_addr != htonl(INADDR_ANY))
! 	ap_snprintf(addr, sizeof(addr), "address %s port %d",
! 		inet_ntoa(server->sin_addr), ntohs(server->sin_port));
!     else
! 	ap_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port));
  
      /* note that because we're about to slack we don't use psocket */
      ap_block_alarms();
!     if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
  	    ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
  		    "make_sock: failed to get a socket for %s", addr);
  
--- 3269,3315 ----
  #define sock_disable_nagle(s)	/* NOOP */
  #endif
  
! static int make_sock(pool *p, const struct sockaddr *server)
  {
      int s;
      int one = 1;
!     char addr[INET6_ADDRSTRLEN + 128];
!     char a0[INET6_ADDRSTRLEN];
!     char p0[NI_MAXSERV];
! #ifdef MPE
!     int privport = 0;
! #endif
  
!     switch(server->sa_family){
!     case AF_INET:
! #ifdef INET6
!     case AF_INET6:
! #endif
!       break;
!     default:
!       ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
!                    "make_sock: unsupported address family %u", 
! 		   server->sa_family);
!       ap_unblock_alarms();
!       exit(1);
!     }
!     
!     getnameinfo(server,
! #ifndef SIN6_LEN
! 		SA_LEN(server),
! #else
! 		server->sa_len,
! #endif
! 		a0, sizeof(a0), p0, sizeof(p0), NI_NUMERICHOST | NI_NUMERICSERV);
!     ap_snprintf(addr, sizeof(addr), "address %s port %s", a0, p0);
! #ifdef MPE
!     if (atoi(p0) < 1024)
!       privport++;
! #endif
  
      /* note that because we're about to slack we don't use psocket */
      ap_block_alarms();
!     if ((s = socket(server->sa_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
  	    ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
  		    "make_sock: failed to get a socket for %s", addr);
  
***************
*** 3357,3371 ****
  
  #ifdef MPE
  /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
!     if (ntohs(server->sin_port) < 1024)
  	GETPRIVMODE();
  #endif
! 
!     if (bind(s, (struct sockaddr *) server, sizeof(struct sockaddr_in)) == -1) {
  	ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
  	    "make_sock: could not bind to %s", addr);
  #ifdef MPE
! 	if (ntohs(server->sin_port) < 1024)
  	    GETUSERMODE();
  #endif
  
--- 3412,3430 ----
  
  #ifdef MPE
  /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
!     if (privport)
  	GETPRIVMODE();
  #endif
! #ifndef SIN6_LEN
!     if (bind(s, server, SA_LEN(server)) == -1)
! #else
!     if (bind(s, server, server->sa_len) == -1)
! #endif
!     {
  	ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
  	    "make_sock: could not bind to %s", addr);
  #ifdef MPE
! 	if (privport)
  	    GETUSERMODE();
  #endif
  
***************
*** 3378,3384 ****
  	exit(1);
      }
  #ifdef MPE
!     if (ntohs(server->sin_port) < 1024)
  	GETUSERMODE();
  #endif
  
--- 3437,3443 ----
  	exit(1);
      }
  #ifdef MPE
!     if (privport)
  	GETUSERMODE();
  #endif
  
***************
*** 3505,3511 ****
      for (;;) {
  	fd = find_listener(lr);
  	if (fd < 0) {
!         fd = make_sock(p, &lr->local_addr);
  	}
  	else {
  	    ap_note_cleanups_for_socket(p, fd);
--- 3564,3570 ----
      for (;;) {
  	fd = find_listener(lr);
  	if (fd < 0) {
! 	    fd = make_sock(p, (struct sockaddr *)&lr->local_addr);
  	}
  	else {
  	    ap_note_cleanups_for_socket(p, fd);
***************
*** 3791,3798 ****
  static void child_main(int child_num_arg)
  {
      NET_SIZE_T clen;
!     struct sockaddr sa_server;
!     struct sockaddr sa_client;
      listen_rec *lr;
  
      /* All of initialization is a critical section, we don't care if we're
--- 3850,3857 ----
  static void child_main(int child_num_arg)
  {
      NET_SIZE_T clen;
!     struct sockaddr_storage sa_server;
!     struct sockaddr_storage sa_client;
      listen_rec *lr;
  
      /* All of initialization is a critical section, we don't care if we're
***************
*** 3959,3965 ****
  	    usr1_just_die = 0;
  	    for (;;) {
  		clen = sizeof(sa_client);
! 		csd = ap_accept(sd, &sa_client, &clen);
  		if (csd >= 0 || errno != EINTR)
  		    break;
  		if (deferred_die) {
--- 4018,4024 ----
  	    usr1_just_die = 0;
  	    for (;;) {
  		clen = sizeof(sa_client);
! 		csd = ap_accept(sd, (struct sockaddr *)&sa_client, &clen);
  		if (csd >= 0 || errno != EINTR)
  		    break;
  		if (deferred_die) {
***************
*** 4109,4115 ****
  	 */
  
  	clen = sizeof(sa_server);
! 	if (getsockname(csd, &sa_server, &clen) < 0) {
  	    ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, "getsockname");
  	    continue;
  	}
--- 4168,4174 ----
  	 */
  
  	clen = sizeof(sa_server);
! 	if (getsockname(csd, (struct sockaddr *)&sa_server, &clen) < 0) {
  	    ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, "getsockname");
  	    continue;
  	}
***************
*** 4154,4161 ****
  	ap_bpushfd(conn_io, csd, dupped_csd);
  
  	current_conn = new_connection(ptrans, server_conf, conn_io,
! 				          (struct sockaddr_in *) &sa_client,
! 				          (struct sockaddr_in *) &sa_server,
  				          my_child_num);
  
  	/*
--- 4213,4220 ----
  	ap_bpushfd(conn_io, csd, dupped_csd);
  
  	current_conn = new_connection(ptrans, server_conf, conn_io,
! 				          (struct sockaddr *)&sa_client,
! 				          (struct sockaddr *)&sa_server,
  				          my_child_num);
  
  	/*
***************
*** 4290,4301 ****
  
  #ifdef _OSD_POSIX
      /* BS2000 requires a "special" version of fork() before a setuid() call */
!     if ((pid = os_fork(ap_user_name)) == -1) {
  #elif defined(TPF)
!     if ((pid = os_fork(s, slot)) == -1) {
  #else
!     if ((pid = fork()) == -1) {
  #endif
  	ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new process");
  
  	/* fork didn't succeed. Fix the scoreboard or else
--- 4349,4361 ----
  
  #ifdef _OSD_POSIX
      /* BS2000 requires a "special" version of fork() before a setuid() call */
!     if ((pid = os_fork(ap_user_name)) == -1)
  #elif defined(TPF)
!     if ((pid = os_fork(s, slot)) == -1)
  #else
!     if ((pid = fork()) == -1)
  #endif
+     {
  	ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new process");
  
  	/* fork didn't succeed. Fix the scoreboard or else
***************
*** 4869,4875 ****
      ap_setup_prelinked_modules();
  
      while ((c = getopt(argc, argv,
! 				    "D:C:c:xXd:f:vVlLR:StTh"
  #ifdef DEBUG_SIGSTOP
  				    "Z:"
  #endif
--- 4929,4938 ----
      ap_setup_prelinked_modules();
  
      while ((c = getopt(argc, argv,
! 				    "D:C:c:xXd:f:vVlLR:StTh4"
! #ifdef INET6
! 				    "6"
! #endif
  #ifdef DEBUG_SIGSTOP
  				    "Z:"
  #endif
***************
*** 4944,4951 ****
  	    ap_configtestonly = 1;
  	    ap_docrootcheck = 0;
  	    break;
! 	case 'h':
! 	    usage(argv[0]);
  	case '?':
  	    usage(argv[0]);
  	}
--- 5007,5020 ----
  	    ap_configtestonly = 1;
  	    ap_docrootcheck = 0;
  	    break;
! 	case '4':
! 	    ap_default_family = AF_INET;
! 	    break;
! #ifdef INET6
! 	case '6':
! 	    ap_default_family = AF_INET6;
! 	    break;
! #endif
  	case '?':
  	    usage(argv[0]);
  	}
***************
*** 5003,5011 ****
      else {
  	conn_rec *conn;
  	request_rec *r;
- 	struct sockaddr sa_server, sa_client;
  	BUFF *cio;
  	NET_SIZE_T l;
  
  	ap_set_version();
  	/* Yes this is called twice. */
--- 5072,5081 ----
      else {
  	conn_rec *conn;
  	request_rec *r;
  	BUFF *cio;
+ 	struct sockaddr_storage sa_server, sa_client;
  	NET_SIZE_T l;
+ 	char servbuf[NI_MAXSERV];
  
  	ap_set_version();
  	/* Yes this is called twice. */
***************
*** 5059,5083 ****
  #endif
  
  	l = sizeof(sa_client);
! 	if ((getpeername(sock_in, &sa_client, &l)) < 0) {
  /* get peername will fail if the input isn't a socket */
  	    perror("getpeername");
  	    memset(&sa_client, '\0', sizeof(sa_client));
  	}
  
  	l = sizeof(sa_server);
! 	if (getsockname(sock_in, &sa_server, &l) < 0) {
  	    perror("getsockname");
  	    fprintf(stderr, "Error getting local address\n");
  	    exit(1);
  	}
! 	server_conf->port = ntohs(((struct sockaddr_in *) &sa_server)->sin_port);
  	cio = ap_bcreate(ptrans, B_RDWR | B_SOCKET);
          cio->fd = sock_out;
          cio->fd_in = sock_in;
  	conn = new_connection(ptrans, server_conf, cio,
! 			          (struct sockaddr_in *) &sa_client,
! 			          (struct sockaddr_in *) &sa_server, -1);
  
  	while ((r = ap_read_request(conn)) != NULL) {
  
--- 5129,5160 ----
  #endif
  
  	l = sizeof(sa_client);
! 	if ((getpeername(sock_in, (struct sockaddr *)&sa_client, &l)) < 0) {
  /* get peername will fail if the input isn't a socket */
  	    perror("getpeername");
  	    memset(&sa_client, '\0', sizeof(sa_client));
  	}
  
  	l = sizeof(sa_server);
! 	if (getsockname(sock_in, (struct sockaddr *)&sa_server, &l) < 0) {
  	    perror("getsockname");
  	    fprintf(stderr, "Error getting local address\n");
  	    exit(1);
  	}
! 	if (getnameinfo(((struct sockaddr *)&sa_server), l,
! 			NULL, 0, servbuf, sizeof(servbuf), 
! 			NI_NUMERICSERV)){
! 	    fprintf(stderr, "getnameinfo(): family=%d\n", sa_server.ss_family);
! 	    exit(1);
! 	}
! 	servbuf[sizeof(servbuf)-1] = '\0';
! 	server_conf->port = atoi(servbuf);
  	cio = ap_bcreate(ptrans, B_RDWR | B_SOCKET);
          cio->fd = sock_out;
          cio->fd_in = sock_in;
  	conn = new_connection(ptrans, server_conf, cio,
! 			          (struct sockaddr *)&sa_client,
! 			          (struct sockaddr *)&sa_server, -1);
  
  	while ((r = ap_read_request(conn)) != NULL) {
  
***************
*** 6969,6975 ****
       * but only handle the -L option 
       */
      llp_dir = SHARED_CORE_DIR;
!     while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLR:SZ:tTh")) != -1) {
  	switch (c) {
  	case 'D':
  	case 'C':
--- 7046,7056 ----
       * but only handle the -L option 
       */
      llp_dir = SHARED_CORE_DIR;
!     while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLR:SZ:tTh4"
! #ifdef INET6
! 		"6"
! #endif
! 		)) != -1) {
  	switch (c) {
  	case 'D':
  	case 'C':
***************
*** 6986,6991 ****
--- 7067,7076 ----
  	case 't':
  	case 'T':
  	case 'h':
+ 	case '4':
+ #ifdef INET6
+ 	case '6':
+ #endif
  	case '?':
  	    break;
  	case 'R':
Index: apache13/src/main/http_vhost.c
diff -c apache13/src/main/http_vhost.c:1.1.1.3 apache13/src/main/http_vhost.c:1.18
*** apache13/src/main/http_vhost.c:1.1.1.3	Wed Jan 26 21:12:54 2000
--- apache13/src/main/http_vhost.c	Tue Feb  8 12:08:10 2000
***************
*** 67,72 ****
--- 67,73 ----
  #include "http_log.h"
  #include "http_vhost.h"
  #include "http_protocol.h"
+ #include "sa_len.h"
  
  /*
   * After all the definitions there's an explanation of how it's all put
***************
*** 164,241 ****
   * *paddr is the variable used to keep track of **paddr between calls
   * port is the default port to assume
   */
! static const char *get_addresses(pool *p, char *w, server_addr_rec ***paddr,
! 			    unsigned port)
  {
!     struct hostent *hep;
!     unsigned long my_addr;
      server_addr_rec *sar;
!     char *t;
!     int i, is_an_ip_addr;
  
!     if (*w == 0)
  	return NULL;
  
!     t = strchr(w, ':');
!     if (t) {
! 	if (strcmp(t + 1, "*") == 0) {
! 	    port = 0;
  	}
! 	else if ((i = atoi(t + 1))) {
! 	    port = i;
  	}
  	else {
! 	    return ":port must be numeric";
  	}
! 	*t = 0;
      }
  
!     is_an_ip_addr = 0;
!     if (strcmp(w, "*") == 0) {
! 	my_addr = htonl(INADDR_ANY);
! 	is_an_ip_addr = 1;
!     }
!     else if (strcasecmp(w, "_default_") == 0
! 	     || strcmp(w, "255.255.255.255") == 0) {
! 	my_addr = DEFAULT_VHOST_ADDR;
! 	is_an_ip_addr = 1;
!     }
!     else if ((my_addr = ap_inet_addr(w)) != INADDR_NONE) {
! 	is_an_ip_addr = 1;
      }
!     if (is_an_ip_addr) {
! 	sar = ap_pcalloc(p, sizeof(server_addr_rec));
! 	**paddr = sar;
! 	*paddr = &sar->next;
! 	sar->host_addr.s_addr = my_addr;
! 	sar->host_port = port;
! 	sar->virthost = ap_pstrdup(p, w);
! 	if (t != NULL)
! 	    *t = ':';
! 	return NULL;
      }
- 
-     hep = gethostbyname(w);
  
!     if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
  	ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
! 	    "Cannot resolve host name %s --- ignoring!", w);
! 	if (t != NULL)
! 	    *t = ':';
  	return NULL;
      }
! 
!     for (i = 0; hep->h_addr_list[i]; ++i) {
  	sar = ap_pcalloc(p, sizeof(server_addr_rec));
  	**paddr = sar;
  	*paddr = &sar->next;
! 	sar->host_addr = *(struct in_addr *) hep->h_addr_list[i];
! 	sar->host_port = port;
  	sar->virthost = ap_pstrdup(p, w);
      }
  
!     if (t != NULL)
! 	*t = ':';
      return NULL;
  }
  
--- 165,273 ----
   * *paddr is the variable used to keep track of **paddr between calls
   * port is the default port to assume
   */
! static const char *get_addresses(pool *p, char *w, char *pstr,
! 	server_addr_rec ***paddr, unsigned port)
  {
!     struct addrinfo hints, *res, *res0;
      server_addr_rec *sar;
!     char *t = NULL, *u = NULL, *v = NULL;
!     char *hoststr = NULL, *portstr = NULL;
!     char portpool[10];
!     int error;
!     char servbuf[NI_NUMERICSERV];
  
!     if (w == 0 || *w == 0)
  	return NULL;
  
!     portstr = portpool;
!     ap_snprintf(portpool, sizeof(portpool), "%u", port);
!     if (!pstr) {
! 	v = w;
! 	if (*w == '['){
! 	    u = strrchr(w, ']');
! 	    if (u) {	/* [host]:port or [host] */
! 		w++;
! 		*u = '\0';
! 		v = u + 1;
! 	    }
  	}
! 	t = strrchr(v, ':');
! 	if (t) {
! 	    *t = '\0';
! 	    portstr = t + 1;
  	}
  	else {
! 	    portstr = "0";
  	}
!     } else {
! 	portstr = pstr;
      }
  
!     memset(&hints, 0, sizeof(hints));
!     hints.ai_socktype = SOCK_STREAM;
!     if (strcmp(w, "*") == 0 || strlen(w) == 0) {
! 	hoststr = NULL;
! 	hints.ai_family = PF_UNSPEC;
! 	hints.ai_flags = AI_PASSIVE;
!     }
!     else if (strcasecmp(w, "_default4_") == 0 ||
! 	     ((ap_default_family == AF_INET
! #ifndef INET6
! 	       || ap_default_family == AF_UNSPEC
! #endif
! 	       ) && strcasecmp(w, "default") == 0)){
! 	hoststr = "255.255.255.255";
! 	hints.ai_family = PF_INET;
!     }
! #ifdef INET6
!     else if (strcasecmp(w, "_default6_") == 0 ||
! 	     ((ap_default_family == AF_INET6
! 	       || ap_default_family == AF_UNSPEC
! 	       ) && strcasecmp(w, "default") == 0)){
! 	hoststr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
! 	hints.ai_family = PF_INET6;
      }
! #endif
!     else{
! 	hints.ai_family = PF_UNSPEC;
      }
  
!     error = getaddrinfo(hoststr, portstr, &hints, &res0);
!     if (error || !res0) {
  	ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
! 	    "Cannot resolve host %s port %s --- ignoring!", hoststr, portstr);
! 	if (t != NULL) *t = ':';
! 	if (u != NULL) *u = ']';
  	return NULL;
      }
!     for (res=res0; res; res=res->ai_next) {
! 	switch (res->ai_addr->sa_family) {
! 	case AF_INET:
! #ifdef INET6
! 	case AF_INET6:
! #endif
! 	    break;
! 	default:
! 	    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
! 			 "Unsupported address family %u, for host %s port %s --- ignoring!",
! 			 res->ai_addr->sa_family, hoststr, portstr);
! 	    continue;
! 	}
  	sar = ap_pcalloc(p, sizeof(server_addr_rec));
  	**paddr = sar;
  	*paddr = &sar->next;
! 	memcpy(&sar->host_addr, res->ai_addr, res->ai_addrlen);
! 	sar->host_port =
! 	  ntohs(getnameinfo(res->ai_addr, res->ai_addrlen,
! 			    NULL, 0, servbuf, sizeof(servbuf),
! 			    NI_NUMERICSERV) 
! 		? 0 : atoi(servbuf));
  	sar->virthost = ap_pstrdup(p, w);
      }
  
!     freeaddrinfo(res0);
!     if (t != NULL) *t = ':';
!     if (u != NULL) *u = ']';
      return NULL;
  }
  
***************
*** 249,255 ****
      /* start the list of addreses */
      addrs = &s->addrs;
      while (hostname[0]) {
! 	err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
  	if (err) {
  	    *addrs = NULL;
  	    return err;
--- 281,288 ----
      /* start the list of addreses */
      addrs = &s->addrs;
      while (hostname[0]) {
! 	err = get_addresses(p, ap_getword_conf(p, &hostname), NULL,
! 		&addrs, s->port);
  	if (err) {
  	    *addrs = NULL;
  	    return err;
***************
*** 267,276 ****
  }
  
  
! const char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg)
  {
      /* use whatever port the main server has at this point */
!     return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
  			    cmd->server->port);
  }
  
--- 300,310 ----
  }
  
  
! const char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *h,
! 	char *p)
  {
      /* use whatever port the main server has at this point */
!     return get_addresses(cmd->pool, h, p, &name_vhost_list_tail,
  			    cmd->server->port);
  }
  
***************
*** 344,349 ****
--- 378,396 ----
      return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
  }
  
+ static unsigned hash_addr(struct sockaddr *sa)
+ {
+     switch (sa->sa_family) {
+     case AF_INET:
+ 	return hash_inaddr(((struct sockaddr_in *)sa)->sin_addr.s_addr);
+ #ifdef INET6
+     case AF_INET6:
+ 	return hash_inaddr(((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12]);
+ #endif
+     default:
+ 	return hash_inaddr(sa->sa_family);
+     }
+ }
  
  
  static ipaddr_chain *new_ipaddr_chain(pool *p,
***************
*** 372,393 ****
  }
  
  
! static ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
!     unsigned port)
  {
      unsigned bucket;
      ipaddr_chain *trav;
-     unsigned addr;
  
      /* scan the hash table for an exact match first */
!     addr = server_ip->s_addr;
!     bucket = hash_inaddr(addr);
      for (trav = iphash_table[bucket]; trav; trav = trav->next) {
  	server_addr_rec *sar = trav->sar;
! 	if ((sar->host_addr.s_addr == addr)
! 	    && (sar->host_port == 0 || sar->host_port == port
! 		|| port == 0)) {
! 	    return trav;
  	}
      }
      return NULL;
--- 419,468 ----
  }
  
  
! static ap_inline ipaddr_chain *find_ipaddr(struct sockaddr *sa)
  {
      unsigned bucket;
      ipaddr_chain *trav;
  
      /* scan the hash table for an exact match first */
!     bucket = hash_addr(sa);
      for (trav = iphash_table[bucket]; trav; trav = trav->next) {
  	server_addr_rec *sar = trav->sar;
! 	if (sar->host_addr.ss_family != sa->sa_family)
! 	    continue;
! 	switch (sa->sa_family) {
! 	case AF_INET:
! 	  {
! 	    struct sockaddr_in *sin1, *sin2;
! 	    sin1 = (struct sockaddr_in *)&sar->host_addr;
! 	    sin2 = (struct sockaddr_in *)sa;
! 	    if (sin1->sin_port == 0 || sin2->sin_port == 0
! 	     || sin1->sin_port == sin2->sin_port) {
! 		if (memcmp(&sin1->sin_addr, &sin2->sin_addr,
! 			sizeof(sin1->sin_addr)) == 0) {
! 		    return trav;
! 		}
! 	    }
! 	    break;
! 	  }
! #ifdef INET6
! 	case AF_INET6:
! 	  {
! 	    struct sockaddr_in6 *sin1, *sin2;
! 	    sin1 = (struct sockaddr_in6 *)&sar->host_addr;
! 	    sin2 = (struct sockaddr_in6 *)sa;
! 	    if (sin1->sin6_port == 0 || sin2->sin6_port == 0
! 	     || sin1->sin6_port == sin2->sin6_port) {
! 		if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
! 			sizeof(sin1->sin6_addr)) == 0) {
! 		    return trav;
! 		}
! 	    }
! 	    break;
! 	  }
! #endif
! 	default: /*unsupported*/
! 	    break;
  	}
      }
      return NULL;
***************
*** 424,431 ****
  		ap_snprintf(buf, sizeof(buf), "%pA:*", &ic->sar->host_addr);
  	    }
  	    else {
! 		ap_snprintf(buf, sizeof(buf), "%pA:%u", &ic->sar->host_addr,
! 		    ic->sar->host_port);
  	    }
  	    if (ic->names == NULL) {
  		fprintf(f, "%-22s %s (%s:%u)\n", buf,
--- 499,505 ----
  		ap_snprintf(buf, sizeof(buf), "%pA:*", &ic->sar->host_addr);
  	    }
  	    else {
! 		ap_snprintf(buf, sizeof(buf), "%pI", &ic->sar->host_addr);
  	    }
  	    if (ic->names == NULL) {
  		fprintf(f, "%-22s %s (%s:%u)\n", buf,
***************
*** 496,502 ****
       * occured in the config file, we'll copy it in that order.
       */
      for (sar = name_vhost_list; sar; sar = sar->next) {
! 	unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
  	ipaddr_chain *new = new_ipaddr_chain(p, NULL, sar);
  
  	*iphash_table_tail[bucket] = new;
--- 570,576 ----
       * occured in the config file, we'll copy it in that order.
       */
      for (sar = name_vhost_list; sar; sar = sar->next) {
! 	unsigned bucket = hash_addr((struct sockaddr *)&sar->host_addr);
  	ipaddr_chain *new = new_ipaddr_chain(p, NULL, sar);
  
  	*iphash_table_tail[bucket] = new;
***************
*** 517,525 ****
  	has_default_vhost_addr = 0;
  	for (sar = s->addrs; sar; sar = sar->next) {
  	    ipaddr_chain *ic;
  
! 	    if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
! 		|| sar->host_addr.s_addr == INADDR_ANY) {
  		/* add it to default bucket for each appropriate sar
  		 * since we need to do a port test
  		 */
--- 591,627 ----
  	has_default_vhost_addr = 0;
  	for (sar = s->addrs; sar; sar = sar->next) {
  	    ipaddr_chain *ic;
+ 	    int wildcard;
  
! 	    wildcard = 0;
! 	    switch (sar->host_addr.ss_family) {
! 	    case AF_INET:
! 	      {
! 		struct sockaddr_in *sin;
! 		sin = (struct sockaddr_in *)&sar->host_addr;
! 		if (sin->sin_addr.s_addr == DEFAULT_VHOST_ADDR)
! 		    wildcard++;
! 		else if (sin->sin_addr.s_addr == INADDR_ANY)
! 		    wildcard++;
! 		break;
! 	      }
! #ifdef INET6
! 	    case AF_INET6:
! 	      {
! 		struct sockaddr_in6 *sin6;
! 		sin6 = (struct sockaddr_in6 *)&sar->host_addr;
! 		if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == ~0
! 		 && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == ~0
! 		 && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == ~0
! 		 && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == ~0) {
! 		    wildcard++;
! 		}
! 		break;
! 	      }
! #endif
! 	    }
! 
! 	    if (wildcard) {
  		/* add it to default bucket for each appropriate sar
  		 * since we need to do a port test
  		 */
***************
*** 538,544 ****
  	    }
  	    else {
  		/* see if it matches something we've already got */
! 		ic = find_ipaddr(&sar->host_addr, sar->host_port);
  
  		/* the first time we encounter a NameVirtualHost address
  		 * ic->server will be NULL, on subsequent encounters
--- 640,646 ----
  	    }
  	    else {
  		/* see if it matches something we've already got */
! 		ic = find_ipaddr((struct sockaddr *)&sar->host_addr);
  
  		/* the first time we encounter a NameVirtualHost address
  		 * ic->server will be NULL, on subsequent encounters
***************
*** 570,576 ****
  		    ic->server = s;
  		}
  		else {
! 		    unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
  
  		    ic = new_ipaddr_chain(p, s, sar);
  		    ic->next = *iphash_table_tail[bucket];
--- 672,679 ----
  		    ic->server = s;
  		}
  		else {
! 		    unsigned bucket =
! 			hash_addr((struct sockaddr *)&sar->host_addr);
  
  		    ic = new_ipaddr_chain(p, s, sar);
  		    ic->next = *iphash_table_tail[bucket];
***************
*** 597,615 ****
  	    }
  	    else {
  		struct hostent *h;
  
! 		if ((h = gethostbyaddr((char *) &(s->addrs->host_addr),
! 					sizeof(struct in_addr), AF_INET))) {
! 		    s->server_hostname = ap_pstrdup(p, (char *) h->h_name);
  		}
  		else {
  		    /* again, what can we do?  They didn't specify a
  		       ServerName, and their DNS isn't working. -djg */
  		    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, main_s,
  			    "Failed to resolve server name "
  			    "for %s (check DNS) -- or specify an explicit "
! 			    "ServerName",
! 			    inet_ntoa(s->addrs->host_addr));
  		    s->server_hostname =
  			ap_pstrdup(p, "bogus_host_without_reverse_dns");
  		}
--- 700,732 ----
  	    }
  	    else {
  		struct hostent *h;
+ 		char hostnamebuf[MAXHOSTNAMELEN];
  
! 		if (!getnameinfo((struct sockaddr *)&s->addrs->host_addr,
! #ifndef SIN6_LEN
! 			SA_LEN((struct sockaddr *)&s->addrs->host_addr),
! #else	
! 			s->addrs->host_addr.ss_len,
! #endif
! 			hostnamebuf, sizeof(hostnamebuf),
! 			NULL, 0, 0)) {
! 		    s->server_hostname = ap_pstrdup(p, hostnamebuf);
  		}
  		else {
  		    /* again, what can we do?  They didn't specify a
  		       ServerName, and their DNS isn't working. -djg */
+ 		    getnameinfo((struct sockaddr *)&s->addrs->host_addr,
+ #ifndef SIN6_LEN
+ 			SA_LEN((struct sockaddr *)&s->addrs->host_addr),
+ #else	
+ 			s->addrs->host_addr.ss_len,
+ #endif
+ 			hostnamebuf, sizeof(hostnamebuf),
+ 			NULL, 0, NI_NUMERICHOST);
  		    ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, main_s,
  			    "Failed to resolve server name "
  			    "for %s (check DNS) -- or specify an explicit "
! 			    "ServerName", hostnamebuf);
  		    s->server_hostname =
  			ap_pstrdup(p, "bogus_host_without_reverse_dns");
  		}
***************
*** 665,691 ****
      char *host = ap_palloc(r->pool, strlen(r->hostname) + 1);
      const char *src;
      char *dst;
  
      /* check and copy the host part */
      src = r->hostname;
      dst = host;
!     while (*src) {
! 	if (!ap_isalnum(*src) && *src != '.' && *src != '-') {
! 	    if (*src == ':')
! 		break;
! 	    else
! 		goto bad;
! 	} else {
! 	    *dst++ = *src++;
! 	}
!     }
!     /* check the port part */
!     if (*src++ == ':') {
! 	while (*src) {
! 	    if (!ap_isdigit(*src++)) {
! 		goto bad;
! 	    }
! 	}
      }
      /* strip trailing gubbins */
      if (dst > host && dst[-1] == '.') {
--- 782,830 ----
      char *host = ap_palloc(r->pool, strlen(r->hostname) + 1);
      const char *src;
      char *dst;
+     const char *u = NULL, *v = NULL;
  
      /* check and copy the host part */
      src = r->hostname;
      dst = host;
!     u = src;
!     if (*u == '[') { /* IPv6 numeral address in brackets */
!         v = strchr(u, ']');
!         if (v == NULL) {
!             /* missing closing bracket */
!             goto bad;
!             }
!         if (v == (u +1)) {
!             /* bad empty address */
!             goto bad;
!             }
!         for (src = u+1; src < v; src++)  /* copy IPv6 adress */
!             *dst = *src;
!         v++;
!         while (*v)  /* check if portnum is correct */
!             if (!ap_isdigit(*v++)) {
!                 goto bad;
!                 }
!     } else {
!         while (*src) {
!             if (!ap_isalnum(*src) && *src != '.' && *src != '-') {
!                 if (*src == ':')
!                     break;
!                 else {
!                     goto bad;
!                     }
!             } else {
!                 *dst++ = *src++;
!             }
!         }
!         /* check the port part */
!         if (*src++ == ':') {
!             while (*src) {
!                 if (!ap_isdigit(*src++)) {
!                     goto bad;
!                 }
!             }
!         }
      }
      /* strip trailing gubbins */
      if (dst > host && dst[-1] == '.') {
***************
*** 700,706 ****
  bad:
      r->status = HTTP_BAD_REQUEST;
      ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
! 		  "Client sent malformed Host header");
      return;
  }
  
--- 839,845 ----
  bad:
      r->status = HTTP_BAD_REQUEST;
      ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
! 		  "Client sent malformed Host header <<%s>>",u);
      return;
  }
  
***************
*** 803,813 ****
       *   names we'll match have ports associated with them
       */
      const char *host = r->hostname;
!     unsigned port = ntohs(r->connection->local_addr.sin_port);
      server_rec *s;
      server_rec *last_s;
      name_chain *src;
  
      last_s = NULL;
  
      /* Recall that the name_chain is a list of server_addr_recs, some of
--- 942,966 ----
       *   names we'll match have ports associated with them
       */
      const char *host = r->hostname;
!     unsigned port;
      server_rec *s;
      server_rec *last_s;
      name_chain *src;
  
+     switch (r->connection->local_addr.ss_family) {
+     case AF_INET:
+     	port = ntohs(((struct sockaddr_in *)
+ 		    &r->connection->local_addr)->sin_port);
+ 	break;
+ #ifdef INET6
+     case AF_INET6:
+     	port = ntohs(((struct sockaddr_in6 *)
+ 		    &r->connection->local_addr)->sin6_port);
+ 	break;
+ #endif
+     default:
+ 	port = 0;	/*XXX*/
+     }
      last_s = NULL;
  
      /* Recall that the name_chain is a list of server_addr_recs, some of
***************
*** 862,869 ****
      server_rec *s;
      server_rec *last_s;
      name_chain *src;
!     unsigned port = ntohs(r->connection->local_addr.sin_port);
  
      /*
       * This is in conjunction with the ServerPath code in http_core, so we
       * get the right host attached to a non- Host-sending request.
--- 1015,1037 ----
      server_rec *s;
      server_rec *last_s;
      name_chain *src;
!     unsigned port;
  
+     switch (r->connection->local_addr.ss_family) {
+     case AF_INET:
+     	port = ntohs(((struct sockaddr_in *)
+ 		    &r->connection->local_addr)->sin_port);
+ 	break;
+ #ifdef INET6
+     case AF_INET6:
+     	port = ntohs(((struct sockaddr_in6 *)
+ 		    &r->connection->local_addr)->sin6_port);
+ 	break;
+ #endif
+     default:
+ 	port = 0;	/*XXX*/
+     }
+ 
      /*
       * This is in conjunction with the ServerPath code in http_core, so we
       * get the right host attached to a non- Host-sending request.
***************
*** 922,931 ****
  void ap_update_vhost_given_ip(conn_rec *conn)
  {
      ipaddr_chain *trav;
!     unsigned port = ntohs(conn->local_addr.sin_port);
  
      /* scan the hash table for an exact match first */
!     trav = find_ipaddr(&conn->local_addr.sin_addr, port);
      if (trav) {
  	/* save the name_chain for later in case this is a name-vhost */
  	conn->vhost_lookup_data = trav->names;
--- 1090,1112 ----
  void ap_update_vhost_given_ip(conn_rec *conn)
  {
      ipaddr_chain *trav;
!     unsigned port;
! 
!     switch (conn->local_addr.ss_family) {
!     case AF_INET:
!     	port = ntohs(((struct sockaddr_in *)&conn->local_addr)->sin_port);
! 	break;
! #ifdef INET6
!     case AF_INET6:
!     	port = ntohs(((struct sockaddr_in6 *)&conn->local_addr)->sin6_port);
! 	break;
! #endif
!     default:
! 	port = 0;	/*XXX*/
!     }
  
      /* scan the hash table for an exact match first */
!     trav = find_ipaddr((struct sockaddr *)&conn->local_addr);
      if (trav) {
  	/* save the name_chain for later in case this is a name-vhost */
  	conn->vhost_lookup_data = trav->names;
Index: apache13/src/main/rfc1413.c
diff -c apache13/src/main/rfc1413.c:1.1.1.4 apache13/src/main/rfc1413.c:1.7
*** apache13/src/main/rfc1413.c:1.1.1.4	Wed Jan 26 21:12:54 2000
--- apache13/src/main/rfc1413.c	Wed Jan 26 21:38:12 2000
***************
*** 81,86 ****
--- 81,87 ----
  #include "http_log.h"		/* for aplog_error */
  #include "rfc1413.h"
  #include "http_main.h"		/* set_callback_and_alarm */
+ #include "sa_len.h"
  
  /* Local stuff. */
  /* Semi-well-known port */
***************
*** 108,119 ****
  
  /* bind_connect - bind both ends of a socket */
  /* Ambarish fix this. Very broken */
! static int get_rfc1413(int sock, const struct sockaddr_in *our_sin,
! 		       const struct sockaddr_in *rmt_sin, 
  		       char user[RFC1413_USERLEN+1], server_rec *srv)
  {
!     struct sockaddr_in rmt_query_sin, our_query_sin;
!     unsigned int rmt_port, our_port;
      int i;
      char *cp;
      char buffer[RFC1413_MAXDATA + 1];
--- 109,121 ----
  
  /* bind_connect - bind both ends of a socket */
  /* Ambarish fix this. Very broken */
! static int get_rfc1413(int sock, const struct sockaddr *our_sin,
! 		       const struct sockaddr *rmt_sin, 
  		       char user[RFC1413_USERLEN+1], server_rec *srv)
  {
!     struct sockaddr_storage rmt_query_sin, our_query_sin;
!     unsigned int o_rmt_port, o_our_port;	/* original port pair */
!     unsigned int rmt_port, our_port;		/* replied port pair */
      int i;
      char *cp;
      char buffer[RFC1413_MAXDATA + 1];
***************
*** 128,143 ****
       * addresses from the query socket.
       */
  
!     our_query_sin = *our_sin;
!     our_query_sin.sin_port = htons(ANY_PORT);
! #ifdef MPE 
!     our_query_sin.sin_addr.s_addr = INADDR_ANY;
  #endif
!     rmt_query_sin = *rmt_sin;
!     rmt_query_sin.sin_port = htons(RFC1413_PORT);
  
      if (bind(sock, (struct sockaddr *) &our_query_sin,
! 	     sizeof(struct sockaddr_in)) < 0) {
  	ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
  		    "bind: rfc1413: Error binding to local port");
  	return -1;
--- 130,176 ----
       * addresses from the query socket.
       */
  
! #ifndef SIN6_LEN
!     memcpy(&our_query_sin, our_sin, SA_LEN(our_sin));
!     memcpy(&rmt_query_sin, rmt_sin, SA_LEN(rmt_sin));
! #else
!     memcpy(&our_query_sin, our_sin, our_sin->sa_len);
!     memcpy(&rmt_query_sin, rmt_sin, rmt_sin->sa_len);
  #endif
!     switch (our_sin->sa_family) {
!     case AF_INET:
! #ifdef MPE
!       ((struct sockaddr_in *)&our_query_sin)->sin_addr.s_addr = INADDR_ANY; /* XXX: htonl(??) */
! #endif
!       ((struct sockaddr_in *)&our_query_sin)->sin_port = htons(ANY_PORT);
!       o_our_port = ntohs(((struct sockaddr_in *)our_sin)->sin_port);
!       ((struct sockaddr_in *)&rmt_query_sin)->sin_port = htons(RFC1413_PORT);
!       o_rmt_port = ntohs(((struct sockaddr_in *)rmt_sin)->sin_port);
!       break;
! #ifdef INET6
!     case AF_INET6:
! #ifdef MPE
!       memcpy(&((struct sockaddr_in6 *)&our_query_sin)->sin6_addr, 
! 	     &in6addr_any, sizeof(struct in6_addr));
! #endif
!       ((struct sockaddr_in6 *)&our_query_sin)->sin6_port = htons(ANY_PORT);
!       o_our_port = ntohs(((struct sockaddr_in6 *)our_sin)->sin6_port);
!       ((struct sockaddr_in6 *)&rmt_query_sin)->sin6_port = htons(RFC1413_PORT);
!       o_rmt_port = ntohs(((struct sockaddr_in6 *)rmt_sin)->sin6_port);
!       break;
! #endif
!     default:
!       /* unsupported AF */
!       return -1;
!     }
  
      if (bind(sock, (struct sockaddr *) &our_query_sin,
! #ifndef SIN6_LEN
! 	     SA_LEN((struct sockaddr *) &our_query_sin)
! #else
! 	     our_query_sin.ss_len
! #endif
! 	     ) < 0) {
  	ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
  		    "bind: rfc1413: Error binding to local port");
  	return -1;
***************
*** 148,159 ****
   * the service
   */
      if (connect(sock, (struct sockaddr *) &rmt_query_sin,
! 		sizeof(struct sockaddr_in)) < 0)
! 	            return -1;
  
  /* send the data */
!     buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", ntohs(rmt_sin->sin_port),
! 		ntohs(our_sin->sin_port));
  
      /* send query to server. Handle short write. */
  #ifdef CHARSET_EBCDIC
--- 181,198 ----
   * the service
   */
      if (connect(sock, (struct sockaddr *) &rmt_query_sin,
! #ifndef SIN6_LEN
! 		SA_LEN((struct sockaddr *) &rmt_query_sin)
! #else
! 		rmt_query_sin.ss_len
! #endif
! 		) < 0) {
! 	return -1;
!     }
  
  /* send the data */
!     buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", o_rmt_port,
! 		o_our_port);
  
      /* send query to server. Handle short write. */
  #ifdef CHARSET_EBCDIC
***************
*** 218,226 ****
      ascii2ebcdic(buffer, buffer, (size_t)i);
  #endif
      if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port,
! 	       user) != 3 || ntohs(rmt_sin->sin_port) != rmt_port
! 	|| ntohs(our_sin->sin_port) != our_port)
  	return -1;
  
      /*
       * Strip trailing carriage return. It is part of the
--- 257,265 ----
      ascii2ebcdic(buffer, buffer, (size_t)i);
  #endif
      if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port,
! 	       user) != 3 || o_rmt_port != rmt_port || o_our_port != our_port) {
  	return -1;
+     }
  
      /*
       * Strip trailing carriage return. It is part of the
***************
*** 242,248 ****
  
      result = FROM_UNKNOWN;
  
!     sock = ap_psocket(conn->pool, AF_INET, SOCK_STREAM, IPPROTO_TCP);
      if (sock < 0) {
  	ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
  		    "socket: rfc1413: error creating socket");
--- 281,287 ----
  
      result = FROM_UNKNOWN;
  
!     sock = ap_psocket(conn->pool, conn->remote_addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
      if (sock < 0) {
  	ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
  		    "socket: rfc1413: error creating socket");
***************
*** 255,262 ****
      if (ap_setjmp(timebuf) == 0) {
  	ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout);
  
! 	if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user, srv) >= 0)
  	    result = user;
      }
      ap_set_callback_and_alarm(NULL, 0);
      ap_pclosesocket(conn->pool, sock);
--- 294,303 ----
      if (ap_setjmp(timebuf) == 0) {
  	ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout);
  
! 	if (get_rfc1413(sock, (struct sockaddr *)&conn->local_addr,
! 		(struct sockaddr *)&conn->remote_addr, user, srv) >= 0) {
  	    result = user;
+ 	}
      }
      ap_set_callback_and_alarm(NULL, 0);
      ap_pclosesocket(conn->pool, sock);
Index: apache13/src/main/util.c
diff -c apache13/src/main/util.c:1.1.1.6 apache13/src/main/util.c:1.12
*** apache13/src/main/util.c:1.1.1.6	Wed Jan 26 21:12:54 2000
--- apache13/src/main/util.c	Wed Jan 26 21:38:12 2000
***************
*** 1868,1919 ****
   * Parses a host of the form <address>[:port]
   * :port is permitted if 'port' is not NULL
   */
! unsigned long ap_get_virthost_addr(char *w, unsigned short *ports)
  {
!     struct hostent *hep;
!     unsigned long my_addr;
!     char *p;
! 
!     p = strchr(w, ':');
      if (ports != NULL) {
! 	*ports = 0;
! 	if (p != NULL && strcmp(p + 1, "*") != 0)
! 	    *ports = atoi(p + 1);
      }
  
      if (p != NULL)
  	*p = '\0';
      if (strcmp(w, "*") == 0) {
! 	if (p != NULL)
! 	    *p = ':';
! 	return htonl(INADDR_ANY);
      }
  
!     my_addr = ap_inet_addr((char *)w);
!     if (my_addr != INADDR_NONE) {
! 	if (p != NULL)
! 	    *p = ':';
! 	return my_addr;
!     }
! 
!     hep = gethostbyname(w);
  
!     if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
! 	fprintf(stderr, "Cannot resolve host name %s --- exiting!\n", w);
  	exit(1);
      }
  
!     if (hep->h_addr_list[1]) {
! 	fprintf(stderr, "Host %s has multiple addresses ---\n", w);
  	fprintf(stderr, "you must choose one explicitly for use as\n");
  	fprintf(stderr, "a virtual host.  Exiting!!!\n");
  	exit(1);
      }
  
      if (p != NULL)
  	*p = ':';
  
!     return ((struct in_addr *) (hep->h_addr))->s_addr;
  }
  
  
--- 1868,1949 ----
   * Parses a host of the form <address>[:port]
   * :port is permitted if 'port' is not NULL
   */
! struct sockaddr *ap_get_virthost_addr(char *w, unsigned short *ports)
  {
!     static struct sockaddr_storage ss;
!     struct addrinfo hints, *res;
!     char *p, *r;
!     char *host;
!     char *port = "0";
!     int error;
!     char servbuf[NI_MAXSERV];
! 
!     if (w == NULL)
! 	w = "*";
!     p = r = NULL;
!     if (*w == '['){
! 	if (r = strrchr(w+1, ']')){
! 	    *r = '\0';
! 	    p = r + 1;
! 	    switch(*p){
! 	    case ':':
! 	      p++;
! 	      /* nobreak; */
! 	    case '\0':
! 	      w++;
! 	      break;
! 	    default:
! 	      p = NULL;
! 	    }
! 	}
!     }
      if (ports != NULL) {
! 	if (p != NULL && *p && strcmp(p + 1, "*") != 0)
! 	    port = p + 1;
      }
  
+     memset(&hints, 0, sizeof(hints));
+     hints.ai_socktype = SOCK_STREAM;
      if (p != NULL)
  	*p = '\0';
      if (strcmp(w, "*") == 0) {
! 	host = NULL;
! 	hints.ai_flags = AI_PASSIVE;
! 	hints.ai_family = ap_default_family;
!     } else {
! 	host = w;
! 	hints.ai_family = PF_UNSPEC;
      }
  
!     error = getaddrinfo(host, port, &hints, &res);
  
!     if (error || !res) {
! 	fprintf(stderr, "ap_get_vitrhost_addr(): getaddrinfo(%s):%s --- exiting!\n", w, gai_strerror(error));
  	exit(1);
      }
  
!     if (res->ai_next) {
! 	fprintf(stderr, "ap_get_vitrhost_addr(): Host %s has multiple addresses ---\n", w);
  	fprintf(stderr, "you must choose one explicitly for use as\n");
  	fprintf(stderr, "a virtual host.  Exiting!!!\n");
  	exit(1);
      }
  
+     if (r != NULL)
+ 	*r = ']';
      if (p != NULL)
  	*p = ':';
  
!     memcpy(&ss, res->ai_addr, res->ai_addrlen);
!     if (getnameinfo(res->ai_addr, res->ai_addrlen,
! 		    NULL, 0, servbuf, sizeof(servbuf),
! 		    NI_NUMERICSERV)){
! 	fprintf(stderr, "ap_get_virthost_addr(): getnameinfo() failed --- Exiting!!!\n");
! 	exit(1);
!     }
!     if (ports) *ports = atoi(servbuf);
!     freeaddrinfo(res);
!     return (struct sockaddr *)&ss;
  }
  
  
***************
*** 1939,1945 ****
  #endif
      char str[MAXHOSTNAMELEN];
      char *server_hostname;
!     struct hostent *p;
  
  #ifdef BEOS /* BeOS returns zero as an error for gethostname */
      if (gethostname(str, sizeof(str) - 1) == 0) {
--- 1969,1976 ----
  #endif
      char str[MAXHOSTNAMELEN];
      char *server_hostname;
!     struct addrinfo hints, *res;
!     int error;
  
  #ifdef BEOS /* BeOS returns zero as an error for gethostname */
      if (gethostname(str, sizeof(str) - 1) == 0) {
***************
*** 1950,1962 ****
  	exit(1);
      }
      str[sizeof(str) - 1] = '\0';
!     if ((!(p = gethostbyname(str))) || (!(server_hostname = find_fqdn(a, p)))) {
  	fprintf(stderr, "%s: cannot determine local host name.\n",
  		ap_server_argv0);
  	fprintf(stderr, "Use the ServerName directive to set it manually.\n");
  	exit(1);
      }
! 
      return server_hostname;
  }
  
--- 1981,1998 ----
  	exit(1);
      }
      str[sizeof(str) - 1] = '\0';
!     memset(&hints, 0, sizeof(hints));
!     hints.ai_family = PF_UNSPEC;
!     hints.ai_flags = AI_CANONNAME;
!     error = getaddrinfo(str, NULL, &hints, &res);
!     if (error || !res || !res->ai_canonname) {
  	fprintf(stderr, "%s: cannot determine local host name.\n",
  		ap_server_argv0);
  	fprintf(stderr, "Use the ServerName directive to set it manually.\n");
  	exit(1);
      }
!     server_hostname = ap_pstrdup(a, res->ai_canonname);
!     freeaddrinfo(res);
      return server_hostname;
  }
  
***************
*** 2034,2040 ****
      char *quote_doubled_str, *dest;
      
      while (str[len]) {
!         num_quotes += str[len++] == '\"';
      }
      
      quote_doubled_str = ap_palloc(p, len + num_quotes + 1);
--- 2070,2076 ----
      char *quote_doubled_str, *dest;
      
      while (str[len]) {
! 	num_quotes += str[len++] == '\"';
      }
      
      quote_doubled_str = ap_palloc(p, len + num_quotes + 1);
***************
*** 2146,2148 ****
--- 2182,2192 ----
      *outchr = '\0';
      return outstring;
  }
+ 
+ #ifdef NEED_GETADDRINFO
+ #include "getaddrinfo.c"
+ #endif
+ 
+ #ifdef NEED_GETNAMEINFO
+ #include "getnameinfo.c"
+ #endif
Index: apache13/src/main/util_script.c
diff -c apache13/src/main/util_script.c:1.1.1.6 apache13/src/main/util_script.c:1.9
*** apache13/src/main/util_script.c:1.1.1.6	Wed Jan 26 21:12:54 2000
--- apache13/src/main/util_script.c	Mon Feb  7 22:37:18 2000
***************
*** 66,71 ****
--- 66,72 ----
  #include "http_request.h"	/* for sub_req_lookup_uri() */
  #include "util_script.h"
  #include "util_date.h"		/* For parseHTTPdate() */
+ #include "sa_len.h"
  
  #ifdef OS2
  #define INCL_DOS
***************
*** 207,212 ****
--- 208,214 ----
      array_header *hdrs_arr = ap_table_elts(r->headers_in);
      table_entry *hdrs = (table_entry *) hdrs_arr->elts;
      int i;
+     char servbuf[NI_MAXSERV];
  
      /* use a temporary table which we'll overlap onto
       * r->subprocess_env later
***************
*** 297,304 ****
      ap_table_addn(e, "SERVER_ADMIN", s->server_admin);	/* Apache */
      ap_table_addn(e, "SCRIPT_FILENAME", r->filename);	/* Apache */
  
!     ap_table_addn(e, "REMOTE_PORT",
! 		  ap_psprintf(r->pool, "%d", ntohs(c->remote_addr.sin_port)));
  
      if (c->user) {
  	ap_table_addn(e, "REMOTE_USER", c->user);
--- 299,314 ----
      ap_table_addn(e, "SERVER_ADMIN", s->server_admin);	/* Apache */
      ap_table_addn(e, "SCRIPT_FILENAME", r->filename);	/* Apache */
  
!     servbuf[0] = '\0';
!     if (!getnameinfo((struct sockaddr *)&c->remote_addr,
! #ifndef HAVE_SOCKADDR_LEN
! 		     SA_LEN((struct sockaddr *)&c->remote_addr),
! #else
! 		     c->remote_addr.ss_len,
! #endif
! 		     NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)){
! 	ap_table_addn(e, "REMOTE_PORT", servbuf);
!     }
  
      if (c->user) {
  	ap_table_addn(e, "REMOTE_USER", c->user);
Index: apache13/src/modules/proxy/mod_proxy.h
diff -c apache13/src/modules/proxy/mod_proxy.h:1.1.1.4 apache13/src/modules/proxy/mod_proxy.h:1.5
*** apache13/src/modules/proxy/mod_proxy.h:1.1.1.4	Wed Jan 26 21:12:59 2000
--- apache13/src/modules/proxy/mod_proxy.h	Wed Jan 26 21:38:14 2000
***************
*** 311,317 ****
  int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p);
  int ap_proxy_is_hostname(struct dirconn_entry *This, pool *p);
  int ap_proxy_is_word(struct dirconn_entry *This, pool *p);
! int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
  int ap_proxy_garbage_init(server_rec *, pool *);
  /* This function is called by ap_table_do() for all header lines */
  int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
--- 311,317 ----
  int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p);
  int ap_proxy_is_hostname(struct dirconn_entry *This, pool *p);
  int ap_proxy_is_word(struct dirconn_entry *This, pool *p);
! int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r);
  int ap_proxy_garbage_init(server_rec *, pool *);
  /* This function is called by ap_table_do() for all header lines */
  int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
Index: apache13/src/modules/proxy/proxy_connect.c
diff -c apache13/src/modules/proxy/proxy_connect.c:1.1.1.5 apache13/src/modules/proxy/proxy_connect.c:1.3
*** apache13/src/modules/proxy/proxy_connect.c:1.1.1.5	Wed Jan 26 21:12:59 2000
--- apache13/src/modules/proxy/proxy_connect.c	Wed Jan 26 21:38:14 2000
***************
*** 203,209 ****
      while (server_hp.h_addr_list[j] != NULL) {
  	memcpy(&server.sin_addr, server_hp.h_addr_list[j],
  	       sizeof(struct in_addr));
! 	i = ap_proxy_doconnect(sock, &server, r);
  	if (i == 0)
  	    break;
  	j++;
--- 203,209 ----
      while (server_hp.h_addr_list[j] != NULL) {
  	memcpy(&server.sin_addr, server_hp.h_addr_list[j],
  	       sizeof(struct in_addr));
! 	i = ap_proxy_doconnect(sock, (struct sockaddr *)&server, r);
  	if (i == 0)
  	    break;
  	j++;
Index: apache13/src/modules/proxy/proxy_ftp.c
diff -c apache13/src/modules/proxy/proxy_ftp.c:1.1.1.5 apache13/src/modules/proxy/proxy_ftp.c:1.14
*** apache13/src/modules/proxy/proxy_ftp.c:1.1.1.5	Wed Jan 26 21:12:59 2000
--- apache13/src/modules/proxy/proxy_ftp.c	Tue Feb  8 11:36:30 2000
***************
*** 61,66 ****
--- 61,67 ----
  #include "http_main.h"
  #include "http_log.h"
  #include "http_core.h"
+ #include "sa_len.h"
  
  #define AUTODETECT_PWD
  
***************
*** 452,459 ****
      const char *err;
      int port, i, j, len, sock, dsock, rc, nocache = 0;
      int csd = 0;
!     struct sockaddr_in server;
!     struct hostent server_hp;
      struct in_addr destaddr;
      table *resp_hdrs;
      BUFF *f;
--- 453,462 ----
      const char *err;
      int port, i, j, len, sock, dsock, rc, nocache = 0;
      int csd = 0;
!     struct sockaddr_storage server;
!     struct addrinfo hints, *res, *res0;
!     char portbuf[10];
!     int error;
      struct in_addr destaddr;
      table *resp_hdrs;
      BUFF *f;
***************
*** 474,484 ****
      unsigned int presult, h0, h1, h2, h3, p0, p1;
      unsigned int paddr;
      unsigned short pport;
!     struct sockaddr_in data_addr;
      int pasvmode = 0;
      char pasv[64];
      char *pstr;
  
  /* stuff for responses */
      char resp[MAX_STRING_LEN];
      char *size = NULL;
--- 477,494 ----
      unsigned int presult, h0, h1, h2, h3, p0, p1;
      unsigned int paddr;
      unsigned short pport;
!     struct sockaddr_storage data_addr;
!     struct sockaddr_in *sin;
      int pasvmode = 0;
      char pasv[64];
      char *pstr;
  
+ /* stuff for LPSV/EPSV */
+     unsigned int paf, holen, ho[16], polen, po[2];
+     struct sockaddr_in6 *sin6;
+     int lpsvmode = 0;
+     char *cmd;
+ 
  /* stuff for responses */
      char resp[MAX_STRING_LEN];
      char *size = NULL;
***************
*** 547,608 ****
      if (parms != NULL)
  	*(parms++) = '\0';
  
!     memset(&server, 0, sizeof(struct sockaddr_in));
!     server.sin_family = AF_INET;
!     server.sin_port = htons(port);
!     err = ap_proxy_host2addr(host, &server_hp);
!     if (err != NULL)
! 	return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
  
-     sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
-     if (sock == -1) {
- 	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- 		     "proxy: error creating socket");
- 	return HTTP_INTERNAL_SERVER_ERROR;
-     }
- 
  #ifndef TPF
!     if (conf->recv_buffer_size > 0
! 	&& setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
! 		       (const char *) &conf->recv_buffer_size, sizeof(int))
! 	    == -1) {
! 	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 			 "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
!     }
  #endif
  
!     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &one,
! 		   sizeof(one)) == -1) {
  #ifndef _OSD_POSIX /* BS2000 has this option "always on" */
! 	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 		     "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
! 	ap_pclosesocket(p, sock);
! 	return HTTP_INTERNAL_SERVER_ERROR;
  #endif /*_OSD_POSIX*/
-     }
- 
- #ifdef SINIX_D_RESOLVER_BUG
-     {
- 	struct in_addr *ip_addr = (struct in_addr *) *server_hp.h_addr_list;
- 
- 	for (; ip_addr->s_addr != 0; ++ip_addr) {
- 	    memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
- 	    i = ap_proxy_doconnect(sock, &server, r);
- 	    if (i == 0)
- 		break;
  	}
!     }
! #else
!     j = 0;
!     while (server_hp.h_addr_list[j] != NULL) {
! 	memcpy(&server.sin_addr, server_hp.h_addr_list[j],
! 	       sizeof(struct in_addr));
! 	i = ap_proxy_doconnect(sock, &server, r);
  	if (i == 0)
  	    break;
! 	j++;
      }
! #endif
      if (i == -1) {
  	ap_pclosesocket(p, sock);
  	return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool,
--- 557,606 ----
      if (parms != NULL)
  	*(parms++) = '\0';
  
!     ap_snprintf(portbuf, sizeof(portbuf), "%d", port);
!     memset(&hints, 0, sizeof(hints));
!     hints.ai_family = PF_UNSPEC;
!     hints.ai_socktype = SOCK_STREAM;
!     error = getaddrinfo(host, portbuf, &hints, &res0);
!     if (error) {
! 	return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
! 	    gai_strerror(error));
!     }
! 
!     i = -1;
!     for (res = res0; res; res = res->ai_next) {
! 	sock = ap_psocket(p, res->ai_family, res->ai_socktype,
! 	    res->ai_protocol);
! 	if (sock == -1)
! 	    continue;
  
  #ifndef TPF
! 	if (conf->recv_buffer_size > 0
! 	    && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
! 			   (const char *) &conf->recv_buffer_size, sizeof(int))
! 		== -1) {
! 		ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 			     "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
! 	}
  #endif
  
! 	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &one,
! 		       sizeof(one)) == -1) {
  #ifndef _OSD_POSIX /* BS2000 has this option "always on" */
! 	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 			 "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
! 	    ap_pclosesocket(p, sock);
! 	    freeaddrinfo(res0);
! 	    return HTTP_INTERNAL_SERVER_ERROR;
  #endif /*_OSD_POSIX*/
  	}
! 
! 	i = ap_proxy_doconnect(sock, res->ai_addr, r);
  	if (i == 0)
  	    break;
! 	ap_pclosesocket(p, sock);
      }
!     freeaddrinfo(res0);
      if (i == -1) {
  	ap_pclosesocket(p, sock);
  	return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool,
***************
*** 806,812 ****
      }
  
  /* try to set up PASV data connection first */
!     dsock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
      if (dsock == -1) {
  	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
  		     "proxy: error creating PASV socket");
--- 804,810 ----
      }
  
  /* try to set up PASV data connection first */
!     dsock = ap_psocket(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP);
      if (dsock == -1) {
  	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
  		     "proxy: error creating PASV socket");
***************
*** 825,835 ****
      }
  #endif
  
!     ap_bputs("PASV" CRLF, f);
      ap_bflush(f);
!     Explain0("FTP: PASV command issued");
  /* possible results: 227, 421, 500, 501, 502, 530 */
      /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */
      /* 421 Service not available, closing control connection. */
      /* 500 Syntax error, command unrecognized. */
      /* 501 Syntax error in parameters or arguments. */
--- 823,843 ----
      }
  #endif
  
! lpsvagain:
!     if (server.ss_family == AF_INET)
! 	cmd = "PASV";
!     else if (lpsvmode)
! 	cmd = "LPSV";
!     else
! 	cmd = "EPSV";
!     ap_bputs(cmd, f);
!     ap_bputs(CRLF, f);
      ap_bflush(f);
!     Explain0("FTP: passive command issued");
  /* possible results: 227, 421, 500, 501, 502, 530 */
      /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */
+     /* 228 Entering Long Passive Mode (...). */
+     /* 229 Entering Extended Passive Mode (...). */
      /* 421 Service not available, closing control connection. */
      /* 500 Syntax error, command unrecognized. */
      /* 501 Syntax error in parameters or arguments. */
***************
*** 838,844 ****
      i = ap_bgets(pasv, sizeof(pasv), f);
      if (i == -1) {
  	ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r,
! 		     "PASV: control connection is toast");
  	ap_pclosesocket(p, dsock);
  	ap_bclose(f);
  	ap_kill_timeout(r);
--- 846,852 ----
      i = ap_bgets(pasv, sizeof(pasv), f);
      if (i == -1) {
  	ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r,
! 		     "%s: control connection is toast", cmd);
  	ap_pclosesocket(p, dsock);
  	ap_bclose(f);
  	ap_kill_timeout(r);
***************
*** 870,879 ****
  	    pport = (p1 << 8) + p0;
  	    Explain5("FTP: contacting host %d.%d.%d.%d:%d",
  		     h3, h2, h1, h0, pport);
! 	    data_addr.sin_family = AF_INET;
! 	    data_addr.sin_addr.s_addr = htonl(paddr);
! 	    data_addr.sin_port = htons(pport);
! 	    i = ap_proxy_doconnect(dsock, &data_addr, r);
  
  	    if (i == -1) {
  		ap_kill_timeout(r);
--- 878,891 ----
  	    pport = (p1 << 8) + p0;
  	    Explain5("FTP: contacting host %d.%d.%d.%d:%d",
  		     h3, h2, h1, h0, pport);
! 	    sin = (struct sockaddr_in *)&data_addr;
! 	    sin->sin_family = AF_INET;
! #ifdef SIN6_LEN
! 	    sin->sin_len = sizeof(*sin);
! #endif
! 	    sin->sin_addr.s_addr = htonl(paddr);
! 	    sin->sin_port = htons(pport);
! 	    i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
  
  	    if (i == -1) {
  		ap_kill_timeout(r);
***************
*** 881,897 ****
  				     ap_pstrcat(r->pool,
  						"Could not connect to remote machine: ",
  						strerror(errno), NULL));
  	    }
! 	    else {
  		pasvmode = 1;
  	    }
  	}
  	else
  	    ap_pclosesocket(p, dsock);	/* and try the regular way */
      }
  
      if (!pasvmode) {		/* set up data connection */
! 	clen = sizeof(struct sockaddr_in);
  	if (getsockname(sock, (struct sockaddr *) &server, &clen) < 0) {
  	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
  			 "proxy: error getting socket address");
--- 893,968 ----
  				     ap_pstrcat(r->pool,
  						"Could not connect to remote machine: ",
  						strerror(errno), NULL));
+ 	    } else {
+ 		pasvmode = 1;
  	    }
! 	} else if (presult == 228 && pstr != NULL
! 		&& sscanf(pstr,
! "%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
! 		    &paf, &holen, &ho[0], &ho[1], &ho[2], &ho[3],
! 		    &ho[4], &ho[5], &ho[6], &ho[7], &ho[8], &ho[9], &ho[10], &ho[11],
! 		    &ho[12], &ho[13], &ho[14], &ho[15], &polen, &po[0], &po[1]) == 21
! 		&& paf == 6 && holen == 16 && polen == 2) {
! 	    int i;
! 	    sin6 = (struct sockaddr_in6 *)&data_addr;
! 	    sin6->sin6_family = AF_INET6;
! #ifdef SIN6_LEN
! 	    sin6->sin6_len = sizeof(*sin6);
! #endif
! 	    for (i = 0; i < 16; i++)
! 		sin6->sin6_addr.s6_addr[i] = ho[i] & 0xff;
! 	    sin6->sin6_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
! 	    i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
! 
! 	    if (i == -1) {
! 		ap_kill_timeout(r);
! 		return ap_proxyerror(r, HTTP_BAD_GATEWAY,
! 				     ap_pstrcat(r->pool,
! 						"Could not connect to remote machine: ",
! 						strerror(errno), NULL));
! 	    } else {
  		pasvmode = 1;
  	    }
+ 	} else if (presult == 229 && pstr != NULL
+ 		&& pstr[0] == pstr[1] && pstr[0] == pstr[2]
+ 		&& pstr[0] == pstr[strlen(pstr) - 1]) {
+ 	    /* expect "|||port|" */
+ #ifndef SIN6_LEN
+ 	    memcpy(&data_addr, &server, SA_LEN((struct sockaddr *)&server));
+ #else
+ 	    memcpy(&data_addr, &server, server.ss_len);
+ #endif
+ 	    switch (data_addr.ss_family) {
+ 	    case AF_INET:
+ 		sin = (struct sockaddr_in *)&data_addr;
+ 		sin->sin_port = htons(atoi(pstr + 3));
+ 		break;
+ 	    case AF_INET6:
+ 		sin6 = (struct sockaddr_in6 *)&data_addr;
+ 		sin6->sin6_port = htons(atoi(pstr + 3));
+ 		break;
+ 	    }
+ 	    i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
+ 
+ 	    if (i == -1) {
+ 		ap_kill_timeout(r);
+ 		return ap_proxyerror(r, HTTP_BAD_GATEWAY,
+ 				     ap_pstrcat(r->pool,
+ 						"Could not connect to remote machine: ",
+ 						strerror(errno), NULL));
+ 	    } else {
+ 		pasvmode = 1;
+ 	    }
+ 	} else if (!lpsvmode && strcmp(cmd, "EPSV") == 0) {
+ 	    lpsvmode = 1;
+ 	    goto lpsvagain;
  	}
  	else
  	    ap_pclosesocket(p, dsock);	/* and try the regular way */
      }
  
      if (!pasvmode) {		/* set up data connection */
! 	clen = sizeof(server);
  	if (getsockname(sock, (struct sockaddr *) &server, &clen) < 0) {
  	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
  			 "proxy: error getting socket address");
***************
*** 900,906 ****
  	    return HTTP_INTERNAL_SERVER_ERROR;
  	}
  
! 	dsock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
  	if (dsock == -1) {
  	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
  			 "proxy: error creating socket");
--- 971,977 ----
  	    return HTTP_INTERNAL_SERVER_ERROR;
  	}
  
! 	dsock = ap_psocket(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP);
  	if (dsock == -1) {
  	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
  			 "proxy: error creating socket");
***************
*** 921,933 ****
  #endif /*_OSD_POSIX*/
  	}
  
! 	if (bind(dsock, (struct sockaddr *) &server,
! 		 sizeof(struct sockaddr_in)) == -1) {
! 	    char buff[22];
  
! 	    ap_snprintf(buff, sizeof(buff), "%s:%d", inet_ntoa(server.sin_addr), server.sin_port);
  	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 			 "proxy: error binding to ftp data socket %s", buff);
  	    ap_bclose(f);
  	    ap_pclosesocket(p, dsock);
  	    return HTTP_INTERNAL_SERVER_ERROR;
--- 992,1017 ----
  #endif /*_OSD_POSIX*/
  	}
  
! #ifndef SIN6_LEN
! 	if (bind(dsock, (struct sockaddr *) &server, SA_LEN((struct sockaddr *)&server)) == -1)
! #else
! 	if (bind(dsock, (struct sockaddr *) &server, server.ss_len) == -1)
! #endif
! 	{
! 	    char hostnamebuf[MAXHOSTNAMELEN], portnamebuf[MAXHOSTNAMELEN];
  
! 	    getnameinfo((struct sockaddr *)&server,
! #ifndef SIN6_LEN
! 		    SA_LEN((struct sockaddr *)&server),
! #else
! 		    server.ss_len,
! #endif
! 		hostnamebuf, sizeof(hostnamebuf),
! 		portnamebuf, sizeof(portnamebuf),
! 		NI_NUMERICHOST | NI_NUMERICSERV);
  	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 			 "proxy: error binding to ftp data socket %s:%s",
! 			 hostnamebuf, portnamebuf);
  	    ap_bclose(f);
  	    ap_pclosesocket(p, dsock);
  	    return HTTP_INTERNAL_SERVER_ERROR;
***************
*** 1173,1179 ****
  
      if (!pasvmode) {		/* wait for connection */
  	ap_hard_timeout("proxy ftp data connect", r);
! 	clen = sizeof(struct sockaddr_in);
  	do
  	    csd = accept(dsock, (struct sockaddr *) &server, &clen);
  	while (csd == -1 && errno == EINTR);
--- 1257,1263 ----
  
      if (!pasvmode) {		/* wait for connection */
  	ap_hard_timeout("proxy ftp data connect", r);
! 	clen = sizeof(server);
  	do
  	    csd = accept(dsock, (struct sockaddr *) &server, &clen);
  	while (csd == -1 && errno == EINTR);
Index: apache13/src/modules/proxy/proxy_http.c
diff -c apache13/src/modules/proxy/proxy_http.c:1.1.1.5 apache13/src/modules/proxy/proxy_http.c:1.9
*** apache13/src/modules/proxy/proxy_http.c:1.1.1.5	Wed Jan 26 21:13:00 2000
--- apache13/src/modules/proxy/proxy_http.c	Wed Jan 26 22:09:14 2000
***************
*** 176,194 ****
      array_header *reqhdrs_arr;
      table *resp_hdrs;
      table_entry *reqhdrs;
-     struct sockaddr_in server;
-     struct in_addr destaddr;
-     struct hostent server_hp;
      BUFF *f;
      char buffer[HUGE_STRING_LEN];
      char portstr[32];
      pool *p = r->pool;
      const long int zero = 0L;
-     int destport = 0;
      char *destportstr = NULL;
      const char *urlptr = NULL;
      const char *datestr;
      struct tbl_do_args tdo;
  
      void *sconf = r->server->module_config;
      proxy_server_conf *conf =
--- 176,192 ----
      array_header *reqhdrs_arr;
      table *resp_hdrs;
      table_entry *reqhdrs;
      BUFF *f;
      char buffer[HUGE_STRING_LEN];
      char portstr[32];
      pool *p = r->pool;
      const long int zero = 0L;
      char *destportstr = NULL;
      const char *urlptr = NULL;
      const char *datestr;
      struct tbl_do_args tdo;
+     struct addrinfo hints, *res, *res0;
+     int error;
  
      void *sconf = r->server->module_config;
      proxy_server_conf *conf =
***************
*** 197,212 ****
      struct nocache_entry *ncent = (struct nocache_entry *) conf->nocaches->elts;
      int nocache = 0;
  
-     memset(&server, '\0', sizeof(server));
-     server.sin_family = AF_INET;
- 
  /* We break the URL into host, port, path-search */
  
      urlptr = strstr(url, "://");
      if (urlptr == NULL)
  	return HTTP_BAD_REQUEST;
      urlptr += 3;
!     destport = DEFAULT_HTTP_PORT;
      strp = strchr(urlptr, '/');
      if (strp == NULL) {
  	desthost = ap_pstrdup(p, urlptr);
--- 195,208 ----
      struct nocache_entry *ncent = (struct nocache_entry *) conf->nocaches->elts;
      int nocache = 0;
  
  /* We break the URL into host, port, path-search */
  
      urlptr = strstr(url, "://");
      if (urlptr == NULL)
  	return HTTP_BAD_REQUEST;
      urlptr += 3;
!     ap_snprintf(portstr, sizeof(portstr), "%d", DEFAULT_HTTP_PORT);
!     destportstr = portstr;
      strp = strchr(urlptr, '/');
      if (strp == NULL) {
  	desthost = ap_pstrdup(p, urlptr);
***************
*** 223,296 ****
      strp2 = strchr(desthost, ':');
      if (strp2 != NULL) {
  	*(strp2++) = '\0';
! 	if (ap_isdigit(*strp2)) {
! 	    destport = atoi(strp2);
  	    destportstr = strp2;
- 	}
      }
  
  /* check if ProxyBlock directive on this host */
!     destaddr.s_addr = ap_inet_addr(desthost);
!     for (i = 0; i < conf->noproxies->nelts; i++) {
! 	if ((npent[i].name != NULL && strstr(desthost, npent[i].name) != NULL)
! 	    || destaddr.s_addr == npent[i].addr.s_addr || npent[i].name[0] == '*')
  	    return ap_proxyerror(r, HTTP_FORBIDDEN,
  				 "Connect to remote machine blocked");
      }
! 
      if (proxyhost != NULL) {
! 	server.sin_port = htons(proxyport);
! 	err = ap_proxy_host2addr(proxyhost, &server_hp);
! 	if (err != NULL)
  	    return DECLINED;	/* try another */
      }
-     else {
- 	server.sin_port = htons(destport);
- 	err = ap_proxy_host2addr(desthost, &server_hp);
- 	if (err != NULL)
- 	    return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
-     }
  
!     sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
!     if (sock == -1) {
! 	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 		    "proxy: error creating socket");
! 	return HTTP_INTERNAL_SERVER_ERROR;
!     }
  
  #ifndef TPF
!     if (conf->recv_buffer_size) {
! 	if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
! 		       (const char *) &conf->recv_buffer_size, sizeof(int))
! 	    == -1) {
! 	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 			 "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
  	}
-     }
  #endif
  
! #ifdef SINIX_D_RESOLVER_BUG
!     {
! 	struct in_addr *ip_addr = (struct in_addr *) *server_hp.h_addr_list;
! 
! 	for (; ip_addr->s_addr != 0; ++ip_addr) {
! 	    memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
! 	    i = ap_proxy_doconnect(sock, &server, r);
! 	    if (i == 0)
! 		break;
! 	}
!     }
! #else
!     j = 0;
!     while (server_hp.h_addr_list[j] != NULL) {
! 	memcpy(&server.sin_addr, server_hp.h_addr_list[j],
! 	       sizeof(struct in_addr));
! 	i = ap_proxy_doconnect(sock, &server, r);
  	if (i == 0)
  	    break;
! 	j++;
      }
- #endif
      if (i == -1) {
  	if (proxyhost != NULL)
  	    return DECLINED;	/* try again another way */
--- 219,306 ----
      strp2 = strchr(desthost, ':');
      if (strp2 != NULL) {
  	*(strp2++) = '\0';
! 	if (ap_isdigit(*strp2))
  	    destportstr = strp2;
      }
  
+     memset(&hints, 0, sizeof(hints));
+     hints.ai_family = PF_UNSPEC;
+     hints.ai_socktype = SOCK_STREAM;
+     hints.ai_protocol = IPPROTO_TCP;
+     error = getaddrinfo(desthost, destportstr, &hints, &res0);
+     if (error) {
+ 	return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
+ 		    gai_strerror(error));	/* give up */
+     }
+ 
+ 
  /* check if ProxyBlock directive on this host */
!     for (res = res0; res; res = res->ai_next) {
! 	struct sockaddr_in *sin;
! #ifdef INET6
! 	struct sockaddr_in6 *sin6;
! #endif
! 	int fail;
! 
! 	fail = 0;
! 	for (i = 0; i < conf->noproxies->nelts; i++) {
! 	    if (npent[i].name != NULL && strstr(desthost, npent[i].name))
! 		fail++;
! 	    if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
! 		fail++;
! 	    switch (res->ai_family) {
! 	    case AF_INET:
! 		sin = (struct sockaddr_in *)res->ai_addr;
! 		if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
! 		    fail++;
! 		break;
! 	    }
! 	}
! 	if (fail) {
! 	    freeaddrinfo(res0);
  	    return ap_proxyerror(r, HTTP_FORBIDDEN,
  				 "Connect to remote machine blocked");
+ 	}
      }
!   
      if (proxyhost != NULL) {
! 	char pbuf[10];
! 
! 	freeaddrinfo(res0);
! 
! 	ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
! 	memset(&hints, 0, sizeof(hints));
! 	hints.ai_family = PF_UNSPEC;
! 	hints.ai_socktype = SOCK_STREAM;
! 	hints.ai_protocol = IPPROTO_TCP;
! 	error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
! 	if (error)
  	    return DECLINED;	/* try another */
      }
  
!     sock = i = -1;
!     for (res = res0; res; res = res->ai_next) {
! 	sock = ap_psocket(p, res->ai_family, res->ai_socktype,
! 	    res->ai_protocol);
! 	if (sock < 0)
! 	    continue;
  
  #ifndef TPF
! 	if (conf->recv_buffer_size) {
! 	    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
! 			   (const char *) &conf->recv_buffer_size, sizeof(int))
! 		== -1) {
! 		ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 			     "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
! 	    }
  	}
  #endif
  
! 	i = ap_proxy_doconnect(sock, res->ai_addr, r);
  	if (i == 0)
  	    break;
! 	close(sock);
      }
      if (i == -1) {
  	if (proxyhost != NULL)
  	    return DECLINED;	/* try again another way */
***************
*** 299,304 ****
--- 309,315 ----
  				"Could not connect to remote machine: ",
  				strerror(errno), NULL));
      }
+     freeaddrinfo(res0);
  
      clear_connection(r->pool, r->headers_in);	/* Strip connection-based headers */
  
***************
*** 308,314 ****
      ap_hard_timeout("proxy send", r);
      ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF,
  	   NULL);
!     if (destportstr != NULL && destport != DEFAULT_HTTP_PORT)
  	ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
      else
  	ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
--- 319,325 ----
      ap_hard_timeout("proxy send", r);
      ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.0" CRLF,
  	   NULL);
!     if (destportstr != NULL && atoi(destportstr) != DEFAULT_HTTP_PORT)
  	ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
      else
  	ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
***************
*** 470,480 ****
  	ap_table_set(resp_hdrs, "URI", proxy_location_reverse_map(r, datestr));
  
  /* check if NoCache directive on this host */
      for (i = 0; i < conf->nocaches->nelts; i++) {
! 	if ((ncent[i].name != NULL && strstr(desthost, ncent[i].name) != NULL)
! 	    || destaddr.s_addr == ncent[i].addr.s_addr || ncent[i].name[0] == '*')
! 	    nocache = 1;
      }
  
      i = ap_proxy_cache_update(c, resp_hdrs, !backasswards, nocache);
      if (i != DECLINED) {
--- 481,506 ----
  	ap_table_set(resp_hdrs, "URI", proxy_location_reverse_map(r, datestr));
  
  /* check if NoCache directive on this host */
+   {
+     struct sockaddr_in *sin;
+ #ifdef INET6
+     struct sockaddr_in6 *sin6;
+ #endif
+ 
      for (i = 0; i < conf->nocaches->nelts; i++) {
! 	if (ncent[i].name != NULL && strstr(desthost, ncent[i].name))
! 	    nocache++;
! 	if (ncent[i].name != NULL && strcmp(ncent[i].name, "*") == 0)
! 	    nocache++;
! 	switch (res->ai_addr->sa_family) {
! 	case AF_INET:
! 	    sin = (struct sockaddr_in *)res->ai_addr;
! 	    if (sin->sin_addr.s_addr == ncent[i].addr.s_addr) {
! 		nocache++;
! 	    }
! 	}
      }
+   }
  
      i = ap_proxy_cache_update(c, resp_hdrs, !backasswards, nocache);
      if (i != DECLINED) {
Index: apache13/src/modules/proxy/proxy_util.c
diff -c apache13/src/modules/proxy/proxy_util.c:1.1.1.5 apache13/src/modules/proxy/proxy_util.c:1.11
*** apache13/src/modules/proxy/proxy_util.c:1.1.1.5	Wed Jan 26 21:13:04 2000
--- apache13/src/modules/proxy/proxy_util.c	Mon Feb  7 12:48:25 2000
***************
*** 63,68 ****
--- 63,69 ----
  #include "http_log.h"
  #include "util_uri.h"
  #include "util_date.h"	/* get ap_checkmask() decl. */
+ #include "sa_len.h"
  
  static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
  static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
***************
*** 1235,1256 ****
      return host != NULL && strstr(host, This->name) != NULL;
  }
  
! int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r)
  {
      int i;
  
      ap_hard_timeout("proxy connect", r);
      do {
! 	i = connect(sock, (struct sockaddr *) addr, sizeof(struct sockaddr_in));
  #if defined(WIN32) || defined(NETWARE)
  	if (i == SOCKET_ERROR)
  	    errno = WSAGetLastError();
  #endif /* WIN32 */
      } while (i == -1 && errno == EINTR);
      if (i == -1) {
  	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 		     "proxy connect to %s port %d failed",
! 		     inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
      }
      ap_kill_timeout(r);
  
--- 1236,1280 ----
      return host != NULL && strstr(host, This->name) != NULL;
  }
  
! int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r)
  {
      int i;
+     int salen;
+     char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+ #ifdef NI_WITHSCOPEID
+     const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
+ #else
+     const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
+ #endif
  
      ap_hard_timeout("proxy connect", r);
+ #ifdef HAVE_SOCKADDR_LEN
+     salen = addr->sa_len;
+ #else
+     switch (addr->sa_family) {
+     case AF_INET6:
+ 	salen = sizeof(struct sockaddr_in6);
+ 	break;
+     default:
+ 	salen = sizeof(struct sockaddr_in);
+ 	break;
+     }
+ #endif
      do {
! 	i = connect(sock,  addr, salen);
  #if defined(WIN32) || defined(NETWARE)
  	if (i == SOCKET_ERROR)
  	    errno = WSAGetLastError();
  #endif /* WIN32 */
      } while (i == -1 && errno == EINTR);
      if (i == -1) {
+ 	if (getnameinfo(addr, salen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
+ 		niflags) != 0) {
+ 	    strcpy(hbuf, "?");
+ 	    strcpy(pbuf, "?");
+ 	}
  	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
! 		     "proxy connect to %s port %s failed", hbuf, pbuf);
      }
      ap_kill_timeout(r);
  
Index: apache13/src/modules/standard/mod_access.c
diff -c apache13/src/modules/standard/mod_access.c:1.1.1.3 apache13/src/modules/standard/mod_access.c:1.14
*** apache13/src/modules/standard/mod_access.c:1.1.1.3	Tue Aug 24 13:20:41 1999
--- apache13/src/modules/standard/mod_access.c	Wed Jan 26 21:38:17 2000
***************
*** 73,79 ****
      T_ALL,
      T_IP,
      T_HOST,
!     T_FAIL
  };
  
  typedef struct {
--- 73,82 ----
      T_ALL,
      T_IP,
      T_HOST,
!     T_FAIL,
! #ifdef INET6
!     T_IP6,
! #endif
  };
  
  typedef struct {
***************
*** 81,89 ****
      union {
  	char *from;
  	struct {
! 	    unsigned long net;
! 	    unsigned long mask;
  	} ip;
      } x;
      enum allowdeny_type type;
  } allowdeny;
--- 84,98 ----
      union {
  	char *from;
  	struct {
! 	    struct in_addr net;
! 	    struct in_addr mask;
  	} ip;
+ #ifdef INET6
+ 	struct {
+ 	    struct in6_addr net6;
+ 	    struct in6_addr mask6;
+ 	} ip6;
+ #endif
      } x;
      enum allowdeny_type type;
  } allowdeny;
***************
*** 166,255 ****
  
      }
      else if ((s = strchr(where, '/'))) {
! 	unsigned long mask;
  
! 	a->type = T_IP;
  	/* trample on where, we won't be using it any more */
  	*s++ = '\0';
  
! 	if (!is_ip(where)
! 	    || (a->x.ip.net = ap_inet_addr(where)) == INADDR_NONE) {
  	    a->type = T_FAIL;
  	    return "syntax error in network portion of network/netmask";
  	}
  
! 	/* is_ip just tests if it matches [\d.]+ */
! 	if (!is_ip(s)) {
  	    a->type = T_FAIL;
! 	    return "syntax error in mask portion of network/netmask";
  	}
! 	/* is it in /a.b.c.d form? */
! 	if (strchr(s, '.')) {
! 	    mask = ap_inet_addr(s);
! 	    if (mask == INADDR_NONE) {
  		a->type = T_FAIL;
  		return "syntax error in mask portion of network/netmask";
- 	    }
- 	}
- 	else {
- 	    /* assume it's in /nnn form */
- 	    mask = atoi(s);
- 	    if (mask > 32 || mask <= 0) {
- 		a->type = T_FAIL;
- 		return "invalid mask in network/netmask";
  	    }
! 	    mask = 0xFFFFFFFFUL << (32 - mask);
! 	    mask = htonl(mask);
! 	}
! 	a->x.ip.mask = mask;
!         a->x.ip.net  = (a->x.ip.net & mask);   /* pjr - This fixes PR 4770 */
!     }
!     else if (ap_isdigit(*where) && is_ip(where)) {
! 	/* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
! 	int shift;
! 	char *t;
! 	int octet;
! 
! 	a->type = T_IP;
! 	/* parse components */
! 	s = where;
! 	a->x.ip.net = 0;
! 	a->x.ip.mask = 0;
! 	shift = 24;
! 	while (*s) {
! 	    t = s;
! 	    if (!ap_isdigit(*t)) {
  		a->type = T_FAIL;
! 		return "invalid ip address";
  	    }
! 	    while (ap_isdigit(*t)) {
! 		++t;
! 	    }
! 	    if (*t == '.') {
! 		*t++ = 0;
! 	    }
! 	    else if (*t) {
  		a->type = T_FAIL;
! 		return "invalid ip address";
  	    }
! 	    if (shift < 0) {
! 		return "invalid ip address, only 4 octets allowed";
  	    }
! 	    octet = atoi(s);
! 	    if (octet < 0 || octet > 255) {
! 		a->type = T_FAIL;
! 		return "each octet must be between 0 and 255 inclusive";
  	    }
- 	    a->x.ip.net |= octet << shift;
- 	    a->x.ip.mask |= 0xFFUL << shift;
- 	    s = t;
- 	    shift -= 8;
  	}
- 	a->x.ip.net = ntohl(a->x.ip.net);
- 	a->x.ip.mask = ntohl(a->x.ip.mask);
      }
      else {
! 	a->type = T_HOST;
      }
  
      return NULL;
--- 175,399 ----
  
      }
      else if ((s = strchr(where, '/'))) {
! 	struct addrinfo hints, *resnet, *resmask;
! 	struct sockaddr_storage net, mask;
! 	int error;
! 	char *p;
! 	int justdigits;
  
! 	a->type = T_FAIL;	/*just in case*/
  	/* trample on where, we won't be using it any more */
  	*s++ = '\0';
+ 
+ 	justdigits = 0;
+ 	for (p = s; *p; p++) {
+ 	    if (!isdigit(*p))
+ 		break;
+ 	}
+ 	if (!*p)
+ 	    justdigits++;
  
! 	memset(&hints, 0, sizeof(hints));
! 	hints.ai_family = PF_UNSPEC;
! #ifdef AI_NUMERICHOST
! 	hints.ai_flags = AI_NUMERICHOST;	/*don't resolve*/
! #endif
! 	resnet = NULL;
! 	error = getaddrinfo(where, NULL, &hints, &resnet);
! 	if (error || !resnet) {
! 	    if (resnet)
! 		freeaddrinfo(resnet);
  	    a->type = T_FAIL;
  	    return "syntax error in network portion of network/netmask";
  	}
+ 	if (resnet->ai_next) {
+ 	    freeaddrinfo(resnet);
+ 	    a->type = T_FAIL;
+ 	    return "network/netmask resolved to multiple addresses";
+ 	}
+ 	memcpy(&net, resnet->ai_addr, resnet->ai_addrlen);
+ 	freeaddrinfo(resnet);
  
! 	switch (net.ss_family) {
! 	case AF_INET:
! 	    a->type = T_IP;
! 	    a->x.ip.net.s_addr = ((struct sockaddr_in *)&net)->sin_addr.s_addr;
! 	    break;
! #ifdef INET6
! 	case AF_INET6:
! 	    a->type = T_IP6;
! 	    memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&net)->sin6_addr,
! 		sizeof(a->x.ip6.net6));
! 	    break;
! #endif
! 	default:
  	    a->type = T_FAIL;
! 	    return "unknown address family for network";
  	}
! 
! 	if (!justdigits) {
! 	    memset(&hints, 0, sizeof(hints));
! 	    hints.ai_family = PF_UNSPEC;
! 	    hints.ai_flags = AI_NUMERICHOST;	/*don't resolve*/
! 	    resmask = NULL;
! 	    error = getaddrinfo(s, NULL, &hints, &resmask);
! 	    if (error || !resmask) {
! 		if (resmask)
! 		    freeaddrinfo(resmask);
  		a->type = T_FAIL;
  		return "syntax error in mask portion of network/netmask";
  	    }
! 	    if (resmask->ai_next) {
! 		freeaddrinfo(resmask);
  		a->type = T_FAIL;
! 		return "network/netmask resolved to multiple addresses";
  	    }
! 	    memcpy(&mask, resmask->ai_addr, resmask->ai_addrlen);
! 	    freeaddrinfo(resmask);
! 
! 	    if (net.ss_family != mask.ss_family) {
  		a->type = T_FAIL;
! 		return "network/netmask resolved to different address family";
  	    }
! 
! 	    switch (a->type) {
! 	    case T_IP:
! 		a->x.ip.mask.s_addr =
! 		    ((struct sockaddr_in *)&mask)->sin_addr.s_addr;
! 		break;
! #ifdef INET6
! 	    case T_IP6:
! 		memcpy(&a->x.ip6.mask6,
! 		    &((struct sockaddr_in6 *)&mask)->sin6_addr,
! 		    sizeof(a->x.ip6.mask6));
! 		break;
! #endif
  	    }
! 	} else {
! 	    int mask;
! 	    mask = atoi(s);
! 	    switch (a->type) {
! 	    case T_IP:
! 		if (mask < 0 || 32 < mask) {
! 		    a->type = T_FAIL;
! 		    return "netmask out of range";
! 		}
! 		a->x.ip.mask.s_addr = htonl(0xFFFFFFFFUL << (32 - mask));
! 		break;
! #ifdef INET6
! 	    case T_IP6:
! 	      {
! 		int i;
! 		if (mask < 0 || 128 < mask) {
! 		    a->type = T_FAIL;
! 		    return "netmask out of range";
! 		}
! 		for (i = 0; i < mask / 8; i++) {
! 		    a->x.ip6.mask6.s6_addr[i] = 0xff;
! 		}
! 		if (mask % 8)
! 		    a->x.ip6.mask6.s6_addr[i] = 0xff << (8 - (mask % 8));
! 		break;
! 	      }
! #endif
  	    }
  	}
      }
      else {
! 	struct addrinfo hints, *res;
! 	struct sockaddr_storage ss;
! 	int error;
! 
! 	a->type = T_FAIL;	/*just in case*/
! 
! 	/* First, try using the old apache code to match */
! 	/* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
! 	if (ap_isdigit(*where) && is_ip(where)) {
! 	    int shift;
! 	    char *t;
! 	    int octet;
! 
! 	    a->type = T_IP;
! 	    /* parse components */
! 	    s = where;
! 	    a->x.ip.net.s_addr = 0;
! 	    a->x.ip.mask.s_addr = 0;
! 	    shift = 24;
! 	    while (*s) {
! 		t = s;
! 		if (!ap_isdigit(*t)) {
! 		    a->type = T_FAIL;
! 		    return "invalid ip address";
! 		}
! 		while (ap_isdigit(*t)) {
! 		    ++t;
! 		}
! 		if (*t == '.') {
! 		    *t++ = 0;
! 		}
! 		else if (*t) {
! 		    a->type = T_FAIL;
! 		    return "invalid ip address";
! 		}
! 		if (shift < 0) {
! 		    return "invalid ip address, only 4 octets allowed";
! 		}
! 		octet = atoi(s);
! 		if (octet < 0 || octet > 255) {
! 		    a->type = T_FAIL;
! 		    return "each octet must be between 0 and 255 inclusive";
! 		}
! 		a->x.ip.net.s_addr |= octet << shift;
! 		a->x.ip.mask.s_addr |= 0xFFUL << shift;
! 		s = t;
! 		shift -= 8;
! 	    }
! 	    a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
! 	    a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
! 
! 	    return NULL;
! 	}
! 
! 	/* IPv4/v6 numeric address */
! 	memset(&hints, 0, sizeof(hints));
! 	hints.ai_family = PF_UNSPEC;
! #ifdef AI_NUMERICHOST
! 	hints.ai_flags = AI_NUMERICHOST;	/*don't resolve*/
! #endif
! 	res = NULL;
! 	error = getaddrinfo(where, NULL, &hints, &res);
! 	if (error || !res) {
! 	    if (res)
! 		freeaddrinfo(res);
! 	    a->type = T_HOST;
! 	    return NULL;
! 	}
! 	if (res->ai_next) {
! 	    freeaddrinfo(res);
! 	    a->type = T_FAIL;
! 	    return "network/netmask resolved to multiple addresses";
! 	}
! 	memcpy(&ss, res->ai_addr, res->ai_addrlen);
! 	freeaddrinfo(res);
! 
! 	switch (ss.ss_family) {
! 	case AF_INET:
! 	    a->type = T_IP;
! 	    a->x.ip.net.s_addr = ((struct sockaddr_in *)&ss)->sin_addr.s_addr;
! 	    memset(&a->x.ip.mask, 0xff, sizeof(a->x.ip.mask));
! 	    break;
! #ifdef INET6
! 	case AF_INET6:
! 	    a->type = T_IP6;
! 	    memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&ss)->sin6_addr,
! 		sizeof(a->x.ip6.net6));
! 	    memset(&a->x.ip6.mask6, 0xff, sizeof(a->x.ip6.mask6));
! 	    break;
! #endif
! 	default:
! 	    a->type = T_FAIL;
! 	    return "unknown address family for network";
! 	}
      }
  
      return NULL;
***************
*** 314,325 ****
  	    return 1;
  
  	case T_IP:
! 	    if (ap[i].x.ip.net != INADDR_NONE
! 		&& (r->connection->remote_addr.sin_addr.s_addr
! 		    & ap[i].x.ip.mask) == ap[i].x.ip.net) {
! 		return 1;
  	    }
  	    break;
  
  	case T_HOST:
  	    if (!gothost) {
--- 458,520 ----
  	    return 1;
  
  	case T_IP:
! 	    if (ap[i].x.ip.net.s_addr == INADDR_NONE)
! 		break;
! 	    switch (r->connection->remote_addr.ss_family) {
! 	    case AF_INET:
! 		if ((((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr
! 			& ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
! 		    return 1;
! 		}
! 		break;
! #ifdef INET6
! 	    case AF_INET6:
! 		if (!IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr))	/*XXX*/
! 		    break;
! 		if ((*(ap_uint32_t *)&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr.s6_addr[12]
! 			& ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
! 		    return 1;
! 		}
! 		break;
! #endif
! 	    }
! 	    break;
! 
! #ifdef INET6
! 	case T_IP6:
! 	  {
! 	    struct in6_addr masked;
! 	    int j;
! 	    if (IN6_IS_ADDR_UNSPECIFIED(&ap[i].x.ip6.net6))
! 		break;
! 	    switch (r->connection->remote_addr.ss_family) {
! 	    case AF_INET:
! 		if (!IN6_IS_ADDR_V4MAPPED(&ap[i].x.ip6.net6))	/*XXX*/
! 		    break;
! 		memset(&masked, 0, sizeof(masked));
! 		masked.s6_addr[10] = masked.s6_addr[11] = 0xff;
! 		memcpy(&masked.s6_addr[12],
! 		    &((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr,
! 		    sizeof(struct sockaddr_in));
! 		for (j = 0; j < sizeof(struct in6_addr); j++)
! 			masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
! 		if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
! 		    return 1;
! 		break;
! 	    case AF_INET6:
! 		memset(&masked, 0, sizeof(masked));
! 		memcpy(&masked,
! 		    &((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr,
! 		    sizeof(masked));
! 		for (j = 0; j < sizeof(struct in6_addr); j++)
! 		    masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
! 		if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
! 		    return 1;
! 		break;
  	    }
  	    break;
+ 	  }
+ #endif
  
  	case T_HOST:
  	    if (!gothost) {
Index: apache13/src/modules/standard/mod_unique_id.c
diff -c apache13/src/modules/standard/mod_unique_id.c:1.1.1.3 apache13/src/modules/standard/mod_unique_id.c:1.7
*** apache13/src/modules/standard/mod_unique_id.c:1.1.1.3	Tue Aug 24 13:20:44 1999
--- apache13/src/modules/standard/mod_unique_id.c	Mon Nov 15 15:42:36 1999
***************
*** 66,79 ****
  #include "http_config.h"
  #include "http_log.h"
  #include "multithread.h"
  
  #ifdef MULTITHREAD
  #error sorry this module does not support multithreaded servers yet
  #endif
  
  typedef struct {
      unsigned int stamp;
!     unsigned int in_addr;
      unsigned int pid;
      unsigned short counter;
  } unique_id_rec;
--- 66,91 ----
  #include "http_config.h"
  #include "http_log.h"
  #include "multithread.h"
+ #include "sa_len.h"
  
  #ifdef MULTITHREAD
  #error sorry this module does not support multithreaded servers yet
  #endif
  
+ /*#define SHORT_UNIQUE_ID*/
+ 
  typedef struct {
      unsigned int stamp;
!     union {
! 	struct in_addr in;
! #ifdef INET6
! # ifdef SHORT_UNIQUE_ID
! 	ap_uint32_t in6;
! # else
! 	struct in6_addr in6;
! # endif
! #endif
!     } addr;
      unsigned int pid;
      unsigned short counter;
  } unique_id_rec;
***************
*** 141,147 ****
   * htonl/ntohl. Well, this shouldn't be a problem till year 2106.
   */
  
! static unsigned global_in_addr;
  
  static APACHE_TLS unique_id_rec cur_unique_id;
  
--- 153,159 ----
   * htonl/ntohl. Well, this shouldn't be a problem till year 2106.
   */
  
! static struct sockaddr_storage global_addr;
  
  static APACHE_TLS unique_id_rec cur_unique_id;
  
***************
*** 161,167 ****
  #define MAXHOSTNAMELEN 256
  #endif
      char str[MAXHOSTNAMELEN + 1];
!     struct hostent *hent;
  #ifndef NO_GETTIMEOFDAY
      struct timeval tv;
  #endif
--- 173,180 ----
  #define MAXHOSTNAMELEN 256
  #endif
      char str[MAXHOSTNAMELEN + 1];
!     struct addrinfo hints, *res, *res0;
!     int error;
  #ifndef NO_GETTIMEOFDAY
      struct timeval tv;
  #endif
***************
*** 171,178 ****
       */
      unique_id_rec_offset[0] = XtOffsetOf(unique_id_rec, stamp);
      unique_id_rec_size[0] = sizeof(cur_unique_id.stamp);
!     unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, in_addr);
!     unique_id_rec_size[1] = sizeof(cur_unique_id.in_addr);
      unique_id_rec_offset[2] = XtOffsetOf(unique_id_rec, pid);
      unique_id_rec_size[2] = sizeof(cur_unique_id.pid);
      unique_id_rec_offset[3] = XtOffsetOf(unique_id_rec, counter);
--- 184,191 ----
       */
      unique_id_rec_offset[0] = XtOffsetOf(unique_id_rec, stamp);
      unique_id_rec_size[0] = sizeof(cur_unique_id.stamp);
!     unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, addr);
!     unique_id_rec_size[1] = sizeof(cur_unique_id.addr);
      unique_id_rec_offset[2] = XtOffsetOf(unique_id_rec, pid);
      unique_id_rec_size[2] = sizeof(cur_unique_id.pid);
      unique_id_rec_offset[3] = XtOffsetOf(unique_id_rec, counter);
***************
*** 197,213 ****
      }
      str[sizeof(str) - 1] = '\0';
  
!     if ((hent = gethostbyname(str)) == NULL) {
          ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
!                     "mod_unique_id: unable to gethostbyname(\"%s\")", str);
          exit(1);
      }
  
!     global_in_addr = ((struct in_addr *) hent->h_addr_list[0])->s_addr;
  
      ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, s,
!                 "mod_unique_id: using ip addr %s",
!                 inet_ntoa(*(struct in_addr *) hent->h_addr_list[0]));
  
      /*
       * If the server is pummelled with restart requests we could possibly end
--- 210,253 ----
      }
      str[sizeof(str) - 1] = '\0';
  
!     memset(&hints, 0, sizeof(hints));
!     hints.ai_family = PF_UNSPEC;
!     error = getaddrinfo(str, NULL, &hints, &res0);
!     if (error) {
          ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
!                     "mod_unique_id: getaddrinfo failed for \"%s\" (%s)", str,
! 		    gai_strerror(error));
          exit(1);
      }
  
!     error = 1;
!     for (res = res0; res; res = res->ai_next) {
! 	switch (res->ai_family) {
! 	case AF_INET:
! #ifdef INET6
! 	case AF_INET6:
! #endif
! 	    memcpy(&global_addr, res->ai_addr, res->ai_addrlen);
! 	    error = 0;
! 	    break;
! 	}
!     }
!     freeaddrinfo(res0);
!     if (error) {
!         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
!                     "mod_unique_id: no known AF found for \"%s\" (%s)", str);
!         exit(1);
!     }
  
+     getnameinfo((struct sockaddr *)&global_addr,
+ #ifndef SIN6_LEN
+ 	SA_LEN((struct sockaddr *)&global_addr),
+ #else
+ 	global_addr.ss_len,
+ #endif
+ 	str, sizeof(str), NULL, 0, NI_NUMERICHOST);
      ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, s,
!                 "mod_unique_id: using ip addr %s", str);
  
      /*
       * If the server is pummelled with restart requests we could possibly end
***************
*** 266,272 ****
                      "oh no! pids are greater than 32-bits!  I'm broken!");
      }
  
!     cur_unique_id.in_addr = global_in_addr;
  
      /*
       * If we use 0 as the initial counter we have a little less protection
--- 306,328 ----
                      "oh no! pids are greater than 32-bits!  I'm broken!");
      }
  
!     memset(&cur_unique_id.addr, 0, sizeof(cur_unique_id.addr));
!     switch (global_addr.ss_family) {
!     case AF_INET:
! 	cur_unique_id.addr.in = ((struct sockaddr_in *)&global_addr)->sin_addr;
! 	break;
! #ifdef INET6
!     case AF_INET6:
! #ifdef SHORT_UNIQUE_ID
! 	cur_unique_id.addr.in6 =
! 	    ((struct sockaddr_in6 *)&global_addr)->sin6_addr.s6_addr32[3];
! #else
! 	cur_unique_id.addr.in6 =
! 	    ((struct sockaddr_in6 *)&global_addr)->sin6_addr;
! #endif
! 	break;
! #endif
!     }
  
      /*
       * If we use 0 as the initial counter we have a little less protection
Index: apache13/src/support/ab.c
diff -c apache13/src/support/ab.c:1.1.1.5 apache13/src/support/ab.c:1.9
*** apache13/src/support/ab.c:1.1.1.5	Wed Jan 26 21:13:13 2000
--- apache13/src/support/ab.c	Wed Jan 26 21:38:18 2000
***************
*** 137,142 ****
--- 137,144 ----
  #include <sys/uio.h>
  #endif
  
+ #include "sa_len.h"
+ 
  #endif				/* NO_APACHE_INCLUDES */
  /* ------------------- DEFINITIONS -------------------------- */
  
***************
*** 192,198 ****
       auth[1024],		/* optional (basic/uuencoded)
  				 * authentification */
       hdrs[4096];		/* optional arbitrary headers */
! int port = 80;			/* port number */
  
  int use_html = 0;		/* use html in the report */
  char *tablestring;
--- 194,200 ----
       auth[1024],		/* optional (basic/uuencoded)
  				 * authentification */
       hdrs[4096];		/* optional arbitrary headers */
! char *port = "80";		/* port number */
  
  int use_html = 0;		/* use html in the report */
  char *tablestring;
***************
*** 224,230 ****
  struct data *stats;		/* date for each request */
  
  fd_set readbits, writebits;	/* bits for select */
! struct sockaddr_in server;	/* server addr structure */
  
  #ifndef BEOS
  #define ab_close(s) close(s)
--- 226,232 ----
  struct data *stats;		/* date for each request */
  
  fd_set readbits, writebits;	/* bits for select */
! struct sockaddr_storage server;      /* server addr structure */
  
  #ifndef BEOS
  #define ab_close(s) close(s)
***************
*** 329,335 ****
      printf("\r                                                                           \r");
      printf("Server Software:        %s\n", servername);
      printf("Server Hostname:        %s\n", hostname);
!     printf("Server Port:            %d\n", port);
      printf("\n");
      printf("Document Path:          %s\n", path);
      printf("Document Length:        %d bytes\n", doclen);
--- 331,337 ----
      printf("\r                                                                           \r");
      printf("Server Software:        %s\n", servername);
      printf("Server Hostname:        %s\n", hostname);
!     printf("Server Port:            %s\n", port);
      printf("\n");
      printf("Document Path:          %s\n", path);
      printf("Document Length:        %d bytes\n", doclen);
***************
*** 528,541 ****
      c->cbx = 0;
      c->gotheader = 0;
  
!     c->fd = socket(AF_INET, SOCK_STREAM, 0);
      if (c->fd < 0)
  	err("socket");
  
      nonblock(c->fd);
      gettimeofday(&c->start, 0);
  
!     if (connect(c->fd, (struct sockaddr *) & server, sizeof(server)) < 0) {
  	if (errno == EINPROGRESS) {
  	    c->state = STATE_CONNECTING;
  	    FD_SET(c->fd, &writebits);
--- 530,548 ----
      c->cbx = 0;
      c->gotheader = 0;
  
!     c->fd = socket(server.ss_family, SOCK_STREAM, 0);
      if (c->fd < 0)
  	err("socket");
  
      nonblock(c->fd);
      gettimeofday(&c->start, 0);
  
! #ifndef SIN6_LEN
!     if (connect(c->fd, (struct sockaddr *) & server, SA_LEN((struct sockaddr*)&server)) < 0)
! #else
!     if (connect(c->fd, (struct sockaddr *) &server, server.ss_len) < 0)
! #endif
!     {
  	if (errno == EINPROGRESS) {
  	    c->state = STATE_CONNECTING;
  	    FD_SET(c->fd, &writebits);
***************
*** 769,782 ****
      }
  
      {
! 	/* get server information */
! 	struct hostent *he;
! 	he = gethostbyname(hostname);
! 	if (!he)
! 	    err("bad hostname");
! 	server.sin_family = he->h_addrtype;
! 	server.sin_port = htons(port);
! 	server.sin_addr.s_addr = ((unsigned long *) (he->h_addr_list[0]))[0];
      }
  
      con = malloc(concurrency * sizeof(struct connection));
--- 776,792 ----
      }
  
      {
!         /* get server information */
! 	struct addrinfo hints, *res;
! 	int error;
! 
! 	memset(&hints, 0, sizeof(hints));
! 	hints.ai_family = AF_UNSPEC;
! 	error = getaddrinfo(hostname, port, &hints, &res);
! 	if (error)
! 		err("bad hostname");
! 	memcpy(&server, res->ai_addr, res->ai_addrlen);
! 	freeaddrinfo(res);
      }
  
      con = malloc(concurrency * sizeof(struct connection));
***************
*** 951,957 ****
      *cp = '\0';
      strcpy(hostname, h);
      if (p != NULL)
! 	port = atoi(p);
      return 0;
  }
  
--- 961,967 ----
      *cp = '\0';
      strcpy(hostname, h);
      if (p != NULL)
!         port = strdup(p);
      return 0;
  }
  
***************
*** 1128,1130 ****
--- 1138,1144 ----
  
      exit(0);
  }
+ 
+ #ifdef NEED_GETADDRINFO
+ #include "../main/getaddrinfo.c"
+ #endif
Index: apache13/src/support/logresolve.c
diff -c apache13/src/support/logresolve.c:1.1.1.2 apache13/src/support/logresolve.c:1.10
*** apache13/src/support/logresolve.c:1.1.1.2	Wed Jan 26 21:13:13 2000
--- apache13/src/support/logresolve.c	Wed Jan 26 21:38:18 2000
***************
*** 48,54 ****
  #include <arpa/inet.h>
  #endif
  
! static void cgethost(struct in_addr ipnum, char *string, int check);
  static int getline(char *s, int n);
  static void stats(FILE *output);
  
--- 48,56 ----
  #include <arpa/inet.h>
  #endif
  
! #include "sa_len.h"
! 
! static void cgethost(struct sockaddr *sa, char *string, int check);
  static int getline(char *s, int n);
  static void stats(FILE *output);
  
***************
*** 85,91 ****
   */
  
  struct nsrec {
!     struct in_addr ipnum;
      char *hostname;
      int noname;
      struct nsrec *next;
--- 87,93 ----
   */
  
  struct nsrec {
!     struct sockaddr_storage addr;
      char *hostname;
      int noname;
      struct nsrec *next;
***************
*** 116,132 ****
   * IP numbers with their IP number as hostname, setting noname flag
   */
  
! static void cgethost (struct in_addr ipnum, char *string, int check)
  {
      struct nsrec **current, *new;
-     struct hostent *hostdata;
      char *name;
  
!     current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) +
! 			 (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)];
  
-     while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr)
  	current = &(*current)->next;
  
      if (*current == NULL) {
  	cachesize++;
--- 118,165 ----
   * IP numbers with their IP number as hostname, setting noname flag
   */
  
! static void cgethost (struct sockaddr *sa, char *string, int check)
  {
+     ap_uint32_t hashval;
+     struct sockaddr_in *sin;
+ #ifdef INET6
+     struct sockaddr_in6 *sin6;
+ #endif
      struct nsrec **current, *new;
      char *name;
+     char hostnamebuf[MAXHOSTNAMELEN];
+ 
+     switch (sa->sa_family) {
+     case AF_INET:
+ 	hashval = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
+ 	break;
+ #ifdef INET6
+     case AF_INET6:
+ 	hashval = *(ap_uint32_t *)&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12];
+ 	break;
+ #endif
+     default:
+ 	hashval = 0;
+ 	break;
+     }
+ 
+     current = &nscache[((hashval + (hashval >> 8) +
+ 			 (hashval >> 16) + (hashval >> 24)) % BUCKETS)];
  
!     while (*current) {
! #ifndef SIN6_LEN
! 	if (SA_LEN(sa) == SA_LEN((struct sockaddr *)&(*current)->addr)
! 	 && memcmp(sa, &(*current)->addr, SA_LEN(sa)) == 0)
! #else
! 	if (sa->sa_len == (*current)->addr.ss_len
! 	 && memcmp(sa, &(*current)->addr, sa->sa_len) == 0)
! #endif
! 	{
! 	    break;
! 	}
  
  	current = &(*current)->next;
+     }
  
      if (*current == NULL) {
  	cachesize++;
***************
*** 139,183 ****
  	*current = new;
  	new->next = NULL;
  
! 	new->ipnum = ipnum;
  
! 	hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr),
! 				 AF_INET);
! 	if (hostdata == NULL) {
! 	    if (h_errno > MAX_ERR)
! 		errors[UNKNOWN_ERR]++;
! 	    else
! 		errors[h_errno]++;
! 	    new->noname = h_errno;
! 	    name = strdup(inet_ntoa(ipnum));
! 	}
! 	else {
! 	    new->noname = 0;
! 	    name = strdup(hostdata->h_name);
! 	    if (check) {
! 		if (name == NULL) {
! 		    perror("strdup");
! 		    fprintf(stderr, "Insufficient memory\n");
! 		    exit(1);
! 		}
! 		hostdata = gethostbyname(name);
! 		if (hostdata != NULL) {
! 		    char **hptr;
! 
! 		    for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++)
! 			if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr)
! 			    break;
! 		    if (*hptr == NULL)
! 			hostdata = NULL;
! 		}
! 		if (hostdata == NULL) {
! 		    fprintf(stderr, "Bad host: %s != %s\n", name,
! 			    inet_ntoa(ipnum));
! 		    new->noname = NO_REVERSE;
! 		    free(name);
! 		    name = strdup(inet_ntoa(ipnum));
! 		    errors[NO_REVERSE]++;
  		}
  	    }
  	}
  	new->hostname = name;
--- 172,226 ----
  	*current = new;
  	new->next = NULL;
  
! #ifndef SIN6_LEN
! 	memcpy(&new->addr, sa, SA_LEN(sa));
! #else
! 	memcpy(&new->addr, sa, sa->sa_len);
! #endif
  
! 	new->noname = getnameinfo(sa,
! #ifndef SIN6_LEN
! 		SA_LEN(sa),
! #else
! 		sa->sa_len,
! #endif
! 		    hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0);
! 	name = strdup(hostnamebuf);
! 	if (check) {
! 	    struct addrinfo hints, *res;
! 	    int error;
! 	    memset(&hints, 0, sizeof(hints));
! 	    hints.ai_family = AF_UNSPEC;
! 	    error = getaddrinfo(hostnamebuf, NULL, &hints, &res);
! 	    if (!error) {
! 		while (res) {
! #ifndef SIN6_LEN
! 		    if (SA_LEN(sa) == res->ai_addrlen
! 		     && memcmp(sa, res->ai_addr, SA_LEN(sa)) == 0)
! #else
! 		    if (sa->sa_len == res->ai_addrlen
! 		     && memcmp(sa, res->ai_addr, sa->sa_len) == 0)
! #endif
! 		    {
! 			break;
! 		    }
! 		    res = res->ai_next;
  		}
+ 		if (!res)
+ 		    error++;
+ 	    }
+ 	    if (error) {
+ 		getnameinfo(sa,
+ #ifndef SIN6_LEN
+ 		    SA_LEN(sa),
+ #else
+ 		    sa->sa_len,
+ #endif
+ 		    hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
+ 		fprintf(stderr, "Bad host: %s != %s\n", name, hostnamebuf);
+ 		new->noname = NO_REVERSE;
+ 		free(name);
+ 		name = strdup(hostnamebuf);
  	    }
  	}
  	new->hostname = name;
***************
*** 205,210 ****
--- 248,254 ----
      char *ipstring;
      struct nsrec *current;
      char *errstring[MAX_ERR + 3];
+     char hostnamebuf[MAXHOSTNAMELEN];
  
      for (i = 0; i < MAX_ERR + 3; i++)
  	errstring[i] = "Unknown error";
***************
*** 236,242 ****
  
      for (i = 0; i < BUCKETS; i++)
  	for (current = nscache[i]; current != NULL; current = current->next) {
! 	    ipstring = inet_ntoa(current->ipnum);
  	    if (current->noname == 0)
  		fprintf(output, "  %3d  %15s - %s\n", i, ipstring,
  			current->hostname);
--- 280,293 ----
  
      for (i = 0; i < BUCKETS; i++)
  	for (current = nscache[i]; current != NULL; current = current->next) {
! 	    getnameinfo((struct sockaddr *)&current->addr,
! #ifndef SIN6_LEN
! 		    SA_LEN((struct sockaddr *)&current->addr),
! #else
! 		    current->addr.ss_len,
! #endif
! 		    hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
! 	    ipstring = hostnamebuf;
  	    if (current->noname == 0)
  		fprintf(output, "  %3d  %15s - %s\n", i, ipstring,
  			current->hostname);
***************
*** 270,278 ****
  
  int main (int argc, char *argv[])
  {
-     struct in_addr ipnum;
      char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
      int i, check;
  
      check = 0;
      statfile = NULL;
--- 321,330 ----
  
  int main (int argc, char *argv[])
  {
      char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
      int i, check;
+     struct addrinfo hints, *res;
+     int error;
  
      check = 0;
      statfile = NULL;
***************
*** 311,318 ****
  	bar = strchr(line, ' ');
  	if (bar != NULL)
  	    *bar = '\0';
! 	ipnum.s_addr = inet_addr(line);
! 	if (ipnum.s_addr == 0xffffffffu) {
  	    if (bar != NULL)
  		*bar = ' ';
  	    puts(line);
--- 363,372 ----
  	bar = strchr(line, ' ');
  	if (bar != NULL)
  	    *bar = '\0';
! 	memset(&hints, 0, sizeof(hints));
! 	hints.ai_family = AF_UNSPEC;
! 	error = getaddrinfo(line, NULL, &hints, &res);
! 	if (error) {
  	    if (bar != NULL)
  		*bar = ' ';
  	    puts(line);
***************
*** 322,332 ****
  
  	resolves++;
  
! 	cgethost(ipnum, hoststring, check);
  	if (bar != NULL)
  	    printf("%s %s\n", hoststring, bar + 1);
  	else
  	    puts(hoststring);
      }
  
      if (statfile != NULL) {
--- 376,387 ----
  
  	resolves++;
  
! 	cgethost(res->ai_addr, hoststring, check);
  	if (bar != NULL)
  	    printf("%s %s\n", hoststring, bar + 1);
  	else
  	    puts(hoststring);
+ 	freeaddrinfo(res);
      }
  
      if (statfile != NULL) {
***************
*** 343,345 ****
--- 398,408 ----
  
      return (0);
  }
+ 
+ #ifdef NEED_GETADDRINFO
+ #include "../main/getaddrinfo.c"
+ #endif
+ 
+ #ifdef NEED_GETNAMEINFO
+ #include "../main/getnameinfo.c"
+ #endif
