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