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