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