1 diff -Nur apache_1.3.23.orig/README.v6 apache_1.3.23/README.v6
2 --- apache_1.3.23.orig/README.v6 Thu Jan 1 01:00:00 1970
3 +++ apache_1.3.23/README.v6 Wed Feb 6 20:20:48 2002
5 +IPv6-ready apache 1.3.x
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.
13 +Basically you can write IPv6 address where IPv4 address fits.
15 +extra command-line argument:
16 + -4 Assume IPv4 address on ambiguous directives
17 + -6 Assume IPv6 address on ambiguous directives (default)
19 + The above two can be used, for example, to disambiguate
24 + Listen is expanded to take one or two arguments.
28 + This is to let you specify "Listen :: 80", since "Listen :::80"
34 + "deny from" and "allow from" supports IPv6 addresses, under the
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.
43 + http/ftp proxying for both IPv4 and IPv6 is possible.
44 + Access control functions (NoProxy) are not updated yet.
46 + NOTE: for security reasons, we recommend you to filter out
47 + outsider's access to your proxy, by directives like below:
51 + allow from 10.0.0.0/8
52 + allow from 3ffe:9999:8888:7777::/64
56 + If you would like to this feature, you must describe 'Listen'
57 + part on configuration file explicitly. like below:
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.
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.
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>
89 +logresolve (src/support)
90 + error statistics in nameserver cache code is omitted.
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.
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
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.
115 + The behavior should be improved in the near future; we welcome your
118 +Modules known to be incompatible with IPv6
122 + Configure has extra option, --enable-rule=INET6. if the option
123 + is specified, IPv6 code will be enabled.
126 + We do not support IPv4 mapped address (IPv6 address format like
127 + ::ffff:10.1.1.1) in configuration file.
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.
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"
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.
155 + Thanks to all people submitted patches/fixes for this patch kit,
157 + "Chris P. Ross" <cross@eng.us.uu.net>
160 + Jun-ichiro itojun Hagino, KAME project
161 + http://www.kame.net/
162 + mailto:core@kame.net
164 + Arkadiusz Miskiewicz, Polish Linux Distribution project (IPv6)
165 + http://www.pld.org.pl/
166 + mailto:feedback@pld.org.pl
167 + Satoshi SHIDA, Linux IPv6 Users Group JP
168 + http://www.v6.linux.or.jp/
169 + YOSHIFUJI Hideaki, USAGI Project
170 + http://www.linux-ipv6.org/
171 diff -Nur apache_1.3.23.orig/conf/httpd.conf-dist apache_1.3.23/conf/httpd.conf-dist
172 --- apache_1.3.23.orig/conf/httpd.conf-dist Wed Jan 9 17:05:31 2002
173 +++ apache_1.3.23/conf/httpd.conf-dist Wed Feb 6 20:20:48 2002
176 #Listen 12.34.56.78:80
178 +# Listen can take two arguments.
179 +# (this is an extension for supporting IPv6 addresses)
184 # BindAddress: You can support virtual hosts with this option. This directive
185 # is used to tell the server which IP address to listen to. It can either
186 diff -Nur apache_1.3.23.orig/configure.v6 apache_1.3.23/configure.v6
187 --- apache_1.3.23.orig/configure.v6 Thu Jan 1 01:00:00 1970
188 +++ apache_1.3.23/configure.v6 Wed Feb 6 20:20:48 2002
192 +./configure --enable-rule=INET6 --enable-module=proxy $*
193 diff -Nur apache_1.3.23.orig/src/Configuration.tmpl apache_1.3.23/src/Configuration.tmpl
194 --- apache_1.3.23.orig/src/Configuration.tmpl Wed Feb 6 20:17:43 2002
195 +++ apache_1.3.23/src/Configuration.tmpl Wed Feb 6 20:21:56 2002
197 # Rule EXPAT=default : If Expat can be found at the system or
198 # in lib/expat-lite, use it; otherwise
205 # Use Win32 API system calls for socket communication instead
211 Rule CYGWIN_WINSOCK=no
214 diff -Nur apache_1.3.23.orig/src/Configure apache_1.3.23/src/Configure
215 --- apache_1.3.23.orig/src/Configure Wed Feb 6 20:17:43 2002
216 +++ apache_1.3.23/src/Configure Wed Feb 6 20:20:48 2002
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`
223 ####################################################################
224 ## Rule SHARED_CORE implies required DSO support
225 @@ -1698,6 +1699,124 @@
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
238 + if [ -f /usr/include/netinet6/in6.h -a "x`egrep '__KAME__' /usr/include/netinet6/in6.h 2>/dev/null`" != "x" ]; then
243 + if [ /usr/include/netinet/ip6.h -a -d /usr/include/linux ]; then
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})"
258 + if [ "$IPV6_STACKTYPE" != "UNKNOWN" ]; then
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"
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"
276 + echo "** WARNING: No getaddrinfo found, linkage may fail"
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."
289 + LIBS="$LIBS -lresolv"
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"
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
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"
308 + echo " + you don't have sa_len in struct sockaddr."
310 +rm -f testfunc.c testfunc.o
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
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"
320 + CFLAGS="$CFLAGS -DNEED_SOCKADDR_STORAGE"
321 + echo " + you need struct sockaddr_storage"
323 +rm -f testfunc.c testfunc.o
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
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"
333 +rm -f testfunc.c testfunc.o
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
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"
344 +rm -f testfunc.c testfunc.o
347 ####################################################################
348 ## Find out what modules we want and try and configure things for them
349 ## Module lines can look like this:
350 @@ -2293,6 +2412,38 @@
351 echo "#define AP_LONGEST_LONG $AP_LONGEST_LONG" >>$AP_CONFIG_AUTO_H
352 echo "#endif" >>$AP_CONFIG_AUTO_H
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"
383 + echo " - Warning: cannot determine what type should we use as 32bit unsigned int"
386 ####################################################################
387 ## More building ap_config_auto.h
389 diff -Nur apache_1.3.23.orig/src/ap/ap_snprintf.c apache_1.3.23/src/ap/ap_snprintf.c
390 --- apache_1.3.23.orig/src/ap/ap_snprintf.c Mon Jan 21 22:56:43 2002
391 +++ apache_1.3.23/src/ap/ap_snprintf.c Wed Feb 6 20:20:48 2002
405 +static char *conv_sockaddr(struct sockaddr *sa, char *buf_end, int *len)
408 + char hostnamebuf[MAXHOSTNAMELEN];
409 + char portnamebuf[MAXHOSTNAMELEN];
414 + salen = SA_LEN(sa);
416 + salen = sa->sa_len;
418 + if (getnameinfo(sa, salen, hostnamebuf, sizeof(hostnamebuf),
419 + portnamebuf, sizeof(portnamebuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
420 + strcpy(hostnamebuf, "???");
421 + strcpy(portnamebuf, "???");
423 + if (strcmp(portnamebuf,"0") == 0)
424 + strcpy(portnamebuf, "*");
425 + q = portnamebuf + strlen(portnamebuf);
426 + while (portnamebuf < q)
429 + q = hostnamebuf + strlen(hostnamebuf);
430 + while (hostnamebuf < q)
433 + *len = buf_end - p;
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 */
448 struct sockaddr_in *si;
450 si = va_arg(ap, struct sockaddr_in *);
451 @@ -1063,6 +1101,16 @@
452 if (adjust_precision && precision < s_len)
456 + struct sockaddr *sa;
458 + sa = va_arg(ap, struct sockaddr *);
460 + s = conv_sockaddr(sa, &num_buf[NUM_BUF_SIZE], &s_len);
461 + if (adjust_precision && precision < s_len)
468 diff -Nur apache_1.3.23.orig/src/include/ap.h apache_1.3.23/src/include/ap.h
469 --- apache_1.3.23.orig/src/include/ap.h Mon Jan 21 22:56:43 2002
470 +++ apache_1.3.23/src/include/ap.h Wed Feb 6 20:20:48 2002
472 * with some extensions. The extensions are:
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
480 * The %p hacks are to force gcc's printf warning code to skip
481 diff -Nur apache_1.3.23.orig/src/include/ap_config.h apache_1.3.23/src/include/ap_config.h
482 --- apache_1.3.23.orig/src/include/ap_config.h Thu Jan 17 14:20:51 2002
483 +++ apache_1.3.23/src/include/ap_config.h Wed Feb 6 20:20:48 2002
487 #define S_IWOTH 000002
491 +typedef u_long n_long;
494 #define STDIN_FILENO 0
495 @@ -1507,6 +1511,70 @@
496 #define ap_wait_t int
500 +#define sockaddr_storage sockaddr
501 +#define ss_family sa_family
502 +#define ss_len sa_len
504 +#include "sockaddr_storage.h" /* sshida@st.rim.or.jp */
507 +#ifndef INET6_ADDRSTRLEN
508 +#define INET6_ADDRSTRLEN 46
510 +#ifndef INET_ADDRSTRLEN
511 +#define INET_ADDRSTRLEN 16
514 +#define NI_MAXHOST 1025
517 +#define NI_MAXSERV 32
520 +#if defined(NEED_GETADDRINFO) || defined(NEED_GETNAMEINFO)
522 + * minimal definitions for fake getaddrinfo()/getnameinfo().
525 +#define EAI_NODATA 1
526 +#define EAI_MEMORY 2
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
539 +#ifdef NEED_GETADDRINFO
540 +#ifdef NEED_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 */
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);
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,
566 diff -Nur apache_1.3.23.orig/src/include/http_conf_globals.h apache_1.3.23/src/include/http_conf_globals.h
567 --- apache_1.3.23.orig/src/include/http_conf_globals.h Wed Feb 6 20:17:43 2002
568 +++ apache_1.3.23/src/include/http_conf_globals.h Wed Feb 6 20:23:09 2002
570 extern API_VAR_EXPORT int ap_max_requests_per_child;
571 extern API_VAR_EXPORT int ap_threads_per_child;
572 extern API_VAR_EXPORT int ap_excess_requests_per_child;
573 -extern API_VAR_EXPORT struct in_addr ap_bind_address;
574 +extern API_VAR_EXPORT struct sockaddr_storage ap_bind_address;
575 +extern API_VAR_EXPORT int ap_default_family;
576 extern listen_rec *ap_listeners;
577 extern API_VAR_EXPORT int ap_daemons_to_start;
578 extern API_VAR_EXPORT int ap_daemons_min_free;
579 diff -Nur apache_1.3.23.orig/src/include/http_vhost.h apache_1.3.23/src/include/http_vhost.h
580 --- apache_1.3.23.orig/src/include/http_vhost.h Mon Jan 21 00:13:51 2002
581 +++ apache_1.3.23/src/include/http_vhost.h Wed Feb 6 20:23:58 2002
583 API_EXPORT(const char *) ap_parse_vhost_addrs(pool *p, const char *hostname, server_rec *s);
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);
589 /* given an ip address only, give our best guess as to what vhost it is */
590 API_EXPORT(void) ap_update_vhost_given_ip(conn_rec *conn);
591 diff -Nur apache_1.3.23.orig/src/include/httpd.h apache_1.3.23/src/include/httpd.h
592 --- apache_1.3.23.orig/src/include/httpd.h Wed Feb 6 20:17:43 2002
593 +++ apache_1.3.23/src/include/httpd.h Wed Feb 6 20:24:49 2002
596 /* Who is the client? */
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,
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> */
616 @@ -1024,7 +1024,7 @@
617 /* These are more like real hosts than virtual hosts */
620 - struct sockaddr_in local_addr; /* local IP address and port */
621 + struct sockaddr_storage local_addr; /* local IP address and port */
623 int used; /* Only used during restart */
624 /* more stuff here, like which protocol is bound to the port */
625 @@ -1184,7 +1184,7 @@
626 #endif /*#ifdef CHARSET_EBCDIC*/
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);
632 extern API_VAR_EXPORT time_t ap_restart_time;
634 diff -Nur apache_1.3.23.orig/src/include/sa_len.h apache_1.3.23/src/include/sa_len.h
635 --- apache_1.3.23.orig/src/include/sa_len.h Thu Jan 1 01:00:00 1970
636 +++ apache_1.3.23/src/include/sa_len.h Wed Feb 6 20:20:48 2002
638 +/* sa_len.h : tiny version of SA_LEN (written by <yoshfuji@ecei.tohoku.ac.jp>) */
640 +#include <sys/types.h>
641 +#include <sys/socket.h>
642 +#include <netinet/in.h>
645 +#ifndef HAVE_SOCKADDR_LEN
647 +#define SA_LEN(s_) ap_sa_len((s_)->sa_family)
649 +static NET_SIZE_T ap_sa_len (sa_family_t af)
652 +#if defined(AF_INET)
654 + return (sizeof(struct sockaddr_in));
655 +#endif /* AF_INET */
656 +#if defined(AF_INET6)
658 + return (sizeof(struct sockaddr_in6));
662 +#endif /* AF_LOCAL */
663 +#if defined(AF_UNIX) && (AF_UNIX != AF_LOCAL)
665 +#endif /* AF_UNIX */
666 +#if defined(AF_FILE) && (AF_FILE != AF_LOCAL || AF_FILE != AF_UNIX)
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) */
678 +#endif /* HAVE_SOCKADDR_LEN */
679 diff -Nur apache_1.3.23.orig/src/include/sockaddr_storage.h apache_1.3.23/src/include/sockaddr_storage.h
680 --- apache_1.3.23.orig/src/include/sockaddr_storage.h Thu Jan 1 01:00:00 1970
681 +++ apache_1.3.23/src/include/sockaddr_storage.h Wed Feb 6 20:20:48 2002
684 +struct sockaddr_storage
686 + RFC2553 proposes struct sockaddr_storage.
687 + This is a placeholder for all sockaddr-variant structures. This is
688 + implemented like follows:
690 + You should use this structure to hold any of sockaddr-variant
693 +#ifdef NEED_SOCKADDR_STORAGE
695 +struct sockaddr_storage {
696 +#ifdef HAVE_SOCKADDR_LEN
702 + u_char __padding[128 - 2];
708 + Alternatively, you may want to implement sockunion.h, with the
711 + NOTE: For better portability, struct sockaddr_storage should be used.
712 + union sockunion is okay, but is not really portable enough.
716 +#ifdef HAVE_SOCKADDR_LEN
724 + struct sockaddr_in su_sin;
726 + struct sockaddr_in6 su_sin6;
729 +#ifdef HAVE_SOCKADDR_LEN
730 +#define su_len su_si.si_len
732 +#define su_family su_si.si_family
733 +#define su_port su_si.si_port
735 +#endif /* NEED_SOCKADDR_STORAGE */
736 diff -Nur apache_1.3.23.orig/src/main/getaddrinfo.c apache_1.3.23/src/main/getaddrinfo.c
737 --- apache_1.3.23.orig/src/main/getaddrinfo.c Thu Jan 1 01:00:00 1970
738 +++ apache_1.3.23/src/main/getaddrinfo.c Wed Feb 6 20:20:48 2002
741 + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
742 + * All rights reserved.
744 + * Redistribution and use in source and binary forms, with or without
745 + * modification, are permitted provided that the following conditions
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.
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
769 + * fake library for ssh v6 enabler patch
771 + * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
772 + * These funtions are defined in rfc2133.
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.
778 + * In the case not using 'configure --enable-ipv6', this getaddrinfo.c
779 + * will be used if you have broken getaddrinfo or no getaddrinfo.
784 +#include <sys/types.h>
785 +#include <sys/socket.h>
786 +#include <netinet/in.h>
787 +#include <arpa/inet.h>
792 +static struct addrinfo *
793 +malloc_ai(port, addr, socktype, protocol)
799 + struct addrinfo *ai;
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 =
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;
826 + return "no address associated with hostname.";
828 + return "memory allocation failure.";
830 + return "unknown error.";
836 +struct addrinfo *ai;
838 + struct addrinfo *next;
841 + next = ai->ai_next;
843 + } while (ai = next);
847 +getaddrinfo(hostname, servname, hints, res)
848 +const char *hostname, *servname;
849 +const struct addrinfo *hints;
850 +struct addrinfo **res;
852 + struct addrinfo *cur, *prev = NULL;
853 + struct hostent *hp;
857 + port = htons(atoi(servname));
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))
868 + if (*res = malloc_ai(port, htonl(0x7f000001),
869 + (*res)->ai_socktype ? (*res)->ai_socktype : SOCK_STREAM,
870 + (*res)->ai_protocol))
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))
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)) {
889 + prev->ai_next = cur;
895 + freeaddrinfo(*res);
902 diff -Nur apache_1.3.23.orig/src/main/getnameinfo.c apache_1.3.23/src/main/getnameinfo.c
903 --- apache_1.3.23.orig/src/main/getnameinfo.c Thu Jan 1 01:00:00 1970
904 +++ apache_1.3.23/src/main/getnameinfo.c Wed Feb 6 20:20:48 2002
907 + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
908 + * All rights reserved.
910 + * Redistribution and use in source and binary forms, with or without
911 + * modification, are permitted provided that the following conditions
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.
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
935 + * fake library for ssh v6 enabler patch
937 + * This file includes getnameinfo().
938 + * These funtions are defined in rfc2133.
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.
944 + * In the case not using 'configure --enable-ipv6', this getnameinfo.c
945 + * will be used if you have broken getnameinfo or no getnameinfo.
950 +#include <sys/types.h>
951 +#include <sys/socket.h>
952 +#include <netinet/in.h>
953 +#include <arpa/inet.h>
960 +getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
961 +const struct sockaddr *sa;
969 + struct sockaddr_in *sin = (struct sockaddr_in *)sa;
970 + struct hostent *hp;
974 + sprintf(tmpserv, "%d", ntohs(sin->sin_port));
975 + if (strlen(tmpserv) > servlen)
978 + strcpy(serv, tmpserv);
981 + if (flags & NI_NUMERICHOST)
982 + if (strlen(inet_ntoa(sin->sin_addr)) > hostlen)
985 + strcpy(host, inet_ntoa(sin->sin_addr));
989 + if (hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr),
991 + if (strlen(hp->h_name) > hostlen)
994 + strcpy(host, hp->h_name);
1001 diff -Nur apache_1.3.23.orig/src/main/http_config.c apache_1.3.23/src/main/http_config.c
1002 --- apache_1.3.23.orig/src/main/http_config.c Wed Feb 6 20:17:43 2002
1003 +++ apache_1.3.23/src/main/http_config.c Wed Feb 6 20:28:01 2002
1004 @@ -1564,7 +1564,6 @@
1005 ap_scoreboard_fname = DEFAULT_SCOREBOARD;
1006 ap_lock_fname = DEFAULT_LOCKFILE;
1007 ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
1008 - ap_bind_address.s_addr = htonl(INADDR_ANY);
1009 ap_listeners = NULL;
1010 ap_listenbacklog = DEFAULT_LISTENBACKLOG;
1011 ap_extended_status = 0;
1012 @@ -1597,7 +1596,13 @@
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));
1019 + s->addrs->host_addr.ss_family = ap_default_family; /* XXX: needed?, XXX: PF_xxx can be different from AF_xxx */
1021 +#ifdef HAVE_SOCKADDR_LEN
1022 + s->addrs->host_addr.ss_len = sizeof(s->addrs->host_addr); /* XXX: needed ? */
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)
1031 + struct addrinfo hints, *res0, *res;
1033 + char servbuf[NI_MAXSERV];
1035 if (ap_listeners != NULL) {
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);
1045 + fprintf(stderr, "default_listeners(): getaddrinfo(PASSIVE) for family %u: %s\n",
1046 + gai_strerror(gai), ap_default_family);
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);
1062 + freeaddrinfo(res0);
1066 diff -Nur apache_1.3.23.orig/src/main/http_core.c apache_1.3.23/src/main/http_core.c
1067 --- apache_1.3.23.orig/src/main/http_core.c Wed Jan 16 22:34:32 2002
1068 +++ apache_1.3.23/src/main/http_core.c Wed Feb 6 20:20:48 2002
1070 #include "util_md5.h"
1071 #include "scoreboard.h"
1072 #include "fnmatch.h"
1073 +#include "sa_len.h"
1075 #ifdef USE_MMAP_FILES
1076 #include <sys/mman.h>
1078 /* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
1079 static ap_inline void do_double_reverse (conn_rec *conn)
1081 - struct hostent *hptr;
1082 + struct addrinfo hints, *res, *res0;
1083 + char hostbuf1[128], hostbuf2[128]; /* INET6_ADDRSTRLEN(=46) is enough */
1086 if (conn->double_reverse) {
1088 @@ -632,28 +635,51 @@
1089 conn->double_reverse = -1;
1092 - hptr = gethostbyname(conn->remote_host);
1096 - for (haddr = hptr->h_addr_list; *haddr; haddr++) {
1097 - if (((struct in_addr *)(*haddr))->s_addr
1098 - == conn->remote_addr.sin_addr.s_addr) {
1099 - conn->double_reverse = 1;
1102 + memset(&hints, 0, sizeof(hints));
1103 + hints.ai_family = PF_UNSPEC;
1104 + hints.ai_socktype = SOCK_STREAM;
1105 + if (getaddrinfo(conn->remote_host, NULL, &hints, &res0)) {
1106 + conn->double_reverse = -1;
1109 + for (res = res0; res; res = res->ai_next) {
1110 + if (res->ai_addr->sa_family != conn->remote_addr.ss_family ||
1111 + !(res->ai_family == AF_INET
1113 + || res->ai_family == AF_INET6
1118 +#ifndef HAVE_SOCKADDR_LEN
1119 + if (res->ai_addrlen != SA_LEN((struct sockaddr *)&conn->remote_addr))
1121 + if (res->ai_addr->sa_len != conn->remote_addr.ss_len)
1124 + if (getnameinfo(res->ai_addr, res->ai_addrlen,
1125 + hostbuf1, sizeof(hostbuf1), NULL, 0,
1128 + if (getnameinfo(((struct sockaddr *)&conn->remote_addr), res->ai_addrlen,
1129 + hostbuf2, sizeof(hostbuf2), NULL, 0,
1132 + if (strcmp(hostbuf1, hostbuf2) == 0){
1137 - conn->double_reverse = -1;
1138 + conn->double_reverse = ok ? 1 : -1;
1139 + freeaddrinfo(res0);
1142 API_EXPORT(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
1145 - struct in_addr *iaddr;
1146 - struct hostent *hptr;
1147 int hostname_lookups;
1148 int old_stat = SERVER_DEAD; /* we shouldn't ever be in this state */
1149 + char hostnamebuf[MAXHOSTNAMELEN];
1151 /* If we haven't checked the host name, and we want to */
1153 @@ -675,10 +701,14 @@
1154 || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
1155 old_stat = ap_update_child_status(conn->child_num, SERVER_BUSY_DNS,
1156 (request_rec*)NULL);
1157 - iaddr = &(conn->remote_addr.sin_addr);
1158 - hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
1159 - if (hptr != NULL) {
1160 - conn->remote_host = ap_pstrdup(conn->pool, (void *)hptr->h_name);
1161 + if (!getnameinfo((struct sockaddr *)&conn->remote_addr,
1163 + SA_LEN((struct sockaddr *)&conn->remote_addr),
1165 + conn->remote_addr.ss_len,
1167 + hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0)) {
1168 + conn->remote_host = ap_pstrdup(conn->pool, (void *)hostnamebuf);
1169 ap_str_tolower(conn->remote_host);
1171 if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
1174 conn_rec *conn = r->connection;
1176 + char hbuf[MAXHOSTNAMELEN];
1178 d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
1180 @@ -768,23 +799,22 @@
1182 if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
1183 if (conn->local_host == NULL) {
1184 - struct in_addr *iaddr;
1185 - struct hostent *hptr;
1187 old_stat = ap_update_child_status(conn->child_num,
1188 SERVER_BUSY_DNS, r);
1189 - iaddr = &(conn->local_addr.sin_addr);
1190 - hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr),
1192 - if (hptr != NULL) {
1193 - conn->local_host = ap_pstrdup(conn->pool,
1194 - (void *)hptr->h_name);
1195 - ap_str_tolower(conn->local_host);
1198 - conn->local_host = ap_pstrdup(conn->pool,
1199 - r->server->server_hostname);
1200 + if (getnameinfo((struct sockaddr *)&conn->local_addr,
1202 + SA_LEN((struct sockaddr *)&conn->local_addr),
1204 + conn->local_addr.ss_len,
1206 + hbuf, sizeof(hbuf), NULL, 0, 0) == 0) {
1207 + conn->local_host = ap_pstrdup(conn->pool, hbuf);
1209 + conn->local_host = ap_pstrdup(conn->pool,
1210 + r->server->server_hostname);
1212 + ap_str_tolower(conn->local_host);
1213 (void) ap_update_child_status(conn->child_num, old_stat, r);
1215 return conn->local_host;
1216 @@ -803,11 +833,13 @@
1218 if (d->use_canonical_name == USE_CANONICAL_NAME_OFF
1219 || d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
1220 - return r->hostname ? ntohs(r->connection->local_addr.sin_port)
1225 + return r->hostname
1226 + ? ntohs(((struct sockaddr_in *)&r->connection->local_addr)->sin_port)
1229 + return r->hostname
1230 + ? ntohs(((struct sockaddr_in *)&r->connection->local_addr)->sin_port)
1234 API_EXPORT(char *) ap_construct_url(pool *p, const char *uri,
1235 @@ -2539,12 +2571,25 @@
1237 static const char *set_bind_address(cmd_parms *cmd, void *dummy, char *arg)
1239 + struct addrinfo hints, *res;
1240 + struct sockaddr *sa;
1243 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1248 - ap_bind_address.s_addr = ap_get_virthost_addr(arg, NULL);
1249 + if (strcmp(arg, "*") == 0)
1252 + sa = ap_get_virthost_addr(arg, NULL);
1253 +#ifdef HAVE_SOCKADDR_LEN
1254 + sa_len = sa->sa_len;
1256 + sa_len = SA_LEN(sa);
1258 + memcpy(&ap_bind_address, &sa, sa_len);
1262 @@ -2576,44 +2621,70 @@
1266 -static const char *set_listener(cmd_parms *cmd, void *dummy, char *ips)
1267 +static const char *set_listener(cmd_parms *cmd, void *dummy, char *h, char *p)
1271 - unsigned short port;
1272 + char *host, *port;
1273 + struct addrinfo hints, *res;
1276 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1281 - ports = strchr(ips, ':');
1282 - if (ports != NULL) {
1283 - if (ports == ips) {
1284 - return "Missing IP address";
1286 - else if (ports[1] == '\0') {
1287 - return "Address must end in :<port-number>";
1288 + host = port = NULL;
1290 + port = strrchr(h, ':');
1291 + if (port != NULL) {
1293 + return "Missing IP address";
1295 + else if (port[1] == '\0') {
1296 + return "Address must end in :<port-number>";
1305 - *(ports++) = '\0';
1314 - new=ap_pcalloc(cmd->pool, sizeof(listen_rec));
1315 - new->local_addr.sin_family = AF_INET;
1316 - if (ports == ips) { /* no address */
1317 - new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
1320 - new->local_addr.sin_addr.s_addr = ap_get_virthost_addr(ips, NULL);
1322 - port = atoi(ports);
1324 - return "Port must be numeric";
1325 + if (host && strcmp(host, "*") == 0)
1328 + new = ap_pcalloc(cmd->pool, sizeof(listen_rec));
1330 + memset(&hints, 0, sizeof(hints));
1331 + hints.ai_family = host ? PF_UNSPEC : ap_default_family;
1332 + hints.ai_flags = AI_PASSIVE;
1333 + hints.ai_socktype = SOCK_STREAM;
1334 + error = getaddrinfo(host, port, &hints, &res);
1335 + if (error || !res) {
1336 + fprintf(stderr, "could not resolve ");
1338 + fprintf(stderr, "host \"%s\" ", host);
1340 + fprintf(stderr, "port \"%s\" ", port);
1341 + fprintf(stderr, "--- %s\n", gai_strerror(error));
1344 + if (res->ai_next) {
1346 + fprintf(stderr, "host \"%s\" ", host);
1348 + fprintf(stderr, "port \"%s\" ", port);
1349 + fprintf(stderr, "resolved to multiple addresses, ambiguous.\n");
1352 - new->local_addr.sin_port = htons(port);
1354 + memcpy(&new->local_addr, res->ai_addr, res->ai_addrlen);
1358 new->next = ap_listeners;
1359 @@ -3328,7 +3399,7 @@
1360 { "ThreadStackSize", set_threadstacksize, NULL, RSRC_CONF, TAKE1,
1361 "Stack size each created thread will use."},
1363 -{ "Listen", set_listener, NULL, RSRC_CONF, TAKE1,
1364 +{ "Listen", set_listener, NULL, RSRC_CONF, TAKE12,
1365 "A port number or a numeric IP address and a port number"},
1366 { "SendBufferSize", set_send_buffer_size, NULL, RSRC_CONF, TAKE1,
1367 "Send buffer size in bytes"},
1368 @@ -3362,7 +3433,7 @@
1369 "Name of the config file to be included" },
1370 { "LogLevel", set_loglevel, NULL, RSRC_CONF, TAKE1,
1371 "Level of verbosity in error logging" },
1372 -{ "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE1,
1373 +{ "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE12,
1374 "A numeric IP address:port, or the name of a host" },
1376 { "BS2000Account", set_bs2000_account, NULL, RSRC_CONF, TAKE1,
1377 diff -Nur apache_1.3.23.orig/src/main/http_main.c apache_1.3.23/src/main/http_main.c
1378 --- apache_1.3.23.orig/src/main/http_main.c Wed Feb 6 20:17:43 2002
1379 +++ apache_1.3.23/src/main/http_main.c Wed Feb 6 20:29:52 2002
1381 #include <bstring.h> /* for IRIX, FD_SET calls bzero() */
1384 +#include "sa_len.h"
1387 /* special debug stuff -- PCS */
1389 @@ -249,7 +251,12 @@
1390 API_VAR_EXPORT char *ap_scoreboard_fname=NULL;
1391 API_VAR_EXPORT char *ap_lock_fname=NULL;
1392 API_VAR_EXPORT char *ap_server_argv0=NULL;
1393 -API_VAR_EXPORT struct in_addr ap_bind_address={0};
1395 +API_VAR_EXPORT int ap_default_family = PF_INET6;
1397 +API_VAR_EXPORT int ap_default_family = PF_INET;
1399 +API_VAR_EXPORT struct sockaddr_storage ap_bind_address={0};
1400 API_VAR_EXPORT int ap_daemons_to_start=0;
1401 API_VAR_EXPORT int ap_daemons_min_free=0;
1402 API_VAR_EXPORT int ap_daemons_max_free=0;
1403 @@ -1384,7 +1391,11 @@
1404 fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin);
1406 fprintf(stderr, " %s [-C \"directive\"] [-c \"directive\"]\n", pad);
1407 - fprintf(stderr, " %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]\n", pad);
1408 + fprintf(stderr, " %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T]"
1413 fprintf(stderr, "Options:\n");
1415 fprintf(stderr, " -R directory : specify an alternate location for shared object files\n");
1416 @@ -1406,6 +1417,10 @@
1418 fprintf(stderr, " -t : run syntax check for config files (with docroot check)\n");
1419 fprintf(stderr, " -T : run syntax check for config files (without docroot check)\n");
1421 + fprintf(stderr, " -4 : assume IPv4 on parsing configuration file\n");
1422 + fprintf(stderr, " -6 : assume IPv6 on parsing configuration file\n");
1425 fprintf(stderr, " -n name : name the Apache service for -k options below;\n");
1426 fprintf(stderr, " -k stop|shutdown : tell running Apache to shutdown\n");
1427 @@ -3566,11 +3581,13 @@
1430 static conn_rec *new_connection(pool *p, server_rec *server, BUFF *inout,
1431 - const struct sockaddr_in *remaddr,
1432 - const struct sockaddr_in *saddr,
1433 + const struct sockaddr *remaddr,
1434 + const struct sockaddr *saddr,
1437 conn_rec *conn = (conn_rec *) ap_pcalloc(p, sizeof(conn_rec));
1438 + char hostnamebuf[MAXHOSTNAMELEN];
1441 /* Got a connection structure, so initialize what fields we can
1442 * (the rest are zeroed out by pcalloc).
1443 @@ -3579,17 +3596,29 @@
1444 conn->child_num = child_num;
1447 - conn->local_addr = *saddr;
1448 - conn->local_ip = ap_pstrdup(conn->pool,
1449 - inet_ntoa(conn->local_addr.sin_addr));
1451 + addr_len = SA_LEN(saddr);
1453 + addr_len = saddr->sa_len;
1455 + memcpy(&conn->local_addr, saddr, addr_len);
1456 + getnameinfo((struct sockaddr *)&conn->local_addr, addr_len,
1457 + hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
1458 + conn->local_ip = ap_pstrdup(conn->pool, hostnamebuf);
1459 conn->server = server; /* just a guess for now */
1460 ap_update_vhost_given_ip(conn);
1461 conn->base_server = conn->server;
1462 conn->client = inout;
1464 - conn->remote_addr = *remaddr;
1465 - conn->remote_ip = ap_pstrdup(conn->pool,
1466 - inet_ntoa(conn->remote_addr.sin_addr));
1468 + addr_len = SA_LEN(remaddr);
1470 + addr_len = remaddr->sa_len;
1472 + memcpy(&conn->remote_addr, remaddr, addr_len);
1473 + getnameinfo((struct sockaddr *)&conn->remote_addr, addr_len,
1474 + hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
1475 + conn->remote_ip = ap_pstrdup(conn->pool, hostnamebuf);
1477 conn->ctx = ap_ctx_new(conn->pool);
1479 @@ -3640,21 +3669,47 @@
1480 #define sock_disable_nagle(s) /* NOOP */
1483 -static int make_sock(pool *p, const struct sockaddr_in *server)
1484 +static int make_sock(pool *p, const struct sockaddr *server)
1489 + char addr[INET6_ADDRSTRLEN + 128];
1490 + char a0[INET6_ADDRSTRLEN];
1491 + char p0[NI_MAXSERV];
1496 - if (server->sin_addr.s_addr != htonl(INADDR_ANY))
1497 - ap_snprintf(addr, sizeof(addr), "address %s port %d",
1498 - inet_ntoa(server->sin_addr), ntohs(server->sin_port));
1500 - ap_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port));
1501 + switch(server->sa_family){
1508 + ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
1509 + "make_sock: unsupported address family %u",
1510 + server->sa_family);
1511 + ap_unblock_alarms();
1515 + getnameinfo(server,
1521 + a0, sizeof(a0), p0, sizeof(p0), NI_NUMERICHOST | NI_NUMERICSERV);
1522 + ap_snprintf(addr, sizeof(addr), "address %s port %s", a0, p0);
1524 + if (atoi(p0) < 1024)
1528 /* note that because we're about to slack we don't use psocket */
1530 - if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
1531 + if ((s = socket(server->sa_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
1532 ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
1533 "make_sock: failed to get a socket for %s", addr);
1535 @@ -3757,15 +3812,19 @@
1538 /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
1539 - if (ntohs(server->sin_port) < 1024)
1544 - if (bind(s, (struct sockaddr *) server, sizeof(struct sockaddr_in)) == -1) {
1546 + if (bind(s, server, SA_LEN(server)) == -1)
1548 + if (bind(s, server, server->sa_len) == -1)
1551 ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
1552 "make_sock: could not bind to %s", addr);
1554 - if (ntohs(server->sin_port) < 1024)
1559 @@ -3778,7 +3837,7 @@
1563 - if (ntohs(server->sin_port) < 1024)
1568 @@ -3931,15 +3990,17 @@
1570 fd = find_listener(lr);
1572 - fd = make_sock(p, &lr->local_addr);
1573 + fd = make_sock(p, (struct sockaddr *)&lr->local_addr);
1576 ap_note_cleanups_for_socket(p, fd);
1578 /* if we get here, (fd >= 0) && (fd < FD_SETSIZE) */
1579 - FD_SET(fd, &listenfds);
1580 - if (fd > listenmaxfd)
1583 + FD_SET(fd, &listenfds);
1584 + if (fd > listenmaxfd)
1588 if (lr->next == NULL)
1590 @@ -4257,8 +4318,8 @@
1591 static void child_main(int child_num_arg)
1594 - struct sockaddr sa_server;
1595 - struct sockaddr sa_client;
1596 + struct sockaddr_storage sa_server;
1597 + struct sockaddr_storage sa_client;
1600 /* All of initialization is a critical section, we don't care if we're
1601 @@ -4423,7 +4484,7 @@
1604 clen = sizeof(sa_client);
1605 - csd = ap_accept(sd, &sa_client, &clen);
1606 + csd = ap_accept(sd, (struct sockaddr *)&sa_client, &clen);
1607 if (csd >= 0 || errno != EINTR)
1610 @@ -4586,7 +4647,7 @@
1613 clen = sizeof(sa_server);
1614 - if (getsockname(csd, &sa_server, &clen) < 0) {
1615 + if (getsockname(csd, (struct sockaddr *)&sa_server, &clen) < 0) {
1616 ap_log_error(APLOG_MARK, APLOG_ERR, server_conf, "getsockname");
1619 @@ -4631,8 +4692,8 @@
1620 ap_bpushfd(conn_io, csd, dupped_csd);
1622 current_conn = new_connection(ptrans, server_conf, conn_io,
1623 - (struct sockaddr_in *) &sa_client,
1624 - (struct sockaddr_in *) &sa_server,
1625 + (struct sockaddr *)&sa_client,
1626 + (struct sockaddr *)&sa_server,
1630 @@ -4776,12 +4837,13 @@
1633 /* BS2000 requires a "special" version of fork() before a setuid() call */
1634 - if ((pid = os_fork(ap_user_name)) == -1) {
1635 + if ((pid = os_fork(ap_user_name)) == -1)
1637 - if ((pid = os_fork(s, slot)) == -1) {
1638 + if ((pid = os_fork(s, slot)) == -1)
1640 - if ((pid = fork()) == -1) {
1641 + if ((pid = fork()) == -1)
1644 ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new process");
1646 /* fork didn't succeed. Fix the scoreboard or else
1647 @@ -5390,7 +5452,10 @@
1648 ap_setup_prelinked_modules();
1650 while ((c = getopt(argc, argv,
1651 - "D:C:c:xXd:f:vVlLR:StTh"
1652 + "D:C:c:xXd:f:vVlLR:StTh4"
1656 #ifdef DEBUG_SIGSTOP
1659 @@ -5465,8 +5530,14 @@
1660 ap_configtestonly = 1;
1661 ap_docrootcheck = 0;
1666 + ap_default_family = PF_INET;
1670 + ap_default_family = PF_INET6;
1676 @@ -5546,9 +5617,10 @@
1680 - struct sockaddr sa_server, sa_client;
1682 + struct sockaddr_storage sa_server, sa_client;
1684 + char servbuf[NI_MAXSERV];
1687 /* Yes this is called twice. */
1688 @@ -5595,25 +5667,32 @@
1691 l = sizeof(sa_client);
1692 - if ((getpeername(sock_in, &sa_client, &l)) < 0) {
1693 + if ((getpeername(sock_in, (struct sockaddr *)&sa_client, &l)) < 0) {
1694 /* get peername will fail if the input isn't a socket */
1695 perror("getpeername");
1696 memset(&sa_client, '\0', sizeof(sa_client));
1699 l = sizeof(sa_server);
1700 - if (getsockname(sock_in, &sa_server, &l) < 0) {
1701 + if (getsockname(sock_in, (struct sockaddr *)&sa_server, &l) < 0) {
1702 perror("getsockname");
1703 fprintf(stderr, "Error getting local address\n");
1706 - server_conf->port = ntohs(((struct sockaddr_in *) &sa_server)->sin_port);
1707 + if (getnameinfo(((struct sockaddr *)&sa_server), l,
1708 + NULL, 0, servbuf, sizeof(servbuf),
1710 + fprintf(stderr, "getnameinfo(): family=%d\n", sa_server.ss_family);
1713 + servbuf[sizeof(servbuf)-1] = '\0';
1714 + server_conf->port = atoi(servbuf);
1715 cio = ap_bcreate(ptrans, B_RDWR | B_SOCKET);
1717 cio->fd_in = sock_in;
1718 conn = new_connection(ptrans, server_conf, cio,
1719 - (struct sockaddr_in *) &sa_client,
1720 - (struct sockaddr_in *) &sa_server, -1);
1721 + (struct sockaddr *)&sa_client,
1722 + (struct sockaddr *)&sa_server, -1);
1724 while ((r = ap_read_request(conn)) != NULL) {
1726 @@ -7820,7 +7899,11 @@
1727 * but only handle the -L option
1729 llp_dir = SHARED_CORE_DIR;
1730 - while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLR:SZ:tTh")) != -1) {
1731 + while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLR:SZ:tTh4"
1739 @@ -7837,6 +7920,10 @@
1750 diff -Nur apache_1.3.23.orig/src/main/http_vhost.c apache_1.3.23/src/main/http_vhost.c
1751 --- apache_1.3.23.orig/src/main/http_vhost.c Mon Jan 21 00:13:51 2002
1752 +++ apache_1.3.23/src/main/http_vhost.c Wed Feb 6 20:30:51 2002
1754 #include "http_log.h"
1755 #include "http_vhost.h"
1756 #include "http_protocol.h"
1757 +#include "sa_len.h"
1760 * After all the definitions there's an explanation of how it's all put
1761 @@ -165,78 +166,114 @@
1762 * *paddr is the variable used to keep track of **paddr between calls
1763 * port is the default port to assume
1765 -static const char *get_addresses(pool *p, char *w, server_addr_rec ***paddr,
1767 +static const char *get_addresses(pool *p, char *w, char *pstr,
1768 + server_addr_rec ***paddr, unsigned port)
1770 - struct hostent *hep;
1771 - unsigned long my_addr;
1772 + struct addrinfo hints, *res, *res0;
1773 server_addr_rec *sar;
1775 - int i, is_an_ip_addr;
1776 + char *t = NULL, *u = NULL, *v = NULL;
1777 + char *hoststr = NULL, *portstr = NULL;
1778 + char portpool[10];
1780 + char servbuf[NI_MAXSERV];
1783 + if (w == 0 || *w == 0)
1786 - t = strchr(w, ':');
1788 - if (strcmp(t + 1, "*") == 0) {
1790 + portstr = portpool;
1791 + ap_snprintf(portpool, sizeof(portpool), "%u", port);
1796 + u = strrchr(w, ']');
1797 + if (u) { /* [host]:port or [host] */
1803 - else if ((i = atoi(t + 1))) {
1805 + /* w uv , w=v , w=v */
1806 + /* u!=0: [host]:port , u==0: [host:port , host */
1807 + t = strchr(v, ':');
1808 + if (t != NULL && strchr(t+1, ':') == NULL) {
1809 + /* [host]:port-w/o-colons, host-without-colons:port-w/o-colons */
1814 - return ":port must be numeric";
1822 - is_an_ip_addr = 0;
1823 - if (strcmp(w, "*") == 0) {
1824 - my_addr = htonl(INADDR_ANY);
1825 - is_an_ip_addr = 1;
1827 - else if (strcasecmp(w, "_default_") == 0
1828 - || strcmp(w, "255.255.255.255") == 0) {
1829 - my_addr = DEFAULT_VHOST_ADDR;
1830 - is_an_ip_addr = 1;
1832 - else if ((my_addr = ap_inet_addr(w)) != INADDR_NONE) {
1833 - is_an_ip_addr = 1;
1834 + memset(&hints, 0, sizeof(hints));
1835 + hints.ai_socktype = SOCK_STREAM;
1836 + if (strcmp(w, "*") == 0 || strlen(w) == 0) {
1838 + hints.ai_family = PF_UNSPEC;
1839 + hints.ai_flags = AI_PASSIVE;
1841 + else if (strcasecmp(w, "_default4_") == 0 ||
1842 + ((ap_default_family == PF_INET
1844 + || ap_default_family == PF_UNSPEC
1846 + ) && strcasecmp(w, "_default_") == 0)){
1847 + hoststr = "255.255.255.255";
1848 + hints.ai_family = PF_INET;
1851 + else if (strcasecmp(w, "_default6_") == 0 ||
1852 + ((ap_default_family == PF_INET6
1853 + || ap_default_family == PF_UNSPEC
1854 + ) && strcasecmp(w, "_default_") == 0)){
1855 + hoststr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
1856 + hints.ai_family = PF_INET6;
1858 - if (is_an_ip_addr) {
1859 - sar = ap_pcalloc(p, sizeof(server_addr_rec));
1861 - *paddr = &sar->next;
1862 - sar->host_addr.s_addr = my_addr;
1863 - sar->host_port = port;
1864 - sar->virthost = ap_pstrdup(p, w);
1871 + hints.ai_family = PF_UNSPEC;
1874 - hep = gethostbyname(w);
1876 - if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
1877 + error = getaddrinfo(hoststr, portstr, &hints, &res0);
1878 + if (error || !res0) {
1879 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
1880 - "Cannot resolve host name %s --- ignoring!", w);
1883 + "Cannot resolve host %s port %s --- ignoring!", hoststr, portstr);
1884 + if (t != NULL) *t = ':';
1885 + if (u != NULL) *u = ']';
1889 - for (i = 0; hep->h_addr_list[i]; ++i) {
1890 + for (res=res0; res; res=res->ai_next) {
1891 + switch (res->ai_addr->sa_family) {
1898 + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
1899 + "Unsupported address family %u, for host %s port %s --- ignoring!",
1900 + res->ai_addr->sa_family, hoststr, portstr);
1903 sar = ap_pcalloc(p, sizeof(server_addr_rec));
1905 *paddr = &sar->next;
1906 - sar->host_addr = *(struct in_addr *) hep->h_addr_list[i];
1907 - sar->host_port = port;
1908 + memcpy(&sar->host_addr, res->ai_addr, res->ai_addrlen);
1909 + if (getnameinfo(res->ai_addr, res->ai_addrlen, NULL, 0, servbuf,
1910 + sizeof(servbuf), NI_NUMERICSERV) == 0)
1911 + sar->host_port = atoi(servbuf);
1913 + sar->host_port = 0;
1914 sar->virthost = ap_pstrdup(p, w);
1919 + freeaddrinfo(res0);
1920 + if (t != NULL) *t = ':';
1921 + if (u != NULL) *u = ']';
1926 /* start the list of addreses */
1928 while (hostname[0]) {
1929 - err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
1930 + err = get_addresses(p, ap_getword_conf(p, &hostname), NULL,
1935 @@ -268,10 +306,11 @@
1939 -API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg)
1940 +API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *h,
1943 /* use whatever port the main server has at this point */
1944 - return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
1945 + return get_addresses(cmd->pool, h, p, &name_vhost_list_tail,
1949 @@ -345,6 +384,19 @@
1950 return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
1953 +static unsigned hash_addr(struct sockaddr *sa)
1955 + switch (sa->sa_family) {
1957 + return hash_inaddr(((struct sockaddr_in *)sa)->sin_addr.s_addr);
1960 + return hash_inaddr(((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12]);
1963 + return hash_inaddr(sa->sa_family);
1968 static ipaddr_chain *new_ipaddr_chain(pool *p,
1969 @@ -372,25 +424,77 @@
1974 -static ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
1976 +static ap_inline ipaddr_chain *find_ipaddr(struct sockaddr *sa)
1981 + char a[NI_MAXHOST], b[NI_MAXHOST];
1983 /* scan the hash table for an exact match first */
1984 - addr = server_ip->s_addr;
1985 - bucket = hash_inaddr(addr);
1986 + bucket = hash_addr(sa);
1987 for (trav = iphash_table[bucket]; trav; trav = trav->next) {
1988 server_addr_rec *sar = trav->sar;
1989 - if ((sar->host_addr.s_addr == addr)
1990 - && (sar->host_port == 0 || sar->host_port == port
1993 + if (sar->host_addr.ss_family != sa->sa_family)
1995 + switch (sa->sa_family) {
1998 + struct sockaddr_in *sin1, *sin2;
1999 + sin1 = (struct sockaddr_in *)&sar->host_addr;
2000 + sin2 = (struct sockaddr_in *)sa;
2001 + if (sin1->sin_port == 0 || sin2->sin_port == 0
2002 + || sin1->sin_port == sin2->sin_port) {
2003 + if (memcmp(&sin1->sin_addr, &sin2->sin_addr,
2004 + sizeof(sin1->sin_addr)) == 0) {
2013 + struct sockaddr_in6 *sin1, *sin2;
2014 + sin1 = (struct sockaddr_in6 *)&sar->host_addr;
2015 + sin2 = (struct sockaddr_in6 *)sa;
2016 + if (sin1->sin6_port == 0 || sin2->sin6_port == 0
2017 + || sin1->sin6_port == sin2->sin6_port) {
2018 + if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
2019 + sizeof(sin1->sin6_addr)) == 0) {
2026 + default: /*unsupported*/
2032 + if (sa->sa_family == AF_INET6 &&
2033 + IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) {
2035 + * This is just horrible. I just hate IPv4 mapped address. It
2036 + * complicates access control too much.
2037 + * Due to hashed lookup, we need to visit it again.
2039 + struct sockaddr_in sin;
2041 + memset(&sin, 0, sizeof(sin));
2042 + sin.sin_family = AF_INET;
2044 + sin.sin_len = sizeof(sin);
2046 + sin.sin_port = ((struct sockaddr_in6 *)sa)->sin6_port;
2047 + memcpy(&sin.sin_addr,
2048 + &((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12],
2049 + sizeof(sin.sin_addr));
2050 + return find_ipaddr((struct sockaddr *)&sin);
2057 @@ -416,21 +520,7 @@
2059 char buf[MAX_STRING_LEN];
2061 - if (ic->sar->host_addr.s_addr == DEFAULT_VHOST_ADDR) {
2062 - len = ap_snprintf(buf, sizeof(buf), "_default_:%u",
2063 - ic->sar->host_port);
2065 - else if (ic->sar->host_addr.s_addr == INADDR_ANY) {
2066 - len = ap_snprintf(buf, sizeof(buf), "*:%u",
2067 - ic->sar->host_port);
2070 - len = ap_snprintf(buf, sizeof(buf), "%pA:%u",
2071 - &ic->sar->host_addr, ic->sar->host_port);
2073 - if (ic->sar->host_port == 0) {
2076 + len = ap_snprintf(buf, sizeof(buf), "%pI", &ic->sar->host_addr);
2077 if (ic->names == NULL) {
2078 if (ic->server == NULL)
2079 fprintf(f, "%-22s WARNING: No <VirtualHost> defined for this NameVirtualHost!\n", buf);
2080 @@ -558,10 +648,37 @@
2081 * occured in the config file, we'll copy it in that order.
2083 for (sar = name_vhost_list; sar; sar = sar->next) {
2084 - unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
2085 + unsigned bucket = hash_addr((struct sockaddr *)&sar->host_addr);
2086 ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
2090 + switch (sar->host_addr.ss_family) {
2093 + struct sockaddr_in *sin;
2094 + sin = (struct sockaddr_in *)&sar->host_addr;
2095 + if (sin->sin_addr.s_addr == INADDR_ANY)
2102 + struct sockaddr_in6 *sin6;
2103 + sin6 = (struct sockaddr_in6 *)&sar->host_addr;
2104 + if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == 0
2105 + && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == 0
2106 + && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == 0
2107 + && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == 0) {
2115 - if (sar->host_addr.s_addr != INADDR_ANY) {
2117 *iphash_table_tail[bucket] = ic;
2118 iphash_table_tail[bucket] = &ic->next;
2120 @@ -588,12 +705,45 @@
2121 has_default_vhost_addr = 0;
2122 for (sar = s->addrs; sar; sar = sar->next) {
2127 + switch (sar->host_addr.ss_family) {
2130 + struct sockaddr_in *sin;
2131 + sin = (struct sockaddr_in *)&sar->host_addr;
2132 + if (sin->sin_addr.s_addr == DEFAULT_VHOST_ADDR)
2134 + else if (sin->sin_addr.s_addr == INADDR_ANY)
2141 + struct sockaddr_in6 *sin6;
2142 + sin6 = (struct sockaddr_in6 *)&sar->host_addr;
2143 + if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == ~0
2144 + && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == ~0
2145 + && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == ~0
2146 + && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == ~0) {
2154 - if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
2155 - || sar->host_addr.s_addr == INADDR_ANY) {
2156 - ic = find_default_server(sar->host_port);
2157 - if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
2158 - if (ic && ic->sar->host_port != 0) {
2160 + /* add it to default bucket for each appropriate sar
2161 + * since we need to do a port test
2163 + ipaddr_chain *other;
2165 + other = find_default_server(sar->host_port);
2166 + if (!other || !add_name_vhost_config(p, main_s, s, sar, other)) {
2167 + if (other && other->sar->host_port != 0) {
2168 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
2169 main_s, "_default_ VirtualHost overlap on port %u,"
2170 " the first has precedence", sar->host_port);
2171 @@ -606,10 +756,11 @@
2174 /* see if it matches something we've already got */
2175 - ic = find_ipaddr(&sar->host_addr, sar->host_port);
2176 + ic = find_ipaddr((struct sockaddr *)&sar->host_addr);
2179 - unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
2181 + hash_addr((struct sockaddr *)&sar->host_addr);
2183 ic = new_ipaddr_chain(p, s, sar);
2184 ic->next = *iphash_table_tail[bucket];
2185 @@ -646,19 +797,33 @@
2189 + char hostnamebuf[MAXHOSTNAMELEN];
2191 - if ((h = gethostbyaddr((char *) &(s->addrs->host_addr),
2192 - sizeof(struct in_addr), AF_INET))) {
2193 - s->server_hostname = ap_pstrdup(p, (char *) h->h_name);
2194 + if (!getnameinfo((struct sockaddr *)&s->addrs->host_addr,
2196 + SA_LEN((struct sockaddr *)&s->addrs->host_addr),
2198 + s->addrs->host_addr.ss_len,
2200 + hostnamebuf, sizeof(hostnamebuf),
2202 + s->server_hostname = ap_pstrdup(p, hostnamebuf);
2205 /* again, what can we do? They didn't specify a
2206 ServerName, and their DNS isn't working. -djg */
2207 + getnameinfo((struct sockaddr *)&s->addrs->host_addr,
2209 + SA_LEN((struct sockaddr *)&s->addrs->host_addr),
2211 + s->addrs->host_addr.ss_len,
2213 + hostnamebuf, sizeof(hostnamebuf),
2214 + NULL, 0, NI_NUMERICHOST);
2215 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, main_s,
2216 "Failed to resolve server name "
2217 "for %s (check DNS) -- or specify an explicit "
2219 - inet_ntoa(s->addrs->host_addr));
2220 + "ServerName", hostnamebuf);
2221 s->server_hostname =
2222 ap_pstrdup(p, "bogus_host_without_reverse_dns");
2224 @@ -705,35 +870,58 @@
2225 char *host = ap_palloc(r->pool, strlen(r->hostname) + 1);
2228 + const char *u = NULL, *v = NULL;
2230 /* check and copy the host part */
2231 - src = r->hostname;
2232 + u = src = r->hostname;
2236 - if (*src == '.') {
2243 - if (*src == '/' || *src == '\\') {
2246 - if (*src == ':') {
2247 - /* check the port part */
2249 - if (!ap_isdigit(*src)) {
2253 - if (src[-1] == ':')
2257 + if (*u == '[') { /* IPv6 numeral address in brackets */
2258 + v = strchr(u, ']');
2260 + /* missing closing bracket */
2263 + if (v == (u + 1)) {
2264 + /* bad empty address */
2267 + for (src = u+1; src < v; src++) /* copy IPv6 adress */
2272 + while (*v) { /* check if portnum is correct */
2273 + if (!ap_isdigit(*v++))
2280 + if (*src == '.') {
2287 + if (*src == '/' || *src == '\\') {
2290 + if (*src == ':') {
2291 + /* sheck the port part */
2293 + if (!ap_isdigit(*src)) {
2297 + if (src[-1] == ':')
2305 /* strip trailing gubbins */
2306 if (dst > host && dst[-1] == '.') {
2309 r->status = HTTP_BAD_REQUEST;
2310 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
2311 - "Client sent malformed Host header");
2312 + "Client sent malformed Host header <<%s>>",u);
2316 @@ -851,11 +1039,25 @@
2317 * names we'll match have ports associated with them
2319 const char *host = r->hostname;
2320 - unsigned port = ntohs(r->connection->local_addr.sin_port);
2326 + switch (r->connection->local_addr.ss_family) {
2328 + port = ntohs(((struct sockaddr_in *)
2329 + &r->connection->local_addr)->sin_port);
2333 + port = ntohs(((struct sockaddr_in6 *)
2334 + &r->connection->local_addr)->sin6_port);
2342 /* Recall that the name_chain is a list of server_addr_recs, some of
2343 @@ -910,7 +1112,22 @@
2347 - unsigned port = ntohs(r->connection->local_addr.sin_port);
2350 + switch (r->connection->local_addr.ss_family) {
2352 + port = ntohs(((struct sockaddr_in *)
2353 + &r->connection->local_addr)->sin_port);
2357 + port = ntohs(((struct sockaddr_in6 *)
2358 + &r->connection->local_addr)->sin6_port);
2366 * This is in conjunction with the ServerPath code in http_core, so we
2367 @@ -970,10 +1187,22 @@
2368 API_EXPORT(void) ap_update_vhost_given_ip(conn_rec *conn)
2371 - unsigned port = ntohs(conn->local_addr.sin_port);
2372 + char portbuf[NI_MAXSERV];
2375 + if (getnameinfo((struct sockaddr *)&conn->local_addr,
2377 + SA_LEN((struct sockaddr *)&conn->local_addr),
2379 + conn->local_addr.ss_len,
2381 + NULL, 0, portbuf, sizeof(portbuf), NI_NUMERICSERV) != 0) {
2384 + port = atoi(portbuf);
2386 /* scan the hash table for an exact match first */
2387 - trav = find_ipaddr(&conn->local_addr.sin_addr, port);
2388 + trav = find_ipaddr((struct sockaddr *)&conn->local_addr);
2390 /* save the name_chain for later in case this is a name-vhost */
2391 conn->vhost_lookup_data = trav->names;
2392 @@ -991,6 +1220,7 @@
2397 /* otherwise we're stuck with just the main server
2398 * and no name-based vhosts
2400 diff -Nur apache_1.3.23.orig/src/main/rfc1413.c apache_1.3.23/src/main/rfc1413.c
2401 --- apache_1.3.23.orig/src/main/rfc1413.c Sun Jan 20 21:14:37 2002
2402 +++ apache_1.3.23/src/main/rfc1413.c Wed Feb 6 20:20:48 2002
2404 #include "http_log.h" /* for aplog_error */
2405 #include "rfc1413.h"
2406 #include "http_main.h" /* set_callback_and_alarm */
2407 +#include "sa_len.h"
2410 /* Semi-well-known port */
2411 @@ -109,12 +110,13 @@
2413 /* bind_connect - bind both ends of a socket */
2414 /* Ambarish fix this. Very broken */
2415 -static int get_rfc1413(int sock, const struct sockaddr_in *our_sin,
2416 - const struct sockaddr_in *rmt_sin,
2417 +static int get_rfc1413(int sock, const struct sockaddr *our_sin,
2418 + const struct sockaddr *rmt_sin,
2419 char user[RFC1413_USERLEN+1], server_rec *srv)
2421 - struct sockaddr_in rmt_query_sin, our_query_sin;
2422 - unsigned int rmt_port, our_port;
2423 + struct sockaddr_storage rmt_query_sin, our_query_sin;
2424 + unsigned int o_rmt_port, o_our_port; /* original port pair */
2425 + unsigned int rmt_port, our_port; /* replied port pair */
2428 char buffer[RFC1413_MAXDATA + 1];
2429 @@ -129,16 +131,47 @@
2430 * addresses from the query socket.
2433 - our_query_sin = *our_sin;
2434 - our_query_sin.sin_port = htons(ANY_PORT);
2436 - our_query_sin.sin_addr.s_addr = INADDR_ANY;
2438 + memcpy(&our_query_sin, our_sin, SA_LEN(our_sin));
2439 + memcpy(&rmt_query_sin, rmt_sin, SA_LEN(rmt_sin));
2441 + memcpy(&our_query_sin, our_sin, our_sin->sa_len);
2442 + memcpy(&rmt_query_sin, rmt_sin, rmt_sin->sa_len);
2444 - rmt_query_sin = *rmt_sin;
2445 - rmt_query_sin.sin_port = htons(RFC1413_PORT);
2446 + switch (our_sin->sa_family) {
2449 + ((struct sockaddr_in *)&our_query_sin)->sin_addr.s_addr = INADDR_ANY; /* XXX: htonl(??) */
2451 + ((struct sockaddr_in *)&our_query_sin)->sin_port = htons(ANY_PORT);
2452 + o_our_port = ntohs(((struct sockaddr_in *)our_sin)->sin_port);
2453 + ((struct sockaddr_in *)&rmt_query_sin)->sin_port = htons(RFC1413_PORT);
2454 + o_rmt_port = ntohs(((struct sockaddr_in *)rmt_sin)->sin_port);
2459 + memcpy(&((struct sockaddr_in6 *)&our_query_sin)->sin6_addr,
2460 + &in6addr_any, sizeof(struct in6_addr));
2462 + ((struct sockaddr_in6 *)&our_query_sin)->sin6_port = htons(ANY_PORT);
2463 + o_our_port = ntohs(((struct sockaddr_in6 *)our_sin)->sin6_port);
2464 + ((struct sockaddr_in6 *)&rmt_query_sin)->sin6_port = htons(RFC1413_PORT);
2465 + o_rmt_port = ntohs(((struct sockaddr_in6 *)rmt_sin)->sin6_port);
2469 + /* unsupported AF */
2473 if (bind(sock, (struct sockaddr *) &our_query_sin,
2474 - sizeof(struct sockaddr_in)) < 0) {
2476 + SA_LEN((struct sockaddr *) &our_query_sin)
2478 + our_query_sin.ss_len
2481 ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
2482 "bind: rfc1413: Error binding to local port");
2484 @@ -149,12 +182,18 @@
2487 if (connect(sock, (struct sockaddr *) &rmt_query_sin,
2488 - sizeof(struct sockaddr_in)) < 0)
2491 + SA_LEN((struct sockaddr *) &rmt_query_sin)
2493 + rmt_query_sin.ss_len
2500 - buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", ntohs(rmt_sin->sin_port),
2501 - ntohs(our_sin->sin_port));
2502 + buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", o_rmt_port,
2505 /* send query to server. Handle short write. */
2506 #ifdef CHARSET_EBCDIC
2508 ascii2ebcdic(buffer, buffer, (size_t)i);
2510 if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port,
2511 - user) != 3 || ntohs(rmt_sin->sin_port) != rmt_port
2512 - || ntohs(our_sin->sin_port) != our_port)
2513 + user) != 3 || o_rmt_port != rmt_port || o_our_port != our_port) {
2518 * Strip trailing carriage return. It is part of the
2521 result = FROM_UNKNOWN;
2523 - sock = ap_psocket(conn->pool, AF_INET, SOCK_STREAM, IPPROTO_TCP);
2524 + sock = ap_psocket(conn->pool, conn->remote_addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
2526 ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
2527 "socket: rfc1413: error creating socket");
2528 @@ -256,8 +295,10 @@
2529 if (ap_setjmp(timebuf) == 0) {
2530 ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout);
2532 - if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user, srv) >= 0)
2533 + if (get_rfc1413(sock, (struct sockaddr *)&conn->local_addr,
2534 + (struct sockaddr *)&conn->remote_addr, user, srv) >= 0) {
2538 ap_set_callback_and_alarm(NULL, 0);
2539 ap_pclosesocket(conn->pool, sock);
2540 diff -Nur apache_1.3.23.orig/src/main/util.c apache_1.3.23/src/main/util.c
2541 --- apache_1.3.23.orig/src/main/util.c Fri Dec 28 06:03:07 2001
2542 +++ apache_1.3.23/src/main/util.c Wed Feb 6 20:36:21 2002
2543 @@ -1962,52 +1962,87 @@
2544 * Parses a host of the form <address>[:port]
2545 * :port is permitted if 'port' is not NULL
2547 -API_EXPORT(unsigned long) ap_get_virthost_addr(char *w, unsigned short *ports)
2548 +API_EXPORT(struct sockaddr *) ap_get_virthost_addr(char *w, unsigned short *ports)
2550 - struct hostent *hep;
2551 - unsigned long my_addr;
2554 - p = strchr(w, ':');
2555 + static struct sockaddr_storage ss;
2556 + struct addrinfo hints, *res;
2561 + char servbuf[NI_MAXSERV];
2567 + if (r = strrchr(w+1, ']')){
2583 + p = strchr(w, ':');
2584 + if (p != NULL && strchr(p+1, ':') != NULL)
2587 if (ports != NULL) {
2589 - if (p != NULL && strcmp(p + 1, "*") != 0)
2590 - *ports = atoi(p + 1);
2591 + if (p != NULL && *p && strcmp(p + 1, "*") != 0)
2595 + memset(&hints, 0, sizeof(hints));
2596 + hints.ai_socktype = SOCK_STREAM;
2599 if (strcmp(w, "*") == 0) {
2602 - return htonl(INADDR_ANY);
2605 - my_addr = ap_inet_addr((char *)w);
2606 - if (my_addr != INADDR_NONE) {
2611 + hints.ai_flags = AI_PASSIVE;
2612 + hints.ai_family = ap_default_family;
2615 + hints.ai_family = PF_UNSPEC;
2618 - hep = gethostbyname(w);
2619 + error = getaddrinfo(host, port, &hints, &res);
2621 - if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
2622 - fprintf(stderr, "Cannot resolve host name %s --- exiting!\n", w);
2623 + if (error || !res) {
2624 + fprintf(stderr, "ap_get_vitrhost_addr(): getaddrinfo(%s):%s --- exiting!\n", w, gai_strerror(error));
2628 - if (hep->h_addr_list[1]) {
2629 - fprintf(stderr, "Host %s has multiple addresses ---\n", w);
2630 + if (res->ai_next) {
2631 + fprintf(stderr, "ap_get_vitrhost_addr(): Host %s has multiple addresses ---\n", w);
2632 fprintf(stderr, "you must choose one explicitly for use as\n");
2633 fprintf(stderr, "a virtual host. Exiting!!!\n");
2642 - return ((struct in_addr *) (hep->h_addr))->s_addr;
2643 + memcpy(&ss, res->ai_addr, res->ai_addrlen);
2644 + if (getnameinfo(res->ai_addr, res->ai_addrlen,
2645 + NULL, 0, servbuf, sizeof(servbuf),
2647 + fprintf(stderr, "ap_get_virthost_addr(): getnameinfo() failed --- Exiting!!!\n");
2650 + if (ports) *ports = atoi(servbuf);
2651 + freeaddrinfo(res);
2652 + return (struct sockaddr *)&ss;
2656 @@ -2035,7 +2070,8 @@
2658 char str[MAXHOSTNAMELEN];
2659 char *server_hostname = NULL;
2660 - struct hostent *p;
2661 + struct addrinfo hints, *res;
2664 #ifdef BEOS /* BeOS returns zero as an error for gethostname */
2665 if (gethostname(str, sizeof(str) - 1) == 0) {
2666 @@ -2048,29 +2084,38 @@
2670 - str[sizeof(str) - 1] = '\0';
2671 - if ((!(p = gethostbyname(str)))
2672 - || (!(server_hostname = find_fqdn(a, p)))) {
2673 - /* Recovery - return the default servername by IP: */
2674 - if (p && p->h_addr_list && p->h_addr_list[0]) {
2675 - ap_snprintf(str, sizeof(str), "%pA", p->h_addr_list[0]);
2676 - server_hostname = ap_pstrdup(a, str);
2677 - /* We will drop through to report the IP-named server */
2681 - /* Since we found a fqdn, return it with no logged message. */
2682 - return server_hostname;
2685 - /* If we don't have an fdqn or IP, fall back to the loopback addr */
2686 - if (!server_hostname)
2687 - server_hostname = ap_pstrdup(a, "127.0.0.1");
2689 - ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
2690 - "%s: Could not determine the server's fully qualified "
2691 - "domain name, using %s for ServerName",
2692 - ap_server_argv0, server_hostname);
2693 + str[sizeof(str) - 1] = '\0';
2694 + memset(&hints, 0, sizeof(hints));
2695 + hints.ai_family = PF_UNSPEC;
2696 + hints.ai_flags = AI_CANONNAME;
2697 + error = getaddrinfo(str, NULL, &hints, &res);
2700 + /* Recovery - return the default servername by IP: */
2702 + fprintf(stderr, "%s: cannot determine local host name.\n",
2704 + fprintf(stderr, "Use the ServerName directive to set it manually.\n");
2707 + server_hostname = ap_pstrdup(a, res->ai_canonname);
2709 + else if (1) /*fqdn found*/
2711 + /* XXX should check more conditions */
2712 + server_hostname = ap_pstrdup(a, res->ai_canonname);
2716 + ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
2717 + "%s: Could not determine the server's fully qualified "
2718 + "domain name, using %s for ServerName",
2719 + ap_server_argv0, server_hostname);
2722 + /* Since we found a fdqn, return it with no logged message. */
2723 + freeaddrinfo(res);
2726 return server_hostname;
2728 @@ -2149,7 +2194,7 @@
2729 char *quote_doubled_str, *dest;
2732 - num_quotes += str[len++] == '\"';
2733 + num_quotes += str[len++] == '\"';
2736 quote_doubled_str = ap_palloc(p, len + num_quotes + 1);
2737 @@ -2274,3 +2319,11 @@
2742 +#ifdef NEED_GETADDRINFO
2743 +#include "getaddrinfo.c"
2746 +#ifdef NEED_GETNAMEINFO
2747 +#include "getnameinfo.c"
2749 diff -Nur apache_1.3.23.orig/src/main/util_script.c apache_1.3.23/src/main/util_script.c
2750 --- apache_1.3.23.orig/src/main/util_script.c Fri Oct 12 01:37:39 2001
2751 +++ apache_1.3.23/src/main/util_script.c Wed Feb 6 20:20:48 2002
2753 #include "http_request.h" /* for sub_req_lookup_uri() */
2754 #include "util_script.h"
2755 #include "util_date.h" /* For parseHTTPdate() */
2756 +#include "sa_len.h"
2761 array_header *hdrs_arr = ap_table_elts(r->headers_in);
2762 table_entry *hdrs = (table_entry *) hdrs_arr->elts;
2764 + char servbuf[NI_MAXSERV];
2766 /* use a temporary table which we'll overlap onto
2767 * r->subprocess_env later
2768 @@ -298,8 +300,16 @@
2769 ap_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
2770 ap_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */
2772 - ap_table_addn(e, "REMOTE_PORT",
2773 - ap_psprintf(r->pool, "%d", ntohs(c->remote_addr.sin_port)));
2774 + servbuf[0] = '\0';
2775 + if (!getnameinfo((struct sockaddr *)&c->remote_addr,
2776 +#ifndef HAVE_SOCKADDR_LEN
2777 + SA_LEN((struct sockaddr *)&c->remote_addr),
2779 + c->remote_addr.ss_len,
2781 + NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)){
2782 + ap_table_addn(e, "REMOTE_PORT", ap_pstrdup(r->pool, servbuf));
2786 ap_table_addn(e, "REMOTE_USER", c->user);
2787 diff -Nur apache_1.3.23.orig/src/main/util_uri.c apache_1.3.23/src/main/util_uri.c
2788 --- apache_1.3.23.orig/src/main/util_uri.c Sun Jan 20 21:14:37 2002
2789 +++ apache_1.3.23/src/main/util_uri.c Wed Feb 6 20:20:48 2002
2790 @@ -419,6 +419,12 @@
2791 * the hostname. If there's a port it is the first colon.
2793 s = memchr(hostinfo, ':', uri - hostinfo);
2794 + if (*hostinfo == '[') {
2795 + s = memchr(hostinfo+1, ']', uri - hostinfo - 1);
2797 + s = strchr(s, ':');
2799 + s = memchr(hostinfo, ':', uri - hostinfo);
2801 /* we expect the common case to have no port */
2802 uptr->hostname = ap_pstrndup(p, hostinfo, uri - hostinfo);
2803 @@ -475,7 +481,12 @@
2804 /* We expect hostinfo to point to the first character of
2805 * the hostname. There must be a port, separated by a colon
2807 - s = strchr(hostinfo, ':');
2808 + if (*hostinfo == '[') {
2809 + s = strchr(hostinfo+1, ']');
2811 + s = strchr(s, ':');
2813 + s = strchr(hostinfo, ':');
2815 return HTTP_BAD_REQUEST;
2817 diff -Nur apache_1.3.23.orig/src/modules/proxy/mod_proxy.c apache_1.3.23/src/modules/proxy/mod_proxy.c
2818 --- apache_1.3.23.orig/src/modules/proxy/mod_proxy.c Wed Feb 6 20:17:43 2002
2819 +++ apache_1.3.23/src/modules/proxy/mod_proxy.c Wed Feb 6 20:38:49 2002
2820 @@ -556,11 +556,31 @@
2821 struct proxy_remote *new;
2824 + char *bl = NULL, *br = NULL;
2827 if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0')
2828 return "ProxyRemote: Bad syntax for a remote proxy server";
2829 - q = strchr(p + 3, ':');
2832 + br = strrchr(bl+1, ']');
2836 + if (*(br+1) == ':'){ /* [host]:xx */
2839 + else if (*(br+1) == '\0'){ /* [host] */
2843 + q = strrchr(br, ':'); /* XXX */
2846 + q = strrchr(bl, ':'); /* XXX */
2849 + q = strrchr(bl, ':');
2851 if (sscanf(q + 1, "%u", &port) != 1 || port > 65535)
2852 return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)";
2855 if (strchr(f, ':') == NULL)
2856 ap_str_tolower(f); /* lowercase scheme */
2857 - ap_str_tolower(p + 3); /* lowercase hostname */
2858 + ap_str_tolower(bl); /* lowercase hostname */
2863 new = ap_push_array(conf->proxies);
2866 - new->hostname = p + 3;
2867 + new->hostname = bl;
2871 diff -Nur apache_1.3.23.orig/src/modules/proxy/mod_proxy.h apache_1.3.23/src/modules/proxy/mod_proxy.h
2872 --- apache_1.3.23.orig/src/modules/proxy/mod_proxy.h Fri Jan 18 21:26:58 2002
2873 +++ apache_1.3.23/src/modules/proxy/mod_proxy.h Wed Feb 6 20:20:48 2002
2875 int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p);
2876 int ap_proxy_is_hostname(struct dirconn_entry *This, pool *p);
2877 int ap_proxy_is_word(struct dirconn_entry *This, pool *p);
2878 -int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
2879 +int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r);
2880 int ap_proxy_garbage_init(server_rec *, pool *);
2881 /* This function is called by ap_table_do() for all header lines */
2882 int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
2883 diff -Nur apache_1.3.23.orig/src/modules/proxy/mod_proxy.h.orig apache_1.3.23/src/modules/proxy/mod_proxy.h.orig
2884 --- apache_1.3.23.orig/src/modules/proxy/mod_proxy.h.orig Thu Jan 1 01:00:00 1970
2885 +++ apache_1.3.23/src/modules/proxy/mod_proxy.h.orig Fri Jan 18 21:26:58 2002
2887 +/* ====================================================================
2888 + * The Apache Software License, Version 1.1
2890 + * Copyright (c) 2000 The Apache Software Foundation. All rights
2893 + * Redistribution and use in source and binary forms, with or without
2894 + * modification, are permitted provided that the following conditions
2897 + * 1. Redistributions of source code must retain the above copyright
2898 + * notice, this list of conditions and the following disclaimer.
2900 + * 2. Redistributions in binary form must reproduce the above copyright
2901 + * notice, this list of conditions and the following disclaimer in
2902 + * the documentation and/or other materials provided with the
2905 + * 3. The end-user documentation included with the redistribution,
2906 + * if any, must include the following acknowledgment:
2907 + * "This product includes software developed by the
2908 + * Apache Software Foundation (http://www.apache.org/)."
2909 + * Alternately, this acknowledgment may appear in the software itself,
2910 + * if and wherever such third-party acknowledgments normally appear.
2912 + * 4. The names "Apache" and "Apache Software Foundation" must
2913 + * not be used to endorse or promote products derived from this
2914 + * software without prior written permission. For written
2915 + * permission, please contact apache@apache.org.
2917 + * 5. Products derived from this software may not be called "Apache",
2918 + * nor may "Apache" appear in their name, without prior written
2919 + * permission of the Apache Software Foundation.
2921 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
2922 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2923 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2924 + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
2925 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2926 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2927 + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2928 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2929 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2930 + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
2931 + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2933 + * ====================================================================
2935 + * This software consists of voluntary contributions made by many
2936 + * individuals on behalf of the Apache Software Foundation. For more
2937 + * information on the Apache Software Foundation, please see
2938 + * <http://www.apache.org/>.
2940 + * Portions of this software are based upon public domain software
2941 + * originally written at the National Center for Supercomputing Applications,
2942 + * University of Illinois, Urbana-Champaign.
2945 +#ifndef MOD_PROXY_H
2946 +#define MOD_PROXY_H
2949 + * Main include file for the Apache proxy
2954 + Note numerous FIXMEs and CHECKMEs which should be eliminated.
2956 + If TESTING is set, then garbage collection doesn't delete ... probably a good
2957 + idea when hacking.
2964 +#include "http_config.h"
2965 +#include "http_protocol.h"
2967 +#include "explain.h"
2969 +extern module MODULE_VAR_EXPORT proxy_module;
2972 +/* for proxy_canonenc() */
2974 + enc_path, enc_search, enc_user, enc_fpath, enc_parm
2977 +#define HDR_APP (0) /* append header, for proxy_add_header() */
2978 +#define HDR_REP (1) /* replace header, for proxy_add_header() */
2980 +/* number of characters in the hash */
2981 +#define HASH_LEN (22*2)
2983 +/* maximum 'CacheDirLevels*CacheDirLength' value */
2984 +#define CACHEFILE_LEN 20 /* must be less than HASH_LEN/2 */
2986 +#define SEC_ONE_DAY 86400 /* one day, in seconds */
2987 +#define SEC_ONE_HR 3600 /* one hour, in seconds */
2989 +#define DEFAULT_FTP_DATA_PORT 20
2990 +#define DEFAULT_FTP_PORT 21
2991 +#define DEFAULT_GOPHER_PORT 70
2992 +#define DEFAULT_NNTP_PORT 119
2993 +#define DEFAULT_WAIS_PORT 210
2994 +#define DEFAULT_HTTPS_PORT 443
2995 +#define DEFAULT_SNEWS_PORT 563
2996 +#define DEFAULT_PROSPERO_PORT 1525 /* WARNING: conflict w/Oracle */
2998 +/* Some WWW schemes and their default ports; this is basically /etc/services */
2999 +struct proxy_services {
3000 + const char *scheme;
3004 +/* static information about a remote proxy */
3005 +struct proxy_remote {
3006 + const char *scheme; /* the schemes handled by this proxy, or '*' */
3007 + const char *protocol; /* the scheme used to talk to this proxy */
3008 + const char *hostname; /* the hostname of this proxy */
3009 + int port; /* the port for this proxy */
3012 +struct proxy_alias {
3017 +struct dirconn_entry {
3019 + struct in_addr addr, mask;
3020 + struct hostent *hostentry;
3021 + int (*matcher) (struct dirconn_entry * This, request_rec *r);
3024 +struct noproxy_entry {
3026 + struct in_addr addr;
3029 +struct nocache_entry {
3031 + struct in_addr addr;
3034 +#define DEFAULT_CACHE_SPACE 5
3035 +#define DEFAULT_CACHE_MAXEXPIRE SEC_ONE_DAY
3036 +#define DEFAULT_CACHE_EXPIRE SEC_ONE_HR
3037 +#define DEFAULT_CACHE_LMFACTOR (0.1)
3038 +#define DEFAULT_CACHE_COMPLETION (0.9)
3039 +#define DEFAULT_CACHE_GCINTERVAL SEC_ONE_HR
3042 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
3045 +#define MIN(a,b) ((a) < (b) ? (a) : (b))
3048 +/* static information about the local cache */
3049 +struct cache_conf {
3050 + const char *root; /* the location of the cache directory */
3051 + off_t space; /* Maximum cache size (in 1024 bytes) */
3053 + time_t maxexpire; /* Maximum time to keep cached files in secs */
3054 + char maxexpire_set;
3055 + time_t defaultexpire; /* default time to keep cached file in secs */
3056 + char defaultexpire_set;
3057 + double lmfactor; /* factor for estimating expires date */
3058 + char lmfactor_set;
3059 + time_t gcinterval; /* garbage collection interval, in seconds */
3060 + char gcinterval_set;
3061 + int dirlevels; /* Number of levels of subdirectories */
3062 + char dirlevels_set;
3063 + int dirlength; /* Length of subdirectory names */
3064 + char dirlength_set;
3065 + float cache_completion; /* Force cache completion after this point */
3066 + char cache_completion_set;
3070 + struct cache_conf cache; /* cache configuration */
3071 + array_header *proxies;
3072 + array_header *aliases;
3073 + array_header *raliases;
3074 + array_header *noproxies;
3075 + array_header *dirconn;
3076 + array_header *nocaches;
3077 + array_header *allowed_connect_ports;
3078 + char *domain; /* domain name to use in absence of a domain name in the request */
3079 + int req; /* true if proxy requests are enabled */
3086 + } viaopt; /* how to deal with proxy Via: headers */
3088 + size_t recv_buffer_size;
3089 + char recv_buffer_size_set;
3090 +} proxy_server_conf;
3093 + const char *field;
3094 + const char *value;
3097 +/* caching information about a request */
3099 + request_rec *req; /* the request */
3100 + char *url; /* the URL requested */
3101 + char *filename; /* name of the cache file,
3102 + or NULL if no cache */
3103 + char *tempfile; /* name of the temporary file,
3104 + or NULL if not caching */
3105 + time_t ims; /* if-Modified-Since date of request,
3106 + -1 if no header */
3107 + time_t ius; /* if-Unmodified-Since date of request,
3108 + -1 if no header */
3109 + const char *im; /* if-Match etag of request,
3110 + NULL if no header */
3111 + const char *inm; /* if-None-Match etag of request,
3112 + NULL if no header */
3113 + BUFF *fp; /* the cache file descriptor if the file
3114 + is cached and may be returned,
3115 + or NULL if the file is not cached
3116 + (or must be reloaded) */
3117 + BUFF *origfp; /* the old cache file descriptor if the file has
3118 + been revalidated and is being rewritten to
3120 + time_t expire; /* calculated expire date of cached entity */
3121 + time_t lmod; /* last-modified date of cached entity */
3122 + time_t date; /* the date the cached file was last touched */
3123 + time_t req_time; /* the time the request started */
3124 + time_t resp_time; /* the time the response was received */
3125 + int version; /* update count of the file */
3126 + off_t len; /* content length */
3127 + char *protocol; /* Protocol, and major/minor number,
3129 + int status; /* the status of the cached file */
3130 + unsigned int written; /* total *content* bytes written to cache */
3131 + float cache_completion; /* specific to this request */
3132 + char *resp_line; /* the whole status line
3133 + (protocol, code + message) */
3134 + table *req_hdrs; /* the original request headers */
3135 + table *hdrs; /* the original HTTP response headers
3137 + char *xcache; /* the X-Cache header value
3138 + to be sent to client */
3141 +struct per_thread_data {
3142 + struct hostent hpbuf;
3144 + char *charpbuf[2];
3146 +/* Function prototypes */
3148 +/* proxy_cache.c */
3150 +void ap_proxy_cache_tidy(cache_req *c);
3151 +int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf *conf,
3153 +int ap_proxy_cache_update(cache_req *c, table *resp_hdrs,
3154 + const int is_HTTP1, int nocache);
3155 +void ap_proxy_garbage_coll(request_rec *r);
3157 +/* proxy_connect.c */
3159 +int ap_proxy_connect_handler(request_rec *r, cache_req *c, char *url,
3160 + const char *proxyhost, int proxyport);
3164 +int ap_proxy_ftp_canon(request_rec *r, char *url);
3165 +int ap_proxy_ftp_handler(request_rec *r, cache_req *c, char *url);
3169 +int ap_proxy_http_canon(request_rec *r, char *url, const char *scheme,
3171 +int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url,
3172 + const char *proxyhost, int proxyport);
3176 +int ap_proxy_hex2c(const char *x);
3177 +void ap_proxy_c2hex(int ch, char *x);
3178 +char *ap_proxy_canonenc(pool *p, const char *x, int len, enum enctype t,
3179 + enum proxyreqtype isenc);
3180 +char *ap_proxy_canon_netloc(pool *p, char **const urlp, char **userp,
3181 + char **passwordp, char **hostp, int *port);
3182 +const char *ap_proxy_date_canon(pool *p, const char *x);
3183 +table *ap_proxy_read_headers(request_rec *r, char *buffer, int size, BUFF *f);
3184 +long int ap_proxy_send_fb(BUFF *f, request_rec *r, cache_req *c, off_t len, int nowrite);
3185 +void ap_proxy_write_headers(cache_req *c, const char *respline, table *t);
3186 +int ap_proxy_liststr(const char *list, const char *key, char **val);
3187 +void ap_proxy_hash(const char *it, char *val, int ndepth, int nlength);
3188 +int ap_proxy_hex2sec(const char *x);
3189 +void ap_proxy_sec2hex(int t, char *y);
3190 +cache_req *ap_proxy_cache_error(cache_req *r);
3191 +int ap_proxyerror(request_rec *r, int statuscode, const char *message);
3192 +const char *ap_proxy_host2addr(const char *host, struct hostent *reqhp);
3193 +int ap_proxy_is_ipaddr(struct dirconn_entry *This, pool *p);
3194 +int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p);
3195 +int ap_proxy_is_hostname(struct dirconn_entry *This, pool *p);
3196 +int ap_proxy_is_word(struct dirconn_entry *This, pool *p);
3197 +int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
3198 +int ap_proxy_garbage_init(server_rec *, pool *);
3199 +/* This function is called by ap_table_do() for all header lines */
3200 +int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
3201 +unsigned ap_proxy_bputs2(const char *data, BUFF *client, cache_req *cache);
3202 +time_t ap_proxy_current_age(cache_req *c, const time_t age_value);
3203 +BUFF *ap_proxy_open_cachefile(request_rec *r, char *filename);
3204 +BUFF *ap_proxy_create_cachefile(request_rec *r, char *filename);
3205 +void ap_proxy_clear_connection(pool *p, table *headers);
3206 +int ap_proxy_table_replace(table *base, table *overlay);
3208 +/* WARNING - PRIVATE DEFINITION BELOW */
3210 +/* XXX: if you tweak this you should look at is_empty_table() and table_elts()
3213 + * NOTE: this private definition is a duplicate of the one in alloc.c
3214 + * It's here for ap_proxy_table_replace() to avoid breaking binary compat
3217 + /* This has to be first to promote backwards compatibility with
3218 + * older modules which cast a table * to an array_header *...
3219 + * they should use the table_elts() function for most of the
3220 + * cases they do this for.
3223 +#ifdef MAKE_TABLE_PROFILE
3228 +#endif /*MOD_PROXY_H*/
3229 diff -Nur apache_1.3.23.orig/src/modules/proxy/proxy_connect.c apache_1.3.23/src/modules/proxy/proxy_connect.c
3230 --- apache_1.3.23.orig/src/modules/proxy/proxy_connect.c Sun Jan 20 21:14:37 2002
3231 +++ apache_1.3.23/src/modules/proxy/proxy_connect.c Wed Feb 6 20:49:52 2002
3232 @@ -114,14 +114,15 @@
3233 const char *proxyhost, int proxyport)
3235 struct sockaddr_in server;
3236 - struct in_addr destaddr;
3237 - struct hostent server_hp;
3238 - const char *host, *err;
3239 + struct addrinfo hints, *res, *res0;
3240 + const char *hoststr;
3241 + const char *portstr = NULL;
3244 char buffer[HUGE_STRING_LEN];
3250 void *sconf = r->server->module_config;
3251 proxy_server_conf *conf =
3252 @@ -129,27 +130,59 @@
3253 struct noproxy_entry *npent = (struct noproxy_entry *)conf->noproxies->elts;
3255 memset(&server, '\0', sizeof(server));
3256 +#ifdef HAVE_SOCKADDR_LEN
3257 + server.sin_len = sizeof(server);
3259 server.sin_family = AF_INET;
3261 /* Break the URL into host:port pairs */
3265 p = strchr(url, ':');
3267 - port = DEFAULT_HTTPS_PORT;
3269 - port = atoi(p + 1);
3272 + ap_snprintf(pbuf, sizeof(pbuf), "%d", DEFAULT_HTTPS_PORT);
3278 + port = atoi(portstr);
3280 + memset(&hints, 0, sizeof(hints));
3281 + hints.ai_family = PF_UNSPEC;
3282 + hints.ai_socktype = SOCK_STREAM;
3283 + hints.ai_protocol = IPPROTO_TCP;
3284 + error = getaddrinfo(hoststr, portstr, &hints, &res0);
3286 + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3287 + gai_strerror(error)); /* give up */
3290 /* check if ProxyBlock directive on this host */
3291 - destaddr.s_addr = ap_inet_addr(host);
3292 - for (i = 0; i < conf->noproxies->nelts; i++) {
3293 - if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL)
3294 - || destaddr.s_addr == npent[i].addr.s_addr
3295 - || npent[i].name[0] == '*')
3296 + for (res = res0; res; res = res = res->ai_next) {
3297 + struct sockaddr_in *sin;
3301 + for (i = 0; i < conf->noproxies->nelts; i++) {
3302 + if (npent[i].name != NULL && strstr(hoststr, npent[i].name))
3304 + if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
3306 + switch (res->ai_family) {
3308 + sin = (struct sockaddr_in *)res->ai_addr;
3309 + if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
3315 + freeaddrinfo(res0);
3316 return ap_proxyerror(r, HTTP_FORBIDDEN,
3317 "Connect to remote machine blocked");
3321 /* Check if it is an allowed port */
3322 @@ -160,33 +193,41 @@
3323 case DEFAULT_SNEWS_PORT:
3326 + freeaddrinfo(res0);
3327 return HTTP_FORBIDDEN;
3329 - } else if(!allowed_port(conf, port))
3330 + } else if(!allowed_port(conf, port)) {
3331 + freeaddrinfo(res0);
3332 return HTTP_FORBIDDEN;
3338 + freeaddrinfo(res0);
3340 + ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
3341 + memset(&hints, 0, sizeof(hints));
3342 + hints.ai_family = PF_UNSPEC;
3343 + hints.ai_socktype = SOCK_STREAM;
3344 + hints.ai_protocol = IPPROTO_TCP;
3345 + error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
3347 + return HTTP_INTERNAL_SERVER_ERROR; /* XXX */
3349 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
3350 "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
3353 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server,
3354 - "CONNECT to %s on port %d", host, port);
3355 + "CONNECT to %s on port %d", hoststr, port);
3358 - /* Nasty cast to work around broken terniary expressions on MSVC */
3359 - server.sin_port = htons((unsigned short)(proxyport ? proxyport : port));
3360 - err = ap_proxy_host2addr(proxyhost ? proxyhost : host, &server_hp);
3363 - return ap_proxyerror(r,
3364 - proxyhost ? HTTP_BAD_GATEWAY : HTTP_INTERNAL_SERVER_ERROR, err);
3366 - sock = ap_psocket(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP);
3368 - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "proxy: error creating socket");
3369 - return HTTP_INTERNAL_SERVER_ERROR;
3372 + for (res = res0; res; res = res->ai_next) {
3373 + sock = ap_psocket(r->pool, res->ai_family, res->ai_socktype, res->ai_protocol);
3377 #ifdef CHECK_FD_SETSIZE
3378 if (sock >= FD_SETSIZE) {
3379 @@ -196,19 +237,15 @@
3380 "found, you probably need to rebuild Apache with a "
3381 "larger FD_SETSIZE", sock, FD_SETSIZE);
3382 ap_pclosesocket(r->pool, sock);
3383 - return HTTP_INTERNAL_SERVER_ERROR;
3389 - while (server_hp.h_addr_list[j] != NULL) {
3390 - memcpy(&server.sin_addr, server_hp.h_addr_list[j],
3391 - sizeof(struct in_addr));
3392 - i = ap_proxy_doconnect(sock, &server, r);
3393 + i = ap_proxy_doconnect(sock, res->ai_addr, r);
3398 + freeaddrinfo(res0);
3400 ap_pclosesocket(r->pool, sock);
3401 return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, ap_pstrcat(r->pool,
3402 diff -Nur apache_1.3.23.orig/src/modules/proxy/proxy_ftp.c apache_1.3.23/src/modules/proxy/proxy_ftp.c
3403 --- apache_1.3.23.orig/src/modules/proxy/proxy_ftp.c Sun Jan 20 21:14:37 2002
3404 +++ apache_1.3.23/src/modules/proxy/proxy_ftp.c Wed Feb 6 21:08:39 2002
3406 #include "http_main.h"
3407 #include "http_log.h"
3408 #include "http_core.h"
3409 +#include "sa_len.h"
3411 #define AUTODETECT_PWD
3413 @@ -451,8 +452,10 @@
3415 int port, i, j, len, sock, dsock, rc, nocache = 0;
3417 - struct sockaddr_in server;
3418 - struct hostent server_hp;
3419 + struct sockaddr_storage server;
3420 + struct addrinfo hints, *res, *res0;
3423 struct in_addr destaddr;
3426 @@ -471,11 +474,18 @@
3427 unsigned int presult, h0, h1, h2, h3, p0, p1;
3429 unsigned short pport;
3430 - struct sockaddr_in data_addr;
3431 + struct sockaddr_storage data_addr;
3432 + struct sockaddr_in *sin;
3437 +/* stuff for LPSV/EPSV */
3438 + unsigned int paf, holen, ho[16], polen, po[2];
3439 + struct sockaddr_in6 *sin6;
3443 /* stuff for responses */
3444 char resp[MAX_STRING_LEN];
3446 @@ -545,62 +555,52 @@
3450 - memset(&server, 0, sizeof(struct sockaddr_in));
3451 - server.sin_family = AF_INET;
3452 - server.sin_port = htons((unsigned short)port);
3453 - err = ap_proxy_host2addr(host, &server_hp);
3455 - return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
3457 - sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
3459 - ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3460 - "proxy: error creating socket");
3461 - return HTTP_INTERNAL_SERVER_ERROR;
3463 + ap_snprintf(portbuf, sizeof(portbuf), "%d", port);
3464 + memset(&hints, 0, sizeof(hints));
3465 + hints.ai_family = PF_UNSPEC;
3466 + hints.ai_socktype = SOCK_STREAM;
3467 + error = getaddrinfo(host, portbuf, &hints, &res0);
3469 + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3470 + gai_strerror(error));
3474 + for (res = res0; res; res = res->ai_next) {
3475 + sock = ap_psocket(p, res->ai_family, res->ai_socktype,
3476 + res->ai_protocol);
3480 #if !defined(TPF) && !defined(BEOS)
3481 - if (conf->recv_buffer_size > 0
3482 - && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
3483 - (const char *) &conf->recv_buffer_size, sizeof(int))
3485 - ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3486 - "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
3488 + if (conf->recv_buffer_size > 0
3489 + && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
3490 + (const char *) &conf->recv_buffer_size, sizeof(int))
3492 + ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3493 + "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
3497 - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &one,
3498 - sizeof(one)) == -1) {
3499 + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &one,
3500 + sizeof(one)) == -1) {
3501 #ifndef _OSD_POSIX /* BS2000 has this option "always on" */
3502 - ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3503 - "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
3504 - ap_pclosesocket(p, sock);
3505 - return HTTP_INTERNAL_SERVER_ERROR;
3506 + ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3507 + "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
3508 + ap_pclosesocket(p, sock);
3509 + freeaddrinfo(res0);
3510 + return HTTP_INTERNAL_SERVER_ERROR;
3511 #endif /*_OSD_POSIX*/
3514 -#ifdef SINIX_D_RESOLVER_BUG
3516 - struct in_addr *ip_addr = (struct in_addr *) *server_hp.h_addr_list;
3518 - for (; ip_addr->s_addr != 0; ++ip_addr) {
3519 - memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
3520 - i = ap_proxy_doconnect(sock, &server, r);
3527 - while (server_hp.h_addr_list[j] != NULL) {
3528 - memcpy(&server.sin_addr, server_hp.h_addr_list[j],
3529 - sizeof(struct in_addr));
3530 - i = ap_proxy_doconnect(sock, &server, r);
3533 + i = ap_proxy_doconnect(sock, res->ai_addr, r);
3535 + memcpy(&server, res->ai_addr, res->ai_addrlen);
3539 + ap_pclosesocket(p, sock);
3542 + freeaddrinfo(res0);
3544 ap_pclosesocket(p, sock);
3545 return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool,
3549 /* try to set up PASV data connection first */
3550 - dsock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
3551 + dsock = ap_psocket(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP);
3553 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3554 "proxy: error creating PASV socket");
3555 @@ -826,11 +826,22 @@
3559 - ap_bputs("PASV" CRLF, f);
3561 + if (server.ss_family == AF_INET)
3563 + else if (lpsvmode)
3568 + ap_bputs(CRLF, f);
3570 + Explain0("FTP: passive command issued");
3571 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: PASV command issued");
3572 -/* possible results: 227, 421, 500, 501, 502, 530 */
3573 + /* possible results: 227, 228, 229, 421, 500, 501, 502, 530 */
3574 /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */
3575 + /* 228 Entering Long Passive Mode (...). */
3576 + /* 229 Entering Extended Passive Mode (...). */
3577 /* 421 Service not available, closing control connection. */
3578 /* 500 Syntax error, command unrecognized. */
3579 /* 501 Syntax error in parameters or arguments. */
3581 i = ap_bgets(pasv, sizeof(pasv), f);
3583 ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r,
3584 - "PASV: control connection is toast");
3585 + "%s: control connection is toast", cmd);
3586 ap_pclosesocket(p, dsock);
3589 @@ -871,10 +882,14 @@
3590 pport = (p1 << 8) + p0;
3591 ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, r->server, "FTP: contacting host %d.%d.%d.%d:%d",
3592 h3, h2, h1, h0, pport);
3593 - data_addr.sin_family = AF_INET;
3594 - data_addr.sin_addr.s_addr = htonl(paddr);
3595 - data_addr.sin_port = htons(pport);
3596 - i = ap_proxy_doconnect(dsock, &data_addr, r);
3597 + sin = (struct sockaddr_in *)&data_addr;
3598 + sin->sin_family = AF_INET;
3600 + sin->sin_len = sizeof(*sin);
3602 + sin->sin_addr.s_addr = htonl(paddr);
3603 + sin->sin_port = htons(pport);
3604 + i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
3608 @@ -886,13 +901,73 @@
3612 + } else if (presult == 228 && pstr != NULL
3614 +"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
3615 + &paf, &holen, &ho[0], &ho[1], &ho[2], &ho[3],
3616 + &ho[4], &ho[5], &ho[6], &ho[7], &ho[8], &ho[9], &ho[10], &ho[11],
3617 + &ho[12], &ho[13], &ho[14], &ho[15], &polen, &po[0], &po[1]) == 21
3618 + && paf == 6 && holen == 16 && polen == 2) {
3620 + sin6 = (struct sockaddr_in6 *)&data_addr;
3621 + sin6->sin6_family = AF_INET6;
3623 + sin6->sin6_len = sizeof(*sin6);
3625 + for (i = 0; i < 16; i++)
3626 + sin6->sin6_addr.s6_addr[i] = ho[i] & 0xff;
3627 + sin6->sin6_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
3628 + i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
3631 + ap_kill_timeout(r);
3632 + return ap_proxyerror(r, HTTP_BAD_GATEWAY,
3633 + ap_pstrcat(r->pool,
3634 + "Could not connect to remote machine: ",
3635 + strerror(errno), NULL));
3639 + } else if (presult == 229 && pstr != NULL
3640 + && pstr[0] == pstr[1] && pstr[0] == pstr[2]
3641 + && pstr[0] == pstr[strlen(pstr) - 1]) {
3642 + /* expect "|||port|" */
3644 + memcpy(&data_addr, &server, SA_LEN((struct sockaddr *)&server));
3646 + memcpy(&data_addr, &server, server.ss_len);
3648 + switch (data_addr.ss_family) {
3650 + sin = (struct sockaddr_in *)&data_addr;
3651 + sin->sin_port = htons(atoi(pstr + 3));
3654 + sin6 = (struct sockaddr_in6 *)&data_addr;
3655 + sin6->sin6_port = htons(atoi(pstr + 3));
3658 + i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
3661 + ap_kill_timeout(r);
3662 + return ap_proxyerror(r, HTTP_BAD_GATEWAY,
3663 + ap_pstrcat(r->pool,
3664 + "Could not connect to remote machine: ",
3665 + strerror(errno), NULL));
3669 + } else if (!lpsvmode && strcmp(cmd, "EPSV") == 0) {
3674 ap_pclosesocket(p, dsock); /* and try the regular way */
3677 if (!pasvmode) { /* set up data connection */
3678 - clen = sizeof(struct sockaddr_in);
3679 + clen = sizeof(server);
3680 if (getsockname(sock, (struct sockaddr *) &server, &clen) < 0) {
3681 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3682 "proxy: error getting socket address");
3684 return HTTP_INTERNAL_SERVER_ERROR;
3687 - dsock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
3688 + dsock = ap_psocket(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP);
3690 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3691 "proxy: error creating socket");
3692 @@ -922,13 +997,26 @@
3693 #endif /*_OSD_POSIX*/
3696 - if (bind(dsock, (struct sockaddr *) &server,
3697 - sizeof(struct sockaddr_in)) == -1) {
3700 + if (bind(dsock, (struct sockaddr *) &server, SA_LEN((struct sockaddr *)&server)) == -1)
3702 + if (bind(dsock, (struct sockaddr *) &server, server.ss_len) == -1)
3705 + char hostnamebuf[MAXHOSTNAMELEN], portnamebuf[MAXHOSTNAMELEN];
3707 + getnameinfo((struct sockaddr *)&server,
3709 + SA_LEN((struct sockaddr *)&server),
3713 + hostnamebuf, sizeof(hostnamebuf),
3714 + portnamebuf, sizeof(portnamebuf),
3715 + NI_NUMERICHOST | NI_NUMERICSERV);
3716 - ap_snprintf(buff, sizeof(buff), "%s:%d", inet_ntoa(server.sin_addr), server.sin_port);
3717 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3718 - "proxy: error binding to ftp data socket %s", buff);
3719 + "proxy: error binding to ftp data socket %s:%s",
3720 + hostnamebuf, portnamebuf);
3722 ap_pclosesocket(p, dsock);
3723 return HTTP_INTERNAL_SERVER_ERROR;
3724 @@ -1187,7 +1276,7 @@
3726 if (!pasvmode) { /* wait for connection */
3727 ap_hard_timeout("proxy ftp data connect", r);
3728 - clen = sizeof(struct sockaddr_in);
3729 + clen = sizeof(server);
3731 csd = accept(dsock, (struct sockaddr *) &server, &clen);
3732 while (csd == -1 && errno == EINTR);
3733 diff -Nur apache_1.3.23.orig/src/modules/proxy/proxy_http.c apache_1.3.23/src/modules/proxy/proxy_http.c
3734 --- apache_1.3.23.orig/src/modules/proxy/proxy_http.c Wed Feb 6 20:17:43 2002
3735 +++ apache_1.3.23/src/modules/proxy/proxy_http.c Wed Feb 6 21:18:32 2002
3737 table *req_hdrs, *resp_hdrs;
3738 array_header *reqhdrs_arr;
3739 table_entry *reqhdrs_elts;
3740 - struct sockaddr_in server;
3741 - struct in_addr destaddr;
3742 - struct hostent server_hp;
3743 + struct addrinfo hints, *res, *res0;
3746 char buffer[HUGE_STRING_LEN];
3750 if (conf->cache.root == NULL) nocache = 1;
3752 - memset(&server, '\0', sizeof(server));
3753 - server.sin_family = AF_INET;
3755 /* We break the URL into host, port, path-search */
3757 urlptr = strstr(url, "://");
3759 return HTTP_BAD_REQUEST;
3761 destport = DEFAULT_HTTP_PORT;
3762 + ap_snprintf(portstr, sizeof(portstr), "%d", DEFAULT_HTTP_PORT);
3763 + destportstr = portstr;
3765 ap_hook_use("ap::mod_proxy::http::handler::set_destport",
3766 AP_HOOK_SIG2(int,ptr),
3767 @@ -207,7 +205,20 @@
3772 + if (*desthost == '['){
3773 + char *u = strrchr(desthost+1, ']');
3777 + if (*(u+1) == ':'){ /* [host]:xx */
3779 + } else if (*(u+1) == '\0'){ /* [host] */
3782 + return HTTP_BAD_REQUEST;
3784 + return HTTP_BAD_REQUEST;
3786 strp2 = strchr(desthost, ':');
3787 if (strp2 != NULL) {
3789 @@ -218,45 +229,69 @@
3792 /* check if ProxyBlock directive on this host */
3793 - destaddr.s_addr = ap_inet_addr(desthost);
3794 - for (i = 0; i < conf->noproxies->nelts; i++) {
3795 - if (destaddr.s_addr == npent[i].addr.s_addr ||
3796 - (npent[i].name != NULL &&
3797 - (npent[i].name[0] == '*' || strstr(desthost, npent[i].name) != NULL)))
3798 + memset(&hints, 0, sizeof(hints));
3799 + hints.ai_family = PF_UNSPEC;
3800 + hints.ai_socktype = SOCK_STREAM;
3801 + hints.ai_protocol = IPPROTO_TCP;
3802 + error = getaddrinfo(desthost, destportstr, &hints, &res0);
3804 + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3805 + gai_strerror(error)); /* give up */
3808 + /* check if ProxyBlock directive on this host */
3809 + for (res = res0; res; res = res->ai_next) {
3810 + struct sockaddr_in *sin;
3812 + struct sockaddr_in6 *sin6;
3817 + for (i = 0; i < conf->noproxies->nelts; i++) {
3818 + if (npent[i].name != NULL && strstr(desthost, npent[i].name))
3820 + if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
3822 + switch (res->ai_family) {
3824 + sin = (struct sockaddr_in *)res->ai_addr;
3825 + if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
3831 + freeaddrinfo(res0);
3832 return ap_proxyerror(r, HTTP_FORBIDDEN,
3833 "Connect to remote machine blocked");
3836 - if (proxyhost != NULL) {
3837 - server.sin_port = htons((unsigned short)proxyport);
3838 - err = ap_proxy_host2addr(proxyhost, &server_hp);
3843 + if (proxyhost != NULL) {
3846 + freeaddrinfo(res0);
3847 + ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
3848 + memset(&hints, 0, sizeof(hints));
3849 + hints.ai_family = PF_UNSPEC;
3850 + hints.ai_socktype = SOCK_STREAM;
3851 + hints.ai_protocol = IPPROTO_TCP;
3852 + error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
3854 return DECLINED; /* try another */
3856 - peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);
3860 - server.sin_port = htons((unsigned short)destport);
3861 - err = ap_proxy_host2addr(desthost, &server_hp);
3863 - return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
3865 - peer = ap_psprintf(p, "%s:%u", desthost, destport);
3870 - /* we have worked out who exactly we are going to connect to, now
3871 - * make that connection...
3873 - sock = ap_psocket(p, PF_INET, SOCK_STREAM, IPPROTO_TCP);
3875 - ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3876 - "proxy: error creating socket");
3877 - return HTTP_INTERNAL_SERVER_ERROR;
3881 + peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);
3886 + for (res = res0; res; res = res->ai_next) {
3887 + sock = ap_psocket(p, res->ai_family, res->ai_socktype,
3888 + res->ai_protocol);
3892 #if !defined(TPF) && !defined(BEOS)
3893 if (conf->recv_buffer_size) {
3894 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
3895 @@ -268,28 +303,12 @@
3899 -#ifdef SINIX_D_RESOLVER_BUG
3901 - struct in_addr *ip_addr = (struct in_addr *) *server_hp.h_addr_list;
3903 - for (; ip_addr->s_addr != 0; ++ip_addr) {
3904 - memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
3905 - i = ap_proxy_doconnect(sock, &server, r);
3912 - while (server_hp.h_addr_list[j] != NULL) {
3913 - memcpy(&server.sin_addr, server_hp.h_addr_list[j],
3914 - sizeof(struct in_addr));
3915 - i = ap_proxy_doconnect(sock, &server, r);
3916 + i = ap_proxy_doconnect(sock, res->ai_addr, r);
3920 + ap_pclosesocket(p, sock);
3923 + freeaddrinfo(res0);
3925 if (proxyhost != NULL)
3926 return DECLINED; /* try again another way */
3927 @@ -544,16 +563,30 @@
3928 ap_table_set(resp_hdrs, "Content-Location", proxy_location_reverse_map(r , urlstr));
3930 /* check if NoCache directive on this host */
3932 + struct sockaddr_in *sin;
3934 + struct sockaddr_in6 *sin6;
3938 for (i = 0; i < conf->nocaches->nelts; i++) {
3939 - if (destaddr.s_addr == ncent[i].addr.s_addr ||
3940 - (ncent[i].name != NULL &&
3941 - (ncent[i].name[0] == '*' ||
3942 - strstr(desthost, ncent[i].name) != NULL))) {
3945 + if (ncent[i].name != NULL &&
3946 + (ncent[i].name[0] == '*' ||
3947 + strstr(desthost, ncent[i].name) != NULL)) {
3951 + switch (res->ai_addr->sa_family) {
3953 + sin = (struct sockaddr_in *)res->ai_addr;
3954 + if (sin->sin_addr.s_addr == ncent[i].addr.s_addr) {
3962 /* update the cache file, possibly even fulfilling the request if
3963 * it turns out a conditional allowed us to serve the object from the
3964 diff -Nur apache_1.3.23.orig/src/modules/proxy/proxy_util.c apache_1.3.23/src/modules/proxy/proxy_util.c
3965 --- apache_1.3.23.orig/src/modules/proxy/proxy_util.c Fri Jan 18 21:26:58 2002
3966 +++ apache_1.3.23/src/modules/proxy/proxy_util.c Wed Feb 6 21:25:17 2002
3968 #include "http_log.h"
3969 #include "util_uri.h"
3970 #include "util_date.h" /* get ap_checkmask() decl. */
3971 +#include "sa_len.h"
3973 static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
3974 static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
3977 char *strp, *host, *url = *urlp;
3978 char *user = NULL, *password = NULL;
3979 + char *t = NULL, *u = NULL, *v = NULL;
3981 if (url[0] != '/' || url[1] != '/')
3982 return "Malformed URL";
3983 @@ -256,11 +258,22 @@
3984 *passwordp = password;
3987 - strp = strrchr(host, ':');
3988 - if (strp != NULL) {
3991 - for (i = 0; strp[i] != '\0'; i++)
3993 + if (*host == '['){
3994 + u = strrchr(host, ']');
4001 + t = strrchr(v, ':');
4007 + for (i=0; strp[i] != '\0'; i++)
4008 if (!ap_isdigit(strp[i]))
4011 @@ -278,17 +291,29 @@
4012 return "Missing host in URL";
4013 /* check hostname syntax */
4014 for (i = 0; host[i] != '\0'; i++)
4015 - if (!ap_isdigit(host[i]) && host[i] != '.')
4016 + if (!ap_isdigit(host[i]) && host[i] != '.' && host[i] != ':')
4018 /* must be an IP address */
4019 #if defined(WIN32) || defined(NETWARE) || defined(TPF) || defined(BEOS)
4020 if (host[i] == '\0' && (inet_addr(host) == -1))
4021 + return "Bad IP address in URL";
4023 + if (host[i] == '\0') {
4024 + struct addrinfo hints, *res0;
4026 + memset(&hints, 0, sizeof(hints));
4027 + hints.ai_family = PF_UNSPEC;
4028 + hints.ai_flags = AI_NUMERICHOST;
4029 + if (gai = getaddrinfo(host, NULL, &hints, &res0)) {
4031 + return gai_strerror(gai);
4033 - if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1))
4034 + return "Bad IP address in URL";
4037 - return "Bad IP address in URL";
4039 + freeaddrinfo(res0);
4043 /* if (strchr(host,'.') == NULL && domain != NULL)
4044 host = pstrcat(p, host, domain, NULL);
4045 @@ -1284,22 +1309,45 @@
4046 return host != NULL && strstr(host, This->name) != NULL;
4049 -int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r)
4050 +int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r)
4054 + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
4055 +#ifdef NI_WITHSCOPEID
4056 + const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
4058 + const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
4061 ap_hard_timeout("proxy connect", r);
4062 +#ifdef HAVE_SOCKADDR_LEN
4063 + salen = addr->sa_len;
4065 + switch (addr->sa_family) {
4067 + salen = sizeof(struct sockaddr_in6);
4070 + salen = sizeof(struct sockaddr_in);
4075 - i = connect(sock, (struct sockaddr *) addr, sizeof(struct sockaddr_in));
4076 + i = connect(sock, addr, salen);
4077 #if defined(WIN32) || defined(NETWARE)
4078 if (i == SOCKET_ERROR)
4079 errno = WSAGetLastError();
4081 } while (i == -1 && errno == EINTR);
4083 + if (getnameinfo(addr, salen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
4085 + strcpy(hbuf, "?");
4086 + strcpy(pbuf, "?");
4088 ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
4089 - "proxy connect to %s port %d failed",
4090 - inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
4091 + "proxy connect to %s port %d failed", hbuf, pbuf);
4095 diff -Nur apache_1.3.23.orig/src/modules/standard/mod_access.c apache_1.3.23/src/modules/standard/mod_access.c
4096 --- apache_1.3.23.orig/src/modules/standard/mod_access.c Mon Jan 15 18:05:34 2001
4097 +++ apache_1.3.23/src/modules/standard/mod_access.c Wed Feb 6 20:20:48 2002
4114 - unsigned long net;
4115 - unsigned long mask;
4116 + struct in_addr net;
4117 + struct in_addr mask;
4121 + struct in6_addr net6;
4122 + struct in6_addr mask6;
4126 enum allowdeny_type type;
4128 @@ -167,90 +176,230 @@
4131 else if ((s = strchr(where, '/'))) {
4132 - unsigned long mask;
4133 + struct addrinfo hints, *resnet, *resmask;
4134 + struct sockaddr_storage net, mask;
4140 + a->type = T_FAIL; /*just in case*/
4141 /* trample on where, we won't be using it any more */
4145 - || (a->x.ip.net = ap_inet_addr(where)) == INADDR_NONE) {
4147 + for (p = s; *p; p++) {
4154 + memset(&hints, 0, sizeof(hints));
4155 + hints.ai_family = PF_UNSPEC;
4156 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
4157 +#ifdef AI_NUMERICHOST
4158 + hints.ai_flags = AI_NUMERICHOST; /*don't resolve*/
4161 + error = getaddrinfo(where, NULL, &hints, &resnet);
4162 + if (error || !resnet) {
4164 + freeaddrinfo(resnet);
4166 return "syntax error in network portion of network/netmask";
4168 + if (resnet->ai_next) {
4169 + freeaddrinfo(resnet);
4171 + return "network/netmask resolved to multiple addresses";
4173 + memcpy(&net, resnet->ai_addr, resnet->ai_addrlen);
4174 + freeaddrinfo(resnet);
4176 - /* is_ip just tests if it matches [\d.]+ */
4178 + switch (net.ss_family) {
4181 + a->x.ip.net.s_addr = ((struct sockaddr_in *)&net)->sin_addr.s_addr;
4186 + memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&net)->sin6_addr,
4187 + sizeof(a->x.ip6.net6));
4192 - return "syntax error in mask portion of network/netmask";
4193 + return "unknown address family for network";
4195 - /* is it in /a.b.c.d form? */
4196 - if (strchr(s, '.')) {
4197 - mask = ap_inet_addr(s);
4198 - if (mask == INADDR_NONE) {
4200 + if (!justdigits) {
4201 + memset(&hints, 0, sizeof(hints));
4202 + hints.ai_family = PF_UNSPEC;
4203 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
4204 +#ifdef AI_NUMERICHOST
4205 + hints.ai_flags = AI_NUMERICHOST; /*don't resolve*/
4208 + error = getaddrinfo(s, NULL, &hints, &resmask);
4209 + if (error || !resmask) {
4211 + freeaddrinfo(resmask);
4213 return "syntax error in mask portion of network/netmask";
4217 - /* assume it's in /nnn form */
4219 - if (mask > 32 || mask <= 0) {
4221 - return "invalid mask in network/netmask";
4223 - mask = 0xFFFFFFFFUL << (32 - mask);
4224 - mask = htonl(mask);
4226 - a->x.ip.mask = mask;
4227 - a->x.ip.net = (a->x.ip.net & mask); /* pjr - This fixes PR 4770 */
4229 - else if (ap_isdigit(*where) && is_ip(where)) {
4230 - /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
4236 - /* parse components */
4243 - if (!ap_isdigit(*t)) {
4244 + if (resmask->ai_next) {
4245 + freeaddrinfo(resmask);
4247 - return "invalid ip address";
4248 + return "network/netmask resolved to multiple addresses";
4250 - while (ap_isdigit(*t)) {
4257 + memcpy(&mask, resmask->ai_addr, resmask->ai_addrlen);
4258 + freeaddrinfo(resmask);
4260 + if (net.ss_family != mask.ss_family) {
4262 - return "invalid ip address";
4263 + return "network/netmask resolved to different address family";
4266 - return "invalid ip address, only 4 octets allowed";
4268 + switch (a->type) {
4270 + a->x.ip.mask.s_addr =
4271 + ((struct sockaddr_in *)&mask)->sin_addr.s_addr;
4275 + memcpy(&a->x.ip6.mask6,
4276 + &((struct sockaddr_in6 *)&mask)->sin6_addr,
4277 + sizeof(a->x.ip6.mask6));
4282 - if (octet < 0 || octet > 255) {
4284 - return "each octet must be between 0 and 255 inclusive";
4288 + switch (a->type) {
4290 + if (mask < 0 || 32 < mask) {
4292 + return "netmask out of range";
4294 + a->x.ip.mask.s_addr = htonl(0xFFFFFFFFUL << (32 - mask));
4300 + if (mask < 0 || 128 < mask) {
4302 + return "netmask out of range";
4304 + for (i = 0; i < mask / 8; i++) {
4305 + a->x.ip6.mask6.s6_addr[i] = 0xff;
4308 + a->x.ip6.mask6.s6_addr[i] = 0xff << (8 - (mask % 8));
4313 - a->x.ip.net |= octet << shift;
4314 - a->x.ip.mask |= 0xFFUL << shift;
4318 - a->x.ip.net = ntohl(a->x.ip.net);
4319 - a->x.ip.mask = ntohl(a->x.ip.mask);
4323 + struct addrinfo hints, *res;
4324 + struct sockaddr_storage ss;
4327 + a->type = T_FAIL; /*just in case*/
4329 + /* First, try using the old apache code to match */
4330 + /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
4331 + if (ap_isdigit(*where) && is_ip(where)) {
4337 + /* parse components */
4339 + a->x.ip.net.s_addr = 0;
4340 + a->x.ip.mask.s_addr = 0;
4344 + if (!ap_isdigit(*t)) {
4346 + return "invalid ip address";
4348 + while (ap_isdigit(*t)) {
4356 + return "invalid ip address";
4359 + return "invalid ip address, only 4 octets allowed";
4362 + if (octet < 0 || octet > 255) {
4364 + return "each octet must be between 0 and 255 inclusive";
4366 + a->x.ip.net.s_addr |= octet << shift;
4367 + a->x.ip.mask.s_addr |= 0xFFUL << shift;
4371 + a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
4372 + a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
4377 + /* IPv4/v6 numeric address */
4378 + memset(&hints, 0, sizeof(hints));
4379 + hints.ai_family = PF_UNSPEC;
4380 + hints.ai_socktype = SOCK_STREAM; /*dummy*/
4381 +#ifdef AI_NUMERICHOST
4382 + hints.ai_flags = AI_NUMERICHOST; /*don't resolve*/
4385 + error = getaddrinfo(where, NULL, &hints, &res);
4386 + if (error || !res) {
4388 + freeaddrinfo(res);
4392 + if (res->ai_next) {
4393 + freeaddrinfo(res);
4395 + return "network/netmask resolved to multiple addresses";
4397 + memcpy(&ss, res->ai_addr, res->ai_addrlen);
4398 + freeaddrinfo(res);
4400 + switch (ss.ss_family) {
4403 + a->x.ip.net.s_addr = ((struct sockaddr_in *)&ss)->sin_addr.s_addr;
4404 + memset(&a->x.ip.mask, 0xff, sizeof(a->x.ip.mask));
4409 + memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&ss)->sin6_addr,
4410 + sizeof(a->x.ip6.net6));
4411 + memset(&a->x.ip6.mask6, 0xff, sizeof(a->x.ip6.mask6));
4416 + return "unknown address family for network";
4421 @@ -315,12 +464,63 @@
4425 - if (ap[i].x.ip.net != INADDR_NONE
4426 - && (r->connection->remote_addr.sin_addr.s_addr
4427 - & ap[i].x.ip.mask) == ap[i].x.ip.net) {
4429 + if (ap[i].x.ip.net.s_addr == INADDR_NONE)
4431 + switch (r->connection->remote_addr.ss_family) {
4433 + if ((((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr
4434 + & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
4440 + if (!IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr)) /*XXX*/
4442 + if ((*(ap_uint32_t *)&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr.s6_addr[12]
4443 + & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
4454 + struct in6_addr masked;
4456 + if (IN6_IS_ADDR_UNSPECIFIED(&ap[i].x.ip6.net6))
4458 + switch (r->connection->remote_addr.ss_family) {
4460 + if (!IN6_IS_ADDR_V4MAPPED(&ap[i].x.ip6.net6)) /*XXX*/
4462 + memset(&masked, 0, sizeof(masked));
4463 + masked.s6_addr[10] = masked.s6_addr[11] = 0xff;
4464 + memcpy(&masked.s6_addr[12],
4465 + &((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr,
4466 + sizeof(struct sockaddr_in));
4467 + for (j = 0; j < sizeof(struct in6_addr); j++)
4468 + masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
4469 + if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
4473 + memset(&masked, 0, sizeof(masked));
4475 + &((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr,
4477 + for (j = 0; j < sizeof(struct in6_addr); j++)
4478 + masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
4479 + if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
4489 diff -Nur apache_1.3.23.orig/src/modules/standard/mod_unique_id.c apache_1.3.23/src/modules/standard/mod_unique_id.c
4490 --- apache_1.3.23.orig/src/modules/standard/mod_unique_id.c Tue Oct 2 18:11:13 2001
4491 +++ apache_1.3.23/src/modules/standard/mod_unique_id.c Wed Feb 6 20:20:48 2002
4493 #include "http_config.h"
4494 #include "http_log.h"
4495 #include "multithread.h"
4496 +#include "sa_len.h"
4498 +/*#define SHORT_UNIQUE_ID*/
4502 - unsigned int in_addr;
4504 + struct in_addr in;
4506 +# ifdef SHORT_UNIQUE_ID
4509 + struct in6_addr in6;
4517 * this shouldn't be a problem till year 2106.
4520 -static unsigned global_in_addr;
4521 +static struct sockaddr_storage global_addr;
4526 #define MAXHOSTNAMELEN 256
4528 char str[MAXHOSTNAMELEN + 1];
4529 - struct hostent *hent;
4530 + struct addrinfo hints, *res, *res0;
4532 #ifndef NO_GETTIMEOFDAY
4537 unique_id_rec_offset[0] = XtOffsetOf(unique_id_rec, stamp);
4538 unique_id_rec_size[0] = sizeof(cur_unique_id->stamp);
4539 - unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, in_addr);
4540 - unique_id_rec_size[1] = sizeof(cur_unique_id->in_addr);
4541 + unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, addr);
4542 + unique_id_rec_size[1] = sizeof(cur_unique_id->addr);
4543 unique_id_rec_offset[2] = XtOffsetOf(unique_id_rec, pid);
4544 unique_id_rec_size[2] = sizeof(cur_unique_id->pid);
4546 @@ -269,17 +282,44 @@
4548 str[sizeof(str) - 1] = '\0';
4550 - if ((hent = gethostbyname(str)) == NULL) {
4551 + memset(&hints, 0, sizeof(hints));
4552 + hints.ai_family = PF_UNSPEC;
4553 + error = getaddrinfo(str, NULL, &hints, &res0);
4555 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
4556 - "mod_unique_id: unable to gethostbyname(\"%s\")", str);
4557 + "mod_unique_id: getaddrinfo failed for \"%s\" (%s)", str,
4558 + gai_strerror(error));
4562 - global_in_addr = ((struct in_addr *) hent->h_addr_list[0])->s_addr;
4564 + for (res = res0; res; res = res->ai_next) {
4565 + switch (res->ai_family) {
4570 + memcpy(&global_addr, res->ai_addr, res->ai_addrlen);
4575 + freeaddrinfo(res0);
4577 + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
4578 + "mod_unique_id: no known AF found for \"%s\"", str);
4582 + getnameinfo((struct sockaddr *)&global_addr,
4584 + SA_LEN((struct sockaddr *)&global_addr),
4586 + global_addr.ss_len,
4588 + str, sizeof(str), NULL, 0, NI_NUMERICHOST);
4589 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, s,
4590 - "mod_unique_id: using ip addr %s",
4591 - inet_ntoa(*(struct in_addr *) hent->h_addr_list[0]));
4592 + "mod_unique_id: using ip addr %s", str);
4595 * If the server is pummelled with restart requests we could possibly end
4596 @@ -336,7 +376,23 @@
4597 "oh no! pids are greater than 32-bits! I'm broken!");
4600 - cur_unique_id->in_addr = global_in_addr;
4601 + memset(&cur_unique_id->addr, 0, sizeof(cur_unique_id->addr));
4602 + switch (global_addr.ss_family) {
4604 + cur_unique_id->addr.in = ((struct sockaddr_in *)&global_addr)->sin_addr;
4608 +#ifdef SHORT_UNIQUE_ID
4609 + cur_unique_id->addr.in6 =
4610 + ((struct sockaddr_in6 *)&global_addr)->sin6_addr.s6_addr32[3];
4612 + cur_unique_id->addr.in6 =
4613 + ((struct sockaddr_in6 *)&global_addr)->sin6_addr;
4620 * If we use 0 as the initial counter we have a little less protection
4621 diff -Nur apache_1.3.23.orig/src/support/ab.c apache_1.3.23/src/support/ab.c
4622 --- apache_1.3.23.orig/src/support/ab.c Mon Oct 8 19:54:42 2001
4623 +++ apache_1.3.23/src/support/ab.c Wed Feb 6 20:20:48 2002
4625 #include <sys/uio.h>
4628 +#include "sa_len.h"
4630 #endif /* NO_APACHE_INCLUDES */
4634 char servername[1024]; /* name that server reports */
4635 char hostname[1024]; /* host name */
4636 char proxyhost[1024]; /* proxy host name */
4637 -int proxyport = 0; /* proxy port */
4638 +char *proxyport = NULL; /* proxy port */
4640 char path[1024]; /* path name */
4641 char postfile[1024]; /* name of file containing post data */
4643 auth[1024], /* optional (basic/uuencoded)
4644 * authentification */
4645 hdrs[4096]; /* optional arbitrary headers */
4646 -int port = 80; /* port number */
4647 +char *port = "80"; /* port number */
4649 int use_html = 0; /* use html in the report */
4652 struct data *stats; /* date for each request */
4654 fd_set readbits, writebits; /* bits for select */
4655 -struct sockaddr_in server; /* server addr structure */
4656 +struct sockaddr_storage server; /* server addr structure */
4659 #define ab_close(s) close(s)
4662 printf("Server Software: %s\n", servername);
4663 printf("Server Hostname: %s\n", hostname);
4664 - printf("Server Port: %d\n", port);
4665 + printf("Server Port: %s\n", port);
4667 printf("Document Path: %s\n", path);
4668 printf("Document Length: %d bytes\n", doclen);
4673 - c->fd = socket(AF_INET, SOCK_STREAM, 0);
4674 + c->fd = socket(server.ss_family, SOCK_STREAM, 0);
4678 @@ -879,7 +881,12 @@
4681 gettimeofday(&c->start, 0);
4682 - if (connect(c->fd, (struct sockaddr *) & server, sizeof(server)) < 0) {
4684 + if (connect(c->fd, (struct sockaddr *) & server, SA_LEN((struct sockaddr*)&server)) < 0)
4686 + if (connect(c->fd, (struct sockaddr *) & server, server.ss_len) < 0)
4689 if (errno == EINPROGRESS) {
4690 c->state = STATE_CONNECTING;
4692 @@ -1171,7 +1178,7 @@
4693 struct timeval timeout, now;
4694 fd_set sel_read, sel_except, sel_write;
4697 + char * connectport;
4698 char * url_on_request, * host;
4700 /* There are four hostname's involved:
4701 @@ -1209,16 +1216,21 @@
4704 /* get server information */
4705 - struct hostent *he;
4706 - he = gethostbyname(host);
4708 - char theerror[1024];
4709 - sprintf(theerror, "Bad hostname: %s\n", host);
4712 - server.sin_family = he->h_addrtype;
4713 - server.sin_port = htons(connectport);
4714 - server.sin_addr.s_addr = ((unsigned long *) (he->h_addr_list[0]))[0];
4715 + struct addrinfo hints, *res;
4718 + memset(&hints, 0, sizeof(hints));
4719 + hints.ai_family = PF_UNSPEC;
4720 + hints.ai_socktype = SOCK_STREAM;
4721 + error = getaddrinfo(host, connectport, &hints, &res);
4723 + char *theerror=malloc(strlen(host)+16);
4724 + sprintf(theerror, "Bad hostname: %s\n", host);
4728 + memcpy(&server, res->ai_addr, res->ai_addrlen);
4729 + freeaddrinfo(res);
4732 con = malloc(concurrency * sizeof(struct connection));
4733 @@ -1404,7 +1416,7 @@
4734 if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
4741 if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
4742 @@ -1425,7 +1437,7 @@
4744 strcpy(hostname, h);
4751 @@ -1585,7 +1597,7 @@
4752 if ((p = strchr(optarg, ':'))) {
4755 - proxyport = atoi(p);
4756 + proxyport = strdup(p);
4758 strcpy(proxyhost, optarg);
4760 @@ -1668,3 +1680,7 @@
4765 +#ifdef NEED_GETADDRINFO
4766 +#include "../main/getaddrinfo.c"
4768 diff -Nur apache_1.3.23.orig/src/support/logresolve.c apache_1.3.23/src/support/logresolve.c
4769 --- apache_1.3.23.orig/src/support/logresolve.c Wed May 23 00:52:21 2001
4770 +++ apache_1.3.23/src/support/logresolve.c Wed Feb 6 20:20:48 2002
4773 #endif /* !MPE && !WIN32*/
4775 -static void cgethost(struct in_addr ipnum, char *string, int check);
4776 +#include "sa_len.h"
4778 +static void cgethost(struct sockaddr *sa, char *string, int check);
4779 static int getline(char *s, int n);
4780 static void stats(FILE *output);
4786 - struct in_addr ipnum;
4787 + struct sockaddr_storage addr;
4791 @@ -122,17 +124,48 @@
4792 * IP numbers with their IP number as hostname, setting noname flag
4795 -static void cgethost (struct in_addr ipnum, char *string, int check)
4796 +static void cgethost (struct sockaddr *sa, char *string, int check)
4798 + ap_uint32_t hashval;
4799 + struct sockaddr_in *sin;
4801 + struct sockaddr_in6 *sin6;
4803 struct nsrec **current, *new;
4804 - struct hostent *hostdata;
4806 + char hostnamebuf[MAXHOSTNAMELEN];
4808 + switch (sa->sa_family) {
4810 + hashval = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
4814 + hashval = *(ap_uint32_t *)&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12];
4822 + current = &nscache[((hashval + (hashval >> 8) +
4823 + (hashval >> 16) + (hashval >> 24)) % BUCKETS)];
4825 - current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) +
4826 - (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)];
4827 + while (*current) {
4829 + if (SA_LEN(sa) == SA_LEN((struct sockaddr *)&(*current)->addr)
4830 + && memcmp(sa, &(*current)->addr, SA_LEN(sa)) == 0)
4832 + if (sa->sa_len == (*current)->addr.ss_len
4833 + && memcmp(sa, &(*current)->addr, sa->sa_len) == 0)
4839 - while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr)
4840 current = &(*current)->next;
4843 if (*current == NULL) {
4845 @@ -145,45 +178,55 @@
4849 - new->ipnum = ipnum;
4851 + memcpy(&new->addr, sa, SA_LEN(sa));
4853 + memcpy(&new->addr, sa, sa->sa_len);
4856 - hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr),
4858 - if (hostdata == NULL) {
4859 - if (h_errno > MAX_ERR)
4860 - errors[UNKNOWN_ERR]++;
4862 - errors[h_errno]++;
4863 - new->noname = h_errno;
4864 - name = strdup(inet_ntoa(ipnum));
4868 - name = strdup(hostdata->h_name);
4870 - if (name == NULL) {
4872 - fprintf(stderr, "Insufficient memory\n");
4875 - hostdata = gethostbyname(name);
4876 - if (hostdata != NULL) {
4879 - for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++)
4880 - if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr)
4882 - if (*hptr == NULL)
4885 - if (hostdata == NULL) {
4886 - fprintf(stderr, "Bad host: %s != %s\n", name,
4887 - inet_ntoa(ipnum));
4888 - new->noname = NO_REVERSE;
4890 - name = strdup(inet_ntoa(ipnum));
4891 - errors[NO_REVERSE]++;
4892 + new->noname = getnameinfo(sa,
4898 + hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0);
4899 + name = strdup(hostnamebuf);
4901 + struct addrinfo hints, *res;
4903 + memset(&hints, 0, sizeof(hints));
4904 + hints.ai_family = PF_UNSPEC;
4905 + error = getaddrinfo(hostnamebuf, NULL, &hints, &res);
4909 + if (SA_LEN(sa) == res->ai_addrlen
4910 + && memcmp(sa, res->ai_addr, SA_LEN(sa)) == 0)
4912 + if (sa->sa_len == res->ai_addrlen
4913 + && memcmp(sa, res->ai_addr, sa->sa_len) == 0)
4918 + res = res->ai_next;
4930 + hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
4931 + fprintf(stderr, "Bad host: %s != %s\n", name, hostnamebuf);
4932 + new->noname = NO_REVERSE;
4934 + name = strdup(hostnamebuf);
4937 new->hostname = name;
4940 struct nsrec *current;
4941 char *errstring[MAX_ERR + 3];
4942 + char hostnamebuf[MAXHOSTNAMELEN];
4944 for (i = 0; i < MAX_ERR + 3; i++)
4945 errstring[i] = "Unknown error";
4946 @@ -242,7 +286,14 @@
4948 for (i = 0; i < BUCKETS; i++)
4949 for (current = nscache[i]; current != NULL; current = current->next) {
4950 - ipstring = inet_ntoa(current->ipnum);
4951 + getnameinfo((struct sockaddr *)¤t->addr,
4953 + SA_LEN((struct sockaddr *)¤t->addr),
4955 + current->addr.ss_len,
4957 + hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
4958 + ipstring = hostnamebuf;
4959 if (current->noname == 0)
4960 fprintf(output, " %3d %15s - %s\n", i, ipstring,
4962 @@ -276,9 +327,10 @@
4964 int main (int argc, char *argv[])
4966 - struct in_addr ipnum;
4967 char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
4969 + struct addrinfo hints, *res;
4974 @@ -322,8 +374,10 @@
4975 bar = strchr(line, ' ');
4978 - ipnum.s_addr = inet_addr(line);
4979 - if (ipnum.s_addr == 0xffffffffu) {
4980 + memset(&hints, 0, sizeof(hints));
4981 + hints.ai_family = PF_UNSPEC;
4982 + error = getaddrinfo(line, NULL, &hints, &res);
4987 @@ -333,11 +387,12 @@
4991 - cgethost(ipnum, hoststring, check);
4992 + cgethost(res->ai_addr, hoststring, check);
4994 printf("%s %s\n", hoststring, bar + 1);
4997 + freeaddrinfo(res);
5001 @@ -358,3 +413,11 @@
5006 +#ifdef NEED_GETADDRINFO
5007 +#include "../main/getaddrinfo.c"
5010 +#ifdef NEED_GETNAMEINFO
5011 +#include "../main/getnameinfo.c"