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
7 +# Listen can take two arguments.
8 +# (this is an extension for supporting IPv6 addresses)
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
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
24 +IPv6-ready apache 1.3.x
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.
32 +Basically you can write IPv6 address where IPv4 address fits.
34 +extra command-line argument:
35 + -4 Assume IPv4 address on ambiguous directives
36 + -6 Assume IPv6 address on ambiguous directives (default)
38 + The above two can be used, for example, to disambiguate
43 + Listen is expanded to take one or two arguments.
47 + This is to let you specify "Listen :: 80", since "Listen :::80"
53 + "deny from" and "allow from" supports IPv6 addresses, under the
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.
62 + http/ftp proxying for both IPv4 and IPv6 is possible.
63 + Access control functions (NoProxy) are not updated yet.
65 + NOTE: for security reasons, we recommend you to filter out
66 + outsider's access to your proxy, by directives like below:
70 + allow from 10.0.0.0/8
71 + allow from 3ffe:9999:8888:7777::/64
75 + If you would like to this feature, you must describe 'Listen'
76 + part on configuration file explicitly. like below:
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.
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.
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>
108 +logresolve (src/support)
109 + error statistics in nameserver cache code is omitted.
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.
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
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.
134 + The behavior should be improved in the near future; we welcome your
137 +Modules known to be incompatible with IPv6
141 + Configure has extra option, --enable-rule=INET6. if the option
142 + is specified, IPv6 code will be enabled.
145 + We do not support IPv4 mapped address (IPv6 address format like
146 + ::ffff:10.1.1.1) in configuration file.
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.
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"
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.
174 + Thanks to all people submitted patches/fixes for this patch kit,
176 + "Chris P. Ross" <cross@eng.us.uu.net>
179 + Jun-ichiro itojun Hagino, KAME project
180 + http://www.kame.net/
181 + mailto:core@kame.net
183 + Arkadiusz Miskiewicz, Polish Linux Distribution project (IPv6)
184 + http://www.pld.org.pl/
185 + mailto:feedback@pld.org.pl
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/
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
205 +static char *conv_sockaddr(struct sockaddr *sa, char *buf_end, int *len)
208 + char hostnamebuf[MAXHOSTNAMELEN];
209 + char portnamebuf[MAXHOSTNAMELEN];
214 + salen = SA_LEN(sa);
216 + salen = sa->sa_len;
218 + if (getnameinfo(sa, salen, hostnamebuf, sizeof(hostnamebuf),
219 + portnamebuf, sizeof(portnamebuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
220 + strcpy(hostnamebuf, "???");
221 + strcpy(portnamebuf, "???");
223 + if (strcmp(portnamebuf,"0") == 0)
224 + strcpy(portnamebuf, "*");
225 + q = portnamebuf + strlen(portnamebuf);
226 + while (portnamebuf < q)
229 + q = hostnamebuf + strlen(hostnamebuf);
230 + while (hostnamebuf < q)
233 + *len = buf_end - p;
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 */
248 struct sockaddr_in *si;
250 si = va_arg(ap, struct sockaddr_in *);
251 @@ -1023,6 +1061,16 @@
252 if (adjust_precision && precision < s_len)
256 + struct sockaddr *sa;
258 + sa = va_arg(ap, struct sockaddr *);
260 + s = conv_sockaddr(sa, &num_buf[NUM_BUF_SIZE], &s_len);
261 + if (adjust_precision && precision < s_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
271 # Rule EXPAT=default : If Expat can be found at the system or
272 # in lib/expat-lite, use it; otherwise
279 # Use Win32 API system calls for socket communication instead
285 Rule CYGWIN_WINSOCK=no
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
291 RULE_CYGWIN_WINSOCK=`./helpers/CutRule CYGWIN_WINSOCK $file`
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`
296 ####################################################################
297 ## Rule SHARED_CORE implies required DSO support
298 @@ -1692,6 +1693,124 @@
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
311 + if [ -f /usr/include/netinet6/in6.h -a "x`egrep '__KAME__' /usr/include/netinet6/in6.h 2>/dev/null`" != "x" ]; then
316 + if [ /usr/include/netinet/ip6.h -a -d /usr/include/linux ]; then
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})"
331 + if [ "$IPV6_STACKTYPE" != "UNKNOWN" ]; then
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"
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"
349 + echo "** WARNING: No getaddrinfo found, linkage may fail"
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."
362 + LIBS="$LIBS -lresolv"
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"
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
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"
381 + echo " + you don't have sa_len in struct sockaddr."
383 +rm -f testfunc.c testfunc.o
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
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"
393 + CFLAGS="$CFLAGS -DNEED_SOCKADDR_STORAGE"
394 + echo " + you need struct sockaddr_storage"
396 +rm -f testfunc.c testfunc.o
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
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"
406 +rm -f testfunc.c testfunc.o
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
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"
417 +rm -f testfunc.c testfunc.o
420 ####################################################################
421 ## Find out what modules we want and try and configure things for them
422 ## Module lines can look like this:
423 @@ -2296,6 +2415,38 @@
424 echo "#define AP_LONGEST_LONG $AP_LONGEST_LONG" >>$AP_CONFIG_AUTO_H
425 echo "#endif" >>$AP_CONFIG_AUTO_H
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"
456 + echo " - Warning: cannot determine what type should we use as 32bit unsigned int"
459 ####################################################################
460 ## More building ap_config_auto.h
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
467 #define S_IWOTH 000002
471 +typedef u_long n_long;
474 #define STDIN_FILENO 0
475 @@ -1455,6 +1459,70 @@
476 #define ap_wait_t int
480 +#define sockaddr_storage sockaddr
481 +#define ss_family sa_family
482 +#define ss_len sa_len
484 +#include "sockaddr_storage.h" /* sshida@st.rim.or.jp */
487 +#ifndef INET6_ADDRSTRLEN
488 +#define INET6_ADDRSTRLEN 46
490 +#ifndef INET_ADDRSTRLEN
491 +#define INET_ADDRSTRLEN 16
494 +#define NI_MAXHOST 1025
497 +#define NI_MAXSERV 32
500 +#if defined(NEED_GETADDRINFO) || defined(NEED_GETNAMEINFO)
502 + * minimal definitions for fake getaddrinfo()/getnameinfo().
505 +#define EAI_NODATA 1
506 +#define EAI_MEMORY 2
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
519 +#ifdef NEED_GETADDRINFO
520 +#ifdef NEED_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 */
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);
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,
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
549 * with some extensions. The extensions are:
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
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
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;
564 -extern API_VAR_EXPORT struct in_addr ap_bind_address;
565 +extern API_VAR_EXPORT struct sockaddr_storage ap_bind_address;
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;
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
574 /* Who is the client? */
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,
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> */
595 /* These are more like real hosts than virtual hosts */
598 - struct sockaddr_in local_addr; /* local IP address and port */
599 + struct sockaddr_storage local_addr; /* local IP address and port */
601 int used; /* Only used during restart */
602 /* more stuff here, like which protocol is bound to the port */
603 @@ -1147,7 +1147,7 @@
604 #endif /*#ifdef CHARSET_EBCDIC*/
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);
610 extern API_VAR_EXPORT time_t ap_restart_time;
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
615 API_EXPORT(const char *) ap_parse_vhost_addrs(pool *p, const char *hostname, server_rec *s);
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);
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
626 +/* sa_len.h : tiny version of SA_LEN (written by <yoshfuji@ecei.tohoku.ac.jp>) */
628 +#include <sys/types.h>
629 +#include <sys/socket.h>
630 +#include <netinet/in.h>
633 +#ifndef HAVE_SOCKADDR_LEN
635 +#define SA_LEN(s_) ap_sa_len((s_)->sa_family)
637 +static NET_SIZE_T ap_sa_len (sa_family_t af)
640 +#if defined(AF_INET)
642 + return (sizeof(struct sockaddr_in));
643 +#endif /* AF_INET */
644 +#if defined(AF_INET6)
646 + return (sizeof(struct sockaddr_in6));
650 +#endif /* AF_LOCAL */
651 +#if defined(AF_UNIX) && (AF_UNIX != AF_LOCAL)
653 +#endif /* AF_UNIX */
654 +#if defined(AF_FILE) && (AF_FILE != AF_LOCAL || AF_FILE != AF_UNIX)
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) */
666 +#endif /* HAVE_SOCKADDR_LEN */
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
671 +struct sockaddr_storage
673 + RFC2553 proposes struct sockaddr_storage.
674 + This is a placeholder for all sockaddr-variant structures. This is
675 + implemented like follows:
677 + You should use this structure to hold any of sockaddr-variant
680 +#ifdef NEED_SOCKADDR_STORAGE
682 +struct sockaddr_storage {
683 +#ifdef HAVE_SOCKADDR_LEN
689 + u_char __padding[128 - 2];
695 + Alternatively, you may want to implement sockunion.h, with the
698 + NOTE: For better portability, struct sockaddr_storage should be used.
699 + union sockunion is okay, but is not really portable enough.
703 +#ifdef HAVE_SOCKADDR_LEN
711 + struct sockaddr_in su_sin;
713 + struct sockaddr_in6 su_sin6;
716 +#ifdef HAVE_SOCKADDR_LEN
717 +#define su_len su_si.si_len
719 +#define su_family su_si.si_family
720 +#define su_port su_si.si_port
722 +#endif /* NEED_SOCKADDR_STORAGE */
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
727 + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
728 + * All rights reserved.
730 + * Redistribution and use in source and binary forms, with or without
731 + * modification, are permitted provided that the following conditions
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.
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
755 + * fake library for ssh v6 enabler patch
757 + * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
758 + * These funtions are defined in rfc2133.
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.
764 + * In the case not using 'configure --enable-ipv6', this getaddrinfo.c
765 + * will be used if you have broken getaddrinfo or no getaddrinfo.
770 +#include <sys/types.h>
771 +#include <sys/socket.h>
772 +#include <netinet/in.h>
773 +#include <arpa/inet.h>
778 +static struct addrinfo *
779 +malloc_ai(port, addr, socktype, protocol)
785 + struct addrinfo *ai;
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 =
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;
812 + return "no address associated with hostname.";
814 + return "memory allocation failure.";
816 + return "unknown error.";
822 +struct addrinfo *ai;
824 + struct addrinfo *next;
827 + next = ai->ai_next;
829 + } while (ai = next);
833 +getaddrinfo(hostname, servname, hints, res)
834 +const char *hostname, *servname;
835 +const struct addrinfo *hints;
836 +struct addrinfo **res;
838 + struct addrinfo *cur, *prev = NULL;
839 + struct hostent *hp;
843 + port = htons(atoi(servname));
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))
854 + if (*res = malloc_ai(port, htonl(0x7f000001),
855 + (*res)->ai_socktype ? (*res)->ai_socktype : SOCK_STREAM,
856 + (*res)->ai_protocol))
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))
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)) {
875 + prev->ai_next = cur;
881 + freeaddrinfo(*res);
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
892 + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
893 + * All rights reserved.
895 + * Redistribution and use in source and binary forms, with or without
896 + * modification, are permitted provided that the following conditions
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.
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
920 + * fake library for ssh v6 enabler patch
922 + * This file includes getnameinfo().
923 + * These funtions are defined in rfc2133.
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.
929 + * In the case not using 'configure --enable-ipv6', this getnameinfo.c
930 + * will be used if you have broken getnameinfo or no getnameinfo.
935 +#include <sys/types.h>
936 +#include <sys/socket.h>
937 +#include <netinet/in.h>
938 +#include <arpa/inet.h>
945 +getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
946 +const struct sockaddr *sa;
954 + struct sockaddr_in *sin = (struct sockaddr_in *)sa;
955 + struct hostent *hp;
959 + sprintf(tmpserv, "%d", ntohs(sin->sin_port));
960 + if (strlen(tmpserv) > servlen)
963 + strcpy(serv, tmpserv);
966 + if (flags & NI_NUMERICHOST)
967 + if (strlen(inet_ntoa(sin->sin_addr)) > hostlen)
970 + strcpy(host, inet_ntoa(sin->sin_addr));
974 + if (hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr),
976 + if (strlen(hp->h_name) > hostlen)
979 + strcpy(host, hp->h_name);
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 @@
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);
994 ap_listenbacklog = DEFAULT_LISTENBACKLOG;
995 ap_extended_status = 0;
996 @@ -1586,7 +1585,13 @@
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));
1003 + s->addrs->host_addr.ss_family = ap_default_family; /* XXX: needed?, XXX: PF_xxx can be different from AF_xxx */
1005 +#ifdef HAVE_SOCKADDR_LEN
1006 + s->addrs->host_addr.ss_len = sizeof(s->addrs->host_addr); /* XXX: needed ? */
1008 s->addrs->host_port = 0; /* matches any port */
1009 s->addrs->virthost = ""; /* must be non-NULL */
1010 s->names = s->wild_names = NULL;
1011 @@ -1605,21 +1610,33 @@
1012 static void default_listeners(pool *p, server_rec *s)
1015 + struct addrinfo hints, *res0, *res;
1017 + char servbuf[NI_MAXSERV];
1019 if (ap_listeners != NULL) {
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);
1029 + fprintf(stderr, "default_listeners(): getaddrinfo(PASSIVE) for family %u: %s\n",
1030 + gai_strerror(gai), ap_default_family);
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;
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));
1040 + memcpy(&new->local_addr, res0->ai_addr, res0->ai_addrlen);
1046 + freeaddrinfo(res0);
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
1053 #include "util_md5.h"
1054 #include "scoreboard.h"
1055 #include "fnmatch.h"
1056 +#include "sa_len.h"
1058 #ifdef USE_MMAP_FILES
1059 #include <sys/mman.h>
1061 * file if you care. So the adhoc value should do.
1063 return ap_psprintf(r->pool,"%pA%pp%pp%pp%pp",
1064 - &r->connection->local_addr.sin_addr,
1065 + &((struct sockaddr_in *)&(r->connection->local_addr))->sin_addr,
1066 (void *)ap_user_name,
1067 (void *)ap_listeners,
1068 (void *)ap_server_argv0,
1071 static ap_inline void do_double_reverse (conn_rec *conn)
1073 - struct hostent *hptr;
1074 + struct addrinfo hints, *res, *res0;
1075 + char hostbuf1[128], hostbuf2[128]; /* INET6_ADDRSTRLEN(=46) is enough */
1078 if (conn->double_reverse) {
1080 @@ -679,30 +682,54 @@
1081 conn->remote_host = ""; /* prevent another lookup */
1084 - hptr = gethostbyname(conn->remote_host);
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;
1094 + memset(&hints, 0, sizeof(hints));
1095 + hints.ai_family = PF_UNSPEC;
1096 + hints.ai_socktype = SOCK_STREAM;
1097 + if (getaddrinfo(conn->remote_host, NULL, &hints, &res0)) {
1098 + conn->double_reverse = -1;
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
1105 + || res->ai_family == AF_INET6
1110 +#ifndef HAVE_SOCKADDR_LEN
1111 + if (res->ai_addrlen != SA_LEN((struct sockaddr *)&conn->remote_addr))
1113 + if (res->ai_addr->sa_len != conn->remote_addr.ss_len)
1116 + if (getnameinfo(res->ai_addr, res->ai_addrlen,
1117 + hostbuf1, sizeof(hostbuf1), NULL, 0,
1120 + if (getnameinfo(((struct sockaddr *)&conn->remote_addr), res->ai_addrlen,
1121 + hostbuf2, sizeof(hostbuf2), NULL, 0,
1124 + if (strcmp(hostbuf1, hostbuf2) == 0){
1129 - conn->double_reverse = -1;
1130 + conn->double_reverse = ok ? 1 : -1;
1131 + freeaddrinfo(res0);
1132 /* invalidate possible reverse-resolved hostname if forward lookup fails */
1133 - conn->remote_host = "";
1135 + conn->remote_host = "";
1138 API_EXPORT(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
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];
1147 /* If we haven't checked the host name, and we want to */
1149 @@ -724,10 +751,14 @@
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,
1159 + SA_LEN((struct sockaddr *)&conn->remote_addr),
1161 + conn->remote_addr.ss_len,
1163 + hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0)) {
1164 + conn->remote_host = ap_pstrdup(conn->pool, (void *)hostnamebuf);
1165 ap_str_tolower(conn->remote_host);
1167 if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
1170 conn_rec *conn = r->connection;
1172 + char hbuf[MAXHOSTNAMELEN];
1174 d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
1176 @@ -814,23 +846,22 @@
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;
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),
1188 - if (hptr != NULL) {
1189 - conn->local_host = ap_pstrdup(conn->pool,
1190 - (void *)hptr->h_name);
1191 - ap_str_tolower(conn->local_host);
1194 - conn->local_host = ap_pstrdup(conn->pool,
1195 - r->server->server_hostname);
1196 + if (getnameinfo((struct sockaddr *)&conn->local_addr,
1198 + SA_LEN((struct sockaddr *)&conn->local_addr),
1200 + conn->local_addr.ss_len,
1202 + hbuf, sizeof(hbuf), NULL, 0, 0) == 0) {
1203 + conn->local_host = ap_pstrdup(conn->pool, hbuf);
1205 + conn->local_host = ap_pstrdup(conn->pool,
1206 + r->server->server_hostname);
1208 + ap_str_tolower(conn->local_host);
1209 (void) ap_update_child_status(conn->child_num, old_stat, r);
1211 return conn->local_host;
1213 API_EXPORT(unsigned) ap_get_server_port(const request_rec *r)
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);
1221 @@ -2648,12 +2679,25 @@
1223 static const char *set_bind_address(cmd_parms *cmd, void *dummy, char *arg)
1225 + struct addrinfo hints, *res;
1226 + struct sockaddr *sa;
1229 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1234 - ap_bind_address.s_addr = ap_get_virthost_addr(arg, NULL);
1235 + if (strcmp(arg, "*") == 0)
1238 + sa = ap_get_virthost_addr(arg, NULL);
1239 +#ifdef HAVE_SOCKADDR_LEN
1240 + sa_len = sa->sa_len;
1242 + sa_len = SA_LEN(sa);
1244 + memcpy(&ap_bind_address, &sa, sa_len);
1248 @@ -2685,48 +2729,71 @@
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)
1256 - char *ports, *endptr;
1258 + char *host, *port;
1259 + struct addrinfo hints, *res;
1262 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
1267 - ports = strchr(ips, ':');
1268 - if (ports != NULL) {
1269 - if (ports == ips) {
1270 - return "Missing IP address";
1272 - else if (ports[1] == '\0') {
1273 - return "Address must end in :<port-number>";
1274 + host = port = NULL;
1276 + port = strrchr(h, ':');
1277 + if (port != NULL) {
1279 + return "Missing IP address";
1281 + else if (port[1] == '\0') {
1282 + return "Address must end in :<port-number>";
1292 - *(ports++) = '\0';
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);
1307 - new->local_addr.sin_addr.s_addr = ap_get_virthost_addr(ips, NULL);
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 */
1315 - return "Missing, invalid, or non-numeric port";
1316 + if (host && strcmp(host, "*") == 0)
1319 + new = ap_pcalloc(cmd->pool, sizeof(listen_rec));
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 ");
1329 + fprintf(stderr, "host \"%s\" ", host);
1331 + fprintf(stderr, "port \"%s\" ", port);
1332 + fprintf(stderr, "--- %s\n", gai_strerror(error));
1335 + if (res->ai_next) {
1337 + fprintf(stderr, "host \"%s\" ", host);
1339 + fprintf(stderr, "port \"%s\" ", port);
1340 + fprintf(stderr, "resolved to multiple addresses, ambiguous.\n");
1343 - new->local_addr.sin_port = htons((unsigned short)port);
1345 + memcpy(&new->local_addr, res->ai_addr, res->ai_addrlen);
1349 new->next = ap_listeners;
1350 @@ -3651,7 +3718,7 @@
1351 { "ThreadStackSize", set_threadstacksize, NULL, RSRC_CONF, TAKE1,
1352 "Stack size each created thread will use."},
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"},
1359 @@ -3685,7 +3752,7 @@
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" },
1367 { "BS2000Account", set_bs2000_account, NULL, RSRC_CONF, TAKE1,
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
1371 #include <sys/prctl.h>
1374 +#include "sa_len.h"
1377 /* special debug stuff -- PCS */
1379 @@ -210,7 +212,12 @@
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};
1385 +API_VAR_EXPORT int ap_default_family = PF_INET6;
1387 +API_VAR_EXPORT int ap_default_family = PF_INET;
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;
1393 @@ -1461,7 +1468,11 @@
1394 fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin);
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]"
1403 fprintf(stderr, "Options:\n");
1405 fprintf(stderr, " -R directory : specify an alternate location for shared object files\n");
1406 @@ -1487,6 +1498,10 @@
1408 fprintf(stderr, " -F : run main process in foreground, for process supervisors\n");
1411 + fprintf(stderr, " -4 : assume IPv4 on parsing configuration file\n");
1412 + fprintf(stderr, " -6 : assume IPv6 on parsing configuration file\n");
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");
1417 @@ -3740,11 +3755,13 @@
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,
1427 conn_rec *conn = (conn_rec *) ap_pcalloc(p, sizeof(conn_rec));
1428 + char hostnamebuf[MAXHOSTNAMELEN];
1431 /* Got a connection structure, so initialize what fields we can
1432 * (the rest are zeroed out by pcalloc).
1433 @@ -3753,17 +3770,29 @@
1434 conn->child_num = child_num;
1437 - conn->local_addr = *saddr;
1438 - conn->local_ip = ap_pstrdup(conn->pool,
1439 - inet_ntoa(conn->local_addr.sin_addr));
1441 + addr_len = SA_LEN(saddr);
1443 + addr_len = saddr->sa_len;
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;
1454 - conn->remote_addr = *remaddr;
1455 - conn->remote_ip = ap_pstrdup(conn->pool,
1456 - inet_ntoa(conn->remote_addr.sin_addr));
1458 + addr_len = SA_LEN(remaddr);
1460 + addr_len = remaddr->sa_len;
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);
1467 conn->ctx = ap_ctx_new(conn->pool);
1469 @@ -3821,21 +3850,47 @@
1470 #define sock_disable_nagle(s, c) /* NOOP */
1473 -static int make_sock(pool *p, const struct sockaddr_in *server)
1474 +static int make_sock(pool *p, const struct sockaddr *server)
1479 + char addr[INET6_ADDRSTRLEN + 128];
1480 + char a0[INET6_ADDRSTRLEN];
1481 + char p0[NI_MAXSERV];
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));
1490 - ap_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port));
1491 + switch(server->sa_family){
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();
1505 + getnameinfo(server,
1511 + a0, sizeof(a0), p0, sizeof(p0), NI_NUMERICHOST | NI_NUMERICSERV);
1512 + ap_snprintf(addr, sizeof(addr), "address %s port %s", a0, p0);
1514 + if (atoi(p0) < 1024)
1518 /* note that because we're about to slack we don't use psocket */
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);
1525 @@ -3930,15 +3985,19 @@
1528 /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
1529 - if (ntohs(server->sin_port) < 1024)
1534 - if (bind(s, (struct sockaddr *) server, sizeof(struct sockaddr_in)) == -1) {
1536 + if (bind(s, server, SA_LEN(server)) == -1)
1538 + if (bind(s, server, server->sa_len) == -1)
1541 ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
1542 "make_sock: could not bind to %s", addr);
1544 - if (ntohs(server->sin_port) < 1024)
1549 @@ -3947,7 +4006,7 @@
1553 - if (ntohs(server->sin_port) < 1024)
1558 @@ -4162,15 +4221,17 @@
1560 fd = find_listener(lr);
1562 - fd = make_sock(p, &lr->local_addr);
1563 + fd = make_sock(p, (struct sockaddr *)&lr->local_addr);
1566 ap_note_cleanups_for_socket_ex(p, fd, 1);
1568 /* if we get here, (fd >= 0) && (fd < FD_SETSIZE) */
1569 - FD_SET(fd, &listenfds);
1570 - if (fd > listenmaxfd)
1573 + FD_SET(fd, &listenfds);
1574 + if (fd > listenmaxfd)
1578 if (lr->next == NULL)
1580 @@ -4521,8 +4582,8 @@
1581 static void child_main(int child_num_arg)
1584 - struct sockaddr sa_server;
1585 - struct sockaddr sa_client;
1586 + struct sockaddr_storage sa_server;
1587 + struct sockaddr_storage sa_client;
1590 /* All of initialization is a critical section, we don't care if we're
1591 @@ -4711,7 +4772,7 @@
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)
1600 @@ -4900,7 +4961,7 @@
1601 #endif /* NONBLOCK_WHEN_MULTI_LISTEN */
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 "
1609 @@ -4948,8 +5009,8 @@
1610 ap_bpushfd(conn_io, csd, dupped_csd);
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,
1620 @@ -5104,12 +5165,13 @@
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)
1627 - if ((pid = os_fork(s, slot)) == -1) {
1628 + if ((pid = os_fork(s, slot)) == -1)
1630 - if ((pid = fork()) == -1) {
1631 + if ((pid = fork()) == -1)
1634 ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new process");
1636 /* fork didn't succeed. Fix the scoreboard or else
1637 @@ -5756,7 +5818,10 @@
1638 ap_setup_prelinked_modules();
1640 while ((c = getopt(argc, argv,
1641 - "D:C:c:xXd:Ff:vVlLR:StTh"
1642 + "D:C:c:xXd:Ff:vVlLR:StTh4"
1646 #ifdef DEBUG_SIGSTOP
1649 @@ -5834,8 +5899,14 @@
1650 ap_configtestonly = 1;
1651 ap_docrootcheck = 0;
1656 + ap_default_family = PF_INET;
1660 + ap_default_family = PF_INET6;
1666 @@ -5924,9 +5995,10 @@
1670 - struct sockaddr sa_server, sa_client;
1672 + struct sockaddr_storage sa_server, sa_client;
1674 + char servbuf[NI_MAXSERV];
1677 /* Yes this is called twice. */
1678 @@ -5981,25 +6053,32 @@
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));
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");
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),
1700 + fprintf(stderr, "getnameinfo(): family=%d\n", sa_server.ss_family);
1703 + servbuf[sizeof(servbuf)-1] = '\0';
1704 + server_conf->port = atoi(servbuf);
1705 cio = ap_bcreate(ptrans, B_RDWR | B_SOCKET);
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);
1714 while ((r = ap_read_request(conn)) != NULL) {
1716 @@ -7713,7 +7792,11 @@
1718 while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLz:Z:wiuStThk:n:W:")) != -1) {
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"
1729 @@ -8259,6 +8342,10 @@
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
1743 #include "http_log.h"
1744 #include "http_vhost.h"
1745 #include "http_protocol.h"
1746 +#include "sa_len.h"
1749 * After all the definitions there's an explanation of how it's all put
1750 @@ -123,78 +124,114 @@
1751 * *paddr is the variable used to keep track of **paddr between calls
1752 * port is the default port to assume
1754 -static const char *get_addresses(pool *p, char *w, server_addr_rec ***paddr,
1756 +static const char *get_addresses(pool *p, char *w, char *pstr,
1757 + server_addr_rec ***paddr, unsigned port)
1759 - struct hostent *hep;
1760 - unsigned long my_addr;
1761 + struct addrinfo hints, *res, *res0;
1762 server_addr_rec *sar;
1764 - int i, is_an_ip_addr;
1765 + char *t = NULL, *u = NULL, *v = NULL;
1766 + char *hoststr = NULL, *portstr = NULL;
1767 + char portpool[10];
1769 + char servbuf[NI_MAXSERV];
1772 + if (w == 0 || *w == 0)
1775 - t = strchr(w, ':');
1777 - if (strcmp(t + 1, "*") == 0) {
1779 + portstr = portpool;
1780 + ap_snprintf(portpool, sizeof(portpool), "%u", port);
1785 + u = strrchr(w, ']');
1786 + if (u) { /* [host]:port or [host] */
1792 - else if ((i = atoi(t + 1))) {
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 */
1803 - return ":port must be numeric";
1811 - is_an_ip_addr = 0;
1812 - if (strcmp(w, "*") == 0) {
1813 - my_addr = htonl(INADDR_ANY);
1814 - is_an_ip_addr = 1;
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;
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) {
1827 + hints.ai_family = PF_UNSPEC;
1828 + hints.ai_flags = AI_PASSIVE;
1830 + else if (strcasecmp(w, "_default4_") == 0 ||
1831 + ((ap_default_family == PF_INET
1833 + || ap_default_family == PF_UNSPEC
1835 + ) && strcasecmp(w, "_default_") == 0)){
1836 + hoststr = "255.255.255.255";
1837 + hints.ai_family = PF_INET;
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;
1847 - if (is_an_ip_addr) {
1848 - sar = ap_pcalloc(p, sizeof(server_addr_rec));
1850 - *paddr = &sar->next;
1851 - sar->host_addr.s_addr = my_addr;
1852 - sar->host_port = port;
1853 - sar->virthost = ap_pstrdup(p, w);
1860 + hints.ai_family = PF_UNSPEC;
1863 - hep = gethostbyname(w);
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);
1872 + "Cannot resolve host %s port %s --- ignoring!", hoststr, portstr);
1873 + if (t != NULL) *t = ':';
1874 + if (u != NULL) *u = ']';
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) {
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);
1892 sar = ap_pcalloc(p, sizeof(server_addr_rec));
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);
1902 + sar->host_port = 0;
1903 sar->virthost = ap_pstrdup(p, w);
1908 + freeaddrinfo(res0);
1909 + if (t != NULL) *t = ':';
1910 + if (u != NULL) *u = ']';
1915 /* start the list of addreses */
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,
1924 @@ -226,10 +264,11 @@
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,
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,
1938 @@ -303,6 +342,19 @@
1939 return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
1942 +static unsigned hash_addr(struct sockaddr *sa)
1944 + switch (sa->sa_family) {
1946 + return hash_inaddr(((struct sockaddr_in *)sa)->sin_addr.s_addr);
1949 + return hash_inaddr(((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12]);
1952 + return hash_inaddr(sa->sa_family);
1957 static ipaddr_chain *new_ipaddr_chain(pool *p,
1958 @@ -330,25 +382,77 @@
1963 -static ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
1965 +static ap_inline ipaddr_chain *find_ipaddr(struct sockaddr *sa)
1970 + char a[NI_MAXHOST], b[NI_MAXHOST];
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
1982 + if (sar->host_addr.ss_family != sa->sa_family)
1984 + switch (sa->sa_family) {
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) {
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) {
2015 + default: /*unsupported*/
2021 + if (sa->sa_family == AF_INET6 &&
2022 + IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) {
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.
2028 + struct sockaddr_in sin;
2030 + memset(&sin, 0, sizeof(sin));
2031 + sin.sin_family = AF_INET;
2033 + sin.sin_len = sizeof(sin);
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);
2046 @@ -374,21 +478,7 @@
2048 char buf[MAX_STRING_LEN];
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);
2054 - else if (ic->sar->host_addr.s_addr == INADDR_ANY) {
2055 - len = ap_snprintf(buf, sizeof(buf), "*:%u",
2056 - ic->sar->host_port);
2059 - len = ap_snprintf(buf, sizeof(buf), "%pA:%u",
2060 - &ic->sar->host_addr, ic->sar->host_port);
2062 - if (ic->sar->host_port == 0) {
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);
2069 @@ -516,10 +606,37 @@
2070 * occured in the config file, we'll copy it in that order.
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);
2078 - if (sar->host_addr.s_addr != INADDR_ANY) {
2080 + switch (sar->host_addr.ss_family) {
2083 + struct sockaddr_in *sin;
2084 + sin = (struct sockaddr_in *)&sar->host_addr;
2085 + if (sin->sin_addr.s_addr == INADDR_ANY)
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) {
2106 *iphash_table_tail[bucket] = ic;
2107 iphash_table_tail[bucket] = &ic->next;
2109 @@ -546,12 +663,45 @@
2110 has_default_vhost_addr = 0;
2111 for (sar = s->addrs; sar; sar = sar->next) {
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) {
2121 + switch (sar->host_addr.ss_family) {
2124 + struct sockaddr_in *sin;
2125 + sin = (struct sockaddr_in *)&sar->host_addr;
2126 + if (sin->sin_addr.s_addr == DEFAULT_VHOST_ADDR)
2128 + else if (sin->sin_addr.s_addr == INADDR_ANY)
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) {
2149 + /* add it to default bucket for each appropriate sar
2150 + * since we need to do a port test
2152 + ipaddr_chain *other;
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);
2160 @@ -564,10 +714,11 @@
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);
2168 - unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
2170 + hash_addr((struct sockaddr *)&sar->host_addr);
2172 ic = new_ipaddr_chain(p, s, sar);
2173 ic->next = *iphash_table_tail[bucket];
2174 @@ -604,19 +755,33 @@
2178 + char hostnamebuf[MAXHOSTNAMELEN];
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,
2185 + SA_LEN((struct sockaddr *)&s->addrs->host_addr),
2187 + s->addrs->host_addr.ss_len,
2189 + hostnamebuf, sizeof(hostnamebuf),
2191 + s->server_hostname = ap_pstrdup(p, hostnamebuf);
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,
2198 + SA_LEN((struct sockaddr *)&s->addrs->host_addr),
2200 + s->addrs->host_addr.ss_len,
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 "
2208 - inet_ntoa(s->addrs->host_addr));
2209 + "ServerName", hostnamebuf);
2210 s->server_hostname =
2211 ap_pstrdup(p, "bogus_host_without_reverse_dns");
2213 @@ -664,45 +829,81 @@
2216 const char *port_str;
2217 + const char *u, *v = NULL;
2219 /* check and copy the host part */
2220 - src = r->hostname;
2221 + u = src = r->hostname;
2225 - if (*src == '.') {
2232 - if (*src == '/' || *src == '\\') {
2235 - if (*src == ':') {
2236 - port_str = src + 1;
2237 - /* check the port part */
2239 - if (!ap_isdigit(*src)) {
2240 + if (*u == '[') { /* IPv6 numeral address in brackets */
2241 + v = strchr(u, ']');
2243 + /* missing closing bracket */
2246 + if (v == (u + 1)) {
2247 + /* bad empty address */
2250 + for (src = u+1; src < v; src++) /* copy IPv6 adress */
2256 + while (*v) { /* check if portnum is correct */
2257 + if (!ap_isdigit(*v++))
2261 - if (src[-1] == ':')
2265 + /* a known "good" port value */
2267 + iport = atoi(port_str);
2268 + if (iport < 1 || iport > 65535) {
2271 + r->parsed_uri.port_str = ap_pstrdup(r->pool, port_str);
2272 + r->parsed_uri.port = iport;
2277 + if (*src == '.') {
2284 + if (*src == '/' || *src == '\\') {
2287 - /* a known "good" port value */
2289 - iport = atoi(port_str);
2290 - if (iport < 1 || iport > 65535) {
2292 + if (*src == ':') {
2293 + port_str = src + 1;
2294 + /* sheck the port part */
2296 + if (!ap_isdigit(*src)) {
2300 + if (src[-1] == ':')
2303 + /* a known "good" port value */
2305 + iport = atoi(port_str);
2306 + if (iport < 1 || iport > 65535) {
2309 + r->parsed_uri.port_str = ap_pstrdup(r->pool, port_str);
2310 + r->parsed_uri.port = iport;
2313 - r->parsed_uri.port_str = ap_pstrdup(r->pool, port_str);
2314 - r->parsed_uri.port = iport;
2321 /* strip trailing gubbins */
2322 if (dst > host && dst[-1] == '.') {
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);
2332 @@ -820,11 +1021,25 @@
2333 * names we'll match have ports associated with them
2335 const char *host = r->hostname;
2336 - unsigned port = ntohs(r->connection->local_addr.sin_port);
2342 + switch (r->connection->local_addr.ss_family) {
2344 + port = ntohs(((struct sockaddr_in *)
2345 + &r->connection->local_addr)->sin_port);
2349 + port = ntohs(((struct sockaddr_in6 *)
2350 + &r->connection->local_addr)->sin6_port);
2358 /* Recall that the name_chain is a list of server_addr_recs, some of
2359 @@ -879,7 +1094,22 @@
2363 - unsigned port = ntohs(r->connection->local_addr.sin_port);
2366 + switch (r->connection->local_addr.ss_family) {
2368 + port = ntohs(((struct sockaddr_in *)
2369 + &r->connection->local_addr)->sin_port);
2373 + port = ntohs(((struct sockaddr_in6 *)
2374 + &r->connection->local_addr)->sin6_port);
2382 * This is in conjunction with the ServerPath code in http_core, so we
2383 @@ -939,10 +1169,22 @@
2384 API_EXPORT(void) ap_update_vhost_given_ip(conn_rec *conn)
2387 - unsigned port = ntohs(conn->local_addr.sin_port);
2388 + char portbuf[NI_MAXSERV];
2391 + if (getnameinfo((struct sockaddr *)&conn->local_addr,
2393 + SA_LEN((struct sockaddr *)&conn->local_addr),
2395 + conn->local_addr.ss_len,
2397 + NULL, 0, portbuf, sizeof(portbuf), NI_NUMERICSERV) != 0) {
2400 + port = atoi(portbuf);
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);
2406 /* save the name_chain for later in case this is a name-vhost */
2407 conn->vhost_lookup_data = trav->names;
2408 @@ -960,6 +1202,7 @@
2413 /* otherwise we're stuck with just the main server
2414 * and no name-based vhosts
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
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"
2425 /* Semi-well-known port */
2426 @@ -100,12 +101,13 @@
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)
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 */
2443 char buffer[RFC1413_MAXDATA + 1];
2444 @@ -120,16 +122,47 @@
2445 * addresses from the query socket.
2448 - our_query_sin = *our_sin;
2449 - our_query_sin.sin_port = htons(ANY_PORT);
2451 - our_query_sin.sin_addr.s_addr = INADDR_ANY;
2453 + memcpy(&our_query_sin, our_sin, SA_LEN(our_sin));
2454 + memcpy(&rmt_query_sin, rmt_sin, SA_LEN(rmt_sin));
2456 + memcpy(&our_query_sin, our_sin, our_sin->sa_len);
2457 + memcpy(&rmt_query_sin, rmt_sin, rmt_sin->sa_len);
2459 + switch (our_sin->sa_family) {
2462 + ((struct sockaddr_in *)&our_query_sin)->sin_addr.s_addr = INADDR_ANY; /* XXX: htonl(??) */
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);
2472 + memcpy(&((struct sockaddr_in6 *)&our_query_sin)->sin6_addr,
2473 + &in6addr_any, sizeof(struct in6_addr));
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);
2481 - rmt_query_sin = *rmt_sin;
2482 - rmt_query_sin.sin_port = htons(RFC1413_PORT);
2484 + /* unsupported AF */
2488 if (bind(sock, (struct sockaddr *) &our_query_sin,
2489 - sizeof(struct sockaddr_in)) < 0) {
2491 + SA_LEN((struct sockaddr *) &our_query_sin)
2493 + our_query_sin.ss_len
2496 ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
2497 "bind: rfc1413: Error binding to local port");
2499 @@ -140,12 +173,18 @@
2502 if (connect(sock, (struct sockaddr *) &rmt_query_sin,
2503 - sizeof(struct sockaddr_in)) < 0)
2506 + SA_LEN((struct sockaddr *) &rmt_query_sin)
2508 + rmt_query_sin.ss_len
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,
2520 /* send query to server. Handle short write. */
2521 #ifdef CHARSET_EBCDIC
2523 ascii2ebcdic(buffer, buffer, (size_t)i);
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) {
2533 * Strip trailing carriage return. It is part of the
2536 result = FROM_UNKNOWN;
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);
2541 ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
2542 "socket: rfc1413: error creating socket");
2543 @@ -253,8 +292,10 @@
2544 if (ap_setjmp(timebuf) == 0) {
2545 ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout);
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) {
2553 ap_set_callback_and_alarm(NULL, 0);
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 @@
2558 * Parses a host of the form <address>[:port]
2559 * :port is permitted if 'port' is not NULL
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)
2564 - struct hostent *hep;
2565 - unsigned long my_addr;
2568 - p = strchr(w, ':');
2569 + static struct sockaddr_storage ss;
2570 + struct addrinfo hints, *res;
2575 + char servbuf[NI_MAXSERV];
2581 + if (r = strrchr(w+1, ']')){
2597 + p = strchr(w, ':');
2598 + if (p != NULL && strchr(p+1, ':') != NULL)
2601 if (ports != NULL) {
2603 - if (p != NULL && strcmp(p + 1, "*") != 0)
2604 - *ports = atoi(p + 1);
2605 + if (p != NULL && *p && strcmp(p + 1, "*") != 0)
2609 + memset(&hints, 0, sizeof(hints));
2610 + hints.ai_socktype = SOCK_STREAM;
2613 if (strcmp(w, "*") == 0) {
2616 - return htonl(INADDR_ANY);
2619 - my_addr = ap_inet_addr((char *)w);
2620 - if (my_addr != INADDR_NONE) {
2625 + hints.ai_flags = AI_PASSIVE;
2626 + hints.ai_family = ap_default_family;
2629 + hints.ai_family = PF_UNSPEC;
2632 - hep = gethostbyname(w);
2633 + error = getaddrinfo(host, port, &hints, &res);
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));
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");
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),
2661 + fprintf(stderr, "ap_get_virthost_addr(): getnameinfo() failed --- Exiting!!!\n");
2664 + if (ports) *ports = atoi(servbuf);
2665 + freeaddrinfo(res);
2666 + return (struct sockaddr *)&ss;
2670 @@ -2117,7 +2152,8 @@
2672 char str[MAXHOSTNAMELEN];
2673 char *server_hostname = NULL;
2674 - struct hostent *p;
2675 + struct addrinfo hints, *res;
2678 #ifdef BEOS /* BeOS returns zero as an error for gethostname */
2679 if (gethostname(str, sizeof(str) - 1) == 0) {
2680 @@ -2130,29 +2166,38 @@
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 */
2695 - /* Since we found a fqdn, return it with no logged message. */
2696 - return server_hostname;
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");
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);
2714 + /* Recovery - return the default servername by IP: */
2716 + fprintf(stderr, "%s: cannot determine local host name.\n",
2718 + fprintf(stderr, "Use the ServerName directive to set it manually.\n");
2721 + server_hostname = ap_pstrdup(a, res->ai_canonname);
2723 + else if (1) /*fqdn found*/
2725 + /* XXX should check more conditions */
2726 + server_hostname = ap_pstrdup(a, res->ai_canonname);
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);
2736 + /* Since we found a fdqn, return it with no logged message. */
2737 + freeaddrinfo(res);
2740 return server_hostname;
2742 @@ -2396,3 +2441,11 @@
2747 +#ifdef NEED_GETADDRINFO
2748 +#include "getaddrinfo.c"
2751 +#ifdef NEED_GETNAMEINFO
2752 +#include "getnameinfo.c"
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
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"
2765 array_header *hdrs_arr = ap_table_elts(r->headers_in);
2766 table_entry *hdrs = (table_entry *) hdrs_arr->elts;
2768 + char servbuf[NI_MAXSERV];
2770 /* use a temporary table which we'll overlap onto
2771 * r->subprocess_env later
2772 @@ -252,8 +254,16 @@
2773 ap_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
2774 ap_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */
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),
2783 + c->remote_addr.ss_len,
2785 + NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)){
2786 + ap_table_addn(e, "REMOTE_PORT", ap_pstrdup(r->pool, servbuf));
2790 ap_table_addn(e, "REMOTE_USER", c->user);
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 @@
2794 * the hostname. If there's a port it is the first colon.
2796 s = memchr(hostinfo, ':', uri - hostinfo);
2797 + if (*hostinfo == '[') {
2798 + s = memchr(hostinfo+1, ']', uri - hostinfo - 1);
2800 + s = strchr(s, ':');
2802 + s = memchr(hostinfo, ':', uri - hostinfo);
2804 /* we expect the common case to have no port */
2805 uptr->hostname = ap_pstrndup(p, hostinfo, uri - hostinfo);
2806 @@ -438,7 +444,12 @@
2807 /* We expect hostinfo to point to the first character of
2808 * the hostname. There must be a port, separated by a colon
2810 - s = strchr(hostinfo, ':');
2811 + if (*hostinfo == '[') {
2812 + s = strchr(hostinfo+1, ']');
2814 + s = strchr(s, ':');
2816 + s = strchr(hostinfo, ':');
2818 return HTTP_BAD_REQUEST;
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 @@
2823 struct proxy_remote *new;
2826 + char *bl = NULL, *br = NULL;
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, ':');
2834 + br = strrchr(bl+1, ']');
2838 + if (*(br+1) == ':'){ /* [host]:xx */
2841 + else if (*(br+1) == '\0'){ /* [host] */
2845 + q = strrchr(br, ':'); /* XXX */
2848 + q = strrchr(bl, ':'); /* XXX */
2851 + q = strrchr(bl, ':');
2853 if (sscanf(q + 1, "%u", &port) != 1 || port > 65535)
2854 return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)";
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 */
2865 new = ap_push_array(conf->proxies);
2868 - new->hostname = p + 3;
2869 + new->hostname = bl;
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
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);
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
2887 const char *proxyhost, int proxyport)
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;
2898 char buffer[HUGE_STRING_LEN];
2904 void *sconf = r->server->module_config;
2905 proxy_server_conf *conf =
2907 struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
2909 memset(&server, '\0', sizeof(server));
2910 +#ifdef HAVE_SOCKADDR_LEN
2911 + server.sin_len = sizeof(server);
2913 server.sin_family = AF_INET;
2915 /* Break the URL into host:port pairs */
2919 p = strchr(url, ':');
2921 - port = DEFAULT_HTTPS_PORT;
2923 - port = atoi(p + 1);
2926 + ap_snprintf(pbuf, sizeof(pbuf), "%d", DEFAULT_HTTPS_PORT);
2932 + port = atoi(portstr);
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);
2940 + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
2941 + gai_strerror(error)); /* give up */
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;
2955 + for (i = 0; i < conf->noproxies->nelts; i++) {
2956 + if (npent[i].name != NULL && strstr(hoststr, npent[i].name))
2958 + if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
2960 + switch (res->ai_family) {
2962 + sin = (struct sockaddr_in *)res->ai_addr;
2963 + if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
2969 + freeaddrinfo(res0);
2970 return ap_proxyerror(r, HTTP_FORBIDDEN,
2971 "Connect to remote machine blocked");
2975 /* Check if it is an allowed port */
2976 @@ -117,34 +150,42 @@
2977 case DEFAULT_SNEWS_PORT:
2980 + freeaddrinfo(res0);
2981 return HTTP_FORBIDDEN;
2984 - else if (!allowed_port(conf, port))
2985 + else if (!allowed_port(conf, port)) {
2986 + freeaddrinfo(res0);
2987 return HTTP_FORBIDDEN;
2993 + freeaddrinfo(res0);
2995 + ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
2996 + memset(&hints, 0, sizeof(hints));
2997 + hints.ai_family = PF_UNSPEC;
2998 + hints.ai_socktype = SOCK_STREAM;
2999 + hints.ai_protocol = IPPROTO_TCP;
3000 + error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
3002 + return HTTP_INTERNAL_SERVER_ERROR; /* XXX */
3004 ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
3005 "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
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);
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);
3018 - return ap_proxyerror(r,
3019 - proxyhost ? HTTP_BAD_GATEWAY : HTTP_INTERNAL_SERVER_ERROR, err);
3021 - sock = ap_psocket_ex(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3023 - ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "proxy: error creating socket");
3024 - return HTTP_INTERNAL_SERVER_ERROR;
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);
3032 #ifdef CHECK_FD_SETSIZE
3033 if (sock >= FD_SETSIZE) {
3034 @@ -154,19 +195,15 @@
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;
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);
3053 + freeaddrinfo(res0);
3055 ap_pclosesocket(r->pool, sock);
3056 return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, ap_pstrcat(r->pool,
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
3060 #include "http_main.h"
3061 #include "http_log.h"
3062 #include "http_core.h"
3063 +#include "sa_len.h"
3065 #define AUTODETECT_PWD
3067 @@ -514,8 +515,10 @@
3069 int destport, i, j, len, rc, nocache = 0;
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;
3077 struct in_addr destaddr;
3080 @@ -538,11 +541,18 @@
3081 unsigned int presult, h0, h1, h2, h3, p0, p1;
3083 unsigned short pport;
3084 - struct sockaddr_in data_addr;
3085 + struct sockaddr_storage data_addr;
3086 + struct sockaddr_in *sin;
3091 +/* stuff for LPSV/EPSV */
3092 + unsigned int paf, holen, ho[16], polen, po[2];
3093 + struct sockaddr_in6 *sin6;
3097 /* stuff for responses */
3098 char resp[MAX_STRING_LEN];
3100 @@ -636,62 +646,50 @@
3104 - memset(&server, 0, sizeof(struct sockaddr_in));
3105 - server.sin_family = AF_INET;
3106 - server.sin_port = htons((unsigned short)destport);
3107 - err = ap_proxy_host2addr(desthost, &server_hp);
3109 - return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
3111 - sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3113 - ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3114 - "proxy: error creating socket");
3115 - return HTTP_INTERNAL_SERVER_ERROR;
3116 + ap_snprintf(portbuf, sizeof(portbuf), "%d", destport);
3117 + memset(&hints, 0, sizeof(hints));
3118 + hints.ai_family = PF_UNSPEC;
3119 + hints.ai_socktype = SOCK_STREAM;
3120 + error = getaddrinfo(desthost, portbuf, &hints, &res0);
3122 + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, gai_strerror(error));
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);
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))
3137 - ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3138 - "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
3140 + if (conf->recv_buffer_size > 0
3141 + && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
3142 + (const char *)&conf->recv_buffer_size, sizeof(int))
3144 + ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3145 + "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
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 */
3166 -#ifdef SINIX_D_RESOLVER_BUG
3168 - struct in_addr *ip_addr = (struct in_addr *)*server_hp.h_addr_list;
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);
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);
3184 + i = ap_proxy_doconnect(sock, res->ai_addr, r);
3186 + memcpy(&server, res->ai_addr, res->ai_addrlen);
3190 + ap_pclosesocket(p, sock);
3193 + freeaddrinfo(res0);
3195 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3196 ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool,
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);
3204 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3205 ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3206 @@ -939,11 +937,22 @@
3210 - ap_bputs("PASV" CRLF, ctrl);
3212 + if (server.ss_family == AF_INET)
3214 + else if (lpsvmode)
3218 + ap_bputs(cmd, ctrl);
3219 + ap_bputs(CRLF, 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. */
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)));
3240 @@ -982,10 +991,14 @@
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;
3251 + sin->sin_len = sizeof(*sin);
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);
3258 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3259 @@ -995,6 +1008,64 @@
3260 strerror(errno), NULL)));
3263 + } else if (presult == 228 && pstr != NULL
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) {
3271 + sin6 = (struct sockaddr_in6 *)&data_addr;
3272 + sin6->sin6_family = AF_INET6;
3274 + sin6->sin6_len = sizeof(*sin6);
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);
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)));
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|" */
3294 + memcpy(&data_addr, &server, SA_LEN((struct sockaddr *)&server));
3296 + memcpy(&data_addr, &server, server.ss_len);
3298 + switch (data_addr.ss_family) {
3300 + sin = (struct sockaddr_in *)&data_addr;
3301 + sin->sin_port = htons(atoi(pstr + 3));
3304 + sin6 = (struct sockaddr_in6 *)&data_addr;
3305 + sin6->sin6_port = htons(atoi(pstr + 3));
3308 + i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
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)));
3318 + } else if (!lpsvmode && strcmp(cmd, "EPSV") == 0) {
3323 ap_pclosesocket(p, dsock); /* and try the regular way */
3324 @@ -1003,14 +1074,14 @@
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"));
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);
3339 return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
3340 ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3341 @@ -1026,13 +1097,28 @@
3342 #endif /* _OSD_POSIX */
3345 - if (bind(dsock, (struct sockaddr *)&server,
3346 - sizeof(struct sockaddr_in)) == -1) {
3348 + if (bind(dsock, (struct sockaddr *)&server, SA_LEN((struct sockaddr *)&server)) == -1)
3350 + if (bind(dsock, (struct sockaddr *)&server, server.ss_len) == -1)
3353 + char hostnamebuf[MAXHOSTNAMELEN], portnamebuf[MAXHOSTNAMELEN];
3355 + getnameinfo((struct sockaddr *)&server,
3357 + SA_LEN((struct sockaddr *)&server),
3361 + hostnamebuf, sizeof(hostnamebuf),
3362 + portnamebuf, sizeof(portnamebuf),
3363 + NI_NUMERICHOST | NI_NUMERICSERV);
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)));
3372 listen(dsock, 2); /* only need a short queue */
3374 @@ -1286,7 +1372,7 @@
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);
3381 csd = accept(dsock, (struct sockaddr *)&server, &clen);
3382 while (csd == -1 && errno == EINTR);
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
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;
3395 char buffer[HUGE_STRING_LEN];
3398 if (conf->cache.root == NULL)
3401 - memset(&server, '\0', sizeof(server));
3402 - server.sin_family = AF_INET;
3404 /* We break the URL into host, port, path-search */
3406 urlptr = strstr(url, "://");
3408 return HTTP_BAD_REQUEST;
3410 destport = DEFAULT_HTTP_PORT;
3411 + ap_snprintf(portstr, sizeof(portstr), "%d", DEFAULT_HTTP_PORT);
3412 + destportstr = portstr;
3414 ap_hook_use("ap::mod_proxy::http::handler::set_destport",
3415 AP_HOOK_SIG2(int,ptr),
3416 @@ -170,7 +168,20 @@
3421 + if (*desthost == '['){
3422 + char *u = strrchr(desthost+1, ']');
3426 + if (*(u+1) == ':'){ /* [host]:xx */
3428 + } else if (*(u+1) == '\0'){ /* [host] */
3431 + return HTTP_BAD_REQUEST;
3433 + return HTTP_BAD_REQUEST;
3435 strp2 = strchr(desthost, ':');
3436 if (strp2 != NULL) {
3438 @@ -180,46 +191,71 @@
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);
3448 + return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
3449 + gai_strerror(error)); /* give up */
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;
3461 + struct sockaddr_in6 *sin6;
3466 + for (i = 0; i < conf->noproxies->nelts; i++) {
3467 + if (npent[i].name != NULL && strstr(desthost, npent[i].name))
3469 + if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
3471 + switch (res->ai_family) {
3473 + sin = (struct sockaddr_in *)res->ai_addr;
3474 + if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
3480 + freeaddrinfo(res0);
3481 return ap_proxyerror(r, HTTP_FORBIDDEN,
3482 "Connect to remote machine blocked");
3486 if (proxyhost != NULL) {
3487 - server.sin_port = htons((unsigned short)proxyport);
3488 - err = ap_proxy_host2addr(proxyhost, &server_hp);
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);
3500 return DECLINED; /* try another */
3502 peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);
3506 - server.sin_port = htons((unsigned short)destport);
3507 - err = ap_proxy_host2addr(desthost, &server_hp);
3509 - return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
3511 - peer = ap_psprintf(p, "%s:%u", desthost, destport);
3517 * we have worked out who exactly we are going to connect to, now make
3518 * that connection...
3520 - sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3522 - ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
3523 - "proxy: error creating socket");
3524 - return HTTP_INTERNAL_SERVER_ERROR;
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);
3532 #if !defined(TPF) && !defined(BEOS)
3533 if (conf->recv_buffer_size) {
3534 @@ -232,38 +268,13 @@
3538 -#ifdef SINIX_D_RESOLVER_BUG
3540 - struct in_addr *ip_addr = (struct in_addr *)*server_hp.h_addr_list;
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);
3548 - * Even if the connection was unsuccesful we should
3549 - * reinit the socket
3551 - sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
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);
3560 + i = ap_proxy_doconnect(sock, res->ai_addr, r);
3564 - * Even if the connection was unsuccesful we should
3565 - * reinit the socket
3567 - sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
3568 + ap_pclosesocket(p, sock);
3572 + freeaddrinfo(res0);
3574 if (proxyhost != NULL)
3575 return DECLINED; /* try again another way */
3576 @@ -595,17 +606,30 @@
3577 ap_table_set(resp_hdrs, "Content-Location", proxy_location_reverse_map(r, urlstr));
3579 /* check if NoCache directive on this host */
3581 + struct sockaddr_in *sin;
3583 + struct sockaddr_in6 *sin6;
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))) {
3594 + if (ncent[i].name != NULL &&
3595 + (ncent[i].name[0] == '*' ||
3596 + strstr(desthost, ncent[i].name) != NULL)) {
3600 + switch (res->ai_addr->sa_family) {
3602 + sin = (struct sockaddr_in *)res->ai_addr;
3603 + if (sin->sin_addr.s_addr == ncent[i].addr.s_addr) {
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
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
3617 #include "http_log.h"
3618 #include "util_uri.h"
3619 #include "util_date.h" /* get ap_checkmask() decl. */
3620 +#include "sa_len.h"
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);
3626 char *strp, *host, *url = *urlp;
3627 char *user = NULL, *password = NULL;
3628 + char *t = NULL, *u = NULL, *v = NULL;
3630 if (url[0] != '/' || url[1] != '/')
3631 return "Malformed URL";
3632 @@ -215,11 +217,22 @@
3633 *passwordp = password;
3636 - strp = strrchr(host, ':');
3637 - if (strp != NULL) {
3640 - for (i = 0; strp[i] != '\0'; i++)
3642 + if (*host == '['){
3643 + u = strrchr(host, ']');
3650 + t = strrchr(v, ':');
3656 + for (i=0; strp[i] != '\0'; i++)
3657 if (!ap_isdigit(strp[i]))
3660 @@ -238,17 +251,29 @@
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] != ':')
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";
3672 + if (host[i] == '\0') {
3673 + struct addrinfo hints, *res0;
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)) {
3680 + return gai_strerror(gai);
3682 - if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1))
3683 + return "Bad IP address in URL";
3686 - return "Bad IP address in URL";
3688 + freeaddrinfo(res0);
3694 @@ -1401,22 +1426,46 @@
3695 return host != NULL && strstr(host, This->name) != NULL;
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)
3703 + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
3704 +#ifdef NI_WITHSCOPEID
3705 + const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
3707 + const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
3710 ap_hard_timeout("proxy connect", r);
3711 +#ifdef HAVE_SOCKADDR_LEN
3712 + salen = addr->sa_len;
3714 + switch (addr->sa_family) {
3716 + salen = sizeof(struct sockaddr_in6);
3719 + salen = sizeof(struct sockaddr_in);
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();
3730 } while (i == -1 && errno == EINTR);
3732 + if (getnameinfo(addr, salen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
3734 + strcpy(hbuf, "?");
3735 + strcpy(pbuf, "?");
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));
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
3760 struct in_addr mask;
3764 + struct in6_addr net6;
3765 + struct in6_addr mask6;
3769 enum allowdeny_type type;
3771 @@ -125,94 +134,242 @@
3774 else if ((s = strchr(where, '/'))) {
3775 - struct in_addr mask;
3776 + struct addrinfo hints, *resnet, *resmask;
3777 + struct sockaddr_storage net, mask;
3783 + a->type = T_FAIL; /*just in case*/
3784 /* trample on where, we won't be using it any more */
3788 - || (a->x.ip.net.s_addr = ap_inet_addr(where)) == INADDR_NONE) {
3790 - return "syntax error in network portion of network/netmask";
3792 + for (p = s; *p; p++) {
3799 - /* is_ip just tests if it matches [\d.]+ */
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*/
3808 + error = getaddrinfo(where, NULL, &hints, &resnet);
3809 + if (error || !resnet) {
3811 + freeaddrinfo(resnet);
3813 - return "syntax error in mask portion of network/netmask";
3814 + return "syntax error in network portion of network/netmask";
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) {
3821 - return "syntax error in mask portion of network/netmask";
3823 + if (resnet->ai_next) {
3824 + freeaddrinfo(resnet);
3826 + return "network/netmask resolved to multiple addresses";
3830 + memcpy(&net, resnet->ai_addr, resnet->ai_addrlen);
3831 + freeaddrinfo(resnet);
3833 - /* assume it's in /nnn form */
3835 - if (i > 32 || i <= 0) {
3837 - return "invalid mask in network/netmask";
3839 - mask.s_addr = 0xFFFFFFFFUL << (32 - i);
3840 - mask.s_addr = htonl(mask.s_addr);
3841 + switch (net.ss_family) {
3844 + a->x.ip.net.s_addr = ((struct sockaddr_in *)&net)->sin_addr.s_addr;
3849 + memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&net)->sin6_addr,
3850 + sizeof(a->x.ip6.net6));
3855 + return "unknown address family for network";
3857 - a->x.ip.mask = mask;
3858 - a->x.ip.net.s_addr = (a->x.ip.net.s_addr & mask.s_addr); /* pjr - This fixes PR 4770 */
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 */
3867 - /* parse components */
3869 - a->x.ip.net.s_addr = 0;
3870 - a->x.ip.mask.s_addr = 0;
3874 - if (!ap_isdigit(*t)) {
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*/
3884 + error = getaddrinfo(s, NULL, &hints, &resmask);
3885 + if (error || !resmask) {
3887 + freeaddrinfo(resmask);
3889 - return "invalid ip address";
3891 - while (ap_isdigit(*t)) {
3896 + return "syntax error in mask portion of network/netmask";
3899 + if (resmask->ai_next) {
3900 + freeaddrinfo(resmask);
3902 - return "invalid ip address";
3903 + return "network/netmask resolved to multiple addresses";
3906 + memcpy(&mask, resmask->ai_addr, resmask->ai_addrlen);
3907 + freeaddrinfo(resmask);
3909 + if (net.ss_family != mask.ss_family) {
3911 - return "invalid ip address, only 4 octets allowed";
3912 + return "network/netmask resolved to different address family";
3915 - if (octet < 0 || octet > 255) {
3917 - return "each octet must be between 0 and 255 inclusive";
3919 + switch (a->type) {
3921 + a->x.ip.mask.s_addr =
3922 + ((struct sockaddr_in *)&mask)->sin_addr.s_addr;
3926 + memcpy(&a->x.ip6.mask6,
3927 + &((struct sockaddr_in6 *)&mask)->sin6_addr,
3928 + sizeof(a->x.ip6.mask6));
3935 + switch (a->type) {
3937 + if (mask < 0 || 32 < mask) {
3939 + return "netmask out of range";
3941 + a->x.ip.mask.s_addr = htonl(0xFFFFFFFFUL << (32 - mask));
3947 + if (mask < 0 || 128 < mask) {
3949 + return "netmask out of range";
3951 + for (i = 0; i < mask / 8; i++) {
3952 + a->x.ip6.mask6.s6_addr[i] = 0xff;
3955 + a->x.ip6.mask6.s6_addr[i] = 0xff << (8 - (mask % 8));
3960 - a->x.ip.net.s_addr |= (unsigned int)octet << shift;
3961 - a->x.ip.mask.s_addr |= 0xFFUL << shift;
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);
3967 + /* mask network address */
3968 + switch (a->type) {
3970 + a->x.ip.net.s_addr &= a->x.ip.mask.s_addr;
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];
3982 + struct addrinfo hints, *res;
3983 + struct sockaddr_storage ss;
3986 + a->type = T_FAIL; /*just in case*/
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)) {
3996 + /* parse components */
3998 + a->x.ip.net.s_addr = 0;
3999 + a->x.ip.mask.s_addr = 0;
4003 + if (!ap_isdigit(*t)) {
4005 + return "invalid ip address";
4007 + while (ap_isdigit(*t)) {
4015 + return "invalid ip address";
4018 + return "invalid ip address, only 4 octets allowed";
4021 + if (octet < 0 || octet > 255) {
4023 + return "each octet must be between 0 and 255 inclusive";
4025 + a->x.ip.net.s_addr |= (unsigned int)octet << shift;
4026 + a->x.ip.mask.s_addr |= 0xFFUL << shift;
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);
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*/
4044 + error = getaddrinfo(where, NULL, &hints, &res);
4045 + if (error || !res) {
4047 + freeaddrinfo(res);
4051 + if (res->ai_next) {
4052 + freeaddrinfo(res);
4054 + return "network/netmask resolved to multiple addresses";
4056 + memcpy(&ss, res->ai_addr, res->ai_addrlen);
4057 + freeaddrinfo(res);
4059 + switch (ss.ss_family) {
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));
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));
4075 + return "unknown address family for network";
4081 @@ -276,13 +433,63 @@
4085 - if (ap[i].x.ip.net.s_addr != INADDR_NONE
4086 - && (r->connection->remote_addr.sin_addr.s_addr
4087 - & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
4089 + if (ap[i].x.ip.net.s_addr == INADDR_NONE)
4091 + switch (r->connection->remote_addr.ss_family) {
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) {
4100 + if (!IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr)) /*XXX*/
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) {
4114 + struct in6_addr masked;
4116 + if (IN6_IS_ADDR_UNSPECIFIED(&ap[i].x.ip6.net6))
4118 + switch (r->connection->remote_addr.ss_family) {
4120 + if (!IN6_IS_ADDR_V4MAPPED(&ap[i].x.ip6.net6)) /*XXX*/
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)
4133 + memset(&masked, 0, sizeof(masked));
4135 + &((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr,
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)
4148 remotehost = ap_get_remote_host(r->connection, r->per_dir_config,
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
4154 #include "mod_rewrite.h"
4155 +#include "sa_len.h"
4159 @@ -3667,8 +3668,19 @@
4160 result = r->connection->remote_ip;
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),
4171 + r->connection->remote_addr.ss_len,
4173 + NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)) {
4174 + return ap_pstrdup(r->pool, servbuf);
4176 + return ap_pstrdup(r->pool, "");
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
4184 #include "http_config.h"
4185 #include "http_log.h"
4186 #include "multithread.h"
4187 +#include "sa_len.h"
4189 +/*#define SHORT_UNIQUE_ID*/
4193 - unsigned int in_addr;
4195 + struct in_addr in;
4197 +# ifdef SHORT_UNIQUE_ID
4200 + struct in6_addr in6;
4208 * this shouldn't be a problem till year 2106.
4211 -static unsigned global_in_addr;
4212 +static struct sockaddr_storage global_addr;
4217 #define MAXHOSTNAMELEN 256
4219 char str[MAXHOSTNAMELEN + 1];
4220 - struct hostent *hent;
4221 + struct addrinfo hints, *res, *res0;
4223 #ifndef NO_GETTIMEOFDAY
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);
4237 @@ -227,17 +240,44 @@
4239 str[sizeof(str) - 1] = '\0';
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);
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));
4253 - global_in_addr = ((struct in_addr *) hent->h_addr_list[0])->s_addr;
4255 + for (res = res0; res; res = res->ai_next) {
4256 + switch (res->ai_family) {
4261 + memcpy(&global_addr, res->ai_addr, res->ai_addrlen);
4266 + freeaddrinfo(res0);
4268 + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
4269 + "mod_unique_id: no known AF found for \"%s\"", str);
4273 + getnameinfo((struct sockaddr *)&global_addr,
4275 + SA_LEN((struct sockaddr *)&global_addr),
4277 + global_addr.ss_len,
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);
4286 * If the server is pummelled with restart requests we could possibly end
4287 @@ -294,7 +334,23 @@
4288 "oh no! pids are greater than 32-bits! I'm broken!");
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) {
4295 + cur_unique_id->addr.in = ((struct sockaddr_in *)&global_addr)->sin_addr;
4299 +#ifdef SHORT_UNIQUE_ID
4300 + cur_unique_id->addr.in6 =
4301 + ((struct sockaddr_in6 *)&global_addr)->sin6_addr.s6_addr32[3];
4303 + cur_unique_id->addr.in6 =
4304 + ((struct sockaddr_in6 *)&global_addr)->sin6_addr;
4311 * If we use 0 as the initial counter we have a little less protection
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
4315 long reqtime = (long) r->request_time;
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,
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
4326 #include <sys/uio.h>
4329 +#include "sa_len.h"
4331 #endif /* NO_APACHE_INCLUDES */
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 */
4341 char path[1024]; /* path name */
4342 char postfile[1024]; /* name of file containing post data */
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 */
4350 int use_html = 0; /* use html in the report */
4353 struct data *stats; /* date for each request */
4355 fd_set readbits, writebits; /* bits for select */
4356 -struct sockaddr_in server; /* server addr structure */
4357 +struct sockaddr_storage server; /* server addr structure */
4360 #define ab_close(s) close(s)
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);
4368 printf("Document Path: %s\n", path);
4369 printf("Document Length: %d bytes\n", doclen);
4374 - c->fd = socket(AF_INET, SOCK_STREAM, 0);
4375 + c->fd = socket(server.ss_family, SOCK_STREAM, 0);
4379 @@ -853,7 +855,12 @@
4382 gettimeofday(&c->start, 0);
4383 - if (connect(c->fd, (struct sockaddr *) & server, sizeof(server)) < 0) {
4385 + if (connect(c->fd, (struct sockaddr *) & server, SA_LEN((struct sockaddr*)&server)) < 0)
4387 + if (connect(c->fd, (struct sockaddr *) & server, server.ss_len) < 0)
4390 if (errno != EINPROGRESS) {
4393 @@ -1147,7 +1154,7 @@
4394 struct timeval timeout, now;
4395 fd_set sel_read, sel_except, sel_write;
4398 + char * connectport;
4400 char * url_on_request;
4402 @@ -1190,17 +1197,21 @@
4405 /* get server information */
4406 - struct hostent *he;
4407 - he = gethostbyname(connecthost);
4409 - char theerror[1024];
4410 - ap_snprintf(theerror, sizeof(theerror),
4411 - "Bad hostname: %s\n", connecthost);
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;
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);
4425 + char *theerror=malloc(strlen(connecthost)+16);
4426 + sprintf(theerror, "Bad hostname: %s\n", connecthost);
4430 + memcpy(&server, res->ai_addr, res->ai_addrlen);
4431 + freeaddrinfo(res);
4434 con = malloc(concurrency * sizeof(struct connection));
4435 @@ -1388,7 +1399,7 @@
4436 if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
4443 if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
4444 @@ -1409,15 +1420,15 @@
4446 strcpy(hostname, h);
4453 - (ssl != 0) && (port != 443)) || ((ssl == 0) &&
4454 + (ssl != 0) && (strcmp(port, "443"))) || ((ssl == 0) &&
4457 + (strcmp(port, "80"))))
4459 - ap_snprintf(colonport,sizeof(colonport),":%d",port);
4460 + ap_snprintf(colonport,sizeof(colonport),":%s",port);
4462 colonport[0] = '\0';
4464 @@ -1589,7 +1600,7 @@
4465 if ((p = strchr(optarg, ':'))) {
4468 - proxyport = atoi(p);
4469 + proxyport = strdup(p);
4471 strcpy(proxyhost, optarg);
4473 @@ -1672,3 +1683,7 @@
4478 +#ifdef NEED_GETADDRINFO
4479 +#include "../main/getaddrinfo.c"
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
4485 #endif /* !MPE && !WIN32*/
4487 -static void cgethost(struct in_addr ipnum, char *string, int check);
4488 +#include "sa_len.h"
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);
4498 - struct in_addr ipnum;
4499 + struct sockaddr_storage addr;
4503 @@ -138,17 +140,48 @@
4504 * IP numbers with their IP number as hostname, setting noname flag
4507 -static void cgethost (struct in_addr ipnum, char *string, int check)
4508 +static void cgethost (struct sockaddr *sa, char *string, int check)
4510 + ap_uint32_t hashval;
4511 + struct sockaddr_in *sin;
4513 + struct sockaddr_in6 *sin6;
4515 struct nsrec **current, *new;
4516 - struct hostent *hostdata;
4518 + char hostnamebuf[MAXHOSTNAMELEN];
4520 + switch (sa->sa_family) {
4522 + hashval = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
4526 + hashval = *(ap_uint32_t *)&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12];
4534 + current = &nscache[((hashval + (hashval >> 8) +
4535 + (hashval >> 16) + (hashval >> 24)) % BUCKETS)];
4537 - current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) +
4538 - (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)];
4539 + while (*current) {
4541 + if (SA_LEN(sa) == SA_LEN((struct sockaddr *)&(*current)->addr)
4542 + && memcmp(sa, &(*current)->addr, SA_LEN(sa)) == 0)
4544 + if (sa->sa_len == (*current)->addr.ss_len
4545 + && memcmp(sa, &(*current)->addr, sa->sa_len) == 0)
4551 - while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr)
4552 current = &(*current)->next;
4555 if (*current == NULL) {
4557 @@ -161,45 +194,55 @@
4561 - new->ipnum = ipnum;
4563 + memcpy(&new->addr, sa, SA_LEN(sa));
4565 + memcpy(&new->addr, sa, sa->sa_len);
4568 - hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr),
4570 - if (hostdata == NULL || !hostdata->h_name || !*hostdata->h_name) {
4571 - if (h_errno > MAX_ERR)
4572 - errors[UNKNOWN_ERR]++;
4574 - errors[h_errno]++;
4575 - new->noname = h_errno;
4576 - name = strdup(inet_ntoa(ipnum));
4580 - name = strdup(hostdata->h_name);
4582 - if (name == NULL) {
4584 - fprintf(stderr, "Insufficient memory\n");
4587 - hostdata = gethostbyname(name);
4588 - if (hostdata != NULL) {
4591 - for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++)
4592 - if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr)
4594 - if (*hptr == NULL)
4597 - if (hostdata == NULL) {
4598 - fprintf(stderr, "Bad host: %s != %s\n", name,
4599 - inet_ntoa(ipnum));
4600 - new->noname = NO_REVERSE;
4602 - name = strdup(inet_ntoa(ipnum));
4603 - errors[NO_REVERSE]++;
4604 + new->noname = getnameinfo(sa,
4610 + hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0);
4611 + name = strdup(hostnamebuf);
4613 + struct addrinfo hints, *res;
4615 + memset(&hints, 0, sizeof(hints));
4616 + hints.ai_family = PF_UNSPEC;
4617 + error = getaddrinfo(hostnamebuf, NULL, &hints, &res);
4621 + if (SA_LEN(sa) == res->ai_addrlen
4622 + && memcmp(sa, res->ai_addr, SA_LEN(sa)) == 0)
4624 + if (sa->sa_len == res->ai_addrlen
4625 + && memcmp(sa, res->ai_addr, sa->sa_len) == 0)
4630 + res = res->ai_next;
4642 + hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
4643 + fprintf(stderr, "Bad host: %s != %s\n", name, hostnamebuf);
4644 + new->noname = NO_REVERSE;
4646 + name = strdup(hostnamebuf);
4649 new->hostname = name;
4652 struct nsrec *current;
4653 char *errstring[MAX_ERR + 3];
4654 + char hostnamebuf[MAXHOSTNAMELEN];
4656 for (i = 0; i < MAX_ERR + 3; i++)
4657 errstring[i] = "Unknown error";
4658 @@ -258,7 +302,14 @@
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 *)¤t->addr,
4665 + SA_LEN((struct sockaddr *)¤t->addr),
4667 + current->addr.ss_len,
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,
4674 @@ -292,9 +343,10 @@
4676 int main (int argc, char *argv[])
4678 - struct in_addr ipnum;
4679 char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
4681 + struct addrinfo hints, *res;
4686 @@ -338,8 +390,10 @@
4687 bar = strchr(line, ' ');
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);
4699 @@ -349,11 +403,12 @@
4703 - cgethost(ipnum, hoststring, check);
4704 + cgethost(res->ai_addr, hoststring, check);
4706 printf("%s %s\n", hoststring, bar + 1);
4709 + freeaddrinfo(res);
4713 @@ -374,3 +429,11 @@
4718 +#ifdef NEED_GETADDRINFO
4719 +#include "../main/getaddrinfo.c"
4722 +#ifdef NEED_GETNAMEINFO
4723 +#include "../main/getnameinfo.c"