-diff -Nur apache_1.3.26.orig/README.v6 apache_1.3.26/README.v6
---- apache_1.3.26.orig/README.v6 Thu Jan 1 01:00:00 1970
-+++ apache_1.3.26/README.v6 Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/README.v6 apache_1.3.28/README.v6
+--- apache_1.3.28.orig/README.v6 Thu Jan 1 01:00:00 1970
++++ apache_1.3.28/README.v6 Fri Jul 25 11:01:55 2003
@@ -0,0 +1,166 @@
+IPv6-ready apache 1.3.x
+KAME Project
+ http://www.v6.linux.or.jp/
+ YOSHIFUJI Hideaki, USAGI Project
+ http://www.linux-ipv6.org/
-diff -Nur apache_1.3.26.orig/conf/httpd.conf-dist apache_1.3.26/conf/httpd.conf-dist
---- apache_1.3.26.orig/conf/httpd.conf-dist Tue Mar 5 17:19:12 2002
-+++ apache_1.3.26/conf/httpd.conf-dist Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/conf/httpd.conf-dist apache_1.3.28/conf/httpd.conf-dist
+--- apache_1.3.28.orig/conf/httpd.conf-dist Wed Jul 16 21:36:41 2003
++++ apache_1.3.28/conf/httpd.conf-dist Fri Jul 25 11:01:55 2003
@@ -174,6 +174,11 @@
#Listen 3000
#Listen 12.34.56.78:80
#
# BindAddress: You can support virtual hosts with this option. This directive
# is used to tell the server which IP address to listen to. It can either
-diff -Nur apache_1.3.26.orig/configure.v6 apache_1.3.26/configure.v6
---- apache_1.3.26.orig/configure.v6 Thu Jan 1 01:00:00 1970
-+++ apache_1.3.26/configure.v6 Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/configure.v6 apache_1.3.28/configure.v6
+--- apache_1.3.28.orig/configure.v6 Thu Jan 1 01:00:00 1970
++++ apache_1.3.28/configure.v6 Fri Jul 25 11:01:55 2003
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+./configure --enable-rule=INET6 --enable-module=proxy $*
-diff -Nur apache_1.3.26.orig/src/Configuration.tmpl apache_1.3.26/src/Configuration.tmpl
---- apache_1.3.26.orig/src/Configuration.tmpl Wed Jun 19 10:25:56 2002
-+++ apache_1.3.26/src/Configuration.tmpl Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/src/Configuration.tmpl apache_1.3.28/src/Configuration.tmpl
+--- apache_1.3.28.orig/src/Configuration.tmpl Fri Jul 25 11:00:49 2003
++++ apache_1.3.28/src/Configuration.tmpl Fri Jul 25 11:01:55 2003
@@ -191,6 +191,9 @@
# Rule EXPAT=default : If Expat can be found at the system or
# in lib/expat-lite, use it; otherwise
Rule CYGWIN_WINSOCK=no
# DEV_RANDOM:
-diff -Nur apache_1.3.26.orig/src/Configure apache_1.3.26/src/Configure
---- apache_1.3.26.orig/src/Configure Wed Jun 19 10:25:56 2002
-+++ apache_1.3.26/src/Configure Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/src/Configure apache_1.3.28/src/Configure
+--- apache_1.3.28.orig/src/Configure Fri Jul 25 11:00:49 2003
++++ apache_1.3.28/src/Configure Fri Jul 25 11:01:55 2003
@@ -238,6 +238,7 @@
RULE_CYGWIN_WINSOCK=`./helpers/CutRule CYGWIN_WINSOCK $file`
RULE_SHARED_CORE=`./helpers/CutRule SHARED_CORE $file`
####################################################################
## Rule SHARED_CORE implies required DSO support
-@@ -1701,6 +1702,124 @@
+@@ -1724,6 +1725,124 @@
esac
fi
####################################################################
## Find out what modules we want and try and configure things for them
## Module lines can look like this:
-@@ -2296,6 +2415,38 @@
+@@ -2320,6 +2439,38 @@
echo "#define AP_LONGEST_LONG $AP_LONGEST_LONG" >>$AP_CONFIG_AUTO_H
echo "#endif" >>$AP_CONFIG_AUTO_H
####################################################################
## More building ap_config_auto.h
##
-diff -Nur apache_1.3.26.orig/src/ap/ap_snprintf.c apache_1.3.26/src/ap/ap_snprintf.c
---- apache_1.3.26.orig/src/ap/ap_snprintf.c Thu Mar 14 13:08:06 2002
-+++ apache_1.3.26/src/ap/ap_snprintf.c Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/src/ap/ap_snprintf.c apache_1.3.28/src/ap/ap_snprintf.c
+--- apache_1.3.28.orig/src/ap/ap_snprintf.c Mon Feb 3 18:13:17 2003
++++ apache_1.3.28/src/ap/ap_snprintf.c Fri Jul 25 11:01:55 2003
@@ -73,6 +73,7 @@
#include <string.h>
#include <stdlib.h>
#ifdef WIN32
#include <float.h>
#endif
-@@ -504,6 +505,42 @@
+@@ -510,6 +511,42 @@
/*
* Convert a floating point number to a string formats 'f', 'e' or 'E'.
* The result is placed in buf, and len denotes the length of the string
-@@ -1055,6 +1092,7 @@
+@@ -1057,6 +1094,7 @@
/* print a struct sockaddr_in as a.b.c.d:port */
case 'I':
{
struct sockaddr_in *si;
si = va_arg(ap, struct sockaddr_in *);
-@@ -1063,6 +1101,16 @@
+@@ -1065,6 +1103,16 @@
if (adjust_precision && precision < s_len)
s_len = precision;
}
else {
s = S_NULL;
s_len = S_NULL_LEN;
-diff -Nur apache_1.3.26.orig/src/include/ap.h apache_1.3.26/src/include/ap.h
---- apache_1.3.26.orig/src/include/ap.h Tue Jun 18 06:19:45 2002
-+++ apache_1.3.26/src/include/ap.h Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/src/include/ap.h apache_1.3.28/src/include/ap.h
+--- apache_1.3.28.orig/src/include/ap.h Mon Feb 3 18:13:17 2003
++++ apache_1.3.28/src/include/ap.h Fri Jul 25 11:01:55 2003
@@ -95,7 +95,8 @@
* with some extensions. The extensions are:
*
* %pp takes a void * and outputs it in hex
*
* The %p hacks are to force gcc's printf warning code to skip
-diff -Nur apache_1.3.26.orig/src/include/ap_config.h apache_1.3.26/src/include/ap_config.h
---- apache_1.3.26.orig/src/include/ap_config.h Mon Jun 3 14:28:27 2002
-+++ apache_1.3.26/src/include/ap_config.h Wed Jun 19 10:26:32 2002
-@@ -407,6 +407,10 @@
+diff -Nur apache_1.3.28.orig/src/include/ap_config.h apache_1.3.28/src/include/ap_config.h
+--- apache_1.3.28.orig/src/include/ap_config.h Mon May 5 13:45:49 2003
++++ apache_1.3.28/src/include/ap_config.h Fri Jul 25 11:01:55 2003
+@@ -411,6 +411,10 @@
#endif
#ifndef S_IWOTH
#define S_IWOTH 000002
#endif
#define STDIN_FILENO 0
-@@ -1509,6 +1513,70 @@
+@@ -1523,6 +1527,70 @@
#define ap_wait_t int
#endif
#ifdef __cplusplus
}
#endif
-diff -Nur apache_1.3.26.orig/src/include/http_conf_globals.h apache_1.3.26/src/include/http_conf_globals.h
---- apache_1.3.26.orig/src/include/http_conf_globals.h Wed Jun 19 10:25:56 2002
-+++ apache_1.3.26/src/include/http_conf_globals.h Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/src/include/http_conf_globals.h apache_1.3.28/src/include/http_conf_globals.h
+--- apache_1.3.28.orig/src/include/http_conf_globals.h Fri Jul 25 11:00:49 2003
++++ apache_1.3.28/src/include/http_conf_globals.h Fri Jul 25 11:01:55 2003
@@ -82,7 +82,8 @@
extern API_VAR_EXPORT int ap_max_requests_per_child;
extern API_VAR_EXPORT int ap_threads_per_child;
extern listen_rec *ap_listeners;
extern API_VAR_EXPORT int ap_daemons_to_start;
extern API_VAR_EXPORT int ap_daemons_min_free;
-diff -Nur apache_1.3.26.orig/src/include/http_vhost.h apache_1.3.26/src/include/http_vhost.h
---- apache_1.3.26.orig/src/include/http_vhost.h Wed Mar 13 22:05:29 2002
-+++ apache_1.3.26/src/include/http_vhost.h Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/src/include/http_vhost.h apache_1.3.28/src/include/http_vhost.h
+--- apache_1.3.28.orig/src/include/http_vhost.h Mon Feb 3 18:13:19 2003
++++ apache_1.3.28/src/include/http_vhost.h Fri Jul 25 11:01:55 2003
@@ -73,7 +73,7 @@
API_EXPORT(const char *) ap_parse_vhost_addrs(pool *p, const char *hostname, server_rec *s);
/* given an ip address only, give our best guess as to what vhost it is */
API_EXPORT(void) ap_update_vhost_given_ip(conn_rec *conn);
-diff -Nur apache_1.3.26.orig/src/include/httpd.h apache_1.3.26/src/include/httpd.h
---- apache_1.3.26.orig/src/include/httpd.h Wed Jun 19 10:25:56 2002
-+++ apache_1.3.26/src/include/httpd.h Wed Jun 19 10:26:32 2002
-@@ -903,8 +903,8 @@
+diff -Nur apache_1.3.28.orig/src/include/httpd.h apache_1.3.28/src/include/httpd.h
+--- apache_1.3.28.orig/src/include/httpd.h Fri Jul 25 11:00:49 2003
++++ apache_1.3.28/src/include/httpd.h Fri Jul 25 11:01:55 2003
+@@ -904,8 +904,8 @@
/* Who is the client? */
char *remote_ip; /* Client's IP address */
char *remote_host; /* Client's DNS name, if known.
* NULL if DNS hasn't been checked,
-@@ -946,8 +946,8 @@
+@@ -947,8 +947,8 @@
typedef struct server_addr_rec server_addr_rec;
struct server_addr_rec {
server_addr_rec *next;
char *virthost; /* The name given in <VirtualHost> */
};
-@@ -1015,7 +1015,7 @@
+@@ -1016,7 +1016,7 @@
/* These are more like real hosts than virtual hosts */
struct listen_rec {
listen_rec *next;
int fd;
int used; /* Only used during restart */
/* more stuff here, like which protocol is bound to the port */
-@@ -1183,7 +1183,7 @@
+@@ -1184,7 +1184,7 @@
#endif /*#ifdef CHARSET_EBCDIC*/
API_EXPORT(char *) ap_get_local_host(pool *);
extern API_VAR_EXPORT time_t ap_restart_time;
-diff -Nur apache_1.3.26.orig/src/include/sa_len.h apache_1.3.26/src/include/sa_len.h
---- apache_1.3.26.orig/src/include/sa_len.h Thu Jan 1 01:00:00 1970
-+++ apache_1.3.26/src/include/sa_len.h Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/src/include/sa_len.h apache_1.3.28/src/include/sa_len.h
+--- apache_1.3.28.orig/src/include/sa_len.h Thu Jan 1 01:00:00 1970
++++ apache_1.3.28/src/include/sa_len.h Fri Jul 25 11:01:55 2003
@@ -0,0 +1,41 @@
+/* sa_len.h : tiny version of SA_LEN (written by <yoshfuji@ecei.tohoku.ac.jp>) */
+
+}
+#endif /* SA_LEN */
+#endif /* HAVE_SOCKADDR_LEN */
-diff -Nur apache_1.3.26.orig/src/include/sockaddr_storage.h apache_1.3.26/src/include/sockaddr_storage.h
---- apache_1.3.26.orig/src/include/sockaddr_storage.h Thu Jan 1 01:00:00 1970
-+++ apache_1.3.26/src/include/sockaddr_storage.h Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/src/include/sockaddr_storage.h apache_1.3.28/src/include/sockaddr_storage.h
+--- apache_1.3.28.orig/src/include/sockaddr_storage.h Thu Jan 1 01:00:00 1970
++++ apache_1.3.28/src/include/sockaddr_storage.h Fri Jul 25 11:01:55 2003
@@ -0,0 +1,53 @@
+/*
+struct sockaddr_storage
+#define su_port su_si.si_port
+
+#endif /* NEED_SOCKADDR_STORAGE */
-diff -Nur apache_1.3.26.orig/src/main/getaddrinfo.c apache_1.3.26/src/main/getaddrinfo.c
---- apache_1.3.26.orig/src/main/getaddrinfo.c Thu Jan 1 01:00:00 1970
-+++ apache_1.3.26/src/main/getaddrinfo.c Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/src/main/getaddrinfo.c apache_1.3.28/src/main/getaddrinfo.c
+--- apache_1.3.28.orig/src/main/getaddrinfo.c Thu Jan 1 01:00:00 1970
++++ apache_1.3.28/src/main/getaddrinfo.c Fri Jul 25 11:01:55 2003
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+ }
+ return EAI_NODATA;
+}
-diff -Nur apache_1.3.26.orig/src/main/getnameinfo.c apache_1.3.26/src/main/getnameinfo.c
---- apache_1.3.26.orig/src/main/getnameinfo.c Thu Jan 1 01:00:00 1970
-+++ apache_1.3.26/src/main/getnameinfo.c Wed Jun 19 10:26:32 2002
+diff -Nur apache_1.3.28.orig/src/main/getnameinfo.c apache_1.3.28/src/main/getnameinfo.c
+--- apache_1.3.28.orig/src/main/getnameinfo.c Thu Jan 1 01:00:00 1970
++++ apache_1.3.28/src/main/getnameinfo.c Fri Jul 25 11:01:55 2003
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
+ return EAI_NODATA;
+ return 0;
+}
-diff -Nur apache_1.3.26.orig/src/main/http_config.c apache_1.3.26/src/main/http_config.c
---- apache_1.3.26.orig/src/main/http_config.c Wed Jun 19 10:25:56 2002
-+++ apache_1.3.26/src/main/http_config.c Wed Jun 19 10:26:32 2002
-@@ -1564,7 +1564,6 @@
+diff -Nur apache_1.3.28.orig/src/main/http_config.c apache_1.3.28/src/main/http_config.c
+--- apache_1.3.28.orig/src/main/http_config.c Fri Jul 25 11:00:49 2003
++++ apache_1.3.28/src/main/http_config.c Fri Jul 25 11:01:55 2003
+@@ -1591,7 +1591,6 @@
ap_scoreboard_fname = DEFAULT_SCOREBOARD;
ap_lock_fname = DEFAULT_LOCKFILE;
ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD;
ap_listeners = NULL;
ap_listenbacklog = DEFAULT_LISTENBACKLOG;
ap_extended_status = 0;
-@@ -1597,7 +1596,13 @@
+@@ -1624,7 +1623,13 @@
s->next = NULL;
s->addrs = ap_pcalloc(p, sizeof(server_addr_rec));
/* NOT virtual host; don't match any real network interface */
s->addrs->host_port = 0; /* matches any port */
s->addrs->virthost = ""; /* must be non-NULL */
s->names = s->wild_names = NULL;
-@@ -1616,21 +1621,33 @@
+@@ -1643,21 +1648,33 @@
static void default_listeners(pool *p, server_rec *s)
{
listen_rec *new;
}
-diff -Nur apache_1.3.26.orig/src/main/http_vhost.c apache_1.3.26/src/main/http_vhost.c
---- apache_1.3.26.orig/src/main/http_vhost.c Wed Mar 13 22:05:31 2002
-+++ apache_1.3.26/src/main/http_vhost.c Wed Jun 19 10:26:32 2002
-@@ -68,6 +68,7 @@
- #include "http_log.h"
- #include "http_vhost.h"
- #include "http_protocol.h"
+--- apache_1.3.34/src/main/http_core.c.orig 2005-06-28 20:03:25.000000000 +0200
++++ apache_1.3.34/src/main/http_core.c 2005-10-18 10:14:09.000000000 +0200
+@@ -28,6 +28,7 @@
+ #include "util_md5.h"
+ #include "scoreboard.h"
+ #include "fnmatch.h"
+#include "sa_len.h"
- /*
- * After all the definitions there's an explanation of how it's all put
-@@ -165,78 +166,114 @@
- * *paddr is the variable used to keep track of **paddr between calls
- * port is the default port to assume
+ #ifdef USE_MMAP_FILES
+ #include <sys/mman.h>
+@@ -570,7 +571,7 @@
+ * file if you care. So the adhoc value should do.
+ */
+ return ap_psprintf(r->pool,"%pA%pp%pp%pp%pp",
+- &r->connection->local_addr.sin_addr,
++ &((struct sockaddr_in *)&(r->connection->local_addr))->sin_addr,
+ (void *)ap_user_name,
+ (void *)ap_listeners,
+ (void *)ap_server_argv0,
+@@ -666,7 +667,9 @@
*/
--static const char *get_addresses(pool *p, char *w, server_addr_rec ***paddr,
-- unsigned port)
-+static const char *get_addresses(pool *p, char *w, char *pstr,
-+ server_addr_rec ***paddr, unsigned port)
+ static ap_inline void do_double_reverse (conn_rec *conn)
{
-- struct hostent *hep;
-- unsigned long my_addr;
+- struct hostent *hptr;
+ struct addrinfo hints, *res, *res0;
- server_addr_rec *sar;
-- char *t;
-- int i, is_an_ip_addr;
-+ char *t = NULL, *u = NULL, *v = NULL;
-+ char *hoststr = NULL, *portstr = NULL;
-+ char portpool[10];
-+ int error;
-+ char servbuf[NI_MAXSERV];
-
-- if (*w == 0)
-+ if (w == 0 || *w == 0)
- return NULL;
++ char hostbuf1[128], hostbuf2[128]; /* INET6_ADDRSTRLEN(=46) is enough */
++ int ok = 0;
-- t = strchr(w, ':');
-- if (t) {
-- if (strcmp(t + 1, "*") == 0) {
-- port = 0;
-+ portstr = portpool;
-+ ap_snprintf(portpool, sizeof(portpool), "%u", port);
-+ if (!pstr) {
-+ v = w;
-+ u = NULL;
-+ if (*w == '['){
-+ u = strrchr(w, ']');
-+ if (u) { /* [host]:port or [host] */
-+ w++;
-+ *u = '\0';
-+ v = u + 1;
-+ }
- }
-- else if ((i = atoi(t + 1))) {
-- port = i;
-+ /* w uv , w=v , w=v */
-+ /* u!=0: [host]:port , u==0: [host:port , host */
-+ t = strchr(v, ':');
-+ if (t != NULL && strchr(t+1, ':') == NULL) {
-+ /* [host]:port-w/o-colons, host-without-colons:port-w/o-colons */
-+ *t = '\0';
-+ portstr = t + 1;
- }
- else {
-- return ":port must be numeric";
-+ portstr = "0";
- }
-- *t = 0;
-+ } else {
-+ portstr = pstr;
+ if (conn->double_reverse) {
+ /* already done */
+@@ -678,30 +681,54 @@
+ conn->remote_host = ""; /* prevent another lookup */
+ return;
}
-
-- is_an_ip_addr = 0;
-- if (strcmp(w, "*") == 0) {
-- my_addr = htonl(INADDR_ANY);
-- is_an_ip_addr = 1;
-- }
-- else if (strcasecmp(w, "_default_") == 0
-- || strcmp(w, "255.255.255.255") == 0) {
-- my_addr = DEFAULT_VHOST_ADDR;
-- is_an_ip_addr = 1;
-- }
-- else if ((my_addr = ap_inet_addr(w)) != INADDR_NONE) {
-- is_an_ip_addr = 1;
+- hptr = gethostbyname(conn->remote_host);
+- if (hptr) {
+- char **haddr;
+-
+- for (haddr = hptr->h_addr_list; *haddr; haddr++) {
+- if (((struct in_addr *)(*haddr))->s_addr
+- == conn->remote_addr.sin_addr.s_addr) {
+- conn->double_reverse = 1;
+- return;
+- }
+ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
-+ if (strcmp(w, "*") == 0 || strlen(w) == 0) {
-+ hoststr = NULL;
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_flags = AI_PASSIVE;
-+ }
-+ else if (strcasecmp(w, "_default4_") == 0 ||
-+ ((ap_default_family == PF_INET
-+#ifndef INET6
-+ || ap_default_family == PF_UNSPEC
-+#endif
-+ ) && strcasecmp(w, "_default_") == 0)){
-+ hoststr = "255.255.255.255";
-+ hints.ai_family = PF_INET;
++ if (getaddrinfo(conn->remote_host, NULL, &hints, &res0)) {
++ conn->double_reverse = -1;
++ return;
+ }
++ for (res = res0; res; res = res->ai_next) {
++ if (res->ai_addr->sa_family != conn->remote_addr.ss_family ||
++ !(res->ai_family == AF_INET
+#ifdef INET6
-+ else if (strcasecmp(w, "_default6_") == 0 ||
-+ ((ap_default_family == PF_INET6
-+ || ap_default_family == PF_UNSPEC
-+ ) && strcasecmp(w, "_default_") == 0)){
-+ hoststr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
-+ hints.ai_family = PF_INET6;
- }
-- if (is_an_ip_addr) {
-- sar = ap_pcalloc(p, sizeof(server_addr_rec));
-- **paddr = sar;
-- *paddr = &sar->next;
-- sar->host_addr.s_addr = my_addr;
-- sar->host_port = port;
-- sar->virthost = ap_pstrdup(p, w);
-- if (t != NULL)
-- *t = ':';
-- return NULL;
++ || res->ai_family == AF_INET6
+#endif
-+ else{
-+ hoststr = w;
-+ hints.ai_family = PF_UNSPEC;
- }
-
-- hep = gethostbyname(w);
--
-- if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
-+ error = getaddrinfo(hoststr, portstr, &hints, &res0);
-+ if (error || !res0) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
-- "Cannot resolve host name %s --- ignoring!", w);
-- if (t != NULL)
-- *t = ':';
-+ "Cannot resolve host %s port %s --- ignoring!", hoststr, portstr);
-+ if (t != NULL) *t = ':';
-+ if (u != NULL) *u = ']';
- return NULL;
- }
--
-- for (i = 0; hep->h_addr_list[i]; ++i) {
-+ for (res=res0; res; res=res->ai_next) {
-+ switch (res->ai_addr->sa_family) {
-+ case AF_INET:
-+#ifdef INET6
-+ case AF_INET6:
++ )
++ )
++ continue;
++#ifndef HAVE_SOCKADDR_LEN
++ if (res->ai_addrlen != SA_LEN((struct sockaddr *)&conn->remote_addr))
++#else
++ if (res->ai_addr->sa_len != conn->remote_addr.ss_len)
+#endif
-+ break;
-+ default:
-+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
-+ "Unsupported address family %u, for host %s port %s --- ignoring!",
-+ res->ai_addr->sa_family, hoststr, portstr);
+ continue;
-+ }
- sar = ap_pcalloc(p, sizeof(server_addr_rec));
- **paddr = sar;
- *paddr = &sar->next;
-- sar->host_addr = *(struct in_addr *) hep->h_addr_list[i];
-- sar->host_port = port;
-+ memcpy(&sar->host_addr, res->ai_addr, res->ai_addrlen);
-+ if (getnameinfo(res->ai_addr, res->ai_addrlen, NULL, 0, servbuf,
-+ sizeof(servbuf), NI_NUMERICSERV) == 0)
-+ sar->host_port = atoi(servbuf);
-+ else
-+ sar->host_port = 0;
- sar->virthost = ap_pstrdup(p, w);
++ if (getnameinfo(res->ai_addr, res->ai_addrlen,
++ hostbuf1, sizeof(hostbuf1), NULL, 0,
++ NI_NUMERICHOST))
++ continue;
++ if (getnameinfo(((struct sockaddr *)&conn->remote_addr), res->ai_addrlen,
++ hostbuf2, sizeof(hostbuf2), NULL, 0,
++ NI_NUMERICHOST))
++ continue;
++ if (strcmp(hostbuf1, hostbuf2) == 0){
++ ok = 1;
++ break;
+ }
}
-
-- if (t != NULL)
-- *t = ':';
+- conn->double_reverse = -1;
++ conn->double_reverse = ok ? 1 : -1;
+ freeaddrinfo(res0);
-+ if (t != NULL) *t = ':';
-+ if (u != NULL) *u = ']';
- return NULL;
- }
-
-@@ -250,7 +287,8 @@
- /* start the list of addreses */
- addrs = &s->addrs;
- while (hostname[0]) {
-- err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
-+ err = get_addresses(p, ap_getword_conf(p, &hostname), NULL,
-+ &addrs, s->port);
- if (err) {
- *addrs = NULL;
- return err;
-@@ -268,10 +306,11 @@
+ /* invalidate possible reverse-resolved hostname if forward lookup fails */
+- conn->remote_host = "";
++ if(!ok)
++ conn->remote_host = "";
}
+ API_EXPORT(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
+ int type)
+ {
+- struct in_addr *iaddr;
+- struct hostent *hptr;
+ int hostname_lookups;
+ int old_stat = SERVER_DEAD; /* we shouldn't ever be in this state */
++ char hostnamebuf[MAXHOSTNAMELEN];
--API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg)
-+API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *h,
-+ char *p)
+ /* If we haven't checked the host name, and we want to */
+ if (dir_config) {
+@@ -723,10 +750,14 @@
+ || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
+ old_stat = ap_update_child_status(conn->child_num, SERVER_BUSY_DNS,
+ (request_rec*)NULL);
+- iaddr = &(conn->remote_addr.sin_addr);
+- hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
+- if (hptr != NULL) {
+- conn->remote_host = ap_pstrdup(conn->pool, (void *)hptr->h_name);
++ if (!getnameinfo((struct sockaddr *)&conn->remote_addr,
++#ifndef SIN6_LEN
++ SA_LEN((struct sockaddr *)&conn->remote_addr),
++#else
++ conn->remote_addr.ss_len,
++#endif
++ hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0)) {
++ conn->remote_host = ap_pstrdup(conn->pool, (void *)hostnamebuf);
+ ap_str_tolower(conn->remote_host);
+
+ if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
+@@ -804,6 +835,7 @@
{
- /* use whatever port the main server has at this point */
-- return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
-+ return get_addresses(cmd->pool, h, p, &name_vhost_list_tail,
- cmd->server->port);
- }
+ conn_rec *conn = r->connection;
+ core_dir_config *d;
++ char hbuf[MAXHOSTNAMELEN];
-@@ -345,6 +384,19 @@
- return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
- }
-
-+static unsigned hash_addr(struct sockaddr *sa)
-+{
-+ switch (sa->sa_family) {
-+ case AF_INET:
-+ return hash_inaddr(((struct sockaddr_in *)sa)->sin_addr.s_addr);
-+#ifdef INET6
-+ case AF_INET6:
-+ return hash_inaddr(((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12]);
+ d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
+ &core_module);
+@@ -813,23 +845,22 @@
+ }
+ if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
+ if (conn->local_host == NULL) {
+- struct in_addr *iaddr;
+- struct hostent *hptr;
+ int old_stat;
+ old_stat = ap_update_child_status(conn->child_num,
+ SERVER_BUSY_DNS, r);
+- iaddr = &(conn->local_addr.sin_addr);
+- hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr),
+- AF_INET);
+- if (hptr != NULL) {
+- conn->local_host = ap_pstrdup(conn->pool,
+- (void *)hptr->h_name);
+- ap_str_tolower(conn->local_host);
+- }
+- else {
+- conn->local_host = ap_pstrdup(conn->pool,
+- r->server->server_hostname);
++ if (getnameinfo((struct sockaddr *)&conn->local_addr,
++#ifndef SIN6_LEN
++ SA_LEN((struct sockaddr *)&conn->local_addr),
++#else
++ conn->local_addr.ss_len,
+#endif
-+ default:
-+ return hash_inaddr(sa->sa_family);
-+ }
-+}
++ hbuf, sizeof(hbuf), NULL, 0, 0) == 0) {
++ conn->local_host = ap_pstrdup(conn->pool, hbuf);
++ } else {
++ conn->local_host = ap_pstrdup(conn->pool,
++ r->server->server_hostname);
+ }
++ ap_str_tolower(conn->local_host);
+ (void) ap_update_child_status(conn->child_num, old_stat, r);
+ }
+ return conn->local_host;
+@@ -841,7 +872,7 @@
+ API_EXPORT(unsigned) ap_get_server_port(const request_rec *r)
+ {
+ unsigned port;
+- unsigned cport = ntohs(r->connection->local_addr.sin_port);
++ unsigned cport = ntohs(((struct sockaddr_in *)&r->connection->local_addr)->sin_port);
+ core_dir_config *d =
+ (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module);
+
+@@ -2647,12 +2678,25 @@
+ static const char *set_bind_address(cmd_parms *cmd, void *dummy, char *arg)
+ {
++ struct addrinfo hints, *res;
++ struct sockaddr *sa;
++ size_t sa_len;
++ int error;
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err != NULL) {
+ return err;
+ }
- static ipaddr_chain *new_ipaddr_chain(pool *p,
-@@ -372,25 +424,77 @@
- return new;
+- ap_bind_address.s_addr = ap_get_virthost_addr(arg, NULL);
++ if (strcmp(arg, "*") == 0)
++ arg = NULL;
++
++ sa = ap_get_virthost_addr(arg, NULL);
++#ifdef HAVE_SOCKADDR_LEN
++ sa_len = sa->sa_len;
++#else
++ sa_len = SA_LEN(sa);
++#endif
++ memcpy(&ap_bind_address, &sa, sa_len);
+ return NULL;
}
--
--static ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
-- unsigned port)
-+static ap_inline ipaddr_chain *find_ipaddr(struct sockaddr *sa)
+@@ -2684,48 +2728,71 @@
+ return NULL;
+ }
+
+-static const char *set_listener(cmd_parms *cmd, void *dummy, char *ips)
++static const char *set_listener(cmd_parms *cmd, void *dummy, char *h, char *p)
{
- unsigned bucket;
- ipaddr_chain *trav;
-- unsigned addr;
-+ char a[NI_MAXHOST], b[NI_MAXHOST];
+ listen_rec *new;
+- char *ports, *endptr;
+- long port;
++ char *host, *port;
++ struct addrinfo hints, *res;
++ int error;
+
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err != NULL) {
+ return err;
+ }
- /* scan the hash table for an exact match first */
-- addr = server_ip->s_addr;
-- bucket = hash_inaddr(addr);
-+ bucket = hash_addr(sa);
- for (trav = iphash_table[bucket]; trav; trav = trav->next) {
- server_addr_rec *sar = trav->sar;
-- if ((sar->host_addr.s_addr == addr)
-- && (sar->host_port == 0 || sar->host_port == port
-- || port == 0)) {
-- return trav;
-+ if (sar->host_addr.ss_family != sa->sa_family)
-+ continue;
-+ switch (sa->sa_family) {
-+ case AF_INET:
-+ {
-+ struct sockaddr_in *sin1, *sin2;
-+ sin1 = (struct sockaddr_in *)&sar->host_addr;
-+ sin2 = (struct sockaddr_in *)sa;
-+ if (sin1->sin_port == 0 || sin2->sin_port == 0
-+ || sin1->sin_port == sin2->sin_port) {
-+ if (memcmp(&sin1->sin_addr, &sin2->sin_addr,
-+ sizeof(sin1->sin_addr)) == 0) {
-+ return trav;
-+ }
+- ports = strchr(ips, ':');
+- if (ports != NULL) {
+- if (ports == ips) {
+- return "Missing IP address";
+- }
+- else if (ports[1] == '\0') {
+- return "Address must end in :<port-number>";
++ host = port = NULL;
++ if (!p) {
++ port = strrchr(h, ':');
++ if (port != NULL) {
++ if (port == h) {
++ return "Missing IP address";
+ }
-+ break;
-+ }
-+#ifdef INET6
-+ case AF_INET6:
-+ {
-+ struct sockaddr_in6 *sin1, *sin2;
-+ sin1 = (struct sockaddr_in6 *)&sar->host_addr;
-+ sin2 = (struct sockaddr_in6 *)sa;
-+ if (sin1->sin6_port == 0 || sin2->sin6_port == 0
-+ || sin1->sin6_port == sin2->sin6_port) {
-+ if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
-+ sizeof(sin1->sin6_addr)) == 0) {
-+ return trav;
-+ }
++ else if (port[1] == '\0') {
++ return "Address must end in :<port-number>";
+ }
-+ break;
-+ }
-+#endif
-+ default: /*unsupported*/
-+ break;
++ *(port++) = '\0';
++ if (*h)
++ host = h;
++ }
++ else {
++ host = NULL;
++ port = h;
}
+- *(ports++) = '\0';
+- }
+- else {
+- ports = ips;
++ } else {
++ host = h;
++ port = p;
}
-+
-+#ifdef INET6
-+ if (sa->sa_family == AF_INET6 &&
-+ IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) {
-+ /*
-+ * This is just horrible. I just hate IPv4 mapped address. It
-+ * complicates access control too much.
-+ * Due to hashed lookup, we need to visit it again.
-+ */
-+ struct sockaddr_in sin;
-+
-+ memset(&sin, 0, sizeof(sin));
-+ sin.sin_family = AF_INET;
-+#ifdef SIN6_LEN
-+ sin.sin_len = sizeof(sin);
-+#endif
-+ sin.sin_port = ((struct sockaddr_in6 *)sa)->sin6_port;
-+ memcpy(&sin.sin_addr,
-+ &((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12],
-+ sizeof(sin.sin_addr));
-+ return find_ipaddr((struct sockaddr *)&sin);
-+ }
-+#endif
-+
- return NULL;
- }
-
-@@ -416,21 +520,7 @@
- int len;
- char buf[MAX_STRING_LEN];
-- if (ic->sar->host_addr.s_addr == DEFAULT_VHOST_ADDR) {
-- len = ap_snprintf(buf, sizeof(buf), "_default_:%u",
-- ic->sar->host_port);
-- }
-- else if (ic->sar->host_addr.s_addr == INADDR_ANY) {
-- len = ap_snprintf(buf, sizeof(buf), "*:%u",
-- ic->sar->host_port);
+- new=ap_pcalloc(cmd->pool, sizeof(listen_rec));
+- new->local_addr.sin_family = AF_INET;
+- if (ports == ips) { /* no address */
+- new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- }
- else {
-- len = ap_snprintf(buf, sizeof(buf), "%pA:%u",
-- &ic->sar->host_addr, ic->sar->host_port);
-- }
-- if (ic->sar->host_port == 0) {
-- buf[len-1] = '*';
+- new->local_addr.sin_addr.s_addr = ap_get_virthost_addr(ips, NULL);
- }
-+ len = ap_snprintf(buf, sizeof(buf), "%pI", &ic->sar->host_addr);
- if (ic->names == NULL) {
- if (ic->server == NULL)
- fprintf(f, "%-22s WARNING: No <VirtualHost> defined for this NameVirtualHost!\n", buf);
-@@ -558,10 +648,37 @@
- * occured in the config file, we'll copy it in that order.
- */
- for (sar = name_vhost_list; sar; sar = sar->next) {
-- unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
-+ unsigned bucket = hash_addr((struct sockaddr *)&sar->host_addr);
- ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
-+ int wildcard;
+- errno = 0; /* clear errno before calling strtol */
+- port = ap_strtol(ports, &endptr, 10);
+- if (errno /* some sort of error */
+- || (endptr && *endptr) /* make sure no trailing characters */
+- || port < 1 || port > 65535) /* underflow/overflow */
+- {
+- return "Missing, invalid, or non-numeric port";
++ if (host && strcmp(host, "*") == 0)
++ host = NULL;
++
++ new = ap_pcalloc(cmd->pool, sizeof(listen_rec));
+
-+ wildcard = 0;
-+ switch (sar->host_addr.ss_family) {
-+ case AF_INET:
-+ {
-+ struct sockaddr_in *sin;
-+ sin = (struct sockaddr_in *)&sar->host_addr;
-+ if (sin->sin_addr.s_addr == INADDR_ANY)
-+ wildcard++;
-+ break;
-+ }
-+#ifdef INET6
-+ case AF_INET6:
-+ {
-+ struct sockaddr_in6 *sin6;
-+ sin6 = (struct sockaddr_in6 *)&sar->host_addr;
-+ if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == 0
-+ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == 0
-+ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == 0
-+ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == 0) {
-+ wildcard++;
-+ }
-+ break;
-+ }
-+#endif
-+ }
-
-- if (sar->host_addr.s_addr != INADDR_ANY) {
-+ if (!wildcard) {
- *iphash_table_tail[bucket] = ic;
- iphash_table_tail[bucket] = &ic->next;
- }
-@@ -588,12 +705,45 @@
- has_default_vhost_addr = 0;
- for (sar = s->addrs; sar; sar = sar->next) {
- ipaddr_chain *ic;
-+ int wildcard;
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = host ? PF_UNSPEC : ap_default_family;
++ hints.ai_flags = AI_PASSIVE;
++ hints.ai_socktype = SOCK_STREAM;
++ error = getaddrinfo(host, port, &hints, &res);
++ if (error || !res) {
++ fprintf(stderr, "could not resolve ");
++ if (host)
++ fprintf(stderr, "host \"%s\" ", host);
++ if (port)
++ fprintf(stderr, "port \"%s\" ", port);
++ fprintf(stderr, "--- %s\n", gai_strerror(error));
++ exit(1);
++ }
++ if (res->ai_next) {
++ if (host)
++ fprintf(stderr, "host \"%s\" ", host);
++ if (port)
++ fprintf(stderr, "port \"%s\" ", port);
++ fprintf(stderr, "resolved to multiple addresses, ambiguous.\n");
++ exit(1);
+ }
+- new->local_addr.sin_port = htons((unsigned short)port);
+
-+ wildcard = 0;
-+ switch (sar->host_addr.ss_family) {
-+ case AF_INET:
-+ {
-+ struct sockaddr_in *sin;
-+ sin = (struct sockaddr_in *)&sar->host_addr;
-+ if (sin->sin_addr.s_addr == DEFAULT_VHOST_ADDR)
-+ wildcard++;
-+ else if (sin->sin_addr.s_addr == INADDR_ANY)
-+ wildcard++;
-+ break;
-+ }
++ memcpy(&new->local_addr, res->ai_addr, res->ai_addrlen);
++
+ new->fd = -1;
+ new->used = 0;
+ new->next = ap_listeners;
+@@ -3650,7 +3717,7 @@
+ { "ThreadStackSize", set_threadstacksize, NULL, RSRC_CONF, TAKE1,
+ "Stack size each created thread will use."},
+ #endif
+-{ "Listen", set_listener, NULL, RSRC_CONF, TAKE1,
++{ "Listen", set_listener, NULL, RSRC_CONF, TAKE12,
+ "A port number or a numeric IP address and a port number"},
+ { "SendBufferSize", set_send_buffer_size, NULL, RSRC_CONF, TAKE1,
+ "Send buffer size in bytes"},
+@@ -3684,7 +3751,7 @@
+ "Name of the config file to be included" },
+ { "LogLevel", set_loglevel, NULL, RSRC_CONF, TAKE1,
+ "Level of verbosity in error logging" },
+-{ "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE1,
++{ "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE12,
+ "A numeric IP address:port, or the name of a host" },
+ #ifdef _OSD_POSIX
+ { "BS2000Account", set_bs2000_account, NULL, RSRC_CONF, TAKE1,
+diff -Nur apache_1.3.28.orig/src/main/http_main.c apache_1.3.28/src/main/http_main.c
+--- apache_1.3.28.orig/src/main/http_main.c Fri Jul 25 11:00:49 2003
++++ apache_1.3.28/src/main/http_main.c Fri Jul 25 12:13:12 2003
+@@ -124,6 +124,8 @@
+ #include <bstring.h> /* for IRIX, FD_SET calls bzero() */
+ #endif
+
++#include "sa_len.h"
++
+ #ifdef MULTITHREAD
+ /* special debug stuff -- PCS */
+
+@@ -249,7 +251,12 @@
+ API_VAR_EXPORT char *ap_scoreboard_fname=NULL;
+ API_VAR_EXPORT char *ap_lock_fname=NULL;
+ API_VAR_EXPORT char *ap_server_argv0=NULL;
+-API_VAR_EXPORT struct in_addr ap_bind_address={0};
+#ifdef INET6
-+ case AF_INET6:
-+ {
-+ struct sockaddr_in6 *sin6;
-+ sin6 = (struct sockaddr_in6 *)&sar->host_addr;
-+ if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == ~0
-+ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == ~0
-+ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == ~0
-+ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == ~0) {
-+ wildcard++;
-+ }
-+ break;
-+ }
++API_VAR_EXPORT int ap_default_family = PF_INET6;
++#else
++API_VAR_EXPORT int ap_default_family = PF_INET;
+#endif
-+ }
++API_VAR_EXPORT struct sockaddr_storage ap_bind_address={0};
+ API_VAR_EXPORT int ap_daemons_to_start=0;
+ API_VAR_EXPORT int ap_daemons_min_free=0;
+ API_VAR_EXPORT int ap_daemons_max_free=0;
+@@ -1448,7 +1455,11 @@
+ fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin);
+ #endif
+ fprintf(stderr, " %s [-C \"directive\"] [-c \"directive\"]\n", pad);
+- fprintf(stderr, " %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T] [-F]\n", pad);
++ fprintf(stderr, " %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T] [-F]"
++#ifdef INET6
++ " [-46]"
++#endif
++ "\n", pad);
+ fprintf(stderr, "Options:\n");
+ #ifdef SHARED_CORE
+ fprintf(stderr, " -R directory : specify an alternate location for shared object files\n");
+@@ -1474,6 +1485,10 @@
+ #ifndef WIN32
+ fprintf(stderr, " -F : run main process in foreground, for process supervisors\n");
+ #endif
++#ifdef INET6
++ fprintf(stderr, " -4 : assume IPv4 on parsing configuration file\n");
++ fprintf(stderr, " -6 : assume IPv6 on parsing configuration file\n");
++#endif
+ #ifdef WIN32
+ fprintf(stderr, " -n name : name the Apache service for -k options below;\n");
+ fprintf(stderr, " -k stop|shutdown : tell running Apache to shutdown\n");
+@@ -3630,11 +3645,13 @@
-- if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
-- || sar->host_addr.s_addr == INADDR_ANY) {
-- ic = find_default_server(sar->host_port);
-- if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
-- if (ic && ic->sar->host_port != 0) {
-+ if (wildcard) {
-+ /* add it to default bucket for each appropriate sar
-+ * since we need to do a port test
-+ */
-+ ipaddr_chain *other;
-+
-+ other = find_default_server(sar->host_port);
-+ if (!other || !add_name_vhost_config(p, main_s, s, sar, other)) {
-+ if (other && other->sar->host_port != 0) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
- main_s, "_default_ VirtualHost overlap on port %u,"
- " the first has precedence", sar->host_port);
-@@ -606,10 +756,11 @@
- }
- else {
- /* see if it matches something we've already got */
-- ic = find_ipaddr(&sar->host_addr, sar->host_port);
-+ ic = find_ipaddr((struct sockaddr *)&sar->host_addr);
- if (!ic) {
-- unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
-+ unsigned bucket =
-+ hash_addr((struct sockaddr *)&sar->host_addr);
+ static conn_rec *new_connection(pool *p, server_rec *server, BUFF *inout,
+- const struct sockaddr_in *remaddr,
+- const struct sockaddr_in *saddr,
++ const struct sockaddr *remaddr,
++ const struct sockaddr *saddr,
+ int child_num)
+ {
+ conn_rec *conn = (conn_rec *) ap_pcalloc(p, sizeof(conn_rec));
++ char hostnamebuf[MAXHOSTNAMELEN];
++ size_t addr_len;
- ic = new_ipaddr_chain(p, s, sar);
- ic->next = *iphash_table_tail[bucket];
-@@ -646,19 +797,33 @@
- }
- else {
- struct hostent *h;
-+ char hostnamebuf[MAXHOSTNAMELEN];
+ /* Got a connection structure, so initialize what fields we can
+ * (the rest are zeroed out by pcalloc).
+@@ -3643,17 +3660,29 @@
+ conn->child_num = child_num;
-- if ((h = gethostbyaddr((char *) &(s->addrs->host_addr),
-- sizeof(struct in_addr), AF_INET))) {
-- s->server_hostname = ap_pstrdup(p, (char *) h->h_name);
-+ if (!getnameinfo((struct sockaddr *)&s->addrs->host_addr,
+ conn->pool = p;
+- conn->local_addr = *saddr;
+- conn->local_ip = ap_pstrdup(conn->pool,
+- inet_ntoa(conn->local_addr.sin_addr));
+#ifndef SIN6_LEN
-+ SA_LEN((struct sockaddr *)&s->addrs->host_addr),
-+#else
-+ s->addrs->host_addr.ss_len,
++ addr_len = SA_LEN(saddr);
++#else
++ addr_len = saddr->sa_len;
+#endif
-+ hostnamebuf, sizeof(hostnamebuf),
-+ NULL, 0, 0)) {
-+ s->server_hostname = ap_pstrdup(p, hostnamebuf);
- }
- else {
- /* again, what can we do? They didn't specify a
- ServerName, and their DNS isn't working. -djg */
-+ getnameinfo((struct sockaddr *)&s->addrs->host_addr,
-+#ifndef SIN6_LEN
-+ SA_LEN((struct sockaddr *)&s->addrs->host_addr),
-+#else
-+ s->addrs->host_addr.ss_len,
++ memcpy(&conn->local_addr, saddr, addr_len);
++ getnameinfo((struct sockaddr *)&conn->local_addr, addr_len,
++ hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
++ conn->local_ip = ap_pstrdup(conn->pool, hostnamebuf);
+ conn->server = server; /* just a guess for now */
+ ap_update_vhost_given_ip(conn);
+ conn->base_server = conn->server;
+ conn->client = inout;
+
+- conn->remote_addr = *remaddr;
+- conn->remote_ip = ap_pstrdup(conn->pool,
+- inet_ntoa(conn->remote_addr.sin_addr));
++#ifndef SIN6_LEN
++ addr_len = SA_LEN(remaddr);
++#else
++ addr_len = remaddr->sa_len;
+#endif
-+ hostnamebuf, sizeof(hostnamebuf),
-+ NULL, 0, NI_NUMERICHOST);
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, main_s,
- "Failed to resolve server name "
- "for %s (check DNS) -- or specify an explicit "
-- "ServerName",
-- inet_ntoa(s->addrs->host_addr));
-+ "ServerName", hostnamebuf);
- s->server_hostname =
- ap_pstrdup(p, "bogus_host_without_reverse_dns");
- }
-@@ -705,35 +870,58 @@
- char *host = ap_palloc(r->pool, strlen(r->hostname) + 1);
- const char *src;
- char *dst;
-+ const char *u = NULL, *v = NULL;
++ memcpy(&conn->remote_addr, remaddr, addr_len);
++ getnameinfo((struct sockaddr *)&conn->remote_addr, addr_len,
++ hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
++ conn->remote_ip = ap_pstrdup(conn->pool, hostnamebuf);
+ #ifdef EAPI
+ conn->ctx = ap_ctx_new(conn->pool);
+ #endif /* EAPI */
+@@ -3711,21 +3740,47 @@
+ #define sock_disable_nagle(s, c) /* NOOP */
+ #endif
- /* check and copy the host part */
-- src = r->hostname;
-+ u = src = r->hostname;
+-static int make_sock(pool *p, const struct sockaddr_in *server)
++static int make_sock(pool *p, const struct sockaddr *server)
+ {
+ int s;
+ int one = 1;
+- char addr[512];
++ char addr[INET6_ADDRSTRLEN + 128];
++ char a0[INET6_ADDRSTRLEN];
++ char p0[NI_MAXSERV];
++#ifdef MPE
++ int privport = 0;
++#endif
- dst = host;
-- while (*src) {
-- if (*src == '.') {
-- *dst++ = *src++;
-- if (*src == '.')
-- goto bad;
-- else
-- continue;
-- }
-- if (*src == '/' || *src == '\\') {
-- goto bad;
-- }
-- if (*src == ':') {
-- /* check the port part */
-- while (*++src) {
-- if (!ap_isdigit(*src)) {
-- goto bad;
-- }
-- }
-- if (src[-1] == ':')
-- goto bad;
-- else
-- break;
-+ if (*u == '[') { /* IPv6 numeral address in brackets */
-+ v = strchr(u, ']');
-+ if (v == NULL) {
-+ /* missing closing bracket */
-+ goto bad;
-+ }
-+ if (v == (u + 1)) {
-+ /* bad empty address */
-+ goto bad;
-+ }
-+ for (src = u+1; src < v; src++) /* copy IPv6 adress */
-+ *dst = *src;
-+ v++;
-+ if (*v == ':') {
-+ v++;
-+ while (*v) { /* check if portnum is correct */
-+ if (!ap_isdigit(*v++))
-+ goto bad;
-+ }
- }
-- *dst++ = *src++;
-+ } else {
-+ while (*src) {
-+ if (*src == '.') {
-+ *dst++ = *src++;
-+ if (*src == '.')
-+ goto bad;
-+ else
-+ continue;
-+ }
-+ if (*src == '/' || *src == '\\') {
-+ goto bad;
-+ }
-+ if (*src == ':') {
-+ /* sheck the port part */
-+ while (*++src) {
-+ if (!ap_isdigit(*src)) {
-+ goto bad;
-+ }
-+ }
-+ if (src[-1] == ':')
-+ goto bad;
-+ else
-+ break;
-+ }
-+ *dst++ = *src++;
-+ }
- }
- /* strip trailing gubbins */
- if (dst > host && dst[-1] == '.') {
-@@ -748,7 +936,7 @@
- bad:
- r->status = HTTP_BAD_REQUEST;
- ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
-- "Client sent malformed Host header");
-+ "Client sent malformed Host header <<%s>>",u);
- return;
- }
-
-@@ -851,11 +1039,25 @@
- * names we'll match have ports associated with them
- */
- const char *host = r->hostname;
-- unsigned port = ntohs(r->connection->local_addr.sin_port);
-+ unsigned port;
- server_rec *s;
- server_rec *last_s;
- name_chain *src;
-
-+ switch (r->connection->local_addr.ss_family) {
-+ case AF_INET:
-+ port = ntohs(((struct sockaddr_in *)
-+ &r->connection->local_addr)->sin_port);
-+ break;
-+#ifdef INET6
-+ case AF_INET6:
-+ port = ntohs(((struct sockaddr_in6 *)
-+ &r->connection->local_addr)->sin6_port);
-+ break;
-+#endif
-+ default:
-+ port = 0; /*XXX*/
-+ }
- last_s = NULL;
-
- /* Recall that the name_chain is a list of server_addr_recs, some of
-@@ -910,7 +1112,22 @@
- server_rec *s;
- server_rec *last_s;
- name_chain *src;
-- unsigned port = ntohs(r->connection->local_addr.sin_port);
-+ unsigned port;
-+
-+ switch (r->connection->local_addr.ss_family) {
+- if (server->sin_addr.s_addr != htonl(INADDR_ANY))
+- ap_snprintf(addr, sizeof(addr), "address %s port %d",
+- inet_ntoa(server->sin_addr), ntohs(server->sin_port));
+- else
+- ap_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port));
++ switch(server->sa_family){
+ case AF_INET:
-+ port = ntohs(((struct sockaddr_in *)
-+ &r->connection->local_addr)->sin_port);
-+ break;
+#ifdef INET6
+ case AF_INET6:
-+ port = ntohs(((struct sockaddr_in6 *)
-+ &r->connection->local_addr)->sin6_port);
-+ break;
+#endif
++ break;
+ default:
-+ port = 0; /*XXX*/
++ ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
++ "make_sock: unsupported address family %u",
++ server->sa_family);
++ ap_unblock_alarms();
++ exit(1);
+ }
-
- /*
- * This is in conjunction with the ServerPath code in http_core, so we
-@@ -970,10 +1187,22 @@
- API_EXPORT(void) ap_update_vhost_given_ip(conn_rec *conn)
- {
- ipaddr_chain *trav;
-- unsigned port = ntohs(conn->local_addr.sin_port);
-+ char portbuf[NI_MAXSERV];
-+ unsigned port;
-+
-+ if (getnameinfo((struct sockaddr *)&conn->local_addr,
++
++ getnameinfo(server,
+#ifndef SIN6_LEN
-+ SA_LEN((struct sockaddr *)&conn->local_addr),
-+#else
-+ conn->local_addr.ss_len,
++ SA_LEN(server),
++#else
++ server->sa_len,
++#endif
++ a0, sizeof(a0), p0, sizeof(p0), NI_NUMERICHOST | NI_NUMERICSERV);
++ ap_snprintf(addr, sizeof(addr), "address %s port %s", a0, p0);
++#ifdef MPE
++ if (atoi(p0) < 1024)
++ privport++;
+#endif
-+ NULL, 0, portbuf, sizeof(portbuf), NI_NUMERICSERV) != 0) {
-+ goto fail;
-+ }
-+ port = atoi(portbuf);
- /* scan the hash table for an exact match first */
-- trav = find_ipaddr(&conn->local_addr.sin_addr, port);
-+ trav = find_ipaddr((struct sockaddr *)&conn->local_addr);
- if (trav) {
- /* save the name_chain for later in case this is a name-vhost */
- conn->vhost_lookup_data = trav->names;
-@@ -991,6 +1220,7 @@
- return;
- }
+ /* note that because we're about to slack we don't use psocket */
+ ap_block_alarms();
+- if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
++ if ((s = socket(server->sa_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
+ "make_sock: failed to get a socket for %s", addr);
-+fail:
- /* otherwise we're stuck with just the main server
- * and no name-based vhosts
- */
-diff -Nur apache_1.3.26.orig/src/main/util.c apache_1.3.26/src/main/util.c
---- apache_1.3.26.orig/src/main/util.c Tue Jun 18 02:59:58 2002
-+++ apache_1.3.26/src/main/util.c Wed Jun 19 10:26:32 2002
-@@ -2017,52 +2017,87 @@
- * Parses a host of the form <address>[:port]
- * :port is permitted if 'port' is not NULL
- */
--API_EXPORT(unsigned long) ap_get_virthost_addr(char *w, unsigned short *ports)
-+API_EXPORT(struct sockaddr *) ap_get_virthost_addr(char *w, unsigned short *ports)
- {
-- struct hostent *hep;
-- unsigned long my_addr;
-- char *p;
--
-- p = strchr(w, ':');
-+ static struct sockaddr_storage ss;
-+ struct addrinfo hints, *res;
-+ char *p, *r;
-+ char *host;
-+ char *port = "0";
-+ int error;
-+ char servbuf[NI_MAXSERV];
-+
-+ if (w == NULL)
-+ w = "*";
-+ p = r = NULL;
-+ if (*w == '['){
-+ if (r = strrchr(w+1, ']')){
-+ *r = '\0';
-+ p = r + 1;
-+ switch(*p){
-+ case ':':
-+ p++;
-+ /* nobreak; */
-+ case '\0':
-+ w++;
-+ break;
-+ default:
-+ p = NULL;
-+ }
-+ }
-+ }
-+ else{
-+ p = strchr(w, ':');
-+ if (p != NULL && strchr(p+1, ':') != NULL)
-+ p = NULL;
-+ }
- if (ports != NULL) {
-- *ports = 0;
-- if (p != NULL && strcmp(p + 1, "*") != 0)
-- *ports = atoi(p + 1);
-+ if (p != NULL && *p && strcmp(p + 1, "*") != 0)
-+ port = p + 1;
- }
+@@ -3828,15 +3883,19 @@
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_socktype = SOCK_STREAM;
- if (p != NULL)
- *p = '\0';
- if (strcmp(w, "*") == 0) {
-- if (p != NULL)
-- *p = ':';
-- return htonl(INADDR_ANY);
-- }
+ #ifdef MPE
+ /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
+- if (ntohs(server->sin_port) < 1024)
++ if (privport)
+ GETPRIVMODE();
+ #endif
-
-- my_addr = ap_inet_addr((char *)w);
-- if (my_addr != INADDR_NONE) {
-- if (p != NULL)
-- *p = ':';
-- return my_addr;
-+ host = NULL;
-+ hints.ai_flags = AI_PASSIVE;
-+ hints.ai_family = ap_default_family;
-+ } else {
-+ host = w;
-+ hints.ai_family = PF_UNSPEC;
- }
-
-- hep = gethostbyname(w);
-+ error = getaddrinfo(host, port, &hints, &res);
-
-- if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
-- fprintf(stderr, "Cannot resolve host name %s --- exiting!\n", w);
-+ if (error || !res) {
-+ fprintf(stderr, "ap_get_vitrhost_addr(): getaddrinfo(%s):%s --- exiting!\n", w, gai_strerror(error));
- exit(1);
- }
+- if (bind(s, (struct sockaddr *) server, sizeof(struct sockaddr_in)) == -1) {
++#ifndef SIN6_LEN
++ if (bind(s, server, SA_LEN(server)) == -1)
++#else
++ if (bind(s, server, server->sa_len) == -1)
++#endif
++ {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
+ "make_sock: could not bind to %s", addr);
+ #ifdef MPE
+- if (ntohs(server->sin_port) < 1024)
++ if (privport)
+ GETUSERMODE();
+ #endif
-- if (hep->h_addr_list[1]) {
-- fprintf(stderr, "Host %s has multiple addresses ---\n", w);
-+ if (res->ai_next) {
-+ fprintf(stderr, "ap_get_vitrhost_addr(): Host %s has multiple addresses ---\n", w);
- fprintf(stderr, "you must choose one explicitly for use as\n");
- fprintf(stderr, "a virtual host. Exiting!!!\n");
+@@ -3849,7 +3908,7 @@
exit(1);
}
-
-+ if (r != NULL)
-+ *r = ']';
- if (p != NULL)
- *p = ':';
-
-- return ((struct in_addr *) (hep->h_addr))->s_addr;
-+ memcpy(&ss, res->ai_addr, res->ai_addrlen);
-+ if (getnameinfo(res->ai_addr, res->ai_addrlen,
-+ NULL, 0, servbuf, sizeof(servbuf),
-+ NI_NUMERICSERV)){
-+ fprintf(stderr, "ap_get_virthost_addr(): getnameinfo() failed --- Exiting!!!\n");
-+ exit(1);
-+ }
-+ if (ports) *ports = atoi(servbuf);
-+ freeaddrinfo(res);
-+ return (struct sockaddr *)&ss;
- }
-
-
-@@ -2090,7 +2125,8 @@
+ #ifdef MPE
+- if (ntohs(server->sin_port) < 1024)
++ if (privport)
+ GETUSERMODE();
#endif
- char str[MAXHOSTNAMELEN];
- char *server_hostname = NULL;
-- struct hostent *p;
-+ struct addrinfo hints, *res;
-+ int error;
- #ifdef BEOS /* BeOS returns zero as an error for gethostname */
- if (gethostname(str, sizeof(str) - 1) == 0) {
-@@ -2103,29 +2139,38 @@
- }
- else
- {
-- str[sizeof(str) - 1] = '\0';
-- if ((!(p = gethostbyname(str)))
-- || (!(server_hostname = find_fqdn(a, p)))) {
-- /* Recovery - return the default servername by IP: */
-- if (p && p->h_addr_list && p->h_addr_list[0]) {
-- ap_snprintf(str, sizeof(str), "%pA", p->h_addr_list[0]);
-- server_hostname = ap_pstrdup(a, str);
-- /* We will drop through to report the IP-named server */
-- }
-- }
-- else
-- /* Since we found a fqdn, return it with no logged message. */
-- return server_hostname;
-- }
--
-- /* If we don't have an fdqn or IP, fall back to the loopback addr */
-- if (!server_hostname)
-- server_hostname = ap_pstrdup(a, "127.0.0.1");
--
-- ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
-- "%s: Could not determine the server's fully qualified "
-- "domain name, using %s for ServerName",
-- ap_server_argv0, server_hostname);
-+ str[sizeof(str) - 1] = '\0';
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_flags = AI_CANONNAME;
-+ error = getaddrinfo(str, NULL, &hints, &res);
-+ if (error)
-+ {
-+ /* Recovery - return the default servername by IP: */
-+
-+ fprintf(stderr, "%s: cannot determine local host name.\n",
-+ ap_server_argv0);
-+ fprintf(stderr, "Use the ServerName directive to set it manually.\n");
-+ exit(1);
-+
-+ server_hostname = ap_pstrdup(a, res->ai_canonname);
-+ }
-+ else if (1) /*fqdn found*/
-+ {
-+ /* XXX should check more conditions */
-+ server_hostname = ap_pstrdup(a, res->ai_canonname);
-+ }
-+ else
-+ {
-+ ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
-+ "%s: Could not determine the server's fully qualified "
-+ "domain name, using %s for ServerName",
-+ ap_server_argv0, server_hostname);
-+ }
-+
-+ /* Since we found a fdqn, return it with no logged message. */
-+ freeaddrinfo(res);
-+ }
-
- return server_hostname;
- }
-@@ -2369,3 +2414,11 @@
- }
- *dest = 0;
- }
-+
-+#ifdef NEED_GETADDRINFO
-+#include "getaddrinfo.c"
-+#endif
-+
-+#ifdef NEED_GETNAMEINFO
-+#include "getnameinfo.c"
-+#endif
-diff -Nur apache_1.3.26.orig/src/main/util_script.c apache_1.3.26/src/main/util_script.c
---- apache_1.3.26.orig/src/main/util_script.c Thu Mar 21 17:07:02 2002
-+++ apache_1.3.26/src/main/util_script.c Wed Jun 19 10:26:32 2002
-@@ -67,6 +67,7 @@
- #include "http_request.h" /* for sub_req_lookup_uri() */
- #include "util_script.h"
- #include "util_date.h" /* For parseHTTPdate() */
-+#include "sa_len.h"
+@@ -4002,15 +4061,17 @@
+ for (;;) {
+ fd = find_listener(lr);
+ if (fd < 0) {
+- fd = make_sock(p, &lr->local_addr);
++ fd = make_sock(p, (struct sockaddr *)&lr->local_addr);
+ }
+ else {
+ ap_note_cleanups_for_socket_ex(p, fd, 1);
+ }
+ /* if we get here, (fd >= 0) && (fd < FD_SETSIZE) */
+- FD_SET(fd, &listenfds);
+- if (fd > listenmaxfd)
+- listenmaxfd = fd;
++ if (fd > 0) {
++ FD_SET(fd, &listenfds);
++ if (fd > listenmaxfd)
++ listenmaxfd = fd;
++ }
+ lr->fd = fd;
+ if (lr->next == NULL)
+ break;
+@@ -4327,8 +4388,8 @@
+ static void child_main(int child_num_arg)
+ {
+ NET_SIZE_T clen;
+- struct sockaddr sa_server;
+- struct sockaddr sa_client;
++ struct sockaddr_storage sa_server;
++ struct sockaddr_storage sa_client;
+ listen_rec *lr;
- #ifdef OS2
- #define INCL_DOS
-@@ -203,6 +204,7 @@
- array_header *hdrs_arr = ap_table_elts(r->headers_in);
- table_entry *hdrs = (table_entry *) hdrs_arr->elts;
- int i;
-+ char servbuf[NI_MAXSERV];
+ /* All of initialization is a critical section, we don't care if we're
+@@ -4505,7 +4566,7 @@
+ usr1_just_die = 0;
+ for (;;) {
+ clen = sizeof(sa_client);
+- csd = ap_accept(sd, &sa_client, &clen);
++ csd = ap_accept(sd, (struct sockaddr *)&sa_client, &clen);
+ if (csd >= 0 || errno != EINTR)
+ break;
+ if (deferred_die) {
+@@ -4671,7 +4732,7 @@
+ */
- /* use a temporary table which we'll overlap onto
- * r->subprocess_env later
-@@ -293,8 +295,16 @@
- ap_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
- ap_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */
+ clen = sizeof(sa_server);
+- if (getsockname(csd, &sa_server, &clen) < 0) {
++ if (getsockname(csd, (struct sockaddr *)&sa_server, &clen) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, server_conf,
+ "getsockname, client %pA probably dropped the "
+ "connection",
+@@ -4719,8 +4780,8 @@
+ ap_bpushfd(conn_io, csd, dupped_csd);
-- ap_table_addn(e, "REMOTE_PORT",
-- ap_psprintf(r->pool, "%d", ntohs(c->remote_addr.sin_port)));
-+ servbuf[0] = '\0';
-+ if (!getnameinfo((struct sockaddr *)&c->remote_addr,
-+#ifndef HAVE_SOCKADDR_LEN
-+ SA_LEN((struct sockaddr *)&c->remote_addr),
-+#else
-+ c->remote_addr.ss_len,
-+#endif
-+ NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)){
-+ ap_table_addn(e, "REMOTE_PORT", ap_pstrdup(r->pool, servbuf));
-+ }
+ current_conn = new_connection(ptrans, server_conf, conn_io,
+- (struct sockaddr_in *) &sa_client,
+- (struct sockaddr_in *) &sa_server,
++ (struct sockaddr *)&sa_client,
++ (struct sockaddr *)&sa_server,
+ my_child_num);
- if (c->user) {
- ap_table_addn(e, "REMOTE_USER", c->user);
-diff -Nur apache_1.3.26.orig/src/main/util_uri.c apache_1.3.26/src/main/util_uri.c
---- apache_1.3.26.orig/src/main/util_uri.c Tue Jun 18 02:59:58 2002
-+++ apache_1.3.26/src/main/util_uri.c Wed Jun 19 10:26:32 2002
-@@ -419,6 +419,12 @@
- * the hostname. If there's a port it is the first colon.
- */
- s = memchr(hostinfo, ':', uri - hostinfo);
-+ if (*hostinfo == '[') {
-+ s = memchr(hostinfo+1, ']', uri - hostinfo - 1);
-+ if (s)
-+ s = strchr(s, ':');
-+ } else
-+ s = memchr(hostinfo, ':', uri - hostinfo);
- if (s == NULL) {
- /* we expect the common case to have no port */
- uptr->hostname = ap_pstrndup(p, hostinfo, uri - hostinfo);
-@@ -475,7 +481,12 @@
- /* We expect hostinfo to point to the first character of
- * the hostname. There must be a port, separated by a colon
- */
-- s = strchr(hostinfo, ':');
-+ if (*hostinfo == '[') {
-+ s = strchr(hostinfo+1, ']');
-+ if (s)
-+ s = strchr(s, ':');
-+ } else
-+ s = strchr(hostinfo, ':');
- if (s == NULL) {
- return HTTP_BAD_REQUEST;
- }
-diff -Nur apache_1.3.26.orig/src/modules/proxy/mod_proxy.c apache_1.3.26/src/modules/proxy/mod_proxy.c
---- apache_1.3.26.orig/src/modules/proxy/mod_proxy.c Wed Jun 19 10:25:56 2002
-+++ apache_1.3.26/src/modules/proxy/mod_proxy.c Wed Jun 19 10:32:29 2002
-@@ -574,11 +574,31 @@
- struct proxy_remote *new;
- char *p, *q;
- int port;
-+ char *bl = NULL, *br = NULL;
+ /*
+@@ -4875,12 +4936,13 @@
- p = strchr(r, ':');
- if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0')
- return "ProxyRemote: Bad syntax for a remote proxy server";
-- q = strchr(p + 3, ':');
-+ bl = p + 3;
-+ if (*bl == '['){
-+ br = strrchr(bl+1, ']');
-+ if (br){
-+ bl++;
-+ *br = '\0';
-+ if (*(br+1) == ':'){ /* [host]:xx */
-+ q = br+1;
-+ }
-+ else if (*(br+1) == '\0'){ /* [host] */
-+ q = NULL;
-+ }
-+ else
-+ q = strrchr(br, ':'); /* XXX */
-+ }
-+ else
-+ q = strrchr(bl, ':'); /* XXX */
-+ }
-+ else
-+ q = strrchr(bl, ':');
- if (q != NULL) {
- if (sscanf(q + 1, "%u", &port) != 1 || port > 65535)
- return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)";
-@@ -589,7 +609,7 @@
- *p = '\0';
- if (strchr(f, ':') == NULL)
- ap_str_tolower(f); /* lowercase scheme */
-- ap_str_tolower(p + 3); /* lowercase hostname */
-+ ap_str_tolower(bl); /* lowercase hostname */
+ #ifdef _OSD_POSIX
+ /* BS2000 requires a "special" version of fork() before a setuid() call */
+- if ((pid = os_fork(ap_user_name)) == -1) {
++ if ((pid = os_fork(ap_user_name)) == -1)
+ #elif defined(TPF)
+- if ((pid = os_fork(s, slot)) == -1) {
++ if ((pid = os_fork(s, slot)) == -1)
+ #else
+- if ((pid = fork()) == -1) {
++ if ((pid = fork()) == -1)
+ #endif
++ {
+ ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new process");
- if (port == -1) {
- int i;
-@@ -602,7 +622,7 @@
- new = ap_push_array(conf->proxies);
- new->scheme = f;
- new->protocol = r;
-- new->hostname = p + 3;
-+ new->hostname = bl;
- new->port = port;
- return NULL;
- }
-diff -Nur apache_1.3.26.orig/src/modules/proxy/mod_proxy.h apache_1.3.26/src/modules/proxy/mod_proxy.h
---- apache_1.3.26.orig/src/modules/proxy/mod_proxy.h Sun Apr 21 13:35:07 2002
-+++ apache_1.3.26/src/modules/proxy/mod_proxy.h Wed Jun 19 10:26:32 2002
-@@ -310,7 +310,7 @@
- int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p);
- int ap_proxy_is_hostname(struct dirconn_entry *This, pool *p);
- int ap_proxy_is_word(struct dirconn_entry *This, pool *p);
--int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
-+int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r);
- int ap_proxy_garbage_init(server_rec *, pool *);
- /* This function is called by ap_table_do() for all header lines */
- int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
-diff -Nur apache_1.3.26.orig/src/modules/proxy/proxy_util.c apache_1.3.26/src/modules/proxy/proxy_util.c
---- apache_1.3.26.orig/src/modules/proxy/proxy_util.c Tue Jun 18 02:59:59 2002
-+++ apache_1.3.26/src/modules/proxy/proxy_util.c Wed Jun 19 11:05:11 2002
-@@ -64,6 +64,7 @@
- #include "http_log.h"
- #include "util_uri.h"
- #include "util_date.h" /* get ap_checkmask() decl. */
-+#include "sa_len.h"
+ /* fork didn't succeed. Fix the scoreboard or else
+@@ -5497,7 +5559,10 @@
+ ap_setup_prelinked_modules();
- static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
- static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
-@@ -219,6 +220,7 @@
- int i;
- char *strp, *host, *url = *urlp;
- char *user = NULL, *password = NULL;
-+ char *t = NULL, *u = NULL, *v = NULL;
+ while ((c = getopt(argc, argv,
+- "D:C:c:xXd:Ff:vVlLR:StTh"
++ "D:C:c:xXd:Ff:vVlLR:StTh4"
++#ifdef INET6
++ "6"
++#endif
+ #ifdef DEBUG_SIGSTOP
+ "Z:"
+ #endif
+@@ -5575,8 +5640,14 @@
+ ap_configtestonly = 1;
+ ap_docrootcheck = 0;
+ break;
+- case 'h':
+- usage(argv[0]);
++ case '4':
++ ap_default_family = PF_INET;
++ break;
++#ifdef INET6
++ case '6':
++ ap_default_family = PF_INET6;
++ break;
++#endif
+ case '?':
+ usage(argv[0]);
+ }
+@@ -5665,9 +5736,10 @@
+ else {
+ conn_rec *conn;
+ request_rec *r;
+- struct sockaddr sa_server, sa_client;
+ BUFF *cio;
++ struct sockaddr_storage sa_server, sa_client;
+ NET_SIZE_T l;
++ char servbuf[NI_MAXSERV];
- if (url[0] != '/' || url[1] != '/')
- return "Malformed URL";
-@@ -257,11 +259,22 @@
- *passwordp = password;
- }
+ ap_set_version();
+ /* Yes this is called twice. */
+@@ -5722,25 +5794,32 @@
+ #endif
-- strp = strrchr(host, ':');
-- if (strp != NULL) {
-- *(strp++) = '\0';
--
-- for (i = 0; strp[i] != '\0'; i++)
-+ v = host;
-+ if (*host == '['){
-+ u = strrchr(host, ']');
-+ if (u){
-+ host++;
-+ *u = '\0';
-+ v = u + 1;
+ l = sizeof(sa_client);
+- if ((getpeername(sock_in, &sa_client, &l)) < 0) {
++ if ((getpeername(sock_in, (struct sockaddr *)&sa_client, &l)) < 0) {
+ /* get peername will fail if the input isn't a socket */
+ perror("getpeername");
+ memset(&sa_client, '\0', sizeof(sa_client));
+ }
+
+ l = sizeof(sa_server);
+- if (getsockname(sock_in, &sa_server, &l) < 0) {
++ if (getsockname(sock_in, (struct sockaddr *)&sa_server, &l) < 0) {
+ perror("getsockname");
+ fprintf(stderr, "Error getting local address\n");
+ exit(1);
+ }
+- server_conf->port = ntohs(((struct sockaddr_in *) &sa_server)->sin_port);
++ if (getnameinfo(((struct sockaddr *)&sa_server), l,
++ NULL, 0, servbuf, sizeof(servbuf),
++ NI_NUMERICSERV)){
++ fprintf(stderr, "getnameinfo(): family=%d\n", sa_server.ss_family);
++ exit(1);
+ }
-+ }
-+ t = strrchr(v, ':');
-+ if (t){
-+ *t = '\0';
-+ strp = t + 1;
-+ }
-+ if (strp) {
-+ for (i=0; strp[i] != '\0'; i++)
- if (!ap_isdigit(strp[i]))
- break;
++ servbuf[sizeof(servbuf)-1] = '\0';
++ server_conf->port = atoi(servbuf);
+ cio = ap_bcreate(ptrans, B_RDWR | B_SOCKET);
+ cio->fd = sock_out;
+ cio->fd_in = sock_in;
+ conn = new_connection(ptrans, server_conf, cio,
+- (struct sockaddr_in *) &sa_client,
+- (struct sockaddr_in *) &sa_server, -1);
++ (struct sockaddr *)&sa_client,
++ (struct sockaddr *)&sa_server, -1);
-@@ -280,17 +293,29 @@
- return "Missing host in URL";
- /* check hostname syntax */
- for (i = 0; host[i] != '\0'; i++)
-- if (!ap_isdigit(host[i]) && host[i] != '.')
-+ if (!ap_isdigit(host[i]) && host[i] != '.' && host[i] != ':')
- break;
- /* must be an IP address */
- #if defined(WIN32) || defined(NETWARE) || defined(TPF) || defined(BEOS)
- if (host[i] == '\0' && (inet_addr(host) == -1))
-+ return "Bad IP address in URL";
-+#else
-+ if (host[i] == '\0') {
-+ struct addrinfo hints, *res0;
-+ int gai;
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_flags = AI_NUMERICHOST;
-+ if (gai = getaddrinfo(host, NULL, &hints, &res0)) {
-+#if 0
-+ return gai_strerror(gai);
- #else
-- if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1))
-+ return "Bad IP address in URL";
+ while ((r = ap_read_request(conn)) != NULL) {
+
+@@ -7447,7 +7526,11 @@
+
+ while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLz:Z:wiuStThk:n:W:")) != -1) {
+ #else /* !WIN32 */
+- while ((c = getopt(argc, argv, "D:C:c:Xd:Ff:vVlLesStTh")) != -1) {
++ while ((c = getopt(argc, argv, "D:C:c:Xd:Ff:vVlLesStTh4"
++#ifdef INET6
++ "6"
++#endif
++ )) != -1) {
#endif
-- {
-- return "Bad IP address in URL";
-+ }
-+ freeaddrinfo(res0);
- }
+ char **new;
+ switch (c) {
+@@ -7993,6 +8076,10 @@
+ case 't':
+ case 'T':
+ case 'h':
++ case '4':
++#ifdef INET6
++ case '6':
+#endif
+ case '?':
+ break;
+ case 'R':
+--- apache_1.3.31/src/main/http_vhost.c.orig Mon Mar 29 23:03:25 2004
++++ apache_1.3.31/src/main/http_vhost.c Wed May 12 13:49:13 2004
+@@ -25,6 +25,7 @@
+ #include "http_log.h"
+ #include "http_vhost.h"
+ #include "http_protocol.h"
++#include "sa_len.h"
- /* if (strchr(host,'.') == NULL && domain != NULL)
- host = pstrcat(p, host, domain, NULL);
-@@ -1359,22 +1384,46 @@
- return host != NULL && strstr(host, This->name) != NULL;
- }
-
--int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r)
-+int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r)
+ /*
+ * After all the definitions there's an explanation of how it's all put
+@@ -122,78 +123,114 @@
+ * *paddr is the variable used to keep track of **paddr between calls
+ * port is the default port to assume
+ */
+-static const char *get_addresses(pool *p, char *w, server_addr_rec ***paddr,
+- unsigned port)
++static const char *get_addresses(pool *p, char *w, char *pstr,
++ server_addr_rec ***paddr, unsigned port)
{
- int i;
-+ int salen;
-+ char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
-+#ifdef NI_WITHSCOPEID
-+ const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
-+#else
-+ const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
-+#endif
+- struct hostent *hep;
+- unsigned long my_addr;
++ struct addrinfo hints, *res, *res0;
+ server_addr_rec *sar;
+- char *t;
+- int i, is_an_ip_addr;
++ char *t = NULL, *u = NULL, *v = NULL;
++ char *hoststr = NULL, *portstr = NULL;
++ char portpool[10];
++ int error;
++ char servbuf[NI_MAXSERV];
- ap_hard_timeout("proxy connect", r);
-+#ifdef HAVE_SOCKADDR_LEN
-+ salen = addr->sa_len;
-+#else
-+ switch (addr->sa_family) {
-+ case AF_INET6:
-+ salen = sizeof(struct sockaddr_in6);
-+ break;
-+ default:
-+ salen = sizeof(struct sockaddr_in);
-+ break;
-+ }
-+#endif
- do {
-- i = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
-+ i = connect(sock, addr, salen);
- #if defined(WIN32) || defined(NETWARE)
- if (i == SOCKET_ERROR)
- errno = WSAGetLastError();
- #endif /* WIN32 */
- } while (i == -1 && errno == EINTR);
- if (i == -1) {
-+ if (getnameinfo(addr, salen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
-+ niflags) != 0) {
-+ strcpy(hbuf, "?");
-+ strcpy(pbuf, "?");
-+ }
- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
- "proxy connect to %s port %d failed",
-- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
-+ hbuf, pbuf);
+- if (*w == 0)
++ if (w == 0 || *w == 0)
+ return NULL;
+
+- t = strchr(w, ':');
+- if (t) {
+- if (strcmp(t + 1, "*") == 0) {
+- port = 0;
++ portstr = portpool;
++ ap_snprintf(portpool, sizeof(portpool), "%u", port);
++ if (!pstr) {
++ v = w;
++ u = NULL;
++ if (*w == '['){
++ u = strrchr(w, ']');
++ if (u) { /* [host]:port or [host] */
++ w++;
++ *u = '\0';
++ v = u + 1;
++ }
+ }
+- else if ((i = atoi(t + 1))) {
+- port = i;
++ /* w uv , w=v , w=v */
++ /* u!=0: [host]:port , u==0: [host:port , host */
++ t = strchr(v, ':');
++ if (t != NULL && strchr(t+1, ':') == NULL) {
++ /* [host]:port-w/o-colons, host-without-colons:port-w/o-colons */
++ *t = '\0';
++ portstr = t + 1;
+ }
+ else {
+- return ":port must be numeric";
++ portstr = "0";
+ }
+- *t = 0;
++ } else {
++ portstr = pstr;
}
- ap_kill_timeout(r);
-diff -Nur apache_1.3.26.orig/src/modules/standard/mod_access.c apache_1.3.26/src/modules/standard/mod_access.c
---- apache_1.3.26.orig/src/modules/standard/mod_access.c Wed Mar 13 22:05:33 2002
-+++ apache_1.3.26/src/modules/standard/mod_access.c Wed Jun 19 10:26:32 2002
-@@ -74,7 +74,10 @@
- T_ALL,
- T_IP,
- T_HOST,
-- T_FAIL
-+ T_FAIL,
-+#ifdef INET6
-+ T_IP6,
+- is_an_ip_addr = 0;
+- if (strcmp(w, "*") == 0) {
+- my_addr = htonl(INADDR_ANY);
+- is_an_ip_addr = 1;
+- }
+- else if (strcasecmp(w, "_default_") == 0
+- || strcmp(w, "255.255.255.255") == 0) {
+- my_addr = DEFAULT_VHOST_ADDR;
+- is_an_ip_addr = 1;
+- }
+- else if ((my_addr = ap_inet_addr(w)) != INADDR_NONE) {
+- is_an_ip_addr = 1;
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_socktype = SOCK_STREAM;
++ if (strcmp(w, "*") == 0 || strlen(w) == 0) {
++ hoststr = NULL;
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_flags = AI_PASSIVE;
++ }
++ else if (strcasecmp(w, "_default4_") == 0 ||
++ ((ap_default_family == PF_INET
++#ifndef INET6
++ || ap_default_family == PF_UNSPEC
+#endif
- };
-
- typedef struct {
-@@ -82,9 +85,15 @@
- union {
- char *from;
- struct {
-- unsigned long net;
-- unsigned long mask;
-+ struct in_addr net;
-+ struct in_addr mask;
- } ip;
++ ) && strcasecmp(w, "_default_") == 0)){
++ hoststr = "255.255.255.255";
++ hints.ai_family = PF_INET;
++ }
+#ifdef INET6
-+ struct {
-+ struct in6_addr net6;
-+ struct in6_addr mask6;
-+ } ip6;
-+#endif
- } x;
- enum allowdeny_type type;
- } allowdeny;
-@@ -167,90 +176,230 @@
-
++ else if (strcasecmp(w, "_default6_") == 0 ||
++ ((ap_default_family == PF_INET6
++ || ap_default_family == PF_UNSPEC
++ ) && strcasecmp(w, "_default_") == 0)){
++ hoststr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
++ hints.ai_family = PF_INET6;
}
- else if ((s = strchr(where, '/'))) {
-- unsigned long mask;
-+ struct addrinfo hints, *resnet, *resmask;
-+ struct sockaddr_storage net, mask;
-+ int error;
-+ char *p;
-+ int justdigits;
-
-- a->type = T_IP;
-+ a->type = T_FAIL; /*just in case*/
- /* trample on where, we won't be using it any more */
- *s++ = '\0';
-
-- if (!is_ip(where)
-- || (a->x.ip.net = ap_inet_addr(where)) == INADDR_NONE) {
-+ justdigits = 0;
-+ for (p = s; *p; p++) {
-+ if (!isdigit(*p))
-+ break;
-+ }
-+ if (!*p)
-+ justdigits++;
-+
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM; /*dummy*/
-+#ifdef AI_NUMERICHOST
-+ hints.ai_flags = AI_NUMERICHOST; /*don't resolve*/
+- if (is_an_ip_addr) {
+- sar = ap_pcalloc(p, sizeof(server_addr_rec));
+- **paddr = sar;
+- *paddr = &sar->next;
+- sar->host_addr.s_addr = my_addr;
+- sar->host_port = port;
+- sar->virthost = ap_pstrdup(p, w);
+- if (t != NULL)
+- *t = ':';
+- return NULL;
+#endif
-+ resnet = NULL;
-+ error = getaddrinfo(where, NULL, &hints, &resnet);
-+ if (error || !resnet) {
-+ if (resnet)
-+ freeaddrinfo(resnet);
- a->type = T_FAIL;
- return "syntax error in network portion of network/netmask";
- }
-+ if (resnet->ai_next) {
-+ freeaddrinfo(resnet);
-+ a->type = T_FAIL;
-+ return "network/netmask resolved to multiple addresses";
-+ }
-+ memcpy(&net, resnet->ai_addr, resnet->ai_addrlen);
-+ freeaddrinfo(resnet);
++ else{
++ hoststr = w;
++ hints.ai_family = PF_UNSPEC;
+ }
-- /* is_ip just tests if it matches [\d.]+ */
-- if (!is_ip(s)) {
-+ switch (net.ss_family) {
+- hep = gethostbyname(w);
+-
+- if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
++ error = getaddrinfo(hoststr, portstr, &hints, &res0);
++ if (error || !res0) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
+- "Cannot resolve host name %s --- ignoring!", w);
+- if (t != NULL)
+- *t = ':';
++ "Cannot resolve host %s port %s --- ignoring!", hoststr, portstr);
++ if (t != NULL) *t = ':';
++ if (u != NULL) *u = ']';
+ return NULL;
+ }
+-
+- for (i = 0; hep->h_addr_list[i]; ++i) {
++ for (res=res0; res; res=res->ai_next) {
++ switch (res->ai_addr->sa_family) {
+ case AF_INET:
-+ a->type = T_IP;
-+ a->x.ip.net.s_addr = ((struct sockaddr_in *)&net)->sin_addr.s_addr;
-+ break;
+#ifdef INET6
+ case AF_INET6:
-+ a->type = T_IP6;
-+ memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&net)->sin6_addr,
-+ sizeof(a->x.ip6.net6));
-+ break;
+#endif
++ break;
+ default:
- a->type = T_FAIL;
-- return "syntax error in mask portion of network/netmask";
-+ return "unknown address family for network";
- }
-- /* is it in /a.b.c.d form? */
-- if (strchr(s, '.')) {
-- mask = ap_inet_addr(s);
-- if (mask == INADDR_NONE) {
-+
-+ if (!justdigits) {
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM; /*dummy*/
-+#ifdef AI_NUMERICHOST
-+ hints.ai_flags = AI_NUMERICHOST; /*don't resolve*/
-+#endif
-+ resmask = NULL;
-+ error = getaddrinfo(s, NULL, &hints, &resmask);
-+ if (error || !resmask) {
-+ if (resmask)
-+ freeaddrinfo(resmask);
- a->type = T_FAIL;
- return "syntax error in mask portion of network/netmask";
- }
-- }
-- else {
-- /* assume it's in /nnn form */
-- mask = atoi(s);
-- if (mask > 32 || mask <= 0) {
-- a->type = T_FAIL;
-- return "invalid mask in network/netmask";
-- }
-- mask = 0xFFFFFFFFUL << (32 - mask);
-- mask = htonl(mask);
-- }
-- a->x.ip.mask = mask;
-- a->x.ip.net = (a->x.ip.net & mask); /* pjr - This fixes PR 4770 */
-- }
-- else if (ap_isdigit(*where) && is_ip(where)) {
-- /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
-- int shift;
-- char *t;
-- int octet;
--
-- a->type = T_IP;
-- /* parse components */
-- s = where;
-- a->x.ip.net = 0;
-- a->x.ip.mask = 0;
-- shift = 24;
-- while (*s) {
-- t = s;
-- if (!ap_isdigit(*t)) {
-+ if (resmask->ai_next) {
-+ freeaddrinfo(resmask);
- a->type = T_FAIL;
-- return "invalid ip address";
-+ return "network/netmask resolved to multiple addresses";
- }
-- while (ap_isdigit(*t)) {
-- ++t;
-- }
-- if (*t == '.') {
-- *t++ = 0;
-- }
-- else if (*t) {
-+ memcpy(&mask, resmask->ai_addr, resmask->ai_addrlen);
-+ freeaddrinfo(resmask);
-+
-+ if (net.ss_family != mask.ss_family) {
- a->type = T_FAIL;
-- return "invalid ip address";
-+ return "network/netmask resolved to different address family";
- }
-- if (shift < 0) {
-- return "invalid ip address, only 4 octets allowed";
-+
-+ switch (a->type) {
-+ case T_IP:
-+ a->x.ip.mask.s_addr =
-+ ((struct sockaddr_in *)&mask)->sin_addr.s_addr;
-+ break;
++ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, NULL,
++ "Unsupported address family %u, for host %s port %s --- ignoring!",
++ res->ai_addr->sa_family, hoststr, portstr);
++ continue;
++ }
+ sar = ap_pcalloc(p, sizeof(server_addr_rec));
+ **paddr = sar;
+ *paddr = &sar->next;
+- sar->host_addr = *(struct in_addr *) hep->h_addr_list[i];
+- sar->host_port = port;
++ memcpy(&sar->host_addr, res->ai_addr, res->ai_addrlen);
++ if (getnameinfo(res->ai_addr, res->ai_addrlen, NULL, 0, servbuf,
++ sizeof(servbuf), NI_NUMERICSERV) == 0)
++ sar->host_port = atoi(servbuf);
++ else
++ sar->host_port = 0;
+ sar->virthost = ap_pstrdup(p, w);
+ }
+
+- if (t != NULL)
+- *t = ':';
++ freeaddrinfo(res0);
++ if (t != NULL) *t = ':';
++ if (u != NULL) *u = ']';
+ return NULL;
+ }
+
+@@ -207,7 +244,8 @@
+ /* start the list of addreses */
+ addrs = &s->addrs;
+ while (hostname[0]) {
+- err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
++ err = get_addresses(p, ap_getword_conf(p, &hostname), NULL,
++ &addrs, s->port);
+ if (err) {
+ *addrs = NULL;
+ return err;
+@@ -225,10 +263,11 @@
+ }
+
+
+-API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *arg)
++API_EXPORT_NONSTD(const char *) ap_set_name_virtual_host (cmd_parms *cmd, void *dummy, char *h,
++ char *p)
+ {
+ /* use whatever port the main server has at this point */
+- return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
++ return get_addresses(cmd->pool, h, p, &name_vhost_list_tail,
+ cmd->server->port);
+ }
+
+@@ -302,6 +341,19 @@
+ return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
+ }
+
++static unsigned hash_addr(struct sockaddr *sa)
++{
++ switch (sa->sa_family) {
++ case AF_INET:
++ return hash_inaddr(((struct sockaddr_in *)sa)->sin_addr.s_addr);
+#ifdef INET6
-+ case T_IP6:
-+ memcpy(&a->x.ip6.mask6,
-+ &((struct sockaddr_in6 *)&mask)->sin6_addr,
-+ sizeof(a->x.ip6.mask6));
-+ break;
++ case AF_INET6:
++ return hash_inaddr(((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12]);
+#endif
- }
-- octet = atoi(s);
-- if (octet < 0 || octet > 255) {
-- a->type = T_FAIL;
-- return "each octet must be between 0 and 255 inclusive";
-+ } else {
-+ int mask;
-+ mask = atoi(s);
-+ switch (a->type) {
-+ case T_IP:
-+ if (mask < 0 || 32 < mask) {
-+ a->type = T_FAIL;
-+ return "netmask out of range";
++ default:
++ return hash_inaddr(sa->sa_family);
++ }
++}
+
+
+ static ipaddr_chain *new_ipaddr_chain(pool *p,
+@@ -329,25 +381,77 @@
+ return new;
+ }
+
+-
+-static ap_inline ipaddr_chain *find_ipaddr(struct in_addr *server_ip,
+- unsigned port)
++static ap_inline ipaddr_chain *find_ipaddr(struct sockaddr *sa)
+ {
+ unsigned bucket;
+ ipaddr_chain *trav;
+- unsigned addr;
++ char a[NI_MAXHOST], b[NI_MAXHOST];
+
+ /* scan the hash table for an exact match first */
+- addr = server_ip->s_addr;
+- bucket = hash_inaddr(addr);
++ bucket = hash_addr(sa);
+ for (trav = iphash_table[bucket]; trav; trav = trav->next) {
+ server_addr_rec *sar = trav->sar;
+- if ((sar->host_addr.s_addr == addr)
+- && (sar->host_port == 0 || sar->host_port == port
+- || port == 0)) {
+- return trav;
++ if (sar->host_addr.ss_family != sa->sa_family)
++ continue;
++ switch (sa->sa_family) {
++ case AF_INET:
++ {
++ struct sockaddr_in *sin1, *sin2;
++ sin1 = (struct sockaddr_in *)&sar->host_addr;
++ sin2 = (struct sockaddr_in *)sa;
++ if (sin1->sin_port == 0 || sin2->sin_port == 0
++ || sin1->sin_port == sin2->sin_port) {
++ if (memcmp(&sin1->sin_addr, &sin2->sin_addr,
++ sizeof(sin1->sin_addr)) == 0) {
++ return trav;
+ }
-+ a->x.ip.mask.s_addr = htonl(0xFFFFFFFFUL << (32 - mask));
-+ break;
++ }
++ break;
++ }
+#ifdef INET6
-+ case T_IP6:
-+ {
-+ int i;
-+ if (mask < 0 || 128 < mask) {
-+ a->type = T_FAIL;
-+ return "netmask out of range";
-+ }
-+ for (i = 0; i < mask / 8; i++) {
-+ a->x.ip6.mask6.s6_addr[i] = 0xff;
++ case AF_INET6:
++ {
++ struct sockaddr_in6 *sin1, *sin2;
++ sin1 = (struct sockaddr_in6 *)&sar->host_addr;
++ sin2 = (struct sockaddr_in6 *)sa;
++ if (sin1->sin6_port == 0 || sin2->sin6_port == 0
++ || sin1->sin6_port == sin2->sin6_port) {
++ if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
++ sizeof(sin1->sin6_addr)) == 0) {
++ return trav;
+ }
-+ if (mask % 8)
-+ a->x.ip6.mask6.s6_addr[i] = 0xff << (8 - (mask % 8));
-+ break;
-+ }
++ }
++ break;
++ }
+#endif
- }
-- a->x.ip.net |= octet << shift;
-- a->x.ip.mask |= 0xFFUL << shift;
-- s = t;
-- shift -= 8;
++ default: /*unsupported*/
++ break;
}
-- a->x.ip.net = ntohl(a->x.ip.net);
-- a->x.ip.mask = ntohl(a->x.ip.mask);
}
- else {
-- a->type = T_HOST;
-+ struct addrinfo hints, *res;
-+ struct sockaddr_storage ss;
-+ int error;
-+
-+ a->type = T_FAIL; /*just in case*/
-+
-+ /* First, try using the old apache code to match */
-+ /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
-+ if (ap_isdigit(*where) && is_ip(where)) {
-+ int shift;
-+ char *t;
-+ int octet;
-+
-+ a->type = T_IP;
-+ /* parse components */
-+ s = where;
-+ a->x.ip.net.s_addr = 0;
-+ a->x.ip.mask.s_addr = 0;
-+ shift = 24;
-+ while (*s) {
-+ t = s;
-+ if (!ap_isdigit(*t)) {
-+ a->type = T_FAIL;
-+ return "invalid ip address";
-+ }
-+ while (ap_isdigit(*t)) {
-+ ++t;
-+ }
-+ if (*t == '.') {
-+ *t++ = 0;
-+ }
-+ else if (*t) {
-+ a->type = T_FAIL;
-+ return "invalid ip address";
-+ }
-+ if (shift < 0) {
-+ return "invalid ip address, only 4 octets allowed";
-+ }
-+ octet = atoi(s);
-+ if (octet < 0 || octet > 255) {
-+ a->type = T_FAIL;
-+ return "each octet must be between 0 and 255 inclusive";
-+ }
-+ a->x.ip.net.s_addr |= octet << shift;
-+ a->x.ip.mask.s_addr |= 0xFFUL << shift;
-+ s = t;
-+ shift -= 8;
-+ }
-+ a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
-+ a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
+
-+ return NULL;
-+ }
++#ifdef INET6
++ if (sa->sa_family == AF_INET6 &&
++ IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sa)->sin6_addr)) {
++ /*
++ * This is just horrible. I just hate IPv4 mapped address. It
++ * complicates access control too much.
++ * Due to hashed lookup, we need to visit it again.
++ */
++ struct sockaddr_in sin;
+
-+ /* IPv4/v6 numeric address */
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM; /*dummy*/
-+#ifdef AI_NUMERICHOST
-+ hints.ai_flags = AI_NUMERICHOST; /*don't resolve*/
++ memset(&sin, 0, sizeof(sin));
++ sin.sin_family = AF_INET;
++#ifdef SIN6_LEN
++ sin.sin_len = sizeof(sin);
++#endif
++ sin.sin_port = ((struct sockaddr_in6 *)sa)->sin6_port;
++ memcpy(&sin.sin_addr,
++ &((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12],
++ sizeof(sin.sin_addr));
++ return find_ipaddr((struct sockaddr *)&sin);
++ }
+#endif
-+ res = NULL;
-+ error = getaddrinfo(where, NULL, &hints, &res);
-+ if (error || !res) {
-+ if (res)
-+ freeaddrinfo(res);
-+ a->type = T_HOST;
-+ return NULL;
-+ }
-+ if (res->ai_next) {
-+ freeaddrinfo(res);
-+ a->type = T_FAIL;
-+ return "network/netmask resolved to multiple addresses";
-+ }
-+ memcpy(&ss, res->ai_addr, res->ai_addrlen);
-+ freeaddrinfo(res);
+
-+ switch (ss.ss_family) {
+ return NULL;
+ }
+
+@@ -373,21 +477,7 @@
+ int len;
+ char buf[MAX_STRING_LEN];
+
+- if (ic->sar->host_addr.s_addr == DEFAULT_VHOST_ADDR) {
+- len = ap_snprintf(buf, sizeof(buf), "_default_:%u",
+- ic->sar->host_port);
+- }
+- else if (ic->sar->host_addr.s_addr == INADDR_ANY) {
+- len = ap_snprintf(buf, sizeof(buf), "*:%u",
+- ic->sar->host_port);
+- }
+- else {
+- len = ap_snprintf(buf, sizeof(buf), "%pA:%u",
+- &ic->sar->host_addr, ic->sar->host_port);
+- }
+- if (ic->sar->host_port == 0) {
+- buf[len-1] = '*';
+- }
++ len = ap_snprintf(buf, sizeof(buf), "%pI", &ic->sar->host_addr);
+ if (ic->names == NULL) {
+ if (ic->server == NULL)
+ fprintf(f, "%-22s WARNING: No <VirtualHost> defined for this NameVirtualHost!\n", buf);
+@@ -515,10 +605,37 @@
+ * occured in the config file, we'll copy it in that order.
+ */
+ for (sar = name_vhost_list; sar; sar = sar->next) {
+- unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
++ unsigned bucket = hash_addr((struct sockaddr *)&sar->host_addr);
+ ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
++ int wildcard;
+
+- if (sar->host_addr.s_addr != INADDR_ANY) {
++ wildcard = 0;
++ switch (sar->host_addr.ss_family) {
+ case AF_INET:
-+ a->type = T_IP;
-+ a->x.ip.net.s_addr = ((struct sockaddr_in *)&ss)->sin_addr.s_addr;
-+ memset(&a->x.ip.mask, 0xff, sizeof(a->x.ip.mask));
++ {
++ struct sockaddr_in *sin;
++ sin = (struct sockaddr_in *)&sar->host_addr;
++ if (sin->sin_addr.s_addr == INADDR_ANY)
++ wildcard++;
+ break;
++ }
+#ifdef INET6
+ case AF_INET6:
-+ a->type = T_IP6;
-+ memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&ss)->sin6_addr,
-+ sizeof(a->x.ip6.net6));
-+ memset(&a->x.ip6.mask6, 0xff, sizeof(a->x.ip6.mask6));
++ {
++ struct sockaddr_in6 *sin6;
++ sin6 = (struct sockaddr_in6 *)&sar->host_addr;
++ if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == 0
++ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == 0
++ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == 0
++ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == 0) {
++ wildcard++;
++ }
+ break;
++ }
+#endif
-+ default:
-+ a->type = T_FAIL;
-+ return "unknown address family for network";
+ }
- }
-
- return NULL;
-@@ -315,12 +464,63 @@
- return 1;
-
- case T_IP:
-- if (ap[i].x.ip.net != INADDR_NONE
-- && (r->connection->remote_addr.sin_addr.s_addr
-- & ap[i].x.ip.mask) == ap[i].x.ip.net) {
-- return 1;
-+ if (ap[i].x.ip.net.s_addr == INADDR_NONE)
-+ break;
-+ switch (r->connection->remote_addr.ss_family) {
++
++ if (!wildcard) {
+ *iphash_table_tail[bucket] = ic;
+ iphash_table_tail[bucket] = &ic->next;
+ }
+@@ -545,12 +662,45 @@
+ has_default_vhost_addr = 0;
+ for (sar = s->addrs; sar; sar = sar->next) {
+ ipaddr_chain *ic;
++ int wildcard;
+
+- if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
+- || sar->host_addr.s_addr == INADDR_ANY) {
+- ic = find_default_server(sar->host_port);
+- if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
+- if (ic && ic->sar->host_port != 0) {
++ wildcard = 0;
++ switch (sar->host_addr.ss_family) {
+ case AF_INET:
-+ if ((((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr
-+ & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
-+ return 1;
-+ }
++ {
++ struct sockaddr_in *sin;
++ sin = (struct sockaddr_in *)&sar->host_addr;
++ if (sin->sin_addr.s_addr == DEFAULT_VHOST_ADDR)
++ wildcard++;
++ else if (sin->sin_addr.s_addr == INADDR_ANY)
++ wildcard++;
+ break;
++ }
+#ifdef INET6
+ case AF_INET6:
-+ if (!IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr)) /*XXX*/
-+ break;
-+ if ((*(ap_uint32_t *)&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr.s6_addr[12]
-+ & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
-+ return 1;
++ {
++ struct sockaddr_in6 *sin6;
++ sin6 = (struct sockaddr_in6 *)&sar->host_addr;
++ if (*(ap_uint32_t *)&sin6->sin6_addr.s6_addr[0] == ~0
++ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[4] == ~0
++ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[8] == ~0
++ && *(ap_uint32_t *)&sin6->sin6_addr.s6_addr[12] == ~0) {
++ wildcard++;
+ }
+ break;
++ }
+#endif
+ }
-+ break;
+
-+#ifdef INET6
-+ case T_IP6:
-+ {
-+ struct in6_addr masked;
-+ int j;
-+ if (IN6_IS_ADDR_UNSPECIFIED(&ap[i].x.ip6.net6))
-+ break;
-+ switch (r->connection->remote_addr.ss_family) {
-+ case AF_INET:
-+ if (!IN6_IS_ADDR_V4MAPPED(&ap[i].x.ip6.net6)) /*XXX*/
-+ break;
-+ memset(&masked, 0, sizeof(masked));
-+ masked.s6_addr[10] = masked.s6_addr[11] = 0xff;
-+ memcpy(&masked.s6_addr[12],
-+ &((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr,
-+ sizeof(struct sockaddr_in));
-+ for (j = 0; j < sizeof(struct in6_addr); j++)
-+ masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
-+ if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
-+ return 1;
-+ break;
-+ case AF_INET6:
-+ memset(&masked, 0, sizeof(masked));
-+ memcpy(&masked,
-+ &((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr,
-+ sizeof(masked));
-+ for (j = 0; j < sizeof(struct in6_addr); j++)
-+ masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
-+ if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
-+ return 1;
-+ break;
++ if (wildcard) {
++ /* add it to default bucket for each appropriate sar
++ * since we need to do a port test
++ */
++ ipaddr_chain *other;
++
++ other = find_default_server(sar->host_port);
++ if (!other || !add_name_vhost_config(p, main_s, s, sar, other)) {
++ if (other && other->sar->host_port != 0) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
+ main_s, "_default_ VirtualHost overlap on port %u,"
+ " the first has precedence", sar->host_port);
+@@ -563,10 +713,11 @@
}
- break;
-+ }
-+#endif
+ else {
+ /* see if it matches something we've already got */
+- ic = find_ipaddr(&sar->host_addr, sar->host_port);
++ ic = find_ipaddr((struct sockaddr *)&sar->host_addr);
- case T_HOST:
- if (!gothost) {
-diff -Nur apache_1.3.26.orig/src/modules/standard/mod_unique_id.c apache_1.3.26/src/modules/standard/mod_unique_id.c
---- apache_1.3.26.orig/src/modules/standard/mod_unique_id.c Wed Mar 13 22:05:34 2002
-+++ apache_1.3.26/src/modules/standard/mod_unique_id.c Wed Jun 19 10:26:32 2002
-@@ -67,10 +67,22 @@
- #include "http_config.h"
- #include "http_log.h"
- #include "multithread.h"
-+#include "sa_len.h"
-+
-+/*#define SHORT_UNIQUE_ID*/
+ if (!ic) {
+- unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
++ unsigned bucket =
++ hash_addr((struct sockaddr *)&sar->host_addr);
- typedef struct {
- unsigned int stamp;
-- unsigned int in_addr;
-+ union {
-+ struct in_addr in;
-+#ifdef INET6
-+# ifdef SHORT_UNIQUE_ID
-+ ap_uint32_t in6;
-+# else
-+ struct in6_addr in6;
-+# endif
+ ic = new_ipaddr_chain(p, s, sar);
+ ic->next = *iphash_table_tail[bucket];
+@@ -603,19 +754,33 @@
+ }
+ else {
+ struct hostent *h;
++ char hostnamebuf[MAXHOSTNAMELEN];
+
+- if ((h = gethostbyaddr((char *) &(s->addrs->host_addr),
+- sizeof(struct in_addr), AF_INET))) {
+- s->server_hostname = ap_pstrdup(p, (char *) h->h_name);
++ if (!getnameinfo((struct sockaddr *)&s->addrs->host_addr,
++#ifndef SIN6_LEN
++ SA_LEN((struct sockaddr *)&s->addrs->host_addr),
++#else
++ s->addrs->host_addr.ss_len,
+#endif
-+ } addr;
- unsigned int pid;
- #ifdef MULTITHREAD
- unsigned int tid;
-@@ -142,7 +154,7 @@
- * this shouldn't be a problem till year 2106.
- */
++ hostnamebuf, sizeof(hostnamebuf),
++ NULL, 0, 0)) {
++ s->server_hostname = ap_pstrdup(p, hostnamebuf);
+ }
+ else {
+ /* again, what can we do? They didn't specify a
+ ServerName, and their DNS isn't working. -djg */
++ getnameinfo((struct sockaddr *)&s->addrs->host_addr,
++#ifndef SIN6_LEN
++ SA_LEN((struct sockaddr *)&s->addrs->host_addr),
++#else
++ s->addrs->host_addr.ss_len,
++#endif
++ hostnamebuf, sizeof(hostnamebuf),
++ NULL, 0, NI_NUMERICHOST);
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, main_s,
+ "Failed to resolve server name "
+ "for %s (check DNS) -- or specify an explicit "
+- "ServerName",
+- inet_ntoa(s->addrs->host_addr));
++ "ServerName", hostnamebuf);
+ s->server_hostname =
+ ap_pstrdup(p, "bogus_host_without_reverse_dns");
+ }
+@@ -663,45 +828,80 @@
+ const char *src;
+ char *dst;
+ const char *port_str;
++ const char *u, *v = NULL;
--static unsigned global_in_addr;
-+static struct sockaddr_storage global_addr;
+ /* check and copy the host part */
+- src = r->hostname;
++ u = src = r->hostname;
- #ifdef WIN32
+ dst = host;
+- while (*src) {
+- if (*src == '.') {
+- *dst++ = *src++;
+- if (*src == '.')
+- goto bad;
+- else
+- continue;
+- }
+- if (*src == '/' || *src == '\\') {
+- goto bad;
+- }
+- if (*src == ':') {
+- port_str = src + 1;
+- /* check the port part */
+- while (*++src) {
+- if (!ap_isdigit(*src)) {
++ if (*u == '[') { /* IPv6 numeral address in brackets */
++ v = strchr(u, ']');
++ if (v == NULL) {
++ /* missing closing bracket */
++ goto bad;
++ }
++ if (v == (u + 1)) {
++ /* bad empty address */
++ goto bad;
++ }
++ for (src = u+1; src < v; src++) /* copy IPv6 adress */
++ *dst = *src;
++ v++;
++ if (*v == ':') {
++ port_str = v + 1;
++ v++;
++ while (*v) { /* check if portnum is correct */
++ if (!ap_isdigit(*v++))
+ goto bad;
+- }
+ }
+- if (src[-1] == ':')
++ if (v[-1] == ':')
++ goto bad;
++ else {
++ /* a known "good" port value */
++ int iport;
++ iport = atoi(port_str);
++ if (iport < 1 || iport > 65535) {
++ goto bad;
++ }
++ r->parsed_uri.port_str = ap_pstrdup(r->pool, port_str);
++ r->parsed_uri.port = iport;
++ }
++ }
++ } else {
++ while (*src) {
++ if (*src == '.') {
++ *dst++ = *src++;
++ if (*src == '.')
++ goto bad;
++ else
++ continue;
++ }
++ if (*src == '/' || *src == '\\') {
+ goto bad;
+- else {
+- /* a known "good" port value */
+- int iport;
+- iport = atoi(port_str);
+- if (iport < 1 || iport > 65535) {
++ }
++ if (*src == ':') {
++ port_str = src + 1;
++ /* sheck the port part */
++ while (*++src) {
++ if (!ap_isdigit(*src)) {
++ goto bad;
++ }
++ }
++ if (src[-1] == ':')
+ goto bad;
++ else {
++ /* a known "good" port value */
++ int iport;
++ iport = atoi(port_str);
++ if (iport < 1 || iport > 65535) {
++ goto bad;
++ }
++ r->parsed_uri.port_str = ap_pstrdup(r->pool, port_str);
++ r->parsed_uri.port = iport;
+ }
+- r->parsed_uri.port_str = ap_pstrdup(r->pool, port_str);
+- r->parsed_uri.port = iport;
+- break;
+ }
++ *dst++ = *src++;
+ }
+- *dst++ = *src++;
+ }
+ /* strip trailing gubbins */
+ if (dst > host && dst[-1] == '.') {
+@@ -716,7 +916,7 @@
+ bad:
+ r->status = HTTP_BAD_REQUEST;
+ ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
+- "Client sent malformed Host header");
++ "Client sent malformed Host header <<%s>>",u);
+ return;
+ }
-@@ -221,7 +233,8 @@
- #define MAXHOSTNAMELEN 256
- #endif
- char str[MAXHOSTNAMELEN + 1];
-- struct hostent *hent;
-+ struct addrinfo hints, *res, *res0;
-+ int error;
- #ifndef NO_GETTIMEOFDAY
- struct timeval tv;
- #endif
-@@ -232,8 +245,8 @@
+@@ -819,11 +1019,25 @@
+ * names we'll match have ports associated with them
*/
- unique_id_rec_offset[0] = XtOffsetOf(unique_id_rec, stamp);
- unique_id_rec_size[0] = sizeof(cur_unique_id->stamp);
-- unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, in_addr);
-- unique_id_rec_size[1] = sizeof(cur_unique_id->in_addr);
-+ unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, addr);
-+ unique_id_rec_size[1] = sizeof(cur_unique_id->addr);
- unique_id_rec_offset[2] = XtOffsetOf(unique_id_rec, pid);
- unique_id_rec_size[2] = sizeof(cur_unique_id->pid);
- #ifdef MULTITHREAD
-@@ -269,17 +282,44 @@
- }
- str[sizeof(str) - 1] = '\0';
+ const char *host = r->hostname;
+- unsigned port = ntohs(r->connection->local_addr.sin_port);
++ unsigned port;
+ server_rec *s;
+ server_rec *last_s;
+ name_chain *src;
-- if ((hent = gethostbyname(str)) == NULL) {
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ error = getaddrinfo(str, NULL, &hints, &res0);
-+ if (error) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
-- "mod_unique_id: unable to gethostbyname(\"%s\")", str);
-+ "mod_unique_id: getaddrinfo failed for \"%s\" (%s)", str,
-+ gai_strerror(error));
- exit(1);
- }
++ switch (r->connection->local_addr.ss_family) {
++ case AF_INET:
++ port = ntohs(((struct sockaddr_in *)
++ &r->connection->local_addr)->sin_port);
++ break;
++#ifdef INET6
++ case AF_INET6:
++ port = ntohs(((struct sockaddr_in6 *)
++ &r->connection->local_addr)->sin6_port);
++ break;
++#endif
++ default:
++ port = 0; /*XXX*/
++ }
+ last_s = NULL;
-- global_in_addr = ((struct in_addr *) hent->h_addr_list[0])->s_addr;
-+ error = 1;
-+ for (res = res0; res; res = res->ai_next) {
-+ switch (res->ai_family) {
-+ case AF_INET:
+ /* Recall that the name_chain is a list of server_addr_recs, some of
+@@ -878,7 +1092,22 @@
+ server_rec *s;
+ server_rec *last_s;
+ name_chain *src;
+- unsigned port = ntohs(r->connection->local_addr.sin_port);
++ unsigned port;
++
++ switch (r->connection->local_addr.ss_family) {
++ case AF_INET:
++ port = ntohs(((struct sockaddr_in *)
++ &r->connection->local_addr)->sin_port);
++ break;
+#ifdef INET6
-+ case AF_INET6:
++ case AF_INET6:
++ port = ntohs(((struct sockaddr_in6 *)
++ &r->connection->local_addr)->sin6_port);
++ break;
+#endif
-+ memcpy(&global_addr, res->ai_addr, res->ai_addrlen);
-+ error = 0;
-+ break;
-+ }
-+ }
-+ freeaddrinfo(res0);
-+ if (error) {
-+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
-+ "mod_unique_id: no known AF found for \"%s\"", str);
-+ exit(1);
++ default:
++ port = 0; /*XXX*/
+ }
-+ getnameinfo((struct sockaddr *)&global_addr,
+ /*
+ * This is in conjunction with the ServerPath code in http_core, so we
+@@ -938,10 +1167,22 @@
+ API_EXPORT(void) ap_update_vhost_given_ip(conn_rec *conn)
+ {
+ ipaddr_chain *trav;
+- unsigned port = ntohs(conn->local_addr.sin_port);
++ char portbuf[NI_MAXSERV];
++ unsigned port;
++
++ if (getnameinfo((struct sockaddr *)&conn->local_addr,
+#ifndef SIN6_LEN
-+ SA_LEN((struct sockaddr *)&global_addr),
-+#else
-+ global_addr.ss_len,
++ SA_LEN((struct sockaddr *)&conn->local_addr),
++#else
++ conn->local_addr.ss_len,
+#endif
-+ str, sizeof(str), NULL, 0, NI_NUMERICHOST);
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, s,
-- "mod_unique_id: using ip addr %s",
-- inet_ntoa(*(struct in_addr *) hent->h_addr_list[0]));
-+ "mod_unique_id: using ip addr %s", str);
++ NULL, 0, portbuf, sizeof(portbuf), NI_NUMERICSERV) != 0) {
++ goto fail;
++ }
++ port = atoi(portbuf);
- /*
- * If the server is pummelled with restart requests we could possibly end
-@@ -336,7 +376,23 @@
- "oh no! pids are greater than 32-bits! I'm broken!");
+ /* scan the hash table for an exact match first */
+- trav = find_ipaddr(&conn->local_addr.sin_addr, port);
++ trav = find_ipaddr((struct sockaddr *)&conn->local_addr);
+ if (trav) {
+ /* save the name_chain for later in case this is a name-vhost */
+ conn->vhost_lookup_data = trav->names;
+@@ -959,6 +1200,7 @@
+ return;
}
-- cur_unique_id->in_addr = global_in_addr;
-+ memset(&cur_unique_id->addr, 0, sizeof(cur_unique_id->addr));
-+ switch (global_addr.ss_family) {
++fail:
+ /* otherwise we're stuck with just the main server
+ * and no name-based vhosts
+ */
+diff -Nur apache_1.3.28.orig/src/main/rfc1413.c apache_1.3.28/src/main/rfc1413.c
+--- apache_1.3.28.orig/src/main/rfc1413.c Mon Feb 3 18:13:23 2003
++++ apache_1.3.28/src/main/rfc1413.c Fri Jul 25 12:15:05 2003
+@@ -82,6 +82,7 @@
+ #include "http_log.h" /* for aplog_error */
+ #include "rfc1413.h"
+ #include "http_main.h" /* set_callback_and_alarm */
++#include "sa_len.h"
+
+ /* Local stuff. */
+ /* Semi-well-known port */
+@@ -109,12 +110,13 @@
+
+ /* bind_connect - bind both ends of a socket */
+ /* Ambarish fix this. Very broken */
+-static int get_rfc1413(int sock, const struct sockaddr_in *our_sin,
+- const struct sockaddr_in *rmt_sin,
++static int get_rfc1413(int sock, const struct sockaddr *our_sin,
++ const struct sockaddr *rmt_sin,
+ char user[RFC1413_USERLEN+1], server_rec *srv)
+ {
+- struct sockaddr_in rmt_query_sin, our_query_sin;
+- unsigned int rmt_port, our_port;
++ struct sockaddr_storage rmt_query_sin, our_query_sin;
++ unsigned int o_rmt_port, o_our_port; /* original port pair */
++ unsigned int rmt_port, our_port; /* replied port pair */
+ int i;
+ char *cp;
+ char buffer[RFC1413_MAXDATA + 1];
+@@ -129,16 +131,47 @@
+ * addresses from the query socket.
+ */
+
+- our_query_sin = *our_sin;
+- our_query_sin.sin_port = htons(ANY_PORT);
+-#ifdef MPE
+- our_query_sin.sin_addr.s_addr = INADDR_ANY;
++#ifndef SIN6_LEN
++ memcpy(&our_query_sin, our_sin, SA_LEN(our_sin));
++ memcpy(&rmt_query_sin, rmt_sin, SA_LEN(rmt_sin));
++#else
++ memcpy(&our_query_sin, our_sin, our_sin->sa_len);
++ memcpy(&rmt_query_sin, rmt_sin, rmt_sin->sa_len);
+ #endif
+- rmt_query_sin = *rmt_sin;
+- rmt_query_sin.sin_port = htons(RFC1413_PORT);
++ switch (our_sin->sa_family) {
+ case AF_INET:
-+ cur_unique_id->addr.in = ((struct sockaddr_in *)&global_addr)->sin_addr;
-+ break;
++#ifdef MPE
++ ((struct sockaddr_in *)&our_query_sin)->sin_addr.s_addr = INADDR_ANY; /* XXX: htonl(??) */
++#endif
++ ((struct sockaddr_in *)&our_query_sin)->sin_port = htons(ANY_PORT);
++ o_our_port = ntohs(((struct sockaddr_in *)our_sin)->sin_port);
++ ((struct sockaddr_in *)&rmt_query_sin)->sin_port = htons(RFC1413_PORT);
++ o_rmt_port = ntohs(((struct sockaddr_in *)rmt_sin)->sin_port);
++ break;
+#ifdef INET6
+ case AF_INET6:
-+#ifdef SHORT_UNIQUE_ID
-+ cur_unique_id->addr.in6 =
-+ ((struct sockaddr_in6 *)&global_addr)->sin6_addr.s6_addr32[3];
++#ifdef MPE
++ memcpy(&((struct sockaddr_in6 *)&our_query_sin)->sin6_addr,
++ &in6addr_any, sizeof(struct in6_addr));
++#endif
++ ((struct sockaddr_in6 *)&our_query_sin)->sin6_port = htons(ANY_PORT);
++ o_our_port = ntohs(((struct sockaddr_in6 *)our_sin)->sin6_port);
++ ((struct sockaddr_in6 *)&rmt_query_sin)->sin6_port = htons(RFC1413_PORT);
++ o_rmt_port = ntohs(((struct sockaddr_in6 *)rmt_sin)->sin6_port);
++ break;
++#endif
++ default:
++ /* unsupported AF */
++ return -1;
++ }
+
+ if (bind(sock, (struct sockaddr *) &our_query_sin,
+- sizeof(struct sockaddr_in)) < 0) {
++#ifndef SIN6_LEN
++ SA_LEN((struct sockaddr *) &our_query_sin)
+#else
-+ cur_unique_id->addr.in6 =
-+ ((struct sockaddr_in6 *)&global_addr)->sin6_addr;
++ our_query_sin.ss_len
+#endif
-+ break;
++ ) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
+ "bind: rfc1413: Error binding to local port");
+ return -1;
+@@ -149,12 +182,18 @@
+ * the service
+ */
+ if (connect(sock, (struct sockaddr *) &rmt_query_sin,
+- sizeof(struct sockaddr_in)) < 0)
+- return -1;
++#ifndef SIN6_LEN
++ SA_LEN((struct sockaddr *) &rmt_query_sin)
++#else
++ rmt_query_sin.ss_len
+#endif
++ ) < 0) {
++ return -1;
++ }
+
+ /* send the data */
+- buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", ntohs(rmt_sin->sin_port),
+- ntohs(our_sin->sin_port));
++ buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", o_rmt_port,
++ o_our_port);
+
+ /* send query to server. Handle short write. */
+ #ifdef CHARSET_EBCDIC
+@@ -219,9 +258,9 @@
+ ascii2ebcdic(buffer, buffer, (size_t)i);
+ #endif
+ if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port,
+- user) != 3 || ntohs(rmt_sin->sin_port) != rmt_port
+- || ntohs(our_sin->sin_port) != our_port)
++ user) != 3 || o_rmt_port != rmt_port || o_our_port != our_port) {
+ return -1;
++ }
+
+ /*
+ * Strip trailing carriage return. It is part of the
+@@ -243,7 +282,7 @@
+
+ result = FROM_UNKNOWN;
+
+- sock = ap_psocket_ex(conn->pool, AF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
++ sock = ap_psocket_ex(conn->pool, conn->remote_addr.ss_family, SOCK_STREAM, IPPROTO_TCP, 1);
+ if (sock < 0) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
+ "socket: rfc1413: error creating socket");
+@@ -256,8 +295,10 @@
+ if (ap_setjmp(timebuf) == 0) {
+ ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout);
+
+- if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user, srv) >= 0)
++ if (get_rfc1413(sock, (struct sockaddr *)&conn->local_addr,
++ (struct sockaddr *)&conn->remote_addr, user, srv) >= 0) {
+ result = user;
++ }
+ }
+ ap_set_callback_and_alarm(NULL, 0);
+ ap_pclosesocket(conn->pool, sock);
+diff -Nur apache_1.3.28.orig/src/main/util.c apache_1.3.28/src/main/util.c
+--- apache_1.3.28.orig/src/main/util.c Mon Feb 3 18:13:23 2003
++++ apache_1.3.28/src/main/util.c Fri Jul 25 11:01:55 2003
+@@ -2017,52 +2017,87 @@
+ * Parses a host of the form <address>[:port]
+ * :port is permitted if 'port' is not NULL
+ */
+-API_EXPORT(unsigned long) ap_get_virthost_addr(char *w, unsigned short *ports)
++API_EXPORT(struct sockaddr *) ap_get_virthost_addr(char *w, unsigned short *ports)
+ {
+- struct hostent *hep;
+- unsigned long my_addr;
+- char *p;
+-
+- p = strchr(w, ':');
++ static struct sockaddr_storage ss;
++ struct addrinfo hints, *res;
++ char *p, *r;
++ char *host;
++ char *port = "0";
++ int error;
++ char servbuf[NI_MAXSERV];
++
++ if (w == NULL)
++ w = "*";
++ p = r = NULL;
++ if (*w == '['){
++ if (r = strrchr(w+1, ']')){
++ *r = '\0';
++ p = r + 1;
++ switch(*p){
++ case ':':
++ p++;
++ /* nobreak; */
++ case '\0':
++ w++;
++ break;
++ default:
++ p = NULL;
++ }
++ }
+ }
++ else{
++ p = strchr(w, ':');
++ if (p != NULL && strchr(p+1, ':') != NULL)
++ p = NULL;
++ }
+ if (ports != NULL) {
+- *ports = 0;
+- if (p != NULL && strcmp(p + 1, "*") != 0)
+- *ports = atoi(p + 1);
++ if (p != NULL && *p && strcmp(p + 1, "*") != 0)
++ port = p + 1;
+ }
- /*
- * If we use 0 as the initial counter we have a little less protection
-diff -Nur apache_1.3.26.orig/src/support/ab.c apache_1.3.26/src/support/ab.c
---- apache_1.3.26.orig/src/support/ab.c Sat May 11 22:47:57 2002
-+++ apache_1.3.26/src/support/ab.c Wed Jun 19 11:08:58 2002
-@@ -158,6 +158,8 @@
- #include <sys/uio.h>
- #endif
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_socktype = SOCK_STREAM;
+ if (p != NULL)
+ *p = '\0';
+ if (strcmp(w, "*") == 0) {
+- if (p != NULL)
+- *p = ':';
+- return htonl(INADDR_ANY);
+- }
+-
+- my_addr = ap_inet_addr((char *)w);
+- if (my_addr != INADDR_NONE) {
+- if (p != NULL)
+- *p = ':';
+- return my_addr;
++ host = NULL;
++ hints.ai_flags = AI_PASSIVE;
++ hints.ai_family = ap_default_family;
++ } else {
++ host = w;
++ hints.ai_family = PF_UNSPEC;
+ }
-+#include "sa_len.h"
-+
- #endif /* NO_APACHE_INCLUDES */
+- hep = gethostbyname(w);
++ error = getaddrinfo(host, port, &hints, &res);
- #ifdef USE_SSL
-@@ -246,7 +248,7 @@
- char servername[1024]; /* name that server reports */
- char hostname[1024]; /* host name */
- char proxyhost[1024]; /* proxy host name */
--int proxyport = 0; /* proxy port */
-+char *proxyport = NULL; /* proxy port */
- int isproxy = 0;
- char path[1024]; /* path name */
- char postfile[1024]; /* name of file containing post data */
-@@ -262,7 +264,7 @@
- auth[1024], /* optional (basic/uuencoded)
- * authentification */
- hdrs[4096]; /* optional arbitrary headers */
--int port = 80; /* port number */
-+char *port = "80"; /* port number */
+- if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) {
+- fprintf(stderr, "Cannot resolve host name %s --- exiting!\n", w);
++ if (error || !res) {
++ fprintf(stderr, "ap_get_vitrhost_addr(): getaddrinfo(%s):%s --- exiting!\n", w, gai_strerror(error));
+ exit(1);
+ }
- int use_html = 0; /* use html in the report */
- char *tablestring;
-@@ -299,7 +301,7 @@
- struct data *stats; /* date for each request */
+- if (hep->h_addr_list[1]) {
+- fprintf(stderr, "Host %s has multiple addresses ---\n", w);
++ if (res->ai_next) {
++ fprintf(stderr, "ap_get_vitrhost_addr(): Host %s has multiple addresses ---\n", w);
+ fprintf(stderr, "you must choose one explicitly for use as\n");
+ fprintf(stderr, "a virtual host. Exiting!!!\n");
+ exit(1);
+ }
- fd_set readbits, writebits; /* bits for select */
--struct sockaddr_in server; /* server addr structure */
-+struct sockaddr_storage server; /* server addr structure */
++ if (r != NULL)
++ *r = ']';
+ if (p != NULL)
+ *p = ':';
- #ifndef BEOS
- #define ab_close(s) close(s)
-@@ -525,7 +527,7 @@
- printf("\r \r");
- printf("Server Software: %s\n", servername);
- printf("Server Hostname: %s\n", hostname);
-- printf("Server Port: %d\n", port);
-+ printf("Server Port: %s\n", port);
- printf("\n");
- printf("Document Path: %s\n", path);
- printf("Document Length: %d bytes\n", doclen);
-@@ -878,7 +880,7 @@
- c->cbx = 0;
- c->gotheader = 0;
+- return ((struct in_addr *) (hep->h_addr))->s_addr;
++ memcpy(&ss, res->ai_addr, res->ai_addrlen);
++ if (getnameinfo(res->ai_addr, res->ai_addrlen,
++ NULL, 0, servbuf, sizeof(servbuf),
++ NI_NUMERICSERV)){
++ fprintf(stderr, "ap_get_virthost_addr(): getnameinfo() failed --- Exiting!!!\n");
++ exit(1);
++ }
++ if (ports) *ports = atoi(servbuf);
++ freeaddrinfo(res);
++ return (struct sockaddr *)&ss;
+ }
-- c->fd = socket(AF_INET, SOCK_STREAM, 0);
-+ c->fd = socket(server.ss_family, SOCK_STREAM, 0);
- if (c->fd < 0) {
- what = "SOCKET";
- goto _bad;
-@@ -895,7 +897,12 @@
- again:
- gettimeofday(&c->start, 0);
-- if (connect(c->fd, (struct sockaddr *) & server, sizeof(server)) < 0) {
-+#ifndef SIN6_LEN
-+ if (connect(c->fd, (struct sockaddr *) & server, SA_LEN((struct sockaddr*)&server)) < 0)
-+#else
-+ if (connect(c->fd, (struct sockaddr *) & server, server.ss_len) < 0)
-+#endif
-+ {
- if (errno != EINPROGRESS) {
- what = "CONNECT";
- goto _bad;
-@@ -1182,7 +1189,7 @@
- struct timeval timeout, now;
- fd_set sel_read, sel_except, sel_write;
- long i;
-- int connectport;
-+ char * connectport;
- char * connecthost;
- char * url_on_request;
+@@ -2090,7 +2125,8 @@
+ #endif
+ char str[MAXHOSTNAMELEN];
+ char *server_hostname = NULL;
+- struct hostent *p;
++ struct addrinfo hints, *res;
++ int error;
-@@ -1225,17 +1232,21 @@
+ #ifdef BEOS /* BeOS returns zero as an error for gethostname */
+ if (gethostname(str, sizeof(str) - 1) == 0) {
+@@ -2103,29 +2139,38 @@
}
+ else
{
- /* get server information */
-- struct hostent *he;
-- he = gethostbyname(connecthost);
-- if (!he) {
-- char theerror[1024];
-- ap_snprintf(theerror, sizeof(theerror),
-- "Bad hostname: %s\n", connecthost);
-- err(theerror);
-- }
-- server.sin_family = he->h_addrtype;
-- server.sin_port = htons(connectport);
-- server.sin_addr.s_addr = ((unsigned long *) (he->h_addr_list[0]))[0];
-+ struct addrinfo hints, *res;
-+ int error;
+- str[sizeof(str) - 1] = '\0';
+- if ((!(p = gethostbyname(str)))
+- || (!(server_hostname = find_fqdn(a, p)))) {
+- /* Recovery - return the default servername by IP: */
+- if (p && p->h_addr_list && p->h_addr_list[0]) {
+- ap_snprintf(str, sizeof(str), "%pA", p->h_addr_list[0]);
+- server_hostname = ap_pstrdup(a, str);
+- /* We will drop through to report the IP-named server */
+- }
+- }
+- else
+- /* Since we found a fqdn, return it with no logged message. */
+- return server_hostname;
+- }
+-
+- /* If we don't have an fdqn or IP, fall back to the loopback addr */
+- if (!server_hostname)
+- server_hostname = ap_pstrdup(a, "127.0.0.1");
+-
+- ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
+- "%s: Could not determine the server's fully qualified "
+- "domain name, using %s for ServerName",
+- ap_server_argv0, server_hostname);
++ str[sizeof(str) - 1] = '\0';
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_flags = AI_CANONNAME;
++ error = getaddrinfo(str, NULL, &hints, &res);
++ if (error)
++ {
++ /* Recovery - return the default servername by IP: */
+
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ error = getaddrinfo(connecthost, connectport, &hints, &res);
-+ if (error) {
-+ char *theerror=malloc(strlen(connecthost)+16);
-+ sprintf(theerror, "Bad hostname: %s\n", connecthost);
-+ err(theerror);
-+ free(theerror);
-+ }
-+ memcpy(&server, res->ai_addr, res->ai_addrlen);
-+ freeaddrinfo(res);
- }
-
- con = malloc(concurrency * sizeof(struct connection));
-@@ -1423,7 +1434,7 @@
- if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
- purl += 8;
- ssl = 1;
-- port = 443;
-+ port = "443";
- }
- #else
- if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
-@@ -1444,15 +1455,15 @@
- *cp = '\0';
- strcpy(hostname, h);
- if (p != NULL)
-- port = atoi(p);
-+ port = strdup(p);
-
- if ((
- #ifdef USE_SSL
-- (ssl != 0) && (port != 443)) || ((ssl == 0) &&
-+ (ssl != 0) && (strcmp(port, "443"))) || ((ssl == 0) &&
- #endif
-- (port != 80)))
-+ (strcmp(port, "80"))))
- {
-- ap_snprintf(colonport,sizeof(colonport),":%d",port);
-+ ap_snprintf(colonport,sizeof(colonport),":%s",port);
- } else {
- colonport[0] = '\0';
- }
-@@ -1615,7 +1626,7 @@
- if ((p = strchr(optarg, ':'))) {
- *p = '\0';
- p++;
-- proxyport = atoi(p);
-+ proxyport = strdup(p);
- };
- strcpy(proxyhost, optarg);
- isproxy = 1;
-@@ -1698,3 +1709,7 @@
-
- exit(0);
++ fprintf(stderr, "%s: cannot determine local host name.\n",
++ ap_server_argv0);
++ fprintf(stderr, "Use the ServerName directive to set it manually.\n");
++ exit(1);
++
++ server_hostname = ap_pstrdup(a, res->ai_canonname);
++ }
++ else if (1) /*fqdn found*/
++ {
++ /* XXX should check more conditions */
++ server_hostname = ap_pstrdup(a, res->ai_canonname);
++ }
++ else
++ {
++ ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_NOERRNO, NULL,
++ "%s: Could not determine the server's fully qualified "
++ "domain name, using %s for ServerName",
++ ap_server_argv0, server_hostname);
++ }
++
++ /* Since we found a fdqn, return it with no logged message. */
++ freeaddrinfo(res);
++ }
+
+ return server_hostname;
+ }
+@@ -2369,3 +2414,11 @@
+ }
+ *dest = 0;
}
+
+#ifdef NEED_GETADDRINFO
-+#include "../main/getaddrinfo.c"
-+#endif
-diff -Nur apache_1.3.26.orig/src/support/logresolve.c apache_1.3.26/src/support/logresolve.c
---- apache_1.3.26.orig/src/support/logresolve.c Wed May 23 00:52:21 2001
-+++ apache_1.3.26/src/support/logresolve.c Wed Jun 19 10:26:32 2002
-@@ -54,7 +54,9 @@
- #endif /* BEOS */
- #endif /* !MPE && !WIN32*/
-
--static void cgethost(struct in_addr ipnum, char *string, int check);
-+#include "sa_len.h"
-+
-+static void cgethost(struct sockaddr *sa, char *string, int check);
- static int getline(char *s, int n);
- static void stats(FILE *output);
-
-@@ -91,7 +93,7 @@
- */
-
- struct nsrec {
-- struct in_addr ipnum;
-+ struct sockaddr_storage addr;
- char *hostname;
- int noname;
- struct nsrec *next;
-@@ -122,17 +124,48 @@
- * IP numbers with their IP number as hostname, setting noname flag
- */
-
--static void cgethost (struct in_addr ipnum, char *string, int check)
-+static void cgethost (struct sockaddr *sa, char *string, int check)
- {
-+ ap_uint32_t hashval;
-+ struct sockaddr_in *sin;
-+#ifdef INET6
-+ struct sockaddr_in6 *sin6;
-+#endif
- struct nsrec **current, *new;
-- struct hostent *hostdata;
- char *name;
-+ char hostnamebuf[MAXHOSTNAMELEN];
-+
-+ switch (sa->sa_family) {
-+ case AF_INET:
-+ hashval = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
-+ break;
-+#ifdef INET6
-+ case AF_INET6:
-+ hashval = *(ap_uint32_t *)&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12];
-+ break;
++#include "getaddrinfo.c"
+#endif
-+ default:
-+ hashval = 0;
-+ break;
-+ }
+
-+ current = &nscache[((hashval + (hashval >> 8) +
-+ (hashval >> 16) + (hashval >> 24)) % BUCKETS)];
-
-- current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) +
-- (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)];
-+ while (*current) {
-+#ifndef SIN6_LEN
-+ if (SA_LEN(sa) == SA_LEN((struct sockaddr *)&(*current)->addr)
-+ && memcmp(sa, &(*current)->addr, SA_LEN(sa)) == 0)
-+#else
-+ if (sa->sa_len == (*current)->addr.ss_len
-+ && memcmp(sa, &(*current)->addr, sa->sa_len) == 0)
++#ifdef NEED_GETNAMEINFO
++#include "getnameinfo.c"
+#endif
-+ {
-+ break;
-+ }
-
-- while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr)
- current = &(*current)->next;
-+ }
+diff -Nur apache_1.3.28.orig/src/main/util_script.c apache_1.3.28/src/main/util_script.c
+--- apache_1.3.28.orig/src/main/util_script.c Mon Feb 3 18:13:23 2003
++++ apache_1.3.28/src/main/util_script.c Fri Jul 25 11:01:55 2003
+@@ -67,6 +67,7 @@
+ #include "http_request.h" /* for sub_req_lookup_uri() */
+ #include "util_script.h"
+ #include "util_date.h" /* For parseHTTPdate() */
++#include "sa_len.h"
- if (*current == NULL) {
- cachesize++;
-@@ -145,45 +178,55 @@
- *current = new;
- new->next = NULL;
+ #ifdef OS2
+ #define INCL_DOS
+@@ -203,6 +204,7 @@
+ array_header *hdrs_arr = ap_table_elts(r->headers_in);
+ table_entry *hdrs = (table_entry *) hdrs_arr->elts;
+ int i;
++ char servbuf[NI_MAXSERV];
-- new->ipnum = ipnum;
-+#ifndef SIN6_LEN
-+ memcpy(&new->addr, sa, SA_LEN(sa));
-+#else
-+ memcpy(&new->addr, sa, sa->sa_len);
-+#endif
+ /* use a temporary table which we'll overlap onto
+ * r->subprocess_env later
+@@ -294,8 +296,16 @@
+ ap_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
+ ap_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */
-- hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr),
-- AF_INET);
-- if (hostdata == NULL) {
-- if (h_errno > MAX_ERR)
-- errors[UNKNOWN_ERR]++;
-- else
-- errors[h_errno]++;
-- new->noname = h_errno;
-- name = strdup(inet_ntoa(ipnum));
-- }
-- else {
-- new->noname = 0;
-- name = strdup(hostdata->h_name);
-- if (check) {
-- if (name == NULL) {
-- perror("strdup");
-- fprintf(stderr, "Insufficient memory\n");
-- exit(1);
-- }
-- hostdata = gethostbyname(name);
-- if (hostdata != NULL) {
-- char **hptr;
--
-- for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++)
-- if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr)
-- break;
-- if (*hptr == NULL)
-- hostdata = NULL;
-- }
-- if (hostdata == NULL) {
-- fprintf(stderr, "Bad host: %s != %s\n", name,
-- inet_ntoa(ipnum));
-- new->noname = NO_REVERSE;
-- free(name);
-- name = strdup(inet_ntoa(ipnum));
-- errors[NO_REVERSE]++;
-+ new->noname = getnameinfo(sa,
-+#ifndef SIN6_LEN
-+ SA_LEN(sa),
-+#else
-+ sa->sa_len,
-+#endif
-+ hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0);
-+ name = strdup(hostnamebuf);
-+ if (check) {
-+ struct addrinfo hints, *res;
-+ int error;
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ error = getaddrinfo(hostnamebuf, NULL, &hints, &res);
-+ if (!error) {
-+ while (res) {
-+#ifndef SIN6_LEN
-+ if (SA_LEN(sa) == res->ai_addrlen
-+ && memcmp(sa, res->ai_addr, SA_LEN(sa)) == 0)
-+#else
-+ if (sa->sa_len == res->ai_addrlen
-+ && memcmp(sa, res->ai_addr, sa->sa_len) == 0)
-+#endif
-+ {
-+ break;
-+ }
-+ res = res->ai_next;
- }
-+ if (!res)
-+ error++;
-+ }
-+ if (error) {
-+ getnameinfo(sa,
-+#ifndef SIN6_LEN
-+ SA_LEN(sa),
+- ap_table_addn(e, "REMOTE_PORT",
+- ap_psprintf(r->pool, "%d", ntohs(c->remote_addr.sin_port)));
++ servbuf[0] = '\0';
++ if (!getnameinfo((struct sockaddr *)&c->remote_addr,
++#ifndef HAVE_SOCKADDR_LEN
++ SA_LEN((struct sockaddr *)&c->remote_addr),
+#else
-+ sa->sa_len,
++ c->remote_addr.ss_len,
+#endif
-+ hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
-+ fprintf(stderr, "Bad host: %s != %s\n", name, hostnamebuf);
-+ new->noname = NO_REVERSE;
-+ free(name);
-+ name = strdup(hostnamebuf);
- }
- }
- new->hostname = name;
-@@ -211,6 +254,7 @@
- char *ipstring;
- struct nsrec *current;
- char *errstring[MAX_ERR + 3];
-+ char hostnamebuf[MAXHOSTNAMELEN];
-
- for (i = 0; i < MAX_ERR + 3; i++)
- errstring[i] = "Unknown error";
-@@ -242,7 +286,14 @@
++ NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)){
++ ap_table_addn(e, "REMOTE_PORT", ap_pstrdup(r->pool, servbuf));
++ }
- for (i = 0; i < BUCKETS; i++)
- for (current = nscache[i]; current != NULL; current = current->next) {
-- ipstring = inet_ntoa(current->ipnum);
-+ getnameinfo((struct sockaddr *)¤t->addr,
-+#ifndef SIN6_LEN
-+ SA_LEN((struct sockaddr *)¤t->addr),
-+#else
-+ current->addr.ss_len,
-+#endif
-+ hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
-+ ipstring = hostnamebuf;
- if (current->noname == 0)
- fprintf(output, " %3d %15s - %s\n", i, ipstring,
- current->hostname);
-@@ -276,9 +327,10 @@
+ if (c->user) {
+ ap_table_addn(e, "REMOTE_USER", c->user);
+diff -Nur apache_1.3.28.orig/src/main/util_uri.c apache_1.3.28/src/main/util_uri.c
+--- apache_1.3.28.orig/src/main/util_uri.c Mon Feb 3 18:13:24 2003
++++ apache_1.3.28/src/main/util_uri.c Fri Jul 25 11:01:55 2003
+@@ -424,6 +424,12 @@
+ * the hostname. If there's a port it is the first colon.
+ */
+ s = memchr(hostinfo, ':', uri - hostinfo);
++ if (*hostinfo == '[') {
++ s = memchr(hostinfo+1, ']', uri - hostinfo - 1);
++ if (s)
++ s = strchr(s, ':');
++ } else
++ s = memchr(hostinfo, ':', uri - hostinfo);
+ if (s == NULL) {
+ /* we expect the common case to have no port */
+ uptr->hostname = ap_pstrndup(p, hostinfo, uri - hostinfo);
+@@ -480,7 +486,12 @@
+ /* We expect hostinfo to point to the first character of
+ * the hostname. There must be a port, separated by a colon
+ */
+- s = strchr(hostinfo, ':');
++ if (*hostinfo == '[') {
++ s = strchr(hostinfo+1, ']');
++ if (s)
++ s = strchr(s, ':');
++ } else
++ s = strchr(hostinfo, ':');
+ if (s == NULL) {
+ return HTTP_BAD_REQUEST;
+ }
+diff -Nur apache_1.3.28.orig/src/modules/proxy/mod_proxy.c apache_1.3.28/src/modules/proxy/mod_proxy.c
+--- apache_1.3.28.orig/src/modules/proxy/mod_proxy.c Fri Jul 25 11:00:49 2003
++++ apache_1.3.28/src/modules/proxy/mod_proxy.c Fri Jul 25 11:01:55 2003
+@@ -574,11 +574,31 @@
+ struct proxy_remote *new;
+ char *p, *q;
+ int port;
++ char *bl = NULL, *br = NULL;
- int main (int argc, char *argv[])
+ p = strchr(r, ':');
+ if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0')
+ return "ProxyRemote: Bad syntax for a remote proxy server";
+- q = strchr(p + 3, ':');
++ bl = p + 3;
++ if (*bl == '['){
++ br = strrchr(bl+1, ']');
++ if (br){
++ bl++;
++ *br = '\0';
++ if (*(br+1) == ':'){ /* [host]:xx */
++ q = br+1;
++ }
++ else if (*(br+1) == '\0'){ /* [host] */
++ q = NULL;
++ }
++ else
++ q = strrchr(br, ':'); /* XXX */
++ }
++ else
++ q = strrchr(bl, ':'); /* XXX */
++ }
++ else
++ q = strrchr(bl, ':');
+ if (q != NULL) {
+ if (sscanf(q + 1, "%u", &port) != 1 || port > 65535)
+ return "ProxyRemote: Bad syntax for a remote proxy server (bad port number)";
+@@ -589,7 +609,7 @@
+ *p = '\0';
+ if (strchr(f, ':') == NULL)
+ ap_str_tolower(f); /* lowercase scheme */
+- ap_str_tolower(p + 3); /* lowercase hostname */
++ ap_str_tolower(bl); /* lowercase hostname */
+
+ if (port == -1) {
+ int i;
+@@ -602,7 +622,7 @@
+ new = ap_push_array(conf->proxies);
+ new->scheme = f;
+ new->protocol = r;
+- new->hostname = p + 3;
++ new->hostname = bl;
+ new->port = port;
+ return NULL;
+ }
+diff -Nur apache_1.3.28.orig/src/modules/proxy/mod_proxy.h apache_1.3.28/src/modules/proxy/mod_proxy.h
+--- apache_1.3.28.orig/src/modules/proxy/mod_proxy.h Mon Feb 3 18:13:26 2003
++++ apache_1.3.28/src/modules/proxy/mod_proxy.h Fri Jul 25 11:01:55 2003
+@@ -310,7 +310,7 @@
+ int ap_proxy_is_domainname(struct dirconn_entry *This, pool *p);
+ int ap_proxy_is_hostname(struct dirconn_entry *This, pool *p);
+ int ap_proxy_is_word(struct dirconn_entry *This, pool *p);
+-int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r);
++int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r);
+ int ap_proxy_garbage_init(server_rec *, pool *);
+ /* This function is called by ap_table_do() for all header lines */
+ int ap_proxy_send_hdr_line(void *p, const char *key, const char *value);
+diff -Nur apache_1.3.28.orig/src/modules/proxy/proxy_connect.c apache_1.3.28/src/modules/proxy/proxy_connect.c
+--- apache_1.3.28.orig/src/modules/proxy/proxy_connect.c Mon Feb 3 18:13:26 2003
++++ apache_1.3.28/src/modules/proxy/proxy_connect.c Fri Jul 25 11:27:12 2003
+@@ -113,14 +113,15 @@
+ const char *proxyhost, int proxyport)
{
-- struct in_addr ipnum;
- char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
- int i, check;
-+ struct addrinfo hints, *res;
+ struct sockaddr_in server;
+- struct in_addr destaddr;
+- struct hostent server_hp;
+- const char *host, *err;
++ struct addrinfo hints, *res, *res0;
++ const char *hoststr;
++ const char *portstr = NULL;
+ char *p;
+ int port, sock;
+ char buffer[HUGE_STRING_LEN];
+- int nbytes, i, j;
++ int nbytes, i;
+ fd_set fds;
+ int error;
- #ifdef WIN32
- WSADATA wsaData;
-@@ -322,8 +374,10 @@
- bar = strchr(line, ' ');
- if (bar != NULL)
- *bar = '\0';
-- ipnum.s_addr = inet_addr(line);
-- if (ipnum.s_addr == 0xffffffffu) {
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ error = getaddrinfo(line, NULL, &hints, &res);
-+ if (error) {
- if (bar != NULL)
- *bar = ' ';
- puts(line);
-@@ -333,11 +387,12 @@
+ void *sconf = r->server->module_config;
+ proxy_server_conf *conf =
+@@ -128,27 +129,59 @@
+ struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
- resolves++;
+ memset(&server, '\0', sizeof(server));
++#ifdef HAVE_SOCKADDR_LEN
++ server.sin_len = sizeof(server);
++#endif
+ server.sin_family = AF_INET;
-- cgethost(ipnum, hoststring, check);
-+ cgethost(res->ai_addr, hoststring, check);
- if (bar != NULL)
- printf("%s %s\n", hoststring, bar + 1);
- else
- puts(hoststring);
-+ freeaddrinfo(res);
+ /* Break the URL into host:port pairs */
+
+- host = url;
++ hoststr = url;
+ p = strchr(url, ':');
+- if (p == NULL)
+- port = DEFAULT_HTTPS_PORT;
+- else {
+- port = atoi(p + 1);
++ if (p == NULL) {
++ char pbuf[32];
++ ap_snprintf(pbuf, sizeof(pbuf), "%d", DEFAULT_HTTPS_PORT);
++ portstr = pbuf;
++ } else {
++ portstr = p + 1;
+ *p = '\0';
}
++ port = atoi(portstr);
++
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_socktype = SOCK_STREAM;
++ hints.ai_protocol = IPPROTO_TCP;
++ error = getaddrinfo(hoststr, portstr, &hints, &res0);
++ if (error) {
++ return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
++ gai_strerror(error)); /* give up */
++ }
- #ifdef WIN32
-@@ -358,3 +413,11 @@
+ /* check if ProxyBlock directive on this host */
+- destaddr.s_addr = ap_inet_addr(host);
+- for (i = 0; i < conf->noproxies->nelts; i++) {
+- if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL)
+- || destaddr.s_addr == npent[i].addr.s_addr
+- || npent[i].name[0] == '*')
++ for (res = res0; res; res = res = res->ai_next) {
++ struct sockaddr_in *sin;
++ int fail;
++
++ fail = 0;
++ for (i = 0; i < conf->noproxies->nelts; i++) {
++ if (npent[i].name != NULL && strstr(hoststr, npent[i].name))
++ fail++;
++ if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
++ fail++;
++ switch (res->ai_family) {
++ case AF_INET:
++ sin = (struct sockaddr_in *)res->ai_addr;
++ if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
++ fail++;
++ break;
++ }
++ }
++ if (fail) {
++ freeaddrinfo(res0);
+ return ap_proxyerror(r, HTTP_FORBIDDEN,
+ "Connect to remote machine blocked");
++ }
+ }
- return (0);
- }
+ /* Check if it is an allowed port */
+@@ -159,34 +192,42 @@
+ case DEFAULT_SNEWS_PORT:
+ break;
+ default:
++ freeaddrinfo(res0);
+ return HTTP_FORBIDDEN;
+ }
+ }
+- else if (!allowed_port(conf, port))
++ else if (!allowed_port(conf, port)) {
++ freeaddrinfo(res0);
+ return HTTP_FORBIDDEN;
++ }
+
+ if (proxyhost) {
++ char pbuf[10];
+
-+#ifdef NEED_GETADDRINFO
-+#include "../main/getaddrinfo.c"
-+#endif
++ freeaddrinfo(res0);
+
-+#ifdef NEED_GETNAMEINFO
-+#include "../main/getnameinfo.c"
-+#endif
---- apache_1.3.28/src/main/http_main.c.orig 2003-07-19 12:04:20.000000000 +0200
-+++ apache_1.3.28/src/main/http_main.c 2003-07-19 12:09:47.000000000 +0200
-@@ -124,6 +124,8 @@
- #include <bstring.h> /* for IRIX, FD_SET calls bzero() */
- #endif
-
-+#include "sa_len.h"
++ ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_socktype = SOCK_STREAM;
++ hints.ai_protocol = IPPROTO_TCP;
++ error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
++ if (error)
++ return HTTP_INTERNAL_SERVER_ERROR; /* XXX */
+
- #ifdef MULTITHREAD
- /* special debug stuff -- PCS */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
+ "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
+- "CONNECT to %s on port %d", host, port);
++ "CONNECT to %s on port %d", hoststr, port);
+ }
-@@ -249,7 +251,12 @@
- API_VAR_EXPORT char *ap_scoreboard_fname=NULL;
- API_VAR_EXPORT char *ap_lock_fname=NULL;
- API_VAR_EXPORT char *ap_server_argv0=NULL;
--API_VAR_EXPORT struct in_addr ap_bind_address={0};
-+#ifdef INET6
-+API_VAR_EXPORT int ap_default_family = PF_INET6;
-+#else
-+API_VAR_EXPORT int ap_default_family = PF_INET;
-+#endif
-+API_VAR_EXPORT struct sockaddr_storage ap_bind_address={0};
- API_VAR_EXPORT int ap_daemons_to_start=0;
- API_VAR_EXPORT int ap_daemons_min_free=0;
- API_VAR_EXPORT int ap_daemons_max_free=0;
-@@ -1448,7 +1455,11 @@
- fprintf(stderr, "Usage: %s [-D name] [-d directory] [-f file]\n", bin);
- #endif
- fprintf(stderr, " %s [-C \"directive\"] [-c \"directive\"]\n", pad);
-- fprintf(stderr, " %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T] [-F]\n", pad);
-+ fprintf(stderr, " %s [-v] [-V] [-h] [-l] [-L] [-S] [-t] [-T] [-F]"
-+#ifdef INET6
-+ " [-46]"
-+#endif
-+ "\n", pad);
- fprintf(stderr, "Options:\n");
- #ifdef SHARED_CORE
- fprintf(stderr, " -R directory : specify an alternate location for shared object files\n");
-@@ -1474,6 +1485,10 @@
- #ifndef WIN32
- fprintf(stderr, " -F : run main process in foreground, for process supervisors\n");
+- /* Nasty cast to work around broken terniary expressions on MSVC */
+- server.sin_port = htons((unsigned short)(proxyport ? proxyport : port));
+- err = ap_proxy_host2addr(proxyhost ? proxyhost : host, &server_hp);
+-
+- if (err != NULL)
+- return ap_proxyerror(r,
+- proxyhost ? HTTP_BAD_GATEWAY : HTTP_INTERNAL_SERVER_ERROR, err);
+-
+- sock = ap_psocket_ex(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
+- if (sock == -1) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "proxy: error creating socket");
+- return HTTP_INTERNAL_SERVER_ERROR;
+- }
++ sock = i = -1;
++ for (res = res0; res; res = res->ai_next) {
++ sock = ap_psocket_ex(r->pool, res->ai_family, res->ai_socktype, res->ai_protocol, 1);
++ if (sock == -1)
++ continue;
+
+ #ifdef CHECK_FD_SETSIZE
+ if (sock >= FD_SETSIZE) {
+@@ -196,19 +237,15 @@
+ "found, you probably need to rebuild Apache with a "
+ "larger FD_SETSIZE", sock, FD_SETSIZE);
+ ap_pclosesocket(r->pool, sock);
+- return HTTP_INTERNAL_SERVER_ERROR;
++ continue;
+ }
#endif
-+#ifdef INET6
-+ fprintf(stderr, " -4 : assume IPv4 on parsing configuration file\n");
-+ fprintf(stderr, " -6 : assume IPv6 on parsing configuration file\n");
-+#endif
- #ifdef WIN32
- fprintf(stderr, " -n name : name the Apache service for -k options below;\n");
- fprintf(stderr, " -k stop|shutdown : tell running Apache to shutdown\n");
-@@ -3630,11 +3645,13 @@
+- j = 0;
+- while (server_hp.h_addr_list[j] != NULL) {
+- memcpy(&server.sin_addr, server_hp.h_addr_list[j],
+- sizeof(struct in_addr));
+- i = ap_proxy_doconnect(sock, &server, r);
++ i = ap_proxy_doconnect(sock, res->ai_addr, r);
+ if (i == 0)
+ break;
+- j++;
+ }
++ freeaddrinfo(res0);
+ if (i == -1) {
+ ap_pclosesocket(r->pool, sock);
+ return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, ap_pstrcat(r->pool,
+diff -Nur apache_1.3.28.orig/src/modules/proxy/proxy_ftp.c apache_1.3.28/src/modules/proxy/proxy_ftp.c
+--- apache_1.3.28.orig/src/modules/proxy/proxy_ftp.c Mon Feb 3 18:13:26 2003
++++ apache_1.3.28/src/modules/proxy/proxy_ftp.c Fri Jul 25 11:18:38 2003
+@@ -62,6 +62,7 @@
+ #include "http_main.h"
+ #include "http_log.h"
+ #include "http_core.h"
++#include "sa_len.h"
- static conn_rec *new_connection(pool *p, server_rec *server, BUFF *inout,
-- const struct sockaddr_in *remaddr,
-- const struct sockaddr_in *saddr,
-+ const struct sockaddr *remaddr,
-+ const struct sockaddr *saddr,
- int child_num)
- {
- conn_rec *conn = (conn_rec *) ap_pcalloc(p, sizeof(conn_rec));
-+ char hostnamebuf[MAXHOSTNAMELEN];
-+ size_t addr_len;
+ #define AUTODETECT_PWD
- /* Got a connection structure, so initialize what fields we can
- * (the rest are zeroed out by pcalloc).
-@@ -3643,17 +3660,29 @@
- conn->child_num = child_num;
+@@ -555,8 +556,10 @@
+ const char *err;
+ int port, i, j, len, rc, nocache = 0;
+ int csd = 0, sock = -1, dsock = -1;
+- struct sockaddr_in server;
+- struct hostent server_hp;
++ struct sockaddr_storage server;
++ struct addrinfo hints, *res, *res0;
++ char portbuf[10];
++ int error;
+ struct in_addr destaddr;
+ table *resp_hdrs;
+ BUFF *ctrl = NULL;
+@@ -577,11 +580,18 @@
+ unsigned int presult, h0, h1, h2, h3, p0, p1;
+ unsigned int paddr;
+ unsigned short pport;
+- struct sockaddr_in data_addr;
++ struct sockaddr_storage data_addr;
++ struct sockaddr_in *sin;
+ int pasvmode = 0;
+ char pasv[64];
+ char *pstr;
- conn->pool = p;
-- conn->local_addr = *saddr;
-- conn->local_ip = ap_pstrdup(conn->pool,
-- inet_ntoa(conn->local_addr.sin_addr));
-+#ifndef SIN6_LEN
-+ addr_len = SA_LEN(saddr);
-+#else
-+ addr_len = saddr->sa_len;
-+#endif
-+ memcpy(&conn->local_addr, saddr, addr_len);
-+ getnameinfo((struct sockaddr *)&conn->local_addr, addr_len,
-+ hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
-+ conn->local_ip = ap_pstrdup(conn->pool, hostnamebuf);
- conn->server = server; /* just a guess for now */
- ap_update_vhost_given_ip(conn);
- conn->base_server = conn->server;
- conn->client = inout;
++/* stuff for LPSV/EPSV */
++ unsigned int paf, holen, ho[16], polen, po[2];
++ struct sockaddr_in6 *sin6;
++ int lpsvmode = 0;
++ char *cmd;
++
+ /* stuff for responses */
+ char resp[MAX_STRING_LEN];
+ char *size = NULL;
+@@ -658,62 +668,50 @@
+ if (parms != NULL)
+ *(parms++) = '\0';
-- conn->remote_addr = *remaddr;
-- conn->remote_ip = ap_pstrdup(conn->pool,
-- inet_ntoa(conn->remote_addr.sin_addr));
-+#ifndef SIN6_LEN
-+ addr_len = SA_LEN(remaddr);
-+#else
-+ addr_len = remaddr->sa_len;
-+#endif
-+ memcpy(&conn->remote_addr, remaddr, addr_len);
-+ getnameinfo((struct sockaddr *)&conn->remote_addr, addr_len,
-+ hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
-+ conn->remote_ip = ap_pstrdup(conn->pool, hostnamebuf);
- #ifdef EAPI
- conn->ctx = ap_ctx_new(conn->pool);
- #endif /* EAPI */
-@@ -3711,21 +3740,47 @@
- #define sock_disable_nagle(s, c) /* NOOP */
+- memset(&server, 0, sizeof(struct sockaddr_in));
+- server.sin_family = AF_INET;
+- server.sin_port = htons((unsigned short)destport);
+- err = ap_proxy_host2addr(desthost, &server_hp);
+- if (err != NULL)
+- return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
+-
+- sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
+- if (sock == -1) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+- "proxy: error creating socket");
+- return HTTP_INTERNAL_SERVER_ERROR;
++ ap_snprintf(portbuf, sizeof(portbuf), "%d", destport);
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_socktype = SOCK_STREAM;
++ error = getaddrinfo(desthost, portbuf, &hints, &res0);
++ if (error) {
++ return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, gai_strerror(error));
+ }
+
++ i = -1;
++ for (res = res0; res; res = res->ai_next) {
++ sock = ap_psocket_ex(p, res->ai_family, res->ai_socktype,
++ res->ai_protocol, 1);
++ if (sock == -1)
++ continue;
++
+ #if !defined(TPF) && !defined(BEOS)
+- if (conf->recv_buffer_size > 0
+- && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+- (const char *)&conf->recv_buffer_size, sizeof(int))
+- == -1) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+- "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
+- }
++ if (conf->recv_buffer_size > 0
++ && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
++ (const char *)&conf->recv_buffer_size, sizeof(int))
++ == -1) {
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
++ "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
++ }
#endif
--static int make_sock(pool *p, const struct sockaddr_in *server)
-+static int make_sock(pool *p, const struct sockaddr *server)
- {
- int s;
- int one = 1;
-- char addr[512];
-+ char addr[INET6_ADDRSTRLEN + 128];
-+ char a0[INET6_ADDRSTRLEN];
-+ char p0[NI_MAXSERV];
-+#ifdef MPE
-+ int privport = 0;
-+#endif
+- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
+- sizeof(one)) == -1) {
++ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
++ sizeof(one)) == -1) {
+ #ifndef _OSD_POSIX /* BS2000 has this option "always on" */
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+- "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
+- ap_pclosesocket(p, sock);
+- return HTTP_INTERNAL_SERVER_ERROR;
++ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
++ "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
++ ap_pclosesocket(p, sock);
++ freeaddrinfo(res0);
++ return HTTP_INTERNAL_SERVER_ERROR;
+ #endif /* _OSD_POSIX */
+- }
+-
+-#ifdef SINIX_D_RESOLVER_BUG
+- {
+- struct in_addr *ip_addr = (struct in_addr *)*server_hp.h_addr_list;
+-
+- for (; ip_addr->s_addr != 0; ++ip_addr) {
+- memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
+- i = ap_proxy_doconnect(sock, &server, r);
+- if (i == 0)
+- break;
+ }
+- }
+-#else
+- j = 0;
+- while (server_hp.h_addr_list[j] != NULL) {
+- memcpy(&server.sin_addr, server_hp.h_addr_list[j],
+- sizeof(struct in_addr));
+- i = ap_proxy_doconnect(sock, &server, r);
+- if (i == 0)
++ i = ap_proxy_doconnect(sock, res->ai_addr, r);
++ if (i == 0) {
++ memcpy(&server, res->ai_addr, res->ai_addrlen);
+ break;
+- j++;
++ }
++ ap_pclosesocket(p, sock);
+ }
+-#endif
++ freeaddrinfo(res0);
+ if (i == -1) {
+ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
+ ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool,
+@@ -944,7 +942,7 @@
+ }
-- if (server->sin_addr.s_addr != htonl(INADDR_ANY))
-- ap_snprintf(addr, sizeof(addr), "address %s port %d",
-- inet_ntoa(server->sin_addr), ntohs(server->sin_port));
-- else
-- ap_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port));
-+ switch(server->sa_family){
-+ case AF_INET:
-+#ifdef INET6
-+ case AF_INET6:
+ /* try to set up PASV data connection first */
+- dsock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
++ dsock = ap_psocket_ex(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP, 1);
+ if (dsock == -1) {
+ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
+ ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
+@@ -961,11 +959,22 @@
+ }
+ #endif
+
+- ap_bputs("PASV" CRLF, ctrl);
++lpsvagain:
++ if (server.ss_family == AF_INET)
++ cmd = "PASV";
++ else if (lpsvmode)
++ cmd = "LPSV";
++ else
++ cmd = "EPSV";
++ ap_bputs(cmd, ctrl);
++ ap_bputs(CRLF, ctrl);
+ ap_bflush(ctrl);
++ Explain0("FTP: passive command issued");
+ ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: PASV command issued");
+-/* possible results: 227, 421, 500, 501, 502, 530 */
++/* possible results: 227, 228, 229, 421, 500, 501, 502, 530 */
+ /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */
++ /* 228 Entering Long Passive Mode (...). */
++ /* 229 Entering Extended Passive Mode (...). */
+ /* 421 Service not available, closing control connection. */
+ /* 500 Syntax error, command unrecognized. */
+ /* 501 Syntax error in parameters or arguments. */
+@@ -976,7 +985,7 @@
+ if (i == -1 || i == 421) {
+ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
+ ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
+- "proxy: PASV: control connection is toast"));
++ ap_psprintf(p, "proxy: %s: control connection is toast", cmd)));
+ }
+ else {
+ pasv[i - 1] = '\0';
+@@ -1004,10 +1013,14 @@
+ pport = (p1 << 8) + p0;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: contacting host %d.%d.%d.%d:%d",
+ h3, h2, h1, h0, pport);
+- data_addr.sin_family = AF_INET;
+- data_addr.sin_addr.s_addr = htonl(paddr);
+- data_addr.sin_port = htons(pport);
+- i = ap_proxy_doconnect(dsock, &data_addr, r);
++ sin = (struct sockaddr_in *)&data_addr;
++ sin->sin_family = AF_INET;
++#ifdef SIN6_LEN
++ sin->sin_len = sizeof(*sin);
+#endif
-+ break;
-+ default:
-+ ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
-+ "make_sock: unsupported address family %u",
-+ server->sa_family);
-+ ap_unblock_alarms();
-+ exit(1);
-+ }
-+
-+ getnameinfo(server,
++ sin->sin_addr.s_addr = htonl(paddr);
++ sin->sin_port = htons(pport);
++ i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
+
+ if (i == -1) {
+ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
+@@ -1017,6 +1030,64 @@
+ strerror(errno), NULL)));
+ }
+ pasvmode = 1;
++ } else if (presult == 228 && pstr != NULL
++ && sscanf(pstr,
++"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
++ &paf, &holen, &ho[0], &ho[1], &ho[2], &ho[3],
++ &ho[4], &ho[5], &ho[6], &ho[7], &ho[8], &ho[9], &ho[10], &ho[11],
++ &ho[12], &ho[13], &ho[14], &ho[15], &polen, &po[0], &po[1]) == 21
++ && paf == 6 && holen == 16 && polen == 2) {
++ int i;
++ sin6 = (struct sockaddr_in6 *)&data_addr;
++ sin6->sin6_family = AF_INET6;
++#ifdef SIN6_LEN
++ sin6->sin6_len = sizeof(*sin6);
++#endif
++ for (i = 0; i < 16; i++)
++ sin6->sin6_addr.s6_addr[i] = ho[i] & 0xff;
++ sin6->sin6_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
++ i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
++
++ if (i == -1) {
++ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
++ ap_proxyerror(r, HTTP_BAD_GATEWAY,
++ ap_pstrcat(r->pool,
++ "Could not connect to remote machine: ",
++ strerror(errno), NULL)));
++ }
++ pasvmode = 1;
++ } else if (presult == 229 && pstr != NULL
++ && pstr[0] == pstr[1] && pstr[0] == pstr[2]
++ && pstr[0] == pstr[strlen(pstr) - 1]) {
++ /* expect "|||port|" */
+#ifndef SIN6_LEN
-+ SA_LEN(server),
++ memcpy(&data_addr, &server, SA_LEN((struct sockaddr *)&server));
+#else
-+ server->sa_len,
-+#endif
-+ a0, sizeof(a0), p0, sizeof(p0), NI_NUMERICHOST | NI_NUMERICSERV);
-+ ap_snprintf(addr, sizeof(addr), "address %s port %s", a0, p0);
-+#ifdef MPE
-+ if (atoi(p0) < 1024)
-+ privport++;
++ memcpy(&data_addr, &server, server.ss_len);
+#endif
++ switch (data_addr.ss_family) {
++ case AF_INET:
++ sin = (struct sockaddr_in *)&data_addr;
++ sin->sin_port = htons(atoi(pstr + 3));
++ break;
++ case AF_INET6:
++ sin6 = (struct sockaddr_in6 *)&data_addr;
++ sin6->sin6_port = htons(atoi(pstr + 3));
++ break;
++ }
++ i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
++
++ if (i == -1) {
++ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
++ ap_proxyerror(r, HTTP_BAD_GATEWAY,
++ ap_pstrcat(r->pool,
++ "Could not connect to remote machine: ",
++ strerror(errno), NULL)));
++ }
++ pasvmode = 1;
++ } else if (!lpsvmode && strcmp(cmd, "EPSV") == 0) {
++ lpsvmode = 1;
++ goto lpsvagain;
+ }
+ else {
+ ap_pclosesocket(p, dsock); /* and try the regular way */
+@@ -1025,14 +1096,14 @@
+ }
- /* note that because we're about to slack we don't use psocket */
- ap_block_alarms();
-- if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
-+ if ((s = socket(server->sa_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
- "make_sock: failed to get a socket for %s", addr);
+ if (!pasvmode) { /* set up data connection */
+- clen = sizeof(struct sockaddr_in);
++ clen = sizeof(server);
+ if (getsockname(sock, (struct sockaddr *)&server, &clen) < 0) {
+ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
+ ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
+ "proxy: error getting socket address"));
+ }
-@@ -3828,15 +3883,19 @@
+- dsock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
++ dsock = ap_psocket_ex(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP, 1);
+ if (dsock == -1) {
+ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
+ ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
+@@ -1048,13 +1119,28 @@
+ #endif /* _OSD_POSIX */
+ }
- #ifdef MPE
- /* MPE requires CAP=PM and GETPRIVMODE to bind to ports less than 1024 */
-- if (ntohs(server->sin_port) < 1024)
-+ if (privport)
- GETPRIVMODE();
- #endif
--
-- if (bind(s, (struct sockaddr *) server, sizeof(struct sockaddr_in)) == -1) {
+- if (bind(dsock, (struct sockaddr *)&server,
+- sizeof(struct sockaddr_in)) == -1) {
+#ifndef SIN6_LEN
-+ if (bind(s, server, SA_LEN(server)) == -1)
++ if (bind(dsock, (struct sockaddr *)&server, SA_LEN((struct sockaddr *)&server)) == -1)
+#else
-+ if (bind(s, server, server->sa_len) == -1)
++ if (bind(dsock, (struct sockaddr *)&server, server.ss_len) == -1)
+#endif
-+ {
- ap_log_error(APLOG_MARK, APLOG_CRIT, server_conf,
- "make_sock: could not bind to %s", addr);
- #ifdef MPE
-- if (ntohs(server->sin_port) < 1024)
-+ if (privport)
- GETUSERMODE();
- #endif
++ {
++ char hostnamebuf[MAXHOSTNAMELEN], portnamebuf[MAXHOSTNAMELEN];
++
++ getnameinfo((struct sockaddr *)&server,
++#ifndef SIN6_LEN
++ SA_LEN((struct sockaddr *)&server),
++#else
++ server.ss_len,
++#endif
++ hostnamebuf, sizeof(hostnamebuf),
++ portnamebuf, sizeof(portnamebuf),
++ NI_NUMERICHOST | NI_NUMERICSERV);
-@@ -3849,7 +3908,7 @@
- exit(1);
+ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
+ ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
+- ap_psprintf(p, "proxy: error binding to ftp data socket %s:%d",
+- inet_ntoa(server.sin_addr), server.sin_port)));
++ ap_psprintf(p, "proxy: error binding to ftp data socket %s:%s",
++ hostnamebuf, portnamebuf)));
+ }
+ listen(dsock, 2); /* only need a short queue */
}
- #ifdef MPE
-- if (ntohs(server->sin_port) < 1024)
-+ if (privport)
- GETUSERMODE();
- #endif
-
-@@ -4002,15 +4061,17 @@
- for (;;) {
- fd = find_listener(lr);
- if (fd < 0) {
-- fd = make_sock(p, &lr->local_addr);
-+ fd = make_sock(p, (struct sockaddr *)&lr->local_addr);
- }
- else {
- ap_note_cleanups_for_socket_ex(p, fd, 1);
- }
- /* if we get here, (fd >= 0) && (fd < FD_SETSIZE) */
-- FD_SET(fd, &listenfds);
-- if (fd > listenmaxfd)
-- listenmaxfd = fd;
-+ if (fd > 0) {
-+ FD_SET(fd, &listenfds);
-+ if (fd > listenmaxfd)
-+ listenmaxfd = fd;
-+ }
- lr->fd = fd;
- if (lr->next == NULL)
- break;
-@@ -4327,8 +4388,8 @@
- static void child_main(int child_num_arg)
- {
- NET_SIZE_T clen;
-- struct sockaddr sa_server;
-- struct sockaddr sa_client;
-+ struct sockaddr_storage sa_server;
-+ struct sockaddr_storage sa_client;
- listen_rec *lr;
+@@ -1308,7 +1394,7 @@
- /* All of initialization is a critical section, we don't care if we're
-@@ -4505,7 +4566,7 @@
- usr1_just_die = 0;
- for (;;) {
- clen = sizeof(sa_client);
-- csd = ap_accept(sd, &sa_client, &clen);
-+ csd = ap_accept(sd, (struct sockaddr *)&sa_client, &clen);
- if (csd >= 0 || errno != EINTR)
- break;
- if (deferred_die) {
-@@ -4671,7 +4732,7 @@
- */
+ if (!pasvmode) { /* wait for connection */
+ ap_hard_timeout("proxy ftp data connect", r);
+- clen = sizeof(struct sockaddr_in);
++ clen = sizeof(server);
+ do
+ csd = accept(dsock, (struct sockaddr *)&server, &clen);
+ while (csd == -1 && errno == EINTR);
+--- apache_1.3.34/src/modules/proxy/proxy_http.c.orig 2005-10-18 09:56:15.000000000 +0200
++++ apache_1.3.34/src/modules/proxy/proxy_http.c 2005-10-18 10:15:06.000000000 +0200
+@@ -113,9 +113,8 @@
+ table *req_hdrs, *resp_hdrs;
+ array_header *reqhdrs_arr;
+ table_entry *reqhdrs_elts;
+- struct sockaddr_in server;
+- struct in_addr destaddr;
+- struct hostent server_hp;
++ struct addrinfo hints, *res, *res0;
++ int error;
+ BUFF *f;
+ char buffer[HUGE_STRING_LEN];
+ char portstr[32];
+@@ -141,9 +140,6 @@
+ if (conf->cache.root == NULL)
+ nocache = 1;
- clen = sizeof(sa_server);
-- if (getsockname(csd, &sa_server, &clen) < 0) {
-+ if (getsockname(csd, (struct sockaddr *)&sa_server, &clen) < 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, server_conf,
- "getsockname, client %pA probably dropped the "
- "connection",
-@@ -4719,8 +4780,8 @@
- ap_bpushfd(conn_io, csd, dupped_csd);
+- memset(&server, '\0', sizeof(server));
+- server.sin_family = AF_INET;
+-
+ /* We break the URL into host, port, path-search */
- current_conn = new_connection(ptrans, server_conf, conn_io,
-- (struct sockaddr_in *) &sa_client,
-- (struct sockaddr_in *) &sa_server,
-+ (struct sockaddr *)&sa_client,
-+ (struct sockaddr *)&sa_server,
- my_child_num);
+ urlptr = strstr(url, "://");
+@@ -151,6 +147,8 @@
+ return HTTP_BAD_REQUEST;
+ urlptr += 3;
+ destport = DEFAULT_HTTP_PORT;
++ ap_snprintf(portstr, sizeof(portstr), "%d", DEFAULT_HTTP_PORT);
++ destportstr = portstr;
+ #ifdef EAPI
+ ap_hook_use("ap::mod_proxy::http::handler::set_destport",
+ AP_HOOK_SIG2(int,ptr),
+@@ -169,7 +167,20 @@
+ urlptr = strp;
+ desthost = q;
+ }
+-
++ if (*desthost == '['){
++ char *u = strrchr(desthost+1, ']');
++ if (u){
++ desthost++;
++ *u = '\0';
++ if (*(u+1) == ':'){ /* [host]:xx */
++ strp2 = u+1;
++ } else if (*(u+1) == '\0'){ /* [host] */
++ strp2 = NULL;
++ } else
++ return HTTP_BAD_REQUEST;
++ } else
++ return HTTP_BAD_REQUEST;
++ } else
+ strp2 = strchr(desthost, ':');
+ if (strp2 != NULL) {
+ *(strp2++) = '\0';
+@@ -179,46 +190,71 @@
+ }
+ }
- /*
-@@ -4875,12 +4936,13 @@
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_socktype = SOCK_STREAM;
++ hints.ai_protocol = IPPROTO_TCP;
++ error = getaddrinfo(desthost, destportstr, &hints, &res0);
++ if (error) {
++ return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
++ gai_strerror(error)); /* give up */
++ }
++
+ /* check if ProxyBlock directive on this host */
+- destaddr.s_addr = ap_inet_addr(desthost);
+- for (i = 0; i < conf->noproxies->nelts; i++) {
+- if (destaddr.s_addr == npent[i].addr.s_addr ||
+- (npent[i].name != NULL &&
+- (npent[i].name[0] == '*' || strstr(desthost, npent[i].name) != NULL)))
++ for (res = res0; res; res = res->ai_next) {
++ struct sockaddr_in *sin;
++#ifdef INET6
++ struct sockaddr_in6 *sin6;
++#endif
++ int fail;
++
++ fail = 0;
++ for (i = 0; i < conf->noproxies->nelts; i++) {
++ if (npent[i].name != NULL && strstr(desthost, npent[i].name))
++ fail++;
++ if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
++ fail++;
++ switch (res->ai_family) {
++ case AF_INET:
++ sin = (struct sockaddr_in *)res->ai_addr;
++ if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
++ fail++;
++ break;
++ }
++ }
++ if (fail) {
++ freeaddrinfo(res0);
+ return ap_proxyerror(r, HTTP_FORBIDDEN,
+ "Connect to remote machine blocked");
++ }
+ }
- #ifdef _OSD_POSIX
- /* BS2000 requires a "special" version of fork() before a setuid() call */
-- if ((pid = os_fork(ap_user_name)) == -1) {
-+ if ((pid = os_fork(ap_user_name)) == -1)
- #elif defined(TPF)
-- if ((pid = os_fork(s, slot)) == -1) {
-+ if ((pid = os_fork(s, slot)) == -1)
- #else
-- if ((pid = fork()) == -1) {
-+ if ((pid = fork()) == -1)
+ if (proxyhost != NULL) {
+- server.sin_port = htons((unsigned short)proxyport);
+- err = ap_proxy_host2addr(proxyhost, &server_hp);
+- if (err != NULL)
++ char pbuf[10];
++
++ freeaddrinfo(res0);
++ ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_socktype = SOCK_STREAM;
++ hints.ai_protocol = IPPROTO_TCP;
++ error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
++ if (error)
+ return DECLINED; /* try another */
+ #ifdef EAPI
+ peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);
#endif
-+ {
- ap_log_error(APLOG_MARK, APLOG_ERR, s, "fork: Unable to fork new process");
+ }
+- else {
+- server.sin_port = htons((unsigned short)destport);
+- err = ap_proxy_host2addr(desthost, &server_hp);
+- if (err != NULL)
+- return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
+-#ifdef EAPI
+- peer = ap_psprintf(p, "%s:%u", desthost, destport);
+-#endif
+- }
+-
- /* fork didn't succeed. Fix the scoreboard or else
-@@ -5497,7 +5559,10 @@
- ap_setup_prelinked_modules();
+ /*
+ * we have worked out who exactly we are going to connect to, now make
+ * that connection...
+ */
+- sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
+- if (sock == -1) {
+- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+- "proxy: error creating socket");
+- return HTTP_INTERNAL_SERVER_ERROR;
+- }
++ sock = i = -1;
++ for (res = res0; res; res = res->ai_next) {
++ sock = ap_psocket_ex(p, res->ai_family, res->ai_socktype, res->ai_protocol, 1);
++ if (sock < 0)
++ continue;
- while ((c = getopt(argc, argv,
-- "D:C:c:xXd:Ff:vVlLR:StTh"
-+ "D:C:c:xXd:Ff:vVlLR:StTh4"
-+#ifdef INET6
-+ "6"
-+#endif
- #ifdef DEBUG_SIGSTOP
- "Z:"
+ #if !defined(TPF) && !defined(BEOS)
+ if (conf->recv_buffer_size) {
+@@ -231,38 +267,13 @@
+ }
#endif
-@@ -5575,8 +5640,14 @@
- ap_configtestonly = 1;
- ap_docrootcheck = 0;
- break;
-- case 'h':
-- usage(argv[0]);
-+ case '4':
-+ ap_default_family = PF_INET;
-+ break;
+
+-#ifdef SINIX_D_RESOLVER_BUG
+- {
+- struct in_addr *ip_addr = (struct in_addr *)*server_hp.h_addr_list;
+-
+- for (; ip_addr->s_addr != 0; ++ip_addr) {
+- memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
+- i = ap_proxy_doconnect(sock, &server, r);
+- if (i == 0)
+- break;
+- /*
+- * Even if the connection was unsuccesful we should
+- * reinit the socket
+- */
+- sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
+- }
+- }
+-#else
+- j = 0;
+- while (server_hp.h_addr_list[j] != NULL) {
+- memcpy(&server.sin_addr, server_hp.h_addr_list[j],
+- sizeof(struct in_addr));
+- i = ap_proxy_doconnect(sock, &server, r);
++ i = ap_proxy_doconnect(sock, res->ai_addr, r);
+ if (i == 0)
+ break;
+- /*
+- * Even if the connection was unsuccesful we should
+- * reinit the socket
+- */
+- sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
++ ap_pclosesocket(p, sock);
+ j++;
+ }
+-#endif
++ freeaddrinfo(res0);
+ if (i == -1) {
+ if (proxyhost != NULL)
+ return DECLINED; /* try again another way */
+@@ -591,17 +602,30 @@
+ ap_table_set(resp_hdrs, "Content-Location", proxy_location_reverse_map(r, urlstr));
+
+ /* check if NoCache directive on this host */
++ {
++ struct sockaddr_in *sin;
+#ifdef INET6
-+ case '6':
-+ ap_default_family = PF_INET6;
-+ break;
++ struct sockaddr_in6 *sin6;
+#endif
- case '?':
- usage(argv[0]);
- }
-@@ -5665,9 +5736,10 @@
- else {
- conn_rec *conn;
- request_rec *r;
-- struct sockaddr sa_server, sa_client;
- BUFF *cio;
-+ struct sockaddr_storage sa_server, sa_client;
- NET_SIZE_T l;
-+ char servbuf[NI_MAXSERV];
++
+ if (nocache == 0) {
+ for (i = 0; i < conf->nocaches->nelts; i++) {
+- if (destaddr.s_addr == ncent[i].addr.s_addr ||
+- (ncent[i].name != NULL &&
+- (ncent[i].name[0] == '*' ||
+- strstr(desthost, ncent[i].name) != NULL))) {
+- nocache = 1;
+- break;
++ if (ncent[i].name != NULL &&
++ (ncent[i].name[0] == '*' ||
++ strstr(desthost, ncent[i].name) != NULL)) {
++ nocache = 1;
++ break;
++ }
++ switch (res->ai_addr->sa_family) {
++ case AF_INET:
++ sin = (struct sockaddr_in *)res->ai_addr;
++ if (sin->sin_addr.s_addr == ncent[i].addr.s_addr) {
++ nocache = 1;
++ break;
++ }
+ }
+ }
+-
++ }
+ /*
+ * update the cache file, possibly even fulfilling the request if it
+ * turns out a conditional allowed us to serve the object from the
+diff -Nur apache_1.3.28.orig/src/modules/proxy/proxy_util.c apache_1.3.28/src/modules/proxy/proxy_util.c
+--- apache_1.3.28.orig/src/modules/proxy/proxy_util.c Mon Feb 3 18:13:26 2003
++++ apache_1.3.28/src/modules/proxy/proxy_util.c Fri Jul 25 11:01:55 2003
+@@ -64,6 +64,7 @@
+ #include "http_log.h"
+ #include "util_uri.h"
+ #include "util_date.h" /* get ap_checkmask() decl. */
++#include "sa_len.h"
- ap_set_version();
- /* Yes this is called twice. */
-@@ -5722,25 +5794,32 @@
- #endif
+ static int proxy_match_ipaddr(struct dirconn_entry *This, request_rec *r);
+ static int proxy_match_domainname(struct dirconn_entry *This, request_rec *r);
+@@ -219,6 +220,7 @@
+ int i;
+ char *strp, *host, *url = *urlp;
+ char *user = NULL, *password = NULL;
++ char *t = NULL, *u = NULL, *v = NULL;
- l = sizeof(sa_client);
-- if ((getpeername(sock_in, &sa_client, &l)) < 0) {
-+ if ((getpeername(sock_in, (struct sockaddr *)&sa_client, &l)) < 0) {
- /* get peername will fail if the input isn't a socket */
- perror("getpeername");
- memset(&sa_client, '\0', sizeof(sa_client));
- }
+ if (url[0] != '/' || url[1] != '/')
+ return "Malformed URL";
+@@ -257,11 +259,22 @@
+ *passwordp = password;
+ }
- l = sizeof(sa_server);
-- if (getsockname(sock_in, &sa_server, &l) < 0) {
-+ if (getsockname(sock_in, (struct sockaddr *)&sa_server, &l) < 0) {
- perror("getsockname");
- fprintf(stderr, "Error getting local address\n");
- exit(1);
- }
-- server_conf->port = ntohs(((struct sockaddr_in *) &sa_server)->sin_port);
-+ if (getnameinfo(((struct sockaddr *)&sa_server), l,
-+ NULL, 0, servbuf, sizeof(servbuf),
-+ NI_NUMERICSERV)){
-+ fprintf(stderr, "getnameinfo(): family=%d\n", sa_server.ss_family);
-+ exit(1);
+- strp = strrchr(host, ':');
+- if (strp != NULL) {
+- *(strp++) = '\0';
+-
+- for (i = 0; strp[i] != '\0'; i++)
++ v = host;
++ if (*host == '['){
++ u = strrchr(host, ']');
++ if (u){
++ host++;
++ *u = '\0';
++ v = u + 1;
++ }
++ }
++ t = strrchr(v, ':');
++ if (t){
++ *t = '\0';
++ strp = t + 1;
++ }
++ if (strp) {
++ for (i=0; strp[i] != '\0'; i++)
+ if (!ap_isdigit(strp[i]))
+ break;
+
+@@ -280,17 +293,29 @@
+ return "Missing host in URL";
+ /* check hostname syntax */
+ for (i = 0; host[i] != '\0'; i++)
+- if (!ap_isdigit(host[i]) && host[i] != '.')
++ if (!ap_isdigit(host[i]) && host[i] != '.' && host[i] != ':')
+ break;
+ /* must be an IP address */
+ #if defined(WIN32) || defined(NETWARE) || defined(TPF) || defined(BEOS)
+ if (host[i] == '\0' && (inet_addr(host) == -1))
++ return "Bad IP address in URL";
++#else
++ if (host[i] == '\0') {
++ struct addrinfo hints, *res0;
++ int gai;
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_flags = AI_NUMERICHOST;
++ if (gai = getaddrinfo(host, NULL, &hints, &res0)) {
++#if 0
++ return gai_strerror(gai);
+ #else
+- if (host[i] == '\0' && (ap_inet_addr(host) == -1 || inet_network(host) == -1))
++ return "Bad IP address in URL";
+ #endif
+- {
+- return "Bad IP address in URL";
+ }
-+ servbuf[sizeof(servbuf)-1] = '\0';
-+ server_conf->port = atoi(servbuf);
- cio = ap_bcreate(ptrans, B_RDWR | B_SOCKET);
- cio->fd = sock_out;
- cio->fd_in = sock_in;
- conn = new_connection(ptrans, server_conf, cio,
-- (struct sockaddr_in *) &sa_client,
-- (struct sockaddr_in *) &sa_server, -1);
-+ (struct sockaddr *)&sa_client,
-+ (struct sockaddr *)&sa_server, -1);
++ freeaddrinfo(res0);
+ }
++#endif
- while ((r = ap_read_request(conn)) != NULL) {
+ /* if (strchr(host,'.') == NULL && domain != NULL)
+ host = pstrcat(p, host, domain, NULL);
+@@ -1359,22 +1384,46 @@
+ return host != NULL && strstr(host, This->name) != NULL;
+ }
-@@ -7447,7 +7526,11 @@
+-int ap_proxy_doconnect(int sock, struct sockaddr_in *addr, request_rec *r)
++int ap_proxy_doconnect(int sock, struct sockaddr *addr, request_rec *r)
+ {
+ int i;
++ int salen;
++ char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
++#ifdef NI_WITHSCOPEID
++ const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
++#else
++ const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
++#endif
- while ((c = getopt(argc, argv, "D:C:c:Xd:f:vVlLz:Z:wiuStThk:n:W:")) != -1) {
- #else /* !WIN32 */
-- while ((c = getopt(argc, argv, "D:C:c:Xd:Ff:vVlLesStTh")) != -1) {
-+ while ((c = getopt(argc, argv, "D:C:c:Xd:Ff:vVlLesStTh4"
-+#ifdef INET6
-+ "6"
+ ap_hard_timeout("proxy connect", r);
++#ifdef HAVE_SOCKADDR_LEN
++ salen = addr->sa_len;
++#else
++ switch (addr->sa_family) {
++ case AF_INET6:
++ salen = sizeof(struct sockaddr_in6);
++ break;
++ default:
++ salen = sizeof(struct sockaddr_in);
++ break;
++ }
+#endif
-+ )) != -1) {
- #endif
- char **new;
- switch (c) {
-@@ -7993,6 +8076,10 @@
- case 't':
- case 'T':
- case 'h':
-+ case '4':
+ do {
+- i = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
++ i = connect(sock, addr, salen);
+ #if defined(WIN32) || defined(NETWARE)
+ if (i == SOCKET_ERROR)
+ errno = WSAGetLastError();
+ #endif /* WIN32 */
+ } while (i == -1 && errno == EINTR);
+ if (i == -1) {
++ if (getnameinfo(addr, salen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
++ niflags) != 0) {
++ strcpy(hbuf, "?");
++ strcpy(pbuf, "?");
++ }
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "proxy connect to %s port %d failed",
+- inet_ntoa(addr->sin_addr), ntohs(addr->sin_port));
++ hbuf, pbuf);
+ }
+ ap_kill_timeout(r);
+
+--- apache_1.3.31/src/modules/standard/mod_access.c.orig Sun Mar 7 22:47:14 2004
++++ apache_1.3.31/src/modules/standard/mod_access.c Sat May 15 00:05:40 2004
+@@ -31,7 +31,10 @@
+ T_ALL,
+ T_IP,
+ T_HOST,
+- T_FAIL
++ T_FAIL,
+#ifdef INET6
-+ case '6':
++ T_IP6,
+#endif
- case '?':
- break;
- case 'R':
---- apache_1.3.28/src/main/http_core.c.orig 2003-07-07 15:02:28.000000000 +0200
-+++ apache_1.3.28/src/main/http_core.c 2003-07-19 12:18:57.000000000 +0200
-@@ -71,6 +71,7 @@
- #include "util_md5.h"
- #include "scoreboard.h"
- #include "fnmatch.h"
-+#include "sa_len.h"
+ };
- #ifdef USE_MMAP_FILES
- #include <sys/mman.h>
-@@ -651,7 +652,9 @@
- */
- static ap_inline void do_double_reverse (conn_rec *conn)
- {
-- struct hostent *hptr;
-+ struct addrinfo hints, *res, *res0;
-+ char hostbuf1[128], hostbuf2[128]; /* INET6_ADDRSTRLEN(=46) is enough */
-+ int ok = 0;
+ typedef struct {
+@@ -42,6 +45,12 @@
+ struct in_addr net;
+ struct in_addr mask;
+ } ip;
++#ifdef INET6
++ struct {
++ struct in6_addr net6;
++ struct in6_addr mask6;
++ } ip6;
++#endif
+ } x;
+ enum allowdeny_type type;
+ } allowdeny;
+@@ -124,94 +133,242 @@
- if (conn->double_reverse) {
- /* already done */
-@@ -663,19 +666,43 @@
- conn->remote_host = ""; /* prevent another lookup */
- return;
}
-- hptr = gethostbyname(conn->remote_host);
-- if (hptr) {
-- char **haddr;
+ else if ((s = strchr(where, '/'))) {
+- struct in_addr mask;
++ struct addrinfo hints, *resnet, *resmask;
++ struct sockaddr_storage net, mask;
++ int error;
++ char *p;
++ int justdigits;
+
+- a->type = T_IP;
++ a->type = T_FAIL; /*just in case*/
+ /* trample on where, we won't be using it any more */
+ *s++ = '\0';
+
+- if (!is_ip(where)
+- || (a->x.ip.net.s_addr = ap_inet_addr(where)) == INADDR_NONE) {
++ justdigits = 0;
++ for (p = s; *p; p++) {
++ if (!isdigit(*p))
++ break;
++ }
++ if (!*p)
++ justdigits++;
++
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_socktype = SOCK_STREAM; /*dummy*/
++#ifdef AI_NUMERICHOST
++ hints.ai_flags = AI_NUMERICHOST; /*don't resolve*/
++#endif
++ resnet = NULL;
++ error = getaddrinfo(where, NULL, &hints, &resnet);
++ if (error || !resnet) {
++ if (resnet)
++ freeaddrinfo(resnet);
+ a->type = T_FAIL;
+ return "syntax error in network portion of network/netmask";
+ }
-
-- for (haddr = hptr->h_addr_list; *haddr; haddr++) {
-- if (((struct in_addr *)(*haddr))->s_addr
-- == conn->remote_addr.sin_addr.s_addr) {
-- conn->double_reverse = 1;
-- return;
+- /* is_ip just tests if it matches [\d.]+ */
+- if (!is_ip(s)) {
++ if (resnet->ai_next) {
++ freeaddrinfo(resnet);
+ a->type = T_FAIL;
+- return "syntax error in mask portion of network/netmask";
++ return "network/netmask resolved to multiple addresses";
+ }
+- /* is it in /a.b.c.d form? */
+- if (strchr(s, '.')) {
+- mask.s_addr = ap_inet_addr(s);
+- if (mask.s_addr == INADDR_NONE) {
+- a->type = T_FAIL;
+- return "syntax error in mask portion of network/netmask";
- }
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ if (getaddrinfo(conn->remote_host, NULL, &hints, &res0)) {
-+ conn->double_reverse = -1;
-+ return;
-+ }
-+ for (res = res0; res; res = res->ai_next) {
-+ if (res->ai_addr->sa_family != conn->remote_addr.ss_family ||
-+ !(res->ai_family == AF_INET
-+#ifdef INET6
-+ || res->ai_family == AF_INET6
-+#endif
-+ )
-+ )
-+ continue;
-+#ifndef HAVE_SOCKADDR_LEN
-+ if (res->ai_addrlen != SA_LEN((struct sockaddr *)&conn->remote_addr))
-+#else
-+ if (res->ai_addr->sa_len != conn->remote_addr.ss_len)
-+#endif
-+ continue;
-+ if (getnameinfo(res->ai_addr, res->ai_addrlen,
-+ hostbuf1, sizeof(hostbuf1), NULL, 0,
-+ NI_NUMERICHOST))
-+ continue;
-+ if (getnameinfo(((struct sockaddr *)&conn->remote_addr), res->ai_addrlen,
-+ hostbuf2, sizeof(hostbuf2), NULL, 0,
-+ NI_NUMERICHOST))
-+ continue;
-+ if (strcmp(hostbuf1, hostbuf2) == 0){
-+ ok = 1;
++ memcpy(&net, resnet->ai_addr, resnet->ai_addrlen);
++ freeaddrinfo(resnet);
++
++ switch (net.ss_family) {
++ case AF_INET:
++ a->type = T_IP;
++ a->x.ip.net.s_addr = ((struct sockaddr_in *)&net)->sin_addr.s_addr;
++ break;
++#ifdef INET6
++ case AF_INET6:
++ a->type = T_IP6;
++ memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&net)->sin6_addr,
++ sizeof(a->x.ip6.net6));
+ break;
- }
- }
-- conn->double_reverse = -1;
-+ conn->double_reverse = ok ? 1 : -1;
-+ freeaddrinfo(res0);
- /* invalidate possible reverse-resolved hostname if forward lookup fails */
- conn->remote_host = "";
- }
-@@ -683,10 +710,9 @@
- API_EXPORT(const char *) ap_get_remote_host(conn_rec *conn, void *dir_config,
- int type)
- {
-- struct in_addr *iaddr;
-- struct hostent *hptr;
- int hostname_lookups;
- int old_stat = SERVER_DEAD; /* we shouldn't ever be in this state */
-+ char hostnamebuf[MAXHOSTNAMELEN];
-
- /* If we haven't checked the host name, and we want to */
- if (dir_config) {
-@@ -708,10 +734,14 @@
- || hostname_lookups != HOSTNAME_LOOKUP_OFF)) {
- old_stat = ap_update_child_status(conn->child_num, SERVER_BUSY_DNS,
- (request_rec*)NULL);
-- iaddr = &(conn->remote_addr.sin_addr);
-- hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
-- if (hptr != NULL) {
-- conn->remote_host = ap_pstrdup(conn->pool, (void *)hptr->h_name);
-+ if (!getnameinfo((struct sockaddr *)&conn->remote_addr,
-+#ifndef SIN6_LEN
-+ SA_LEN((struct sockaddr *)&conn->remote_addr),
-+#else
-+ conn->remote_addr.ss_len,
+#endif
-+ hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0)) {
-+ conn->remote_host = ap_pstrdup(conn->pool, (void *)hostnamebuf);
- ap_str_tolower(conn->remote_host);
-
- if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
-@@ -789,6 +819,7 @@
- {
- conn_rec *conn = r->connection;
- core_dir_config *d;
-+ char hbuf[MAXHOSTNAMELEN];
++ default:
++ a->type = T_FAIL;
++ return "unknown address family for network";
+ }
+- else {
+- int i;
- d = (core_dir_config *)ap_get_module_config(r->per_dir_config,
- &core_module);
-@@ -798,23 +829,22 @@
- }
- if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
- if (conn->local_host == NULL) {
-- struct in_addr *iaddr;
-- struct hostent *hptr;
- int old_stat;
- old_stat = ap_update_child_status(conn->child_num,
- SERVER_BUSY_DNS, r);
-- iaddr = &(conn->local_addr.sin_addr);
-- hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr),
-- AF_INET);
-- if (hptr != NULL) {
-- conn->local_host = ap_pstrdup(conn->pool,
-- (void *)hptr->h_name);
-- ap_str_tolower(conn->local_host);
+- /* assume it's in /nnn form */
+- i = atoi(s);
+- if (i > 32 || i <= 0) {
++ if (!justdigits) {
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_socktype = SOCK_STREAM; /*dummy*/
++#ifdef AI_NUMERICHOST
++ hints.ai_flags = AI_NUMERICHOST; /*don't resolve*/
++#endif
++ resmask = NULL;
++ error = getaddrinfo(s, NULL, &hints, &resmask);
++ if (error || !resmask) {
++ if (resmask)
++ freeaddrinfo(resmask);
+ a->type = T_FAIL;
+- return "invalid mask in network/netmask";
++ return "syntax error in mask portion of network/netmask";
+ }
+- mask.s_addr = 0xFFFFFFFFUL << (32 - i);
+- mask.s_addr = htonl(mask.s_addr);
+- }
+- a->x.ip.mask = mask;
+- a->x.ip.net.s_addr = (a->x.ip.net.s_addr & mask.s_addr); /* pjr - This fixes PR 4770 */
+- }
+- else if (ap_isdigit(*where) && is_ip(where)) {
+- /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
+- int shift;
+- char *t;
+- int octet;
+-
+- a->type = T_IP;
+- /* parse components */
+- s = where;
+- a->x.ip.net.s_addr = 0;
+- a->x.ip.mask.s_addr = 0;
+- shift = 24;
+- while (*s) {
+- t = s;
+- if (!ap_isdigit(*t)) {
++ if (resmask->ai_next) {
++ freeaddrinfo(resmask);
+ a->type = T_FAIL;
+- return "invalid ip address";
- }
-- else {
-- conn->local_host = ap_pstrdup(conn->pool,
-- r->server->server_hostname);
-+ if (getnameinfo((struct sockaddr *)&conn->local_addr,
-+#ifndef SIN6_LEN
-+ SA_LEN((struct sockaddr *)&conn->local_addr),
-+#else
-+ conn->local_addr.ss_len,
+- while (ap_isdigit(*t)) {
+- ++t;
+- }
+- if (*t == '.') {
+- *t++ = 0;
++ return "network/netmask resolved to multiple addresses";
+ }
+- else if (*t) {
++ memcpy(&mask, resmask->ai_addr, resmask->ai_addrlen);
++ freeaddrinfo(resmask);
++
++ if (net.ss_family != mask.ss_family) {
+ a->type = T_FAIL;
+- return "invalid ip address";
++ return "network/netmask resolved to different address family";
+ }
+- if (shift < 0) {
+- a->type = T_FAIL;
+- return "invalid ip address, only 4 octets allowed";
++
++ switch (a->type) {
++ case T_IP:
++ a->x.ip.mask.s_addr =
++ ((struct sockaddr_in *)&mask)->sin_addr.s_addr;
++ break;
++#ifdef INET6
++ case T_IP6:
++ memcpy(&a->x.ip6.mask6,
++ &((struct sockaddr_in6 *)&mask)->sin6_addr,
++ sizeof(a->x.ip6.mask6));
++ break;
+#endif
-+ hbuf, sizeof(hbuf), NULL, 0, 0) == 0) {
-+ conn->local_host = ap_pstrdup(conn->pool, hbuf);
-+ } else {
-+ conn->local_host = ap_pstrdup(conn->pool,
-+ r->server->server_hostname);
}
-+ ap_str_tolower(conn->local_host);
- (void) ap_update_child_status(conn->child_num, old_stat, r);
+- octet = atoi(s);
+- if (octet < 0 || octet > 255) {
+- a->type = T_FAIL;
+- return "each octet must be between 0 and 255 inclusive";
++ } else {
++ int mask;
++ mask = atoi(s);
++ switch (a->type) {
++ case T_IP:
++ if (mask < 0 || 32 < mask) {
++ a->type = T_FAIL;
++ return "netmask out of range";
++ }
++ a->x.ip.mask.s_addr = htonl(0xFFFFFFFFUL << (32 - mask));
++ break;
++#ifdef INET6
++ case T_IP6:
++ {
++ int i;
++ if (mask < 0 || 128 < mask) {
++ a->type = T_FAIL;
++ return "netmask out of range";
++ }
++ for (i = 0; i < mask / 8; i++) {
++ a->x.ip6.mask6.s6_addr[i] = 0xff;
++ }
++ if (mask % 8)
++ a->x.ip6.mask6.s6_addr[i] = 0xff << (8 - (mask % 8));
++ break;
++ }
++#endif
+ }
+- a->x.ip.net.s_addr |= (unsigned int)octet << shift;
+- a->x.ip.mask.s_addr |= 0xFFUL << shift;
+- s = t;
+- shift -= 8;
}
- return conn->local_host;
-@@ -833,11 +863,13 @@
-
- if (d->use_canonical_name == USE_CANONICAL_NAME_OFF
- || d->use_canonical_name == USE_CANONICAL_NAME_DNS) {
-- return r->hostname ? ntohs(r->connection->local_addr.sin_port)
-- : port;
-- }
-- /* default */
-- return port;
-+ return r->hostname
-+ ? ntohs(((struct sockaddr_in *)&r->connection->local_addr)->sin_port)
-+ : port;
-+ }
-+ return r->hostname
-+ ? ntohs(((struct sockaddr_in *)&r->connection->local_addr)->sin_port)
-+ : port;
- }
-
- API_EXPORT(char *) ap_construct_url(pool *p, const char *uri,
-@@ -2569,12 +2601,25 @@
-
- static const char *set_bind_address(cmd_parms *cmd, void *dummy, char *arg)
- {
-+ struct addrinfo hints, *res;
-+ struct sockaddr *sa;
-+ size_t sa_len;
-+ int error;
- const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
- if (err != NULL) {
- return err;
+- a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
+- a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
++ /* mask network address */
++ switch (a->type) {
++ case T_IP:
++ a->x.ip.net.s_addr &= a->x.ip.mask.s_addr;
++ break;
++ case T_IP6:
++ a->x.ip6.net6.s6_addr32[0] &= a->x.ip6.mask6.s6_addr32[0];
++ a->x.ip6.net6.s6_addr32[1] &= a->x.ip6.mask6.s6_addr32[1];
++ a->x.ip6.net6.s6_addr32[2] &= a->x.ip6.mask6.s6_addr32[2];
++ a->x.ip6.net6.s6_addr32[3] &= a->x.ip6.mask6.s6_addr32[3];
++ }
}
-
-- ap_bind_address.s_addr = ap_get_virthost_addr(arg, NULL);
-+ if (strcmp(arg, "*") == 0)
-+ arg = NULL;
+ else {
+- a->type = T_HOST;
+- }
++ struct addrinfo hints, *res;
++ struct sockaddr_storage ss;
++ int error;
+
-+ sa = ap_get_virthost_addr(arg, NULL);
-+#ifdef HAVE_SOCKADDR_LEN
-+ sa_len = sa->sa_len;
-+#else
-+ sa_len = SA_LEN(sa);
++ a->type = T_FAIL; /*just in case*/
++
++ /* First, try using the old apache code to match */
++ /* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
++ if (ap_isdigit(*where) && is_ip(where)) {
++ int shift;
++ char *t;
++ int octet;
++
++ a->type = T_IP;
++ /* parse components */
++ s = where;
++ a->x.ip.net.s_addr = 0;
++ a->x.ip.mask.s_addr = 0;
++ shift = 24;
++ while (*s) {
++ t = s;
++ if (!ap_isdigit(*t)) {
++ a->type = T_FAIL;
++ return "invalid ip address";
++ }
++ while (ap_isdigit(*t)) {
++ ++t;
++ }
++ if (*t == '.') {
++ *t++ = 0;
++ }
++ else if (*t) {
++ a->type = T_FAIL;
++ return "invalid ip address";
++ }
++ if (shift < 0) {
++ return "invalid ip address, only 4 octets allowed";
++ }
++ octet = atoi(s);
++ if (octet < 0 || octet > 255) {
++ a->type = T_FAIL;
++ return "each octet must be between 0 and 255 inclusive";
++ }
++ a->x.ip.net.s_addr |= (unsigned int)octet << shift;
++ a->x.ip.mask.s_addr |= 0xFFUL << shift;
++ s = t;
++ shift -= 8;
++ }
++ a->x.ip.net.s_addr = ntohl(a->x.ip.net.s_addr);
++ a->x.ip.mask.s_addr = ntohl(a->x.ip.mask.s_addr);
++
++ return NULL;
++ }
++
++ /* IPv4/v6 numeric address */
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_socktype = SOCK_STREAM; /*dummy*/
++#ifdef AI_NUMERICHOST
++ hints.ai_flags = AI_NUMERICHOST; /*don't resolve*/
++#endif
++ res = NULL;
++ error = getaddrinfo(where, NULL, &hints, &res);
++ if (error || !res) {
++ if (res)
++ freeaddrinfo(res);
++ a->type = T_HOST;
++ return NULL;
++ }
++ if (res->ai_next) {
++ freeaddrinfo(res);
++ a->type = T_FAIL;
++ return "network/netmask resolved to multiple addresses";
++ }
++ memcpy(&ss, res->ai_addr, res->ai_addrlen);
++ freeaddrinfo(res);
++
++ switch (ss.ss_family) {
++ case AF_INET:
++ a->type = T_IP;
++ a->x.ip.net.s_addr = ((struct sockaddr_in *)&ss)->sin_addr.s_addr;
++ memset(&a->x.ip.mask, 0xff, sizeof(a->x.ip.mask));
++ break;
++#ifdef INET6
++ case AF_INET6:
++ a->type = T_IP6;
++ memcpy(&a->x.ip6.net6, &((struct sockaddr_in6 *)&ss)->sin6_addr,
++ sizeof(a->x.ip6.net6));
++ memset(&a->x.ip6.mask6, 0xff, sizeof(a->x.ip6.mask6));
++ break;
+#endif
-+ memcpy(&ap_bind_address, &sa, sa_len);
- return NULL;
- }
++ default:
++ a->type = T_FAIL;
++ return "unknown address family for network";
++ }
++ }
-@@ -2606,9 +2651,11 @@
return NULL;
}
+@@ -275,13 +432,63 @@
+ return 1;
--static const char *set_listener(cmd_parms *cmd, void *dummy, char *ips)
-+static const char *set_listener(cmd_parms *cmd, void *dummy, char *h, char *p)
- {
- listen_rec *new;
-+ char *host, *port;
-+ struct addrinfo hints, *res;
-+ int error;
- char *ports, *endptr;
-- long port;
-
-@@ -2617,37 +2665,82 @@
- return err;
- }
+ case T_IP:
+- if (ap[i].x.ip.net.s_addr != INADDR_NONE
+- && (r->connection->remote_addr.sin_addr.s_addr
+- & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
+- return 1;
++ if (ap[i].x.ip.net.s_addr == INADDR_NONE)
++ break;
++ switch (r->connection->remote_addr.ss_family) {
++ case AF_INET:
++ if ((((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr
++ & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
++ return 1;
++ }
++ break;
++#ifdef INET6
++ case AF_INET6:
++ if (!IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr)) /*XXX*/
++ break;
++ if ((*(ap_uint32_t *)&((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr.s6_addr[12]
++ & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) {
++ return 1;
++ }
++ break;
++#endif
+ }
+ break;
-- ports = strchr(ips, ':');
-- if (ports != NULL) {
-- if (ports == ips) {
-- return "Missing IP address";
-- }
-- else if (ports[1] == '\0') {
-- return "Address must end in :<port-number>";
-- }
-- *(ports++) = '\0';
-- }
-- else {
-- ports = ips;
-- }
-+ host = port = NULL;
-+ if (!p) {
-+ port = strrchr(h, ':');
-+ if (port != NULL) {
-+ if (port == h) {
-+ return "Missing IP address";
-+ }
-+ else if (port[1] == '\0') {
-+ return "Address must end in :<port-number>";
-+ }
-+ *(port++) = '\0';
-+ if (*h)
-+ host = h;
-+ } else {
-+ host = NULL;
-+ port = h;
-+ }
-+ } else {
-+ host = h;
-+ port = p;
-+ }
-+
-+
-+ host = port = NULL;
-+ if (!p) {
-+ port = strrchr(h, ':');
-+ if (port != NULL) {
-+ if (port == h) {
-+ return "Missing IP address";
-+ }
-+ else if (port[1] == '\0') {
-+ return "Address must end in :<port-number>";
-+ }
-+ *(port++) = '\0';
-+ if (*h)
-+ host = h;
-+ } else {
-+ host = NULL;
-+ port = h;
-+ }
-+ } else {
-+ host = h;
-+ port = p;
-+ }
-+
-+ if (host && strcmp(host, "*") == 0)
-+ host = NULL;
-+
-+ new = ap_pcalloc(cmd->pool, sizeof(listen_rec));
-+
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = host ? PF_UNSPEC : ap_default_family;
-+ hints.ai_flags = AI_PASSIVE;
-+ hints.ai_socktype = SOCK_STREAM;
-+ error = getaddrinfo(host, port, &hints, &res);
-+ if (error || !res) {
-+ fprintf(stderr, "could not resolve ");
-+ if (host)
-+ fprintf(stderr, "host \"%s\" ", host);
-+ if (port)
-+ fprintf(stderr, "port \"%s\" ", port);
-+ fprintf(stderr, "--- %s\n", gai_strerror(error));
-+ exit(1);
-+ }
-+ if (res->ai_next) {
-+ if (host)
-+ fprintf(stderr, "host \"%s\" ", host);
-+ if (port)
-+ fprintf(stderr, "port \"%s\" ", port);
-+ fprintf(stderr, "resolved to multiple addresses, ambiguous.\n");
-+ exit(1);
-+ }
-+
-+ memcpy(&new->local_addr, res->ai_addr, res->ai_addrlen);
++#ifdef INET6
++ case T_IP6:
++ {
++ struct in6_addr masked;
++ int j;
++ if (IN6_IS_ADDR_UNSPECIFIED(&ap[i].x.ip6.net6))
++ break;
++ switch (r->connection->remote_addr.ss_family) {
++ case AF_INET:
++ if (!IN6_IS_ADDR_V4MAPPED(&ap[i].x.ip6.net6)) /*XXX*/
++ break;
++ memset(&masked, 0, sizeof(masked));
++ masked.s6_addr[10] = masked.s6_addr[11] = 0xff;
++ memcpy(&masked.s6_addr[12],
++ &((struct sockaddr_in *)&r->connection->remote_addr)->sin_addr.s_addr,
++ sizeof(struct sockaddr_in));
++ for (j = 0; j < sizeof(struct in6_addr); j++)
++ masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
++ if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
++ return 1;
++ break;
++ case AF_INET6:
++ memset(&masked, 0, sizeof(masked));
++ memcpy(&masked,
++ &((struct sockaddr_in6 *)&r->connection->remote_addr)->sin6_addr,
++ sizeof(masked));
++ for (j = 0; j < sizeof(struct in6_addr); j++)
++ masked.s6_addr[j] &= ap[i].x.ip6.mask6.s6_addr[j];
++ if (memcmp(&masked, &ap[i].x.ip6.net6, sizeof(masked)) == 0)
++ return 1;
++ break;
++ }
++ break;
++ }
++#endif
+ case T_HOST:
+ if (!gothost) {
+ remotehost = ap_get_remote_host(r->connection, r->per_dir_config,
+diff -Nur apache_1.3.28.orig/src/modules/standard/mod_unique_id.c apache_1.3.28/src/modules/standard/mod_unique_id.c
+--- apache_1.3.28.orig/src/modules/standard/mod_unique_id.c Mon Feb 3 18:13:30 2003
++++ apache_1.3.28/src/modules/standard/mod_unique_id.c Fri Jul 25 11:01:55 2003
+@@ -67,10 +67,22 @@
+ #include "http_config.h"
+ #include "http_log.h"
+ #include "multithread.h"
++#include "sa_len.h"
+
++/*#define SHORT_UNIQUE_ID*/
-- new=ap_pcalloc(cmd->pool, sizeof(listen_rec));
-- new->local_addr.sin_family = AF_INET;
-- if (ports == ips) { /* no address */
-- new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-- }
-- else {
-- new->local_addr.sin_addr.s_addr = ap_get_virthost_addr(ips, NULL);
-- }
-- errno = 0; /* clear errno before calling strtol */
-- port = ap_strtol(ports, &endptr, 10);
-- if (errno /* some sort of error */
-- || (endptr && *endptr) /* make sure no trailing characters */
-- || port < 1 || port > 65535) /* underflow/overflow */
-- {
-- return "Missing, invalid, or non-numeric port";
-- }
-- new->local_addr.sin_port = htons((unsigned short)port);
- new->fd = -1;
- new->used = 0;
- new->next = ap_listeners;
-@@ -3524,7 +3617,7 @@
- { "ThreadStackSize", set_threadstacksize, NULL, RSRC_CONF, TAKE1,
- "Stack size each created thread will use."},
- #endif
--{ "Listen", set_listener, NULL, RSRC_CONF, TAKE1,
-+{ "Listen", set_listener, NULL, RSRC_CONF, TAKE12,
- "A port number or a numeric IP address and a port number"},
- { "SendBufferSize", set_send_buffer_size, NULL, RSRC_CONF, TAKE1,
- "Send buffer size in bytes"},
-@@ -3558,7 +3651,7 @@
- "Name of the config file to be included" },
- { "LogLevel", set_loglevel, NULL, RSRC_CONF, TAKE1,
- "Level of verbosity in error logging" },
--{ "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE1,
-+{ "NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, TAKE12,
- "A numeric IP address:port, or the name of a host" },
- #ifdef _OSD_POSIX
- { "BS2000Account", set_bs2000_account, NULL, RSRC_CONF, TAKE1,
---- apache_1.3.28/src/main/rfc1413.c.orig 2003-02-03 18:13:23.000000000 +0100
-+++ apache_1.3.28/src/main/rfc1413.c 2003-07-19 12:21:30.000000000 +0200
-@@ -82,6 +82,7 @@
- #include "http_log.h" /* for aplog_error */
- #include "rfc1413.h"
- #include "http_main.h" /* set_callback_and_alarm */
-+#include "sa_len.h"
+ typedef struct {
+ unsigned int stamp;
+- unsigned int in_addr;
++ union {
++ struct in_addr in;
++#ifdef INET6
++# ifdef SHORT_UNIQUE_ID
++ ap_uint32_t in6;
++# else
++ struct in6_addr in6;
++# endif
++#endif
++ } addr;
+ unsigned int pid;
+ #ifdef MULTITHREAD
+ unsigned int tid;
+@@ -142,7 +154,7 @@
+ * this shouldn't be a problem till year 2106.
+ */
- /* Local stuff. */
- /* Semi-well-known port */
-@@ -109,12 +110,13 @@
+-static unsigned global_in_addr;
++static struct sockaddr_storage global_addr;
- /* bind_connect - bind both ends of a socket */
- /* Ambarish fix this. Very broken */
--static int get_rfc1413(int sock, const struct sockaddr_in *our_sin,
-- const struct sockaddr_in *rmt_sin,
-+static int get_rfc1413(int sock, const struct sockaddr *our_sin,
-+ const struct sockaddr *rmt_sin,
- char user[RFC1413_USERLEN+1], server_rec *srv)
- {
-- struct sockaddr_in rmt_query_sin, our_query_sin;
-- unsigned int rmt_port, our_port;
-+ struct sockaddr_storage rmt_query_sin, our_query_sin;
-+ unsigned int o_rmt_port, o_our_port; /* original port pair */
-+ unsigned int rmt_port, our_port; /* replied port pair */
- int i;
- char *cp;
- char buffer[RFC1413_MAXDATA + 1];
-@@ -129,16 +131,47 @@
- * addresses from the query socket.
- */
+ #ifdef WIN32
-- our_query_sin = *our_sin;
-- our_query_sin.sin_port = htons(ANY_PORT);
--#ifdef MPE
-- our_query_sin.sin_addr.s_addr = INADDR_ANY;
-+#ifndef SIN6_LEN
-+ memcpy(&our_query_sin, our_sin, SA_LEN(our_sin));
-+ memcpy(&rmt_query_sin, rmt_sin, SA_LEN(rmt_sin));
-+#else
-+ memcpy(&our_query_sin, our_sin, our_sin->sa_len);
-+ memcpy(&rmt_query_sin, rmt_sin, rmt_sin->sa_len);
+@@ -221,7 +233,8 @@
+ #define MAXHOSTNAMELEN 256
#endif
-- rmt_query_sin = *rmt_sin;
-- rmt_query_sin.sin_port = htons(RFC1413_PORT);
-+ switch (our_sin->sa_family) {
-+ case AF_INET:
-+#ifdef MPE
-+ ((struct sockaddr_in *)&our_query_sin)->sin_addr.s_addr = INADDR_ANY; /* XXX: htonl(??) */
-+#endif
-+ ((struct sockaddr_in *)&our_query_sin)->sin_port = htons(ANY_PORT);
-+ o_our_port = ntohs(((struct sockaddr_in *)our_sin)->sin_port);
-+ ((struct sockaddr_in *)&rmt_query_sin)->sin_port = htons(RFC1413_PORT);
-+ o_rmt_port = ntohs(((struct sockaddr_in *)rmt_sin)->sin_port);
-+ break;
+ char str[MAXHOSTNAMELEN + 1];
+- struct hostent *hent;
++ struct addrinfo hints, *res, *res0;
++ int error;
+ #ifndef NO_GETTIMEOFDAY
+ struct timeval tv;
+ #endif
+@@ -232,8 +245,8 @@
+ */
+ unique_id_rec_offset[0] = XtOffsetOf(unique_id_rec, stamp);
+ unique_id_rec_size[0] = sizeof(cur_unique_id->stamp);
+- unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, in_addr);
+- unique_id_rec_size[1] = sizeof(cur_unique_id->in_addr);
++ unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, addr);
++ unique_id_rec_size[1] = sizeof(cur_unique_id->addr);
+ unique_id_rec_offset[2] = XtOffsetOf(unique_id_rec, pid);
+ unique_id_rec_size[2] = sizeof(cur_unique_id->pid);
+ #ifdef MULTITHREAD
+@@ -269,17 +282,44 @@
+ }
+ str[sizeof(str) - 1] = '\0';
+
+- if ((hent = gethostbyname(str)) == NULL) {
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ error = getaddrinfo(str, NULL, &hints, &res0);
++ if (error) {
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
+- "mod_unique_id: unable to gethostbyname(\"%s\")", str);
++ "mod_unique_id: getaddrinfo failed for \"%s\" (%s)", str,
++ gai_strerror(error));
+ exit(1);
+ }
+
+- global_in_addr = ((struct in_addr *) hent->h_addr_list[0])->s_addr;
++ error = 1;
++ for (res = res0; res; res = res->ai_next) {
++ switch (res->ai_family) {
++ case AF_INET:
+#ifdef INET6
-+ case AF_INET6:
-+#ifdef MPE
-+ memcpy(&((struct sockaddr_in6 *)&our_query_sin)->sin6_addr,
-+ &in6addr_any, sizeof(struct in6_addr));
-+#endif
-+ ((struct sockaddr_in6 *)&our_query_sin)->sin6_port = htons(ANY_PORT);
-+ o_our_port = ntohs(((struct sockaddr_in6 *)our_sin)->sin6_port);
-+ ((struct sockaddr_in6 *)&rmt_query_sin)->sin6_port = htons(RFC1413_PORT);
-+ o_rmt_port = ntohs(((struct sockaddr_in6 *)rmt_sin)->sin6_port);
-+ break;
++ case AF_INET6:
+#endif
-+ default:
-+ /* unsupported AF */
-+ return -1;
++ memcpy(&global_addr, res->ai_addr, res->ai_addrlen);
++ error = 0;
++ break;
++ }
++ }
++ freeaddrinfo(res0);
++ if (error) {
++ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
++ "mod_unique_id: no known AF found for \"%s\"", str);
++ exit(1);
+ }
- if (bind(sock, (struct sockaddr *) &our_query_sin,
-- sizeof(struct sockaddr_in)) < 0) {
-+#ifndef SIN6_LEN
-+ SA_LEN((struct sockaddr *) &our_query_sin)
-+#else
-+ our_query_sin.ss_len
-+#endif
-+ ) < 0) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
- "bind: rfc1413: Error binding to local port");
- return -1;
-@@ -149,12 +182,18 @@
- * the service
- */
- if (connect(sock, (struct sockaddr *) &rmt_query_sin,
-- sizeof(struct sockaddr_in)) < 0)
-- return -1;
++ getnameinfo((struct sockaddr *)&global_addr,
+#ifndef SIN6_LEN
-+ SA_LEN((struct sockaddr *) &rmt_query_sin)
++ SA_LEN((struct sockaddr *)&global_addr),
+#else
-+ rmt_query_sin.ss_len
++ global_addr.ss_len,
+#endif
-+ ) < 0) {
-+ return -1;
-+ }
++ str, sizeof(str), NULL, 0, NI_NUMERICHOST);
+ ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, s,
+- "mod_unique_id: using ip addr %s",
+- inet_ntoa(*(struct in_addr *) hent->h_addr_list[0]));
++ "mod_unique_id: using ip addr %s", str);
- /* send the data */
-- buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", ntohs(rmt_sin->sin_port),
-- ntohs(our_sin->sin_port));
-+ buflen = ap_snprintf(buffer, sizeof(buffer), "%u,%u\r\n", o_rmt_port,
-+ o_our_port);
+ /*
+ * If the server is pummelled with restart requests we could possibly end
+@@ -336,7 +376,23 @@
+ "oh no! pids are greater than 32-bits! I'm broken!");
+ }
- /* send query to server. Handle short write. */
- #ifdef CHARSET_EBCDIC
-@@ -219,9 +258,9 @@
- ascii2ebcdic(buffer, buffer, (size_t)i);
- #endif
- if (sscanf(buffer, "%u , %u : USERID :%*[^:]:%512s", &rmt_port, &our_port,
-- user) != 3 || ntohs(rmt_sin->sin_port) != rmt_port
-- || ntohs(our_sin->sin_port) != our_port)
-+ user) != 3 || o_rmt_port != rmt_port || o_our_port != our_port) {
- return -1;
+- cur_unique_id->in_addr = global_in_addr;
++ memset(&cur_unique_id->addr, 0, sizeof(cur_unique_id->addr));
++ switch (global_addr.ss_family) {
++ case AF_INET:
++ cur_unique_id->addr.in = ((struct sockaddr_in *)&global_addr)->sin_addr;
++ break;
++#ifdef INET6
++ case AF_INET6:
++#ifdef SHORT_UNIQUE_ID
++ cur_unique_id->addr.in6 =
++ ((struct sockaddr_in6 *)&global_addr)->sin6_addr.s6_addr32[3];
++#else
++ cur_unique_id->addr.in6 =
++ ((struct sockaddr_in6 *)&global_addr)->sin6_addr;
++#endif
++ break;
++#endif
+ }
/*
- * Strip trailing carriage return. It is part of the
-@@ -243,7 +282,7 @@
-
- result = FROM_UNKNOWN;
-
-- sock = ap_psocket_ex(conn->pool, AF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
-+ sock = ap_psocket(conn->pool, conn->remote_addr.ss_family, SOCK_STREAM, IPPROTO_TCP);
- if (sock < 0) {
- ap_log_error(APLOG_MARK, APLOG_CRIT, srv,
- "socket: rfc1413: error creating socket");
-@@ -256,8 +295,10 @@
- if (ap_setjmp(timebuf) == 0) {
- ap_set_callback_and_alarm(ident_timeout, ap_rfc1413_timeout);
+ * If we use 0 as the initial counter we have a little less protection
+diff -Nur apache_1.3.28.orig/src/support/ab.c apache_1.3.28/src/support/ab.c
+--- apache_1.3.28.orig/src/support/ab.c Sun Jul 6 19:52:27 2003
++++ apache_1.3.28/src/support/ab.c Fri Jul 25 11:01:55 2003
+@@ -158,6 +158,8 @@
+ #include <sys/uio.h>
+ #endif
-- if (get_rfc1413(sock, &conn->local_addr, &conn->remote_addr, user, srv) >= 0)
-+ if (get_rfc1413(sock, (struct sockaddr *)&conn->local_addr,
-+ (struct sockaddr *)&conn->remote_addr, user, srv) >= 0) {
- result = user;
-+ }
- }
- ap_set_callback_and_alarm(NULL, 0);
- ap_pclosesocket(conn->pool, sock);
---- apache_1.3.28/src/modules/proxy/proxy_connect.c.orig 2003-02-03 18:13:26.000000000 +0100
-+++ apache_1.3.28/src/modules/proxy/proxy_connect.c 2003-07-19 12:27:26.000000000 +0200
-@@ -113,14 +113,15 @@
- const char *proxyhost, int proxyport)
- {
- struct sockaddr_in server;
-- struct in_addr destaddr;
-- struct hostent server_hp;
-- const char *host, *err;
-+ struct addrinfo hints, *res, *res0;
-+ const char *hoststr;
-+ const char *portstr = NULL;
- char *p;
- int port, sock;
- char buffer[HUGE_STRING_LEN];
-- int nbytes, i, j;
-+ int nbytes, i;
- fd_set fds;
-+ int error;
++#include "sa_len.h"
++
+ #endif /* NO_APACHE_INCLUDES */
- void *sconf = r->server->module_config;
- proxy_server_conf *conf =
-@@ -128,27 +129,59 @@
- struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
+ #ifdef USE_SSL
+@@ -246,7 +248,7 @@
+ char servername[1024]; /* name that server reports */
+ char hostname[1024]; /* host name */
+ char proxyhost[1024]; /* proxy host name */
+-int proxyport = 0; /* proxy port */
++char *proxyport = NULL; /* proxy port */
+ int isproxy = 0;
+ char path[1024]; /* path name */
+ char postfile[1024]; /* name of file containing post data */
+@@ -262,7 +264,7 @@
+ auth[1024], /* optional (basic/uuencoded)
+ * authentification */
+ hdrs[4096]; /* optional arbitrary headers */
+-int port = 80; /* port number */
++char *port = "80"; /* port number */
- memset(&server, '\0', sizeof(server));
-+#ifdef HAVE_SOCKADDR_LEN
-+ server.sin_len = sizeof(server);
-+#endif
- server.sin_family = AF_INET;
+ int use_html = 0; /* use html in the report */
+ char *tablestring;
+@@ -299,7 +301,7 @@
+ struct data *stats; /* date for each request */
- /* Break the URL into host:port pairs */
+ fd_set readbits, writebits; /* bits for select */
+-struct sockaddr_in server; /* server addr structure */
++struct sockaddr_storage server; /* server addr structure */
-- host = url;
-+ hoststr = url;
- p = strchr(url, ':');
-- if (p == NULL)
-- port = DEFAULT_HTTPS_PORT;
-- else {
-- port = atoi(p + 1);
-+ if (p == NULL) {
-+ char pbuf[32];
-+ ap_snprintf(pbuf, sizeof(pbuf), "%d", DEFAULT_HTTPS_PORT);
-+ portstr = pbuf;
-+ } else {
-+ portstr = p + 1;
- *p = '\0';
- }
-+ port = atoi(portstr);
-+
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_protocol = IPPROTO_TCP;
-+ error = getaddrinfo(hoststr, portstr, &hints, &res0);
-+ if (error) {
-+ return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
-+ gai_strerror(error)); /* give up */
-+ }
+ #ifndef BEOS
+ #define ab_close(s) close(s)
+@@ -525,7 +527,7 @@
+ printf("\r \r");
+ printf("Server Software: %s\n", servername);
+ printf("Server Hostname: %s\n", hostname);
+- printf("Server Port: %d\n", port);
++ printf("Server Port: %s\n", port);
+ printf("\n");
+ printf("Document Path: %s\n", path);
+ printf("Document Length: %d bytes\n", doclen);
+@@ -878,7 +880,7 @@
+ c->cbx = 0;
+ c->gotheader = 0;
- /* check if ProxyBlock directive on this host */
-- destaddr.s_addr = ap_inet_addr(host);
-- for (i = 0; i < conf->noproxies->nelts; i++) {
-- if ((npent[i].name != NULL && strstr(host, npent[i].name) != NULL)
-- || destaddr.s_addr == npent[i].addr.s_addr
-- || npent[i].name[0] == '*')
-+ for (res = res0; res; res = res = res->ai_next) {
-+ struct sockaddr_in *sin;
-+ int fail;
-+
-+ fail = 0;
-+ for (i = 0; i < conf->noproxies->nelts; i++) {
-+ if (npent[i].name != NULL && strstr(hoststr, npent[i].name))
-+ fail++;
-+ if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
-+ fail++;
-+ switch (res->ai_family) {
-+ case AF_INET:
-+ sin = (struct sockaddr_in *)res->ai_addr;
-+ if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
-+ fail++;
-+ break;
-+ }
-+ }
-+ if (fail) {
-+ freeaddrinfo(res0);
- return ap_proxyerror(r, HTTP_FORBIDDEN,
- "Connect to remote machine blocked");
-+ }
- }
+- c->fd = socket(AF_INET, SOCK_STREAM, 0);
++ c->fd = socket(server.ss_family, SOCK_STREAM, 0);
+ if (c->fd < 0) {
+ what = "SOCKET";
+ goto _bad;
+@@ -895,7 +897,12 @@
- /* Check if it is an allowed port */
-@@ -159,34 +192,41 @@
- case DEFAULT_SNEWS_PORT:
- break;
- default:
-+ freeaddrinfo(res0);
- return HTTP_FORBIDDEN;
- }
+ again:
+ gettimeofday(&c->start, 0);
+- if (connect(c->fd, (struct sockaddr *) & server, sizeof(server)) < 0) {
++#ifndef SIN6_LEN
++ if (connect(c->fd, (struct sockaddr *) & server, SA_LEN((struct sockaddr*)&server)) < 0)
++#else
++ if (connect(c->fd, (struct sockaddr *) & server, server.ss_len) < 0)
++#endif
++ {
+ if (errno != EINPROGRESS) {
+ what = "CONNECT";
+ goto _bad;
+@@ -1189,7 +1196,7 @@
+ struct timeval timeout, now;
+ fd_set sel_read, sel_except, sel_write;
+ long i;
+- int connectport;
++ char * connectport;
+ char * connecthost;
+ char * url_on_request;
+
+@@ -1232,17 +1239,21 @@
}
-- else if (!allowed_port(conf, port))
-+ else if (!allowed_port(conf, port)) {
-+ freeaddrinfo(res0);
- return HTTP_FORBIDDEN;
--
-+ }
- if (proxyhost) {
-+ char pbuf[10];
-+
-+ freeaddrinfo(res0);
-+
-+ ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_protocol = IPPROTO_TCP;
-+ error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
-+ if (error)
-+ return HTTP_INTERNAL_SERVER_ERROR; /* XXX */
+ {
+ /* get server information */
+- struct hostent *he;
+- he = gethostbyname(connecthost);
+- if (!he) {
+- char theerror[1024];
+- ap_snprintf(theerror, sizeof(theerror),
+- "Bad hostname: %s\n", connecthost);
+- err(theerror);
+- }
+- server.sin_family = he->h_addrtype;
+- server.sin_port = htons(connectport);
+- server.sin_addr.s_addr = ((unsigned long *) (he->h_addr_list[0]))[0];
++ struct addrinfo hints, *res;
++ int error;
+
- ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
- "CONNECT to remote proxy %s on port %d", proxyhost, proxyport);
- }
- else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,
-- "CONNECT to %s on port %d", host, port);
-+ "CONNECT to %s on port %d", hoststr, port);
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ hints.ai_socktype = SOCK_STREAM;
++ error = getaddrinfo(connecthost, connectport, &hints, &res);
++ if (error) {
++ char *theerror=malloc(strlen(connecthost)+16);
++ sprintf(theerror, "Bad hostname: %s\n", connecthost);
++ err(theerror);
++ free(theerror);
++ }
++ memcpy(&server, res->ai_addr, res->ai_addrlen);
++ freeaddrinfo(res);
}
-+ sock = i = -1;
-+ for (res = res0; res; res = res->ai_next) {
-+ sock = ap_psocket(r->pool, res->ai_family, res->ai_socktype, res->ai_protocol);
-+ if (sock == -1)
-+ continue;
-
-- /* Nasty cast to work around broken terniary expressions on MSVC */
-- server.sin_port = htons((unsigned short)(proxyport ? proxyport : port));
-- err = ap_proxy_host2addr(proxyhost ? proxyhost : host, &server_hp);
--
-- if (err != NULL)
-- return ap_proxyerror(r,
-- proxyhost ? HTTP_BAD_GATEWAY : HTTP_INTERNAL_SERVER_ERROR, err);
--
-- sock = ap_psocket_ex(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
-- if (sock == -1) {
-- ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "proxy: error creating socket");
-- return HTTP_INTERNAL_SERVER_ERROR;
-- }
- #ifdef CHECK_FD_SETSIZE
- if (sock >= FD_SETSIZE) {
-@@ -196,19 +236,15 @@
- "found, you probably need to rebuild Apache with a "
- "larger FD_SETSIZE", sock, FD_SETSIZE);
- ap_pclosesocket(r->pool, sock);
-- return HTTP_INTERNAL_SERVER_ERROR;
-+ continue;
+ con = malloc(concurrency * sizeof(struct connection));
+@@ -1430,7 +1441,7 @@
+ if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
+ purl += 8;
+ ssl = 1;
+- port = 443;
++ port = "443";
}
+ #else
+ if (strlen(purl) > 8 && strncmp(purl, "https://", 8) == 0) {
+@@ -1451,15 +1462,15 @@
+ *cp = '\0';
+ strcpy(hostname, h);
+ if (p != NULL)
+- port = atoi(p);
++ port = strdup(p);
+
+ if ((
+ #ifdef USE_SSL
+- (ssl != 0) && (port != 443)) || ((ssl == 0) &&
++ (ssl != 0) && (strcmp(port, "443"))) || ((ssl == 0) &&
#endif
+- (port != 80)))
++ (strcmp(port, "80"))))
+ {
+- ap_snprintf(colonport,sizeof(colonport),":%d",port);
++ ap_snprintf(colonport,sizeof(colonport),":%s",port);
+ } else {
+ colonport[0] = '\0';
+ }
+@@ -1622,7 +1633,7 @@
+ if ((p = strchr(optarg, ':'))) {
+ *p = '\0';
+ p++;
+- proxyport = atoi(p);
++ proxyport = strdup(p);
+ };
+ strcpy(proxyhost, optarg);
+ isproxy = 1;
+@@ -1705,3 +1716,7 @@
-- j = 0;
-- while (server_hp.h_addr_list[j] != NULL) {
-- memcpy(&server.sin_addr, server_hp.h_addr_list[j],
-- sizeof(struct in_addr));
-- i = ap_proxy_doconnect(sock, &server, r);
-+ i = ap_proxy_doconnect(sock, res->ai_addr, r);
- if (i == 0)
- break;
-- j++;
- }
-+ freeaddrinfo(res0);
- if (i == -1) {
- ap_pclosesocket(r->pool, sock);
- return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, ap_pstrcat(r->pool,
---- apache_1.3.28/src/modules/proxy/proxy_ftp.c.orig 2003-02-03 18:13:26.000000000 +0100
-+++ apache_1.3.28/src/modules/proxy/proxy_ftp.c 2003-07-19 12:34:34.000000000 +0200
-@@ -62,6 +62,7 @@
- #include "http_main.h"
- #include "http_log.h"
- #include "http_core.h"
+ exit(0);
+ }
++
++#ifdef NEED_GETADDRINFO
++#include "../main/getaddrinfo.c"
++#endif
+diff -Nur apache_1.3.28.orig/src/support/logresolve.c apache_1.3.28/src/support/logresolve.c
+--- apache_1.3.28.orig/src/support/logresolve.c Wed May 23 00:52:21 2001
++++ apache_1.3.28/src/support/logresolve.c Fri Jul 25 11:01:55 2003
+@@ -54,7 +54,9 @@
+ #endif /* BEOS */
+ #endif /* !MPE && !WIN32*/
+
+-static void cgethost(struct in_addr ipnum, char *string, int check);
+#include "sa_len.h"
++
++static void cgethost(struct sockaddr *sa, char *string, int check);
+ static int getline(char *s, int n);
+ static void stats(FILE *output);
- #define AUTODETECT_PWD
+@@ -91,7 +93,7 @@
+ */
-@@ -555,8 +556,10 @@
- const char *err;
- int port, i, j, len, rc, nocache = 0;
- int csd = 0, sock = -1, dsock = -1;
-- struct sockaddr_in server;
-- struct hostent server_hp;
-+ struct sockaddr_storage server;
-+ struct addrinfo hints, *res, *res0;
-+ char portbuf[10];
-+ int error;
- struct in_addr destaddr;
- table *resp_hdrs;
- BUFF *ctrl = NULL;
-@@ -577,11 +580,18 @@
- unsigned int presult, h0, h1, h2, h3, p0, p1;
- unsigned int paddr;
- unsigned short pport;
-- struct sockaddr_in data_addr;
-+ struct sockaddr_storage data_addr;
-+ struct sockaddr_in *sin;
- int pasvmode = 0;
- char pasv[64];
- char *pstr;
+ struct nsrec {
+- struct in_addr ipnum;
++ struct sockaddr_storage addr;
+ char *hostname;
+ int noname;
+ struct nsrec *next;
+@@ -122,17 +124,48 @@
+ * IP numbers with their IP number as hostname, setting noname flag
+ */
-+/* stuff for LPSV/EPSV */
-+ unsigned int paf, holen, ho[16], polen, po[2];
+-static void cgethost (struct in_addr ipnum, char *string, int check)
++static void cgethost (struct sockaddr *sa, char *string, int check)
+ {
++ ap_uint32_t hashval;
++ struct sockaddr_in *sin;
++#ifdef INET6
+ struct sockaddr_in6 *sin6;
-+ int lpsvmode = 0;
-+ char *cmd;
-+
- /* stuff for responses */
- char resp[MAX_STRING_LEN];
- char *size = NULL;
-@@ -658,51 +668,53 @@
- if (parms != NULL)
- *(parms++) = '\0';
-
-- memset(&server, 0, sizeof(struct sockaddr_in));
-- server.sin_family = AF_INET;
-- server.sin_port = htons((unsigned short)port);
-- err = ap_proxy_host2addr(host, &server_hp);
-- if (err != NULL)
-- return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
--
-- sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
-- if (sock == -1) {
-- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
-- "proxy: error creating socket");
-- return HTTP_INTERNAL_SERVER_ERROR;
-- }
-+ ap_snprintf(portbuf, sizeof(portbuf), "%d", port);
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ error = getaddrinfo(host, portbuf, &hints, &res0);
-+ if (error) {
-+ return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
-+ gai_strerror(error));
-+ }
++#endif
+ struct nsrec **current, *new;
+- struct hostent *hostdata;
+ char *name;
++ char hostnamebuf[MAXHOSTNAMELEN];
+
-+ i = -1;
-+ for (res = res0; res; res = res->ai_next) {
-+ sock = ap_psocket(p, res->ai_family, res->ai_socktype,
-+ res->ai_protocol);
-+ if (sock == -1)
-+ continue;
-
- #if !defined(TPF) && !defined(BEOS)
-- if (conf->recv_buffer_size > 0
-- && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
-- (const char *)&conf->recv_buffer_size, sizeof(int))
-- == -1) {
-- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
-- "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
-- }
-+ if (conf->recv_buffer_size > 0
-+ && setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
-+ (const char *)&conf->recv_buffer_size, sizeof(int))
-+ == -1) {
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
-+ "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
-+ }
- #endif
++ switch (sa->sa_family) {
++ case AF_INET:
++ hashval = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
++ break;
++#ifdef INET6
++ case AF_INET6:
++ hashval = *(ap_uint32_t *)&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[12];
++ break;
++#endif
++ default:
++ hashval = 0;
++ break;
++ }
++
++ current = &nscache[((hashval + (hashval >> 8) +
++ (hashval >> 16) + (hashval >> 24)) % BUCKETS)];
-- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
-- sizeof(one)) == -1) {
-+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&one,
-+ sizeof(one)) == -1) {
- #ifndef _OSD_POSIX /* BS2000 has this option "always on" */
-- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
-- "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
-- ap_pclosesocket(p, sock);
-- return HTTP_INTERNAL_SERVER_ERROR;
-+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
-+ "proxy: error setting reuseaddr option: setsockopt(SO_REUSEADDR)");
-+ ap_pclosesocket(p, sock);
-+ freeaddrinfo(res0);
-+ return HTTP_INTERNAL_SERVER_ERROR;
- #endif /* _OSD_POSIX */
- }
+- current = &nscache[((ipnum.s_addr + (ipnum.s_addr >> 8) +
+- (ipnum.s_addr >> 16) + (ipnum.s_addr >> 24)) % BUCKETS)];
++ while (*current) {
++#ifndef SIN6_LEN
++ if (SA_LEN(sa) == SA_LEN((struct sockaddr *)&(*current)->addr)
++ && memcmp(sa, &(*current)->addr, SA_LEN(sa)) == 0)
++#else
++ if (sa->sa_len == (*current)->addr.ss_len
++ && memcmp(sa, &(*current)->addr, sa->sa_len) == 0)
++#endif
++ {
++ break;
++ }
--#ifdef SINIX_D_RESOLVER_BUG
-- {
-- struct in_addr *ip_addr = (struct in_addr *)*server_hp.h_addr_list;
--
-- for (; ip_addr->s_addr != 0; ++ip_addr) {
-- memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
-- i = ap_proxy_doconnect(sock, &server, r);
-- if (i == 0)
-- break;
-- }
-- }
-+ i = ap_proxy_doconnect(sock, res->ai_addr, r);
-+ if (i == 0) {
-+ memcpy(&server, res->ai_addr, res->ai_addrlen);
-+ break;
-+ }
-+ ap_pclosesocket(p, sock);
-+ }
-+ freeaddrinfo(res0);
-+
- #else
- j = 0;
- while (server_hp.h_addr_list[j] != NULL) {
-@@ -944,7 +956,7 @@
- }
+- while (*current != NULL && ipnum.s_addr != (*current)->ipnum.s_addr)
+ current = &(*current)->next;
++ }
- /* try to set up PASV data connection first */
-- dsock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
-+ dsock = ap_psocket(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP);
- if (dsock == -1) {
- return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
- ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
-@@ -961,11 +973,22 @@
- }
- #endif
+ if (*current == NULL) {
+ cachesize++;
+@@ -145,45 +178,55 @@
+ *current = new;
+ new->next = NULL;
-- ap_bputs("PASV" CRLF, ctrl);
-+lpsvagain:
-+ if (server.ss_family == AF_INET)
-+ cmd = "PASV";
-+ else if (lpsvmode)
-+ cmd = "LPSV";
-+ else
-+ cmd = "EPSV";
-+ ap_bputs(cmd, ctrl);
-+ ap_bputs(CRLF, ctrl);
- ap_bflush(ctrl);
-+ Explain0("FTP: passive command issued");
- ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: PASV command issued");
--/* possible results: 227, 421, 500, 501, 502, 530 */
-+/* possible results: 227, 228, 229, 421, 500, 501, 502, 530 */
- /* 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2). */
-+ /* 228 Entering Long Passive Mode (...). */
-+ /* 229 Entering Extended Passive Mode (...). */
- /* 421 Service not available, closing control connection. */
- /* 500 Syntax error, command unrecognized. */
- /* 501 Syntax error in parameters or arguments. */
-@@ -976,7 +999,7 @@
- if (i == -1 || i == 421) {
- return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
- ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
-- "proxy: PASV: control connection is toast"));
-+ ap_psprintf(p, "proxy: %s: control connection is toast", cmd)));
- }
- else {
- pasv[i - 1] = '\0';
-@@ -1004,10 +1027,14 @@
- pport = (p1 << 8) + p0;
- ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "FTP: contacting host %d.%d.%d.%d:%d",
- h3, h2, h1, h0, pport);
-- data_addr.sin_family = AF_INET;
-- data_addr.sin_addr.s_addr = htonl(paddr);
-- data_addr.sin_port = htons(pport);
-- i = ap_proxy_doconnect(dsock, &data_addr, r);
-+ sin = (struct sockaddr_in *)&data_addr;
-+ sin->sin_family = AF_INET;
-+#ifdef SIN6_LEN
-+ sin->sin_len = sizeof(*sin);
+- new->ipnum = ipnum;
++#ifndef SIN6_LEN
++ memcpy(&new->addr, sa, SA_LEN(sa));
++#else
++ memcpy(&new->addr, sa, sa->sa_len);
+#endif
-+ sin->sin_addr.s_addr = htonl(paddr);
-+ sin->sin_port = htons(pport);
-+ i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
- if (i == -1) {
- return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
-@@ -1017,6 +1044,64 @@
- strerror(errno), NULL)));
- }
- pasvmode = 1;
-+ } else if (presult == 228 && pstr != NULL
-+ && sscanf(pstr,
-+"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u",
-+ &paf, &holen, &ho[0], &ho[1], &ho[2], &ho[3],
-+ &ho[4], &ho[5], &ho[6], &ho[7], &ho[8], &ho[9], &ho[10], &ho[11],
-+ &ho[12], &ho[13], &ho[14], &ho[15], &polen, &po[0], &po[1]) == 21
-+ && paf == 6 && holen == 16 && polen == 2) {
-+ int i;
-+ sin6 = (struct sockaddr_in6 *)&data_addr;
-+ sin6->sin6_family = AF_INET6;
-+#ifdef SIN6_LEN
-+ sin6->sin6_len = sizeof(*sin6);
+- hostdata = gethostbyaddr((const char *) &ipnum, sizeof(struct in_addr),
+- AF_INET);
+- if (hostdata == NULL) {
+- if (h_errno > MAX_ERR)
+- errors[UNKNOWN_ERR]++;
+- else
+- errors[h_errno]++;
+- new->noname = h_errno;
+- name = strdup(inet_ntoa(ipnum));
+- }
+- else {
+- new->noname = 0;
+- name = strdup(hostdata->h_name);
+- if (check) {
+- if (name == NULL) {
+- perror("strdup");
+- fprintf(stderr, "Insufficient memory\n");
+- exit(1);
+- }
+- hostdata = gethostbyname(name);
+- if (hostdata != NULL) {
+- char **hptr;
+-
+- for (hptr = hostdata->h_addr_list; *hptr != NULL; hptr++)
+- if (((struct in_addr *) (*hptr))->s_addr == ipnum.s_addr)
+- break;
+- if (*hptr == NULL)
+- hostdata = NULL;
+- }
+- if (hostdata == NULL) {
+- fprintf(stderr, "Bad host: %s != %s\n", name,
+- inet_ntoa(ipnum));
+- new->noname = NO_REVERSE;
+- free(name);
+- name = strdup(inet_ntoa(ipnum));
+- errors[NO_REVERSE]++;
++ new->noname = getnameinfo(sa,
++#ifndef SIN6_LEN
++ SA_LEN(sa),
++#else
++ sa->sa_len,
+#endif
-+ for (i = 0; i < 16; i++)
-+ sin6->sin6_addr.s6_addr[i] = ho[i] & 0xff;
-+ sin6->sin6_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff));
-+ i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
-+
-+ if (i == -1) {
-+ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
-+ ap_proxyerror(r, HTTP_BAD_GATEWAY,
-+ ap_pstrcat(r->pool,
-+ "Could not connect to remote machine: ",
-+ strerror(errno), NULL)));
-+ }
-+ pasvmode = 1;
-+ } else if (presult == 229 && pstr != NULL
-+ && pstr[0] == pstr[1] && pstr[0] == pstr[2]
-+ && pstr[0] == pstr[strlen(pstr) - 1]) {
-+ /* expect "|||port|" */
++ hostnamebuf, sizeof(hostnamebuf), NULL, 0, 0);
++ name = strdup(hostnamebuf);
++ if (check) {
++ struct addrinfo hints, *res;
++ int error;
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ error = getaddrinfo(hostnamebuf, NULL, &hints, &res);
++ if (!error) {
++ while (res) {
+#ifndef SIN6_LEN
-+ memcpy(&data_addr, &server, SA_LEN((struct sockaddr *)&server));
++ if (SA_LEN(sa) == res->ai_addrlen
++ && memcmp(sa, res->ai_addr, SA_LEN(sa)) == 0)
+#else
-+ memcpy(&data_addr, &server, server.ss_len);
++ if (sa->sa_len == res->ai_addrlen
++ && memcmp(sa, res->ai_addr, sa->sa_len) == 0)
+#endif
-+ switch (data_addr.ss_family) {
-+ case AF_INET:
-+ sin = (struct sockaddr_in *)&data_addr;
-+ sin->sin_port = htons(atoi(pstr + 3));
-+ break;
-+ case AF_INET6:
-+ sin6 = (struct sockaddr_in6 *)&data_addr;
-+ sin6->sin6_port = htons(atoi(pstr + 3));
-+ break;
-+ }
-+ i = ap_proxy_doconnect(dsock, (struct sockaddr *)&data_addr, r);
-+
-+ if (i == -1) {
-+ return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
-+ ap_proxyerror(r, HTTP_BAD_GATEWAY,
-+ ap_pstrcat(r->pool,
-+ "Could not connect to remote machine: ",
-+ strerror(errno), NULL)));
++ {
++ break;
++ }
++ res = res->ai_next;
+ }
++ if (!res)
++ error++;
+ }
-+ pasvmode = 1;
-+ } else if (!lpsvmode && strcmp(cmd, "EPSV") == 0) {
-+ lpsvmode = 1;
-+ goto lpsvagain;
- }
- else {
- ap_pclosesocket(p, dsock); /* and try the regular way */
-@@ -1025,14 +1110,14 @@
- }
-
- if (!pasvmode) { /* set up data connection */
-- clen = sizeof(struct sockaddr_in);
-+ clen = sizeof(server);
- if (getsockname(sock, (struct sockaddr *)&server, &clen) < 0) {
- return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
- ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
- "proxy: error getting socket address"));
- }
++ if (error) {
++ getnameinfo(sa,
++#ifndef SIN6_LEN
++ SA_LEN(sa),
++#else
++ sa->sa_len,
++#endif
++ hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
++ fprintf(stderr, "Bad host: %s != %s\n", name, hostnamebuf);
++ new->noname = NO_REVERSE;
++ free(name);
++ name = strdup(hostnamebuf);
+ }
+ }
+ new->hostname = name;
+@@ -211,6 +254,7 @@
+ char *ipstring;
+ struct nsrec *current;
+ char *errstring[MAX_ERR + 3];
++ char hostnamebuf[MAXHOSTNAMELEN];
-- dsock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
-+ dsock = ap_psocket(p, server.ss_family, SOCK_STREAM, IPPROTO_TCP);
- if (dsock == -1) {
- return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
- ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
-@@ -1048,13 +1133,28 @@
- #endif /* _OSD_POSIX */
- }
+ for (i = 0; i < MAX_ERR + 3; i++)
+ errstring[i] = "Unknown error";
+@@ -242,7 +286,14 @@
-- if (bind(dsock, (struct sockaddr *)&server,
-- sizeof(struct sockaddr_in)) == -1) {
-+#ifndef SIN6_LEN
-+ if (bind(dsock, (struct sockaddr *)&server, SA_LEN((struct sockaddr *)&server)) == -1)
-+#else
-+ if (bind(dsock, (struct sockaddr *)&server, server.ss_len) == -1)
-+#endif
-+ {
-+ char hostnamebuf[MAXHOSTNAMELEN], portnamebuf[MAXHOSTNAMELEN];
-+
-+ getnameinfo((struct sockaddr *)&server,
+ for (i = 0; i < BUCKETS; i++)
+ for (current = nscache[i]; current != NULL; current = current->next) {
+- ipstring = inet_ntoa(current->ipnum);
++ getnameinfo((struct sockaddr *)¤t->addr,
+#ifndef SIN6_LEN
-+ SA_LEN((struct sockaddr *)&server),
++ SA_LEN((struct sockaddr *)¤t->addr),
+#else
-+ server.ss_len,
++ current->addr.ss_len,
+#endif
-+ hostnamebuf, sizeof(hostnamebuf),
-+ portnamebuf, sizeof(portnamebuf),
-+ NI_NUMERICHOST | NI_NUMERICSERV);
-
- return ftp_cleanup_and_return(r, ctrl, data, sock, dsock,
- ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
-- ap_psprintf(p, "proxy: error binding to ftp data socket %s:%d",
-- inet_ntoa(server.sin_addr), server.sin_port)));
-+ ap_psprintf(p, "proxy: error binding to ftp data socket %s:%s",
-+ hostnamebuf, portnamebuf)));
- }
- listen(dsock, 2); /* only need a short queue */
- }
-@@ -1308,7 +1408,7 @@
++ hostnamebuf, sizeof(hostnamebuf), NULL, 0, NI_NUMERICHOST);
++ ipstring = hostnamebuf;
+ if (current->noname == 0)
+ fprintf(output, " %3d %15s - %s\n", i, ipstring,
+ current->hostname);
+@@ -276,9 +327,10 @@
- if (!pasvmode) { /* wait for connection */
- ap_hard_timeout("proxy ftp data connect", r);
-- clen = sizeof(struct sockaddr_in);
-+ clen = sizeof(server);
- do
- csd = accept(dsock, (struct sockaddr *)&server, &clen);
- while (csd == -1 && errno == EINTR);
---- apache_1.3.28/src/modules/proxy/proxy_http.c.orig 2003-07-19 12:04:20.000000000 +0200
-+++ apache_1.3.28/src/modules/proxy/proxy_http.c 2003-07-19 22:15:38.000000000 +0200
-@@ -156,9 +156,8 @@
- table *req_hdrs, *resp_hdrs;
- array_header *reqhdrs_arr;
- table_entry *reqhdrs_elts;
-- struct sockaddr_in server;
-- struct in_addr destaddr;
-- struct hostent server_hp;
-+ struct addrinfo hints, *res, *res0;
+ int main (int argc, char *argv[])
+ {
+- struct in_addr ipnum;
+ char *bar, hoststring[MAXDNAME + 1], line[MAXLINE], *statfile;
+ int i, check;
++ struct addrinfo hints, *res;
+ int error;
- BUFF *f;
- char buffer[HUGE_STRING_LEN];
- char portstr[32];
-@@ -184,9 +183,6 @@
- if (conf->cache.root == NULL)
- nocache = 1;
-
-- memset(&server, '\0', sizeof(server));
-- server.sin_family = AF_INET;
--
- /* We break the URL into host, port, path-search */
- urlptr = strstr(url, "://");
-@@ -194,6 +190,8 @@
- return HTTP_BAD_REQUEST;
- urlptr += 3;
- destport = DEFAULT_HTTP_PORT;
-+ ap_snprintf(portstr, sizeof(portstr), "%d", DEFAULT_HTTP_PORT);
-+ destportstr = portstr;
- #ifdef EAPI
- ap_hook_use("ap::mod_proxy::http::handler::set_destport",
- AP_HOOK_SIG2(int,ptr),
-@@ -212,7 +210,20 @@
- urlptr = strp;
- desthost = q;
- }
--
-+ if (*desthost == '['){
-+ char *u = strrchr(desthost+1, ']');
-+ if (u){
-+ desthost++;
-+ *u = '\0';
-+ if (*(u+1) == ':'){ /* [host]:xx */
-+ strp2 = u+1;
-+ } else if (*(u+1) == '\0'){ /* [host] */
-+ strp2 = NULL;
-+ } else
-+ return HTTP_BAD_REQUEST;
-+ } else
-+ return HTTP_BAD_REQUEST;
-+ } else
- strp2 = strchr(desthost, ':');
- if (strp2 != NULL) {
- *(strp2++) = '\0';
-@@ -223,45 +234,71 @@
- }
+ #ifdef WIN32
+ WSADATA wsaData;
+@@ -322,8 +374,10 @@
+ bar = strchr(line, ' ');
+ if (bar != NULL)
+ *bar = '\0';
+- ipnum.s_addr = inet_addr(line);
+- if (ipnum.s_addr == 0xffffffffu) {
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = PF_UNSPEC;
++ error = getaddrinfo(line, NULL, &hints, &res);
++ if (error) {
+ if (bar != NULL)
+ *bar = ' ';
+ puts(line);
+@@ -333,11 +387,12 @@
- /* check if ProxyBlock directive on this host */
-- destaddr.s_addr = ap_inet_addr(desthost);
-- for (i = 0; i < conf->noproxies->nelts; i++) {
-- if (destaddr.s_addr == npent[i].addr.s_addr ||
-- (npent[i].name != NULL &&
-- (npent[i].name[0] == '*' || strstr(desthost, npent[i].name) != NULL)))
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_protocol = IPPROTO_TCP;
-+ error = getaddrinfo(desthost, destportstr, &hints, &res0);
-+ if (error) {
-+ return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
-+ gai_strerror(error)); /* give up */
-+ }
-+
-+ /* check if ProxyBlock directive on this host */
-+ for (res = res0; res; res = res->ai_next) {
-+ struct sockaddr_in *sin;
-+ #ifdef INET6
-+ struct sockaddr_in6 *sin6;
-+ #endif
-+ int fail;
-+
-+ fail = 0;
-+ for (i = 0; i < conf->noproxies->nelts; i++) {
-+ if (npent[i].name != NULL && strstr(desthost, npent[i].name))
-+ fail++;
-+ if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
-+ fail++;
-+ switch (res->ai_family) {
-+ case AF_INET:
-+ sin = (struct sockaddr_in *)res->ai_addr;
-+ if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
-+ fail++;
-+ break;
-+ }
-+ }
-+ if (fail) {
-+ freeaddrinfo(res0);
- return ap_proxyerror(r, HTTP_FORBIDDEN,
-- "Connect to remote machine blocked");
-+ "Connect to remote machine blocked");
-+ }
- }
+ resolves++;
-+
- if (proxyhost != NULL) {
-- server.sin_port = htons((unsigned short)proxyport);
-- err = ap_proxy_host2addr(proxyhost, &server_hp);
-- if (err != NULL)
-+ char pbuf[10];
-+
-+ freeaddrinfo(res0);
-+ ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
-+ memset(&hints, 0, sizeof(hints));
-+ hints.ai_family = PF_UNSPEC;
-+ hints.ai_socktype = SOCK_STREAM;
-+ hints.ai_protocol = IPPROTO_TCP;
-+ error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
-+ if (error)
- return DECLINED; /* try another */
- #ifdef EAPI
- peer = ap_psprintf(p, "%s:%u", proxyhost, proxyport);
- #endif
+- cgethost(ipnum, hoststring, check);
++ cgethost(res->ai_addr, hoststring, check);
+ if (bar != NULL)
+ printf("%s %s\n", hoststring, bar + 1);
+ else
+ puts(hoststring);
++ freeaddrinfo(res);
}
-- else {
-- server.sin_port = htons((unsigned short)destport);
-- err = ap_proxy_host2addr(desthost, &server_hp);
-- if (err != NULL)
-- return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR, err);
--#ifdef EAPI
-- peer = ap_psprintf(p, "%s:%u", desthost, destport);
--#endif
-- }
+ #ifdef WIN32
+@@ -358,3 +413,11 @@
-- /*
-- * we have worked out who exactly we are going to connect to, now make
-- * that connection...
-- */
-- sock = ap_psocket_ex(p, PF_INET, SOCK_STREAM, IPPROTO_TCP, 1);
-- if (sock == -1) {
-- ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
-- "proxy: error creating socket");
-- return HTTP_INTERNAL_SERVER_ERROR;
-- }
-+ sock = i = -1;
-+ for (res = res0; res; res = res->ai_next) {
-+ sock = ap_psocket(p, res->ai_family, res->ai_socktype,
-+ res->ai_protocol);
-+ if (sock < 0)
-+ continue;
+ return (0);
+ }
+
++#ifdef NEED_GETADDRINFO
++#include "../main/getaddrinfo.c"
++#endif
++
++#ifdef NEED_GETNAMEINFO
++#include "../main/getnameinfo.c"
++#endif
+--- apache_1.3.28/src/modules/standard/mod_usertrack.c.orig Mon Feb 3 18:13:30 2003
++++ apache_1.3.28/src/modules/standard/mod_usertrack.c Fri Jul 25 13:13:43 2003
+@@ -162,7 +162,7 @@
+ long reqtime = (long) r->request_time;
+ long clocktime;
+
+- unsigned long ipaddr = ntohl(r->connection->remote_addr.sin_addr.s_addr);
++ unsigned long ipaddr = ntohl(((struct sockaddr_in*)&r->connection->remote_addr)->sin_addr.s_addr);
+ const char *rname = ap_get_remote_host(r->connection, r->per_dir_config,
+ REMOTE_NAME);
+ dcfg = ap_get_module_config(r->per_dir_config, &usertrack_module);
+--- apache_1.3.31/src/modules/standard/mod_rewrite.c.orig Wed May 12 14:57:09 2004
++++ apache_1.3.31/src/modules/standard/mod_rewrite.c Wed May 12 15:40:04 2004
+@@ -48,6 +48,7 @@
+
+
+ #include "mod_rewrite.h"
++#include "sa_len.h"
- #if !defined(TPF) && !defined(BEOS)
- if (conf->recv_buffer_size) {
-@@ -274,28 +311,12 @@
- }
- #endif
-
--#ifdef SINIX_D_RESOLVER_BUG
-- {
-- struct in_addr *ip_addr = (struct in_addr *)*server_hp.h_addr_list;
--
-- for (; ip_addr->s_addr != 0; ++ip_addr) {
-- memcpy(&server.sin_addr, ip_addr, sizeof(struct in_addr));
-- i = ap_proxy_doconnect(sock, &server, r);
-- if (i == 0)
-- break;
-- }
-- }
--#else
-- j = 0;
-- while (server_hp.h_addr_list[j] != NULL) {
-- memcpy(&server.sin_addr, server_hp.h_addr_list[j],
-- sizeof(struct in_addr));
-- i = ap_proxy_doconnect(sock, &server, r);
-+ i = ap_proxy_doconnect(sock, res->ai_addr, r);
- if (i == 0)
- break;
-- j++;
-+ ap_pclosesocket(p, sock);
+ #ifndef NO_WRITEV
+ #ifndef NETWARE
+@@ -3651,8 +3652,19 @@
+ result = r->connection->remote_ip;
}
--#endif
-+ freeaddrinfo(res0);
- if (i == -1) {
- if (proxyhost != NULL)
- return DECLINED; /* try again another way */
-@@ -597,17 +618,30 @@
- ap_table_set(resp_hdrs, "Content-Location", proxy_location_reverse_map(r, urlstr));
-
- /* check if NoCache directive on this host */
-+ {
-+ struct sockaddr_in *sin;
-+#ifdef INET6
-+ struct sockaddr_in6 *sin6;
+ else if (strcasecmp(var, "REMOTE_PORT") == 0) {
+- return ap_psprintf(r->pool, "%d",
+- ntohs(r->connection->remote_addr.sin_port));
++ char servbuf[NI_MAXSERV];
++ servbuf[0] = '\0';
++ if (!getnameinfo((struct sockaddr *)&r->connection->remote_addr,
++#ifndef HAVE_SOCKADDR_LEN
++ SA_LEN((struct sockaddr *)&r->connection->remote_addr),
++#else
++ r->connection->remote_addr.ss_len,
+#endif
-+
- if (nocache == 0) {
- for (i = 0; i < conf->nocaches->nelts; i++) {
-- if (destaddr.s_addr == ncent[i].addr.s_addr ||
-- (ncent[i].name != NULL &&
-- (ncent[i].name[0] == '*' ||
-- strstr(desthost, ncent[i].name) != NULL))) {
-- nocache = 1;
-- break;
-+ if (ncent[i].name != NULL &&
-+ (ncent[i].name[0] == '*' ||
-+ strstr(desthost, ncent[i].name) != NULL)) {
-+ nocache = 1;
-+ break;
-+ }
-+ switch (res->ai_addr->sa_family) {
-+ case AF_INET:
-+ sin = (struct sockaddr_in *)res->ai_addr;
-+ if (sin->sin_addr.s_addr == ncent[i].addr.s_addr) {
-+ nocache = 1;
-+ break;
-+ }
- }
- }
--
-+ }
- /*
- * update the cache file, possibly even fulfilling the request if it
- * turns out a conditional allowed us to serve the object from the
++ NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)) {
++ return ap_pstrdup(r->pool, servbuf);
++ } else {
++ return ap_pstrdup(r->pool, "");
++ }
+ }
+ else if (strcasecmp(var, "REMOTE_HOST") == 0) {
+ result = (char *)ap_get_remote_host(r->connection,