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