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