]> git.pld-linux.org Git - packages/apache.git/blob - apache-ipv6-PLD.patch
- up to 1.3.33; rel 1; SECURITY UPGRADE; stbr to ra
[packages/apache.git] / apache-ipv6-PLD.patch
1 diff -Nur apache_1.3.28.orig/README.v6 apache_1.3.28/README.v6
2 --- apache_1.3.28.orig/README.v6        Thu Jan  1 01:00:00 1970
3 +++ apache_1.3.28/README.v6     Fri Jul 25 11:01:55 2003
4 @@ -0,0 +1,166 @@
5 +IPv6-ready apache 1.3.x
6 +KAME Project
7 +$Id$
8 +
9 +This patchkit enables apache 1.3.x to perform HTTP connection over IPv6.
10 +Most of optional modules are left unchanged, i.e. it won't support IPv6,
11 +and it may not compile.
12 +
13 +Basically you can write IPv6 address where IPv4 address fits.
14 +
15 +extra command-line argument:
16 +       -4      Assume IPv4 address on ambiguous directives
17 +       -6      Assume IPv6 address on ambiguous directives (default)
18 +
19 +       The above two can be used, for example, to disambiguate
20 +       "BindAddress *".
21 +
22 +base commands:
23 +    Listen
24 +       Listen is expanded to take one or two arguments.
25 +               Listen port
26 +               Listen address:port
27 +               Listen address port
28 +       This is to let you specify "Listen :: 80", since "Listen :::80"
29 +       won't work.
30 +
31 +mod_access:
32 +    deny from
33 +    allow from
34 +       "deny from" and "allow from" supports IPv6 addresses, under the
35 +       following forms:
36 +               {deny,allow} from v6addr
37 +               {deny,allow} from v6addr/v6mask
38 +               {deny,allow} from v6addr/prefixlen
39 +       Also, wildcard ("*") and string hostname matches IPv6 hosts as well.
40 +
41 +mod_proxy:
42 +    ProxyRequests on
43 +       http/ftp proxying for both IPv4 and IPv6 is possible.
44 +       Access control functions (NoProxy) are not updated yet.
45 +
46 +       NOTE: for security reasons, we recommend you to filter out
47 +       outsider's access to your proxy, by directives like below:
48 +               <Directory proxy:*>
49 +               order deny,allow
50 +               deny from all
51 +               allow from 10.0.0.0/8
52 +               allow from 3ffe:9999:8888:7777::/64
53 +               </Directory>
54 +
55 +virtual host:
56 +       If you would like to this feature, you must describe 'Listen'
57 +       part on configuration file explicitly. like below:
58 +               Listen :: 80
59 +               Listen 0.0.0.0 80
60 +
61 +    NameVirtualHost
62 +       NameVirtualHost is expanded to take one more two arguments.
63 +               NameVirtualHost address
64 +               NameVirtualHost address:port
65 +               NameVirtualHost address port
66 +       This is to let you specify IPv6 address into address part.
67 +
68 +       Note that, if colon is found in the specified address string,
69 +       the code will to resolve the address in the following way:
70 +       1. try to resolve as address:port (most of IPv6 address fails)
71 +       2. if (1) is failed, try to resolve as address only
72 +       If there's ambiguity, i.e. 3ffe:0501::1:2, the address may not be
73 +       parsed as you expect (3ffe:0501::1 with port 2, or 3ffe:0501::1:2
74 +       with default port).  To get the right effect you are encouraged
75 +       to specify it without ambiguity.  In IPv6 case "address port"
76 +       (specify address and port separated by a space) is the safest way.
77 +
78 +    <VirtualHost host:port [host:port ...]>
79 +       If you would like to specify IPv6 numeric address in host part,
80 +       use bracketed format like below:
81 +               <VirtualHost [::1]:80>
82 +       Note: Now we DO NOT handle old non-bracketed format, 
83 +               <VirtualHost 0:0:0:0:0:0:0:1:80>
84 +             so configuration file must be updated.
85 +       Note: The following is bad example to specify host ::1 port 80.
86 +             This will treated as host ::1:80.
87 +               <VirtualHost ::1:80>
88 +
89 +logresolve (src/support)
90 +       error statistics in nameserver cache code is omitted.
91 +
92 +mod_unique_id
93 +       Originally mod_unique_id used IPv4 address as a seed for UNIQUE_ID,
94 +       and took IPv4 address registered onto DNS for the hostname (UNIX
95 +       hostname taken by gethostname(3)).  Therefore, this does not work
96 +       for IPv6-only hosts as they do not have IPv4 address for them.
97 +
98 +       Now, UNIQUE_ID can be generated using IPv6 address.  IPv6 address can
99 +       be used as the seed for UNIQUE_ID.
100 +       Because of this, UNIQUE_ID will be longer than normal apache.  This
101 +       may cause problem with some of the CGI scripts.
102 +       The preference of the addresses is based on the order returned
103 +       by getaddrinfo().  If your getaddrinfo() returns IPv4 address, IPv4
104 +       adderss will be used as a seed.
105 +       Note that some of IPv6 addresses are "scoped"; If you happened to use
106 +       link-local or site-local address as a seed, the UNIQUE_ID may not be
107 +       worldwide unique.
108 +
109 +       If longer UNIQUE_ID causes a problem, define SHORT_UNIQUE_ID in
110 +       mod_unique_id.c.  In this case, length of UNIQUE_ID will be kept the
111 +       same.  However, for IPv6 addresses mod_unique_id.c will use the last
112 +       32bit (not the whole 128bit) as the seed.  Therefore, there can be
113 +       collision in UNIQUE_ID.
114 +
115 +       The behavior should be improved in the near future; we welcome your
116 +       inputs.
117 +
118 +Modules known to be incompatible with IPv6
119 +       (please report us)
120 +
121 +configure
122 +       Configure has extra option, --enable-rule=INET6.  if the option
123 +       is specified, IPv6 code will be enabled.
124 +
125 +configuration file
126 +       We do not support IPv4 mapped address (IPv6 address format like
127 +       ::ffff:10.1.1.1) in configuration file. 
128 +
129 +This kit assumes that you have working(*) getaddrinfo() and getnameinfo()
130 +library functions.  Even if you don't have one, don't panic.  We have
131 +included last-resort version (which support IPv4 only) into the kit.
132 +For more complete implementation you might want to check BIND 8.2.
133 +(*) NOTE: we have noticed that some of IPv6 stack is shipped with broken
134 +getaddrinfo().  In such cases, you should get and install BIND 8.2.
135 +
136 +When compiling this kit onto IPv6, you may need to specify some additional
137 +library paths or cpp defs (like -linet6 or -DINET6).
138 +Now you don't have to specify --enable-rule=INET6.  The "configure" script
139 +will give you some warnings if the IPv6 stack is not known to the 
140 +"configure" script.  Currently, the following IPv6 stacks are supported:
141 +- KAME IPv6 stack, http://www.kame.net/
142 +       use configure.v6 for convenience,
143 +- Linux IPv6 stack, http://www.linux.org/
144 +       use configure.v6 for convenience.
145 +- Solaris 8 IPv6 stack, http://www.sun.com/
146 +       use configure.v6 for convenience.
147 +To disable IPv6 support, specify --disable-rule=INET6 to the "configure"
148 +script.
149 +
150 +CAVEAT: This patchkit may change some of apache module API, to avoid
151 +IPv4-dependent structure member variable.  Please let us know if there's
152 +any troubles as we know very little about the apache module API.
153 +
154 +Acknowledgements
155 +       Thanks to all people submitted patches/fixes for this patch kit,
156 +       including:
157 +               "Chris P. Ross" <cross@eng.us.uu.net>
158 +
159 +Author contacts
160 +       Jun-ichiro itojun Hagino, KAME project
161 +        http://www.kame.net/
162 +        mailto:core@kame.net
163 +Linux Port
164 +       Arkadiusz Miskiewicz, Polish Linux Distribution project (IPv6)
165 +        http://www.pld.org.pl/
166 +        mailto:feedback@pld.org.pl
167 +       Satoshi SHIDA, Linux IPv6 Users Group JP
168 +        http://www.v6.linux.or.jp/
169 +       YOSHIFUJI Hideaki, USAGI Project
170 +        http://www.linux-ipv6.org/
171 diff -Nur apache_1.3.28.orig/conf/httpd.conf-dist apache_1.3.28/conf/httpd.conf-dist
172 --- apache_1.3.28.orig/conf/httpd.conf-dist     Wed Jul 16 21:36:41 2003
173 +++ apache_1.3.28/conf/httpd.conf-dist  Fri Jul 25 11:01:55 2003
174 @@ -174,6 +174,11 @@
175  #Listen 3000
176  #Listen 12.34.56.78:80
177  
178 +# Listen can take two arguments.
179 +# (this is an extension for supporting IPv6 addresses)
180 +#Listen :: 80
181 +#Listen 0.0.0.0 80
182 +
183  #
184  # BindAddress: You can support virtual hosts with this option. This directive
185  # is used to tell the server which IP address to listen to. It can either
186 diff -Nur apache_1.3.28.orig/configure.v6 apache_1.3.28/configure.v6
187 --- apache_1.3.28.orig/configure.v6     Thu Jan  1 01:00:00 1970
188 +++ apache_1.3.28/configure.v6  Fri Jul 25 11:01:55 2003
189 @@ -0,0 +1,3 @@
190 +#! /bin/sh
191 +
192 +./configure --enable-rule=INET6 --enable-module=proxy $*
193 diff -Nur apache_1.3.28.orig/src/Configuration.tmpl apache_1.3.28/src/Configuration.tmpl
194 --- apache_1.3.28.orig/src/Configuration.tmpl   Fri Jul 25 11:00:49 2003
195 +++ apache_1.3.28/src/Configuration.tmpl        Fri Jul 25 11:01:55 2003
196 @@ -191,6 +191,9 @@
197  #  Rule EXPAT=default   : If Expat can be found at the system or
198  #                         in lib/expat-lite, use it; otherwise
199  #                         skip it
200 +# INET6:
201 +#  IPv6 support.
202 +#
203  # 
204  # CYGWIN_WINSOCK: 
205  #  Use Win32 API system calls for socket communication instead 
206 @@ -205,6 +208,7 @@
207  Rule IRIXN32=yes
208  Rule PARANOID=no
209  Rule EXPAT=default
210 +Rule INET6=no
211  Rule CYGWIN_WINSOCK=no 
212  
213  # DEV_RANDOM:
214 diff -Nur apache_1.3.28.orig/src/Configure apache_1.3.28/src/Configure
215 --- apache_1.3.28.orig/src/Configure    Fri Jul 25 11:00:49 2003
216 +++ apache_1.3.28/src/Configure Fri Jul 25 11:01:55 2003
217 @@ -238,6 +238,7 @@
218  RULE_CYGWIN_WINSOCK=`./helpers/CutRule CYGWIN_WINSOCK $file` 
219  RULE_SHARED_CORE=`./helpers/CutRule SHARED_CORE $file`
220  RULE_SHARED_CHAIN=`./helpers/CutRule SHARED_CHAIN $file`
221 +RULE_INET6=`./helpers/CutRule INET6 $file`
222  
223  ####################################################################
224  ## Rule SHARED_CORE implies required DSO support
225 @@ -1724,6 +1725,124 @@
226      esac
227  fi
228  
229 +# INET6 support.
230 +if [ "$RULE_INET6" = "yes" ]; then
231 +    echo " + enabling INET6 support"
232 +    CFLAGS="$CFLAGS -DINET6"
233 +    CFLAGS="$CFLAGS -Dss_family=__ss_family -Dss_len=__ss_len"
234 +    IPV6_STACKTYPE="UNKNOWN"
235 +    for i in KAME Linux Solaris; do
236 +       case "$i" in
237 +       KAME)
238 +           if [ -f /usr/include/netinet6/in6.h -a "x`egrep '__KAME__' /usr/include/netinet6/in6.h 2>/dev/null`" != "x" ]; then
239 +               IPV6_STACKTYPE=$i
240 +           fi
241 +           ;;
242 +       Linux)
243 +           if [ /usr/include/netinet/ip6.h -a -d /usr/include/linux ]; then
244 +               IPV6_STACKTYPE=$i
245 +           fi
246 +           ;;
247 +       Solaris)
248 +           SOL_VERSION=`(uname -v) 2>/dev/null` || SOL_VERSION="unknown"
249 +           case "${PLAT}-${SOL_VERSION}" in
250 +               *-solaris2.27*-*IPv6*)
251 +                   if [ -f /etc/hostname -o -f /etc/hostname.[a-z]*[0-9] ]; then
252 +                       IPV6_STACKTYPE="Solaris 7 (${SOL_VERSION})"
253 +                   fi
254 +                   ;;
255 +           esac
256 +           ;;
257 +       esac
258 +       if [ "$IPV6_STACKTYPE" != "UNKNOWN" ]; then
259 +           break
260 +       fi
261 +    done
262 +    if [ "$IPV6_STACKTYPE" != "UNKNOWN" ]; then
263 +       echo " + You seem to be using $IPV6_STACKTYPE stack"
264 +       if ./helpers/TestCompile func getaddrinfo; then
265 +           echo "   - Assuming you have working getaddrinfo in libc" 
266 +       else
267 +           if [ -f /usr/local/v6/lib/libinet6.a -a "x`egrep '^EXTRA_L' Makefile.config | grep linet6`" = "x" ]; then
268 +               LIBS="$LIBS -L/usr/local/v6/lib -linet6"
269 +               echo "   - using getaddrinfo in libinet6" 
270 +           elif [ -f /usr/local/lib/libinet6.a -a "x`egrep '^EXTRA_L' Makefile.config | grep linet6`" = "x" ]; then
271 +               LIBS="$LIBS -L/usr/local/lib -linet6"
272 +               echo "   - using getaddrinfo in libinet6"
273 +           elif [ -f /usr/inet6/lib/libinet6.a -a "x`egrep '^EXTRA_L' Makefile.config | grep linet6`" = "x" ]; then
274 +               echo "   - using getaddrinfo in libinet6"
275 +           else
276 +               echo "** WARNING: No getaddrinfo found, linkage may fail" 
277 +           fi
278 +       fi
279 +    else
280 +       echo ""
281 +       echo "** WARNING: We have no explicit knowledge about the IPv6"
282 +       echo "** implementation on this host.  You may need to specify"
283 +       echo "** EXTRA_LIBS so that we can find getaddrinfo() and"
284 +       echo "** getnameinfo() library functions."
285 +       echo ""
286 +    fi
287 +    case $PLAT in
288 +       *-solaris2* )
289 +           LIBS="$LIBS -lresolv"
290 +           ;;
291 +    esac
292 +else
293 +    CFLAGS="$CFLAGS -DNEED_GETADDRINFO -DNEED_GETNAMEINFO"
294 +    if [ -f /usr/include/netdb.h -a "x`egrep 'addrinfo' /usr/include/netdb.h`" = "x" ]; then
295 +       CFLAGS="$CFLAGS -DNEED_ADDRINFO"
296 +    fi
297 +fi
298 +
299 +echo '#include <sys/types.h>' >testfunc.c
300 +echo '#include <sys/socket.h>' >>testfunc.c
301 +echo 'int testfunc(){ struct sockaddr sa; int i = sa.sa_len; };' >>testfunc.c
302 +rm -f testfunc.o
303 +eval "${MAKE-make} -f Makefile.config testfunc.o >/dev/null 2>/dev/null"
304 +if [ -f testfunc.o ]; then
305 +    echo " + you have sa_len in struct sockaddr."
306 +    CFLAGS="$CFLAGS -DHAVE_SOCKADDR_LEN"
307 +else
308 +    echo " + you don't have sa_len in struct sockaddr."
309 +fi
310 +rm -f testfunc.c testfunc.o
311 +
312 +echo '#include <sys/types.h>' >testfunc.c
313 +echo '#include <sys/socket.h>' >>testfunc.c
314 +echo 'struct sockaddr_storage sockaddr_storage;' >>testfunc.c
315 +rm -f testfunc.o
316 +eval "${MAKE-make} -f Makefile.config testfunc.o >/dev/null 2>/dev/null"
317 +if [ -f testfunc.o ]; then
318 +    echo " + assuming you have struct sockaddr_storage"
319 +else
320 +    CFLAGS="$CFLAGS -DNEED_SOCKADDR_STORAGE"
321 +    echo " + you need struct sockaddr_storage"
322 +fi
323 +rm -f testfunc.c testfunc.o
324 +
325 +echo '#include <sys/types.h>' >testfunc.c
326 +echo '#include <sys/socket.h>' >>testfunc.c
327 +echo 'int testfunc(){ socklen_t t; }' >>testfunc.c
328 +rm -f testfunc.o
329 +eval "${MAKE-make} -f Makefile.config testfunc.o >/dev/null 2>/dev/null"
330 +if [ ! -f testfunc.o ]; then
331 +    CFLAGS="$CFLAGS -Dsocklen_t=int"
332 +fi
333 +rm -f testfunc.c testfunc.o
334 +
335 +echo '#include <sys/types.h>' >testfunc.c
336 +echo '#include <sys/socket.h>' >>testfunc.c
337 +echo 'struct sockaddr_in sin;' >>testfunc.c
338 +echo 'int main(){ int i = sin.sin_len; }' >>testfunc.c
339 +rm -f testfunc.o
340 +eval "${MAKE-make} -f Makefile.config testfunc.o >/dev/null 2>/dev/null"
341 +if [ -f testfunc.o ]; then
342 +    CFLAGS="$CFLAGS -DSIN_LEN"
343 +fi
344 +rm -f testfunc.c testfunc.o
345 +
346 +
347  ####################################################################
348  ## Find out what modules we want and try and configure things for them
349  ## Module lines can look like this:
350 @@ -2320,6 +2439,38 @@
351  echo "#define AP_LONGEST_LONG $AP_LONGEST_LONG" >>$AP_CONFIG_AUTO_H
352  echo "#endif" >>$AP_CONFIG_AUTO_H
353  
354 +if [ x`./helpers/TestCompile -r sizeof 'uint32_t'` != x"" ]; then
355 +    echo "" >>$AP_CONFIG_AUTO_H
356 +    echo "/* determine: use uint32_t as 32bit unsigned int */" >>$AP_CONFIG_AUTO_H
357 +    echo "#ifndef ap_uint32_t" >>$AP_CONFIG_AUTO_H
358 +    echo "#define ap_uint32_t uint32_t" >>$AP_CONFIG_AUTO_H
359 +    echo "#endif" >>$AP_CONFIG_AUTO_H
360 +    echo "   - use uint32_t as 32bit unsigned int"
361 +elif [ x`./helpers/TestCompile -r sizeof 'u_int32_t'` != x"" ]; then
362 +    echo "" >>$AP_CONFIG_AUTO_H
363 +    echo "/* determine: use u_int32_t as 32bit unsigned int */" >>$AP_CONFIG_AUTO_H
364 +    echo "#ifndef ap_uint32_t" >>$AP_CONFIG_AUTO_H
365 +    echo "#define ap_uint32_t u_int32_t" >>$AP_CONFIG_AUTO_H
366 +    echo "#endif" >>$AP_CONFIG_AUTO_H
367 +    echo "   - use u_int32_t as 32bit unsigned int"
368 +elif [ x`./helpers/TestCompile -r sizeof 'unsigned int'` = x"4" ]; then
369 +    echo "" >>$AP_CONFIG_AUTO_H
370 +    echo "/* determine: use unsigned int as 32bit unsigned int */" >>$AP_CONFIG_AUTO_H
371 +    echo "#ifndef ap_uint32_t" >>$AP_CONFIG_AUTO_H
372 +    echo "#define ap_uint32_t unsigned int" >>$AP_CONFIG_AUTO_H
373 +    echo "#endif" >>$AP_CONFIG_AUTO_H
374 +    echo "   - use unsigned int as 32bit unsigned int"
375 +elif [ x`./helpers/TestCompile -r sizeof 'unsigned long int'` = x"4" ]; then
376 +    echo "" >>$AP_CONFIG_AUTO_H
377 +    echo "/* determine: use unsigned long int as 32bit unsigned int */" >>$AP_CONFIG_AUTO_H
378 +    echo "#ifndef uint32_t" >>$AP_CONFIG_AUTO_H
379 +    echo "#define uint32_t unsigned long int" >>$AP_CONFIG_AUTO_H
380 +    echo "#endif" >>$AP_CONFIG_AUTO_H
381 +    echo "   - use unsigned long int as 32bit unsigned int"
382 +else
383 +    echo "  - Warning: cannot determine what type should we use as 32bit unsigned int"
384 +fi
385 +
386  ####################################################################
387  ## More building ap_config_auto.h
388  ##
389 diff -Nur apache_1.3.28.orig/src/ap/ap_snprintf.c apache_1.3.28/src/ap/ap_snprintf.c
390 --- apache_1.3.28.orig/src/ap/ap_snprintf.c     Mon Feb  3 18:13:17 2003
391 +++ apache_1.3.28/src/ap/ap_snprintf.c  Fri Jul 25 11:01:55 2003
392 @@ -73,6 +73,7 @@
393  #include <string.h>
394  #include <stdlib.h>
395  #include <math.h>
396 +#include "sa_len.h"
397  #ifdef WIN32
398  #include <float.h>
399  #endif
400 @@ -510,6 +511,42 @@
401  
402  
403  
404 +#ifdef INET6
405 +static char *conv_sockaddr(struct sockaddr *sa, char *buf_end, int *len)
406 +{
407 +    char *p = buf_end;
408 +    char hostnamebuf[MAXHOSTNAMELEN];
409 +    char portnamebuf[MAXHOSTNAMELEN];
410 +    char *q;
411 +    int salen;
412 +
413 +#ifndef SIN6_LEN
414 +    salen = SA_LEN(sa);
415 +#else
416 +    salen = sa->sa_len;
417 +#endif
418 +    if (getnameinfo(sa, salen, hostnamebuf, sizeof(hostnamebuf),
419 +           portnamebuf, sizeof(portnamebuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
420 +       strcpy(hostnamebuf, "???");
421 +       strcpy(portnamebuf, "???");
422 +    }
423 +    if (strcmp(portnamebuf,"0") == 0)
424 +       strcpy(portnamebuf, "*");
425 +    q = portnamebuf + strlen(portnamebuf);
426 +    while (portnamebuf < q)
427 +       *--p = *--q;
428 +    *--p = ':';
429 +    q = hostnamebuf + strlen(hostnamebuf);
430 +    while (hostnamebuf < q)
431 +       *--p = *--q;
432 +
433 +    *len = buf_end - p;
434 +    return (p);
435 +}
436 +#endif /*INET6*/
437 +
438 +
439 +
440  /*
441   * Convert a floating point number to a string formats 'f', 'e' or 'E'.
442   * The result is placed in buf, and len denotes the length of the string
443 @@ -1057,6 +1094,7 @@
444                     /* print a struct sockaddr_in as a.b.c.d:port */
445                 case 'I':
446                     {
447 +#ifndef INET6
448                         struct sockaddr_in *si;
449  
450                         si = va_arg(ap, struct sockaddr_in *);
451 @@ -1065,6 +1103,16 @@
452                             if (adjust_precision && precision < s_len)
453                                 s_len = precision;
454                         }
455 +#else
456 +                       struct sockaddr *sa;
457 +
458 +                       sa = va_arg(ap, struct sockaddr *);
459 +                       if (sa != NULL) {
460 +                           s = conv_sockaddr(sa, &num_buf[NUM_BUF_SIZE], &s_len);
461 +                           if (adjust_precision && precision < s_len)
462 +                               s_len = precision;
463 +                       }
464 +#endif
465                         else {
466                             s = S_NULL;
467                             s_len = S_NULL_LEN;
468 diff -Nur apache_1.3.28.orig/src/include/ap.h apache_1.3.28/src/include/ap.h
469 --- apache_1.3.28.orig/src/include/ap.h Mon Feb  3 18:13:17 2003
470 +++ apache_1.3.28/src/include/ap.h      Fri Jul 25 11:01:55 2003
471 @@ -95,7 +95,8 @@
472   * with some extensions.  The extensions are:
473   *
474   * %pA takes a struct in_addr *, and prints it as a.b.c.d
475 - * %pI takes a struct sockaddr_in * and prints it as a.b.c.d:port
476 + * %pI takes a struct sockaddr * and prints it as a.b.c.d:port, or
477 + *     ipv6-numeric-addr:port
478   * %pp  takes a void * and outputs it in hex
479   *
480   * The %p hacks are to force gcc's printf warning code to skip
481 diff -Nur apache_1.3.28.orig/src/include/ap_config.h apache_1.3.28/src/include/ap_config.h
482 --- apache_1.3.28.orig/src/include/ap_config.h  Mon May  5 13:45:49 2003
483 +++ apache_1.3.28/src/include/ap_config.h       Fri Jul 25 11:01:55 2003
484 @@ -411,6 +411,10 @@
485  #endif
486  #ifndef S_IWOTH
487  #define S_IWOTH 000002
488 +#ifndef rlim_t
489 +typedef int rlim_t;
490 +#endif
491 +typedef u_long n_long;
492  #endif
493  
494  #define STDIN_FILENO  0
495 @@ -1523,6 +1527,70 @@
496  #define ap_wait_t int
497  #endif
498  
499 +#ifndef INET6
500 +#define sockaddr_storage       sockaddr
501 +#define ss_family              sa_family
502 +#define ss_len                 sa_len
503 +#else
504 +#include "sockaddr_storage.h"  /* sshida@st.rim.or.jp */
505 +#endif
506 +
507 +#ifndef INET6_ADDRSTRLEN
508 +#define INET6_ADDRSTRLEN       46
509 +#endif
510 +#ifndef INET_ADDRSTRLEN
511 +#define INET_ADDRSTRLEN                16
512 +#endif
513 +#ifndef NI_MAXHOST
514 +#define NI_MAXHOST             1025
515 +#endif
516 +#ifndef NI_MAXSERV
517 +#define        NI_MAXSERV              32
518 +#endif
519 +
520 +#if defined(NEED_GETADDRINFO) || defined(NEED_GETNAMEINFO)
521 +/*
522 + * minimal definitions for fake getaddrinfo()/getnameinfo().
523 + */
524 +#ifndef EAI_NODATA
525 +#define EAI_NODATA     1
526 +#define EAI_MEMORY     2
527 +#endif
528 +
529 +#ifndef AI_PASSIVE
530 +#define AI_PASSIVE     1
531 +#define AI_CANONNAME   2
532 +#define AI_NUMERICHOST 4
533 +#define NI_NUMERICHOST 8
534 +#define NI_NAMEREQD    16
535 +#define NI_NUMERICSERV 32
536 +#endif
537 +#endif
538 +
539 +#ifdef NEED_GETADDRINFO
540 +#ifdef NEED_ADDRINFO
541 +struct addrinfo {
542 +       int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
543 +       int     ai_family;      /* PF_xxx */
544 +       int     ai_socktype;    /* SOCK_xxx */
545 +       int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
546 +       size_t  ai_addrlen;     /* length of ai_addr */
547 +       char    *ai_canonname;  /* canonical name for hostname */
548 +       struct sockaddr *ai_addr;       /* binary address */
549 +       struct addrinfo *ai_next;       /* next structure in linked list */
550 +};
551 +#endif
552 +extern char *gai_strerror(int ecode);
553 +extern void freeaddrinfo(struct addrinfo *ai);
554 +extern int getaddrinfo(const char *hostname, const char *servname,
555 +       const struct addrinfo *hints, struct addrinfo **res);
556 +#endif
557 +#ifdef NEED_GETNAMEINFO
558 +extern int getnameinfo(const struct sockaddr *sa, size_t salen,
559 +       char *host, size_t hostlen, char *serv, size_t servlen,
560 +       int flag);
561 +#endif
562 +
563  #ifdef __cplusplus
564  }
565  #endif
566 diff -Nur apache_1.3.28.orig/src/include/http_conf_globals.h apache_1.3.28/src/include/http_conf_globals.h
567 --- apache_1.3.28.orig/src/include/http_conf_globals.h  Fri Jul 25 11:00:49 2003
568 +++ apache_1.3.28/src/include/http_conf_globals.h       Fri Jul 25 11:01:55 2003
569 @@ -82,7 +82,8 @@
570  extern API_VAR_EXPORT int ap_max_requests_per_child;
571  extern API_VAR_EXPORT int ap_threads_per_child;
572  extern API_VAR_EXPORT int ap_excess_requests_per_child;
573 -extern API_VAR_EXPORT struct in_addr ap_bind_address;
574 +extern API_VAR_EXPORT struct sockaddr_storage ap_bind_address;
575 +extern API_VAR_EXPORT int ap_default_family;
576  extern listen_rec *ap_listeners;
577  extern API_VAR_EXPORT int ap_daemons_to_start;
578  extern API_VAR_EXPORT int ap_daemons_min_free;
579 diff -Nur apache_1.3.28.orig/src/include/http_vhost.h apache_1.3.28/src/include/http_vhost.h
580 --- apache_1.3.28.orig/src/include/http_vhost.h Mon Feb  3 18:13:19 2003
581 +++ apache_1.3.28/src/include/http_vhost.h      Fri Jul 25 11:01:55 2003
582 @@ -73,7 +73,7 @@
583  API_EXPORT(const char *) ap_parse_vhost_addrs(pool *p, const char *hostname, server_rec *s);
584  
585  /* handle NameVirtualHost directive */
586 -API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg);
587 +API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *h, char *p);
588  
589  /* given an ip address only, give our best guess as to what vhost it is */
590  API_EXPORT(void) ap_update_vhost_given_ip(conn_rec *conn);
591 diff -Nur apache_1.3.28.orig/src/include/httpd.h apache_1.3.28/src/include/httpd.h
592 --- apache_1.3.28.orig/src/include/httpd.h      Fri Jul 25 11:00:49 2003
593 +++ apache_1.3.28/src/include/httpd.h   Fri Jul 25 11:01:55 2003
594 @@ -904,8 +904,8 @@
595  
596      /* Who is the client? */
597  
598 -    struct sockaddr_in local_addr;     /* local address */
599 -    struct sockaddr_in remote_addr;    /* remote address */
600 +    struct sockaddr_storage local_addr;        /* local address */
601 +    struct sockaddr_storage remote_addr; /* remote address */
602      char *remote_ip;           /* Client's IP address */
603      char *remote_host;         /* Client's DNS name, if known.
604                                  * NULL if DNS hasn't been checked,
605 @@ -947,8 +947,8 @@
606  typedef struct server_addr_rec server_addr_rec;
607  struct server_addr_rec {
608      server_addr_rec *next;
609 -    struct in_addr host_addr;  /* The bound address, for this server */
610 -    unsigned short host_port;  /* The bound port, for this server */
611 +    struct sockaddr_storage host_addr; /* The bound address, for this server */
612 +    unsigned short host_port;  /* The bound port, for this server XXX */
613      char *virthost;            /* The name given in <VirtualHost> */
614  };
615  
616 @@ -1016,7 +1016,7 @@
617  /* These are more like real hosts than virtual hosts */
618  struct listen_rec {
619      listen_rec *next;
620 -    struct sockaddr_in local_addr;     /* local IP address and port */
621 +    struct sockaddr_storage local_addr;        /* local IP address and port */
622      int fd;
623      int used;                  /* Only used during restart */        
624  /* more stuff here, like which protocol is bound to the port */
625 @@ -1184,7 +1184,7 @@
626  #endif /*#ifdef CHARSET_EBCDIC*/
627  
628  API_EXPORT(char *) ap_get_local_host(pool *);
629 -API_EXPORT(unsigned long) ap_get_virthost_addr(char *hostname, unsigned short *port);
630 +API_EXPORT(struct sockaddr *) ap_get_virthost_addr(char *hostname, unsigned short *port);
631  
632  extern API_VAR_EXPORT time_t ap_restart_time;
633  
634 diff -Nur apache_1.3.28.orig/src/include/sa_len.h apache_1.3.28/src/include/sa_len.h
635 --- apache_1.3.28.orig/src/include/sa_len.h     Thu Jan  1 01:00:00 1970
636 +++ apache_1.3.28/src/include/sa_len.h  Fri Jul 25 11:01:55 2003
637 @@ -0,0 +1,41 @@
638 +/* sa_len.h : tiny version of SA_LEN (written by <yoshfuji@ecei.tohoku.ac.jp>) */
639
640 +#include <sys/types.h>
641 +#include <sys/socket.h>
642 +#include <netinet/in.h>
643 +#include <sys/un.h>
644 +
645 +#ifndef HAVE_SOCKADDR_LEN
646 +#ifndef SA_LEN
647 +#define SA_LEN(s_)     ap_sa_len((s_)->sa_family)
648 +
649 +static NET_SIZE_T ap_sa_len (sa_family_t af)
650 +{
651 +    switch (af){
652 +#if defined(AF_INET)
653 +    case AF_INET:
654 +       return (sizeof(struct sockaddr_in));
655 +#endif /* AF_INET */
656 +#if defined(AF_INET6)
657 +    case AF_INET6:
658 +       return (sizeof(struct sockaddr_in6));
659 +#endif
660 +#ifdef AF_LOCAL
661 +    case AF_LOCAL:
662 +#endif /* AF_LOCAL */
663 +#if defined(AF_UNIX) && (AF_UNIX != AF_LOCAL)
664 +    case AF_UNIX:
665 +#endif /* AF_UNIX */
666 +#if defined(AF_FILE) && (AF_FILE != AF_LOCAL || AF_FILE != AF_UNIX)
667 +    case AF_FILE:
668 +#endif /* AF_FILE */
669 +#if defined(AF_LOCAL) || defined(AF_UNIX) || defined(AF_FILE)
670 +       return (sizeof(struct sockaddr_un));
671 +#endif /* defined(AF_LOCAL) || defined(AF_UNIX) || defined(AF_FILE) */
672 +    default:
673 +       return 0;
674 +    }
675 +    return 0;
676 +}
677 +#endif /* SA_LEN */
678 +#endif /* HAVE_SOCKADDR_LEN */
679 diff -Nur apache_1.3.28.orig/src/include/sockaddr_storage.h apache_1.3.28/src/include/sockaddr_storage.h
680 --- apache_1.3.28.orig/src/include/sockaddr_storage.h   Thu Jan  1 01:00:00 1970
681 +++ apache_1.3.28/src/include/sockaddr_storage.h        Fri Jul 25 11:01:55 2003
682 @@ -0,0 +1,53 @@
683 +/*
684 +struct sockaddr_storage
685 +
686 +   RFC2553 proposes struct sockaddr_storage.
687 +   This is a placeholder for all sockaddr-variant structures. This is
688 +   implemented like follows:
689 +
690 +   You should use this structure to hold any of sockaddr-variant
691 +   structures.
692 +*/
693 +#ifdef NEED_SOCKADDR_STORAGE
694 +
695 +struct sockaddr_storage {
696 +#ifdef HAVE_SOCKADDR_LEN
697 +       u_char ss_len;
698 +       u_char ss_family;
699 +#else
700 +       u_short ss_family;
701 +#endif
702 +       u_char __padding[128 - 2];
703 +};
704 +
705 +/*
706 +union sockunion
707 +
708 +   Alternatively, you may want to implement sockunion.h, with the
709 +   following content:
710 +
711 +   NOTE: For better portability, struct sockaddr_storage should be used.
712 +   union sockunion is okay, but is not really portable enough.
713 +*/
714 +union sockunion {
715 +       struct sockinet {
716 +#ifdef HAVE_SOCKADDR_LEN
717 +               u_char si_len;
718 +               u_char si_family;
719 +#else
720 +               u_short si_family;
721 +#endif
722 +               u_short si_port;
723 +       } su_si;
724 +       struct sockaddr_in  su_sin;
725 +#ifdef INET6
726 +       struct sockaddr_in6 su_sin6;
727 +#endif
728 +};
729 +#ifdef HAVE_SOCKADDR_LEN
730 +#define su_len         su_si.si_len
731 +#endif
732 +#define su_family      su_si.si_family
733 +#define su_port                su_si.si_port
734 +
735 +#endif /* NEED_SOCKADDR_STORAGE */
736 diff -Nur apache_1.3.28.orig/src/main/getaddrinfo.c apache_1.3.28/src/main/getaddrinfo.c
737 --- apache_1.3.28.orig/src/main/getaddrinfo.c   Thu Jan  1 01:00:00 1970
738 +++ apache_1.3.28/src/main/getaddrinfo.c        Fri Jul 25 11:01:55 2003
739 @@ -0,0 +1,162 @@
740 +/*
741 + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
742 + * All rights reserved.
743 + * 
744 + * Redistribution and use in source and binary forms, with or without
745 + * modification, are permitted provided that the following conditions
746 + * are met:
747 + * 1. Redistributions of source code must retain the above copyright
748 + *    notice, this list of conditions and the following disclaimer.
749 + * 2. Redistributions in binary form must reproduce the above copyright
750 + *    notice, this list of conditions and the following disclaimer in the
751 + *    documentation and/or other materials provided with the distribution.
752 + * 3. Neither the name of the project nor the names of its contributors
753 + *    may be used to endorse or promote products derived from this software
754 + *    without specific prior written permission.
755 + * 
756 + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
757 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
758 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
759 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
760 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
761 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
762 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
763 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
764 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
765 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
766 + * SUCH DAMAGE.
767 + */
768 +/*
769 + * fake library for ssh v6 enabler patch
770 + *
771 + * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
772 + * These funtions are defined in rfc2133.
773 + *
774 + * But these functions are not implemented correctly. The minimum subset
775 + * is implemented for ssh use only. For exapmle, this routine assumes
776 + * that ai_family is AF_INET. Don't use it for another purpose.
777 + * 
778 + * In the case not using 'configure --enable-ipv6', this getaddrinfo.c
779 + * will be used if you have broken getaddrinfo or no getaddrinfo.
780 + */
781 +
782 +#if 0
783 +#include <stdlib.h>
784 +#include <sys/types.h>
785 +#include <sys/socket.h>
786 +#include <netinet/in.h>
787 +#include <arpa/inet.h>
788 +#include <netdb.h>
789 +#include "gai.h"
790 +#endif
791 +
792 +static struct addrinfo *
793 +malloc_ai(port, addr, socktype, protocol)
794 +int port;
795 +u_long addr;
796 +int socktype;
797 +int protocol;
798 +{
799 +  struct addrinfo *ai;
800 +
801 +  if (ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) +
802 +                                    sizeof(struct sockaddr_in))) {
803 +    memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
804 +    ai->ai_addr = (struct sockaddr *)(ai + 1);
805 +#if defined(HAVE_SOCKADDR_LEN)
806 +    ai->ai_addr->sa_len = 
807 +#endif
808 +      ai->ai_addrlen = sizeof(struct sockaddr_in);
809 +    ai->ai_addr->sa_family = ai->ai_family = AF_INET;
810 +    ai->ai_socktype = socktype;
811 +    ai->ai_protocol = protocol;
812 +    ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
813 +    ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
814 +    return ai;
815 +  } else {
816 +    return NULL;
817 +  }
818 +}
819 +
820 +char *
821 +gai_strerror(ecode)
822 +int ecode;
823 +{
824 +  switch (ecode) {
825 +  case EAI_NODATA:
826 +    return "no address associated with hostname.";
827 +  case EAI_MEMORY:
828 +    return "memory allocation failure.";
829 +  default:
830 +    return "unknown error.";
831 +  }
832 +}    
833 +
834 +void
835 +freeaddrinfo(ai)
836 +struct addrinfo *ai;
837 +{
838 +  struct addrinfo *next;
839 +  
840 +  do {
841 +    next = ai->ai_next;
842 +    free(ai);
843 +  } while (ai = next);
844 +}
845 +
846 +int
847 +getaddrinfo(hostname, servname, hints, res)
848 +const char *hostname, *servname;
849 +const struct addrinfo *hints;
850 +struct addrinfo **res;
851 +{
852 +  struct addrinfo *cur, *prev = NULL;
853 +  struct hostent *hp;
854 +  int i, port;
855 +  
856 +  if (servname)
857 +    port = htons(atoi(servname));
858 +  else
859 +    port = 0;
860 +  if (hints && hints->ai_flags & AI_PASSIVE)
861 +    if (*res = malloc_ai(port, htonl(0x00000000), 
862 +                        (*res)->ai_socktype ? (*res)->ai_socktype : SOCK_STREAM,
863 +                        (*res)->ai_protocol))
864 +      return 0;
865 +    else
866 +      return EAI_MEMORY;
867 +  if (!hostname)
868 +    if (*res = malloc_ai(port, htonl(0x7f000001),
869 +                        (*res)->ai_socktype ? (*res)->ai_socktype : SOCK_STREAM,
870 +                        (*res)->ai_protocol))
871 +      return 0;
872 +    else
873 +      return EAI_MEMORY;
874 +  if (inet_addr(hostname) != -1)
875 +    if (*res = malloc_ai(port, inet_addr(hostname),
876 +                        (*res)->ai_socktype ? (*res)->ai_socktype : SOCK_STREAM,
877 +                        (*res)->ai_protocol))
878 +      return 0;
879 +    else
880 +      return EAI_MEMORY;
881 +  if ((hp = gethostbyname(hostname)) &&
882 +      hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
883 +    for (i = 0; hp->h_addr_list[i]; i++)
884 +      if (cur = malloc_ai(port,
885 +                         ((struct in_addr *)hp->h_addr_list[i])->s_addr,
886 +                         (*res)->ai_socktype ? (*res)->ai_socktype : SOCK_STREAM,
887 +                         (*res)->ai_protocol)) {
888 +       if (prev)
889 +         prev->ai_next = cur;
890 +       else
891 +         *res = cur;
892 +       prev = cur;
893 +      } else {
894 +       if (*res)
895 +         freeaddrinfo(*res);
896 +       return EAI_MEMORY;
897 +      }
898 +    return 0;
899 +  }
900 +  return EAI_NODATA;
901 +}
902 diff -Nur apache_1.3.28.orig/src/main/getnameinfo.c apache_1.3.28/src/main/getnameinfo.c
903 --- apache_1.3.28.orig/src/main/getnameinfo.c   Thu Jan  1 01:00:00 1970
904 +++ apache_1.3.28/src/main/getnameinfo.c        Fri Jul 25 11:01:55 2003
905 @@ -0,0 +1,95 @@
906 +/*
907 + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
908 + * All rights reserved.
909 + * 
910 + * Redistribution and use in source and binary forms, with or without
911 + * modification, are permitted provided that the following conditions
912 + * are met:
913 + * 1. Redistributions of source code must retain the above copyright
914 + *    notice, this list of conditions and the following disclaimer.
915 + * 2. Redistributions in binary form must reproduce the above copyright
916 + *    notice, this list of conditions and the following disclaimer in the
917 + *    documentation and/or other materials provided with the distribution.
918 + * 3. Neither the name of the project nor the names of its contributors
919 + *    may be used to endorse or promote products derived from this software
920 + *    without specific prior written permission.
921 + * 
922 + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
923 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
924 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
925 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
926 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
927 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
928 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
929 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
930 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
931 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
932 + * SUCH DAMAGE.
933 + */
934 +/*
935 + * fake library for ssh v6 enabler patch
936 + *
937 + * This file includes getnameinfo().
938 + * These funtions are defined in rfc2133.
939 + *
940 + * But these functions are not implemented correctly. The minimum subset
941 + * is implemented for ssh use only. For exapmle, this routine assumes
942 + * that ai_family is AF_INET. Don't use it for another purpose.
943 + * 
944 + * In the case not using 'configure --enable-ipv6', this getnameinfo.c
945 + * will be used if you have broken getnameinfo or no getnameinfo.
946 + */
947 +
948 +#if 0
949 +#include <stdlib.h>
950 +#include <sys/types.h>
951 +#include <sys/socket.h>
952 +#include <netinet/in.h>
953 +#include <arpa/inet.h>
954 +#include <netdb.h>
955 +#include <string.h>
956 +#include "gai.h"
957 +#endif
958 +
959 +int
960 +getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
961 +const struct sockaddr *sa;
962 +size_t salen;
963 +char *host;
964 +size_t hostlen;
965 +char *serv;
966 +size_t servlen;
967 +int flags;
968 +{
969 +  struct sockaddr_in *sin = (struct sockaddr_in *)sa;
970 +  struct hostent *hp;
971 +  char tmpserv[16];
972 +  
973 +  if (serv) {
974 +    sprintf(tmpserv, "%d", ntohs(sin->sin_port));
975 +    if (strlen(tmpserv) > servlen)
976 +      return EAI_MEMORY;
977 +    else
978 +      strcpy(serv, tmpserv);
979 +  }
980 +  if (host)
981 +    if (flags & NI_NUMERICHOST)
982 +      if (strlen(inet_ntoa(sin->sin_addr)) > hostlen)
983 +       return EAI_MEMORY;
984 +      else {
985 +       strcpy(host, inet_ntoa(sin->sin_addr));
986 +       return 0;
987 +      }
988 +    else
989 +      if (hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr),
990 +                            AF_INET))
991 +       if (strlen(hp->h_name) > hostlen)
992 +         return EAI_MEMORY;
993 +       else {
994 +         strcpy(host, hp->h_name);
995 +         return 0;
996 +       }
997 +      else
998 +       return EAI_NODATA;
999 +  return 0;
1000 +}
1001 diff -Nur apache_1.3.28.orig/src/main/http_config.c apache_1.3.28/src/main/http_config.c
1002 --- apache_1.3.28.orig/src/main/http_config.c   Fri Jul 25 11:00:49 2003
1003 +++ apache_1.3.28/src/main/http_config.c        Fri Jul 25 11:01:55 2003
1004 @@ -1591,7 +1591,6 @@
1005      ap_scoreboard_fname = DEFAULT_SCOREBOARD;
1006      ap_lock_fname = DEFAULT_LOCKFILE;
1007      ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
1008 -    ap_bind_address.s_addr = htonl(INADDR_ANY);
1009      ap_listeners = NULL;
1010      ap_listenbacklog = DEFAULT_LISTENBACKLOG;
1011      ap_extended_status = 0;
1012 @@ -1624,7 +1623,13 @@
1013      s->next = NULL;
1014      s->addrs = ap_pcalloc(p, sizeof(server_addr_rec));
1015      /* NOT virtual host; don't match any real network interface */
1016 -    s->addrs->host_addr.s_addr = htonl(INADDR_ANY);
1017 +    memset(&s->addrs->host_addr, 0, sizeof(s->addrs->host_addr));
1018 +#if 0
1019 +    s->addrs->host_addr.ss_family = ap_default_family; /* XXX: needed?, XXX: PF_xxx can be different from AF_xxx */
1020 +#endif
1021 +#ifdef HAVE_SOCKADDR_LEN
1022 +    s->addrs->host_addr.ss_len = sizeof(s->addrs->host_addr); /* XXX: needed ? */
1023 +#endif
1024      s->addrs->host_port = 0;   /* matches any port */
1025      s->addrs->virthost = "";   /* must be non-NULL */
1026      s->names = s->wild_names = NULL;
1027 @@ -1643,21 +1648,33 @@
1028  static void default_listeners(pool *p, server_rec *s)
1029  {
1030      listen_rec *new;
1031 +    struct addrinfo hints, *res0, *res;
1032 +    int gai;
1033 +    char servbuf[NI_MAXSERV];
1034  
1035      if (ap_listeners != NULL) {
1036         return;
1037      }
1038 +    ap_snprintf(servbuf, sizeof(servbuf), "%d", s->port ? s->port : DEFAULT_HTTP_PORT);
1039 +    memset (&hints, 0, sizeof(hints));
1040 +    hints.ai_family = ap_default_family;
1041 +    hints.ai_socktype = SOCK_STREAM;
1042 +    hints.ai_flags = AI_PASSIVE;
1043 +    gai = getaddrinfo(NULL, servbuf, &hints, &res0);
1044 +    if (gai){
1045 +       fprintf(stderr, "default_listeners(): getaddrinfo(PASSIVE) for family %u: %s\n",
1046 +               gai_strerror(gai), ap_default_family);
1047 +       exit (1);
1048 +    }
1049      /* allocate a default listener */
1050      new = ap_pcalloc(p, sizeof(listen_rec));
1051 -    new->local_addr.sin_family = AF_INET;
1052 -    new->local_addr.sin_addr = ap_bind_address;
1053 -    /* Buck ugly cast to get around terniary op bug in some (MS) compilers */
1054 -    new->local_addr.sin_port = htons((unsigned short)(s->port ? s->port 
1055 -                                                        : DEFAULT_HTTP_PORT));
1056 +    memcpy(&new->local_addr, res0->ai_addr, res0->ai_addrlen);
1057      new->fd = -1;
1058      new->used = 0;
1059      new->next = NULL;
1060      ap_listeners = new;
1061 +
1062 +    freeaddrinfo(res0);
1063  }
1064  
1065  
1066 --- apache_1.3.32/src/main/http_core.c.orig     Mon May  3 22:15:26 2004
1067 +++ apache_1.3.32/src/main/http_core.c  Sat May 15 00:06:26 2004
1068 @@ -28,6 +28,7 @@
1069  #include "util_md5.h"
1070  #include "scoreboard.h"
1071  #include "fnmatch.h"
1072 +#include "sa_len.h"
1073  
1074  #ifdef USE_MMAP_FILES
1075  #include <sys/mman.h>
1076 @@ -564,7 +565,7 @@
1077       * file if you care. So the adhoc value should do.
1078       */
1079      return ap_psprintf(r->pool,"%pI%pp%pp%pp%pp",
1080 -           &r->connection->local_addr.sin_addr,
1081 +           &((struct sockaddr_in *)&(r->connection->local_addr))->sin_addr,
1082             (void *)ap_user_name,
1083             (void *)ap_listeners,
1084             (void *)ap_server_argv0,
1085 @@ -660,7 +661,9 @@
1086   */
1087  static ap_inline void do_double_reverse (conn_rec *conn)
1088  {
1089 -    struct hostent *hptr;
1090 +    struct addrinfo hints, *res, *res0;
1091 +    char hostbuf1[128], hostbuf2[128]; /* INET6_ADDRSTRLEN(=46) is enough */
1092 +    int ok = 0;
1093  
1094      if (conn->double_reverse) {
1095         /* already done */
1096 @@ -672,30 +675,54 @@
1097          conn->remote_host = ""; /* prevent another lookup */
1098         return;
1099      }
1100 -    hptr = gethostbyname(conn->remote_host);
1101 -    if (hptr) {
1102 -       char **haddr;
1103 -
1104 -       for (haddr = hptr->h_addr_list; *haddr; haddr++) {
1105 -           if (((struct in_addr *)(*haddr))->s_addr
1106 -               == conn->remote_addr.sin_addr.s_addr) {
1107 -               conn->double_reverse = 1;
1108 -               return;
1109 -           }
1110 +    memset(&hints, 0, sizeof(hints));
1111 +    hints.ai_family = PF_UNSPEC;
1112 +    hints.ai_socktype = SOCK_STREAM;
1113 +    if (getaddrinfo(conn->remote_host, NULL, &hints, &res0)) {
1114 +       conn->double_reverse = -1;
1115 +       return;
1116 +    }
1117 +    for (res = res0; res; res = res->ai_next) {
1118 +       if (res->ai_addr->sa_family != conn->remote_addr.ss_family ||
1119 +           !(res->ai_family == AF_INET 
1120 +#ifdef INET6
1121 +             || res->ai_family == AF_INET6
1122 +#endif
1123 +             )
1124 +           )
1125 +           continue;
1126 +#ifndef HAVE_SOCKADDR_LEN
1127 +       if (res->ai_addrlen != SA_LEN((struct sockaddr *)&conn->remote_addr))
1128 +#else
1129 +       if (res->ai_addr->sa_len != conn->remote_addr.ss_len)
1130 +#endif
1131 +           continue;
1132 +       if (getnameinfo(res->ai_addr, res->ai_addrlen,
1133 +            hostbuf1, sizeof(hostbuf1), NULL, 0,
1134 +            NI_NUMERICHOST))
1135 +           continue;
1136 +       if (getnameinfo(((struct sockaddr *)&conn->remote_addr), res->ai_addrlen,
1137 +            hostbuf2, sizeof(hostbuf2), NULL, 0,
1138 +            NI_NUMERICHOST))
1139 +           continue;
1140 +       if (strcmp(hostbuf1, hostbuf2) == 0){
1141 +           ok = 1;
1142 +           break;
1143         }
1144      }
1145 -    conn->double_reverse = -1;
1146 +    conn->double_reverse = ok ? 1 : -1;
1147 +    freeaddrinfo(res0);
1148      /* invalidate possible reverse-resolved hostname if forward lookup fails */
1149 -    conn->remote_host = "";
1150 +    if(!ok)
1151 +       conn->remote_host = "";
1152  }
1153  
1154  API_EXPORT(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
1155                                             int type)
1156  {
1157 -    struct in_addr *iaddr;
1158 -    struct hostent *hptr;
1159      int hostname_lookups;
1160      int old_stat = SERVER_DEAD;        /* we shouldn't ever be in this state */
1161 +    char hostnamebuf[MAXHOSTNAMELEN];
1162  
1163      /* If we haven't checked the host name, and we want to */
1164      if (dir_config) {
1165 @@ -717,10 +744,14 @@
1166             || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
1167         old_stat = ap_update_child_status(conn->child_num, SERVER_BUSY_DNS,
1168                                           (request_rec*)NULL);
1169 -       iaddr = &(conn->remote_addr.sin_addr);
1170 -       hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
1171 -       if (hptr != NULL) {
1172 -           conn->remote_host = ap_pstrdup(conn->pool, (void *)hptr->h_name);
1173 +       if (!getnameinfo((struct sockaddr *)&conn->remote_addr,
1174 +#ifndef SIN6_LEN
1175 +               SA_LEN((struct sockaddr *)&conn->remote_addr),
1176 +#else
1177 +               conn->remote_addr.ss_len,
1178 +#endif
1179 +               hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0)) {
1180 +           conn->remote_host = ap_pstrdup(conn->pool, (void *)hostnamebuf);
1181             ap_str_tolower(conn->remote_host);
1182            
1183             if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
1184 @@ -798,6 +829,7 @@
1185  {
1186      conn_rec *conn = r->connection;
1187      core_dir_config *d;
1188 +    char hbuf[MAXHOSTNAMELEN];
1189  
1190      d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
1191                                                 &core_module);
1192 @@ -807,23 +839,22 @@
1193      }
1194      if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
1195          if (conn->local_host == NULL) {
1196 -           struct in_addr *iaddr;
1197 -           struct hostent *hptr;
1198              int old_stat;
1199             old_stat = ap_update_child_status(conn->child_num,
1200                                               SERVER_BUSY_DNS, r);
1201 -           iaddr = &(conn->local_addr.sin_addr);
1202 -           hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr),
1203 -                                AF_INET);
1204 -           if (hptr != NULL) {
1205 -               conn->local_host = ap_pstrdup(conn->pool,
1206 -                                             (void *)hptr->h_name);
1207 -               ap_str_tolower(conn->local_host);
1208 -           }
1209 -           else {
1210 -               conn->local_host = ap_pstrdup(conn->pool,
1211 -                                             r->server->server_hostname);
1212 +           if (getnameinfo((struct sockaddr *)&conn->local_addr,
1213 +#ifndef SIN6_LEN
1214 +                   SA_LEN((struct sockaddr *)&conn->local_addr),
1215 +#else
1216 +                   conn->local_addr.ss_len,
1217 +#endif
1218 +                   hbuf, sizeof(hbuf), NULL, 0, 0) == 0) {
1219 +               conn->local_host = ap_pstrdup(conn->pool, hbuf);
1220 +           } else {
1221 +               conn->local_host = ap_pstrdup(conn->pool,
1222 +                   r->server->server_hostname);
1223             }
1224 +           ap_str_tolower(conn->local_host);
1225             (void) ap_update_child_status(conn->child_num, old_stat, r);
1226         }
1227         return conn->local_host;
1228 @@ -835,7 +866,7 @@
1229  API_EXPORT(unsigned) ap_get_server_port(const request_rec *r)
1230  {
1231      unsigned port;
1232 -    unsigned cport = ntohs(r->connection->local_addr.sin_port);
1233 +    unsigned cport = ntohs(((struct sockaddr_in *)&r->connection->local_addr)->sin_port);
1234      core_dir_config *d =
1235        (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
1236      
1237 @@ -2621,12 +2652,25 @@
1238  
1239  static const char *set_bind_address(cmd_parms *cmd, void *dummy, char *arg) 
1240  {
1241 +    struct addrinfo hints, *res;
1242 +    struct sockaddr *sa;
1243 +    size_t sa_len;
1244 +    int error;
1245      const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1246      if (err != NULL) {
1247          return err;
1248      }
1249  
1250 -    ap_bind_address.s_addr = ap_get_virthost_addr(arg, NULL);
1251 +    if (strcmp(arg, "*") == 0)
1252 +      arg = NULL;
1253 +
1254 +    sa = ap_get_virthost_addr(arg, NULL);
1255 +#ifdef HAVE_SOCKADDR_LEN
1256 +    sa_len = sa->sa_len;
1257 +#else
1258 +    sa_len = SA_LEN(sa);
1259 +#endif
1260 +    memcpy(&ap_bind_address, &sa, sa_len);
1261      return NULL;
1262  }
1263  
1264 @@ -2658,48 +2702,71 @@
1265      return NULL;
1266  }
1267  
1268 -static const char *set_listener(cmd_parms *cmd, void *dummy, char *ips)
1269 +static const char *set_listener(cmd_parms *cmd, void *dummy, char *h, char *p)
1270  {
1271      listen_rec *new;
1272 -    char *ports, *endptr;
1273 -    long port;
1274 +    char *host, *port;
1275 +    struct addrinfo hints, *res;
1276 +    int error;
1277      
1278      const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1279      if (err != NULL) {
1280          return err;
1281      }
1282  
1283 -    ports = strchr(ips, ':');
1284 -    if (ports != NULL) {
1285 -       if (ports == ips) {
1286 -           return "Missing IP address";
1287 -       }
1288 -       else if (ports[1] == '\0') {
1289 -           return "Address must end in :<port-number>";
1290 +    host = port = NULL;
1291 +    if (!p) {
1292 +        port = strrchr(h, ':');
1293 +        if (port != NULL) {
1294 +           if (port == h) {
1295 +               return "Missing IP address";
1296 +           }
1297 +           else if (port[1] == '\0') {
1298 +               return "Address must end in :<port-number>";
1299 +           }
1300 +           *(port++) = '\0';
1301 +           if (*h)
1302 +               host = h;
1303 +        }
1304 +        else {
1305 +           host = NULL;
1306 +           port = h;
1307         }
1308 -       *(ports++) = '\0';
1309 -    }
1310 -    else {
1311 -       ports = ips;
1312 +    } else {
1313 +       host = h;
1314 +       port = p;
1315      }
1316  
1317 -    new=ap_pcalloc(cmd->pool, sizeof(listen_rec));
1318 -    new->local_addr.sin_family = AF_INET;
1319 -    if (ports == ips) { /* no address */
1320 -       new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
1321 -    }
1322 -    else {
1323 -       new->local_addr.sin_addr.s_addr = ap_get_virthost_addr(ips, NULL);
1324 -    }
1325 -    errno = 0; /* clear errno before calling strtol */
1326 -    port = ap_strtol(ports, &endptr, 10);
1327 -    if (errno /* some sort of error */
1328 -       || (endptr && *endptr) /* make sure no trailing characters */
1329 -       || port < 1 || port > 65535) /* underflow/overflow */
1330 -    {
1331 -       return "Missing, invalid, or non-numeric port";
1332 +    if (host && strcmp(host, "*") == 0)
1333 +       host = NULL;
1334 +    
1335 +    new = ap_pcalloc(cmd->pool, sizeof(listen_rec));
1336 +
1337 +    memset(&hints, 0, sizeof(hints));
1338 +    hints.ai_family = host ? PF_UNSPEC : ap_default_family;
1339 +    hints.ai_flags = AI_PASSIVE;
1340 +    hints.ai_socktype = SOCK_STREAM;
1341 +    error = getaddrinfo(host, port, &hints, &res);
1342 +    if (error || !res) {
1343 +       fprintf(stderr, "could not resolve ");
1344 +       if (host)
1345 +           fprintf(stderr, "host \"%s\" ", host);
1346 +       if (port)
1347 +           fprintf(stderr, "port \"%s\" ", port);
1348 +       fprintf(stderr, "--- %s\n", gai_strerror(error));
1349 +       exit(1);
1350 +    }
1351 +    if (res->ai_next) {
1352 +        if (host)
1353 +           fprintf(stderr, "host \"%s\" ", host);
1354 +       if (port)
1355 +           fprintf(stderr, "port \"%s\" ", port);
1356 +       fprintf(stderr, "resolved to multiple addresses, ambiguous.\n");
1357 +       exit(1);
1358      }
1359 -    new->local_addr.sin_port = htons((unsigned short)port);
1360 +
1361 +    memcpy(&new->local_addr, res->ai_addr, res->ai_addrlen);
1362 +
1363      new->fd = -1;
1364      new->used = 0;
1365      new->next = ap_listeners;
1366 @@ -3602,7 +3669,7 @@
1367  { "ThreadStackSize", set_threadstacksize, NULL, RSRC_CONF, TAKE1,
1368    "Stack size each created thread will use."},
1369  #endif
1370 -{ "Listen", set_listener, NULL, RSRC_CONF, TAKE1,
1371 +{ "Listen", set_listener, NULL, RSRC_CONF, TAKE12,
1372    "A port number or a numeric IP address and a port number"},
1373  { "SendBufferSize", set_send_buffer_size, NULL, RSRC_CONF, TAKE1,
1374    "Send buffer size in bytes"},
1375 @@ -3636,7 +3703,7 @@
1376    "Name of the config file to be included" },
1377  { "LogLevel", set_loglevel, NULL, RSRC_CONF, TAKE1,
1378    "Level of verbosity in error logging" },
1379 -{ "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE1,
1380 +{ "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE12,
1381    "A numeric IP address:port, or the name of a host" },
1382  #ifdef _OSD_POSIX
1383  { "BS2000Account", set_bs2000_account, NULL, RSRC_CONF, TAKE1,
1384 diff -Nur apache_1.3.28.orig/src/main/http_main.c apache_1.3.28/src/main/http_main.c
1385 --- apache_1.3.28.orig/src/main/http_main.c     Fri Jul 25 11:00:49 2003
1386 +++ apache_1.3.28/src/main/http_main.c  Fri Jul 25 12:13:12 2003
1387 @@ -124,6 +124,8 @@
1388  #include <bstring.h>           /* for IRIX, FD_SET calls bzero() */
1389  #endif
1390  
1391 +#include "sa_len.h"
1392 +
1393  #ifdef MULTITHREAD
1394  /* special debug stuff -- PCS */
1395  
1396 @@ -249,7 +251,12 @@
1397  API_VAR_EXPORT char *ap_scoreboard_fname=NULL;
1398  API_VAR_EXPORT char *ap_lock_fname=NULL;
1399  API_VAR_EXPORT char *ap_server_argv0=NULL;
1400 -API_VAR_EXPORT struct in_addr ap_bind_address={0};
1401 +#ifdef INET6
1402 +API_VAR_EXPORT int ap_default_family = PF_INET6;
1403 +#else
1404 +API_VAR_EXPORT int ap_default_family = PF_INET;
1405 +#endif
1406 +API_VAR_EXPORT struct sockaddr_storage ap_bind_address={0};
1407  API_VAR_EXPORT int ap_daemons_to_start=0;
1408  API_VAR_EXPORT int ap_daemons_min_free=0;
1409  API_VAR_EXPORT int ap_daemons_max_free=0;
1410 @@ -1448,7 +1455,11 @@
1411      fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin);
1412  #endif
1413      fprintf(stderr, "       %s [-C \"directive\"] [-c \"directive\"]\n", pad);
1414 -    fprintf(stderr, "       %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T] [-F]\n", pad);
1415 +    fprintf(stderr, "       %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T] [-F]"
1416 +#ifdef INET6
1417 +           " [-46]"
1418 +#endif
1419 +           "\n", pad);
1420      fprintf(stderr, "Options:\n");
1421  #ifdef SHARED_CORE
1422      fprintf(stderr, "  -R directory     : specify an alternate location for shared object files\n");
1423 @@ -1474,6 +1485,10 @@
1424  #ifndef WIN32
1425      fprintf(stderr, "  -F               : run main process in foreground, for process supervisors\n");
1426  #endif
1427 +#ifdef INET6
1428 +    fprintf(stderr, "  -4               : assume IPv4 on parsing configuration file\n");
1429 +    fprintf(stderr, "  -6               : assume IPv6 on parsing configuration file\n");
1430 +#endif
1431  #ifdef WIN32
1432      fprintf(stderr, "  -n name          : name the Apache service for -k options below;\n");
1433      fprintf(stderr, "  -k stop|shutdown : tell running Apache to shutdown\n");
1434 @@ -3630,11 +3645,13 @@
1435  
1436  
1437  static conn_rec *new_connection(pool *p, server_rec *server, BUFF *inout,
1438 -                            const struct sockaddr_in *remaddr,
1439 -                            const struct sockaddr_in *saddr,
1440 +                            const struct sockaddr *remaddr,
1441 +                            const struct sockaddr *saddr,
1442                              int child_num)
1443  {
1444      conn_rec *conn = (conn_rec *) ap_pcalloc(p, sizeof(conn_rec));
1445 +    char hostnamebuf[MAXHOSTNAMELEN];
1446 +    size_t addr_len;
1447  
1448      /* Got a connection structure, so initialize what fields we can
1449       * (the rest are zeroed out by pcalloc).
1450 @@ -3643,17 +3660,29 @@
1451      conn->child_num = child_num;
1452  
1453      conn->pool = p;
1454 -    conn->local_addr = *saddr;
1455 -    conn->local_ip = ap_pstrdup(conn->pool,
1456 -                               inet_ntoa(conn->local_addr.sin_addr));
1457 +#ifndef SIN6_LEN
1458 +    addr_len = SA_LEN(saddr);
1459 +#else 
1460 +    addr_len = saddr->sa_len;
1461 +#endif
1462 +    memcpy(&conn->local_addr, saddr, addr_len); 
1463 +    getnameinfo((struct sockaddr *)&conn->local_addr, addr_len,
1464 +            hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);  
1465 +    conn->local_ip = ap_pstrdup(conn->pool, hostnamebuf);
1466      conn->server = server; /* just a guess for now */
1467      ap_update_vhost_given_ip(conn);
1468      conn->base_server = conn->server;
1469      conn->client = inout;
1470  
1471 -    conn->remote_addr = *remaddr;
1472 -    conn->remote_ip = ap_pstrdup(conn->pool,
1473 -                             inet_ntoa(conn->remote_addr.sin_addr));
1474 +#ifndef SIN6_LEN 
1475 +    addr_len = SA_LEN(remaddr);
1476 +#else 
1477 +    addr_len = remaddr->sa_len;
1478 +#endif
1479 +    memcpy(&conn->remote_addr, remaddr, addr_len);
1480 +    getnameinfo((struct sockaddr *)&conn->remote_addr, addr_len,
1481 +           hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
1482 +    conn->remote_ip = ap_pstrdup(conn->pool, hostnamebuf);           
1483  #ifdef EAPI
1484      conn->ctx = ap_ctx_new(conn->pool);
1485  #endif /* EAPI */
1486 @@ -3711,21 +3740,47 @@
1487  #define sock_disable_nagle(s, c)       /* NOOP */
1488  #endif
1489  
1490 -static int make_sock(pool *p, const struct sockaddr_in *server)
1491 +static int make_sock(pool *p, const struct sockaddr *server)
1492  {
1493      int s;
1494      int one = 1;
1495 -    char addr[512];
1496 +    char addr[INET6_ADDRSTRLEN + 128];
1497 +    char a0[INET6_ADDRSTRLEN];
1498 +    char p0[NI_MAXSERV];
1499 +#ifdef MPE
1500 +    int privport = 0;
1501 +#endif
1502  
1503 -    if (server->sin_addr.s_addr != htonl(INADDR_ANY))
1504 -       ap_snprintf(addr, sizeof(addr), "address %s port %d",
1505 -               inet_ntoa(server->sin_addr), ntohs(server->sin_port));
1506 -    else
1507 -       ap_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port));
1508 +    switch(server->sa_family){
1509 +    case AF_INET:
1510 +#ifdef INET6
1511 +    case AF_INET6:
1512 +#endif
1513 +      break;
1514 +    default:
1515 +      ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
1516 +                   "make_sock: unsupported address family %u", 
1517 +                  server->sa_family);
1518 +      ap_unblock_alarms();
1519 +      exit(1);
1520 +    }
1521 +    
1522 +    getnameinfo(server,
1523 +#ifndef SIN6_LEN
1524 +               SA_LEN(server),
1525 +#else
1526 +               server->sa_len,
1527 +#endif
1528 +               a0, sizeof(a0), p0, sizeof(p0), NI_NUMERICHOST | NI_NUMERICSERV);
1529 +    ap_snprintf(addr, sizeof(addr), "address %s port %s", a0, p0);
1530 +#ifdef MPE
1531 +    if (atoi(p0) < 1024)
1532 +      privport++;
1533 +#endif
1534  
1535      /* note that because we're about to slack we don't use psocket */
1536      ap_block_alarms();
1537 -    if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
1538 +    if ((s = socket(server->sa_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
1539             ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
1540                     "make_sock: failed to get a socket for %s", addr);
1541  
1542 @@ -3828,15 +3883,19 @@
1543  
1544  #ifdef MPE
1545  /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
1546 -    if (ntohs(server->sin_port) < 1024)
1547 +    if (privport)
1548         GETPRIVMODE();
1549  #endif
1550 -
1551 -    if (bind(s, (struct sockaddr *) server, sizeof(struct sockaddr_in)) == -1) {
1552 +#ifndef SIN6_LEN
1553 +    if (bind(s, server, SA_LEN(server)) == -1)
1554 +#else
1555 +    if (bind(s, server, server->sa_len) == -1)
1556 +#endif
1557 +    {
1558         ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
1559             "make_sock: could not bind to %s", addr);
1560  #ifdef MPE
1561 -       if (ntohs(server->sin_port) < 1024)
1562 +       if (privport)
1563             GETUSERMODE();
1564  #endif
1565  
1566 @@ -3849,7 +3908,7 @@
1567         exit(1);
1568      }
1569  #ifdef MPE
1570 -    if (ntohs(server->sin_port) < 1024)
1571 +    if (privport)
1572         GETUSERMODE();
1573  #endif
1574  
1575 @@ -4002,15 +4061,17 @@
1576      for (;;) {
1577         fd = find_listener(lr);
1578         if (fd < 0) {
1579 -           fd = make_sock(p, &lr->local_addr);
1580 +           fd = make_sock(p, (struct sockaddr *)&lr->local_addr);
1581         }
1582         else {
1583             ap_note_cleanups_for_socket_ex(p, fd, 1);
1584         }
1585         /* if we get here, (fd >= 0) && (fd < FD_SETSIZE) */
1586 -       FD_SET(fd, &listenfds);
1587 -       if (fd > listenmaxfd)
1588 -           listenmaxfd = fd;
1589 +       if (fd > 0) {
1590 +           FD_SET(fd, &listenfds);
1591 +           if (fd > listenmaxfd)
1592 +               listenmaxfd = fd;
1593 +       }
1594         lr->fd = fd;
1595         if (lr->next == NULL)
1596             break;
1597 @@ -4327,8 +4388,8 @@
1598  static void child_main(int child_num_arg)
1599  {
1600      NET_SIZE_T clen;
1601 -    struct sockaddr sa_server;
1602 -    struct sockaddr sa_client;
1603 +    struct sockaddr_storage sa_server;
1604 +    struct sockaddr_storage sa_client;
1605      listen_rec *lr;
1606  
1607      /* All of initialization is a critical section, we don't care if we're
1608 @@ -4505,7 +4566,7 @@
1609             usr1_just_die = 0;
1610             for (;;) {
1611                 clen = sizeof(sa_client);
1612 -               csd = ap_accept(sd, &sa_client, &clen);
1613 +               csd = ap_accept(sd, (struct sockaddr *)&sa_client, &clen);
1614                 if (csd >= 0 || errno != EINTR)
1615                     break;
1616                 if (deferred_die) {
1617 @@ -4671,7 +4732,7 @@
1618          */
1619  
1620         clen = sizeof(sa_server);
1621 -       if (getsockname(csd, &sa_server, &clen) < 0) {
1622 +       if (getsockname(csd, (struct sockaddr *)&sa_server, &clen) < 0) {
1623             ap_log_error(APLOG_MARK, APLOG_DEBUG, server_conf, 
1624                           "getsockname, client %pA probably dropped the "
1625                           "connection", 
1626 @@ -4719,8 +4780,8 @@
1627         ap_bpushfd(conn_io, csd, dupped_csd);
1628  
1629         current_conn = new_connection(ptrans, server_conf, conn_io,
1630 -                                         (struct sockaddr_in *) &sa_client,
1631 -                                         (struct sockaddr_in *) &sa_server,
1632 +                                         (struct sockaddr *)&sa_client,
1633 +                                         (struct sockaddr *)&sa_server,
1634                                           my_child_num);
1635  
1636         /*
1637 @@ -4875,12 +4936,13 @@
1638  
1639  #ifdef _OSD_POSIX
1640      /* BS2000 requires a "special" version of fork() before a setuid() call */
1641 -    if ((pid = os_fork(ap_user_name)) == -1) {
1642 +    if ((pid = os_fork(ap_user_name)) == -1)
1643  #elif defined(TPF)
1644 -    if ((pid = os_fork(s, slot)) == -1) {
1645 +    if ((pid = os_fork(s, slot)) == -1)
1646  #else
1647 -    if ((pid = fork()) == -1) {
1648 +    if ((pid = fork()) == -1)
1649  #endif
1650 +    {
1651         ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new process");
1652  
1653         /* fork didn't succeed. Fix the scoreboard or else
1654 @@ -5497,7 +5559,10 @@
1655      ap_setup_prelinked_modules();
1656  
1657      while ((c = getopt(argc, argv,
1658 -                                   "D:C:c:xXd:Ff:vVlLR:StTh"
1659 +                                   "D:C:c:xXd:Ff:vVlLR:StTh4"
1660 +#ifdef INET6
1661 +                                   "6"
1662 +#endif
1663  #ifdef DEBUG_SIGSTOP
1664                                     "Z:"
1665  #endif
1666 @@ -5575,8 +5640,14 @@
1667             ap_configtestonly = 1;
1668             ap_docrootcheck = 0;
1669             break;
1670 -       case 'h':
1671 -           usage(argv[0]);
1672 +       case '4':
1673 +           ap_default_family = PF_INET;
1674 +           break;
1675 +#ifdef INET6
1676 +       case '6':
1677 +           ap_default_family = PF_INET6;
1678 +           break;
1679 +#endif
1680         case '?':
1681             usage(argv[0]);
1682         }
1683 @@ -5665,9 +5736,10 @@
1684      else {
1685         conn_rec *conn;
1686         request_rec *r;
1687 -       struct sockaddr sa_server, sa_client;
1688         BUFF *cio;
1689 +       struct sockaddr_storage sa_server, sa_client;
1690         NET_SIZE_T l;
1691 +       char servbuf[NI_MAXSERV];
1692  
1693         ap_set_version();
1694         /* Yes this is called twice. */
1695 @@ -5722,25 +5794,32 @@
1696  #endif
1697  
1698         l = sizeof(sa_client);
1699 -       if ((getpeername(sock_in, &sa_client, &l)) < 0) {
1700 +       if ((getpeername(sock_in, (struct sockaddr *)&sa_client, &l)) < 0) {
1701  /* get peername will fail if the input isn't a socket */
1702             perror("getpeername");
1703             memset(&sa_client, '\0', sizeof(sa_client));
1704         }
1705  
1706         l = sizeof(sa_server);
1707 -       if (getsockname(sock_in, &sa_server, &l) < 0) {
1708 +       if (getsockname(sock_in, (struct sockaddr *)&sa_server, &l) < 0) {
1709             perror("getsockname");
1710             fprintf(stderr, "Error getting local address\n");
1711             exit(1);
1712         }
1713 -       server_conf->port = ntohs(((struct sockaddr_in *) &sa_server)->sin_port);
1714 +       if (getnameinfo(((struct sockaddr *)&sa_server), l,
1715 +                       NULL, 0, servbuf, sizeof(servbuf), 
1716 +                       NI_NUMERICSERV)){
1717 +           fprintf(stderr, "getnameinfo(): family=%d\n", sa_server.ss_family);
1718 +           exit(1);
1719 +       }
1720 +       servbuf[sizeof(servbuf)-1] = '\0';
1721 +       server_conf->port = atoi(servbuf);
1722         cio = ap_bcreate(ptrans, B_RDWR | B_SOCKET);
1723          cio->fd = sock_out;
1724          cio->fd_in = sock_in;
1725         conn = new_connection(ptrans, server_conf, cio,
1726 -                                 (struct sockaddr_in *) &sa_client,
1727 -                                 (struct sockaddr_in *) &sa_server, -1);
1728 +                                 (struct sockaddr *)&sa_client,
1729 +                                 (struct sockaddr *)&sa_server, -1);
1730  
1731         while ((r = ap_read_request(conn)) != NULL) {
1732  
1733 @@ -7447,7 +7526,11 @@
1734  
1735      while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLz:Z:wiuStThk:n:W:")) != -1) {
1736  #else /* !WIN32 */
1737 -    while ((c = getopt(argc, argv, "D:C:c:Xd:Ff:vVlLesStTh")) != -1) {
1738 +    while ((c = getopt(argc, argv, "D:C:c:Xd:Ff:vVlLesStTh4"
1739 +#ifdef INET6
1740 +               "6"
1741 +#endif
1742 +               )) != -1) {
1743  #endif
1744          char **new;
1745         switch (c) {
1746 @@ -7993,6 +8076,10 @@
1747         case 't':
1748         case 'T':
1749         case 'h':
1750 +       case '4':
1751 +#ifdef INET6
1752 +       case '6':
1753 +#endif
1754         case '?':
1755             break;
1756         case 'R':
1757 --- apache_1.3.31/src/main/http_vhost.c.orig    Mon Mar 29 23:03:25 2004
1758 +++ apache_1.3.31/src/main/http_vhost.c Wed May 12 13:49:13 2004
1759 @@ -25,6 +25,7 @@
1760  #include "http_log.h"
1761  #include "http_vhost.h"
1762  #include "http_protocol.h"
1763 +#include "sa_len.h"
1764  
1765  /*
1766   * After all the definitions there's an explanation of how it's all put
1767 @@ -122,78 +123,114 @@
1768   * *paddr is the variable used to keep track of **paddr between calls
1769   * port is the default port to assume
1770   */
1771 -static const char *get_addresses(pool *p, char *w, server_addr_rec ***paddr,
1772 -                           unsigned port)
1773 +static const char *get_addresses(pool *p, char *w, char *pstr,
1774 +       server_addr_rec ***paddr, unsigned port)
1775  {
1776 -    struct hostent *hep;
1777 -    unsigned long my_addr;
1778 +    struct addrinfo hints, *res, *res0;
1779      server_addr_rec *sar;
1780 -    char *t;
1781 -    int i, is_an_ip_addr;
1782 +    char *t = NULL, *u = NULL, *v = NULL;
1783 +    char *hoststr = NULL, *portstr = NULL;
1784 +    char portpool[10];
1785 +    int error;
1786 +    char servbuf[NI_MAXSERV];
1787  
1788 -    if (*w == 0)
1789 +    if (w == 0 || *w == 0)
1790         return NULL;
1791  
1792 -    t = strchr(w, ':');
1793 -    if (t) {
1794 -       if (strcmp(t + 1, "*") == 0) {
1795 -           port = 0;
1796 +    portstr = portpool;
1797 +    ap_snprintf(portpool, sizeof(portpool), "%u", port);
1798 +    if (!pstr) {
1799 +       v = w;
1800 +       u = NULL;
1801 +       if (*w == '['){
1802 +           u = strrchr(w, ']');
1803 +           if (u) {    /* [host]:port or [host] */
1804 +               w++;
1805 +               *u = '\0';
1806 +               v = u + 1;
1807 +           }
1808         }
1809 -       else if ((i = atoi(t + 1))) {
1810 -           port = i;
1811 +       /*        w   uv     ,       w=v        , w=v  */  
1812 +       /* u!=0: [host]:port , u==0: [host:port , host */
1813 +       t = strchr(v, ':');
1814 +       if (t != NULL && strchr(t+1, ':') == NULL) {
1815 +           /* [host]:port-w/o-colons, host-without-colons:port-w/o-colons */
1816 +           *t = '\0';
1817 +           portstr = t + 1;
1818         }
1819         else {
1820 -           return ":port must be numeric";
1821 +           portstr = "0";
1822         }
1823 -       *t = 0;
1824 +    } else {
1825 +       portstr = pstr;
1826      }
1827  
1828 -    is_an_ip_addr = 0;
1829 -    if (strcmp(w, "*") == 0) {
1830 -       my_addr = htonl(INADDR_ANY);
1831 -       is_an_ip_addr = 1;
1832 -    }
1833 -    else if (strcasecmp(w, "_default_") == 0
1834 -            || strcmp(w, "255.255.255.255") == 0) {
1835 -       my_addr = DEFAULT_VHOST_ADDR;
1836 -       is_an_ip_addr = 1;
1837 -    }
1838 -    else if ((my_addr = ap_inet_addr(w)) != INADDR_NONE) {
1839 -       is_an_ip_addr = 1;
1840 +    memset(&hints, 0, sizeof(hints));
1841 +    hints.ai_socktype = SOCK_STREAM;
1842 +    if (strcmp(w, "*") == 0 || strlen(w) == 0) {
1843 +       hoststr = NULL;
1844 +       hints.ai_family = PF_UNSPEC;
1845 +       hints.ai_flags = AI_PASSIVE;
1846 +    }
1847 +    else if (strcasecmp(w, "_default4_") == 0 ||
1848 +            ((ap_default_family == PF_INET
1849 +#ifndef INET6
1850 +              || ap_default_family == PF_UNSPEC
1851 +#endif
1852 +              ) && strcasecmp(w, "_default_") == 0)){
1853 +       hoststr = "255.255.255.255";
1854 +       hints.ai_family = PF_INET;
1855 +    }
1856 +#ifdef INET6
1857 +    else if (strcasecmp(w, "_default6_") == 0 ||
1858 +            ((ap_default_family == PF_INET6
1859 +              || ap_default_family == PF_UNSPEC
1860 +              ) && strcasecmp(w, "_default_") == 0)){
1861 +       hoststr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
1862 +       hints.ai_family = PF_INET6;
1863      }
1864 -    if (is_an_ip_addr) {
1865 -       sar = ap_pcalloc(p, sizeof(server_addr_rec));
1866 -       **paddr = sar;
1867 -       *paddr = &sar->next;
1868 -       sar->host_addr.s_addr = my_addr;
1869 -       sar->host_port = port;
1870 -       sar->virthost = ap_pstrdup(p, w);
1871 -       if (t != NULL)
1872 -           *t = ':';
1873 -       return NULL;
1874 +#endif
1875 +    else{
1876 +       hoststr = w;
1877 +       hints.ai_family = PF_UNSPEC;
1878      }
1879  
1880 -    hep = gethostbyname(w);
1881 -
1882 -    if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
1883 +    error = getaddrinfo(hoststr, portstr, &hints, &res0);
1884 +    if (error || !res0) {
1885         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
1886 -           "Cannot resolve host name %s --- ignoring!", w);
1887 -       if (t != NULL)
1888 -           *t = ':';
1889 +           "Cannot resolve host %s port %s --- ignoring!", hoststr, portstr);
1890 +       if (t != NULL) *t = ':';
1891 +       if (u != NULL) *u = ']';
1892         return NULL;
1893      }
1894 -
1895 -    for (i = 0; hep->h_addr_list[i]; ++i) {
1896 +    for (res=res0; res; res=res->ai_next) {
1897 +       switch (res->ai_addr->sa_family) {
1898 +       case AF_INET:
1899 +#ifdef INET6
1900 +       case AF_INET6:
1901 +#endif
1902 +           break;
1903 +       default:
1904 +           ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
1905 +                        "Unsupported address family %u, for host %s port %s --- ignoring!",
1906 +                        res->ai_addr->sa_family, hoststr, portstr);
1907 +           continue;
1908 +       }
1909         sar = ap_pcalloc(p, sizeof(server_addr_rec));
1910         **paddr = sar;
1911         *paddr = &sar->next;
1912 -       sar->host_addr = *(struct in_addr *) hep->h_addr_list[i];
1913 -       sar->host_port = port;
1914 +       memcpy(&sar->host_addr, res->ai_addr, res->ai_addrlen);
1915 +       if (getnameinfo(res->ai_addr, res->ai_addrlen, NULL, 0, servbuf,
1916 +                       sizeof(servbuf), NI_NUMERICSERV) == 0)
1917 +               sar->host_port = atoi(servbuf);
1918 +       else
1919 +               sar->host_port = 0;
1920         sar->virthost = ap_pstrdup(p, w);
1921      }
1922  
1923 -    if (t != NULL)
1924 -       *t = ':';
1925 +    freeaddrinfo(res0);
1926 +    if (t != NULL) *t = ':';
1927 +    if (u != NULL) *u = ']';
1928      return NULL;
1929  }
1930  
1931 @@ -207,7 +244,8 @@
1932      /* start the list of addreses */
1933      addrs = &s->addrs;
1934      while (hostname[0]) {
1935 -       err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
1936 +       err = get_addresses(p, ap_getword_conf(p, &hostname), NULL,
1937 +               &addrs, s->port);
1938         if (err) {
1939             *addrs = NULL;
1940             return err;
1941 @@ -225,10 +263,11 @@
1942  }
1943  
1944  
1945 -API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg)
1946 +API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *h, 
1947 +       char *p)
1948  {
1949      /* use whatever port the main server has at this point */
1950 -    return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
1951 +    return get_addresses(cmd->pool, h, p, &name_vhost_list_tail,
1952                             cmd->server->port);
1953  }
1954  
1955 @@ -302,6 +341,19 @@
1956      return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
1957  }
1958  
1959 +static unsigned hash_addr(struct sockaddr *sa)
1960 +{
1961 +    switch (sa->sa_family) {
1962 +    case AF_INET:
1963 +       return hash_inaddr(((struct sockaddr_in *)sa)->sin_addr.s_addr);
1964 +#ifdef INET6
1965 +    case AF_INET6:
1966 +       return hash_inaddr(((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12]);
1967 +#endif
1968 +    default:
1969 +       return hash_inaddr(sa->sa_family);
1970 +    }
1971 +}
1972  
1973  
1974  static ipaddr_chain *new_ipaddr_chain(pool *p,
1975 @@ -329,25 +381,77 @@
1976      return new;
1977  }
1978  
1979 -
1980 -static ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
1981 -    unsigned port)
1982 +static ap_inline ipaddr_chain *find_ipaddr(struct sockaddr *sa)
1983  {
1984      unsigned bucket;
1985      ipaddr_chain *trav;
1986 -    unsigned addr;
1987 +    char a[NI_MAXHOST], b[NI_MAXHOST];
1988  
1989      /* scan the hash table for an exact match first */
1990 -    addr = server_ip->s_addr;
1991 -    bucket = hash_inaddr(addr);
1992 +    bucket = hash_addr(sa);
1993      for (trav = iphash_table[bucket]; trav; trav = trav->next) {
1994         server_addr_rec *sar = trav->sar;
1995 -       if ((sar->host_addr.s_addr == addr)
1996 -           && (sar->host_port == 0 || sar->host_port == port
1997 -               || port == 0)) {
1998 -           return trav;
1999 +       if (sar->host_addr.ss_family != sa->sa_family)
2000 +           continue;
2001 +       switch (sa->sa_family) {
2002 +       case AF_INET:
2003 +         {
2004 +           struct sockaddr_in *sin1, *sin2;
2005 +           sin1 = (struct sockaddr_in *)&sar->host_addr;
2006 +           sin2 = (struct sockaddr_in *)sa;
2007 +           if (sin1->sin_port == 0 || sin2->sin_port == 0
2008 +            || sin1->sin_port == sin2->sin_port) {
2009 +               if (memcmp(&sin1->sin_addr, &sin2->sin_addr,
2010 +                       sizeof(sin1->sin_addr)) == 0) {
2011 +                   return trav;
2012 +               }
2013 +           }
2014 +           break;
2015 +         }
2016 +#ifdef INET6
2017 +       case AF_INET6:
2018 +         {
2019 +           struct sockaddr_in6 *sin1, *sin2;
2020 +           sin1 = (struct sockaddr_in6 *)&sar->host_addr;
2021 +           sin2 = (struct sockaddr_in6 *)sa;
2022 +           if (sin1->sin6_port == 0 || sin2->sin6_port == 0
2023 +            || sin1->sin6_port == sin2->sin6_port) {
2024 +               if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
2025 +                       sizeof(sin1->sin6_addr)) == 0) {
2026 +                   return trav;
2027 +               }
2028 +           }
2029 +           break;
2030 +         }
2031 +#endif
2032 +       default: /*unsupported*/
2033 +           break;
2034         }
2035      }
2036 +
2037 +#ifdef INET6
2038 +    if (sa->sa_family == AF_INET6 &&
2039 +       IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) {
2040 +       /*
2041 +        * This is just horrible.  I just hate IPv4 mapped address.  It
2042 +        * complicates access control too much.
2043 +        * Due to hashed lookup, we need to visit it again.
2044 +        */
2045 +       struct sockaddr_in sin;
2046 +
2047 +       memset(&sin, 0, sizeof(sin));
2048 +       sin.sin_family = AF_INET;
2049 +#ifdef SIN6_LEN
2050 +       sin.sin_len = sizeof(sin);
2051 +#endif
2052 +       sin.sin_port = ((struct sockaddr_in6 *)sa)->sin6_port;
2053 +       memcpy(&sin.sin_addr,
2054 +           &((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12],
2055 +           sizeof(sin.sin_addr));
2056 +       return find_ipaddr((struct sockaddr *)&sin);
2057 +    }
2058 +#endif
2059 +
2060      return NULL;
2061  }
2062  
2063 @@ -373,21 +477,7 @@
2064      int len;
2065      char buf[MAX_STRING_LEN];
2066  
2067 -    if (ic->sar->host_addr.s_addr == DEFAULT_VHOST_ADDR) {
2068 -       len = ap_snprintf(buf, sizeof(buf), "_default_:%u",
2069 -               ic->sar->host_port);
2070 -    }
2071 -    else if (ic->sar->host_addr.s_addr == INADDR_ANY) {
2072 -       len = ap_snprintf(buf, sizeof(buf), "*:%u",
2073 -               ic->sar->host_port);
2074 -    }
2075 -    else {
2076 -       len = ap_snprintf(buf, sizeof(buf), "%pA:%u",
2077 -               &ic->sar->host_addr, ic->sar->host_port);
2078 -    }
2079 -    if (ic->sar->host_port == 0) {
2080 -       buf[len-1] = '*';
2081 -    }
2082 +    len = ap_snprintf(buf, sizeof(buf), "%pI", &ic->sar->host_addr);
2083      if (ic->names == NULL) {
2084         if (ic->server == NULL)
2085             fprintf(f, "%-22s WARNING: No <VirtualHost> defined for this NameVirtualHost!\n", buf);
2086 @@ -515,10 +605,37 @@
2087       * occured in the config file, we'll copy it in that order.
2088       */
2089      for (sar = name_vhost_list; sar; sar = sar->next) {
2090 -       unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
2091 +       unsigned bucket = hash_addr((struct sockaddr *)&sar->host_addr);
2092         ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
2093 +       int wildcard;
2094  
2095 -       if (sar->host_addr.s_addr != INADDR_ANY) {
2096 +       wildcard = 0;
2097 +       switch (sar->host_addr.ss_family) {
2098 +       case AF_INET:
2099 +         {
2100 +           struct sockaddr_in *sin;
2101 +           sin = (struct sockaddr_in *)&sar->host_addr;
2102 +           if (sin->sin_addr.s_addr == INADDR_ANY)
2103 +               wildcard++;
2104 +           break;
2105 +         }
2106 +#ifdef INET6
2107 +       case AF_INET6:
2108 +         {
2109 +           struct sockaddr_in6 *sin6;
2110 +           sin6 = (struct sockaddr_in6 *)&sar->host_addr;
2111 +           if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == 0
2112 +            && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == 0
2113 +            && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == 0
2114 +            && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == 0) {
2115 +               wildcard++;
2116 +           }
2117 +           break;
2118 +         }
2119 +#endif
2120 +       }
2121 +
2122 +       if (!wildcard) {
2123             *iphash_table_tail[bucket] = ic;
2124             iphash_table_tail[bucket] = &ic->next;
2125         }
2126 @@ -545,12 +662,45 @@
2127         has_default_vhost_addr = 0;
2128         for (sar = s->addrs; sar; sar = sar->next) {
2129             ipaddr_chain *ic;
2130 +           int wildcard;
2131  
2132 -           if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
2133 -               || sar->host_addr.s_addr == INADDR_ANY) {
2134 -               ic = find_default_server(sar->host_port);
2135 -               if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
2136 -                   if (ic && ic->sar->host_port != 0) {
2137 +           wildcard = 0;
2138 +           switch (sar->host_addr.ss_family) {
2139 +           case AF_INET:
2140 +             {
2141 +               struct sockaddr_in *sin;
2142 +               sin = (struct sockaddr_in *)&sar->host_addr;
2143 +               if (sin->sin_addr.s_addr == DEFAULT_VHOST_ADDR)
2144 +                   wildcard++;
2145 +               else if (sin->sin_addr.s_addr == INADDR_ANY)
2146 +                   wildcard++;
2147 +               break;
2148 +             }
2149 +#ifdef INET6
2150 +           case AF_INET6:
2151 +             {
2152 +               struct sockaddr_in6 *sin6;
2153 +               sin6 = (struct sockaddr_in6 *)&sar->host_addr;
2154 +               if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == ~0
2155 +                && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == ~0
2156 +                && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == ~0
2157 +                && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == ~0) {
2158 +                   wildcard++;
2159 +               }
2160 +               break;
2161 +             }
2162 +#endif
2163 +           }
2164 +
2165 +           if (wildcard) {
2166 +               /* add it to default bucket for each appropriate sar
2167 +                * since we need to do a port test
2168 +                */
2169 +               ipaddr_chain *other;
2170 +
2171 +               other = find_default_server(sar->host_port);
2172 +               if (!other || !add_name_vhost_config(p, main_s, s, sar, other)) {
2173 +                   if (other && other->sar->host_port != 0) {
2174                         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
2175                             main_s, "_default_ VirtualHost overlap on port %u,"
2176                             " the first has precedence", sar->host_port);
2177 @@ -563,10 +713,11 @@
2178             }
2179             else {
2180                 /* see if it matches something we've already got */
2181 -               ic = find_ipaddr(&sar->host_addr, sar->host_port);
2182 +               ic = find_ipaddr((struct sockaddr *)&sar->host_addr);
2183  
2184                 if (!ic) {
2185 -                   unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
2186 +                   unsigned bucket =
2187 +                       hash_addr((struct sockaddr *)&sar->host_addr);
2188  
2189                     ic = new_ipaddr_chain(p, s, sar);
2190                     ic->next = *iphash_table_tail[bucket];
2191 @@ -603,19 +754,33 @@
2192             }
2193             else {
2194                 struct hostent *h;
2195 +               char hostnamebuf[MAXHOSTNAMELEN];
2196  
2197 -               if ((h = gethostbyaddr((char *) &(s->addrs->host_addr),
2198 -                                       sizeof(struct in_addr), AF_INET))) {
2199 -                   s->server_hostname = ap_pstrdup(p, (char *) h->h_name);
2200 +               if (!getnameinfo((struct sockaddr *)&s->addrs->host_addr,
2201 +#ifndef SIN6_LEN
2202 +                       SA_LEN((struct sockaddr *)&s->addrs->host_addr),
2203 +#else  
2204 +                       s->addrs->host_addr.ss_len,
2205 +#endif
2206 +                       hostnamebuf, sizeof(hostnamebuf),
2207 +                       NULL, 0, 0)) {
2208 +                   s->server_hostname = ap_pstrdup(p, hostnamebuf);
2209                 }
2210                 else {
2211                     /* again, what can we do?  They didn't specify a
2212                        ServerName, and their DNS isn't working. -djg */
2213 +                   getnameinfo((struct sockaddr *)&s->addrs->host_addr,
2214 +#ifndef SIN6_LEN
2215 +                       SA_LEN((struct sockaddr *)&s->addrs->host_addr),
2216 +#else  
2217 +                       s->addrs->host_addr.ss_len,
2218 +#endif
2219 +                       hostnamebuf, sizeof(hostnamebuf),
2220 +                       NULL, 0, NI_NUMERICHOST);
2221                     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, main_s,
2222                             "Failed to resolve server name "
2223                             "for %s (check DNS) -- or specify an explicit "
2224 -                           "ServerName",
2225 -                           inet_ntoa(s->addrs->host_addr));
2226 +                           "ServerName", hostnamebuf);
2227                     s->server_hostname =
2228                         ap_pstrdup(p, "bogus_host_without_reverse_dns");
2229                 }
2230 @@ -663,45 +828,80 @@
2231      const char *src;
2232      char *dst;
2233      const char *port_str;
2234 +    const char *u, *v = NULL;
2235  
2236      /* check and copy the host part */
2237 -    src = r->hostname;
2238 +    u = src = r->hostname;
2239  
2240      dst = host;
2241 -    while (*src) {
2242 -       if (*src == '.') {
2243 -           *dst++ = *src++;
2244 -           if (*src == '.')
2245 -               goto bad;
2246 -           else
2247 -               continue;
2248 -       }
2249 -       if (*src == '/' || *src == '\\') {
2250 -           goto bad;
2251 -       }
2252 -        if (*src == ':') {
2253 -            port_str = src + 1;
2254 -            /* check the port part */
2255 -            while (*++src) {
2256 -                if (!ap_isdigit(*src)) {
2257 +    if (*u == '[') { /* IPv6 numeral address in brackets */
2258 +        v = strchr(u, ']');
2259 +        if (v == NULL) {
2260 +            /* missing closing bracket */
2261 +            goto bad;
2262 +        }
2263 +        if (v == (u + 1)) {
2264 +            /* bad empty address */
2265 +            goto bad;
2266 +        }
2267 +        for (src = u+1; src < v; src++)  /* copy IPv6 adress */
2268 +            *dst = *src;
2269 +        v++;
2270 +        if (*v == ':') {
2271 +            port_str = v + 1;
2272 +            v++;
2273 +            while (*v) {  /* check if portnum is correct */
2274 +                if (!ap_isdigit(*v++))
2275                      goto bad;
2276 -                }
2277              }
2278 -            if (src[-1] == ':')
2279 +            if (v[-1] == ':')
2280 +               goto bad;
2281 +             else {
2282 +                 /* a known "good" port value */
2283 +                 int iport;
2284 +                 iport = atoi(port_str);
2285 +                 if (iport < 1 || iport > 65535) {
2286 +                     goto bad;
2287 +                 }
2288 +                 r->parsed_uri.port_str = ap_pstrdup(r->pool, port_str);
2289 +                 r->parsed_uri.port = iport;
2290 +             }
2291 +        }
2292 +    } else {
2293 +        while (*src) {
2294 +            if (*src == '.') {
2295 +                *dst++ = *src++;
2296 +                if (*src == '.')
2297 +                    goto bad;
2298 +                else
2299 +                    continue;
2300 +            }
2301 +            if (*src == '/' || *src == '\\') {
2302                  goto bad;
2303 -            else {
2304 -                /* a known "good" port value */
2305 -                int iport;
2306 -                iport = atoi(port_str);
2307 -                if (iport < 1 || iport > 65535) {
2308 +            }
2309 +            if (*src == ':') {
2310 +                port_str = src + 1;
2311 +                /* sheck the port part */
2312 +                while (*++src) {
2313 +                    if (!ap_isdigit(*src)) {
2314 +                        goto bad;
2315 +                    }
2316 +                }
2317 +                if (src[-1] == ':')
2318                      goto bad;
2319 +                else {
2320 +                  /* a known "good" port value */
2321 +                    int iport;
2322 +                    iport = atoi(port_str);
2323 +                    if (iport < 1 || iport > 65535) {
2324 +                        goto bad;
2325 +                    }
2326 +                    r->parsed_uri.port_str = ap_pstrdup(r->pool, port_str);
2327 +                    r->parsed_uri.port = iport;
2328                  }
2329 -                r->parsed_uri.port_str = ap_pstrdup(r->pool, port_str);
2330 -                r->parsed_uri.port = iport;
2331 -                break;
2332              }
2333 +            *dst++ = *src++;
2334          }
2335 -       *dst++ = *src++;
2336      }
2337      /* strip trailing gubbins */
2338      if (dst > host && dst[-1] == '.') {
2339 @@ -716,7 +916,7 @@
2340  bad:
2341      r->status = HTTP_BAD_REQUEST;
2342      ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
2343 -                 "Client sent malformed Host header");
2344 +                 "Client sent malformed Host header <<%s>>",u);
2345      return;
2346  }
2347  
2348 @@ -819,11 +1019,25 @@
2349       *   names we'll match have ports associated with them
2350       */
2351      const char *host = r->hostname;
2352 -    unsigned port = ntohs(r->connection->local_addr.sin_port);
2353 +    unsigned port;
2354      server_rec *s;
2355      server_rec *last_s;
2356      name_chain *src;
2357  
2358 +    switch (r->connection->local_addr.ss_family) {
2359 +    case AF_INET:
2360 +       port = ntohs(((struct sockaddr_in *)
2361 +                   &r->connection->local_addr)->sin_port);
2362 +       break;
2363 +#ifdef INET6
2364 +    case AF_INET6:
2365 +       port = ntohs(((struct sockaddr_in6 *)
2366 +                   &r->connection->local_addr)->sin6_port);
2367 +       break;
2368 +#endif
2369 +    default:
2370 +       port = 0;       /*XXX*/
2371 +    }
2372      last_s = NULL;
2373  
2374      /* Recall that the name_chain is a list of server_addr_recs, some of
2375 @@ -878,7 +1092,22 @@
2376      server_rec *s;
2377      server_rec *last_s;
2378      name_chain *src;
2379 -    unsigned port = ntohs(r->connection->local_addr.sin_port);
2380 +    unsigned port;
2381 +
2382 +    switch (r->connection->local_addr.ss_family) {
2383 +    case AF_INET:
2384 +       port = ntohs(((struct sockaddr_in *)
2385 +                   &r->connection->local_addr)->sin_port);
2386 +       break;
2387 +#ifdef INET6
2388 +    case AF_INET6:
2389 +       port = ntohs(((struct sockaddr_in6 *)
2390 +                   &r->connection->local_addr)->sin6_port);
2391 +       break;
2392 +#endif
2393 +    default:
2394 +       port = 0;       /*XXX*/
2395 +    }
2396  
2397      /*
2398       * This is in conjunction with the ServerPath code in http_core, so we
2399 @@ -938,10 +1167,22 @@
2400  API_EXPORT(void) ap_update_vhost_given_ip(conn_rec *conn)
2401  {
2402      ipaddr_chain *trav;
2403 -    unsigned port = ntohs(conn->local_addr.sin_port);
2404 +    char portbuf[NI_MAXSERV];
2405 +    unsigned port;
2406 +
2407 +    if (getnameinfo((struct sockaddr *)&conn->local_addr,
2408 +#ifndef SIN6_LEN
2409 +       SA_LEN((struct sockaddr *)&conn->local_addr),
2410 +#else  
2411 +       conn->local_addr.ss_len,
2412 +#endif
2413 +       NULL, 0, portbuf, sizeof(portbuf), NI_NUMERICSERV) != 0) {
2414 +       goto fail;
2415 +    }
2416 +    port = atoi(portbuf);
2417  
2418      /* scan the hash table for an exact match first */
2419 -    trav = find_ipaddr(&conn->local_addr.sin_addr, port);
2420 +    trav = find_ipaddr((struct sockaddr *)&conn->local_addr);
2421      if (trav) {
2422         /* save the name_chain for later in case this is a name-vhost */
2423         conn->vhost_lookup_data = trav->names;
2424 @@ -959,6 +1200,7 @@
2425         return;
2426      }
2427  
2428 +fail:
2429      /* otherwise we're stuck with just the main server
2430       * and no name-based vhosts
2431       */
2432 diff -Nur apache_1.3.28.orig/src/main/rfc1413.c apache_1.3.28/src/main/rfc1413.c
2433 --- apache_1.3.28.orig/src/main/rfc1413.c       Mon Feb  3 18:13:23 2003
2434 +++ apache_1.3.28/src/main/rfc1413.c    Fri Jul 25 12:15:05 2003
2435 @@ -82,6 +82,7 @@
2436  #include "http_log.h"          /* for aplog_error */
2437  #include "rfc1413.h"
2438  #include "http_main.h"         /* set_callback_and_alarm */
2439 +#include "sa_len.h"
2440  
2441  /* Local stuff. */
2442  /* Semi-well-known port */
2443 @@ -109,12 +110,13 @@
2444  
2445  /* bind_connect - bind both ends of a socket */
2446  /* Ambarish fix this. Very broken */
2447 -static int get_rfc1413(int sock, const struct sockaddr_in *our_sin,
2448 -                      const struct sockaddr_in *rmt_sin, 
2449 +static int get_rfc1413(int sock, const struct sockaddr *our_sin,
2450 +                      const struct sockaddr *rmt_sin, 
2451                        char user[RFC1413_USERLEN+1], server_rec *srv)
2452  {
2453 -    struct sockaddr_in rmt_query_sin, our_query_sin;
2454 -    unsigned int rmt_port, our_port;
2455 +    struct sockaddr_storage rmt_query_sin, our_query_sin;
2456 +    unsigned int o_rmt_port, o_our_port;       /* original port pair */
2457 +    unsigned int rmt_port, our_port;           /* replied port pair */
2458      int i;
2459      char *cp;
2460      char buffer[RFC1413_MAXDATA + 1];
2461 @@ -129,16 +131,47 @@
2462       * addresses from the query socket.
2463       */
2464  
2465 -    our_query_sin = *our_sin;
2466 -    our_query_sin.sin_port = htons(ANY_PORT);
2467 -#ifdef MPE 
2468 -    our_query_sin.sin_addr.s_addr = INADDR_ANY;
2469 +#ifndef SIN6_LEN
2470 +    memcpy(&our_query_sin, our_sin, SA_LEN(our_sin));
2471 +    memcpy(&rmt_query_sin, rmt_sin, SA_LEN(rmt_sin));
2472 +#else
2473 +    memcpy(&our_query_sin, our_sin, our_sin->sa_len);
2474 +    memcpy(&rmt_query_sin, rmt_sin, rmt_sin->sa_len);
2475  #endif
2476 -    rmt_query_sin = *rmt_sin;
2477 -    rmt_query_sin.sin_port = htons(RFC1413_PORT);
2478 +    switch (our_sin->sa_family) {
2479 +    case AF_INET:
2480 +#ifdef MPE
2481 +      ((struct sockaddr_in *)&our_query_sin)->sin_addr.s_addr = INADDR_ANY; /* XXX: htonl(??) */
2482 +#endif
2483 +      ((struct sockaddr_in *)&our_query_sin)->sin_port = htons(ANY_PORT);
2484 +      o_our_port = ntohs(((struct sockaddr_in *)our_sin)->sin_port);
2485 +      ((struct sockaddr_in *)&rmt_query_sin)->sin_port = htons(RFC1413_PORT);
2486 +      o_rmt_port = ntohs(((struct sockaddr_in *)rmt_sin)->sin_port);
2487 +      break;
2488 +#ifdef INET6
2489 +    case AF_INET6:
2490 +#ifdef MPE
2491 +      memcpy(&((struct sockaddr_in6 *)&our_query_sin)->sin6_addr, 
2492 +            &in6addr_any, sizeof(struct in6_addr));
2493 +#endif
2494 +      ((struct sockaddr_in6 *)&our_query_sin)->sin6_port = htons(ANY_PORT);
2495 +      o_our_port = ntohs(((struct sockaddr_in6 *)our_sin)->sin6_port);
2496 +      ((struct sockaddr_in6 *)&rmt_query_sin)->sin6_port = htons(RFC1413_PORT);
2497 +      o_rmt_port = ntohs(((struct sockaddr_in6 *)rmt_sin)->sin6_port);
2498 +      break;
2499 +#endif
2500 +    default:
2501 +      /* unsupported AF */
2502 +      return -1;
2503 +    }
2504  
2505      if (bind(sock, (struct sockaddr *) &our_query_sin,
2506 -            sizeof(struct sockaddr_in)) < 0) {
2507 +#ifndef SIN6_LEN
2508 +            SA_LEN((struct sockaddr *) &our_query_sin)
2509 +#else
2510 +            our_query_sin.ss_len
2511 +#endif
2512 +            ) < 0) {
2513         ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
2514                     "bind: rfc1413: Error binding to local port");
2515         return -1;
2516 @@ -149,12 +182,18 @@
2517   * the service
2518   */
2519      if (connect(sock, (struct sockaddr *) &rmt_query_sin,
2520 -               sizeof(struct sockaddr_in)) < 0)
2521 -                   return -1;
2522 +#ifndef SIN6_LEN
2523 +               SA_LEN((struct sockaddr *) &rmt_query_sin)
2524 +#else
2525 +               rmt_query_sin.ss_len
2526 +#endif
2527 +               ) < 0) {
2528 +       return -1;
2529 +    }
2530  
2531  /* send the data */
2532 -    buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", ntohs(rmt_sin->sin_port),
2533 -               ntohs(our_sin->sin_port));
2534 +    buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", o_rmt_port,
2535 +               o_our_port);
2536  
2537      /* send query to server. Handle short write. */
2538  #ifdef CHARSET_EBCDIC
2539 @@ -219,9 +258,9 @@
2540      ascii2ebcdic(buffer, buffer, (size_t)i);
2541  #endif
2542      if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port,
2543 -              user) != 3 || ntohs(rmt_sin->sin_port) != rmt_port
2544 -       || ntohs(our_sin->sin_port) != our_port)
2545 +              user) != 3 || o_rmt_port != rmt_port || o_our_port != our_port) {
2546         return -1;
2547 +    }
2548  
2549      /*
2550       * Strip trailing carriage return. It is part of the
2551 @@ -243,7 +282,7 @@
2552  
2553      result = FROM_UNKNOWN;
2554  
2555 -    sock = ap_psocket_ex(conn->pool, AF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
2556 +    sock = ap_psocket_ex(conn->pool, conn->remote_addr.ss_family, SOCK_STREAM, IPPROTO_TCP, 1);
2557      if (sock < 0) {
2558         ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
2559                     "socket: rfc1413: error creating socket");
2560 @@ -256,8 +295,10 @@
2561      if (ap_setjmp(timebuf) == 0) {
2562         ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout);
2563  
2564 -       if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user, srv) >= 0)
2565 +       if (get_rfc1413(sock, (struct sockaddr *)&conn->local_addr,
2566 +               (struct sockaddr *)&conn->remote_addr, user, srv) >= 0) {
2567             result = user;
2568 +       }
2569      }
2570      ap_set_callback_and_alarm(NULL, 0);
2571      ap_pclosesocket(conn->pool, sock);
2572 diff -Nur apache_1.3.28.orig/src/main/util.c apache_1.3.28/src/main/util.c
2573 --- apache_1.3.28.orig/src/main/util.c  Mon Feb  3 18:13:23 2003
2574 +++ apache_1.3.28/src/main/util.c       Fri Jul 25 11:01:55 2003
2575 @@ -2017,52 +2017,87 @@
2576   * Parses a host of the form <address>[:port]
2577   * :port is permitted if 'port' is not NULL
2578   */
2579 -API_EXPORT(unsigned long) ap_get_virthost_addr(char *w, unsigned short *ports)
2580 +API_EXPORT(struct sockaddr *) ap_get_virthost_addr(char *w, unsigned short *ports)
2581  {
2582 -    struct hostent *hep;
2583 -    unsigned long my_addr;
2584 -    char *p;
2585 -
2586 -    p = strchr(w, ':');
2587 +    static struct sockaddr_storage ss;
2588 +    struct addrinfo hints, *res;
2589 +    char *p, *r;
2590 +    char *host;
2591 +    char *port = "0";
2592 +    int error;
2593 +    char servbuf[NI_MAXSERV];
2594 +
2595 +    if (w == NULL)
2596 +       w = "*";
2597 +    p = r = NULL;
2598 +    if (*w == '['){
2599 +       if (r = strrchr(w+1, ']')){
2600 +           *r = '\0';
2601 +           p = r + 1;
2602 +           switch(*p){
2603 +           case ':':
2604 +             p++;
2605 +             /* nobreak; */
2606 +           case '\0':
2607 +             w++;
2608 +             break;
2609 +           default:
2610 +             p = NULL;
2611 +           }
2612 +       }
2613 +    }
2614 +    else{
2615 +       p = strchr(w, ':');
2616 +       if (p != NULL && strchr(p+1, ':') != NULL)
2617 +           p = NULL;
2618 +    }
2619      if (ports != NULL) {
2620 -       *ports = 0;
2621 -       if (p != NULL && strcmp(p + 1, "*") != 0)
2622 -           *ports = atoi(p + 1);
2623 +       if (p != NULL && *p && strcmp(p + 1, "*") != 0)
2624 +           port = p + 1;
2625      }
2626  
2627 +    memset(&hints, 0, sizeof(hints));
2628 +    hints.ai_socktype = SOCK_STREAM;
2629      if (p != NULL)
2630         *p = '\0';
2631      if (strcmp(w, "*") == 0) {
2632 -       if (p != NULL)
2633 -           *p = ':';
2634 -       return htonl(INADDR_ANY);
2635 -    }
2636 -
2637 -    my_addr = ap_inet_addr((char *)w);
2638 -    if (my_addr != INADDR_NONE) {
2639 -       if (p != NULL)
2640 -           *p = ':';
2641 -       return my_addr;
2642 +       host = NULL;
2643 +       hints.ai_flags = AI_PASSIVE;
2644 +       hints.ai_family = ap_default_family;
2645 +    } else {
2646 +       host = w;
2647 +       hints.ai_family = PF_UNSPEC;
2648      }
2649  
2650 -    hep = gethostbyname(w);
2651 +    error = getaddrinfo(host, port, &hints, &res);
2652  
2653 -    if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
2654 -       fprintf(stderr, "Cannot resolve host name %s --- exiting!\n", w);
2655 +    if (error || !res) {
2656 +       fprintf(stderr, "ap_get_vitrhost_addr(): getaddrinfo(%s):%s --- exiting!\n", w, gai_strerror(error));
2657         exit(1);
2658      }
2659  
2660 -    if (hep->h_addr_list[1]) {
2661 -       fprintf(stderr, "Host %s has multiple addresses ---\n", w);
2662 +    if (res->ai_next) {
2663 +       fprintf(stderr, "ap_get_vitrhost_addr(): Host %s has multiple addresses ---\n", w);
2664         fprintf(stderr, "you must choose one explicitly for use as\n");
2665         fprintf(stderr, "a virtual host.  Exiting!!!\n");
2666         exit(1);
2667      }
2668  
2669 +    if (r != NULL)
2670 +       *r = ']';
2671      if (p != NULL)
2672         *p = ':';
2673  
2674 -    return ((struct in_addr *) (hep->h_addr))->s_addr;
2675 +    memcpy(&ss, res->ai_addr, res->ai_addrlen);
2676 +    if (getnameinfo(res->ai_addr, res->ai_addrlen,
2677 +                   NULL, 0, servbuf, sizeof(servbuf),
2678 +                   NI_NUMERICSERV)){
2679 +       fprintf(stderr, "ap_get_virthost_addr(): getnameinfo() failed --- Exiting!!!\n");
2680 +       exit(1);
2681 +    }
2682 +    if (ports) *ports = atoi(servbuf);
2683 +    freeaddrinfo(res);
2684 +    return (struct sockaddr *)&ss;
2685  }
2686  
2687  
2688 @@ -2090,7 +2125,8 @@
2689  #endif
2690      char str[MAXHOSTNAMELEN];
2691      char *server_hostname = NULL;
2692 -    struct hostent *p;
2693 +    struct addrinfo hints, *res;
2694 +    int error;
2695  
2696  #ifdef BEOS /* BeOS returns zero as an error for gethostname */
2697      if (gethostname(str, sizeof(str) - 1) == 0) {
2698 @@ -2103,29 +2139,38 @@
2699      }
2700      else 
2701      {
2702 -        str[sizeof(str) - 1] = '\0';
2703 -        if ((!(p = gethostbyname(str))) 
2704 -            || (!(server_hostname = find_fqdn(a, p)))) {
2705 -            /* Recovery - return the default servername by IP: */
2706 -            if (p && p->h_addr_list && p->h_addr_list[0]) {
2707 -                ap_snprintf(str, sizeof(str), "%pA", p->h_addr_list[0]);
2708 -               server_hostname = ap_pstrdup(a, str);
2709 -                /* We will drop through to report the IP-named server */
2710 -            }
2711 -        }
2712 -       else
2713 -            /* Since we found a fqdn, return it with no logged message. */
2714 -            return server_hostname;
2715 -    }
2716 -
2717 -    /* If we don't have an fdqn or IP, fall back to the loopback addr */
2718 -    if (!server_hostname) 
2719 -        server_hostname = ap_pstrdup(a, "127.0.0.1");
2720 -    
2721 -    ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
2722 -                "%s: Could not determine the server's fully qualified "
2723 -                 "domain name, using %s for ServerName",
2724 -                 ap_server_argv0, server_hostname);
2725 +       str[sizeof(str) - 1] = '\0';
2726 +       memset(&hints, 0, sizeof(hints));
2727 +       hints.ai_family = PF_UNSPEC;
2728 +       hints.ai_flags = AI_CANONNAME;
2729 +       error = getaddrinfo(str, NULL, &hints, &res);
2730 +       if (error)
2731 +       {
2732 +              /* Recovery - return the default servername by IP: */
2733 +
2734 +           fprintf(stderr, "%s: cannot determine local host name.\n",
2735 +                 ap_server_argv0);
2736 +           fprintf(stderr, "Use the ServerName directive to set it manually.\n");
2737 +           exit(1);
2738 +
2739 +           server_hostname = ap_pstrdup(a, res->ai_canonname);
2740 +       }
2741 +       else if (1)     /*fqdn found*/
2742 +       {
2743 +           /* XXX should check more conditions */
2744 +           server_hostname = ap_pstrdup(a, res->ai_canonname);
2745 +       }
2746 +        else
2747 +       {
2748 +           ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
2749 +                        "%s: Could not determine the server's fully qualified "
2750 +                        "domain name, using %s for ServerName",
2751 +                        ap_server_argv0, server_hostname);
2752 +       }
2753 +
2754 +       /* Since we found a fdqn, return it with no logged message. */
2755 +       freeaddrinfo(res);
2756 +      }
2757      
2758      return server_hostname;
2759  }
2760 @@ -2369,3 +2414,11 @@
2761      }
2762      *dest = 0;
2763  }
2764 +
2765 +#ifdef NEED_GETADDRINFO
2766 +#include "getaddrinfo.c"
2767 +#endif
2768 +
2769 +#ifdef NEED_GETNAMEINFO
2770 +#include "getnameinfo.c"
2771 +#endif
2772 diff -Nur apache_1.3.28.orig/src/main/util_script.c apache_1.3.28/src/main/util_script.c
2773 --- apache_1.3.28.orig/src/main/util_script.c   Mon Feb  3 18:13:23 2003
2774 +++ apache_1.3.28/src/main/util_script.c        Fri Jul 25 11:01:55 2003
2775 @@ -67,6 +67,7 @@
2776  #include "http_request.h"      /* for sub_req_lookup_uri() */
2777  #include "util_script.h"
2778  #include "util_date.h"         /* For parseHTTPdate() */
2779 +#include "sa_len.h"
2780  
2781  #ifdef OS2
2782  #define INCL_DOS
2783 @@ -203,6 +204,7 @@
2784      array_header *hdrs_arr = ap_table_elts(r->headers_in);
2785      table_entry *hdrs = (table_entry *) hdrs_arr->elts;
2786      int i;
2787 +    char servbuf[NI_MAXSERV];
2788  
2789      /* use a temporary table which we'll overlap onto
2790       * r->subprocess_env later
2791 @@ -294,8 +296,16 @@
2792      ap_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
2793      ap_table_addn(e, "SCRIPT_FILENAME", r->filename);  /* Apache */
2794  
2795 -    ap_table_addn(e, "REMOTE_PORT",
2796 -                 ap_psprintf(r->pool, "%d", ntohs(c->remote_addr.sin_port)));
2797 +    servbuf[0] = '\0';
2798 +    if (!getnameinfo((struct sockaddr *)&c->remote_addr,
2799 +#ifndef HAVE_SOCKADDR_LEN
2800 +                    SA_LEN((struct sockaddr *)&c->remote_addr),
2801 +#else
2802 +                    c->remote_addr.ss_len,
2803 +#endif
2804 +                    NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)){
2805 +       ap_table_addn(e, "REMOTE_PORT", ap_pstrdup(r->pool, servbuf));
2806 +    }
2807  
2808      if (c->user) {
2809         ap_table_addn(e, "REMOTE_USER", c->user);
2810 diff -Nur apache_1.3.28.orig/src/main/util_uri.c apache_1.3.28/src/main/util_uri.c
2811 --- apache_1.3.28.orig/src/main/util_uri.c      Mon Feb  3 18:13:24 2003
2812 +++ apache_1.3.28/src/main/util_uri.c   Fri Jul 25 11:01:55 2003
2813 @@ -424,6 +424,12 @@
2814           * the hostname.  If there's a port it is the first colon.
2815           */
2816          s = memchr(hostinfo, ':', uri - hostinfo);
2817 +       if (*hostinfo == '[') {
2818 +           s = memchr(hostinfo+1, ']', uri - hostinfo - 1);
2819 +           if (s)
2820 +               s = strchr(s, ':');
2821 +       } else
2822 +           s = memchr(hostinfo, ':', uri - hostinfo);              
2823          if (s == NULL) {
2824              /* we expect the common case to have no port */
2825              uptr->hostname = ap_pstrndup(p, hostinfo, uri - hostinfo);
2826 @@ -480,7 +486,12 @@
2827      /* We expect hostinfo to point to the first character of
2828       * the hostname.  There must be a port, separated by a colon
2829       */
2830 -    s = strchr(hostinfo, ':');
2831 +    if (*hostinfo == '[') {
2832 +        s = strchr(hostinfo+1, ']');
2833 +        if (s)
2834 +            s = strchr(s, ':');
2835 +    } else
2836 +        s = strchr(hostinfo, ':');
2837      if (s == NULL) {
2838          return HTTP_BAD_REQUEST;
2839      }
2840 diff -Nur apache_1.3.28.orig/src/modules/proxy/mod_proxy.c apache_1.3.28/src/modules/proxy/mod_proxy.c
2841 --- apache_1.3.28.orig/src/modules/proxy/mod_proxy.c    Fri Jul 25 11:00:49 2003
2842 +++ apache_1.3.28/src/modules/proxy/mod_proxy.c Fri Jul 25 11:01:55 2003
2843 @@ -574,11 +574,31 @@
2844      struct proxy_remote *new;
2845      char *p, *q;
2846      int port;
2847 +    char *bl = NULL, *br = NULL;
2848  
2849      p = strchr(r, ':');
2850      if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0')
2851          return "ProxyRemote: Bad syntax for a remote proxy server";
2852 -    q = strchr(p + 3, ':');
2853 +    bl = p + 3;
2854 +    if (*bl == '['){
2855 +       br = strrchr(bl+1, ']');
2856 +       if (br){
2857 +           bl++;
2858 +           *br = '\0';
2859 +           if (*(br+1) == ':'){        /* [host]:xx */
2860 +               q = br+1;
2861 +           }
2862 +           else if (*(br+1) == '\0'){  /* [host] */
2863 +               q = NULL;
2864 +           }
2865 +           else
2866 +               q = strrchr(br, ':');   /* XXX */
2867 +       }
2868 +       else
2869 +           q = strrchr(bl, ':');       /* XXX */
2870 +    }
2871 +    else
2872 +       q = strrchr(bl, ':');
2873      if (q != NULL) {
2874          if (sscanf(q + 1, "%u", &port) != 1 || port > 65535)
2875              return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)";
2876 @@ -589,7 +609,7 @@
2877      *p = '\0';
2878      if (strchr(f, ':') == NULL)
2879          ap_str_tolower(f);      /* lowercase scheme */
2880 -    ap_str_tolower(p + 3);      /* lowercase hostname */
2881 +    ap_str_tolower(bl);         /* lowercase hostname */
2882  
2883      if (port == -1) {
2884          int i;
2885 @@ -602,7 +622,7 @@
2886      new = ap_push_array(conf->proxies);
2887      new->scheme = f;
2888      new->protocol = r;
2889 -    new->hostname = p + 3;
2890 +    new->hostname = bl;
2891      new->port = port;
2892      return NULL;
2893  }
2894 diff -Nur apache_1.3.28.orig/src/modules/proxy/mod_proxy.h apache_1.3.28/src/modules/proxy/mod_proxy.h
2895 --- apache_1.3.28.orig/src/modules/proxy/mod_proxy.h    Mon Feb  3 18:13:26 2003
2896 +++ apache_1.3.28/src/modules/proxy/mod_proxy.h Fri Jul 25 11:01:55 2003
2897 @@ -310,7 +310,7 @@
2898  int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p);
2899  int ap_proxy_is_hostname(struct dirconn_entry *This, pool *p);
2900  int ap_proxy_is_word(struct dirconn_entry *This, pool *p);
2901 -int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
2902 +int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r);
2903  int ap_proxy_garbage_init(server_rec *, pool *);
2904  /* This function is called by ap_table_do() for all header lines */
2905  int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
2906 diff -Nur apache_1.3.28.orig/src/modules/proxy/proxy_connect.c apache_1.3.28/src/modules/proxy/proxy_connect.c
2907 --- apache_1.3.28.orig/src/modules/proxy/proxy_connect.c        Mon Feb  3 18:13:26 2003
2908 +++ apache_1.3.28/src/modules/proxy/proxy_connect.c     Fri Jul 25 11:27:12 2003
2909 @@ -113,14 +113,15 @@
2910                                   const char *proxyhost, int proxyport)
2911  {
2912      struct sockaddr_in server;
2913 -    struct in_addr destaddr;
2914 -    struct hostent server_hp;
2915 -    const char *host, *err;
2916 +    struct addrinfo hints, *res, *res0;
2917 +    const char *hoststr;
2918 +    const char *portstr = NULL;
2919      char *p;
2920      int port, sock;
2921      char buffer[HUGE_STRING_LEN];
2922 -    int nbytes, i, j;
2923 +    int nbytes, i;
2924      fd_set fds;
2925 +    int error;
2926  
2927      void *sconf = r->server->module_config;
2928      proxy_server_conf *conf =
2929 @@ -128,27 +129,59 @@
2930      struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
2931  
2932      memset(&server, '\0', sizeof(server));
2933 +#ifdef HAVE_SOCKADDR_LEN
2934 +    server.sin_len = sizeof(server);
2935 +#endif
2936      server.sin_family = AF_INET;
2937  
2938      /* Break the URL into host:port pairs */
2939  
2940 -    host = url;
2941 +    hoststr = url;
2942      p = strchr(url, ':');
2943 -    if (p == NULL)
2944 -        port = DEFAULT_HTTPS_PORT;
2945 -    else {
2946 -        port = atoi(p + 1);
2947 +    if (p == NULL) {
2948 +       char pbuf[32];
2949 +       ap_snprintf(pbuf, sizeof(pbuf), "%d", DEFAULT_HTTPS_PORT);
2950 +       portstr = pbuf;
2951 +    } else {
2952 +       portstr = p + 1;
2953          *p = '\0';
2954      }
2955 +    port = atoi(portstr);
2956 +
2957 +    memset(&hints, 0, sizeof(hints));
2958 +    hints.ai_family = PF_UNSPEC;
2959 +    hints.ai_socktype = SOCK_STREAM;
2960 +    hints.ai_protocol = IPPROTO_TCP;
2961 +    error = getaddrinfo(hoststr, portstr, &hints, &res0);
2962 +    if (error) {
2963 +       return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
2964 +                   gai_strerror(error));       /* give up */
2965 +    }
2966  
2967  /* check if ProxyBlock directive on this host */
2968 -    destaddr.s_addr = ap_inet_addr(host);
2969 -    for (i = 0; i < conf->noproxies->nelts; i++) {
2970 -        if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL)
2971 -            || destaddr.s_addr == npent[i].addr.s_addr
2972 -            || npent[i].name[0] == '*')
2973 +    for (res = res0; res; res = res = res->ai_next) {
2974 +       struct sockaddr_in *sin;
2975 +       int fail;
2976 +
2977 +       fail = 0;
2978 +       for (i = 0; i < conf->noproxies->nelts; i++) {
2979 +           if (npent[i].name != NULL && strstr(hoststr, npent[i].name))
2980 +               fail++;
2981 +           if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
2982 +               fail++;
2983 +           switch (res->ai_family) {
2984 +           case AF_INET:
2985 +               sin = (struct sockaddr_in *)res->ai_addr;
2986 +               if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
2987 +                   fail++;
2988 +               break;
2989 +           }
2990 +       }
2991 +       if (fail) {
2992 +           freeaddrinfo(res0);
2993              return ap_proxyerror(r, HTTP_FORBIDDEN,
2994                                   "Connect to remote machine blocked");
2995 +       }
2996      }
2997  
2998      /* Check if it is an allowed port */
2999 @@ -159,34 +192,42 @@
3000          case DEFAULT_SNEWS_PORT:
3001              break;
3002          default:
3003 +           freeaddrinfo(res0);
3004              return HTTP_FORBIDDEN;
3005          }
3006      }
3007 -    else if (!allowed_port(conf, port))
3008 +    else if (!allowed_port(conf, port)) {
3009 +       freeaddrinfo(res0);
3010          return HTTP_FORBIDDEN;
3011 +    }
3012  
3013      if (proxyhost) {
3014 +       char pbuf[10];
3015 +
3016 +       freeaddrinfo(res0);
3017 +
3018 +       ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
3019 +       memset(&hints, 0, sizeof(hints));
3020 +       hints.ai_family = PF_UNSPEC;
3021 +       hints.ai_socktype = SOCK_STREAM;
3022 +       hints.ai_protocol = IPPROTO_TCP;
3023 +       error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
3024 +       if (error)
3025 +           return HTTP_INTERNAL_SERVER_ERROR;  /* XXX */
3026 +
3027          ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
3028               "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
3029      }
3030      else {
3031          ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
3032 -                     "CONNECT to %s on port %d", host, port);
3033 +                     "CONNECT to %s on port %d", hoststr, port);
3034      }
3035  
3036 -    /* Nasty cast to work around broken terniary expressions on MSVC */
3037 -    server.sin_port = htons((unsigned short)(proxyport ? proxyport : port));
3038 -    err = ap_proxy_host2addr(proxyhost ? proxyhost : host, &server_hp);
3039 -
3040 -    if (err != NULL)
3041 -        return ap_proxyerror(r,
3042 -            proxyhost ? HTTP_BAD_GATEWAY : HTTP_INTERNAL_SERVER_ERROR, err);
3043 -
3044 -    sock = ap_psocket_ex(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3045 -    if (sock == -1) {
3046 -        ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "proxy: error creating socket");
3047 -        return HTTP_INTERNAL_SERVER_ERROR;
3048 -    }
3049 +    sock = i = -1;
3050 +    for (res = res0; res; res = res->ai_next) {
3051 +       sock = ap_psocket_ex(r->pool, res->ai_family, res->ai_socktype, res->ai_protocol, 1);
3052 +       if (sock == -1)
3053 +           continue;
3054  
3055  #ifdef CHECK_FD_SETSIZE
3056      if (sock >= FD_SETSIZE) {
3057 @@ -196,19 +237,15 @@
3058                       "found, you probably need to rebuild Apache with a "
3059                       "larger FD_SETSIZE", sock, FD_SETSIZE);
3060          ap_pclosesocket(r->pool, sock);
3061 -        return HTTP_INTERNAL_SERVER_ERROR;
3062 +       continue;
3063      }
3064  #endif
3065  
3066 -    j = 0;
3067 -    while (server_hp.h_addr_list[j] != NULL) {
3068 -        memcpy(&server.sin_addr, server_hp.h_addr_list[j],
3069 -               sizeof(struct in_addr));
3070 -        i = ap_proxy_doconnect(sock, &server, r);
3071 +       i = ap_proxy_doconnect(sock, res->ai_addr, r);
3072          if (i == 0)
3073              break;
3074 -        j++;
3075      }
3076 +    freeaddrinfo(res0);
3077      if (i == -1) {
3078          ap_pclosesocket(r->pool, sock);
3079          return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, ap_pstrcat(r->pool,
3080 diff -Nur apache_1.3.28.orig/src/modules/proxy/proxy_ftp.c apache_1.3.28/src/modules/proxy/proxy_ftp.c
3081 --- apache_1.3.28.orig/src/modules/proxy/proxy_ftp.c    Mon Feb  3 18:13:26 2003
3082 +++ apache_1.3.28/src/modules/proxy/proxy_ftp.c Fri Jul 25 11:18:38 2003
3083 @@ -62,6 +62,7 @@
3084  #include "http_main.h"
3085  #include "http_log.h"
3086  #include "http_core.h"
3087 +#include "sa_len.h"
3088  
3089  #define AUTODETECT_PWD
3090  
3091 @@ -555,8 +556,10 @@
3092      const char *err;
3093      int port, i, j, len, rc, nocache = 0;
3094      int csd = 0, sock = -1, dsock = -1;
3095 -    struct sockaddr_in server;
3096 -    struct hostent server_hp;
3097 +    struct sockaddr_storage server;
3098 +    struct addrinfo hints, *res, *res0;
3099 +    char portbuf[10];
3100 +    int error;
3101      struct in_addr destaddr;
3102      table *resp_hdrs;
3103      BUFF *ctrl = NULL;
3104 @@ -577,11 +580,18 @@
3105      unsigned int presult, h0, h1, h2, h3, p0, p1;
3106      unsigned int paddr;
3107      unsigned short pport;
3108 -    struct sockaddr_in data_addr;
3109 +    struct sockaddr_storage data_addr;
3110 +    struct sockaddr_in *sin;
3111      int pasvmode = 0;
3112      char pasv[64];
3113      char *pstr;
3114  
3115 +/* stuff for LPSV/EPSV */
3116 +    unsigned int paf, holen, ho[16], polen, po[2];
3117 +    struct sockaddr_in6 *sin6;
3118 +    int lpsvmode = 0;
3119 +    char *cmd;
3120 +
3121  /* stuff for responses */
3122      char resp[MAX_STRING_LEN];
3123      char *size = NULL;
3124 @@ -658,62 +668,50 @@
3125      if (parms != NULL)
3126          *(parms++) = '\0';
3127  
3128 -    memset(&server, 0, sizeof(struct sockaddr_in));
3129 -    server.sin_family = AF_INET;
3130 -    server.sin_port = htons((unsigned short)destport);
3131 -    err = ap_proxy_host2addr(desthost, &server_hp);
3132 -    if (err != NULL)
3133 -        return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
3134 -
3135 -    sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3136 -    if (sock == -1) {
3137 -        ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3138 -                      "proxy: error creating socket");
3139 -        return HTTP_INTERNAL_SERVER_ERROR;
3140 +    ap_snprintf(portbuf, sizeof(portbuf), "%d", destport);
3141 +    memset(&hints, 0, sizeof(hints));
3142 +    hints.ai_family = PF_UNSPEC;
3143 +    hints.ai_socktype = SOCK_STREAM;
3144 +    error = getaddrinfo(desthost, portbuf, &hints, &res0);
3145 +    if (error) {
3146 +        return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, gai_strerror(error));
3147      }
3148  
3149 +    i = -1;
3150 +    for (res = res0; res; res = res->ai_next) {
3151 +       sock = ap_psocket_ex(p, res->ai_family, res->ai_socktype,
3152 +           res->ai_protocol, 1);
3153 +       if (sock == -1)
3154 +           continue;
3155 +
3156  #if !defined(TPF) && !defined(BEOS)
3157 -    if (conf->recv_buffer_size > 0
3158 -        && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
3159 -                      (const char *)&conf->recv_buffer_size, sizeof(int))
3160 -        == -1) {
3161 -        ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3162 -                      "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
3163 -    }
3164 +        if (conf->recv_buffer_size > 0
3165 +            && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
3166 +                          (const char *)&conf->recv_buffer_size, sizeof(int))
3167 +            == -1) {
3168 +            ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3169 +                          "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
3170 +        }
3171  #endif
3172  
3173 -    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
3174 -                   sizeof(one)) == -1) {
3175 +        if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
3176 +                       sizeof(one)) == -1) {
3177  #ifndef _OSD_POSIX              /* BS2000 has this option "always on" */
3178 -        ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3179 -         "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
3180 -        ap_pclosesocket(p, sock);
3181 -        return HTTP_INTERNAL_SERVER_ERROR;
3182 +            ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3183 +             "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
3184 +            ap_pclosesocket(p, sock);
3185 +           freeaddrinfo(res0);
3186 +            return HTTP_INTERNAL_SERVER_ERROR;
3187  #endif                          /* _OSD_POSIX */
3188 -    }
3189 -
3190 -#ifdef SINIX_D_RESOLVER_BUG
3191 -    {
3192 -        struct in_addr *ip_addr = (struct in_addr *)*server_hp.h_addr_list;
3193 -
3194 -        for (; ip_addr->s_addr != 0; ++ip_addr) {
3195 -            memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
3196 -            i = ap_proxy_doconnect(sock, &server, r);
3197 -            if (i == 0)
3198 -                break;
3199          }
3200 -    }
3201 -#else
3202 -    j = 0;
3203 -    while (server_hp.h_addr_list[j] != NULL) {
3204 -        memcpy(&server.sin_addr, server_hp.h_addr_list[j],
3205 -               sizeof(struct in_addr));
3206 -        i = ap_proxy_doconnect(sock, &server, r);
3207 -        if (i == 0)
3208 +        i = ap_proxy_doconnect(sock, res->ai_addr, r);
3209 +        if (i == 0) {
3210 +           memcpy(&server, res->ai_addr, res->ai_addrlen);
3211              break;
3212 -        j++;
3213 +       }
3214 +       ap_pclosesocket(p, sock);
3215      }
3216 -#endif
3217 +    freeaddrinfo(res0);
3218      if (i == -1) {
3219          return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3220                        ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool,
3221 @@ -944,7 +942,7 @@
3222      }
3223  
3224  /* try to set up PASV data connection first */
3225 -    dsock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3226 +    dsock = ap_psocket_ex(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP, 1);
3227      if (dsock == -1) {
3228          return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3229                                  ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3230 @@ -961,11 +959,22 @@
3231      }
3232  #endif
3233  
3234 -    ap_bputs("PASV" CRLF, ctrl);
3235 +lpsvagain:
3236 +    if (server.ss_family == AF_INET)
3237 +       cmd = "PASV";
3238 +    else if (lpsvmode)
3239 +       cmd = "LPSV";
3240 +    else
3241 +       cmd = "EPSV";
3242 +    ap_bputs(cmd, ctrl);
3243 +    ap_bputs(CRLF, ctrl);
3244      ap_bflush(ctrl);
3245 +    Explain0("FTP: passive command issued");
3246      ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: PASV command issued");
3247 -/* possible results: 227, 421, 500, 501, 502, 530 */
3248 +/* possible results: 227, 228, 229, 421, 500, 501, 502, 530 */
3249      /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */
3250 +    /* 228 Entering Long Passive Mode (...). */
3251 +    /* 229 Entering Extended Passive Mode (...). */
3252      /* 421 Service not available, closing control connection. */
3253      /* 500 Syntax error, command unrecognized. */
3254      /* 501 Syntax error in parameters or arguments. */
3255 @@ -976,7 +985,7 @@
3256      if (i == -1 || i == 421) {
3257          return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3258                                  ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3259 -                               "proxy: PASV: control connection is toast"));
3260 +                                  ap_psprintf(p, "proxy: %s: control connection is toast", cmd)));
3261      }
3262      else {
3263          pasv[i - 1] = '\0';
3264 @@ -1004,10 +1013,14 @@
3265              pport = (p1 << 8) + p0;
3266              ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: contacting host %d.%d.%d.%d:%d",
3267                           h3, h2, h1, h0, pport);
3268 -            data_addr.sin_family = AF_INET;
3269 -            data_addr.sin_addr.s_addr = htonl(paddr);
3270 -            data_addr.sin_port = htons(pport);
3271 -            i = ap_proxy_doconnect(dsock, &data_addr, r);
3272 +           sin = (struct sockaddr_in *)&data_addr;
3273 +           sin->sin_family = AF_INET;
3274 +#ifdef SIN6_LEN
3275 +           sin->sin_len = sizeof(*sin);
3276 +#endif
3277 +           sin->sin_addr.s_addr = htonl(paddr);
3278 +           sin->sin_port = htons(pport);
3279 +           i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
3280  
3281              if (i == -1) {
3282                  return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3283 @@ -1017,6 +1030,64 @@
3284                                                     strerror(errno), NULL)));
3285              }
3286              pasvmode = 1;
3287 +       } else if (presult == 228 && pstr != NULL
3288 +               && sscanf(pstr,
3289 +"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
3290 +                   &paf, &holen, &ho[0], &ho[1], &ho[2], &ho[3],
3291 +                   &ho[4], &ho[5], &ho[6], &ho[7], &ho[8], &ho[9], &ho[10], &ho[11],
3292 +                   &ho[12], &ho[13], &ho[14], &ho[15], &polen, &po[0], &po[1]) == 21
3293 +               && paf == 6 && holen == 16 && polen == 2) {
3294 +           int i;
3295 +           sin6 = (struct sockaddr_in6 *)&data_addr;
3296 +           sin6->sin6_family = AF_INET6;
3297 +#ifdef SIN6_LEN
3298 +           sin6->sin6_len = sizeof(*sin6);
3299 +#endif
3300 +           for (i = 0; i < 16; i++)
3301 +               sin6->sin6_addr.s6_addr[i] = ho[i] & 0xff;
3302 +           sin6->sin6_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
3303 +           i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
3304 +
3305 +           if (i == -1) {
3306 +               return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3307 +                         ap_proxyerror(r, HTTP_BAD_GATEWAY,
3308 +                            ap_pstrcat(r->pool,
3309 +                                       "Could not connect to remote machine: ",
3310 +                                       strerror(errno), NULL)));
3311 +           }
3312 +           pasvmode = 1;
3313 +       } else if (presult == 229 && pstr != NULL
3314 +               && pstr[0] == pstr[1] && pstr[0] == pstr[2]
3315 +               && pstr[0] == pstr[strlen(pstr) - 1]) {
3316 +           /* expect "|||port|" */
3317 +#ifndef SIN6_LEN
3318 +           memcpy(&data_addr, &server, SA_LEN((struct sockaddr *)&server));
3319 +#else
3320 +           memcpy(&data_addr, &server, server.ss_len);
3321 +#endif
3322 +           switch (data_addr.ss_family) {
3323 +           case AF_INET:
3324 +               sin = (struct sockaddr_in *)&data_addr;
3325 +               sin->sin_port = htons(atoi(pstr + 3));
3326 +               break;
3327 +           case AF_INET6:
3328 +               sin6 = (struct sockaddr_in6 *)&data_addr;
3329 +               sin6->sin6_port = htons(atoi(pstr + 3));
3330 +               break;
3331 +           }
3332 +           i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
3333 +
3334 +           if (i == -1) {
3335 +               return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3336 +                         ap_proxyerror(r, HTTP_BAD_GATEWAY,
3337 +                            ap_pstrcat(r->pool,
3338 +                                       "Could not connect to remote machine: ",
3339 +                                       strerror(errno), NULL)));
3340 +           }
3341 +           pasvmode = 1;
3342 +       } else if (!lpsvmode && strcmp(cmd, "EPSV") == 0) {
3343 +           lpsvmode = 1;
3344 +           goto lpsvagain;
3345          }
3346          else {
3347              ap_pclosesocket(p, dsock);  /* and try the regular way */
3348 @@ -1025,14 +1096,14 @@
3349      }
3350  
3351      if (!pasvmode) {            /* set up data connection */
3352 -        clen = sizeof(struct sockaddr_in);
3353 +        clen = sizeof(server);
3354          if (getsockname(sock, (struct sockaddr *)&server, &clen) < 0) {
3355              return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3356                                  ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3357                                      "proxy: error getting socket address"));
3358          }
3359  
3360 -        dsock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3361 +        dsock = ap_psocket_ex(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP, 1);
3362          if (dsock == -1) {
3363              return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3364                                  ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3365 @@ -1048,13 +1119,28 @@
3366  #endif                          /* _OSD_POSIX */
3367          }
3368  
3369 -        if (bind(dsock, (struct sockaddr *)&server,
3370 -                 sizeof(struct sockaddr_in)) == -1) {
3371 +#ifndef SIN6_LEN
3372 +       if (bind(dsock, (struct sockaddr *)&server, SA_LEN((struct sockaddr *)&server)) == -1)
3373 +#else
3374 +       if (bind(dsock, (struct sockaddr *)&server, server.ss_len) == -1)
3375 +#endif
3376 +       {
3377 +           char hostnamebuf[MAXHOSTNAMELEN], portnamebuf[MAXHOSTNAMELEN];
3378 +
3379 +           getnameinfo((struct sockaddr *)&server,
3380 +#ifndef SIN6_LEN
3381 +                   SA_LEN((struct sockaddr *)&server),
3382 +#else
3383 +                   server.ss_len,
3384 +#endif
3385 +               hostnamebuf, sizeof(hostnamebuf),
3386 +               portnamebuf, sizeof(portnamebuf),
3387 +               NI_NUMERICHOST | NI_NUMERICSERV);
3388  
3389              return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3390                                  ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3391 -             ap_psprintf(p, "proxy: error binding to ftp data socket %s:%d",
3392 -                         inet_ntoa(server.sin_addr), server.sin_port)));
3393 +             ap_psprintf(p, "proxy: error binding to ftp data socket %s:%s",
3394 +                         hostnamebuf, portnamebuf)));
3395          }
3396          listen(dsock, 2);       /* only need a short queue */
3397      }
3398 @@ -1308,7 +1394,7 @@
3399  
3400      if (!pasvmode) {            /* wait for connection */
3401          ap_hard_timeout("proxy ftp data connect", r);
3402 -        clen = sizeof(struct sockaddr_in);
3403 +        clen = sizeof(server);
3404          do
3405              csd = accept(dsock, (struct sockaddr *)&server, &clen);
3406          while (csd == -1 && errno == EINTR);
3407 --- apache_1.3.31/src/modules/proxy/proxy_http.c.orig   Wed May 12 12:56:16 2004
3408 +++ apache_1.3.31/src/modules/proxy/proxy_http.c        Wed May 12 14:09:27 2004
3409 @@ -113,9 +113,8 @@
3410      table *req_hdrs, *resp_hdrs;
3411      array_header *reqhdrs_arr;
3412      table_entry *reqhdrs_elts;
3413 -    struct sockaddr_in server;
3414 -    struct in_addr destaddr;
3415 -    struct hostent server_hp;
3416 +    struct addrinfo hints, *res, *res0;
3417 +    int error;
3418      BUFF *f;
3419      char buffer[HUGE_STRING_LEN];
3420      char portstr[32];
3421 @@ -141,9 +140,6 @@
3422      if (conf->cache.root == NULL)
3423          nocache = 1;
3424  
3425 -    memset(&server, '\0', sizeof(server));
3426 -    server.sin_family = AF_INET;
3427 -
3428      /* We break the URL into host, port, path-search */
3429  
3430      urlptr = strstr(url, "://");
3431 @@ -151,6 +147,8 @@
3432          return HTTP_BAD_REQUEST;
3433      urlptr += 3;
3434      destport = DEFAULT_HTTP_PORT;
3435 +    ap_snprintf(portstr, sizeof(portstr), "%d", DEFAULT_HTTP_PORT);
3436 +    destportstr = portstr;           
3437  #ifdef EAPI
3438      ap_hook_use("ap::mod_proxy::http::handler::set_destport", 
3439                  AP_HOOK_SIG2(int,ptr), 
3440 @@ -169,7 +167,20 @@
3441          urlptr = strp;
3442          desthost = q;
3443      }
3444 -
3445 +   if (*desthost == '['){
3446 +       char *u = strrchr(desthost+1, ']');
3447 +       if (u){
3448 +          desthost++;
3449 +          *u = '\0';
3450 +          if (*(u+1) == ':'){ /* [host]:xx */
3451 +              strp2 = u+1;
3452 +          } else if (*(u+1) == '\0'){   /* [host] */
3453 +              strp2 = NULL;
3454 +          } else
3455 +              return HTTP_BAD_REQUEST;
3456 +       } else
3457 +           return HTTP_BAD_REQUEST;
3458 +   } else
3459      strp2 = strchr(desthost, ':');
3460      if (strp2 != NULL) {
3461          *(strp2++) = '\0';
3462 @@ -179,46 +190,71 @@
3463          }
3464      }
3465  
3466 +    memset(&hints, 0, sizeof(hints));
3467 +    hints.ai_family = PF_UNSPEC;
3468 +    hints.ai_socktype = SOCK_STREAM;
3469 +    hints.ai_protocol = IPPROTO_TCP;
3470 +    error = getaddrinfo(desthost, destportstr, &hints, &res0);
3471 +    if (error) {
3472 +        return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3473 +               gai_strerror(error));       /* give up */
3474 +    }
3475 +    
3476      /* check if ProxyBlock directive on this host */
3477 -    destaddr.s_addr = ap_inet_addr(desthost);
3478 -    for (i = 0; i < conf->noproxies->nelts; i++) {
3479 -        if (destaddr.s_addr == npent[i].addr.s_addr ||
3480 -            (npent[i].name != NULL &&
3481 -             (npent[i].name[0] == '*' || strstr(desthost, npent[i].name) != NULL)))
3482 +    for (res = res0; res; res = res->ai_next) {
3483 +        struct sockaddr_in *sin;
3484 +#ifdef INET6
3485 +        struct sockaddr_in6 *sin6;
3486 +#endif
3487 +        int fail;
3488 +
3489 +        fail = 0;
3490 +        for (i = 0; i < conf->noproxies->nelts; i++) {
3491 +            if (npent[i].name != NULL && strstr(desthost, npent[i].name))
3492 +                fail++;
3493 +            if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
3494 +                fail++;
3495 +            switch (res->ai_family) {
3496 +                case AF_INET:
3497 +                    sin = (struct sockaddr_in *)res->ai_addr;
3498 +                    if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
3499 +                        fail++;
3500 +                    break;
3501 +           }
3502 +        }
3503 +        if (fail) {
3504 +            freeaddrinfo(res0);
3505              return ap_proxyerror(r, HTTP_FORBIDDEN,
3506                                   "Connect to remote machine blocked");
3507 +       }
3508      }
3509  
3510      if (proxyhost != NULL) {
3511 -        server.sin_port = htons((unsigned short)proxyport);
3512 -        err = ap_proxy_host2addr(proxyhost, &server_hp);
3513 -        if (err != NULL)
3514 +        char pbuf[10];
3515 +
3516 +        freeaddrinfo(res0);
3517 +        ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
3518 +        memset(&hints, 0, sizeof(hints));
3519 +        hints.ai_family = PF_UNSPEC;
3520 +        hints.ai_socktype = SOCK_STREAM;
3521 +        hints.ai_protocol = IPPROTO_TCP;
3522 +        error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
3523 +        if (error)
3524              return DECLINED;    /* try another */
3525  #ifdef EAPI
3526         peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);  
3527  #endif
3528      }
3529 -    else {
3530 -        server.sin_port = htons((unsigned short)destport);
3531 -        err = ap_proxy_host2addr(desthost, &server_hp);
3532 -        if (err != NULL)
3533 -            return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
3534 -#ifdef EAPI
3535 -       peer =  ap_psprintf(p, "%s:%u", desthost, destport);  
3536 -#endif
3537 -    }
3538 -
3539  
3540      /*
3541       * we have worked out who exactly we are going to connect to, now make
3542       * that connection...
3543       */
3544 -    sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3545 -    if (sock == -1) {
3546 -        ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3547 -                      "proxy: error creating socket");
3548 -        return HTTP_INTERNAL_SERVER_ERROR;
3549 -    }
3550 +    sock = i = -1;
3551 +    for (res = res0; res; res = res->ai_next) {
3552 +        sock = ap_psocket_ex(p, res->ai_family, res->ai_socktype, res->ai_protocol, 1);
3553 +        if (sock < 0)
3554 +            continue;
3555  
3556  #if !defined(TPF) && !defined(BEOS)
3557      if (conf->recv_buffer_size) {
3558 @@ -231,38 +267,13 @@
3559      }
3560  #endif
3561  
3562 -#ifdef SINIX_D_RESOLVER_BUG
3563 -    {
3564 -        struct in_addr *ip_addr = (struct in_addr *)*server_hp.h_addr_list;
3565 -
3566 -        for (; ip_addr->s_addr != 0; ++ip_addr) {
3567 -            memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
3568 -            i = ap_proxy_doconnect(sock, &server, r);
3569 -            if (i == 0)
3570 -                break;
3571 -            /*
3572 -             * Even if the connection was unsuccesful we should
3573 -             * reinit the socket
3574 -             */
3575 -            sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3576 -        }
3577 -    }
3578 -#else
3579 -    j = 0;
3580 -    while (server_hp.h_addr_list[j] != NULL) {
3581 -        memcpy(&server.sin_addr, server_hp.h_addr_list[j],
3582 -               sizeof(struct in_addr));
3583 -        i = ap_proxy_doconnect(sock, &server, r);
3584 +        i = ap_proxy_doconnect(sock, res->ai_addr, r);
3585          if (i == 0)
3586              break;
3587 -        /*
3588 -         * Even if the connection was unsuccesful we should
3589 -         * reinit the socket
3590 -         */
3591 -        sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3592 +        ap_pclosesocket(p, sock);
3593          j++;
3594      }
3595 -#endif
3596 +    freeaddrinfo(res0);
3597      if (i == -1) {
3598          if (proxyhost != NULL)
3599              return DECLINED;    /* try again another way */
3600 @@ -564,17 +575,30 @@
3601          ap_table_set(resp_hdrs, "Content-Location", proxy_location_reverse_map(r, urlstr));
3602  
3603  /* check if NoCache directive on this host */
3604 +  {
3605 +    struct sockaddr_in *sin;
3606 +#ifdef INET6
3607 +    struct sockaddr_in6 *sin6;
3608 +#endif
3609 +
3610      if (nocache == 0) {
3611          for (i = 0; i < conf->nocaches->nelts; i++) {
3612 -            if (destaddr.s_addr == ncent[i].addr.s_addr ||
3613 -                (ncent[i].name != NULL &&
3614 -                 (ncent[i].name[0] == '*' ||
3615 -                  strstr(desthost, ncent[i].name) != NULL))) {
3616 -                nocache = 1;
3617 -                break;
3618 +           if (ncent[i].name != NULL && 
3619 +               (ncent[i].name[0] == '*' ||
3620 +                strstr(desthost, ncent[i].name) != NULL)) {
3621 +               nocache = 1;
3622 +               break;
3623 +           }
3624 +           switch (res->ai_addr->sa_family) {
3625 +           case AF_INET:
3626 +               sin = (struct sockaddr_in *)res->ai_addr;
3627 +               if (sin->sin_addr.s_addr == ncent[i].addr.s_addr) {
3628 +                   nocache = 1;
3629 +                   break;
3630 +               }
3631              }
3632          }
3633 -
3634 +    }
3635          /*
3636           * update the cache file, possibly even fulfilling the request if it
3637           * turns out a conditional allowed us to serve the object from the
3638 diff -Nur apache_1.3.28.orig/src/modules/proxy/proxy_util.c apache_1.3.28/src/modules/proxy/proxy_util.c
3639 --- apache_1.3.28.orig/src/modules/proxy/proxy_util.c   Mon Feb  3 18:13:26 2003
3640 +++ apache_1.3.28/src/modules/proxy/proxy_util.c        Fri Jul 25 11:01:55 2003
3641 @@ -64,6 +64,7 @@
3642  #include "http_log.h"
3643  #include "util_uri.h"
3644  #include "util_date.h"          /* get ap_checkmask() decl. */
3645 +#include "sa_len.h"
3646  
3647  static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
3648  static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
3649 @@ -219,6 +220,7 @@
3650      int i;
3651      char *strp, *host, *url = *urlp;
3652      char *user = NULL, *password = NULL;
3653 +    char *t = NULL, *u = NULL, *v = NULL;
3654  
3655      if (url[0] != '/' || url[1] != '/')
3656          return "Malformed URL";
3657 @@ -257,11 +259,22 @@
3658          *passwordp = password;
3659      }
3660  
3661 -    strp = strrchr(host, ':');
3662 -    if (strp != NULL) {
3663 -        *(strp++) = '\0';
3664 -
3665 -        for (i = 0; strp[i] != '\0'; i++)
3666 +    v = host;
3667 +    if (*host == '['){
3668 +       u = strrchr(host, ']');
3669 +       if (u){
3670 +           host++;
3671 +           *u = '\0';
3672 +           v = u + 1;
3673 +       }
3674 +    }
3675 +    t = strrchr(v, ':');
3676 +    if (t){
3677 +       *t = '\0';
3678 +       strp = t + 1;
3679 +    }
3680 +    if (strp) {
3681 +       for (i=0; strp[i] != '\0'; i++)
3682              if (!ap_isdigit(strp[i]))
3683                  break;
3684  
3685 @@ -280,17 +293,29 @@
3686          return "Missing host in URL";
3687  /* check hostname syntax */
3688      for (i = 0; host[i] != '\0'; i++)
3689 -        if (!ap_isdigit(host[i]) && host[i] != '.')
3690 +        if (!ap_isdigit(host[i]) && host[i] != '.' && host[i] != ':')
3691              break;
3692      /* must be an IP address */
3693  #if defined(WIN32) || defined(NETWARE) || defined(TPF) || defined(BEOS)
3694      if (host[i] == '\0' && (inet_addr(host) == -1))
3695 +       return "Bad IP address in URL";
3696 +#else
3697 +    if (host[i] == '\0') {
3698 +       struct addrinfo hints, *res0;
3699 +       int gai;
3700 +       memset(&hints, 0, sizeof(hints));
3701 +       hints.ai_family = PF_UNSPEC;
3702 +       hints.ai_flags = AI_NUMERICHOST;
3703 +       if (gai = getaddrinfo(host, NULL, &hints, &res0)) {
3704 +#if 0
3705 +           return gai_strerror(gai);
3706  #else
3707 -    if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1))
3708 +           return "Bad IP address in URL";
3709  #endif
3710 -    {
3711 -        return "Bad IP address in URL";
3712 +       }
3713 +       freeaddrinfo(res0);
3714      }
3715 +#endif
3716  
3717  /*    if (strchr(host,'.') == NULL && domain != NULL)
3718     host = pstrcat(p, host, domain, NULL);
3719 @@ -1359,22 +1384,46 @@
3720      return host != NULL && strstr(host, This->name) != NULL;
3721  }
3722  
3723 -int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r)
3724 +int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r)
3725  {
3726      int i;
3727 +    int salen;
3728 +    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
3729 +#ifdef NI_WITHSCOPEID
3730 +    const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
3731 +#else
3732 +    const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
3733 +#endif
3734  
3735      ap_hard_timeout("proxy connect", r);
3736 +#ifdef HAVE_SOCKADDR_LEN
3737 +    salen = addr->sa_len;
3738 +#else
3739 +    switch (addr->sa_family) {
3740 +    case AF_INET6:
3741 +       salen = sizeof(struct sockaddr_in6);
3742 +       break;
3743 +    default:
3744 +       salen = sizeof(struct sockaddr_in);
3745 +       break;
3746 +    }
3747 +#endif
3748      do {
3749 -        i = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
3750 +        i = connect(sock, addr, salen);
3751  #if defined(WIN32) || defined(NETWARE)
3752          if (i == SOCKET_ERROR)
3753              errno = WSAGetLastError();
3754  #endif                          /* WIN32 */
3755      } while (i == -1 && errno == EINTR);
3756      if (i == -1) {
3757 +       if (getnameinfo(addr, salen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
3758 +               niflags) != 0) {
3759 +           strcpy(hbuf, "?");
3760 +           strcpy(pbuf, "?");
3761 +       }
3762          ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3763                        "proxy connect to %s port %d failed",
3764 -                      inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
3765 +                      hbuf, pbuf);
3766      }
3767      ap_kill_timeout(r);
3768  
3769 --- apache_1.3.31/src/modules/standard/mod_access.c.orig        Sun Mar  7 22:47:14 2004
3770 +++ apache_1.3.31/src/modules/standard/mod_access.c     Sat May 15 00:05:40 2004
3771 @@ -31,7 +31,10 @@
3772      T_ALL,
3773      T_IP,
3774      T_HOST,
3775 -    T_FAIL
3776 +    T_FAIL,
3777 +#ifdef INET6
3778 +    T_IP6,
3779 +#endif
3780  };
3781  
3782  typedef struct {
3783 @@ -42,6 +45,12 @@
3784             struct in_addr net;
3785             struct in_addr mask;
3786         } ip;
3787 +#ifdef INET6
3788 +       struct {
3789 +           struct in6_addr net6;
3790 +           struct in6_addr mask6;
3791 +       } ip6;
3792 +#endif
3793      } x;
3794      enum allowdeny_type type;
3795  } allowdeny;
3796 @@ -124,94 +133,242 @@
3797  
3798      }
3799      else if ((s = strchr(where, '/'))) {
3800 -       struct in_addr mask;
3801 +       struct addrinfo hints, *resnet, *resmask;
3802 +       struct sockaddr_storage net, mask;
3803 +       int error;
3804 +       char *p;
3805 +       int justdigits;
3806  
3807 -       a->type = T_IP;
3808 +       a->type = T_FAIL;       /*just in case*/
3809         /* trample on where, we won't be using it any more */
3810         *s++ = '\0';
3811  
3812 -       if (!is_ip(where)
3813 -           || (a->x.ip.net.s_addr = ap_inet_addr(where)) == INADDR_NONE) {
3814 +       justdigits = 0;
3815 +       for (p = s; *p; p++) {
3816 +           if (!isdigit(*p))
3817 +               break;
3818 +       }
3819 +       if (!*p)
3820 +           justdigits++;
3821 +
3822 +       memset(&hints, 0, sizeof(hints));
3823 +       hints.ai_family = PF_UNSPEC;
3824 +       hints.ai_socktype = SOCK_STREAM;        /*dummy*/
3825 +#ifdef AI_NUMERICHOST
3826 +       hints.ai_flags = AI_NUMERICHOST;        /*don't resolve*/
3827 +#endif
3828 +       resnet = NULL;
3829 +       error = getaddrinfo(where, NULL, &hints, &resnet);
3830 +       if (error || !resnet) {
3831 +           if (resnet)
3832 +               freeaddrinfo(resnet);
3833             a->type = T_FAIL;
3834             return "syntax error in network portion of network/netmask";
3835         }
3836 -
3837 -       /* is_ip just tests if it matches [\d.]+ */
3838 -       if (!is_ip(s)) {
3839 +       if (resnet->ai_next) {
3840 +           freeaddrinfo(resnet);
3841             a->type = T_FAIL;
3842 -           return "syntax error in mask portion of network/netmask";
3843 +           return "network/netmask resolved to multiple addresses";
3844         }
3845 -       /* is it in /a.b.c.d form? */
3846 -       if (strchr(s, '.')) {
3847 -           mask.s_addr = ap_inet_addr(s);
3848 -           if (mask.s_addr == INADDR_NONE) {
3849 -               a->type = T_FAIL;
3850 -               return "syntax error in mask portion of network/netmask";
3851 -           }
3852 +       memcpy(&net, resnet->ai_addr, resnet->ai_addrlen);
3853 +       freeaddrinfo(resnet);
3854 +
3855 +       switch (net.ss_family) {
3856 +       case AF_INET:
3857 +           a->type = T_IP;
3858 +           a->x.ip.net.s_addr = ((struct sockaddr_in *)&net)->sin_addr.s_addr;
3859 +           break;
3860 +#ifdef INET6
3861 +       case AF_INET6:
3862 +           a->type = T_IP6;
3863 +           memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&net)->sin6_addr,
3864 +               sizeof(a->x.ip6.net6));
3865 +           break;
3866 +#endif
3867 +       default:
3868 +           a->type = T_FAIL;
3869 +           return "unknown address family for network";
3870         }
3871 -       else {
3872 -           int i;
3873  
3874 -           /* assume it's in /nnn form */
3875 -           i = atoi(s);
3876 -           if (i > 32 || i <= 0) {
3877 +       if (!justdigits) {
3878 +           memset(&hints, 0, sizeof(hints));
3879 +           hints.ai_family = PF_UNSPEC;
3880 +           hints.ai_socktype = SOCK_STREAM;    /*dummy*/ 
3881 +#ifdef AI_NUMERICHOST
3882 +           hints.ai_flags = AI_NUMERICHOST;    /*don't resolve*/
3883 +#endif
3884 +           resmask = NULL;
3885 +           error = getaddrinfo(s, NULL, &hints, &resmask);
3886 +           if (error || !resmask) {
3887 +               if (resmask)
3888 +                   freeaddrinfo(resmask);
3889                 a->type = T_FAIL;
3890 -               return "invalid mask in network/netmask";
3891 +               return "syntax error in mask portion of network/netmask";
3892             }
3893 -           mask.s_addr = 0xFFFFFFFFUL << (32 - i);
3894 -           mask.s_addr = htonl(mask.s_addr);
3895 -       }
3896 -       a->x.ip.mask = mask;
3897 -        a->x.ip.net.s_addr  = (a->x.ip.net.s_addr & mask.s_addr);   /* pjr - This fixes PR 4770 */
3898 -    }
3899 -    else if (ap_isdigit(*where) && is_ip(where)) {
3900 -       /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
3901 -       int shift;
3902 -       char *t;
3903 -       int octet;
3904 -
3905 -       a->type = T_IP;
3906 -       /* parse components */
3907 -       s = where;
3908 -       a->x.ip.net.s_addr = 0;
3909 -       a->x.ip.mask.s_addr = 0;
3910 -       shift = 24;
3911 -       while (*s) {
3912 -           t = s;
3913 -           if (!ap_isdigit(*t)) {
3914 +           if (resmask->ai_next) {
3915 +               freeaddrinfo(resmask);
3916                 a->type = T_FAIL;
3917 -               return "invalid ip address";
3918 -           }
3919 -           while (ap_isdigit(*t)) {
3920 -               ++t;
3921 -           }
3922 -           if (*t == '.') {
3923 -               *t++ = 0;
3924 +               return "network/netmask resolved to multiple addresses";
3925             }
3926 -           else if (*t) {
3927 +           memcpy(&mask, resmask->ai_addr, resmask->ai_addrlen);
3928 +           freeaddrinfo(resmask);
3929 +
3930 +           if (net.ss_family != mask.ss_family) {
3931                 a->type = T_FAIL;
3932 -               return "invalid ip address";
3933 +               return "network/netmask resolved to different address family";
3934             }
3935 -           if (shift < 0) {
3936 -               a->type = T_FAIL;
3937 -               return "invalid ip address, only 4 octets allowed";
3938 +
3939 +           switch (a->type) {
3940 +           case T_IP:
3941 +               a->x.ip.mask.s_addr =
3942 +                   ((struct sockaddr_in *)&mask)->sin_addr.s_addr;
3943 +               break;
3944 +#ifdef INET6
3945 +           case T_IP6:
3946 +               memcpy(&a->x.ip6.mask6,
3947 +                   &((struct sockaddr_in6 *)&mask)->sin6_addr,
3948 +                   sizeof(a->x.ip6.mask6));
3949 +               break;
3950 +#endif
3951             }
3952 -           octet = atoi(s);
3953 -           if (octet < 0 || octet > 255) {
3954 -               a->type = T_FAIL;
3955 -               return "each octet must be between 0 and 255 inclusive";
3956 +       } else {
3957 +           int mask;
3958 +           mask = atoi(s);
3959 +           switch (a->type) {
3960 +           case T_IP:
3961 +               if (mask < 0 || 32 < mask) {
3962 +                   a->type = T_FAIL;
3963 +                   return "netmask out of range";
3964 +               }
3965 +               a->x.ip.mask.s_addr = htonl(0xFFFFFFFFUL << (32 - mask));
3966 +               break;
3967 +#ifdef INET6
3968 +           case T_IP6:
3969 +             {
3970 +               int i;
3971 +               if (mask < 0 || 128 < mask) {
3972 +                   a->type = T_FAIL;
3973 +                   return "netmask out of range";
3974 +               }
3975 +               for (i = 0; i < mask / 8; i++) {
3976 +                   a->x.ip6.mask6.s6_addr[i] = 0xff;
3977 +               }
3978 +               if (mask % 8)
3979 +                   a->x.ip6.mask6.s6_addr[i] = 0xff << (8 - (mask % 8));
3980 +               break;
3981 +             }
3982 +#endif
3983             }
3984 -           a->x.ip.net.s_addr |= (unsigned int)octet << shift;
3985 -           a->x.ip.mask.s_addr |= 0xFFUL << shift;
3986 -           s = t;
3987 -           shift -= 8;
3988         }
3989 -       a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
3990 -       a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
3991 +       /* mask network address */
3992 +       switch (a->type) {
3993 +       case T_IP:
3994 +           a->x.ip.net.s_addr &= a->x.ip.mask.s_addr;
3995 +           break;
3996 +       case T_IP6:
3997 +           a->x.ip6.net6.s6_addr32[0] &= a->x.ip6.mask6.s6_addr32[0];
3998 +           a->x.ip6.net6.s6_addr32[1] &= a->x.ip6.mask6.s6_addr32[1];
3999 +           a->x.ip6.net6.s6_addr32[2] &= a->x.ip6.mask6.s6_addr32[2];
4000 +           a->x.ip6.net6.s6_addr32[3] &= a->x.ip6.mask6.s6_addr32[3];
4001 +       }
4002      }
4003      else {
4004 -       a->type = T_HOST;
4005 -    }
4006 +       struct addrinfo hints, *res;
4007 +       struct sockaddr_storage ss;
4008 +       int error;
4009 +
4010 +       a->type = T_FAIL;       /*just in case*/
4011 +
4012 +       /* First, try using the old apache code to match */
4013 +       /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
4014 +       if (ap_isdigit(*where) && is_ip(where)) {
4015 +           int shift;
4016 +           char *t;
4017 +           int octet;
4018 +
4019 +           a->type = T_IP;
4020 +           /* parse components */
4021 +           s = where;
4022 +           a->x.ip.net.s_addr = 0;
4023 +           a->x.ip.mask.s_addr = 0;
4024 +           shift = 24;
4025 +           while (*s) {
4026 +               t = s;
4027 +               if (!ap_isdigit(*t)) {
4028 +                   a->type = T_FAIL;
4029 +                   return "invalid ip address";
4030 +               }
4031 +               while (ap_isdigit(*t)) {
4032 +                   ++t;
4033 +               }
4034 +               if (*t == '.') {
4035 +                   *t++ = 0;
4036 +               }
4037 +               else if (*t) {
4038 +                   a->type = T_FAIL;
4039 +                   return "invalid ip address";
4040 +               }
4041 +               if (shift < 0) {
4042 +                   return "invalid ip address, only 4 octets allowed";
4043 +               }
4044 +               octet = atoi(s);
4045 +               if (octet < 0 || octet > 255) {
4046 +                   a->type = T_FAIL;
4047 +                   return "each octet must be between 0 and 255 inclusive";
4048 +               }
4049 +               a->x.ip.net.s_addr |= (unsigned int)octet << shift;
4050 +               a->x.ip.mask.s_addr |= 0xFFUL << shift;
4051 +               s = t;
4052 +               shift -= 8;
4053 +           }
4054 +           a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
4055 +           a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
4056 +
4057 +           return NULL;
4058 +       }
4059 +
4060 +       /* IPv4/v6 numeric address */
4061 +       memset(&hints, 0, sizeof(hints));
4062 +       hints.ai_family = PF_UNSPEC;
4063 +       hints.ai_socktype = SOCK_STREAM;        /*dummy*/
4064 +#ifdef AI_NUMERICHOST
4065 +       hints.ai_flags = AI_NUMERICHOST;        /*don't resolve*/
4066 +#endif
4067 +       res = NULL;
4068 +       error = getaddrinfo(where, NULL, &hints, &res);
4069 +       if (error || !res) {
4070 +           if (res)
4071 +               freeaddrinfo(res);
4072 +           a->type = T_HOST;
4073 +           return NULL;
4074 +       }
4075 +       if (res->ai_next) {
4076 +           freeaddrinfo(res);
4077 +           a->type = T_FAIL;
4078 +           return "network/netmask resolved to multiple addresses";
4079 +       }
4080 +       memcpy(&ss, res->ai_addr, res->ai_addrlen);
4081 +       freeaddrinfo(res);
4082 +
4083 +       switch (ss.ss_family) {
4084 +       case AF_INET:
4085 +           a->type = T_IP;
4086 +           a->x.ip.net.s_addr = ((struct sockaddr_in *)&ss)->sin_addr.s_addr;
4087 +           memset(&a->x.ip.mask, 0xff, sizeof(a->x.ip.mask));
4088 +           break;
4089 +#ifdef INET6
4090 +       case AF_INET6:
4091 +           a->type = T_IP6;
4092 +           memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&ss)->sin6_addr,
4093 +               sizeof(a->x.ip6.net6));
4094 +           memset(&a->x.ip6.mask6, 0xff, sizeof(a->x.ip6.mask6));
4095 +           break;
4096 +#endif
4097 +       default:
4098 +           a->type = T_FAIL;
4099 +           return "unknown address family for network";
4100 +       }
4101 +      }
4102  
4103      return NULL;
4104  }
4105 @@ -275,13 +432,63 @@
4106             return 1;
4107  
4108         case T_IP:
4109 -           if (ap[i].x.ip.net.s_addr != INADDR_NONE
4110 -               && (r->connection->remote_addr.sin_addr.s_addr
4111 -                   & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
4112 -               return 1;
4113 +           if (ap[i].x.ip.net.s_addr == INADDR_NONE)
4114 +               break;
4115 +           switch (r->connection->remote_addr.ss_family) {
4116 +           case AF_INET:
4117 +               if ((((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr
4118 +                       & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
4119 +                   return 1;
4120 +               }
4121 +               break;
4122 +#ifdef INET6
4123 +           case AF_INET6:
4124 +               if (!IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr))    /*XXX*/
4125 +                   break;
4126 +               if ((*(ap_uint32_t *)&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr.s6_addr[12]
4127 +                       & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
4128 +                   return 1;
4129 +               }
4130 +               break;
4131 +#endif
4132             }
4133             break;
4134  
4135 +#ifdef INET6
4136 +       case T_IP6:
4137 +         {
4138 +           struct in6_addr masked;
4139 +           int j;
4140 +           if (IN6_IS_ADDR_UNSPECIFIED(&ap[i].x.ip6.net6))
4141 +               break;
4142 +           switch (r->connection->remote_addr.ss_family) {
4143 +           case AF_INET:
4144 +               if (!IN6_IS_ADDR_V4MAPPED(&ap[i].x.ip6.net6))   /*XXX*/
4145 +                   break;
4146 +               memset(&masked, 0, sizeof(masked));
4147 +               masked.s6_addr[10] = masked.s6_addr[11] = 0xff;
4148 +               memcpy(&masked.s6_addr[12],
4149 +                   &((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr,
4150 +                   sizeof(struct sockaddr_in));
4151 +               for (j = 0; j < sizeof(struct in6_addr); j++)
4152 +                       masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
4153 +               if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
4154 +                   return 1;
4155 +               break;
4156 +           case AF_INET6:
4157 +               memset(&masked, 0, sizeof(masked));
4158 +               memcpy(&masked,
4159 +                   &((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr,
4160 +                   sizeof(masked));
4161 +               for (j = 0; j < sizeof(struct in6_addr); j++)
4162 +                   masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
4163 +               if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
4164 +                   return 1;
4165 +               break;
4166 +           }
4167 +           break;
4168 +         }
4169 +#endif
4170         case T_HOST:
4171             if (!gothost) {
4172                 remotehost = ap_get_remote_host(r->connection, r->per_dir_config,
4173 diff -Nur apache_1.3.28.orig/src/modules/standard/mod_unique_id.c apache_1.3.28/src/modules/standard/mod_unique_id.c
4174 --- apache_1.3.28.orig/src/modules/standard/mod_unique_id.c     Mon Feb  3 18:13:30 2003
4175 +++ apache_1.3.28/src/modules/standard/mod_unique_id.c  Fri Jul 25 11:01:55 2003
4176 @@ -67,10 +67,22 @@
4177  #include "http_config.h"
4178  #include "http_log.h"
4179  #include "multithread.h"
4180 +#include "sa_len.h"
4181 +
4182 +/*#define SHORT_UNIQUE_ID*/
4183  
4184  typedef struct {
4185      unsigned int stamp;
4186 -    unsigned int in_addr;
4187 +    union {
4188 +       struct in_addr in;
4189 +#ifdef INET6
4190 +# ifdef SHORT_UNIQUE_ID
4191 +       ap_uint32_t in6;
4192 +# else
4193 +       struct in6_addr in6;
4194 +# endif
4195 +#endif
4196 +    } addr;
4197      unsigned int pid;
4198  #ifdef MULTITHREAD
4199      unsigned int tid;
4200 @@ -142,7 +154,7 @@
4201   * this shouldn't be a problem till year 2106.
4202   */
4203  
4204 -static unsigned global_in_addr;
4205 +static struct sockaddr_storage global_addr;
4206  
4207  #ifdef WIN32
4208  
4209 @@ -221,7 +233,8 @@
4210  #define MAXHOSTNAMELEN 256
4211  #endif
4212      char str[MAXHOSTNAMELEN + 1];
4213 -    struct hostent *hent;
4214 +    struct addrinfo hints, *res, *res0;
4215 +    int error;
4216  #ifndef NO_GETTIMEOFDAY
4217      struct timeval tv;
4218  #endif
4219 @@ -232,8 +245,8 @@
4220       */
4221      unique_id_rec_offset[0] = XtOffsetOf(unique_id_rec, stamp);
4222      unique_id_rec_size[0] = sizeof(cur_unique_id->stamp);
4223 -    unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, in_addr);
4224 -    unique_id_rec_size[1] = sizeof(cur_unique_id->in_addr);
4225 +    unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, addr);
4226 +    unique_id_rec_size[1] = sizeof(cur_unique_id->addr);
4227      unique_id_rec_offset[2] = XtOffsetOf(unique_id_rec, pid);
4228      unique_id_rec_size[2] = sizeof(cur_unique_id->pid);
4229  #ifdef MULTITHREAD
4230 @@ -269,17 +282,44 @@
4231      }
4232      str[sizeof(str) - 1] = '\0';
4233  
4234 -    if ((hent = gethostbyname(str)) == NULL) {
4235 +    memset(&hints, 0, sizeof(hints));
4236 +    hints.ai_family = PF_UNSPEC;
4237 +    error = getaddrinfo(str, NULL, &hints, &res0);
4238 +    if (error) {
4239          ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
4240 -                    "mod_unique_id: unable to gethostbyname(\"%s\")", str);
4241 +                     "mod_unique_id: getaddrinfo failed for \"%s\" (%s)", str,
4242 +                    gai_strerror(error));
4243          exit(1);
4244      }
4245  
4246 -    global_in_addr = ((struct in_addr *) hent->h_addr_list[0])->s_addr;
4247 +    error = 1;
4248 +    for (res = res0; res; res = res->ai_next) {
4249 +       switch (res->ai_family) {
4250 +       case AF_INET:
4251 +#ifdef INET6
4252 +       case AF_INET6:
4253 +#endif
4254 +           memcpy(&global_addr, res->ai_addr, res->ai_addrlen);
4255 +           error = 0;
4256 +           break;
4257 +       }
4258 +    }
4259 +    freeaddrinfo(res0);
4260 +    if (error) {
4261 +        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
4262 +                    "mod_unique_id: no known AF found for \"%s\"", str);
4263 +        exit(1);
4264 +    }
4265  
4266 +    getnameinfo((struct sockaddr *)&global_addr,
4267 +#ifndef SIN6_LEN
4268 +       SA_LEN((struct sockaddr *)&global_addr),
4269 +#else
4270 +       global_addr.ss_len,
4271 +#endif
4272 +       str, sizeof(str), NULL, 0, NI_NUMERICHOST);
4273      ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, s,
4274 -                "mod_unique_id: using ip addr %s",
4275 -                inet_ntoa(*(struct in_addr *) hent->h_addr_list[0]));
4276 +                 "mod_unique_id: using ip addr %s", str);
4277  
4278      /*
4279       * If the server is pummelled with restart requests we could possibly end
4280 @@ -336,7 +376,23 @@
4281                      "oh no! pids are greater than 32-bits!  I'm broken!");
4282      }
4283  
4284 -    cur_unique_id->in_addr = global_in_addr;
4285 +    memset(&cur_unique_id->addr, 0, sizeof(cur_unique_id->addr));
4286 +    switch (global_addr.ss_family) {
4287 +    case AF_INET:
4288 +       cur_unique_id->addr.in = ((struct sockaddr_in *)&global_addr)->sin_addr;
4289 +       break;
4290 +#ifdef INET6
4291 +    case AF_INET6:
4292 +#ifdef SHORT_UNIQUE_ID
4293 +       cur_unique_id->addr.in6 =
4294 +           ((struct sockaddr_in6 *)&global_addr)->sin6_addr.s6_addr32[3];
4295 +#else
4296 +       cur_unique_id->addr.in6 =
4297 +           ((struct sockaddr_in6 *)&global_addr)->sin6_addr;
4298 +#endif
4299 +       break;
4300 +#endif
4301 +    }
4302  
4303      /*
4304       * If we use 0 as the initial counter we have a little less protection
4305 diff -Nur apache_1.3.28.orig/src/support/ab.c apache_1.3.28/src/support/ab.c
4306 --- apache_1.3.28.orig/src/support/ab.c Sun Jul  6 19:52:27 2003
4307 +++ apache_1.3.28/src/support/ab.c      Fri Jul 25 11:01:55 2003
4308 @@ -158,6 +158,8 @@
4309  #include <sys/uio.h>
4310  #endif
4311  
4312 +#include "sa_len.h"
4313 +
4314  #endif                         /* NO_APACHE_INCLUDES */
4315  
4316  #ifdef USE_SSL
4317 @@ -246,7 +248,7 @@
4318  char servername[1024];         /* name that server reports */
4319  char hostname[1024];           /* host name */
4320  char proxyhost[1024];          /* proxy host name */
4321 -int proxyport = 0;             /* proxy port */
4322 +char *proxyport = NULL;                /* proxy port */
4323  int isproxy = 0;
4324  char path[1024];               /* path name */
4325  char postfile[1024];           /* name of file containing post data */
4326 @@ -262,7 +264,7 @@
4327       auth[1024],               /* optional (basic/uuencoded)
4328                                  * authentification */
4329       hdrs[4096];               /* optional arbitrary headers */
4330 -int port = 80;                 /* port number */
4331 +char *port = "80";             /* port number */
4332  
4333  int use_html = 0;              /* use html in the report */
4334  char *tablestring;
4335 @@ -299,7 +301,7 @@
4336  struct data *stats;            /* date for each request */
4337  
4338  fd_set readbits, writebits;    /* bits for select */
4339 -struct sockaddr_in server;     /* server addr structure */
4340 +struct sockaddr_storage server;      /* server addr structure */
4341  
4342  #ifndef BEOS
4343  #define ab_close(s) close(s)
4344 @@ -525,7 +527,7 @@
4345      printf("\r                                                                           \r");
4346      printf("Server Software:        %s\n", servername);
4347      printf("Server Hostname:        %s\n", hostname);
4348 -    printf("Server Port:            %d\n", port);
4349 +    printf("Server Port:            %s\n", port);
4350      printf("\n");
4351      printf("Document Path:          %s\n", path);
4352      printf("Document Length:        %d bytes\n", doclen);
4353 @@ -878,7 +880,7 @@
4354      c->cbx = 0;
4355      c->gotheader = 0;
4356  
4357 -    c->fd = socket(AF_INET, SOCK_STREAM, 0);
4358 +    c->fd = socket(server.ss_family, SOCK_STREAM, 0);
4359      if (c->fd < 0) {
4360         what = "SOCKET";
4361         goto _bad;
4362 @@ -895,7 +897,12 @@
4363  
4364  again:
4365      gettimeofday(&c->start, 0);
4366 -    if (connect(c->fd, (struct sockaddr *) & server, sizeof(server)) < 0) {
4367 +#ifndef SIN6_LEN
4368 +    if (connect(c->fd, (struct sockaddr *) & server, SA_LEN((struct sockaddr*)&server)) < 0)
4369 +#else
4370 +    if (connect(c->fd, (struct sockaddr *) & server, server.ss_len) < 0)
4371 +#endif
4372 +    {
4373         if (errno != EINPROGRESS) {
4374             what = "CONNECT";
4375             goto _bad;
4376 @@ -1189,7 +1196,7 @@
4377      struct timeval timeout, now;
4378      fd_set sel_read, sel_except, sel_write;
4379      long i;
4380 -    int connectport;
4381 +    char * connectport;
4382      char * connecthost;
4383      char * url_on_request;
4384  
4385 @@ -1232,17 +1239,21 @@
4386      }
4387      {
4388         /* get server information */
4389 -       struct hostent *he;
4390 -       he = gethostbyname(connecthost);
4391 -       if (!he) {
4392 -           char theerror[1024];
4393 -           ap_snprintf(theerror, sizeof(theerror),
4394 -                        "Bad hostname: %s\n", connecthost);
4395 -           err(theerror);
4396 -       }
4397 -       server.sin_family = he->h_addrtype;
4398 -       server.sin_port = htons(connectport);
4399 -       server.sin_addr.s_addr = ((unsigned long *) (he->h_addr_list[0]))[0];
4400 +       struct addrinfo hints, *res;
4401 +       int error;
4402 +
4403 +       memset(&hints, 0, sizeof(hints));
4404 +       hints.ai_family = PF_UNSPEC;
4405 +       hints.ai_socktype = SOCK_STREAM;
4406 +       error = getaddrinfo(connecthost, connectport, &hints, &res);
4407 +       if (error) {
4408 +               char *theerror=malloc(strlen(connecthost)+16);
4409 +               sprintf(theerror, "Bad hostname: %s\n", connecthost);
4410 +               err(theerror);
4411 +               free(theerror);
4412 +       }
4413 +       memcpy(&server, res->ai_addr, res->ai_addrlen);
4414 +       freeaddrinfo(res);
4415      }
4416  
4417      con = malloc(concurrency * sizeof(struct connection));
4418 @@ -1430,7 +1441,7 @@
4419      if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
4420         purl += 8;
4421         ssl = 1;
4422 -       port = 443;
4423 +       port = "443";
4424      }
4425  #else
4426      if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
4427 @@ -1451,15 +1462,15 @@
4428      *cp = '\0';
4429      strcpy(hostname, h);
4430      if (p != NULL)
4431 -       port = atoi(p);
4432 +       port = strdup(p);
4433  
4434      if ((
4435  #ifdef USE_SSL
4436 -       (ssl != 0) && (port != 443)) || ((ssl == 0) && 
4437 +       (ssl != 0) && (strcmp(port, "443"))) || ((ssl == 0) && 
4438  #endif
4439 -       (port != 80))) 
4440 +       (strcmp(port, "80")))) 
4441     {
4442 -       ap_snprintf(colonport,sizeof(colonport),":%d",port);
4443 +       ap_snprintf(colonport,sizeof(colonport),":%s",port);
4444     } else {
4445         colonport[0] = '\0';
4446     }
4447 @@ -1622,7 +1633,7 @@
4448                 if ((p = strchr(optarg, ':'))) {
4449                     *p = '\0';
4450                     p++;
4451 -                   proxyport = atoi(p);
4452 +                   proxyport = strdup(p);
4453                 };
4454                 strcpy(proxyhost, optarg);
4455                 isproxy = 1;
4456 @@ -1705,3 +1716,7 @@
4457  
4458      exit(0);
4459  }
4460 +
4461 +#ifdef NEED_GETADDRINFO
4462 +#include "../main/getaddrinfo.c"
4463 +#endif
4464 diff -Nur apache_1.3.28.orig/src/support/logresolve.c apache_1.3.28/src/support/logresolve.c
4465 --- apache_1.3.28.orig/src/support/logresolve.c Wed May 23 00:52:21 2001
4466 +++ apache_1.3.28/src/support/logresolve.c      Fri Jul 25 11:01:55 2003
4467 @@ -54,7 +54,9 @@
4468  #endif /* BEOS */
4469  #endif /* !MPE && !WIN32*/
4470  
4471 -static void cgethost(struct in_addr ipnum, char *string, int check);
4472 +#include "sa_len.h"
4473 +
4474 +static void cgethost(struct sockaddr *sa, char *string, int check);
4475  static int getline(char *s, int n);
4476  static void stats(FILE *output);
4477  
4478 @@ -91,7 +93,7 @@
4479   */
4480  
4481  struct nsrec {
4482 -    struct in_addr ipnum;
4483 +    struct sockaddr_storage addr;
4484      char *hostname;
4485      int noname;
4486      struct nsrec *next;
4487 @@ -122,17 +124,48 @@
4488   * IP numbers with their IP number as hostname, setting noname flag
4489   */
4490  
4491 -static void cgethost (struct in_addr ipnum, char *string, int check)
4492 +static void cgethost (struct sockaddr *sa, char *string, int check)
4493  {
4494 +    ap_uint32_t hashval;
4495 +    struct sockaddr_in *sin;
4496 +#ifdef INET6
4497 +    struct sockaddr_in6 *sin6;
4498 +#endif
4499      struct nsrec **current, *new;
4500 -    struct hostent *hostdata;
4501      char *name;
4502 +    char hostnamebuf[MAXHOSTNAMELEN];
4503 +
4504 +    switch (sa->sa_family) {
4505 +    case AF_INET:
4506 +       hashval = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
4507 +       break;
4508 +#ifdef INET6
4509 +    case AF_INET6:
4510 +       hashval = *(ap_uint32_t *)&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12];
4511 +       break;
4512 +#endif
4513 +    default:
4514 +       hashval = 0;
4515 +       break;
4516 +    }
4517 +
4518 +    current = &nscache[((hashval + (hashval >> 8) +
4519 +                        (hashval >> 16) + (hashval >> 24)) % BUCKETS)];
4520  
4521 -    current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) +
4522 -                        (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)];
4523 +    while (*current) {
4524 +#ifndef SIN6_LEN
4525 +       if (SA_LEN(sa) == SA_LEN((struct sockaddr *)&(*current)->addr)
4526 +        && memcmp(sa, &(*current)->addr, SA_LEN(sa)) == 0)
4527 +#else
4528 +       if (sa->sa_len == (*current)->addr.ss_len
4529 +        && memcmp(sa, &(*current)->addr, sa->sa_len) == 0)
4530 +#endif
4531 +       {
4532 +           break;
4533 +       }
4534  
4535 -    while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr)
4536         current = &(*current)->next;
4537 +    }
4538  
4539      if (*current == NULL) {
4540         cachesize++;
4541 @@ -145,45 +178,55 @@
4542         *current = new;
4543         new->next = NULL;
4544  
4545 -       new->ipnum = ipnum;
4546 +#ifndef SIN6_LEN
4547 +       memcpy(&new->addr, sa, SA_LEN(sa));
4548 +#else
4549 +       memcpy(&new->addr, sa, sa->sa_len);
4550 +#endif
4551  
4552 -       hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr),
4553 -                                AF_INET);
4554 -       if (hostdata == NULL) {
4555 -           if (h_errno > MAX_ERR)
4556 -               errors[UNKNOWN_ERR]++;
4557 -           else
4558 -               errors[h_errno]++;
4559 -           new->noname = h_errno;
4560 -           name = strdup(inet_ntoa(ipnum));
4561 -       }
4562 -       else {
4563 -           new->noname = 0;
4564 -           name = strdup(hostdata->h_name);
4565 -           if (check) {
4566 -               if (name == NULL) {
4567 -                   perror("strdup");
4568 -                   fprintf(stderr, "Insufficient memory\n");
4569 -                   exit(1);
4570 -               }
4571 -               hostdata = gethostbyname(name);
4572 -               if (hostdata != NULL) {
4573 -                   char **hptr;
4574 -
4575 -                   for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++)
4576 -                       if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr)
4577 -                           break;
4578 -                   if (*hptr == NULL)
4579 -                       hostdata = NULL;
4580 -               }
4581 -               if (hostdata == NULL) {
4582 -                   fprintf(stderr, "Bad host: %s != %s\n", name,
4583 -                           inet_ntoa(ipnum));
4584 -                   new->noname = NO_REVERSE;
4585 -                   free(name);
4586 -                   name = strdup(inet_ntoa(ipnum));
4587 -                   errors[NO_REVERSE]++;
4588 +       new->noname = getnameinfo(sa,
4589 +#ifndef SIN6_LEN
4590 +               SA_LEN(sa),
4591 +#else
4592 +               sa->sa_len,
4593 +#endif
4594 +                   hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0);
4595 +       name = strdup(hostnamebuf);
4596 +       if (check) {
4597 +           struct addrinfo hints, *res;
4598 +           int error;
4599 +           memset(&hints, 0, sizeof(hints));
4600 +           hints.ai_family = PF_UNSPEC;
4601 +           error = getaddrinfo(hostnamebuf, NULL, &hints, &res);
4602 +           if (!error) {
4603 +               while (res) {
4604 +#ifndef SIN6_LEN
4605 +                   if (SA_LEN(sa) == res->ai_addrlen
4606 +                    && memcmp(sa, res->ai_addr, SA_LEN(sa)) == 0)
4607 +#else
4608 +                   if (sa->sa_len == res->ai_addrlen
4609 +                    && memcmp(sa, res->ai_addr, sa->sa_len) == 0)
4610 +#endif
4611 +                   {
4612 +                       break;
4613 +                   }
4614 +                   res = res->ai_next;
4615                 }
4616 +               if (!res)
4617 +                   error++;
4618 +           }
4619 +           if (error) {
4620 +               getnameinfo(sa,
4621 +#ifndef SIN6_LEN
4622 +                   SA_LEN(sa),
4623 +#else
4624 +                   sa->sa_len,
4625 +#endif
4626 +                   hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
4627 +               fprintf(stderr, "Bad host: %s != %s\n", name, hostnamebuf);
4628 +               new->noname = NO_REVERSE;
4629 +               free(name);
4630 +               name = strdup(hostnamebuf);
4631             }
4632         }
4633         new->hostname = name;
4634 @@ -211,6 +254,7 @@
4635      char *ipstring;
4636      struct nsrec *current;
4637      char *errstring[MAX_ERR + 3];
4638 +    char hostnamebuf[MAXHOSTNAMELEN];
4639  
4640      for (i = 0; i < MAX_ERR + 3; i++)
4641         errstring[i] = "Unknown error";
4642 @@ -242,7 +286,14 @@
4643  
4644      for (i = 0; i < BUCKETS; i++)
4645         for (current = nscache[i]; current != NULL; current = current->next) {
4646 -           ipstring = inet_ntoa(current->ipnum);
4647 +           getnameinfo((struct sockaddr *)&current->addr,
4648 +#ifndef SIN6_LEN
4649 +                   SA_LEN((struct sockaddr *)&current->addr),
4650 +#else
4651 +                   current->addr.ss_len,
4652 +#endif
4653 +                   hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
4654 +           ipstring = hostnamebuf;
4655             if (current->noname == 0)
4656                 fprintf(output, "  %3d  %15s - %s\n", i, ipstring,
4657                         current->hostname);
4658 @@ -276,9 +327,10 @@
4659  
4660  int main (int argc, char *argv[])
4661  {
4662 -    struct in_addr ipnum;
4663      char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
4664      int i, check;
4665 +    struct addrinfo hints, *res;
4666 +    int error;
4667  
4668  #ifdef WIN32
4669      WSADATA wsaData;
4670 @@ -322,8 +374,10 @@
4671         bar = strchr(line, ' ');
4672         if (bar != NULL)
4673             *bar = '\0';
4674 -       ipnum.s_addr = inet_addr(line);
4675 -       if (ipnum.s_addr == 0xffffffffu) {
4676 +       memset(&hints, 0, sizeof(hints));
4677 +       hints.ai_family = PF_UNSPEC;
4678 +       error = getaddrinfo(line, NULL, &hints, &res);
4679 +       if (error) {
4680             if (bar != NULL)
4681                 *bar = ' ';
4682             puts(line);
4683 @@ -333,11 +387,12 @@
4684  
4685         resolves++;
4686  
4687 -       cgethost(ipnum, hoststring, check);
4688 +       cgethost(res->ai_addr, hoststring, check);
4689         if (bar != NULL)
4690             printf("%s %s\n", hoststring, bar + 1);
4691         else
4692             puts(hoststring);
4693 +       freeaddrinfo(res);
4694      }
4695  
4696  #ifdef WIN32
4697 @@ -358,3 +413,11 @@
4698  
4699      return (0);
4700  }
4701 +
4702 +#ifdef NEED_GETADDRINFO
4703 +#include "../main/getaddrinfo.c"
4704 +#endif
4705 +
4706 +#ifdef NEED_GETNAMEINFO
4707 +#include "../main/getnameinfo.c"
4708 +#endif
4709 --- apache_1.3.28/src/modules/standard/mod_usertrack.c.orig     Mon Feb  3 18:13:30 2003
4710 +++ apache_1.3.28/src/modules/standard/mod_usertrack.c  Fri Jul 25 13:13:43 2003
4711 @@ -162,7 +162,7 @@
4712      long reqtime = (long) r->request_time;
4713      long clocktime;
4714  
4715 -    unsigned long ipaddr = ntohl(r->connection->remote_addr.sin_addr.s_addr);
4716 +    unsigned long ipaddr = ntohl(((struct sockaddr_in*)&r->connection->remote_addr)->sin_addr.s_addr);
4717      const char *rname = ap_get_remote_host(r->connection, r->per_dir_config,
4718                                            REMOTE_NAME);
4719      dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module);
4720 --- apache_1.3.31/src/modules/standard/mod_rewrite.c.orig       Wed May 12 14:57:09 2004
4721 +++ apache_1.3.31/src/modules/standard/mod_rewrite.c    Wed May 12 15:40:04 2004
4722 @@ -48,6 +48,7 @@
4723  
4724  
4725  #include "mod_rewrite.h"
4726 +#include "sa_len.h"
4727  
4728  #ifndef NO_WRITEV
4729  #ifndef NETWARE
4730 @@ -3651,8 +3652,19 @@
4731          result = r->connection->remote_ip;
4732      }
4733      else if (strcasecmp(var, "REMOTE_PORT") == 0) {
4734 -        return ap_psprintf(r->pool, "%d",
4735 -                           ntohs(r->connection->remote_addr.sin_port));
4736 +       char servbuf[NI_MAXSERV];
4737 +       servbuf[0] = '\0';
4738 +       if (!getnameinfo((struct sockaddr *)&r->connection->remote_addr,
4739 +#ifndef HAVE_SOCKADDR_LEN
4740 +                    SA_LEN((struct sockaddr *)&r->connection->remote_addr),
4741 +#else
4742 +                    r->connection->remote_addr.ss_len,
4743 +#endif
4744 +                    NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)) {
4745 +               return ap_pstrdup(r->pool, servbuf);
4746 +       } else {
4747 +               return ap_pstrdup(r->pool, "");
4748 +       }
4749      }
4750      else if (strcasecmp(var, "REMOTE_HOST") == 0) {
4751          result = (char *)ap_get_remote_host(r->connection,
This page took 0.422836 seconds and 3 git commands to generate.