]> git.pld-linux.org Git - packages/apache1.git/blob - apache-ipv6-PLD.patch
- fixed title bug;
[packages/apache1.git] / apache-ipv6-PLD.patch
1 diff -Nur apache_1.3.23.orig/README.v6 apache_1.3.23/README.v6
2 --- apache_1.3.23.orig/README.v6        Thu Jan  1 01:00:00 1970
3 +++ apache_1.3.23/README.v6     Wed Feb  6 20:20:48 2002
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.23.orig/conf/httpd.conf-dist apache_1.3.23/conf/httpd.conf-dist
172 --- apache_1.3.23.orig/conf/httpd.conf-dist     Wed Jan  9 17:05:31 2002
173 +++ apache_1.3.23/conf/httpd.conf-dist  Wed Feb  6 20:20:48 2002
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.23.orig/configure.v6 apache_1.3.23/configure.v6
187 --- apache_1.3.23.orig/configure.v6     Thu Jan  1 01:00:00 1970
188 +++ apache_1.3.23/configure.v6  Wed Feb  6 20:20:48 2002
189 @@ -0,0 +1,3 @@
190 +#! /bin/sh
191 +
192 +./configure --enable-rule=INET6 --enable-module=proxy $*
193 diff -Nur apache_1.3.23.orig/src/Configuration.tmpl apache_1.3.23/src/Configuration.tmpl
194 --- apache_1.3.23.orig/src/Configuration.tmpl   Wed Feb  6 20:17:43 2002
195 +++ apache_1.3.23/src/Configuration.tmpl        Wed Feb  6 20:21:56 2002
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.23.orig/src/Configure apache_1.3.23/src/Configure
215 --- apache_1.3.23.orig/src/Configure    Wed Feb  6 20:17:43 2002
216 +++ apache_1.3.23/src/Configure Wed Feb  6 20:20:48 2002
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 @@ -1698,6 +1699,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 @@ -2293,6 +2412,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.23.orig/src/ap/ap_snprintf.c apache_1.3.23/src/ap/ap_snprintf.c
390 --- apache_1.3.23.orig/src/ap/ap_snprintf.c     Mon Jan 21 22:56:43 2002
391 +++ apache_1.3.23/src/ap/ap_snprintf.c  Wed Feb  6 20:20:48 2002
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 @@ -504,6 +505,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 @@ -1055,6 +1092,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 @@ -1063,6 +1101,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.23.orig/src/include/ap.h apache_1.3.23/src/include/ap.h
469 --- apache_1.3.23.orig/src/include/ap.h Mon Jan 21 22:56:43 2002
470 +++ apache_1.3.23/src/include/ap.h      Wed Feb  6 20:20:48 2002
471 @@ -91,7 +91,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.23.orig/src/include/ap_config.h apache_1.3.23/src/include/ap_config.h
482 --- apache_1.3.23.orig/src/include/ap_config.h  Thu Jan 17 14:20:51 2002
483 +++ apache_1.3.23/src/include/ap_config.h       Wed Feb  6 20:20:48 2002
484 @@ -407,6 +407,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 @@ -1507,6 +1511,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.23.orig/src/include/http_conf_globals.h apache_1.3.23/src/include/http_conf_globals.h
567 --- apache_1.3.23.orig/src/include/http_conf_globals.h  Wed Feb  6 20:17:43 2002
568 +++ apache_1.3.23/src/include/http_conf_globals.h       Wed Feb  6 20:23:09 2002
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.23.orig/src/include/http_vhost.h apache_1.3.23/src/include/http_vhost.h
580 --- apache_1.3.23.orig/src/include/http_vhost.h Mon Jan 21 00:13:51 2002
581 +++ apache_1.3.23/src/include/http_vhost.h      Wed Feb  6 20:23:58 2002
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.23.orig/src/include/httpd.h apache_1.3.23/src/include/httpd.h
592 --- apache_1.3.23.orig/src/include/httpd.h      Wed Feb  6 20:17:43 2002
593 +++ apache_1.3.23/src/include/httpd.h   Wed Feb  6 20:24:49 2002
594 @@ -912,8 +912,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 @@ -955,8 +955,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 @@ -1024,7 +1024,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.23.orig/src/include/sa_len.h apache_1.3.23/src/include/sa_len.h
635 --- apache_1.3.23.orig/src/include/sa_len.h     Thu Jan  1 01:00:00 1970
636 +++ apache_1.3.23/src/include/sa_len.h  Wed Feb  6 20:20:48 2002
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.23.orig/src/include/sockaddr_storage.h apache_1.3.23/src/include/sockaddr_storage.h
680 --- apache_1.3.23.orig/src/include/sockaddr_storage.h   Thu Jan  1 01:00:00 1970
681 +++ apache_1.3.23/src/include/sockaddr_storage.h        Wed Feb  6 20:20:48 2002
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.23.orig/src/main/getaddrinfo.c apache_1.3.23/src/main/getaddrinfo.c
737 --- apache_1.3.23.orig/src/main/getaddrinfo.c   Thu Jan  1 01:00:00 1970
738 +++ apache_1.3.23/src/main/getaddrinfo.c        Wed Feb  6 20:20:48 2002
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.23.orig/src/main/getnameinfo.c apache_1.3.23/src/main/getnameinfo.c
903 --- apache_1.3.23.orig/src/main/getnameinfo.c   Thu Jan  1 01:00:00 1970
904 +++ apache_1.3.23/src/main/getnameinfo.c        Wed Feb  6 20:20:48 2002
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.23.orig/src/main/http_config.c apache_1.3.23/src/main/http_config.c
1002 --- apache_1.3.23.orig/src/main/http_config.c   Wed Feb  6 20:17:43 2002
1003 +++ apache_1.3.23/src/main/http_config.c        Wed Feb  6 20:28:01 2002
1004 @@ -1564,7 +1564,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 @@ -1597,7 +1596,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 @@ -1616,21 +1621,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 diff -Nur apache_1.3.23.orig/src/main/http_core.c apache_1.3.23/src/main/http_core.c
1067 --- apache_1.3.23.orig/src/main/http_core.c     Wed Jan 16 22:34:32 2002
1068 +++ apache_1.3.23/src/main/http_core.c  Wed Feb  6 20:20:48 2002
1069 @@ -71,6 +71,7 @@
1070  #include "util_md5.h"
1071  #include "scoreboard.h"
1072  #include "fnmatch.h"
1073 +#include "sa_len.h"
1074  
1075  #ifdef USE_MMAP_FILES
1076  #include <sys/mman.h>
1077 @@ -621,7 +622,9 @@
1078  /* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
1079  static ap_inline void do_double_reverse (conn_rec *conn)
1080  {
1081 -    struct hostent *hptr;
1082 +    struct addrinfo hints, *res, *res0;
1083 +    char hostbuf1[128], hostbuf2[128]; /* INET6_ADDRSTRLEN(=46) is enough */
1084 +    int ok = 0;
1085  
1086      if (conn->double_reverse) {
1087         /* already done */
1088 @@ -632,28 +635,51 @@
1089         conn->double_reverse = -1;
1090         return;
1091      }
1092 -    hptr = gethostbyname(conn->remote_host);
1093 -    if (hptr) {
1094 -       char **haddr;
1095 -
1096 -       for (haddr = hptr->h_addr_list; *haddr; haddr++) {
1097 -           if (((struct in_addr *)(*haddr))->s_addr
1098 -               == conn->remote_addr.sin_addr.s_addr) {
1099 -               conn->double_reverse = 1;
1100 -               return;
1101 -           }
1102 +    memset(&hints, 0, sizeof(hints));
1103 +    hints.ai_family = PF_UNSPEC;
1104 +    hints.ai_socktype = SOCK_STREAM;
1105 +    if (getaddrinfo(conn->remote_host, NULL, &hints, &res0)) {
1106 +       conn->double_reverse = -1;
1107 +       return;
1108 +    }
1109 +    for (res = res0; res; res = res->ai_next) {
1110 +       if (res->ai_addr->sa_family != conn->remote_addr.ss_family ||
1111 +           !(res->ai_family == AF_INET 
1112 +#ifdef INET6
1113 +             || res->ai_family == AF_INET6
1114 +#endif
1115 +             )
1116 +           )
1117 +           continue;
1118 +#ifndef HAVE_SOCKADDR_LEN
1119 +       if (res->ai_addrlen != SA_LEN((struct sockaddr *)&conn->remote_addr))
1120 +#else
1121 +       if (res->ai_addr->sa_len != conn->remote_addr.ss_len)
1122 +#endif
1123 +           continue;
1124 +       if (getnameinfo(res->ai_addr, res->ai_addrlen,
1125 +            hostbuf1, sizeof(hostbuf1), NULL, 0,
1126 +            NI_NUMERICHOST))
1127 +           continue;
1128 +       if (getnameinfo(((struct sockaddr *)&conn->remote_addr), res->ai_addrlen,
1129 +            hostbuf2, sizeof(hostbuf2), NULL, 0,
1130 +            NI_NUMERICHOST))
1131 +           continue;
1132 +       if (strcmp(hostbuf1, hostbuf2) == 0){
1133 +           ok = 1;
1134 +           break;
1135         }
1136      }
1137 -    conn->double_reverse = -1;
1138 +    conn->double_reverse = ok ? 1 : -1;
1139 +    freeaddrinfo(res0);
1140  }
1141  
1142  API_EXPORT(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
1143                                             int type)
1144  {
1145 -    struct in_addr *iaddr;
1146 -    struct hostent *hptr;
1147      int hostname_lookups;
1148      int old_stat = SERVER_DEAD;        /* we shouldn't ever be in this state */
1149 +    char hostnamebuf[MAXHOSTNAMELEN];
1150  
1151      /* If we haven't checked the host name, and we want to */
1152      if (dir_config) {
1153 @@ -675,10 +701,14 @@
1154             || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
1155         old_stat = ap_update_child_status(conn->child_num, SERVER_BUSY_DNS,
1156                                           (request_rec*)NULL);
1157 -       iaddr = &(conn->remote_addr.sin_addr);
1158 -       hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
1159 -       if (hptr != NULL) {
1160 -           conn->remote_host = ap_pstrdup(conn->pool, (void *)hptr->h_name);
1161 +       if (!getnameinfo((struct sockaddr *)&conn->remote_addr,
1162 +#ifndef SIN6_LEN
1163 +               SA_LEN((struct sockaddr *)&conn->remote_addr),
1164 +#else
1165 +               conn->remote_addr.ss_len,
1166 +#endif
1167 +               hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0)) {
1168 +           conn->remote_host = ap_pstrdup(conn->pool, (void *)hostnamebuf);
1169             ap_str_tolower(conn->remote_host);
1170            
1171             if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
1172 @@ -759,6 +789,7 @@
1173  {
1174      conn_rec *conn = r->connection;
1175      core_dir_config *d;
1176 +    char hbuf[MAXHOSTNAMELEN];
1177  
1178      d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
1179                                                 &core_module);
1180 @@ -768,23 +799,22 @@
1181      }
1182      if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
1183          if (conn->local_host == NULL) {
1184 -           struct in_addr *iaddr;
1185 -           struct hostent *hptr;
1186              int old_stat;
1187             old_stat = ap_update_child_status(conn->child_num,
1188                                               SERVER_BUSY_DNS, r);
1189 -           iaddr = &(conn->local_addr.sin_addr);
1190 -           hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr),
1191 -                                AF_INET);
1192 -           if (hptr != NULL) {
1193 -               conn->local_host = ap_pstrdup(conn->pool,
1194 -                                             (void *)hptr->h_name);
1195 -               ap_str_tolower(conn->local_host);
1196 -           }
1197 -           else {
1198 -               conn->local_host = ap_pstrdup(conn->pool,
1199 -                                             r->server->server_hostname);
1200 +           if (getnameinfo((struct sockaddr *)&conn->local_addr,
1201 +#ifndef SIN6_LEN
1202 +                   SA_LEN((struct sockaddr *)&conn->local_addr),
1203 +#else
1204 +                   conn->local_addr.ss_len,
1205 +#endif
1206 +                   hbuf, sizeof(hbuf), NULL, 0, 0) == 0) {
1207 +               conn->local_host = ap_pstrdup(conn->pool, hbuf);
1208 +           } else {
1209 +               conn->local_host = ap_pstrdup(conn->pool,
1210 +                   r->server->server_hostname);
1211             }
1212 +           ap_str_tolower(conn->local_host);
1213             (void) ap_update_child_status(conn->child_num, old_stat, r);
1214         }
1215         return conn->local_host;
1216 @@ -803,11 +833,13 @@
1217  
1218      if (d->use_canonical_name == USE_CANONICAL_NAME_OFF
1219         || d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
1220 -        return r->hostname ? ntohs(r->connection->local_addr.sin_port)
1221 -                          : port;
1222 -    }
1223 -    /* default */
1224 -    return port;
1225 +        return r->hostname
1226 +           ?  ntohs(((struct sockaddr_in *)&r->connection->local_addr)->sin_port)
1227 +           : port;
1228 +    }
1229 +    return r->hostname
1230 +       ? ntohs(((struct sockaddr_in *)&r->connection->local_addr)->sin_port)
1231 +       : port;
1232  }
1233  
1234  API_EXPORT(char *) ap_construct_url(pool *p, const char *uri,
1235 @@ -2539,12 +2571,25 @@
1236  
1237  static const char *set_bind_address(cmd_parms *cmd, void *dummy, char *arg) 
1238  {
1239 +    struct addrinfo hints, *res;
1240 +    struct sockaddr *sa;
1241 +    size_t sa_len;
1242 +    int error;
1243      const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1244      if (err != NULL) {
1245          return err;
1246      }
1247  
1248 -    ap_bind_address.s_addr = ap_get_virthost_addr(arg, NULL);
1249 +    if (strcmp(arg, "*") == 0)
1250 +      arg = NULL;
1251 +
1252 +    sa = ap_get_virthost_addr(arg, NULL);
1253 +#ifdef HAVE_SOCKADDR_LEN
1254 +    sa_len = sa->sa_len;
1255 +#else
1256 +    sa_len = SA_LEN(sa);
1257 +#endif
1258 +    memcpy(&ap_bind_address, &sa, sa_len);
1259      return NULL;
1260  }
1261  
1262 @@ -2576,44 +2621,70 @@
1263      return NULL;
1264  }
1265  
1266 -static const char *set_listener(cmd_parms *cmd, void *dummy, char *ips)
1267 +static const char *set_listener(cmd_parms *cmd, void *dummy, char *h, char *p)
1268  {
1269      listen_rec *new;
1270 -    char *ports;
1271 -    unsigned short port;
1272 +    char *host, *port;
1273 +    struct addrinfo hints, *res;
1274 +    int error;
1275      
1276      const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1277      if (err != NULL) {
1278          return err;
1279      }
1280  
1281 -    ports = strchr(ips, ':');
1282 -    if (ports != NULL) {
1283 -       if (ports == ips) {
1284 -           return "Missing IP address";
1285 -       }
1286 -       else if (ports[1] == '\0') {
1287 -           return "Address must end in :<port-number>";
1288 +    host = port = NULL;
1289 +    if (!p) {
1290 +       port = strrchr(h, ':');
1291 +       if (port != NULL) {
1292 +           if (port == h) {
1293 +               return "Missing IP address";
1294 +           }
1295 +           else if (port[1] == '\0') {
1296 +               return "Address must end in :<port-number>";
1297 +           }
1298 +           *(port++) = '\0';
1299 +           if (*h)
1300 +               host = h;
1301 +       } else {
1302 +           host = NULL;
1303 +           port = h;
1304         }
1305 -       *(ports++) = '\0';
1306 -    }
1307 -    else {
1308 -       ports = ips;
1309 +    } else {
1310 +       host = h;
1311 +       port = p;
1312      }
1313  
1314 -    new=ap_pcalloc(cmd->pool, sizeof(listen_rec));
1315 -    new->local_addr.sin_family = AF_INET;
1316 -    if (ports == ips) { /* no address */
1317 -       new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
1318 -    }
1319 -    else {
1320 -       new->local_addr.sin_addr.s_addr = ap_get_virthost_addr(ips, NULL);
1321 -    }
1322 -    port = atoi(ports);
1323 -    if (!port) {
1324 -       return "Port must be numeric";
1325 +    if (host && strcmp(host, "*") == 0)
1326 +       host = NULL;
1327 +    
1328 +    new = ap_pcalloc(cmd->pool, sizeof(listen_rec));
1329 +
1330 +    memset(&hints, 0, sizeof(hints));
1331 +    hints.ai_family = host ? PF_UNSPEC : ap_default_family;
1332 +    hints.ai_flags = AI_PASSIVE;
1333 +    hints.ai_socktype = SOCK_STREAM;
1334 +    error = getaddrinfo(host, port, &hints, &res);
1335 +    if (error || !res) {
1336 +       fprintf(stderr, "could not resolve ");
1337 +       if (host)
1338 +           fprintf(stderr, "host \"%s\" ", host);
1339 +       if (port)
1340 +           fprintf(stderr, "port \"%s\" ", port);
1341 +       fprintf(stderr, "--- %s\n", gai_strerror(error));
1342 +       exit(1);
1343 +    }
1344 +    if (res->ai_next) {
1345 +        if (host)
1346 +           fprintf(stderr, "host \"%s\" ", host);
1347 +       if (port)
1348 +           fprintf(stderr, "port \"%s\" ", port);
1349 +       fprintf(stderr, "resolved to multiple addresses, ambiguous.\n");
1350 +       exit(1);
1351      }
1352 -    new->local_addr.sin_port = htons(port);
1353 +
1354 +    memcpy(&new->local_addr, res->ai_addr, res->ai_addrlen);
1355 +
1356      new->fd = -1;
1357      new->used = 0;
1358      new->next = ap_listeners;
1359 @@ -3328,7 +3399,7 @@
1360  { "ThreadStackSize", set_threadstacksize, NULL, RSRC_CONF, TAKE1,
1361    "Stack size each created thread will use."},
1362  #endif
1363 -{ "Listen", set_listener, NULL, RSRC_CONF, TAKE1,
1364 +{ "Listen", set_listener, NULL, RSRC_CONF, TAKE12,
1365    "A port number or a numeric IP address and a port number"},
1366  { "SendBufferSize", set_send_buffer_size, NULL, RSRC_CONF, TAKE1,
1367    "Send buffer size in bytes"},
1368 @@ -3362,7 +3433,7 @@
1369    "Name of the config file to be included" },
1370  { "LogLevel", set_loglevel, NULL, RSRC_CONF, TAKE1,
1371    "Level of verbosity in error logging" },
1372 -{ "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE1,
1373 +{ "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE12,
1374    "A numeric IP address:port, or the name of a host" },
1375  #ifdef _OSD_POSIX
1376  { "BS2000Account", set_bs2000_account, NULL, RSRC_CONF, TAKE1,
1377 diff -Nur apache_1.3.23.orig/src/main/http_main.c apache_1.3.23/src/main/http_main.c
1378 --- apache_1.3.23.orig/src/main/http_main.c     Wed Feb  6 20:17:43 2002
1379 +++ apache_1.3.23/src/main/http_main.c  Wed Feb  6 20:29:52 2002
1380 @@ -124,6 +124,8 @@
1381  #include <bstring.h>           /* for IRIX, FD_SET calls bzero() */
1382  #endif
1383  
1384 +#include "sa_len.h"
1385 +
1386  #ifdef MULTITHREAD
1387  /* special debug stuff -- PCS */
1388  
1389 @@ -249,7 +251,12 @@
1390  API_VAR_EXPORT char *ap_scoreboard_fname=NULL;
1391  API_VAR_EXPORT char *ap_lock_fname=NULL;
1392  API_VAR_EXPORT char *ap_server_argv0=NULL;
1393 -API_VAR_EXPORT struct in_addr ap_bind_address={0};
1394 +#ifdef INET6
1395 +API_VAR_EXPORT int ap_default_family = PF_INET6;
1396 +#else
1397 +API_VAR_EXPORT int ap_default_family = PF_INET;
1398 +#endif
1399 +API_VAR_EXPORT struct sockaddr_storage ap_bind_address={0};
1400  API_VAR_EXPORT int ap_daemons_to_start=0;
1401  API_VAR_EXPORT int ap_daemons_min_free=0;
1402  API_VAR_EXPORT int ap_daemons_max_free=0;
1403 @@ -1384,7 +1391,11 @@
1404      fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin);
1405  #endif
1406      fprintf(stderr, "       %s [-C \"directive\"] [-c \"directive\"]\n", pad);
1407 -    fprintf(stderr, "       %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]\n", pad);
1408 +    fprintf(stderr, "       %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]"
1409 +#ifdef INET6
1410 +           " [-46]"
1411 +#endif
1412 +           "\n", pad);
1413      fprintf(stderr, "Options:\n");
1414  #ifdef SHARED_CORE
1415      fprintf(stderr, "  -R directory     : specify an alternate location for shared object files\n");
1416 @@ -1406,6 +1417,10 @@
1417  #endif
1418      fprintf(stderr, "  -t               : run syntax check for config files (with docroot check)\n");
1419      fprintf(stderr, "  -T               : run syntax check for config files (without docroot check)\n");
1420 +#ifdef INET6
1421 +    fprintf(stderr, "  -4               : assume IPv4 on parsing configuration file\n");
1422 +    fprintf(stderr, "  -6               : assume IPv6 on parsing configuration file\n");
1423 +#endif
1424  #ifdef WIN32
1425      fprintf(stderr, "  -n name          : name the Apache service for -k options below;\n");
1426      fprintf(stderr, "  -k stop|shutdown : tell running Apache to shutdown\n");
1427 @@ -3566,11 +3581,13 @@
1428  
1429  
1430  static conn_rec *new_connection(pool *p, server_rec *server, BUFF *inout,
1431 -                            const struct sockaddr_in *remaddr,
1432 -                            const struct sockaddr_in *saddr,
1433 +                            const struct sockaddr *remaddr,
1434 +                            const struct sockaddr *saddr,
1435                              int child_num)
1436  {
1437      conn_rec *conn = (conn_rec *) ap_pcalloc(p, sizeof(conn_rec));
1438 +    char hostnamebuf[MAXHOSTNAMELEN];
1439 +    size_t addr_len;
1440  
1441      /* Got a connection structure, so initialize what fields we can
1442       * (the rest are zeroed out by pcalloc).
1443 @@ -3579,17 +3596,29 @@
1444      conn->child_num = child_num;
1445  
1446      conn->pool = p;
1447 -    conn->local_addr = *saddr;
1448 -    conn->local_ip = ap_pstrdup(conn->pool,
1449 -                               inet_ntoa(conn->local_addr.sin_addr));
1450 +#ifndef SIN6_LEN
1451 +    addr_len = SA_LEN(saddr);
1452 +#else 
1453 +    addr_len = saddr->sa_len;
1454 +#endif
1455 +    memcpy(&conn->local_addr, saddr, addr_len); 
1456 +    getnameinfo((struct sockaddr *)&conn->local_addr, addr_len,
1457 +            hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);  
1458 +    conn->local_ip = ap_pstrdup(conn->pool, hostnamebuf);
1459      conn->server = server; /* just a guess for now */
1460      ap_update_vhost_given_ip(conn);
1461      conn->base_server = conn->server;
1462      conn->client = inout;
1463  
1464 -    conn->remote_addr = *remaddr;
1465 -    conn->remote_ip = ap_pstrdup(conn->pool,
1466 -                             inet_ntoa(conn->remote_addr.sin_addr));
1467 +#ifndef SIN6_LEN 
1468 +    addr_len = SA_LEN(remaddr);
1469 +#else 
1470 +    addr_len = remaddr->sa_len;
1471 +#endif
1472 +    memcpy(&conn->remote_addr, remaddr, addr_len);
1473 +    getnameinfo((struct sockaddr *)&conn->remote_addr, addr_len,
1474 +           hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
1475 +    conn->remote_ip = ap_pstrdup(conn->pool, hostnamebuf);           
1476  #ifdef EAPI
1477      conn->ctx = ap_ctx_new(conn->pool);
1478  #endif /* EAPI */
1479 @@ -3640,21 +3669,47 @@
1480  #define sock_disable_nagle(s)  /* NOOP */
1481  #endif
1482  
1483 -static int make_sock(pool *p, const struct sockaddr_in *server)
1484 +static int make_sock(pool *p, const struct sockaddr *server)
1485  {
1486      int s;
1487      int one = 1;
1488 -    char addr[512];
1489 +    char addr[INET6_ADDRSTRLEN + 128];
1490 +    char a0[INET6_ADDRSTRLEN];
1491 +    char p0[NI_MAXSERV];
1492 +#ifdef MPE
1493 +    int privport = 0;
1494 +#endif
1495  
1496 -    if (server->sin_addr.s_addr != htonl(INADDR_ANY))
1497 -       ap_snprintf(addr, sizeof(addr), "address %s port %d",
1498 -               inet_ntoa(server->sin_addr), ntohs(server->sin_port));
1499 -    else
1500 -       ap_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port));
1501 +    switch(server->sa_family){
1502 +    case AF_INET:
1503 +#ifdef INET6
1504 +    case AF_INET6:
1505 +#endif
1506 +      break;
1507 +    default:
1508 +      ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
1509 +                   "make_sock: unsupported address family %u", 
1510 +                  server->sa_family);
1511 +      ap_unblock_alarms();
1512 +      exit(1);
1513 +    }
1514 +    
1515 +    getnameinfo(server,
1516 +#ifndef SIN6_LEN
1517 +               SA_LEN(server),
1518 +#else
1519 +               server->sa_len,
1520 +#endif
1521 +               a0, sizeof(a0), p0, sizeof(p0), NI_NUMERICHOST | NI_NUMERICSERV);
1522 +    ap_snprintf(addr, sizeof(addr), "address %s port %s", a0, p0);
1523 +#ifdef MPE
1524 +    if (atoi(p0) < 1024)
1525 +      privport++;
1526 +#endif
1527  
1528      /* note that because we're about to slack we don't use psocket */
1529      ap_block_alarms();
1530 -    if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
1531 +    if ((s = socket(server->sa_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
1532             ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
1533                     "make_sock: failed to get a socket for %s", addr);
1534  
1535 @@ -3757,15 +3812,19 @@
1536  
1537  #ifdef MPE
1538  /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
1539 -    if (ntohs(server->sin_port) < 1024)
1540 +    if (privport)
1541         GETPRIVMODE();
1542  #endif
1543 -
1544 -    if (bind(s, (struct sockaddr *) server, sizeof(struct sockaddr_in)) == -1) {
1545 +#ifndef SIN6_LEN
1546 +    if (bind(s, server, SA_LEN(server)) == -1)
1547 +#else
1548 +    if (bind(s, server, server->sa_len) == -1)
1549 +#endif
1550 +    {
1551         ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
1552             "make_sock: could not bind to %s", addr);
1553  #ifdef MPE
1554 -       if (ntohs(server->sin_port) < 1024)
1555 +       if (privport)
1556             GETUSERMODE();
1557  #endif
1558  
1559 @@ -3778,7 +3837,7 @@
1560         exit(1);
1561      }
1562  #ifdef MPE
1563 -    if (ntohs(server->sin_port) < 1024)
1564 +    if (privport)
1565         GETUSERMODE();
1566  #endif
1567  
1568 @@ -3931,15 +3990,17 @@
1569      for (;;) {
1570         fd = find_listener(lr);
1571         if (fd < 0) {
1572 -           fd = make_sock(p, &lr->local_addr);
1573 +           fd = make_sock(p, (struct sockaddr *)&lr->local_addr);
1574         }
1575         else {
1576             ap_note_cleanups_for_socket(p, fd);
1577         }
1578         /* if we get here, (fd >= 0) && (fd < FD_SETSIZE) */
1579 -       FD_SET(fd, &listenfds);
1580 -       if (fd > listenmaxfd)
1581 -           listenmaxfd = fd;
1582 +       if (fd > 0) {
1583 +           FD_SET(fd, &listenfds);
1584 +           if (fd > listenmaxfd)
1585 +               listenmaxfd = fd;
1586 +       }
1587         lr->fd = fd;
1588         if (lr->next == NULL)
1589             break;
1590 @@ -4257,8 +4318,8 @@
1591  static void child_main(int child_num_arg)
1592  {
1593      NET_SIZE_T clen;
1594 -    struct sockaddr sa_server;
1595 -    struct sockaddr sa_client;
1596 +    struct sockaddr_storage sa_server;
1597 +    struct sockaddr_storage sa_client;
1598      listen_rec *lr;
1599  
1600      /* All of initialization is a critical section, we don't care if we're
1601 @@ -4423,7 +4484,7 @@
1602             usr1_just_die = 0;
1603             for (;;) {
1604                 clen = sizeof(sa_client);
1605 -               csd = ap_accept(sd, &sa_client, &clen);
1606 +               csd = ap_accept(sd, (struct sockaddr *)&sa_client, &clen);
1607                 if (csd >= 0 || errno != EINTR)
1608                     break;
1609                 if (deferred_die) {
1610 @@ -4586,7 +4647,7 @@
1611          */
1612  
1613         clen = sizeof(sa_server);
1614 -       if (getsockname(csd, &sa_server, &clen) < 0) {
1615 +       if (getsockname(csd, (struct sockaddr *)&sa_server, &clen) < 0) {
1616             ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, "getsockname");
1617             continue;
1618         }
1619 @@ -4631,8 +4692,8 @@
1620         ap_bpushfd(conn_io, csd, dupped_csd);
1621  
1622         current_conn = new_connection(ptrans, server_conf, conn_io,
1623 -                                         (struct sockaddr_in *) &sa_client,
1624 -                                         (struct sockaddr_in *) &sa_server,
1625 +                                         (struct sockaddr *)&sa_client,
1626 +                                         (struct sockaddr *)&sa_server,
1627                                           my_child_num);
1628  
1629         /*
1630 @@ -4776,12 +4837,13 @@
1631  
1632  #ifdef _OSD_POSIX
1633      /* BS2000 requires a "special" version of fork() before a setuid() call */
1634 -    if ((pid = os_fork(ap_user_name)) == -1) {
1635 +    if ((pid = os_fork(ap_user_name)) == -1)
1636  #elif defined(TPF)
1637 -    if ((pid = os_fork(s, slot)) == -1) {
1638 +    if ((pid = os_fork(s, slot)) == -1)
1639  #else
1640 -    if ((pid = fork()) == -1) {
1641 +    if ((pid = fork()) == -1)
1642  #endif
1643 +    {
1644         ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new process");
1645  
1646         /* fork didn't succeed. Fix the scoreboard or else
1647 @@ -5390,7 +5452,10 @@
1648      ap_setup_prelinked_modules();
1649  
1650      while ((c = getopt(argc, argv,
1651 -                                   "D:C:c:xXd:f:vVlLR:StTh"
1652 +                                   "D:C:c:xXd:f:vVlLR:StTh4"
1653 +#ifdef INET6
1654 +                                   "6"
1655 +#endif
1656  #ifdef DEBUG_SIGSTOP
1657                                     "Z:"
1658  #endif
1659 @@ -5465,8 +5530,14 @@
1660             ap_configtestonly = 1;
1661             ap_docrootcheck = 0;
1662             break;
1663 -       case 'h':
1664 -           usage(argv[0]);
1665 +       case '4':
1666 +           ap_default_family = PF_INET;
1667 +           break;
1668 +#ifdef INET6
1669 +       case '6':
1670 +           ap_default_family = PF_INET6;
1671 +           break;
1672 +#endif
1673         case '?':
1674             usage(argv[0]);
1675         }
1676 @@ -5546,9 +5617,10 @@
1677      else {
1678         conn_rec *conn;
1679         request_rec *r;
1680 -       struct sockaddr sa_server, sa_client;
1681         BUFF *cio;
1682 +       struct sockaddr_storage sa_server, sa_client;
1683         NET_SIZE_T l;
1684 +       char servbuf[NI_MAXSERV];
1685  
1686         ap_set_version();
1687         /* Yes this is called twice. */
1688 @@ -5595,25 +5667,32 @@
1689  #endif
1690  
1691         l = sizeof(sa_client);
1692 -       if ((getpeername(sock_in, &sa_client, &l)) < 0) {
1693 +       if ((getpeername(sock_in, (struct sockaddr *)&sa_client, &l)) < 0) {
1694  /* get peername will fail if the input isn't a socket */
1695             perror("getpeername");
1696             memset(&sa_client, '\0', sizeof(sa_client));
1697         }
1698  
1699         l = sizeof(sa_server);
1700 -       if (getsockname(sock_in, &sa_server, &l) < 0) {
1701 +       if (getsockname(sock_in, (struct sockaddr *)&sa_server, &l) < 0) {
1702             perror("getsockname");
1703             fprintf(stderr, "Error getting local address\n");
1704             exit(1);
1705         }
1706 -       server_conf->port = ntohs(((struct sockaddr_in *) &sa_server)->sin_port);
1707 +       if (getnameinfo(((struct sockaddr *)&sa_server), l,
1708 +                       NULL, 0, servbuf, sizeof(servbuf), 
1709 +                       NI_NUMERICSERV)){
1710 +           fprintf(stderr, "getnameinfo(): family=%d\n", sa_server.ss_family);
1711 +           exit(1);
1712 +       }
1713 +       servbuf[sizeof(servbuf)-1] = '\0';
1714 +       server_conf->port = atoi(servbuf);
1715         cio = ap_bcreate(ptrans, B_RDWR | B_SOCKET);
1716          cio->fd = sock_out;
1717          cio->fd_in = sock_in;
1718         conn = new_connection(ptrans, server_conf, cio,
1719 -                                 (struct sockaddr_in *) &sa_client,
1720 -                                 (struct sockaddr_in *) &sa_server, -1);
1721 +                                 (struct sockaddr *)&sa_client,
1722 +                                 (struct sockaddr *)&sa_server, -1);
1723  
1724         while ((r = ap_read_request(conn)) != NULL) {
1725  
1726 @@ -7820,7 +7899,11 @@
1727       * but only handle the -L option 
1728       */
1729      llp_dir = SHARED_CORE_DIR;
1730 -    while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLR:SZ:tTh")) != -1) {
1731 +    while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLR:SZ:tTh4"
1732 +#ifdef INET6
1733 +               "6"
1734 +#endif
1735 +               )) != -1) {
1736         switch (c) {
1737         case 'D':
1738         case 'C':
1739 @@ -7837,6 +7920,10 @@
1740         case 't':
1741         case 'T':
1742         case 'h':
1743 +       case '4':
1744 +#ifdef INET6
1745 +       case '6':
1746 +#endif
1747         case '?':
1748             break;
1749         case 'R':
1750 diff -Nur apache_1.3.23.orig/src/main/http_vhost.c apache_1.3.23/src/main/http_vhost.c
1751 --- apache_1.3.23.orig/src/main/http_vhost.c    Mon Jan 21 00:13:51 2002
1752 +++ apache_1.3.23/src/main/http_vhost.c Wed Feb  6 20:30:51 2002
1753 @@ -68,6 +68,7 @@
1754  #include "http_log.h"
1755  #include "http_vhost.h"
1756  #include "http_protocol.h"
1757 +#include "sa_len.h"
1758  
1759  /*
1760   * After all the definitions there's an explanation of how it's all put
1761 @@ -165,78 +166,114 @@
1762   * *paddr is the variable used to keep track of **paddr between calls
1763   * port is the default port to assume
1764   */
1765 -static const char *get_addresses(pool *p, char *w, server_addr_rec ***paddr,
1766 -                           unsigned port)
1767 +static const char *get_addresses(pool *p, char *w, char *pstr,
1768 +       server_addr_rec ***paddr, unsigned port)
1769  {
1770 -    struct hostent *hep;
1771 -    unsigned long my_addr;
1772 +    struct addrinfo hints, *res, *res0;
1773      server_addr_rec *sar;
1774 -    char *t;
1775 -    int i, is_an_ip_addr;
1776 +    char *t = NULL, *u = NULL, *v = NULL;
1777 +    char *hoststr = NULL, *portstr = NULL;
1778 +    char portpool[10];
1779 +    int error;
1780 +    char servbuf[NI_MAXSERV];
1781  
1782 -    if (*w == 0)
1783 +    if (w == 0 || *w == 0)
1784         return NULL;
1785  
1786 -    t = strchr(w, ':');
1787 -    if (t) {
1788 -       if (strcmp(t + 1, "*") == 0) {
1789 -           port = 0;
1790 +    portstr = portpool;
1791 +    ap_snprintf(portpool, sizeof(portpool), "%u", port);
1792 +    if (!pstr) {
1793 +       v = w;
1794 +       u = NULL;
1795 +       if (*w == '['){
1796 +           u = strrchr(w, ']');
1797 +           if (u) {    /* [host]:port or [host] */
1798 +               w++;
1799 +               *u = '\0';
1800 +               v = u + 1;
1801 +           }
1802         }
1803 -       else if ((i = atoi(t + 1))) {
1804 -           port = i;
1805 +       /*        w   uv     ,       w=v        , w=v  */  
1806 +       /* u!=0: [host]:port , u==0: [host:port , host */
1807 +       t = strchr(v, ':');
1808 +       if (t != NULL && strchr(t+1, ':') == NULL) {
1809 +           /* [host]:port-w/o-colons, host-without-colons:port-w/o-colons */
1810 +           *t = '\0';
1811 +           portstr = t + 1;
1812         }
1813         else {
1814 -           return ":port must be numeric";
1815 +           portstr = "0";
1816         }
1817 -       *t = 0;
1818 +    } else {
1819 +       portstr = pstr;
1820      }
1821  
1822 -    is_an_ip_addr = 0;
1823 -    if (strcmp(w, "*") == 0) {
1824 -       my_addr = htonl(INADDR_ANY);
1825 -       is_an_ip_addr = 1;
1826 -    }
1827 -    else if (strcasecmp(w, "_default_") == 0
1828 -            || strcmp(w, "255.255.255.255") == 0) {
1829 -       my_addr = DEFAULT_VHOST_ADDR;
1830 -       is_an_ip_addr = 1;
1831 -    }
1832 -    else if ((my_addr = ap_inet_addr(w)) != INADDR_NONE) {
1833 -       is_an_ip_addr = 1;
1834 +    memset(&hints, 0, sizeof(hints));
1835 +    hints.ai_socktype = SOCK_STREAM;
1836 +    if (strcmp(w, "*") == 0 || strlen(w) == 0) {
1837 +       hoststr = NULL;
1838 +       hints.ai_family = PF_UNSPEC;
1839 +       hints.ai_flags = AI_PASSIVE;
1840 +    }
1841 +    else if (strcasecmp(w, "_default4_") == 0 ||
1842 +            ((ap_default_family == PF_INET
1843 +#ifndef INET6
1844 +              || ap_default_family == PF_UNSPEC
1845 +#endif
1846 +              ) && strcasecmp(w, "_default_") == 0)){
1847 +       hoststr = "255.255.255.255";
1848 +       hints.ai_family = PF_INET;
1849 +    }
1850 +#ifdef INET6
1851 +    else if (strcasecmp(w, "_default6_") == 0 ||
1852 +            ((ap_default_family == PF_INET6
1853 +              || ap_default_family == PF_UNSPEC
1854 +              ) && strcasecmp(w, "_default_") == 0)){
1855 +       hoststr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
1856 +       hints.ai_family = PF_INET6;
1857      }
1858 -    if (is_an_ip_addr) {
1859 -       sar = ap_pcalloc(p, sizeof(server_addr_rec));
1860 -       **paddr = sar;
1861 -       *paddr = &sar->next;
1862 -       sar->host_addr.s_addr = my_addr;
1863 -       sar->host_port = port;
1864 -       sar->virthost = ap_pstrdup(p, w);
1865 -       if (t != NULL)
1866 -           *t = ':';
1867 -       return NULL;
1868 +#endif
1869 +    else{
1870 +       hoststr = w;
1871 +       hints.ai_family = PF_UNSPEC;
1872      }
1873  
1874 -    hep = gethostbyname(w);
1875 -
1876 -    if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
1877 +    error = getaddrinfo(hoststr, portstr, &hints, &res0);
1878 +    if (error || !res0) {
1879         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
1880 -           "Cannot resolve host name %s --- ignoring!", w);
1881 -       if (t != NULL)
1882 -           *t = ':';
1883 +           "Cannot resolve host %s port %s --- ignoring!", hoststr, portstr);
1884 +       if (t != NULL) *t = ':';
1885 +       if (u != NULL) *u = ']';
1886         return NULL;
1887      }
1888 -
1889 -    for (i = 0; hep->h_addr_list[i]; ++i) {
1890 +    for (res=res0; res; res=res->ai_next) {
1891 +       switch (res->ai_addr->sa_family) {
1892 +       case AF_INET:
1893 +#ifdef INET6
1894 +       case AF_INET6:
1895 +#endif
1896 +           break;
1897 +       default:
1898 +           ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
1899 +                        "Unsupported address family %u, for host %s port %s --- ignoring!",
1900 +                        res->ai_addr->sa_family, hoststr, portstr);
1901 +           continue;
1902 +       }
1903         sar = ap_pcalloc(p, sizeof(server_addr_rec));
1904         **paddr = sar;
1905         *paddr = &sar->next;
1906 -       sar->host_addr = *(struct in_addr *) hep->h_addr_list[i];
1907 -       sar->host_port = port;
1908 +       memcpy(&sar->host_addr, res->ai_addr, res->ai_addrlen);
1909 +       if (getnameinfo(res->ai_addr, res->ai_addrlen, NULL, 0, servbuf,
1910 +                       sizeof(servbuf), NI_NUMERICSERV) == 0)
1911 +               sar->host_port = atoi(servbuf);
1912 +       else
1913 +               sar->host_port = 0;
1914         sar->virthost = ap_pstrdup(p, w);
1915      }
1916  
1917 -    if (t != NULL)
1918 -       *t = ':';
1919 +    freeaddrinfo(res0);
1920 +    if (t != NULL) *t = ':';
1921 +    if (u != NULL) *u = ']';
1922      return NULL;
1923  }
1924  
1925 @@ -250,7 +287,8 @@
1926      /* start the list of addreses */
1927      addrs = &s->addrs;
1928      while (hostname[0]) {
1929 -       err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
1930 +       err = get_addresses(p, ap_getword_conf(p, &hostname), NULL,
1931 +               &addrs, s->port);
1932         if (err) {
1933             *addrs = NULL;
1934             return err;
1935 @@ -268,10 +306,11 @@
1936  }
1937  
1938  
1939 -API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg)
1940 +API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *h, 
1941 +       char *p)
1942  {
1943      /* use whatever port the main server has at this point */
1944 -    return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
1945 +    return get_addresses(cmd->pool, h, p, &name_vhost_list_tail,
1946                             cmd->server->port);
1947  }
1948  
1949 @@ -345,6 +384,19 @@
1950      return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
1951  }
1952  
1953 +static unsigned hash_addr(struct sockaddr *sa)
1954 +{
1955 +    switch (sa->sa_family) {
1956 +    case AF_INET:
1957 +       return hash_inaddr(((struct sockaddr_in *)sa)->sin_addr.s_addr);
1958 +#ifdef INET6
1959 +    case AF_INET6:
1960 +       return hash_inaddr(((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12]);
1961 +#endif
1962 +    default:
1963 +       return hash_inaddr(sa->sa_family);
1964 +    }
1965 +}
1966  
1967  
1968  static ipaddr_chain *new_ipaddr_chain(pool *p,
1969 @@ -372,25 +424,77 @@
1970      return new;
1971  }
1972  
1973 -
1974 -static ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
1975 -    unsigned port)
1976 +static ap_inline ipaddr_chain *find_ipaddr(struct sockaddr *sa)
1977  {
1978      unsigned bucket;
1979      ipaddr_chain *trav;
1980 -    unsigned addr;
1981 +    char a[NI_MAXHOST], b[NI_MAXHOST];
1982  
1983      /* scan the hash table for an exact match first */
1984 -    addr = server_ip->s_addr;
1985 -    bucket = hash_inaddr(addr);
1986 +    bucket = hash_addr(sa);
1987      for (trav = iphash_table[bucket]; trav; trav = trav->next) {
1988         server_addr_rec *sar = trav->sar;
1989 -       if ((sar->host_addr.s_addr == addr)
1990 -           && (sar->host_port == 0 || sar->host_port == port
1991 -               || port == 0)) {
1992 -           return trav;
1993 +       if (sar->host_addr.ss_family != sa->sa_family)
1994 +           continue;
1995 +       switch (sa->sa_family) {
1996 +       case AF_INET:
1997 +         {
1998 +           struct sockaddr_in *sin1, *sin2;
1999 +           sin1 = (struct sockaddr_in *)&sar->host_addr;
2000 +           sin2 = (struct sockaddr_in *)sa;
2001 +           if (sin1->sin_port == 0 || sin2->sin_port == 0
2002 +            || sin1->sin_port == sin2->sin_port) {
2003 +               if (memcmp(&sin1->sin_addr, &sin2->sin_addr,
2004 +                       sizeof(sin1->sin_addr)) == 0) {
2005 +                   return trav;
2006 +               }
2007 +           }
2008 +           break;
2009 +         }
2010 +#ifdef INET6
2011 +       case AF_INET6:
2012 +         {
2013 +           struct sockaddr_in6 *sin1, *sin2;
2014 +           sin1 = (struct sockaddr_in6 *)&sar->host_addr;
2015 +           sin2 = (struct sockaddr_in6 *)sa;
2016 +           if (sin1->sin6_port == 0 || sin2->sin6_port == 0
2017 +            || sin1->sin6_port == sin2->sin6_port) {
2018 +               if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
2019 +                       sizeof(sin1->sin6_addr)) == 0) {
2020 +                   return trav;
2021 +               }
2022 +           }
2023 +           break;
2024 +         }
2025 +#endif
2026 +       default: /*unsupported*/
2027 +           break;
2028         }
2029      }
2030 +
2031 +#ifdef INET6
2032 +    if (sa->sa_family == AF_INET6 &&
2033 +       IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) {
2034 +       /*
2035 +        * This is just horrible.  I just hate IPv4 mapped address.  It
2036 +        * complicates access control too much.
2037 +        * Due to hashed lookup, we need to visit it again.
2038 +        */
2039 +       struct sockaddr_in sin;
2040 +
2041 +       memset(&sin, 0, sizeof(sin));
2042 +       sin.sin_family = AF_INET;
2043 +#ifdef SIN6_LEN
2044 +       sin.sin_len = sizeof(sin);
2045 +#endif
2046 +       sin.sin_port = ((struct sockaddr_in6 *)sa)->sin6_port;
2047 +       memcpy(&sin.sin_addr,
2048 +           &((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12],
2049 +           sizeof(sin.sin_addr));
2050 +       return find_ipaddr((struct sockaddr *)&sin);
2051 +    }
2052 +#endif
2053 +
2054      return NULL;
2055  }
2056  
2057 @@ -416,21 +520,7 @@
2058      int len;
2059      char buf[MAX_STRING_LEN];
2060  
2061 -    if (ic->sar->host_addr.s_addr == DEFAULT_VHOST_ADDR) {
2062 -       len = ap_snprintf(buf, sizeof(buf), "_default_:%u",
2063 -               ic->sar->host_port);
2064 -    }
2065 -    else if (ic->sar->host_addr.s_addr == INADDR_ANY) {
2066 -       len = ap_snprintf(buf, sizeof(buf), "*:%u",
2067 -               ic->sar->host_port);
2068 -    }
2069 -    else {
2070 -       len = ap_snprintf(buf, sizeof(buf), "%pA:%u",
2071 -               &ic->sar->host_addr, ic->sar->host_port);
2072 -    }
2073 -    if (ic->sar->host_port == 0) {
2074 -       buf[len-1] = '*';
2075 -    }
2076 +    len = ap_snprintf(buf, sizeof(buf), "%pI", &ic->sar->host_addr);
2077      if (ic->names == NULL) {
2078         if (ic->server == NULL)
2079             fprintf(f, "%-22s WARNING: No <VirtualHost> defined for this NameVirtualHost!\n", buf);
2080 @@ -558,10 +648,37 @@
2081       * occured in the config file, we'll copy it in that order.
2082       */
2083      for (sar = name_vhost_list; sar; sar = sar->next) {
2084 -       unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
2085 +       unsigned bucket = hash_addr((struct sockaddr *)&sar->host_addr);
2086         ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
2087 +       int wildcard;
2088 +
2089 +       wildcard = 0;
2090 +       switch (sar->host_addr.ss_family) {
2091 +       case AF_INET:
2092 +         {
2093 +           struct sockaddr_in *sin;
2094 +           sin = (struct sockaddr_in *)&sar->host_addr;
2095 +           if (sin->sin_addr.s_addr == INADDR_ANY)
2096 +               wildcard++;
2097 +           break;
2098 +         }
2099 +#ifdef INET6
2100 +       case AF_INET6:
2101 +         {
2102 +           struct sockaddr_in6 *sin6;
2103 +           sin6 = (struct sockaddr_in6 *)&sar->host_addr;
2104 +           if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == 0
2105 +            && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == 0
2106 +            && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == 0
2107 +            && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == 0) {
2108 +               wildcard++;
2109 +           }
2110 +           break;
2111 +         }
2112 +#endif
2113 +       }
2114  
2115 -       if (sar->host_addr.s_addr != INADDR_ANY) {
2116 +       if (!wildcard) {
2117             *iphash_table_tail[bucket] = ic;
2118             iphash_table_tail[bucket] = &ic->next;
2119         }
2120 @@ -588,12 +705,45 @@
2121         has_default_vhost_addr = 0;
2122         for (sar = s->addrs; sar; sar = sar->next) {
2123             ipaddr_chain *ic;
2124 +           int wildcard;
2125 +
2126 +           wildcard = 0;
2127 +           switch (sar->host_addr.ss_family) {
2128 +           case AF_INET:
2129 +             {
2130 +               struct sockaddr_in *sin;
2131 +               sin = (struct sockaddr_in *)&sar->host_addr;
2132 +               if (sin->sin_addr.s_addr == DEFAULT_VHOST_ADDR)
2133 +                   wildcard++;
2134 +               else if (sin->sin_addr.s_addr == INADDR_ANY)
2135 +                   wildcard++;
2136 +               break;
2137 +             }
2138 +#ifdef INET6
2139 +           case AF_INET6:
2140 +             {
2141 +               struct sockaddr_in6 *sin6;
2142 +               sin6 = (struct sockaddr_in6 *)&sar->host_addr;
2143 +               if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == ~0
2144 +                && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == ~0
2145 +                && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == ~0
2146 +                && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == ~0) {
2147 +                   wildcard++;
2148 +               }
2149 +               break;
2150 +             }
2151 +#endif
2152 +           }
2153  
2154 -           if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
2155 -               || sar->host_addr.s_addr == INADDR_ANY) {
2156 -               ic = find_default_server(sar->host_port);
2157 -               if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
2158 -                   if (ic && ic->sar->host_port != 0) {
2159 +           if (wildcard) {
2160 +               /* add it to default bucket for each appropriate sar
2161 +                * since we need to do a port test
2162 +                */
2163 +               ipaddr_chain *other;
2164 +
2165 +               other = find_default_server(sar->host_port);
2166 +               if (!other || !add_name_vhost_config(p, main_s, s, sar, other)) {
2167 +                   if (other && other->sar->host_port != 0) {
2168                         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
2169                             main_s, "_default_ VirtualHost overlap on port %u,"
2170                             " the first has precedence", sar->host_port);
2171 @@ -606,10 +756,11 @@
2172             }
2173             else {
2174                 /* see if it matches something we've already got */
2175 -               ic = find_ipaddr(&sar->host_addr, sar->host_port);
2176 +               ic = find_ipaddr((struct sockaddr *)&sar->host_addr);
2177  
2178                 if (!ic) {
2179 -                   unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
2180 +                   unsigned bucket =
2181 +                       hash_addr((struct sockaddr *)&sar->host_addr);
2182  
2183                     ic = new_ipaddr_chain(p, s, sar);
2184                     ic->next = *iphash_table_tail[bucket];
2185 @@ -646,19 +797,33 @@
2186             }
2187             else {
2188                 struct hostent *h;
2189 +               char hostnamebuf[MAXHOSTNAMELEN];
2190  
2191 -               if ((h = gethostbyaddr((char *) &(s->addrs->host_addr),
2192 -                                       sizeof(struct in_addr), AF_INET))) {
2193 -                   s->server_hostname = ap_pstrdup(p, (char *) h->h_name);
2194 +               if (!getnameinfo((struct sockaddr *)&s->addrs->host_addr,
2195 +#ifndef SIN6_LEN
2196 +                       SA_LEN((struct sockaddr *)&s->addrs->host_addr),
2197 +#else  
2198 +                       s->addrs->host_addr.ss_len,
2199 +#endif
2200 +                       hostnamebuf, sizeof(hostnamebuf),
2201 +                       NULL, 0, 0)) {
2202 +                   s->server_hostname = ap_pstrdup(p, hostnamebuf);
2203                 }
2204                 else {
2205                     /* again, what can we do?  They didn't specify a
2206                        ServerName, and their DNS isn't working. -djg */
2207 +                   getnameinfo((struct sockaddr *)&s->addrs->host_addr,
2208 +#ifndef SIN6_LEN
2209 +                       SA_LEN((struct sockaddr *)&s->addrs->host_addr),
2210 +#else  
2211 +                       s->addrs->host_addr.ss_len,
2212 +#endif
2213 +                       hostnamebuf, sizeof(hostnamebuf),
2214 +                       NULL, 0, NI_NUMERICHOST);
2215                     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, main_s,
2216                             "Failed to resolve server name "
2217                             "for %s (check DNS) -- or specify an explicit "
2218 -                           "ServerName",
2219 -                           inet_ntoa(s->addrs->host_addr));
2220 +                           "ServerName", hostnamebuf);
2221                     s->server_hostname =
2222                         ap_pstrdup(p, "bogus_host_without_reverse_dns");
2223                 }
2224 @@ -705,35 +870,58 @@
2225      char *host = ap_palloc(r->pool, strlen(r->hostname) + 1);
2226      const char *src;
2227      char *dst;
2228 +    const char *u = NULL, *v = NULL;
2229  
2230      /* check and copy the host part */
2231 -    src = r->hostname;
2232 +    u = src = r->hostname;
2233  
2234      dst = host;
2235 -    while (*src) {
2236 -       if (*src == '.') {
2237 -           *dst++ = *src++;
2238 -           if (*src == '.')
2239 -               goto bad;
2240 -           else
2241 -               continue;
2242 -       }
2243 -       if (*src == '/' || *src == '\\') {
2244 -           goto bad;
2245 -       }
2246 -        if (*src == ':') {
2247 -            /* check the port part */
2248 -            while (*++src) {
2249 -                if (!ap_isdigit(*src)) {
2250 -                    goto bad;
2251 -                }
2252 -            }
2253 -            if (src[-1] == ':')
2254 -                goto bad;
2255 -            else
2256 -                break;
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 +          v++;
2272 +          while (*v) {  /* check if portnum is correct */
2273 +              if (!ap_isdigit(*v++))
2274 +                  goto bad;
2275 +          }
2276          }
2277 -       *dst++ = *src++;
2278 +     } else {
2279 +         while (*src) {
2280 +           if (*src == '.') {
2281 +               *dst++ = *src++;
2282 +               if (*src == '.')
2283 +                   goto bad;
2284 +               else
2285 +                   continue;
2286 +           }
2287 +           if (*src == '/' || *src == '\\') {
2288 +               goto bad;
2289 +           }
2290 +           if (*src == ':') {
2291 +               /* sheck the port part */
2292 +               while (*++src) {
2293 +                   if (!ap_isdigit(*src)) {
2294 +                       goto bad;
2295 +                   }
2296 +               }
2297 +               if (src[-1] == ':')
2298 +                   goto bad;
2299 +               else
2300 +                   break;
2301 +           }
2302 +           *dst++ = *src++;
2303 +         }
2304      }
2305      /* strip trailing gubbins */
2306      if (dst > host && dst[-1] == '.') {
2307 @@ -748,7 +936,7 @@
2308  bad:
2309      r->status = HTTP_BAD_REQUEST;
2310      ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
2311 -                 "Client sent malformed Host header");
2312 +                 "Client sent malformed Host header <<%s>>",u);
2313      return;
2314  }
2315  
2316 @@ -851,11 +1039,25 @@
2317       *   names we'll match have ports associated with them
2318       */
2319      const char *host = r->hostname;
2320 -    unsigned port = ntohs(r->connection->local_addr.sin_port);
2321 +    unsigned port;
2322      server_rec *s;
2323      server_rec *last_s;
2324      name_chain *src;
2325  
2326 +    switch (r->connection->local_addr.ss_family) {
2327 +    case AF_INET:
2328 +       port = ntohs(((struct sockaddr_in *)
2329 +                   &r->connection->local_addr)->sin_port);
2330 +       break;
2331 +#ifdef INET6
2332 +    case AF_INET6:
2333 +       port = ntohs(((struct sockaddr_in6 *)
2334 +                   &r->connection->local_addr)->sin6_port);
2335 +       break;
2336 +#endif
2337 +    default:
2338 +       port = 0;       /*XXX*/
2339 +    }
2340      last_s = NULL;
2341  
2342      /* Recall that the name_chain is a list of server_addr_recs, some of
2343 @@ -910,7 +1112,22 @@
2344      server_rec *s;
2345      server_rec *last_s;
2346      name_chain *src;
2347 -    unsigned port = ntohs(r->connection->local_addr.sin_port);
2348 +    unsigned port;
2349 +
2350 +    switch (r->connection->local_addr.ss_family) {
2351 +    case AF_INET:
2352 +       port = ntohs(((struct sockaddr_in *)
2353 +                   &r->connection->local_addr)->sin_port);
2354 +       break;
2355 +#ifdef INET6
2356 +    case AF_INET6:
2357 +       port = ntohs(((struct sockaddr_in6 *)
2358 +                   &r->connection->local_addr)->sin6_port);
2359 +       break;
2360 +#endif
2361 +    default:
2362 +       port = 0;       /*XXX*/
2363 +    }
2364  
2365      /*
2366       * This is in conjunction with the ServerPath code in http_core, so we
2367 @@ -970,10 +1187,22 @@
2368  API_EXPORT(void) ap_update_vhost_given_ip(conn_rec *conn)
2369  {
2370      ipaddr_chain *trav;
2371 -    unsigned port = ntohs(conn->local_addr.sin_port);
2372 +    char portbuf[NI_MAXSERV];
2373 +    unsigned port;
2374 +
2375 +    if (getnameinfo((struct sockaddr *)&conn->local_addr,
2376 +#ifndef SIN6_LEN
2377 +       SA_LEN((struct sockaddr *)&conn->local_addr),
2378 +#else  
2379 +       conn->local_addr.ss_len,
2380 +#endif
2381 +       NULL, 0, portbuf, sizeof(portbuf), NI_NUMERICSERV) != 0) {
2382 +       goto fail;
2383 +    }
2384 +    port = atoi(portbuf);
2385  
2386      /* scan the hash table for an exact match first */
2387 -    trav = find_ipaddr(&conn->local_addr.sin_addr, port);
2388 +    trav = find_ipaddr((struct sockaddr *)&conn->local_addr);
2389      if (trav) {
2390         /* save the name_chain for later in case this is a name-vhost */
2391         conn->vhost_lookup_data = trav->names;
2392 @@ -991,6 +1220,7 @@
2393         return;
2394      }
2395  
2396 +fail:
2397      /* otherwise we're stuck with just the main server
2398       * and no name-based vhosts
2399       */
2400 diff -Nur apache_1.3.23.orig/src/main/rfc1413.c apache_1.3.23/src/main/rfc1413.c
2401 --- apache_1.3.23.orig/src/main/rfc1413.c       Sun Jan 20 21:14:37 2002
2402 +++ apache_1.3.23/src/main/rfc1413.c    Wed Feb  6 20:20:48 2002
2403 @@ -82,6 +82,7 @@
2404  #include "http_log.h"          /* for aplog_error */
2405  #include "rfc1413.h"
2406  #include "http_main.h"         /* set_callback_and_alarm */
2407 +#include "sa_len.h"
2408  
2409  /* Local stuff. */
2410  /* Semi-well-known port */
2411 @@ -109,12 +110,13 @@
2412  
2413  /* bind_connect - bind both ends of a socket */
2414  /* Ambarish fix this. Very broken */
2415 -static int get_rfc1413(int sock, const struct sockaddr_in *our_sin,
2416 -                      const struct sockaddr_in *rmt_sin, 
2417 +static int get_rfc1413(int sock, const struct sockaddr *our_sin,
2418 +                      const struct sockaddr *rmt_sin, 
2419                        char user[RFC1413_USERLEN+1], server_rec *srv)
2420  {
2421 -    struct sockaddr_in rmt_query_sin, our_query_sin;
2422 -    unsigned int rmt_port, our_port;
2423 +    struct sockaddr_storage rmt_query_sin, our_query_sin;
2424 +    unsigned int o_rmt_port, o_our_port;       /* original port pair */
2425 +    unsigned int rmt_port, our_port;           /* replied port pair */
2426      int i;
2427      char *cp;
2428      char buffer[RFC1413_MAXDATA + 1];
2429 @@ -129,16 +131,47 @@
2430       * addresses from the query socket.
2431       */
2432  
2433 -    our_query_sin = *our_sin;
2434 -    our_query_sin.sin_port = htons(ANY_PORT);
2435 -#ifdef MPE 
2436 -    our_query_sin.sin_addr.s_addr = INADDR_ANY;
2437 +#ifndef SIN6_LEN
2438 +    memcpy(&our_query_sin, our_sin, SA_LEN(our_sin));
2439 +    memcpy(&rmt_query_sin, rmt_sin, SA_LEN(rmt_sin));
2440 +#else
2441 +    memcpy(&our_query_sin, our_sin, our_sin->sa_len);
2442 +    memcpy(&rmt_query_sin, rmt_sin, rmt_sin->sa_len);
2443  #endif
2444 -    rmt_query_sin = *rmt_sin;
2445 -    rmt_query_sin.sin_port = htons(RFC1413_PORT);
2446 +    switch (our_sin->sa_family) {
2447 +    case AF_INET:
2448 +#ifdef MPE
2449 +      ((struct sockaddr_in *)&our_query_sin)->sin_addr.s_addr = INADDR_ANY; /* XXX: htonl(??) */
2450 +#endif
2451 +      ((struct sockaddr_in *)&our_query_sin)->sin_port = htons(ANY_PORT);
2452 +      o_our_port = ntohs(((struct sockaddr_in *)our_sin)->sin_port);
2453 +      ((struct sockaddr_in *)&rmt_query_sin)->sin_port = htons(RFC1413_PORT);
2454 +      o_rmt_port = ntohs(((struct sockaddr_in *)rmt_sin)->sin_port);
2455 +      break;
2456 +#ifdef INET6
2457 +    case AF_INET6:
2458 +#ifdef MPE
2459 +      memcpy(&((struct sockaddr_in6 *)&our_query_sin)->sin6_addr, 
2460 +            &in6addr_any, sizeof(struct in6_addr));
2461 +#endif
2462 +      ((struct sockaddr_in6 *)&our_query_sin)->sin6_port = htons(ANY_PORT);
2463 +      o_our_port = ntohs(((struct sockaddr_in6 *)our_sin)->sin6_port);
2464 +      ((struct sockaddr_in6 *)&rmt_query_sin)->sin6_port = htons(RFC1413_PORT);
2465 +      o_rmt_port = ntohs(((struct sockaddr_in6 *)rmt_sin)->sin6_port);
2466 +      break;
2467 +#endif
2468 +    default:
2469 +      /* unsupported AF */
2470 +      return -1;
2471 +    }
2472  
2473      if (bind(sock, (struct sockaddr *) &our_query_sin,
2474 -            sizeof(struct sockaddr_in)) < 0) {
2475 +#ifndef SIN6_LEN
2476 +            SA_LEN((struct sockaddr *) &our_query_sin)
2477 +#else
2478 +            our_query_sin.ss_len
2479 +#endif
2480 +            ) < 0) {
2481         ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
2482                     "bind: rfc1413: Error binding to local port");
2483         return -1;
2484 @@ -149,12 +182,18 @@
2485   * the service
2486   */
2487      if (connect(sock, (struct sockaddr *) &rmt_query_sin,
2488 -               sizeof(struct sockaddr_in)) < 0)
2489 -                   return -1;
2490 +#ifndef SIN6_LEN
2491 +               SA_LEN((struct sockaddr *) &rmt_query_sin)
2492 +#else
2493 +               rmt_query_sin.ss_len
2494 +#endif
2495 +               ) < 0) {
2496 +       return -1;
2497 +    }
2498  
2499  /* send the data */
2500 -    buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", ntohs(rmt_sin->sin_port),
2501 -               ntohs(our_sin->sin_port));
2502 +    buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", o_rmt_port,
2503 +               o_our_port);
2504  
2505      /* send query to server. Handle short write. */
2506  #ifdef CHARSET_EBCDIC
2507 @@ -219,9 +258,9 @@
2508      ascii2ebcdic(buffer, buffer, (size_t)i);
2509  #endif
2510      if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port,
2511 -              user) != 3 || ntohs(rmt_sin->sin_port) != rmt_port
2512 -       || ntohs(our_sin->sin_port) != our_port)
2513 +              user) != 3 || o_rmt_port != rmt_port || o_our_port != our_port) {
2514         return -1;
2515 +    }
2516  
2517      /*
2518       * Strip trailing carriage return. It is part of the
2519 @@ -243,7 +282,7 @@
2520  
2521      result = FROM_UNKNOWN;
2522  
2523 -    sock = ap_psocket(conn->pool, AF_INET, SOCK_STREAM, IPPROTO_TCP);
2524 +    sock = ap_psocket(conn->pool, conn->remote_addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
2525      if (sock < 0) {
2526         ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
2527                     "socket: rfc1413: error creating socket");
2528 @@ -256,8 +295,10 @@
2529      if (ap_setjmp(timebuf) == 0) {
2530         ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout);
2531  
2532 -       if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user, srv) >= 0)
2533 +       if (get_rfc1413(sock, (struct sockaddr *)&conn->local_addr,
2534 +               (struct sockaddr *)&conn->remote_addr, user, srv) >= 0) {
2535             result = user;
2536 +       }
2537      }
2538      ap_set_callback_and_alarm(NULL, 0);
2539      ap_pclosesocket(conn->pool, sock);
2540 diff -Nur apache_1.3.23.orig/src/main/util.c apache_1.3.23/src/main/util.c
2541 --- apache_1.3.23.orig/src/main/util.c  Fri Dec 28 06:03:07 2001
2542 +++ apache_1.3.23/src/main/util.c       Wed Feb  6 20:36:21 2002
2543 @@ -1962,52 +1962,87 @@
2544   * Parses a host of the form <address>[:port]
2545   * :port is permitted if 'port' is not NULL
2546   */
2547 -API_EXPORT(unsigned long) ap_get_virthost_addr(char *w, unsigned short *ports)
2548 +API_EXPORT(struct sockaddr *) ap_get_virthost_addr(char *w, unsigned short *ports)
2549  {
2550 -    struct hostent *hep;
2551 -    unsigned long my_addr;
2552 -    char *p;
2553 -
2554 -    p = strchr(w, ':');
2555 +    static struct sockaddr_storage ss;
2556 +    struct addrinfo hints, *res;
2557 +    char *p, *r;
2558 +    char *host;
2559 +    char *port = "0";
2560 +    int error;
2561 +    char servbuf[NI_MAXSERV];
2562 +
2563 +    if (w == NULL)
2564 +       w = "*";
2565 +    p = r = NULL;
2566 +    if (*w == '['){
2567 +       if (r = strrchr(w+1, ']')){
2568 +           *r = '\0';
2569 +           p = r + 1;
2570 +           switch(*p){
2571 +           case ':':
2572 +             p++;
2573 +             /* nobreak; */
2574 +           case '\0':
2575 +             w++;
2576 +             break;
2577 +           default:
2578 +             p = NULL;
2579 +           }
2580 +       }
2581 +    }
2582 +    else{
2583 +       p = strchr(w, ':');
2584 +       if (p != NULL && strchr(p+1, ':') != NULL)
2585 +           p = NULL;
2586 +    }
2587      if (ports != NULL) {
2588 -       *ports = 0;
2589 -       if (p != NULL && strcmp(p + 1, "*") != 0)
2590 -           *ports = atoi(p + 1);
2591 +       if (p != NULL && *p && strcmp(p + 1, "*") != 0)
2592 +           port = p + 1;
2593      }
2594  
2595 +    memset(&hints, 0, sizeof(hints));
2596 +    hints.ai_socktype = SOCK_STREAM;
2597      if (p != NULL)
2598         *p = '\0';
2599      if (strcmp(w, "*") == 0) {
2600 -       if (p != NULL)
2601 -           *p = ':';
2602 -       return htonl(INADDR_ANY);
2603 -    }
2604 -
2605 -    my_addr = ap_inet_addr((char *)w);
2606 -    if (my_addr != INADDR_NONE) {
2607 -       if (p != NULL)
2608 -           *p = ':';
2609 -       return my_addr;
2610 +       host = NULL;
2611 +       hints.ai_flags = AI_PASSIVE;
2612 +       hints.ai_family = ap_default_family;
2613 +    } else {
2614 +       host = w;
2615 +       hints.ai_family = PF_UNSPEC;
2616      }
2617  
2618 -    hep = gethostbyname(w);
2619 +    error = getaddrinfo(host, port, &hints, &res);
2620  
2621 -    if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
2622 -       fprintf(stderr, "Cannot resolve host name %s --- exiting!\n", w);
2623 +    if (error || !res) {
2624 +       fprintf(stderr, "ap_get_vitrhost_addr(): getaddrinfo(%s):%s --- exiting!\n", w, gai_strerror(error));
2625         exit(1);
2626      }
2627  
2628 -    if (hep->h_addr_list[1]) {
2629 -       fprintf(stderr, "Host %s has multiple addresses ---\n", w);
2630 +    if (res->ai_next) {
2631 +       fprintf(stderr, "ap_get_vitrhost_addr(): Host %s has multiple addresses ---\n", w);
2632         fprintf(stderr, "you must choose one explicitly for use as\n");
2633         fprintf(stderr, "a virtual host.  Exiting!!!\n");
2634         exit(1);
2635      }
2636  
2637 +    if (r != NULL)
2638 +       *r = ']';
2639      if (p != NULL)
2640         *p = ':';
2641  
2642 -    return ((struct in_addr *) (hep->h_addr))->s_addr;
2643 +    memcpy(&ss, res->ai_addr, res->ai_addrlen);
2644 +    if (getnameinfo(res->ai_addr, res->ai_addrlen,
2645 +                   NULL, 0, servbuf, sizeof(servbuf),
2646 +                   NI_NUMERICSERV)){
2647 +       fprintf(stderr, "ap_get_virthost_addr(): getnameinfo() failed --- Exiting!!!\n");
2648 +       exit(1);
2649 +    }
2650 +    if (ports) *ports = atoi(servbuf);
2651 +    freeaddrinfo(res);
2652 +    return (struct sockaddr *)&ss;
2653  }
2654  
2655  
2656 @@ -2035,7 +2070,8 @@
2657  #endif
2658      char str[MAXHOSTNAMELEN];
2659      char *server_hostname = NULL;
2660 -    struct hostent *p;
2661 +    struct addrinfo hints, *res;
2662 +    int error;
2663  
2664  #ifdef BEOS /* BeOS returns zero as an error for gethostname */
2665      if (gethostname(str, sizeof(str) - 1) == 0) {
2666 @@ -2048,29 +2084,38 @@
2667      }
2668      else 
2669      {
2670 -        str[sizeof(str) - 1] = '\0';
2671 -        if ((!(p = gethostbyname(str))) 
2672 -            || (!(server_hostname = find_fqdn(a, p)))) {
2673 -            /* Recovery - return the default servername by IP: */
2674 -            if (p && p->h_addr_list && p->h_addr_list[0]) {
2675 -                ap_snprintf(str, sizeof(str), "%pA", p->h_addr_list[0]);
2676 -               server_hostname = ap_pstrdup(a, str);
2677 -                /* We will drop through to report the IP-named server */
2678 -            }
2679 -        }
2680 -       else
2681 -            /* Since we found a fqdn, return it with no logged message. */
2682 -            return server_hostname;
2683 -    }
2684 -
2685 -    /* If we don't have an fdqn or IP, fall back to the loopback addr */
2686 -    if (!server_hostname) 
2687 -        server_hostname = ap_pstrdup(a, "127.0.0.1");
2688 -    
2689 -    ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
2690 -                "%s: Could not determine the server's fully qualified "
2691 -                 "domain name, using %s for ServerName",
2692 -                 ap_server_argv0, server_hostname);
2693 +       str[sizeof(str) - 1] = '\0';
2694 +       memset(&hints, 0, sizeof(hints));
2695 +       hints.ai_family = PF_UNSPEC;
2696 +       hints.ai_flags = AI_CANONNAME;
2697 +       error = getaddrinfo(str, NULL, &hints, &res);
2698 +       if (error)
2699 +       {
2700 +              /* Recovery - return the default servername by IP: */
2701 +
2702 +           fprintf(stderr, "%s: cannot determine local host name.\n",
2703 +                 ap_server_argv0);
2704 +           fprintf(stderr, "Use the ServerName directive to set it manually.\n");
2705 +           exit(1);
2706 +
2707 +           server_hostname = ap_pstrdup(a, res->ai_canonname);
2708 +       }
2709 +       else if (1)     /*fqdn found*/
2710 +       {
2711 +           /* XXX should check more conditions */
2712 +           server_hostname = ap_pstrdup(a, res->ai_canonname);
2713 +       }
2714 +        else
2715 +       {
2716 +           ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
2717 +                        "%s: Could not determine the server's fully qualified "
2718 +                        "domain name, using %s for ServerName",
2719 +                        ap_server_argv0, server_hostname);
2720 +       }
2721 +
2722 +       /* Since we found a fdqn, return it with no logged message. */
2723 +       freeaddrinfo(res);
2724 +      }
2725      
2726      return server_hostname;
2727  }
2728 @@ -2149,7 +2194,7 @@
2729      char *quote_doubled_str, *dest;
2730      
2731      while (str[len]) {
2732 -        num_quotes += str[len++] == '\"';
2733 +       num_quotes += str[len++] == '\"';
2734      }
2735      
2736      quote_doubled_str = ap_palloc(p, len + num_quotes + 1);
2737 @@ -2274,3 +2319,11 @@
2738      }
2739      *dest = 0;
2740  }
2741 +
2742 +#ifdef NEED_GETADDRINFO
2743 +#include "getaddrinfo.c"
2744 +#endif
2745 +
2746 +#ifdef NEED_GETNAMEINFO
2747 +#include "getnameinfo.c"
2748 +#endif
2749 diff -Nur apache_1.3.23.orig/src/main/util_script.c apache_1.3.23/src/main/util_script.c
2750 --- apache_1.3.23.orig/src/main/util_script.c   Fri Oct 12 01:37:39 2001
2751 +++ apache_1.3.23/src/main/util_script.c        Wed Feb  6 20:20:48 2002
2752 @@ -67,6 +67,7 @@
2753  #include "http_request.h"      /* for sub_req_lookup_uri() */
2754  #include "util_script.h"
2755  #include "util_date.h"         /* For parseHTTPdate() */
2756 +#include "sa_len.h"
2757  
2758  #ifdef OS2
2759  #define INCL_DOS
2760 @@ -208,6 +209,7 @@
2761      array_header *hdrs_arr = ap_table_elts(r->headers_in);
2762      table_entry *hdrs = (table_entry *) hdrs_arr->elts;
2763      int i;
2764 +    char servbuf[NI_MAXSERV];
2765  
2766      /* use a temporary table which we'll overlap onto
2767       * r->subprocess_env later
2768 @@ -298,8 +300,16 @@
2769      ap_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
2770      ap_table_addn(e, "SCRIPT_FILENAME", r->filename);  /* Apache */
2771  
2772 -    ap_table_addn(e, "REMOTE_PORT",
2773 -                 ap_psprintf(r->pool, "%d", ntohs(c->remote_addr.sin_port)));
2774 +    servbuf[0] = '\0';
2775 +    if (!getnameinfo((struct sockaddr *)&c->remote_addr,
2776 +#ifndef HAVE_SOCKADDR_LEN
2777 +                    SA_LEN((struct sockaddr *)&c->remote_addr),
2778 +#else
2779 +                    c->remote_addr.ss_len,
2780 +#endif
2781 +                    NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)){
2782 +       ap_table_addn(e, "REMOTE_PORT", ap_pstrdup(r->pool, servbuf));
2783 +    }
2784  
2785      if (c->user) {
2786         ap_table_addn(e, "REMOTE_USER", c->user);
2787 diff -Nur apache_1.3.23.orig/src/main/util_uri.c apache_1.3.23/src/main/util_uri.c
2788 --- apache_1.3.23.orig/src/main/util_uri.c      Sun Jan 20 21:14:37 2002
2789 +++ apache_1.3.23/src/main/util_uri.c   Wed Feb  6 20:20:48 2002
2790 @@ -419,6 +419,12 @@
2791           * the hostname.  If there's a port it is the first colon.
2792           */
2793          s = memchr(hostinfo, ':', uri - hostinfo);
2794 +       if (*hostinfo == '[') {
2795 +           s = memchr(hostinfo+1, ']', uri - hostinfo - 1);
2796 +           if (s)
2797 +               s = strchr(s, ':');
2798 +       } else
2799 +           s = memchr(hostinfo, ':', uri - hostinfo);              
2800          if (s == NULL) {
2801              /* we expect the common case to have no port */
2802              uptr->hostname = ap_pstrndup(p, hostinfo, uri - hostinfo);
2803 @@ -475,7 +481,12 @@
2804      /* We expect hostinfo to point to the first character of
2805       * the hostname.  There must be a port, separated by a colon
2806       */
2807 -    s = strchr(hostinfo, ':');
2808 +    if (*hostinfo == '[') {
2809 +        s = strchr(hostinfo+1, ']');
2810 +        if (s)
2811 +            s = strchr(s, ':');
2812 +    } else
2813 +        s = strchr(hostinfo, ':');
2814      if (s == NULL) {
2815          return HTTP_BAD_REQUEST;
2816      }
2817 diff -Nur apache_1.3.23.orig/src/modules/proxy/mod_proxy.c apache_1.3.23/src/modules/proxy/mod_proxy.c
2818 --- apache_1.3.23.orig/src/modules/proxy/mod_proxy.c    Wed Feb  6 20:17:43 2002
2819 +++ apache_1.3.23/src/modules/proxy/mod_proxy.c Wed Feb  6 20:38:49 2002
2820 @@ -556,11 +556,31 @@
2821      struct proxy_remote *new;
2822      char *p, *q;
2823      int port;
2824 +    char *bl = NULL, *br = NULL;
2825  
2826      p = strchr(r, ':');
2827      if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0')
2828          return "ProxyRemote: Bad syntax for a remote proxy server";
2829 -    q = strchr(p + 3, ':');
2830 +    bl = p + 3;
2831 +    if (*bl == '['){
2832 +       br = strrchr(bl+1, ']');
2833 +       if (br){
2834 +           bl++;
2835 +           *br = '\0';
2836 +           if (*(br+1) == ':'){        /* [host]:xx */
2837 +               q = br+1;
2838 +           }
2839 +           else if (*(br+1) == '\0'){  /* [host] */
2840 +               q = NULL;
2841 +           }
2842 +           else
2843 +               q = strrchr(br, ':');   /* XXX */
2844 +       }
2845 +       else
2846 +           q = strrchr(bl, ':');       /* XXX */
2847 +    }
2848 +    else
2849 +       q = strrchr(bl, ':');
2850      if (q != NULL) {
2851          if (sscanf(q + 1, "%u", &port) != 1 || port > 65535)
2852              return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)";
2853 @@ -571,7 +591,7 @@
2854      *p = '\0';
2855      if (strchr(f, ':') == NULL)
2856          ap_str_tolower(f);              /* lowercase scheme */
2857 -    ap_str_tolower(p + 3);              /* lowercase hostname */
2858 +    ap_str_tolower(bl);                 /* lowercase hostname */
2859  
2860      if (port == -1) {
2861          int i;
2862 @@ -584,7 +604,7 @@
2863      new = ap_push_array(conf->proxies);
2864      new->scheme = f;
2865      new->protocol = r;
2866 -    new->hostname = p + 3;
2867 +    new->hostname = bl;
2868      new->port = port;
2869      return NULL;
2870  }
2871 diff -Nur apache_1.3.23.orig/src/modules/proxy/mod_proxy.h apache_1.3.23/src/modules/proxy/mod_proxy.h
2872 --- apache_1.3.23.orig/src/modules/proxy/mod_proxy.h    Fri Jan 18 21:26:58 2002
2873 +++ apache_1.3.23/src/modules/proxy/mod_proxy.h Wed Feb  6 20:20:48 2002
2874 @@ -308,7 +308,7 @@
2875  int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p);
2876  int ap_proxy_is_hostname(struct dirconn_entry *This, pool *p);
2877  int ap_proxy_is_word(struct dirconn_entry *This, pool *p);
2878 -int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
2879 +int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r);
2880  int ap_proxy_garbage_init(server_rec *, pool *);
2881  /* This function is called by ap_table_do() for all header lines */
2882  int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
2883 diff -Nur apache_1.3.23.orig/src/modules/proxy/mod_proxy.h.orig apache_1.3.23/src/modules/proxy/mod_proxy.h.orig
2884 --- apache_1.3.23.orig/src/modules/proxy/mod_proxy.h.orig       Thu Jan  1 01:00:00 1970
2885 +++ apache_1.3.23/src/modules/proxy/mod_proxy.h.orig    Fri Jan 18 21:26:58 2002
2886 @@ -0,0 +1,342 @@
2887 +/* ====================================================================
2888 + * The Apache Software License, Version 1.1
2889 + *
2890 + * Copyright (c) 2000 The Apache Software Foundation.  All rights
2891 + * reserved.
2892 + *
2893 + * Redistribution and use in source and binary forms, with or without
2894 + * modification, are permitted provided that the following conditions
2895 + * are met:
2896 + *
2897 + * 1. Redistributions of source code must retain the above copyright
2898 + *    notice, this list of conditions and the following disclaimer.
2899 + *
2900 + * 2. Redistributions in binary form must reproduce the above copyright
2901 + *    notice, this list of conditions and the following disclaimer in
2902 + *    the documentation and/or other materials provided with the
2903 + *    distribution.
2904 + *
2905 + * 3. The end-user documentation included with the redistribution,
2906 + *    if any, must include the following acknowledgment:
2907 + *       "This product includes software developed by the
2908 + *        Apache Software Foundation (http://www.apache.org/)."
2909 + *    Alternately, this acknowledgment may appear in the software itself,
2910 + *    if and wherever such third-party acknowledgments normally appear.
2911 + *
2912 + * 4. The names "Apache" and "Apache Software Foundation" must
2913 + *    not be used to endorse or promote products derived from this
2914 + *    software without prior written permission. For written
2915 + *    permission, please contact apache@apache.org.
2916 + *
2917 + * 5. Products derived from this software may not be called "Apache",
2918 + *    nor may "Apache" appear in their name, without prior written
2919 + *    permission of the Apache Software Foundation.
2920 + *
2921 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
2922 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2923 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2924 + * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
2925 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2926 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2927 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2928 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2929 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2930 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2931 + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2932 + * SUCH DAMAGE.
2933 + * ====================================================================
2934 + *
2935 + * This software consists of voluntary contributions made by many
2936 + * individuals on behalf of the Apache Software Foundation.  For more
2937 + * information on the Apache Software Foundation, please see
2938 + * <http://www.apache.org/>.
2939 + *
2940 + * Portions of this software are based upon public domain software
2941 + * originally written at the National Center for Supercomputing Applications,
2942 + * University of Illinois, Urbana-Champaign.
2943 + */
2944 +
2945 +#ifndef MOD_PROXY_H
2946 +#define MOD_PROXY_H 
2947 +
2948 +/*
2949 + * Main include file for the Apache proxy
2950 + */
2951 +
2952 +/*
2953 +
2954 +   Note numerous FIXMEs and CHECKMEs which should be eliminated.
2955 +
2956 +   If TESTING is set, then garbage collection doesn't delete ... probably a good
2957 +   idea when hacking.
2958 +
2959 + */
2960 +
2961 +#define TESTING 0
2962 +
2963 +#include "httpd.h"
2964 +#include "http_config.h"
2965 +#include "http_protocol.h"
2966 +
2967 +#include "explain.h"
2968 +
2969 +extern module MODULE_VAR_EXPORT proxy_module;
2970 +
2971 +
2972 +/* for proxy_canonenc() */
2973 +enum enctype {
2974 +    enc_path, enc_search, enc_user, enc_fpath, enc_parm
2975 +};
2976 +
2977 +#define HDR_APP (0)             /* append header, for proxy_add_header() */
2978 +#define HDR_REP (1)             /* replace header, for proxy_add_header() */
2979 +
2980 +/* number of characters in the hash */
2981 +#define HASH_LEN (22*2)
2982 +
2983 +/* maximum  'CacheDirLevels*CacheDirLength' value */
2984 +#define CACHEFILE_LEN 20        /* must be less than HASH_LEN/2 */
2985 +
2986 +#define SEC_ONE_DAY             86400   /* one day, in seconds */
2987 +#define SEC_ONE_HR              3600    /* one hour, in seconds */
2988 +
2989 +#define DEFAULT_FTP_DATA_PORT   20
2990 +#define DEFAULT_FTP_PORT        21
2991 +#define DEFAULT_GOPHER_PORT     70
2992 +#define DEFAULT_NNTP_PORT       119
2993 +#define DEFAULT_WAIS_PORT       210
2994 +#define DEFAULT_HTTPS_PORT      443
2995 +#define DEFAULT_SNEWS_PORT      563
2996 +#define DEFAULT_PROSPERO_PORT   1525    /* WARNING: conflict w/Oracle */
2997 +
2998 +/* Some WWW schemes and their default ports; this is basically /etc/services */
2999 +struct proxy_services {
3000 +    const char *scheme;
3001 +    int port;
3002 +};
3003 +
3004 +/* static information about a remote proxy */
3005 +struct proxy_remote {
3006 +    const char *scheme;         /* the schemes handled by this proxy, or '*' */
3007 +    const char *protocol;       /* the scheme used to talk to this proxy */
3008 +    const char *hostname;       /* the hostname of this proxy */
3009 +    int port;                   /* the port for this proxy */
3010 +};
3011 +
3012 +struct proxy_alias {
3013 +    char *real;
3014 +    char *fake;
3015 +};
3016 +
3017 +struct dirconn_entry {
3018 +    char *name;
3019 +    struct in_addr addr, mask;
3020 +    struct hostent *hostentry;
3021 +    int (*matcher) (struct dirconn_entry * This, request_rec *r);
3022 +};
3023 +
3024 +struct noproxy_entry {
3025 +    char *name;
3026 +    struct in_addr addr;
3027 +};
3028 +
3029 +struct nocache_entry {
3030 +    char *name;
3031 +    struct in_addr addr;
3032 +};
3033 +
3034 +#define DEFAULT_CACHE_SPACE 5
3035 +#define DEFAULT_CACHE_MAXEXPIRE SEC_ONE_DAY
3036 +#define DEFAULT_CACHE_EXPIRE    SEC_ONE_HR
3037 +#define DEFAULT_CACHE_LMFACTOR (0.1)
3038 +#define DEFAULT_CACHE_COMPLETION (0.9)
3039 +#define DEFAULT_CACHE_GCINTERVAL SEC_ONE_HR
3040 +
3041 +#ifndef MAX
3042 +#define MAX(a,b)                ((a) > (b) ? (a) : (b))
3043 +#endif
3044 +#ifndef MIN
3045 +#define MIN(a,b)                ((a) < (b) ? (a) : (b))
3046 +#endif
3047 +
3048 +/* static information about the local cache */
3049 +struct cache_conf {
3050 +    const char *root;           /* the location of the cache directory */
3051 +    off_t space;                /* Maximum cache size (in 1024 bytes) */
3052 +    char space_set;
3053 +    time_t maxexpire;           /* Maximum time to keep cached files in secs */
3054 +    char maxexpire_set;
3055 +    time_t defaultexpire;       /* default time to keep cached file in secs */
3056 +    char defaultexpire_set;
3057 +    double lmfactor;            /* factor for estimating expires date */
3058 +    char lmfactor_set;
3059 +    time_t gcinterval;          /* garbage collection interval, in seconds */
3060 +    char gcinterval_set;
3061 +    int dirlevels;              /* Number of levels of subdirectories */
3062 +    char dirlevels_set;
3063 +    int dirlength;              /* Length of subdirectory names */
3064 +    char dirlength_set;
3065 +    float cache_completion;     /* Force cache completion after this point */
3066 +    char cache_completion_set;
3067 +};
3068 +
3069 +typedef struct {
3070 +    struct cache_conf cache;    /* cache configuration */
3071 +    array_header *proxies;
3072 +    array_header *aliases;
3073 +    array_header *raliases;
3074 +    array_header *noproxies;
3075 +    array_header *dirconn;
3076 +    array_header *nocaches;
3077 +    array_header *allowed_connect_ports;
3078 +    char *domain;               /* domain name to use in absence of a domain name in the request */
3079 +    int req;                    /* true if proxy requests are enabled */
3080 +    char req_set;
3081 +    enum {
3082 +      via_off,
3083 +      via_on,
3084 +      via_block,
3085 +      via_full
3086 +    } viaopt;                   /* how to deal with proxy Via: headers */
3087 +    char viaopt_set;
3088 +    size_t recv_buffer_size;
3089 +    char recv_buffer_size_set;
3090 +} proxy_server_conf;
3091 +
3092 +struct hdr_entry {
3093 +    const char *field;
3094 +    const char *value;
3095 +};
3096 +
3097 +/* caching information about a request */
3098 +typedef struct {
3099 +    request_rec *req;           /* the request */
3100 +    char *url;                  /* the URL requested */
3101 +    char *filename;             /* name of the cache file,
3102 +                                   or NULL if no cache */
3103 +    char *tempfile;             /* name of the temporary file,
3104 +                                   or NULL if not caching */
3105 +    time_t ims;                 /* if-Modified-Since date of request,
3106 +                                   -1 if no header */
3107 +    time_t ius;                 /* if-Unmodified-Since date of request,
3108 +                                   -1 if no header */
3109 +    const char *im;             /* if-Match etag of request,
3110 +                                   NULL if no header */
3111 +    const char *inm;            /* if-None-Match etag of request,
3112 +                                   NULL if no header */
3113 +    BUFF *fp;                   /* the cache file descriptor if the file
3114 +                                   is cached and may be returned,
3115 +                                   or NULL if the file is not cached
3116 +                                   (or must be reloaded) */
3117 +    BUFF *origfp;               /* the old cache file descriptor if the file has
3118 +                                   been revalidated and is being rewritten to
3119 +                                   disk */
3120 +    time_t expire;              /* calculated expire date of cached entity */
3121 +    time_t lmod;                /* last-modified date of cached entity */
3122 +    time_t date;                /* the date the cached file was last touched */
3123 +    time_t req_time;            /* the time the request started */
3124 +    time_t resp_time;           /* the time the response was received */
3125 +    int version;                /* update count of the file */
3126 +    off_t len;                  /* content length */
3127 +    char *protocol;             /* Protocol, and major/minor number,
3128 +                                   e.g. HTTP/1.1 */
3129 +    int status;                 /* the status of the cached file */
3130 +    unsigned int written;       /* total *content* bytes written to cache */
3131 +    float cache_completion;     /* specific to this request */
3132 +    char *resp_line;            /* the whole status line
3133 +                                   (protocol, code + message) */
3134 +    table *req_hdrs;            /* the original request headers */
3135 +    table *hdrs;                /* the original HTTP response headers
3136 +                                   of the file */
3137 +    char *xcache;               /* the X-Cache header value
3138 +                                   to be sent to client */
3139 +} cache_req;
3140 +
3141 +struct per_thread_data {
3142 +    struct hostent hpbuf;
3143 +    u_long ipaddr;
3144 +    char *charpbuf[2];
3145 +};
3146 +/* Function prototypes */
3147 +
3148 +/* proxy_cache.c */
3149 +
3150 +void ap_proxy_cache_tidy(cache_req *c);
3151 +int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf,
3152 +                      cache_req **cr);
3153 +int ap_proxy_cache_update(cache_req *c, table *resp_hdrs,
3154 +                       const int is_HTTP1, int nocache);
3155 +void ap_proxy_garbage_coll(request_rec *r);
3156 +
3157 +/* proxy_connect.c */
3158 +
3159 +int ap_proxy_connect_handler(request_rec *r, cache_req *c, char *url,
3160 +                          const char *proxyhost, int proxyport);
3161 +
3162 +/* proxy_ftp.c */
3163 +
3164 +int ap_proxy_ftp_canon(request_rec *r, char *url);
3165 +int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url);
3166 +
3167 +/* proxy_http.c */
3168 +
3169 +int ap_proxy_http_canon(request_rec *r, char *url, const char *scheme,
3170 +                     int def_port);
3171 +int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url,
3172 +                       const char *proxyhost, int proxyport);
3173 +
3174 +/* proxy_util.c */
3175 +
3176 +int ap_proxy_hex2c(const char *x);
3177 +void ap_proxy_c2hex(int ch, char *x);
3178 +char *ap_proxy_canonenc(pool *p, const char *x, int len, enum enctype t,
3179 +                        enum proxyreqtype isenc);
3180 +char *ap_proxy_canon_netloc(pool *p, char **const urlp, char **userp,
3181 +                         char **passwordp, char **hostp, int *port);
3182 +const char *ap_proxy_date_canon(pool *p, const char *x);
3183 +table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f);
3184 +long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c, off_t len, int nowrite);
3185 +void ap_proxy_write_headers(cache_req *c, const char *respline, table *t);
3186 +int ap_proxy_liststr(const char *list, const char *key, char **val);
3187 +void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength);
3188 +int ap_proxy_hex2sec(const char *x);
3189 +void ap_proxy_sec2hex(int t, char *y);
3190 +cache_req *ap_proxy_cache_error(cache_req *r);
3191 +int ap_proxyerror(request_rec *r, int statuscode, const char *message);
3192 +const char *ap_proxy_host2addr(const char *host, struct hostent *reqhp);
3193 +int ap_proxy_is_ipaddr(struct dirconn_entry *This, pool *p);
3194 +int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p);
3195 +int ap_proxy_is_hostname(struct dirconn_entry *This, pool *p);
3196 +int ap_proxy_is_word(struct dirconn_entry *This, pool *p);
3197 +int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
3198 +int ap_proxy_garbage_init(server_rec *, pool *);
3199 +/* This function is called by ap_table_do() for all header lines */
3200 +int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
3201 +unsigned ap_proxy_bputs2(const char *data, BUFF *client, cache_req *cache);
3202 +time_t ap_proxy_current_age(cache_req *c, const time_t age_value);
3203 +BUFF *ap_proxy_open_cachefile(request_rec *r, char *filename);
3204 +BUFF *ap_proxy_create_cachefile(request_rec *r, char *filename);
3205 +void ap_proxy_clear_connection(pool *p, table *headers);
3206 +int ap_proxy_table_replace(table *base, table *overlay);
3207 +
3208 +/* WARNING - PRIVATE DEFINITION BELOW */
3209 +
3210 +/* XXX: if you tweak this you should look at is_empty_table() and table_elts()
3211 + * in ap_alloc.h
3212 + *
3213 + * NOTE: this private definition is a duplicate of the one in alloc.c
3214 + * It's here for ap_proxy_table_replace() to avoid breaking binary compat
3215 + */
3216 +struct table {
3217 +    /* This has to be first to promote backwards compatibility with
3218 +     * older modules which cast a table * to an array_header *...
3219 +     * they should use the table_elts() function for most of the
3220 +     * cases they do this for.
3221 +     */
3222 +    array_header a;
3223 +#ifdef MAKE_TABLE_PROFILE
3224 +    void *creator;
3225 +#endif
3226 +};
3227 +
3228 +#endif /*MOD_PROXY_H*/
3229 diff -Nur apache_1.3.23.orig/src/modules/proxy/proxy_connect.c apache_1.3.23/src/modules/proxy/proxy_connect.c
3230 --- apache_1.3.23.orig/src/modules/proxy/proxy_connect.c        Sun Jan 20 21:14:37 2002
3231 +++ apache_1.3.23/src/modules/proxy/proxy_connect.c     Wed Feb  6 20:49:52 2002
3232 @@ -114,14 +114,15 @@
3233                            const char *proxyhost, int proxyport)
3234  {
3235      struct sockaddr_in server;
3236 -    struct in_addr destaddr;
3237 -    struct hostent server_hp;
3238 -    const char *host, *err;
3239 +    struct addrinfo hints, *res, *res0;
3240 +    const char *hoststr;
3241 +    const char *portstr = NULL;
3242      char *p;
3243      int port, sock;
3244      char buffer[HUGE_STRING_LEN];
3245 -    int nbytes, i, j;
3246 +    int nbytes, i;
3247      fd_set fds;
3248 +    int error;
3249  
3250      void *sconf = r->server->module_config;
3251      proxy_server_conf *conf =
3252 @@ -129,27 +130,59 @@
3253      struct noproxy_entry *npent = (struct noproxy_entry *)conf->noproxies->elts;
3254  
3255      memset(&server, '\0', sizeof(server));
3256 +#ifdef HAVE_SOCKADDR_LEN
3257 +    server.sin_len = sizeof(server);
3258 +#endif
3259      server.sin_family = AF_INET;
3260  
3261      /* Break the URL into host:port pairs */
3262  
3263 -    host = url;
3264 +    hoststr = url;
3265      p = strchr(url, ':');
3266 -    if (p == NULL)
3267 -        port = DEFAULT_HTTPS_PORT;
3268 -    else {
3269 -        port = atoi(p + 1);
3270 +    if (p == NULL) {
3271 +       char pbuf[32];
3272 +       ap_snprintf(pbuf, sizeof(pbuf), "%d", DEFAULT_HTTPS_PORT);
3273 +       portstr = pbuf;
3274 +    } else {
3275 +       portstr = p + 1;
3276          *p = '\0';
3277      }
3278 +    port = atoi(portstr);
3279 +
3280 +    memset(&hints, 0, sizeof(hints));
3281 +    hints.ai_family = PF_UNSPEC;
3282 +    hints.ai_socktype = SOCK_STREAM;
3283 +    hints.ai_protocol = IPPROTO_TCP;
3284 +    error = getaddrinfo(hoststr, portstr, &hints, &res0);
3285 +    if (error) {
3286 +       return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3287 +                   gai_strerror(error));       /* give up */
3288 +    }
3289  
3290  /* check if ProxyBlock directive on this host */
3291 -    destaddr.s_addr = ap_inet_addr(host);
3292 -    for (i = 0; i < conf->noproxies->nelts; i++) {
3293 -        if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL)
3294 -            || destaddr.s_addr == npent[i].addr.s_addr
3295 -            || npent[i].name[0] == '*')
3296 +    for (res = res0; res; res = res = res->ai_next) {
3297 +       struct sockaddr_in *sin;
3298 +       int fail;
3299 +
3300 +       fail = 0;
3301 +       for (i = 0; i < conf->noproxies->nelts; i++) {
3302 +           if (npent[i].name != NULL && strstr(hoststr, npent[i].name))
3303 +               fail++;
3304 +           if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
3305 +               fail++;
3306 +           switch (res->ai_family) {
3307 +           case AF_INET:
3308 +               sin = (struct sockaddr_in *)res->ai_addr;
3309 +               if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
3310 +                   fail++;
3311 +               break;
3312 +           }
3313 +       }
3314 +       if (fail) {
3315 +           freeaddrinfo(res0);
3316              return ap_proxyerror(r, HTTP_FORBIDDEN,
3317                                   "Connect to remote machine blocked");
3318 +       }
3319      }
3320  
3321      /* Check if it is an allowed port */
3322 @@ -160,33 +193,41 @@
3323              case DEFAULT_SNEWS_PORT:
3324                  break;
3325              default:
3326 +               freeaddrinfo(res0);
3327                  return HTTP_FORBIDDEN;
3328          }
3329 -    } else if(!allowed_port(conf, port))
3330 +    } else if(!allowed_port(conf, port)) {
3331 +       freeaddrinfo(res0);
3332          return HTTP_FORBIDDEN;
3333 +    }
3334  
3335      if (proxyhost) {
3336 +       char pbuf[10];
3337 +
3338 +       freeaddrinfo(res0);
3339 +
3340 +       ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
3341 +       memset(&hints, 0, sizeof(hints));
3342 +       hints.ai_family = PF_UNSPEC;
3343 +       hints.ai_socktype = SOCK_STREAM;
3344 +       hints.ai_protocol = IPPROTO_TCP;
3345 +       error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
3346 +       if (error)
3347 +           return HTTP_INTERNAL_SERVER_ERROR;  /* XXX */
3348 +
3349          ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
3350              "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
3351      }
3352      else {
3353          ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
3354 -            "CONNECT to %s on port %d", host, port);
3355 +            "CONNECT to %s on port %d", hoststr, port);
3356      }
3357  
3358 -    /* Nasty cast to work around broken terniary expressions on MSVC */
3359 -    server.sin_port = htons((unsigned short)(proxyport ? proxyport : port));
3360 -    err = ap_proxy_host2addr(proxyhost ? proxyhost : host, &server_hp);
3361 -
3362 -    if (err != NULL)
3363 -        return ap_proxyerror(r,
3364 -           proxyhost ? HTTP_BAD_GATEWAY : HTTP_INTERNAL_SERVER_ERROR, err);
3365 -
3366 -    sock = ap_psocket(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP);
3367 -    if (sock == -1) {
3368 -        ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "proxy: error creating socket");
3369 -        return HTTP_INTERNAL_SERVER_ERROR;
3370 -    }
3371 +    sock = i = -1;
3372 +    for (res = res0; res; res = res->ai_next) {
3373 +       sock = ap_psocket(r->pool, res->ai_family, res->ai_socktype, res->ai_protocol);
3374 +       if (sock == -1)
3375 +           continue;
3376  
3377  #ifdef CHECK_FD_SETSIZE
3378      if (sock >= FD_SETSIZE) {
3379 @@ -196,19 +237,15 @@
3380              "found, you probably need to rebuild Apache with a "
3381              "larger FD_SETSIZE", sock, FD_SETSIZE);
3382          ap_pclosesocket(r->pool, sock);
3383 -        return HTTP_INTERNAL_SERVER_ERROR;
3384 +       continue;
3385      }
3386  #endif
3387  
3388 -    j = 0;
3389 -    while (server_hp.h_addr_list[j] != NULL) {
3390 -        memcpy(&server.sin_addr, server_hp.h_addr_list[j],
3391 -               sizeof(struct in_addr));
3392 -        i = ap_proxy_doconnect(sock, &server, r);
3393 +       i = ap_proxy_doconnect(sock, res->ai_addr, r);
3394          if (i == 0)
3395              break;
3396 -        j++;
3397      }
3398 +    freeaddrinfo(res0);
3399      if (i == -1) {
3400          ap_pclosesocket(r->pool, sock);
3401          return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, ap_pstrcat(r->pool,
3402 diff -Nur apache_1.3.23.orig/src/modules/proxy/proxy_ftp.c apache_1.3.23/src/modules/proxy/proxy_ftp.c
3403 --- apache_1.3.23.orig/src/modules/proxy/proxy_ftp.c    Sun Jan 20 21:14:37 2002
3404 +++ apache_1.3.23/src/modules/proxy/proxy_ftp.c Wed Feb  6 21:08:39 2002
3405 @@ -62,6 +62,7 @@
3406  #include "http_main.h"
3407  #include "http_log.h"
3408  #include "http_core.h"
3409 +#include "sa_len.h"
3410  
3411  #define AUTODETECT_PWD
3412  
3413 @@ -451,8 +452,10 @@
3414      const char *err;
3415      int port, i, j, len, sock, dsock, rc, nocache = 0;
3416      int csd = 0;
3417 -    struct sockaddr_in server;
3418 -    struct hostent server_hp;
3419 +    struct sockaddr_storage server;
3420 +    struct addrinfo hints, *res, *res0;
3421 +    char portbuf[10];
3422 +    int error;
3423      struct in_addr destaddr;
3424      table *resp_hdrs;
3425      BUFF *f;
3426 @@ -471,11 +474,18 @@
3427      unsigned int presult, h0, h1, h2, h3, p0, p1;
3428      unsigned int paddr;
3429      unsigned short pport;
3430 -    struct sockaddr_in data_addr;
3431 +    struct sockaddr_storage data_addr;
3432 +    struct sockaddr_in *sin;
3433      int pasvmode = 0;
3434      char pasv[64];
3435      char *pstr;
3436  
3437 +/* stuff for LPSV/EPSV */
3438 +    unsigned int paf, holen, ho[16], polen, po[2];
3439 +    struct sockaddr_in6 *sin6;
3440 +    int lpsvmode = 0;
3441 +    char *cmd;
3442 +
3443  /* stuff for responses */
3444      char resp[MAX_STRING_LEN];
3445      char *size = NULL;
3446 @@ -545,62 +555,52 @@
3447      if (parms != NULL)
3448          *(parms++) = '\0';
3449  
3450 -    memset(&server, 0, sizeof(struct sockaddr_in));
3451 -    server.sin_family = AF_INET;
3452 -    server.sin_port = htons((unsigned short)port);
3453 -    err = ap_proxy_host2addr(host, &server_hp);
3454 -    if (err != NULL)
3455 -        return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
3456 -
3457 -    sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
3458 -    if (sock == -1) {
3459 -        ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3460 -                     "proxy: error creating socket");
3461 -        return HTTP_INTERNAL_SERVER_ERROR;
3462 -    }
3463 +    ap_snprintf(portbuf, sizeof(portbuf), "%d", port);
3464 +    memset(&hints, 0, sizeof(hints));
3465 +    hints.ai_family = PF_UNSPEC;
3466 +    hints.ai_socktype = SOCK_STREAM;
3467 +    error = getaddrinfo(host, portbuf, &hints, &res0);
3468 +    if (error) {
3469 +       return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3470 +           gai_strerror(error));
3471 +    }
3472 +
3473 +    i = -1;
3474 +    for (res = res0; res; res = res->ai_next) {
3475 +       sock = ap_psocket(p, res->ai_family, res->ai_socktype,
3476 +           res->ai_protocol);
3477 +       if (sock == -1)
3478 +           continue;
3479  
3480  #if !defined(TPF) && !defined(BEOS)
3481 -    if (conf->recv_buffer_size > 0
3482 -        && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
3483 -                       (const char *) &conf->recv_buffer_size, sizeof(int))
3484 -            == -1) {
3485 -            ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3486 -                         "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
3487 -    }
3488 +       if (conf->recv_buffer_size > 0
3489 +           && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
3490 +                          (const char *) &conf->recv_buffer_size, sizeof(int))
3491 +               == -1) {
3492 +               ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3493 +                            "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
3494 +       }
3495  #endif
3496  
3497 -    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &one,
3498 -                   sizeof(one)) == -1) {
3499 +       if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &one,
3500 +                      sizeof(one)) == -1) {
3501  #ifndef _OSD_POSIX /* BS2000 has this option "always on" */
3502 -        ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3503 -                     "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
3504 -        ap_pclosesocket(p, sock);
3505 -        return HTTP_INTERNAL_SERVER_ERROR;
3506 +           ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3507 +                        "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
3508 +           ap_pclosesocket(p, sock);
3509 +           freeaddrinfo(res0);
3510 +           return HTTP_INTERNAL_SERVER_ERROR;
3511  #endif /*_OSD_POSIX*/
3512 -    }
3513 -
3514 -#ifdef SINIX_D_RESOLVER_BUG
3515 -    {
3516 -        struct in_addr *ip_addr = (struct in_addr *) *server_hp.h_addr_list;
3517 -
3518 -        for (; ip_addr->s_addr != 0; ++ip_addr) {
3519 -            memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
3520 -            i = ap_proxy_doconnect(sock, &server, r);
3521 -            if (i == 0)
3522 -                break;
3523          }
3524 -    }
3525 -#else
3526 -    j = 0;
3527 -    while (server_hp.h_addr_list[j] != NULL) {
3528 -        memcpy(&server.sin_addr, server_hp.h_addr_list[j],
3529 -               sizeof(struct in_addr));
3530 -        i = ap_proxy_doconnect(sock, &server, r);
3531 -        if (i == 0)
3532 +
3533 +       i = ap_proxy_doconnect(sock, res->ai_addr, r);
3534 +       if (i == 0){
3535 +           memcpy(&server, res->ai_addr, res->ai_addrlen);
3536              break;
3537 -        j++;
3538 +       }
3539 +       ap_pclosesocket(p, sock);
3540      }
3541 -#endif
3542 +    freeaddrinfo(res0);
3543      if (i == -1) {
3544          ap_pclosesocket(p, sock);
3545          return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool,
3546 @@ -807,7 +807,7 @@
3547      }
3548  
3549  /* try to set up PASV data connection first */
3550 -    dsock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
3551 +    dsock = ap_psocket(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP);
3552      if (dsock == -1) {
3553          ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3554                       "proxy: error creating PASV socket");
3555 @@ -826,11 +826,22 @@
3556      }
3557  #endif
3558  
3559 -    ap_bputs("PASV" CRLF, f);
3560 +lpsvagain:
3561 +    if (server.ss_family == AF_INET)
3562 +       cmd = "PASV";
3563 +    else if (lpsvmode)
3564 +       cmd = "LPSV";
3565 +    else
3566 +       cmd = "EPSV";
3567 +    ap_bputs(cmd, f);
3568 +    ap_bputs(CRLF, f);
3569      ap_bflush(f);
3570 +    Explain0("FTP: passive command issued");
3571      ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: PASV command issued");
3572 -/* possible results: 227, 421, 500, 501, 502, 530 */
3573 +    /* possible results: 227, 228, 229, 421, 500, 501, 502, 530 */
3574      /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */
3575 +    /* 228 Entering Long Passive Mode (...). */
3576 +    /* 229 Entering Extended Passive Mode (...). */
3577      /* 421 Service not available, closing control connection. */
3578      /* 500 Syntax error, command unrecognized. */
3579      /* 501 Syntax error in parameters or arguments. */
3580 @@ -839,7 +850,7 @@
3581      i = ap_bgets(pasv, sizeof(pasv), f);
3582      if (i == -1) {
3583          ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r,
3584 -                     "PASV: control connection is toast");
3585 +                     "%s: control connection is toast", cmd);
3586          ap_pclosesocket(p, dsock);
3587          ap_bclose(f);
3588          ap_kill_timeout(r);
3589 @@ -871,10 +882,14 @@
3590              pport = (p1 << 8) + p0;
3591              ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: contacting host %d.%d.%d.%d:%d",
3592                       h3, h2, h1, h0, pport);
3593 -            data_addr.sin_family = AF_INET;
3594 -            data_addr.sin_addr.s_addr = htonl(paddr);
3595 -            data_addr.sin_port = htons(pport);
3596 -            i = ap_proxy_doconnect(dsock, &data_addr, r);
3597 +           sin = (struct sockaddr_in *)&data_addr;
3598 +           sin->sin_family = AF_INET;
3599 +#ifdef SIN6_LEN
3600 +           sin->sin_len = sizeof(*sin);
3601 +#endif
3602 +           sin->sin_addr.s_addr = htonl(paddr);
3603 +           sin->sin_port = htons(pport);
3604 +           i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
3605  
3606              if (i == -1) {
3607                  ap_kill_timeout(r);
3608 @@ -886,13 +901,73 @@
3609              else {
3610                  pasvmode = 1;
3611              }
3612 +       } else if (presult == 228 && pstr != NULL
3613 +               && sscanf(pstr,
3614 +"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
3615 +                   &paf, &holen, &ho[0], &ho[1], &ho[2], &ho[3],
3616 +                   &ho[4], &ho[5], &ho[6], &ho[7], &ho[8], &ho[9], &ho[10], &ho[11],
3617 +                   &ho[12], &ho[13], &ho[14], &ho[15], &polen, &po[0], &po[1]) == 21
3618 +               && paf == 6 && holen == 16 && polen == 2) {
3619 +           int i;
3620 +           sin6 = (struct sockaddr_in6 *)&data_addr;
3621 +           sin6->sin6_family = AF_INET6;
3622 +#ifdef SIN6_LEN
3623 +           sin6->sin6_len = sizeof(*sin6);
3624 +#endif
3625 +           for (i = 0; i < 16; i++)
3626 +               sin6->sin6_addr.s6_addr[i] = ho[i] & 0xff;
3627 +           sin6->sin6_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
3628 +           i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
3629 +
3630 +           if (i == -1) {
3631 +               ap_kill_timeout(r);
3632 +               return ap_proxyerror(r, HTTP_BAD_GATEWAY,
3633 +                                    ap_pstrcat(r->pool,
3634 +                                               "Could not connect to remote machine: ",
3635 +                                               strerror(errno), NULL));
3636 +           } else {
3637 +               pasvmode = 1;
3638 +           }
3639 +       } else if (presult == 229 && pstr != NULL
3640 +               && pstr[0] == pstr[1] && pstr[0] == pstr[2]
3641 +               && pstr[0] == pstr[strlen(pstr) - 1]) {
3642 +           /* expect "|||port|" */
3643 +#ifndef SIN6_LEN
3644 +           memcpy(&data_addr, &server, SA_LEN((struct sockaddr *)&server));
3645 +#else
3646 +           memcpy(&data_addr, &server, server.ss_len);
3647 +#endif
3648 +           switch (data_addr.ss_family) {
3649 +           case AF_INET:
3650 +               sin = (struct sockaddr_in *)&data_addr;
3651 +               sin->sin_port = htons(atoi(pstr + 3));
3652 +               break;
3653 +           case AF_INET6:
3654 +               sin6 = (struct sockaddr_in6 *)&data_addr;
3655 +               sin6->sin6_port = htons(atoi(pstr + 3));
3656 +               break;
3657 +           }
3658 +           i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
3659 +
3660 +           if (i == -1) {
3661 +               ap_kill_timeout(r);
3662 +               return ap_proxyerror(r, HTTP_BAD_GATEWAY,
3663 +                                    ap_pstrcat(r->pool,
3664 +                                               "Could not connect to remote machine: ",
3665 +                                               strerror(errno), NULL));
3666 +           } else {
3667 +               pasvmode = 1;
3668 +           }
3669 +       } else if (!lpsvmode && strcmp(cmd, "EPSV") == 0) {
3670 +           lpsvmode = 1;
3671 +           goto lpsvagain;
3672          }
3673          else
3674              ap_pclosesocket(p, dsock);  /* and try the regular way */
3675      }
3676  
3677      if (!pasvmode) {            /* set up data connection */
3678 -        clen = sizeof(struct sockaddr_in);
3679 +       clen = sizeof(server);
3680          if (getsockname(sock, (struct sockaddr *) &server, &clen) < 0) {
3681              ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3682                           "proxy: error getting socket address");
3683 @@ -901,7 +976,7 @@
3684              return HTTP_INTERNAL_SERVER_ERROR;
3685          }
3686  
3687 -        dsock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
3688 +        dsock = ap_psocket(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP);
3689          if (dsock == -1) {
3690              ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3691                           "proxy: error creating socket");
3692 @@ -922,13 +997,26 @@
3693  #endif /*_OSD_POSIX*/
3694          }
3695  
3696 -        if (bind(dsock, (struct sockaddr *) &server,
3697 -                 sizeof(struct sockaddr_in)) == -1) {
3698 -            char buff[22];
3699 +#ifndef SIN6_LEN
3700 +       if (bind(dsock, (struct sockaddr *) &server, SA_LEN((struct sockaddr *)&server)) == -1)
3701 +#else
3702 +       if (bind(dsock, (struct sockaddr *) &server, server.ss_len) == -1)
3703 +#endif
3704 +       {
3705 +           char hostnamebuf[MAXHOSTNAMELEN], portnamebuf[MAXHOSTNAMELEN];
3706  
3707 +           getnameinfo((struct sockaddr *)&server,
3708 +#ifndef SIN6_LEN
3709 +                   SA_LEN((struct sockaddr *)&server),
3710 +#else
3711 +                   server.ss_len,
3712 +#endif
3713 +               hostnamebuf, sizeof(hostnamebuf),
3714 +               portnamebuf, sizeof(portnamebuf),
3715 +               NI_NUMERICHOST | NI_NUMERICSERV);
3716 -            ap_snprintf(buff, sizeof(buff), "%s:%d", inet_ntoa(server.sin_addr), server.sin_port);
3717              ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3718 -                         "proxy: error binding to ftp data socket %s", buff);
3719 +                         "proxy: error binding to ftp data socket %s:%s",
3720 +                        hostnamebuf, portnamebuf);
3721              ap_bclose(f);
3722              ap_pclosesocket(p, dsock);
3723              return HTTP_INTERNAL_SERVER_ERROR;
3724 @@ -1187,7 +1276,7 @@
3725  
3726      if (!pasvmode) {            /* wait for connection */
3727          ap_hard_timeout("proxy ftp data connect", r);
3728 -        clen = sizeof(struct sockaddr_in);
3729 +        clen = sizeof(server);
3730          do
3731              csd = accept(dsock, (struct sockaddr *) &server, &clen);
3732          while (csd == -1 && errno == EINTR);
3733 diff -Nur apache_1.3.23.orig/src/modules/proxy/proxy_http.c apache_1.3.23/src/modules/proxy/proxy_http.c
3734 --- apache_1.3.23.orig/src/modules/proxy/proxy_http.c   Wed Feb  6 20:17:43 2002
3735 +++ apache_1.3.23/src/modules/proxy/proxy_http.c        Wed Feb  6 21:18:32 2002
3736 @@ -155,9 +155,8 @@
3737      table *req_hdrs, *resp_hdrs;
3738      array_header *reqhdrs_arr;
3739      table_entry *reqhdrs_elts;
3740 -    struct sockaddr_in server;
3741 -    struct in_addr destaddr;
3742 -    struct hostent server_hp;
3743 +    struct addrinfo hints, *res, *res0;
3744 +    int error;
3745      BUFF *f;
3746      char buffer[HUGE_STRING_LEN];
3747      char portstr[32];
3748 @@ -179,9 +178,6 @@
3749  
3750      if (conf->cache.root == NULL) nocache = 1;
3751  
3752 -    memset(&server, '\0', sizeof(server));
3753 -    server.sin_family = AF_INET;
3754 -
3755      /* We break the URL into host, port, path-search */
3756  
3757      urlptr = strstr(url, "://");
3758 @@ -189,6 +185,8 @@
3759          return HTTP_BAD_REQUEST;
3760      urlptr += 3;
3761      destport = DEFAULT_HTTP_PORT;
3762 +    ap_snprintf(portstr, sizeof(portstr), "%d", DEFAULT_HTTP_PORT);
3763 +    destportstr = portstr;           
3764  #ifdef EAPI
3765      ap_hook_use("ap::mod_proxy::http::handler::set_destport", 
3766                  AP_HOOK_SIG2(int,ptr), 
3767 @@ -207,7 +205,20 @@
3768          urlptr = strp;
3769          desthost = q;
3770      }
3771 -
3772 +   if (*desthost == '['){
3773 +       char *u = strrchr(desthost+1, ']');
3774 +       if (u){
3775 +          desthost++;
3776 +          *u = '\0';
3777 +          if (*(u+1) == ':'){ /* [host]:xx */
3778 +              strp2 = u+1;
3779 +          } else if (*(u+1) == '\0'){   /* [host] */
3780 +              strp2 = NULL;
3781 +          } else
3782 +              return HTTP_BAD_REQUEST;
3783 +       } else
3784 +           return HTTP_BAD_REQUEST;
3785 +   } else
3786      strp2 = strchr(desthost, ':');
3787      if (strp2 != NULL) {
3788          *(strp2++) = '\0';
3789 @@ -218,45 +229,69 @@
3790      }
3791  
3792      /* check if ProxyBlock directive on this host */
3793 -    destaddr.s_addr = ap_inet_addr(desthost);
3794 -    for (i = 0; i < conf->noproxies->nelts; i++) {
3795 -        if (destaddr.s_addr == npent[i].addr.s_addr ||
3796 -            (npent[i].name != NULL &&
3797 -              (npent[i].name[0] == '*' || strstr(desthost, npent[i].name) != NULL)))
3798 +     memset(&hints, 0, sizeof(hints));
3799 +     hints.ai_family = PF_UNSPEC;
3800 +     hints.ai_socktype = SOCK_STREAM;
3801 +     hints.ai_protocol = IPPROTO_TCP;
3802 +     error = getaddrinfo(desthost, destportstr, &hints, &res0);
3803 +     if (error) {
3804 +       return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3805 +               gai_strerror(error));       /* give up */
3806 +     }
3807 +    
3808 + /* check if ProxyBlock directive on this host */
3809 +     for (res = res0; res; res = res->ai_next) {
3810 +       struct sockaddr_in *sin;
3811 + #ifdef INET6
3812 +       struct sockaddr_in6 *sin6;
3813 + #endif
3814 +       int fail;
3815 +       
3816 +       fail = 0;
3817 +       for (i = 0; i < conf->noproxies->nelts; i++) {
3818 +           if (npent[i].name != NULL && strstr(desthost, npent[i].name))
3819 +               fail++;
3820 +           if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
3821 +               fail++;
3822 +           switch (res->ai_family) {
3823 +               case AF_INET:
3824 +                   sin = (struct sockaddr_in *)res->ai_addr;
3825 +                   if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
3826 +                       fail++;
3827 +                   break;
3828 +                   }
3829 +           }
3830 +       if (fail) {
3831 +           freeaddrinfo(res0);
3832              return ap_proxyerror(r, HTTP_FORBIDDEN,
3833                                   "Connect to remote machine blocked");
3834 -    }
3835 -
3836 -    if (proxyhost != NULL) {
3837 -        server.sin_port = htons((unsigned short)proxyport);
3838 -        err = ap_proxy_host2addr(proxyhost, &server_hp);
3839 -        if (err != NULL)
3840 +       }
3841 +      }
3842 +  
3843 +      if (proxyhost != NULL) {
3844 +       char pbuf[10];
3845 +       
3846 +       freeaddrinfo(res0);
3847 +       ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
3848 +       memset(&hints, 0, sizeof(hints));
3849 +       hints.ai_family = PF_UNSPEC;
3850 +       hints.ai_socktype = SOCK_STREAM;
3851 +       hints.ai_protocol = IPPROTO_TCP;
3852 +       error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
3853 +       if (error)
3854              return DECLINED;    /* try another */
3855 -#ifdef EAPI
3856 -       peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);  
3857 -#endif
3858 -    }
3859 -    else {
3860 -        server.sin_port = htons((unsigned short)destport);
3861 -        err = ap_proxy_host2addr(desthost, &server_hp);
3862 -        if (err != NULL)
3863 -            return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
3864 -#ifdef EAPI
3865 -       peer =  ap_psprintf(p, "%s:%u", desthost, destport);  
3866 -#endif
3867 -    }
3868 -
3869 -
3870 -    /* we have worked out who exactly we are going to connect to, now
3871 -     * make that connection...
3872 -     */
3873 -    sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
3874 -    if (sock == -1) {
3875 -        ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3876 -                    "proxy: error creating socket");
3877 -        return HTTP_INTERNAL_SERVER_ERROR;
3878 -    }
3879 -
3880 +  #ifdef EAPI
3881 +        peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);  
3882 +  #endif
3883 +      }
3884 +  
3885 +     sock = i = -1;
3886 +     for (res = res0; res; res = res->ai_next) {
3887 +       sock = ap_psocket(p, res->ai_family, res->ai_socktype,
3888 +               res->ai_protocol);
3889 +       if (sock < 0)
3890 +           continue;
3891 +    
3892  #if !defined(TPF) && !defined(BEOS)
3893      if (conf->recv_buffer_size) {
3894          if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
3895 @@ -268,28 +303,12 @@
3896      }
3897  #endif
3898  
3899 -#ifdef SINIX_D_RESOLVER_BUG
3900 -    {
3901 -        struct in_addr *ip_addr = (struct in_addr *) *server_hp.h_addr_list;
3902 -
3903 -        for (; ip_addr->s_addr != 0; ++ip_addr) {
3904 -            memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
3905 -            i = ap_proxy_doconnect(sock, &server, r);
3906 -            if (i == 0)
3907 -                break;
3908 -        }
3909 -    }
3910 -#else
3911 -    j = 0;
3912 -    while (server_hp.h_addr_list[j] != NULL) {
3913 -        memcpy(&server.sin_addr, server_hp.h_addr_list[j],
3914 -               sizeof(struct in_addr));
3915 -        i = ap_proxy_doconnect(sock, &server, r);
3916 +       i = ap_proxy_doconnect(sock, res->ai_addr, r);
3917          if (i == 0)
3918              break;
3919 -        j++;
3920 +       ap_pclosesocket(p, sock); 
3921      }
3922 -#endif
3923 +    freeaddrinfo(res0);
3924      if (i == -1) {
3925          if (proxyhost != NULL)
3926              return DECLINED;    /* try again another way */
3927 @@ -544,16 +563,30 @@
3928        ap_table_set(resp_hdrs, "Content-Location", proxy_location_reverse_map(r , urlstr));
3929  
3930  /* check if NoCache directive on this host */
3931 +  {
3932 +    struct sockaddr_in *sin;
3933 +#ifdef INET6
3934 +    struct sockaddr_in6 *sin6;
3935 +#endif
3936 +
3937      if (nocache == 0) {
3938          for (i = 0; i < conf->nocaches->nelts; i++) {
3939 -            if (destaddr.s_addr == ncent[i].addr.s_addr ||
3940 -                (ncent[i].name != NULL &&
3941 -                  (ncent[i].name[0] == '*' ||
3942 -                   strstr(desthost, ncent[i].name) != NULL))) {
3943 -               nocache = 1;
3944 -               break;
3945 +           if (ncent[i].name != NULL && 
3946 +               (ncent[i].name[0] == '*' ||
3947 +                strstr(desthost, ncent[i].name) != NULL)) {
3948 +               nocache = 1;
3949 +               break;
3950 +           }
3951 +           switch (res->ai_addr->sa_family) {
3952 +           case AF_INET:
3953 +               sin = (struct sockaddr_in *)res->ai_addr;
3954 +               if (sin->sin_addr.s_addr == ncent[i].addr.s_addr) {
3955 +                   nocache = 1;
3956 +                   break;
3957 +               }
3958              }
3959          }
3960 +  }
3961  
3962      /* update the cache file, possibly even fulfilling the request if
3963       * it turns out a conditional allowed us to serve the object from the
3964 diff -Nur apache_1.3.23.orig/src/modules/proxy/proxy_util.c apache_1.3.23/src/modules/proxy/proxy_util.c
3965 --- apache_1.3.23.orig/src/modules/proxy/proxy_util.c   Fri Jan 18 21:26:58 2002
3966 +++ apache_1.3.23/src/modules/proxy/proxy_util.c        Wed Feb  6 21:25:17 2002
3967 @@ -64,6 +64,7 @@
3968  #include "http_log.h"
3969  #include "util_uri.h"
3970  #include "util_date.h"  /* get ap_checkmask() decl. */
3971 +#include "sa_len.h"
3972  
3973  static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
3974  static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
3975 @@ -218,6 +219,7 @@
3976      int i;
3977      char *strp, *host, *url = *urlp;
3978      char *user = NULL, *password = NULL;
3979 +    char *t = NULL, *u = NULL, *v = NULL;
3980  
3981      if (url[0] != '/' || url[1] != '/')
3982          return "Malformed URL";
3983 @@ -256,11 +258,22 @@
3984          *passwordp = password;
3985      }
3986  
3987 -    strp = strrchr(host, ':');
3988 -    if (strp != NULL) {
3989 -        *(strp++) = '\0';
3990 -
3991 -        for (i = 0; strp[i] != '\0'; i++)
3992 +    v = host;
3993 +    if (*host == '['){
3994 +       u = strrchr(host, ']');
3995 +       if (u){
3996 +           host++;
3997 +           *u = '\0';
3998 +           v = u + 1;
3999 +       }
4000 +    }
4001 +    t = strrchr(v, ':');
4002 +    if (t){
4003 +       *t = '\0';
4004 +       strp = t + 1;
4005 +    }
4006 +    if (strp) {
4007 +       for (i=0; strp[i] != '\0'; i++)
4008              if (!ap_isdigit(strp[i]))
4009                  break;
4010  
4011 @@ -278,17 +291,29 @@
4012          return "Missing host in URL";
4013  /* check hostname syntax */
4014      for (i = 0; host[i] != '\0'; i++)
4015 -        if (!ap_isdigit(host[i]) && host[i] != '.')
4016 +        if (!ap_isdigit(host[i]) && host[i] != '.' && host[i] != ':')
4017              break;
4018      /* must be an IP address */
4019  #if defined(WIN32) || defined(NETWARE) || defined(TPF) || defined(BEOS)
4020      if (host[i] == '\0' && (inet_addr(host) == -1))
4021 +       return "Bad IP address in URL";
4022 +#else
4023 +    if (host[i] == '\0') {
4024 +       struct addrinfo hints, *res0;
4025 +       int gai;
4026 +       memset(&hints, 0, sizeof(hints));
4027 +       hints.ai_family = PF_UNSPEC;
4028 +       hints.ai_flags = AI_NUMERICHOST;
4029 +       if (gai = getaddrinfo(host, NULL, &hints, &res0)) {
4030 +#if 0
4031 +           return gai_strerror(gai);
4032  #else
4033 -    if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1))
4034 +           return "Bad IP address in URL";
4035  #endif
4036 -    {
4037 -        return "Bad IP address in URL";
4038 +       }
4039 +       freeaddrinfo(res0);
4040      }
4041 +#endif
4042  
4043  /*    if (strchr(host,'.') == NULL && domain != NULL)
4044     host = pstrcat(p, host, domain, NULL);
4045 @@ -1284,22 +1309,45 @@
4046      return host != NULL && strstr(host, This->name) != NULL;
4047  }
4048  
4049 -int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r)
4050 +int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r)
4051  {
4052      int i;
4053 +    int salen;
4054 +    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
4055 +#ifdef NI_WITHSCOPEID
4056 +    const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
4057 +#else
4058 +    const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
4059 +#endif
4060  
4061      ap_hard_timeout("proxy connect", r);
4062 +#ifdef HAVE_SOCKADDR_LEN
4063 +    salen = addr->sa_len;
4064 +#else
4065 +    switch (addr->sa_family) {
4066 +    case AF_INET6:
4067 +       salen = sizeof(struct sockaddr_in6);
4068 +       break;
4069 +    default:
4070 +       salen = sizeof(struct sockaddr_in);
4071 +       break;
4072 +    }
4073 +#endif
4074      do {
4075 -        i = connect(sock, (struct sockaddr *) addr, sizeof(struct sockaddr_in));
4076 +        i = connect(sock, addr, salen);
4077  #if defined(WIN32) || defined(NETWARE)
4078          if (i == SOCKET_ERROR)
4079              errno = WSAGetLastError();
4080  #endif /* WIN32 */
4081      } while (i == -1 && errno == EINTR);
4082      if (i == -1) {
4083 +       if (getnameinfo(addr, salen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
4084 +               niflags) != 0) {
4085 +           strcpy(hbuf, "?");
4086 +           strcpy(pbuf, "?");
4087 +       }
4088          ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
4089 -                     "proxy connect to %s port %d failed",
4090 -                     inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
4091 +                     "proxy connect to %s port %d failed", hbuf, pbuf);
4092      }
4093      ap_kill_timeout(r);
4094  
4095 diff -Nur apache_1.3.23.orig/src/modules/standard/mod_access.c apache_1.3.23/src/modules/standard/mod_access.c
4096 --- apache_1.3.23.orig/src/modules/standard/mod_access.c        Mon Jan 15 18:05:34 2001
4097 +++ apache_1.3.23/src/modules/standard/mod_access.c     Wed Feb  6 20:20:48 2002
4098 @@ -74,7 +74,10 @@
4099      T_ALL,
4100      T_IP,
4101      T_HOST,
4102 -    T_FAIL
4103 +    T_FAIL,
4104 +#ifdef INET6
4105 +    T_IP6,
4106 +#endif
4107  };
4108  
4109  typedef struct {
4110 @@ -82,9 +85,15 @@
4111      union {
4112         char *from;
4113         struct {
4114 -           unsigned long net;
4115 -           unsigned long mask;
4116 +           struct in_addr net;
4117 +           struct in_addr mask;
4118         } ip;
4119 +#ifdef INET6
4120 +       struct {
4121 +           struct in6_addr net6;
4122 +           struct in6_addr mask6;
4123 +       } ip6;
4124 +#endif
4125      } x;
4126      enum allowdeny_type type;
4127  } allowdeny;
4128 @@ -167,90 +176,230 @@
4129  
4130      }
4131      else if ((s = strchr(where, '/'))) {
4132 -       unsigned long mask;
4133 +       struct addrinfo hints, *resnet, *resmask;
4134 +       struct sockaddr_storage net, mask;
4135 +       int error;
4136 +       char *p;
4137 +       int justdigits;
4138  
4139 -       a->type = T_IP;
4140 +       a->type = T_FAIL;       /*just in case*/
4141         /* trample on where, we won't be using it any more */
4142         *s++ = '\0';
4143  
4144 -       if (!is_ip(where)
4145 -           || (a->x.ip.net = ap_inet_addr(where)) == INADDR_NONE) {
4146 +       justdigits = 0;
4147 +       for (p = s; *p; p++) {
4148 +           if (!isdigit(*p))
4149 +               break;
4150 +       }
4151 +       if (!*p)
4152 +           justdigits++;
4153 +
4154 +       memset(&hints, 0, sizeof(hints));
4155 +       hints.ai_family = PF_UNSPEC;
4156 +       hints.ai_socktype = SOCK_STREAM;        /*dummy*/
4157 +#ifdef AI_NUMERICHOST
4158 +       hints.ai_flags = AI_NUMERICHOST;        /*don't resolve*/
4159 +#endif
4160 +       resnet = NULL;
4161 +       error = getaddrinfo(where, NULL, &hints, &resnet);
4162 +       if (error || !resnet) {
4163 +           if (resnet)
4164 +               freeaddrinfo(resnet);
4165             a->type = T_FAIL;
4166             return "syntax error in network portion of network/netmask";
4167         }
4168 +       if (resnet->ai_next) {
4169 +           freeaddrinfo(resnet);
4170 +           a->type = T_FAIL;
4171 +           return "network/netmask resolved to multiple addresses";
4172 +       }
4173 +       memcpy(&net, resnet->ai_addr, resnet->ai_addrlen);
4174 +       freeaddrinfo(resnet);
4175  
4176 -       /* is_ip just tests if it matches [\d.]+ */
4177 -       if (!is_ip(s)) {
4178 +       switch (net.ss_family) {
4179 +       case AF_INET:
4180 +           a->type = T_IP;
4181 +           a->x.ip.net.s_addr = ((struct sockaddr_in *)&net)->sin_addr.s_addr;
4182 +           break;
4183 +#ifdef INET6
4184 +       case AF_INET6:
4185 +           a->type = T_IP6;
4186 +           memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&net)->sin6_addr,
4187 +               sizeof(a->x.ip6.net6));
4188 +           break;
4189 +#endif
4190 +       default:
4191             a->type = T_FAIL;
4192 -           return "syntax error in mask portion of network/netmask";
4193 +           return "unknown address family for network";
4194         }
4195 -       /* is it in /a.b.c.d form? */
4196 -       if (strchr(s, '.')) {
4197 -           mask = ap_inet_addr(s);
4198 -           if (mask == INADDR_NONE) {
4199 +
4200 +       if (!justdigits) {
4201 +           memset(&hints, 0, sizeof(hints));
4202 +           hints.ai_family = PF_UNSPEC;
4203 +           hints.ai_socktype = SOCK_STREAM;    /*dummy*/ 
4204 +#ifdef AI_NUMERICHOST
4205 +           hints.ai_flags = AI_NUMERICHOST;    /*don't resolve*/
4206 +#endif
4207 +           resmask = NULL;
4208 +           error = getaddrinfo(s, NULL, &hints, &resmask);
4209 +           if (error || !resmask) {
4210 +               if (resmask)
4211 +                   freeaddrinfo(resmask);
4212                 a->type = T_FAIL;
4213                 return "syntax error in mask portion of network/netmask";
4214             }
4215 -       }
4216 -       else {
4217 -           /* assume it's in /nnn form */
4218 -           mask = atoi(s);
4219 -           if (mask > 32 || mask <= 0) {
4220 -               a->type = T_FAIL;
4221 -               return "invalid mask in network/netmask";
4222 -           }
4223 -           mask = 0xFFFFFFFFUL << (32 - mask);
4224 -           mask = htonl(mask);
4225 -       }
4226 -       a->x.ip.mask = mask;
4227 -        a->x.ip.net  = (a->x.ip.net & mask);   /* pjr - This fixes PR 4770 */
4228 -    }
4229 -    else if (ap_isdigit(*where) && is_ip(where)) {
4230 -       /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
4231 -       int shift;
4232 -       char *t;
4233 -       int octet;
4234 -
4235 -       a->type = T_IP;
4236 -       /* parse components */
4237 -       s = where;
4238 -       a->x.ip.net = 0;
4239 -       a->x.ip.mask = 0;
4240 -       shift = 24;
4241 -       while (*s) {
4242 -           t = s;
4243 -           if (!ap_isdigit(*t)) {
4244 +           if (resmask->ai_next) {
4245 +               freeaddrinfo(resmask);
4246                 a->type = T_FAIL;
4247 -               return "invalid ip address";
4248 +               return "network/netmask resolved to multiple addresses";
4249             }
4250 -           while (ap_isdigit(*t)) {
4251 -               ++t;
4252 -           }
4253 -           if (*t == '.') {
4254 -               *t++ = 0;
4255 -           }
4256 -           else if (*t) {
4257 +           memcpy(&mask, resmask->ai_addr, resmask->ai_addrlen);
4258 +           freeaddrinfo(resmask);
4259 +
4260 +           if (net.ss_family != mask.ss_family) {
4261                 a->type = T_FAIL;
4262 -               return "invalid ip address";
4263 +               return "network/netmask resolved to different address family";
4264             }
4265 -           if (shift < 0) {
4266 -               return "invalid ip address, only 4 octets allowed";
4267 +
4268 +           switch (a->type) {
4269 +           case T_IP:
4270 +               a->x.ip.mask.s_addr =
4271 +                   ((struct sockaddr_in *)&mask)->sin_addr.s_addr;
4272 +               break;
4273 +#ifdef INET6
4274 +           case T_IP6:
4275 +               memcpy(&a->x.ip6.mask6,
4276 +                   &((struct sockaddr_in6 *)&mask)->sin6_addr,
4277 +                   sizeof(a->x.ip6.mask6));
4278 +               break;
4279 +#endif
4280             }
4281 -           octet = atoi(s);
4282 -           if (octet < 0 || octet > 255) {
4283 -               a->type = T_FAIL;
4284 -               return "each octet must be between 0 and 255 inclusive";
4285 +       } else {
4286 +           int mask;
4287 +           mask = atoi(s);
4288 +           switch (a->type) {
4289 +           case T_IP:
4290 +               if (mask < 0 || 32 < mask) {
4291 +                   a->type = T_FAIL;
4292 +                   return "netmask out of range";
4293 +               }
4294 +               a->x.ip.mask.s_addr = htonl(0xFFFFFFFFUL << (32 - mask));
4295 +               break;
4296 +#ifdef INET6
4297 +           case T_IP6:
4298 +             {
4299 +               int i;
4300 +               if (mask < 0 || 128 < mask) {
4301 +                   a->type = T_FAIL;
4302 +                   return "netmask out of range";
4303 +               }
4304 +               for (i = 0; i < mask / 8; i++) {
4305 +                   a->x.ip6.mask6.s6_addr[i] = 0xff;
4306 +               }
4307 +               if (mask % 8)
4308 +                   a->x.ip6.mask6.s6_addr[i] = 0xff << (8 - (mask % 8));
4309 +               break;
4310 +             }
4311 +#endif
4312             }
4313 -           a->x.ip.net |= octet << shift;
4314 -           a->x.ip.mask |= 0xFFUL << shift;
4315 -           s = t;
4316 -           shift -= 8;
4317         }
4318 -       a->x.ip.net = ntohl(a->x.ip.net);
4319 -       a->x.ip.mask = ntohl(a->x.ip.mask);
4320      }
4321      else {
4322 -       a->type = T_HOST;
4323 +       struct addrinfo hints, *res;
4324 +       struct sockaddr_storage ss;
4325 +       int error;
4326 +
4327 +       a->type = T_FAIL;       /*just in case*/
4328 +
4329 +       /* First, try using the old apache code to match */
4330 +       /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
4331 +       if (ap_isdigit(*where) && is_ip(where)) {
4332 +           int shift;
4333 +           char *t;
4334 +           int octet;
4335 +
4336 +           a->type = T_IP;
4337 +           /* parse components */
4338 +           s = where;
4339 +           a->x.ip.net.s_addr = 0;
4340 +           a->x.ip.mask.s_addr = 0;
4341 +           shift = 24;
4342 +           while (*s) {
4343 +               t = s;
4344 +               if (!ap_isdigit(*t)) {
4345 +                   a->type = T_FAIL;
4346 +                   return "invalid ip address";
4347 +               }
4348 +               while (ap_isdigit(*t)) {
4349 +                   ++t;
4350 +               }
4351 +               if (*t == '.') {
4352 +                   *t++ = 0;
4353 +               }
4354 +               else if (*t) {
4355 +                   a->type = T_FAIL;
4356 +                   return "invalid ip address";
4357 +               }
4358 +               if (shift < 0) {
4359 +                   return "invalid ip address, only 4 octets allowed";
4360 +               }
4361 +               octet = atoi(s);
4362 +               if (octet < 0 || octet > 255) {
4363 +                   a->type = T_FAIL;
4364 +                   return "each octet must be between 0 and 255 inclusive";
4365 +               }
4366 +               a->x.ip.net.s_addr |= octet << shift;
4367 +               a->x.ip.mask.s_addr |= 0xFFUL << shift;
4368 +               s = t;
4369 +               shift -= 8;
4370 +           }
4371 +           a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
4372 +           a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
4373 +
4374 +           return NULL;
4375 +       }
4376 +
4377 +       /* IPv4/v6 numeric address */
4378 +       memset(&hints, 0, sizeof(hints));
4379 +       hints.ai_family = PF_UNSPEC;
4380 +       hints.ai_socktype = SOCK_STREAM;        /*dummy*/
4381 +#ifdef AI_NUMERICHOST
4382 +       hints.ai_flags = AI_NUMERICHOST;        /*don't resolve*/
4383 +#endif
4384 +       res = NULL;
4385 +       error = getaddrinfo(where, NULL, &hints, &res);
4386 +       if (error || !res) {
4387 +           if (res)
4388 +               freeaddrinfo(res);
4389 +           a->type = T_HOST;
4390 +           return NULL;
4391 +       }
4392 +       if (res->ai_next) {
4393 +           freeaddrinfo(res);
4394 +           a->type = T_FAIL;
4395 +           return "network/netmask resolved to multiple addresses";
4396 +       }
4397 +       memcpy(&ss, res->ai_addr, res->ai_addrlen);
4398 +       freeaddrinfo(res);
4399 +
4400 +       switch (ss.ss_family) {
4401 +       case AF_INET:
4402 +           a->type = T_IP;
4403 +           a->x.ip.net.s_addr = ((struct sockaddr_in *)&ss)->sin_addr.s_addr;
4404 +           memset(&a->x.ip.mask, 0xff, sizeof(a->x.ip.mask));
4405 +           break;
4406 +#ifdef INET6
4407 +       case AF_INET6:
4408 +           a->type = T_IP6;
4409 +           memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&ss)->sin6_addr,
4410 +               sizeof(a->x.ip6.net6));
4411 +           memset(&a->x.ip6.mask6, 0xff, sizeof(a->x.ip6.mask6));
4412 +           break;
4413 +#endif
4414 +       default:
4415 +           a->type = T_FAIL;
4416 +           return "unknown address family for network";
4417 +       }
4418      }
4419  
4420      return NULL;
4421 @@ -315,12 +464,63 @@
4422             return 1;
4423  
4424         case T_IP:
4425 -           if (ap[i].x.ip.net != INADDR_NONE
4426 -               && (r->connection->remote_addr.sin_addr.s_addr
4427 -                   & ap[i].x.ip.mask) == ap[i].x.ip.net) {
4428 -               return 1;
4429 +           if (ap[i].x.ip.net.s_addr == INADDR_NONE)
4430 +               break;
4431 +           switch (r->connection->remote_addr.ss_family) {
4432 +           case AF_INET:
4433 +               if ((((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr
4434 +                       & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
4435 +                   return 1;
4436 +               }
4437 +               break;
4438 +#ifdef INET6
4439 +           case AF_INET6:
4440 +               if (!IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr))    /*XXX*/
4441 +                   break;
4442 +               if ((*(ap_uint32_t *)&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr.s6_addr[12]
4443 +                       & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
4444 +                   return 1;
4445 +               }
4446 +               break;
4447 +#endif
4448 +           }
4449 +           break;
4450 +
4451 +#ifdef INET6
4452 +       case T_IP6:
4453 +         {
4454 +           struct in6_addr masked;
4455 +           int j;
4456 +           if (IN6_IS_ADDR_UNSPECIFIED(&ap[i].x.ip6.net6))
4457 +               break;
4458 +           switch (r->connection->remote_addr.ss_family) {
4459 +           case AF_INET:
4460 +               if (!IN6_IS_ADDR_V4MAPPED(&ap[i].x.ip6.net6))   /*XXX*/
4461 +                   break;
4462 +               memset(&masked, 0, sizeof(masked));
4463 +               masked.s6_addr[10] = masked.s6_addr[11] = 0xff;
4464 +               memcpy(&masked.s6_addr[12],
4465 +                   &((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr,
4466 +                   sizeof(struct sockaddr_in));
4467 +               for (j = 0; j < sizeof(struct in6_addr); j++)
4468 +                       masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
4469 +               if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
4470 +                   return 1;
4471 +               break;
4472 +           case AF_INET6:
4473 +               memset(&masked, 0, sizeof(masked));
4474 +               memcpy(&masked,
4475 +                   &((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr,
4476 +                   sizeof(masked));
4477 +               for (j = 0; j < sizeof(struct in6_addr); j++)
4478 +                   masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
4479 +               if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
4480 +                   return 1;
4481 +               break;
4482             }
4483             break;
4484 +         }
4485 +#endif
4486  
4487         case T_HOST:
4488             if (!gothost) {
4489 diff -Nur apache_1.3.23.orig/src/modules/standard/mod_unique_id.c apache_1.3.23/src/modules/standard/mod_unique_id.c
4490 --- apache_1.3.23.orig/src/modules/standard/mod_unique_id.c     Tue Oct  2 18:11:13 2001
4491 +++ apache_1.3.23/src/modules/standard/mod_unique_id.c  Wed Feb  6 20:20:48 2002
4492 @@ -67,10 +67,22 @@
4493  #include "http_config.h"
4494  #include "http_log.h"
4495  #include "multithread.h"
4496 +#include "sa_len.h"
4497 +
4498 +/*#define SHORT_UNIQUE_ID*/
4499  
4500  typedef struct {
4501      unsigned int stamp;
4502 -    unsigned int in_addr;
4503 +    union {
4504 +       struct in_addr in;
4505 +#ifdef INET6
4506 +# ifdef SHORT_UNIQUE_ID
4507 +       ap_uint32_t in6;
4508 +# else
4509 +       struct in6_addr in6;
4510 +# endif
4511 +#endif
4512 +    } addr;
4513      unsigned int pid;
4514  #ifdef MULTITHREAD
4515      unsigned int tid;
4516 @@ -142,7 +154,7 @@
4517   * this shouldn't be a problem till year 2106.
4518   */
4519  
4520 -static unsigned global_in_addr;
4521 +static struct sockaddr_storage global_addr;
4522  
4523  #ifdef WIN32
4524  
4525 @@ -221,7 +233,8 @@
4526  #define MAXHOSTNAMELEN 256
4527  #endif
4528      char str[MAXHOSTNAMELEN + 1];
4529 -    struct hostent *hent;
4530 +    struct addrinfo hints, *res, *res0;
4531 +    int error;
4532  #ifndef NO_GETTIMEOFDAY
4533      struct timeval tv;
4534  #endif
4535 @@ -232,8 +245,8 @@
4536       */
4537      unique_id_rec_offset[0] = XtOffsetOf(unique_id_rec, stamp);
4538      unique_id_rec_size[0] = sizeof(cur_unique_id->stamp);
4539 -    unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, in_addr);
4540 -    unique_id_rec_size[1] = sizeof(cur_unique_id->in_addr);
4541 +    unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, addr);
4542 +    unique_id_rec_size[1] = sizeof(cur_unique_id->addr);
4543      unique_id_rec_offset[2] = XtOffsetOf(unique_id_rec, pid);
4544      unique_id_rec_size[2] = sizeof(cur_unique_id->pid);
4545  #ifdef MULTITHREAD
4546 @@ -269,17 +282,44 @@
4547      }
4548      str[sizeof(str) - 1] = '\0';
4549  
4550 -    if ((hent = gethostbyname(str)) == NULL) {
4551 +    memset(&hints, 0, sizeof(hints));
4552 +    hints.ai_family = PF_UNSPEC;
4553 +    error = getaddrinfo(str, NULL, &hints, &res0);
4554 +    if (error) {
4555          ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
4556 -                    "mod_unique_id: unable to gethostbyname(\"%s\")", str);
4557 +                     "mod_unique_id: getaddrinfo failed for \"%s\" (%s)", str,
4558 +                    gai_strerror(error));
4559          exit(1);
4560      }
4561  
4562 -    global_in_addr = ((struct in_addr *) hent->h_addr_list[0])->s_addr;
4563 +    error = 1;
4564 +    for (res = res0; res; res = res->ai_next) {
4565 +       switch (res->ai_family) {
4566 +       case AF_INET:
4567 +#ifdef INET6
4568 +       case AF_INET6:
4569 +#endif
4570 +           memcpy(&global_addr, res->ai_addr, res->ai_addrlen);
4571 +           error = 0;
4572 +           break;
4573 +       }
4574 +    }
4575 +    freeaddrinfo(res0);
4576 +    if (error) {
4577 +        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
4578 +                    "mod_unique_id: no known AF found for \"%s\"", str);
4579 +        exit(1);
4580 +    }
4581  
4582 +    getnameinfo((struct sockaddr *)&global_addr,
4583 +#ifndef SIN6_LEN
4584 +       SA_LEN((struct sockaddr *)&global_addr),
4585 +#else
4586 +       global_addr.ss_len,
4587 +#endif
4588 +       str, sizeof(str), NULL, 0, NI_NUMERICHOST);
4589      ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, s,
4590 -                "mod_unique_id: using ip addr %s",
4591 -                inet_ntoa(*(struct in_addr *) hent->h_addr_list[0]));
4592 +                 "mod_unique_id: using ip addr %s", str);
4593  
4594      /*
4595       * If the server is pummelled with restart requests we could possibly end
4596 @@ -336,7 +376,23 @@
4597                      "oh no! pids are greater than 32-bits!  I'm broken!");
4598      }
4599  
4600 -    cur_unique_id->in_addr = global_in_addr;
4601 +    memset(&cur_unique_id->addr, 0, sizeof(cur_unique_id->addr));
4602 +    switch (global_addr.ss_family) {
4603 +    case AF_INET:
4604 +       cur_unique_id->addr.in = ((struct sockaddr_in *)&global_addr)->sin_addr;
4605 +       break;
4606 +#ifdef INET6
4607 +    case AF_INET6:
4608 +#ifdef SHORT_UNIQUE_ID
4609 +       cur_unique_id->addr.in6 =
4610 +           ((struct sockaddr_in6 *)&global_addr)->sin6_addr.s6_addr32[3];
4611 +#else
4612 +       cur_unique_id->addr.in6 =
4613 +           ((struct sockaddr_in6 *)&global_addr)->sin6_addr;
4614 +#endif
4615 +       break;
4616 +#endif
4617 +    }
4618  
4619      /*
4620       * If we use 0 as the initial counter we have a little less protection
4621 diff -Nur apache_1.3.23.orig/src/support/ab.c apache_1.3.23/src/support/ab.c
4622 --- apache_1.3.23.orig/src/support/ab.c Mon Oct  8 19:54:42 2001
4623 +++ apache_1.3.23/src/support/ab.c      Wed Feb  6 20:20:48 2002
4624 @@ -158,6 +158,8 @@
4625  #include <sys/uio.h>
4626  #endif
4627  
4628 +#include "sa_len.h"
4629 +
4630  #endif                         /* NO_APACHE_INCLUDES */
4631  
4632  #ifdef USE_SSL
4633 @@ -246,7 +248,7 @@
4634  char servername[1024];         /* name that server reports */
4635  char hostname[1024];           /* host name */
4636  char proxyhost[1024];          /* proxy host name */
4637 -int proxyport = 0;             /* proxy port */
4638 +char *proxyport = NULL;                /* proxy port */
4639  int isproxy = 0;
4640  char path[1024];               /* path name */
4641  char postfile[1024];           /* name of file containing post data */
4642 @@ -261,7 +263,7 @@
4643       auth[1024],               /* optional (basic/uuencoded)
4644                                  * authentification */
4645       hdrs[4096];               /* optional arbitrary headers */
4646 -int port = 80;                 /* port number */
4647 +char *port = "80";             /* port number */
4648  
4649  int use_html = 0;              /* use html in the report */
4650  char *tablestring;
4651 @@ -298,7 +300,7 @@
4652  struct data *stats;            /* date for each request */
4653  
4654  fd_set readbits, writebits;    /* bits for select */
4655 -struct sockaddr_in server;     /* server addr structure */
4656 +struct sockaddr_storage server;      /* server addr structure */
4657  
4658  #ifndef BEOS
4659  #define ab_close(s) close(s)
4660 @@ -509,7 +511,7 @@
4661      printf("\r                                                                           \r");
4662      printf("Server Software:        %s\n", servername);
4663      printf("Server Hostname:        %s\n", hostname);
4664 -    printf("Server Port:            %d\n", port);
4665 +    printf("Server Port:            %s\n", port);
4666      printf("\n");
4667      printf("Document Path:          %s\n", path);
4668      printf("Document Length:        %d bytes\n", doclen);
4669 @@ -862,7 +864,7 @@
4670      c->cbx = 0;
4671      c->gotheader = 0;
4672  
4673 -    c->fd = socket(AF_INET, SOCK_STREAM, 0);
4674 +    c->fd = socket(server.ss_family, SOCK_STREAM, 0);
4675      if (c->fd < 0) {
4676         what = "SOCKET";
4677         goto bad;
4678 @@ -879,7 +881,12 @@
4679  
4680  again:
4681      gettimeofday(&c->start, 0);
4682 -    if (connect(c->fd, (struct sockaddr *) & server, sizeof(server)) < 0) {
4683 +#ifndef SIN6_LEN
4684 +    if (connect(c->fd, (struct sockaddr *) & server, SA_LEN((struct sockaddr*)&server)) < 0)
4685 +#else
4686 +    if (connect(c->fd, (struct sockaddr *) & server, server.ss_len) < 0)
4687 +#endif
4688 +    {
4689         if (errno == EINPROGRESS) {
4690             c->state = STATE_CONNECTING;
4691         }
4692 @@ -1171,7 +1178,7 @@
4693      struct timeval timeout, now;
4694      fd_set sel_read, sel_except, sel_write;
4695      long i;
4696 -    int connectport;
4697 +    char * connectport;
4698      char * url_on_request, * host;
4699  
4700      /* There are four hostname's involved:
4701 @@ -1209,16 +1216,21 @@
4702      }
4703      {
4704         /* get server information */
4705 -       struct hostent *he;
4706 -       he = gethostbyname(host);
4707 -       if (!he) {
4708 -           char theerror[1024];
4709 -           sprintf(theerror, "Bad hostname: %s\n", host);
4710 -           err(theerror);
4711 -       }
4712 -       server.sin_family = he->h_addrtype;
4713 -       server.sin_port = htons(connectport);
4714 -       server.sin_addr.s_addr = ((unsigned long *) (he->h_addr_list[0]))[0];
4715 +        struct addrinfo hints, *res;
4716 +       int error;
4717 +
4718 +       memset(&hints, 0, sizeof(hints));
4719 +       hints.ai_family = PF_UNSPEC;
4720 +       hints.ai_socktype = SOCK_STREAM;
4721 +       error = getaddrinfo(host, connectport, &hints, &res);
4722 +       if (error) {
4723 +               char *theerror=malloc(strlen(host)+16);
4724 +               sprintf(theerror, "Bad hostname: %s\n", host);
4725 +               err(theerror);
4726 +               free(theerror);
4727 +       }
4728 +       memcpy(&server, res->ai_addr, res->ai_addrlen);
4729 +       freeaddrinfo(res);
4730      }
4731  
4732      con = malloc(concurrency * sizeof(struct connection));
4733 @@ -1404,7 +1416,7 @@
4734      if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
4735         purl += 8;
4736         ssl = 1;
4737 -       port = 443;
4738 +       port = "443";
4739      }
4740  #else
4741      if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
4742 @@ -1425,7 +1437,7 @@
4743      *cp = '\0';
4744      strcpy(hostname, h);
4745      if (p != NULL)
4746 -       port = atoi(p);
4747 +        port = strdup(p);
4748      return 0;
4749  }
4750  
4751 @@ -1585,7 +1597,7 @@
4752                 if ((p = strchr(optarg, ':'))) {
4753                     *p = '\0';
4754                     p++;
4755 -                   proxyport = atoi(p);
4756 +                   proxyport = strdup(p);
4757                 };
4758                 strcpy(proxyhost, optarg);
4759                 isproxy = 1;
4760 @@ -1668,3 +1680,7 @@
4761  
4762      exit(0);
4763  }
4764 +
4765 +#ifdef NEED_GETADDRINFO
4766 +#include "../main/getaddrinfo.c"
4767 +#endif
4768 diff -Nur apache_1.3.23.orig/src/support/logresolve.c apache_1.3.23/src/support/logresolve.c
4769 --- apache_1.3.23.orig/src/support/logresolve.c Wed May 23 00:52:21 2001
4770 +++ apache_1.3.23/src/support/logresolve.c      Wed Feb  6 20:20:48 2002
4771 @@ -54,7 +54,9 @@
4772  #endif /* BEOS */
4773  #endif /* !MPE && !WIN32*/
4774  
4775 -static void cgethost(struct in_addr ipnum, char *string, int check);
4776 +#include "sa_len.h"
4777 +
4778 +static void cgethost(struct sockaddr *sa, char *string, int check);
4779  static int getline(char *s, int n);
4780  static void stats(FILE *output);
4781  
4782 @@ -91,7 +93,7 @@
4783   */
4784  
4785  struct nsrec {
4786 -    struct in_addr ipnum;
4787 +    struct sockaddr_storage addr;
4788      char *hostname;
4789      int noname;
4790      struct nsrec *next;
4791 @@ -122,17 +124,48 @@
4792   * IP numbers with their IP number as hostname, setting noname flag
4793   */
4794  
4795 -static void cgethost (struct in_addr ipnum, char *string, int check)
4796 +static void cgethost (struct sockaddr *sa, char *string, int check)
4797  {
4798 +    ap_uint32_t hashval;
4799 +    struct sockaddr_in *sin;
4800 +#ifdef INET6
4801 +    struct sockaddr_in6 *sin6;
4802 +#endif
4803      struct nsrec **current, *new;
4804 -    struct hostent *hostdata;
4805      char *name;
4806 +    char hostnamebuf[MAXHOSTNAMELEN];
4807 +
4808 +    switch (sa->sa_family) {
4809 +    case AF_INET:
4810 +       hashval = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
4811 +       break;
4812 +#ifdef INET6
4813 +    case AF_INET6:
4814 +       hashval = *(ap_uint32_t *)&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12];
4815 +       break;
4816 +#endif
4817 +    default:
4818 +       hashval = 0;
4819 +       break;
4820 +    }
4821 +
4822 +    current = &nscache[((hashval + (hashval >> 8) +
4823 +                        (hashval >> 16) + (hashval >> 24)) % BUCKETS)];
4824  
4825 -    current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) +
4826 -                        (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)];
4827 +    while (*current) {
4828 +#ifndef SIN6_LEN
4829 +       if (SA_LEN(sa) == SA_LEN((struct sockaddr *)&(*current)->addr)
4830 +        && memcmp(sa, &(*current)->addr, SA_LEN(sa)) == 0)
4831 +#else
4832 +       if (sa->sa_len == (*current)->addr.ss_len
4833 +        && memcmp(sa, &(*current)->addr, sa->sa_len) == 0)
4834 +#endif
4835 +       {
4836 +           break;
4837 +       }
4838  
4839 -    while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr)
4840         current = &(*current)->next;
4841 +    }
4842  
4843      if (*current == NULL) {
4844         cachesize++;
4845 @@ -145,45 +178,55 @@
4846         *current = new;
4847         new->next = NULL;
4848  
4849 -       new->ipnum = ipnum;
4850 +#ifndef SIN6_LEN
4851 +       memcpy(&new->addr, sa, SA_LEN(sa));
4852 +#else
4853 +       memcpy(&new->addr, sa, sa->sa_len);
4854 +#endif
4855  
4856 -       hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr),
4857 -                                AF_INET);
4858 -       if (hostdata == NULL) {
4859 -           if (h_errno > MAX_ERR)
4860 -               errors[UNKNOWN_ERR]++;
4861 -           else
4862 -               errors[h_errno]++;
4863 -           new->noname = h_errno;
4864 -           name = strdup(inet_ntoa(ipnum));
4865 -       }
4866 -       else {
4867 -           new->noname = 0;
4868 -           name = strdup(hostdata->h_name);
4869 -           if (check) {
4870 -               if (name == NULL) {
4871 -                   perror("strdup");
4872 -                   fprintf(stderr, "Insufficient memory\n");
4873 -                   exit(1);
4874 -               }
4875 -               hostdata = gethostbyname(name);
4876 -               if (hostdata != NULL) {
4877 -                   char **hptr;
4878 -
4879 -                   for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++)
4880 -                       if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr)
4881 -                           break;
4882 -                   if (*hptr == NULL)
4883 -                       hostdata = NULL;
4884 -               }
4885 -               if (hostdata == NULL) {
4886 -                   fprintf(stderr, "Bad host: %s != %s\n", name,
4887 -                           inet_ntoa(ipnum));
4888 -                   new->noname = NO_REVERSE;
4889 -                   free(name);
4890 -                   name = strdup(inet_ntoa(ipnum));
4891 -                   errors[NO_REVERSE]++;
4892 +       new->noname = getnameinfo(sa,
4893 +#ifndef SIN6_LEN
4894 +               SA_LEN(sa),
4895 +#else
4896 +               sa->sa_len,
4897 +#endif
4898 +                   hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0);
4899 +       name = strdup(hostnamebuf);
4900 +       if (check) {
4901 +           struct addrinfo hints, *res;
4902 +           int error;
4903 +           memset(&hints, 0, sizeof(hints));
4904 +           hints.ai_family = PF_UNSPEC;
4905 +           error = getaddrinfo(hostnamebuf, NULL, &hints, &res);
4906 +           if (!error) {
4907 +               while (res) {
4908 +#ifndef SIN6_LEN
4909 +                   if (SA_LEN(sa) == res->ai_addrlen
4910 +                    && memcmp(sa, res->ai_addr, SA_LEN(sa)) == 0)
4911 +#else
4912 +                   if (sa->sa_len == res->ai_addrlen
4913 +                    && memcmp(sa, res->ai_addr, sa->sa_len) == 0)
4914 +#endif
4915 +                   {
4916 +                       break;
4917 +                   }
4918 +                   res = res->ai_next;
4919                 }
4920 +               if (!res)
4921 +                   error++;
4922 +           }
4923 +           if (error) {
4924 +               getnameinfo(sa,
4925 +#ifndef SIN6_LEN
4926 +                   SA_LEN(sa),
4927 +#else
4928 +                   sa->sa_len,
4929 +#endif
4930 +                   hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
4931 +               fprintf(stderr, "Bad host: %s != %s\n", name, hostnamebuf);
4932 +               new->noname = NO_REVERSE;
4933 +               free(name);
4934 +               name = strdup(hostnamebuf);
4935             }
4936         }
4937         new->hostname = name;
4938 @@ -211,6 +254,7 @@
4939      char *ipstring;
4940      struct nsrec *current;
4941      char *errstring[MAX_ERR + 3];
4942 +    char hostnamebuf[MAXHOSTNAMELEN];
4943  
4944      for (i = 0; i < MAX_ERR + 3; i++)
4945         errstring[i] = "Unknown error";
4946 @@ -242,7 +286,14 @@
4947  
4948      for (i = 0; i < BUCKETS; i++)
4949         for (current = nscache[i]; current != NULL; current = current->next) {
4950 -           ipstring = inet_ntoa(current->ipnum);
4951 +           getnameinfo((struct sockaddr *)&current->addr,
4952 +#ifndef SIN6_LEN
4953 +                   SA_LEN((struct sockaddr *)&current->addr),
4954 +#else
4955 +                   current->addr.ss_len,
4956 +#endif
4957 +                   hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
4958 +           ipstring = hostnamebuf;
4959             if (current->noname == 0)
4960                 fprintf(output, "  %3d  %15s - %s\n", i, ipstring,
4961                         current->hostname);
4962 @@ -276,9 +327,10 @@
4963  
4964  int main (int argc, char *argv[])
4965  {
4966 -    struct in_addr ipnum;
4967      char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
4968      int i, check;
4969 +    struct addrinfo hints, *res;
4970 +    int error;
4971  
4972  #ifdef WIN32
4973      WSADATA wsaData;
4974 @@ -322,8 +374,10 @@
4975         bar = strchr(line, ' ');
4976         if (bar != NULL)
4977             *bar = '\0';
4978 -       ipnum.s_addr = inet_addr(line);
4979 -       if (ipnum.s_addr == 0xffffffffu) {
4980 +       memset(&hints, 0, sizeof(hints));
4981 +       hints.ai_family = PF_UNSPEC;
4982 +       error = getaddrinfo(line, NULL, &hints, &res);
4983 +       if (error) {
4984             if (bar != NULL)
4985                 *bar = ' ';
4986             puts(line);
4987 @@ -333,11 +387,12 @@
4988  
4989         resolves++;
4990  
4991 -       cgethost(ipnum, hoststring, check);
4992 +       cgethost(res->ai_addr, hoststring, check);
4993         if (bar != NULL)
4994             printf("%s %s\n", hoststring, bar + 1);
4995         else
4996             puts(hoststring);
4997 +       freeaddrinfo(res);
4998      }
4999  
5000  #ifdef WIN32
5001 @@ -358,3 +413,11 @@
5002  
5003      return (0);
5004  }
5005 +
5006 +#ifdef NEED_GETADDRINFO
5007 +#include "../main/getaddrinfo.c"
5008 +#endif
5009 +
5010 +#ifdef NEED_GETNAMEINFO
5011 +#include "../main/getnameinfo.c"
5012 +#endif
This page took 3.278654 seconds and 3 git commands to generate.