]> git.pld-linux.org Git - packages/apache1.git/blobdiff - apache1-ipv6-PLD.patch
- release 4: do not obsolete "webserver"
[packages/apache1.git] / apache1-ipv6-PLD.patch
index 1c372262a107d4a36e9f29d358d174d5bf737d0a..ef9f5a25c7dd19abd619055c88682f348aa854c5 100644 (file)
@@ -1,6 +1,6 @@
-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
@@ -168,9 +168,9 @@ diff -Nur apache_1.3.26.orig/README.v6 apache_1.3.26/README.v6
 +       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
@@ -183,16 +183,16 @@ diff -Nur apache_1.3.26.orig/conf/httpd.conf-dist apache_1.3.26/conf/httpd.conf-
  #
  # 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
@@ -211,9 +211,9 @@ diff -Nur apache_1.3.26.orig/src/Configuration.tmpl apache_1.3.26/src/Configurat
  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`
@@ -222,7 +222,7 @@ diff -Nur apache_1.3.26.orig/src/Configure apache_1.3.26/src/Configure
  
  ####################################################################
  ## Rule SHARED_CORE implies required DSO support
-@@ -1701,6 +1702,124 @@
+@@ -1724,6 +1725,124 @@
      esac
  fi
  
@@ -347,7 +347,7 @@ diff -Nur apache_1.3.26.orig/src/Configure apache_1.3.26/src/Configure
  ####################################################################
  ## 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
  
@@ -386,9 +386,9 @@ diff -Nur apache_1.3.26.orig/src/Configure apache_1.3.26/src/Configure
  ####################################################################
  ## 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>
@@ -397,7 +397,7 @@ diff -Nur apache_1.3.26.orig/src/ap/ap_snprintf.c apache_1.3.26/src/ap/ap_snprin
  #ifdef WIN32
  #include <float.h>
  #endif
-@@ -504,6 +505,42 @@
+@@ -510,6 +511,42 @@
  
  
  
@@ -440,7 +440,7 @@ diff -Nur apache_1.3.26.orig/src/ap/ap_snprintf.c apache_1.3.26/src/ap/ap_snprin
  /*
   * 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':
                    {
@@ -448,7 +448,7 @@ diff -Nur apache_1.3.26.orig/src/ap/ap_snprintf.c apache_1.3.26/src/ap/ap_snprin
                        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;
                        }
@@ -465,9 +465,9 @@ diff -Nur apache_1.3.26.orig/src/ap/ap_snprintf.c apache_1.3.26/src/ap/ap_snprin
                        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:
   *
@@ -478,10 +478,10 @@ diff -Nur apache_1.3.26.orig/src/include/ap.h apache_1.3.26/src/include/ap.h
   * %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
@@ -492,7 +492,7 @@ diff -Nur apache_1.3.26.orig/src/include/ap_config.h apache_1.3.26/src/include/a
  #endif
  
  #define STDIN_FILENO  0
-@@ -1509,6 +1513,70 @@
+@@ -1523,6 +1527,70 @@
  #define ap_wait_t int
  #endif
  
@@ -563,9 +563,9 @@ diff -Nur apache_1.3.26.orig/src/include/ap_config.h apache_1.3.26/src/include/a
  #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;
@@ -576,9 +576,9 @@ diff -Nur apache_1.3.26.orig/src/include/http_conf_globals.h apache_1.3.26/src/i
  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);
  
@@ -588,10 +588,10 @@ diff -Nur apache_1.3.26.orig/src/include/http_vhost.h apache_1.3.26/src/include/
  
  /* 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? */
  
@@ -602,7 +602,7 @@ diff -Nur apache_1.3.26.orig/src/include/httpd.h apache_1.3.26/src/include/httpd
      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;
@@ -613,7 +613,7 @@ diff -Nur apache_1.3.26.orig/src/include/httpd.h apache_1.3.26/src/include/httpd
      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;
@@ -622,7 +622,7 @@ diff -Nur apache_1.3.26.orig/src/include/httpd.h apache_1.3.26/src/include/httpd
      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 *);
@@ -631,9 +631,9 @@ diff -Nur apache_1.3.26.orig/src/include/httpd.h apache_1.3.26/src/include/httpd
  
  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>) */
 + 
@@ -676,9 +676,9 @@ diff -Nur apache_1.3.26.orig/src/include/sa_len.h apache_1.3.26/src/include/sa_l
 +}
 +#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
@@ -733,9 +733,9 @@ diff -Nur apache_1.3.26.orig/src/include/sockaddr_storage.h apache_1.3.26/src/in
 +#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.
@@ -899,9 +899,9 @@ diff -Nur apache_1.3.26.orig/src/main/getaddrinfo.c apache_1.3.26/src/main/getad
 +  }
 +  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.
@@ -998,10 +998,10 @@ diff -Nur apache_1.3.26.orig/src/main/getnameinfo.c apache_1.3.26/src/main/getna
 +      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;
@@ -1009,7 +1009,7 @@ diff -Nur apache_1.3.26.orig/src/main/http_config.c apache_1.3.26/src/main/http_
      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 */
@@ -1024,7 +1024,7 @@ diff -Nur apache_1.3.26.orig/src/main/http_config.c apache_1.3.26/src/main/http_
      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;
@@ -1063,3619 +1063,3689 @@ diff -Nur apache_1.3.26.orig/src/main/http_config.c apache_1.3.26/src/main/http_
  }
  
  
-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.31/src/main/http_core.c.orig    Mon May  3 22:15:26 2004
++++ apache_1.3.31/src/main/http_core.c Sat May 15 00:06:26 2004
+@@ -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>
+@@ -564,7 +565,7 @@
+      * file if you care. So the adhoc value should do.
+      */
+     return ap_psprintf(r->pool,"%pp%pp%pp%pp%pp",
+-           (void *)&((r->connection->local_addr).sin_addr ),
++           (void *)&(((struct sockaddr_in *)&(r->connection->local_addr))->sin_addr),
+            (void *)ap_user_name,
+            (void *)ap_listeners,
+            (void *)ap_server_argv0,
+@@ -660,7 +661,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 */
+@@ -672,30 +675,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) {
+@@ -717,10 +744,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) {
+@@ -798,6 +829,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);
+@@ -807,23 +839,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;
+@@ -835,7 +866,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);
+     
+@@ -2621,12 +2652,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)
+@@ -2658,48 +2702,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;
+@@ -3602,7 +3669,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"},
+@@ -3636,7 +3703,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 *)&current->addr,
-+#ifndef SIN6_LEN
-+                  SA_LEN((struct sockaddr *)&current->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.31/src/modules/proxy/proxy_http.c.orig  Wed May 12 12:56:16 2004
++++ apache_1.3.31/src/modules/proxy/proxy_http.c       Wed May 12 14:09:27 2004
+@@ -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 */
+@@ -564,17 +575,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 *)&current->addr,
 +#ifndef SIN6_LEN
-+                  SA_LEN((struct sockaddr *)&server),
++                  SA_LEN((struct sockaddr *)&current->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,
This page took 0.402927 seconds and 4 git commands to generate.