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