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