httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "David Reid" <dr...@jetnet.co.uk>
Subject [PATCH] apr_sockaddr_t & friends
Date Sun, 12 Nov 2000 21:10:50 GMT
Folks,

I've been having a look at getting the apr_sockaddr_t structures added and
used throughout APR and the apache code, and in doing so have had to add
some APR functions and changed a LOT of the networking code...  the
resulting patch is bigger than I'd intended and touches more files than I'd
hoped.  The patch follows this text and can be found at
http://dev.apache.org/~dreid/sa_patch

Sendfile seems to be broken on FreeBSD (in a clean checkout it's broken as
well so it's not this patch :)) so I havn't managed to do as much checking
as I'd wished to.

whilst VirtualHosts seem to be work, the code needs a lot of attention to
get them working in a more protocol independant manner.  I think we'll need
to rework http_vhost.c following Tony's suggestion of using apr_hash and
thus allowing us to deal with more than IPv4.  That's the main reason I'm
not committing this :) Hopefully someone who knows the code well (fanf?) can
have a look and see what's required.

IPv6 support has started to be added and works in a limited fashion now.
For the adventurous in you, once applied change the line in
apr_create_tcp_socket from AF_INET to AF_INET6 and you'll have a server that
runs and will server either IPv4 or IPv6 requests. :)  Of course, the IPv6
support needs a lot more work yet.

There is a lot still to be done...  It's late and my brain is well addled
but these are a few that spring to mind...
- finish adding v6 support to APR
- rework the main apache code to remove the last vestiges of specific v4
coding
- add code safe version of inet_pton/inet_ntop for platforms that don't have
them
- http_vhost and hashing for v4 or v6

Given the above, I'm offering up the patch for public abuse and comment.  It
needs more eyes looking at it to get it to the next stage as I'm too close
to it at the moment...

It's possible to seperate out bits of this to apply in stages if that would
be preferred, or we can just go "BIG BANG"?

I'd like to get this in before we split APR out, but we'll see :)  If WW3
doesn't erupt then I'll commit Tuesday once I get home and catch up on my
mails.

david

Index: include/httpd.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/include/httpd.h,v
retrieving revision 1.116
diff -u -r1.116 httpd.h
--- include/httpd.h 2000/11/10 00:58:25 1.116
+++ include/httpd.h 2000/11/12 21:04:57
@@ -836,10 +836,17 @@

     /* Who is the client? */

+/* We shouldn't need these as they are cached in the socket that the
+ * structure has...
+ */
     /** local address */
+/*
     struct sockaddr_in local_addr;
+*/
     /** remote address */
+/*
     struct sockaddr_in remote_addr;
+*/
     /** Client's IP address */
     char *remote_ip;
     /** Client's DNS name, if known.  NULL if DNS hasn't been checked,
@@ -900,7 +907,7 @@
     /** The next server in the list */
     server_addr_rec *next;
     /** The bound address, for this server */
-    apr_in_addr_t host_addr;
+    apr_in_addr_t *host_addr;
     /** The bound port, for this server */
     apr_port_t host_port;
     /** The name given in <VirtualHost> */
Index: lib/apr/include/apr_network_io.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_network_io.h,v
retrieving revision 1.68
diff -u -r1.68 apr_network_io.h
--- lib/apr/include/apr_network_io.h 2000/11/10 19:21:31 1.68
+++ lib/apr/include/apr_network_io.h 2000/11/12 21:05:02
@@ -113,6 +113,16 @@
 }
 #endif

+struct apr_in_addr_t {
+    union {
+        struct in_addr ia;
+#if APR_HAVE_IPV6
+        struct in6_addr ia6;
+#endif
+    } u;
+    int family;
+};
+
 /* Enum to tell us if we're interested in remote or local socket */
 typedef enum {
     APR_LOCAL,
@@ -132,7 +142,7 @@
 typedef struct apr_socket_t     apr_socket_t;
 typedef struct apr_pollfd_t     apr_pollfd_t;
 typedef struct apr_hdtr_t       apr_hdtr_t;
-typedef struct in_addr          apr_in_addr_t;
+typedef struct apr_in_addr_t    apr_in_addr_t;

 /* use apr_uint16_t just in case some system has a short that isn't 16
bits... */
 typedef apr_uint16_t            apr_port_t;
@@ -156,12 +166,13 @@
 #endif
     } sa;
     apr_socklen_t sa_len;          /* How big is the sockaddr we're using?
*/
+    int ipaddr_len;                /* How big is the ip address structure
we're using? */
     int addr_str_len;              /* How big should the address buffer be?
                                     * 16 for v4 or 46 for v6
                                     * used in inet_ntop...
                                     */
-     void *ipaddr_ptr;              /* This points to the IP address
-                                    * structure within the appropriate
+    void *ipaddr_ptr;              /* This points to the IP address
+                                    * structure within the appropriate
                                     * sockaddr structure.
                                     */
 } apr_sockaddr_t;
@@ -449,18 +460,12 @@
 /**
  * Return the local socket name as a BSD style struct sockaddr_in.
  * @param name The local name associated with the socket.
+ * @param which Which interface do we wnat the apr_sockaddr_t for?
  * @param sock The socket to use
  */
-apr_status_t apr_get_local_name(struct sockaddr_in **name, apr_socket_t
*sock);
+apr_status_t apr_get_name(apr_sockaddr_t **sa, apr_interface_e which,
apr_socket_t *sock);

 /**
- * Return the remote socket name as a BSD style struct sockaddr_in.
- * @param name The remote name associated with the socket.
- * @param sock The socket to use
- */
-apr_status_t apr_get_remote_name(struct sockaddr_in **name, apr_socket_t
*sock);
-
-/**
  * Setup the memory required for poll to operate properly>
  * @param new_poll The poll structure to be used.
  * @param num The number of socket descriptors to be polled.
@@ -584,7 +589,7 @@
  * @param addr The apr_in_addr_t structure to return.
  * @param hostname The hostname to lookup.
  */
-apr_status_t apr_get_inaddr(apr_in_addr_t *addr, char *hostname);
+apr_status_t apr_get_inaddr(apr_in_addr_t **addr, char *hostname,
apr_pool_t *cont);

 /**
  * Given an apr_socket_t get the apr_in_addr_t for the requested interface
@@ -592,8 +597,54 @@
  * @param which The interface to return for
  * @param sock The apr_socket_t to use
  */
-apr_status_t apr_get_socket_inaddr(apr_in_addr_t *addr, apr_interface_e
which,
+apr_status_t apr_get_socket_inaddr(apr_in_addr_t **addr, apr_interface_e
which,
                   apr_socket_t *sock);
+
+/**
+ * This returns the s_addr from an apr_in_addr_t if it's available
+ * @param saddr the return value
+ * @param ia The apr_in_addr_t structure
+ */
+apr_status_t apr_get_v4_address(apr_uint32_t *saddr, apr_in_addr_t *ia);
+
+apr_int32_t apr_inaddr_compare(apr_in_addr_t *a, apr_in_addr_t *b);
+
+apr_status_t apr_inet_ntop(char **addr, apr_in_addr_t *sa, apr_pool_t *p);
+
+/**
+ * Given an apr_socket_t, preform a reverse lookup...
+ * @param sock The apr_socket_t to preform the lookup on
+ * @tip This fundtion will first peform a hostname lookup if it has not
already been
+ *      done.
+ */
+apr_status_t apr_check_reverse_lookup(apr_socket_t *sock);
+
+/**
+ * Given an apr_socket_t, find the hostname for the specified interface and
return it
+ * in the hostname.
+ * @param sock The apr_socket_t structure to use
+ * @param which Which interface should we lookup?
+ * @param hostname The returned hostname
+ * @tip The hostname is also stored in the address structure of the
apr_socket_t.
+ */
+apr_status_t apr_gethostbyname(apr_socket_t *sock, apr_interface_e which,
const char *hostname);
+
+/**
+ * This is a replacement for inet_addr which is threadsafe
+ * @param sock The apr_socket_t into which the result will be stored
+ * @param which Which interface are we storing the address for?
+ * @param ipaddr The address in it's standard test form to convert
+ */
+apr_status_t apr_socket_inet_pton(apr_socket_t *sock, apr_interface_e which
,
+                        const char* hostname);
+
+/**
+ * This is a replacement for inet_ntoa which is threadsafe
+ * @param addr The converted string
+ * @param which The interface to convert
+ * @param sock The apr_socket_t to use for the address
+ */
+apr_status_t apr_socket_inet_ntop(char **addr, apr_interface_e which,
apr_socket_t *sock);

 #ifdef __cplusplus
 }
Index: lib/apr/network_io/unix/networkio.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/networkio.h,v
retrieving revision 1.33
diff -u -r1.33 networkio.h
--- lib/apr/network_io/unix/networkio.h 2000/09/29 04:03:20 1.33
+++ lib/apr/network_io/unix/networkio.h 2000/11/12 21:05:04
@@ -122,8 +122,8 @@
 struct apr_socket_t {
     apr_pool_t *cntxt;
     int socketdes;
-    struct sockaddr_in *local_addr;
-    struct sockaddr_in *remote_addr;
+    apr_sockaddr_t *local_addr;
+    apr_sockaddr_t *remote_addr;
     apr_socklen_t addr_len;
     apr_interval_time_t timeout;
 #ifndef HAVE_POLL
Index: lib/apr/network_io/unix/sa_common.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sa_common.c,v
retrieving revision 1.4
diff -u -r1.4 sa_common.c
--- lib/apr/network_io/unix/sa_common.c 2000/11/11 06:05:59 1.4
+++ lib/apr/network_io/unix/sa_common.c 2000/11/12 21:05:05
@@ -68,11 +68,14 @@
 apr_status_t apr_set_port(apr_socket_t *sock, apr_interface_e which,
                          apr_port_t port)
 {
-    if (which == APR_LOCAL)
-        sock->local_addr->sin_port = htons(port);
-    else if (which == APR_REMOTE)
-        sock->remote_addr->sin_port = htons(port);
-    else
+    if (which == APR_LOCAL){
+        sock->local_addr->sa.sin.sin_port = htons(port);
+        sock->local_addr->port = port;
+        sock->local_port_unknown = 0;
+    }else if (which == APR_REMOTE){
+        sock->remote_addr->sa.sin.sin_port = htons(port);
+        sock->remote_addr->port = port;
+    }else
         return APR_EINVAL;
     return APR_SUCCESS;
 }
@@ -88,10 +91,19 @@
                 return rv;
             }
         }
-
-        *port = ntohs(sock->local_addr->sin_port);
+        if (sock->local_addr->port > 0)
+            *port = sock->local_addr->port;
+        else{
+            *port = ntohs(sock->local_addr->sa.sin.sin_port);
+            sock->local_addr->port = *port;
+        }
     } else if (which == APR_REMOTE)
-        *port = ntohs(sock->remote_addr->sin_port);
+        if (sock->remote_addr->port > 0)
+            *port = sock->remote_addr->port;
+        else {
+            *port = ntohs(sock->remote_addr->sa.sin.sin_port);
+            sock->remote_addr->port = *port;
+        }
     else
         return APR_EINVAL;
     return APR_SUCCESS;
@@ -107,39 +119,49 @@
                 return rv;
             }
         }
-        *addr = apr_pstrdup(sock->cntxt,
inet_ntoa(sock->local_addr->sin_addr));
-    } else if (which == APR_REMOTE)
-        *addr = apr_pstrdup(sock->cntxt,
inet_ntoa(sock->remote_addr->sin_addr));
-    else
-        return APR_EINVAL;
+    }

-    return APR_SUCCESS;
+    return apr_socket_inet_ntop(addr, which, sock);
 }

-apr_status_t apr_get_inaddr(apr_in_addr_t *addr, char *hostname)
+/* XXX - This needs to work for IPv6 as well as IPv4 */
+apr_status_t apr_get_inaddr(apr_in_addr_t **addr, char *hostname,
apr_pool_t *cont)
 {
     struct hostent *he;
-
+
+    if ((*addr) == NULL)
+        (*addr) = (apr_in_addr_t*)apr_pcalloc(cont, sizeof(apr_in_addr_t));
+    (*addr)->family = AF_INET;
+
     if (strcmp(hostname,"*") == 0){
-        addr->s_addr = htonl(INADDR_ANY);
+        (*addr)->u.ia.s_addr = htonl(INADDR_ANY);
         return APR_SUCCESS;
     }
-    if ((addr->s_addr = apr_inet_addr(hostname)) != APR_INADDR_NONE)
+    if (strcasecmp(hostname,"_default_") == 0 ||
strcmp(hostname,"255.255.255.255") == 0){
+        /* the define of DEFAULT_VHOST_ADDR is the same as INADDR_BROADCAST
*/
+        (*addr)->u.ia.s_addr = htonl(INADDR_BROADCAST);
         return APR_SUCCESS;
+    }
+    if (((*addr)->u.ia.s_addr = apr_inet_addr(hostname)) !=
APR_INADDR_NONE)
+        return APR_SUCCESS;

     /* hmmm, it's not a numeric IP address so we need to look it up :( */
     he = gethostbyname(hostname);
     if (!he || he->h_addrtype != AF_INET || !he->h_addr_list[0])
         return (h_errno + APR_OS_START_SYSERR);

-    *addr = *(struct in_addr*)he->h_addr_list[0];
+    memcpy(&(*addr)->u, he->h_addr_list[0], he->h_length);

     return APR_SUCCESS;
 }

-apr_status_t apr_get_socket_inaddr(apr_in_addr_t *addr, apr_interface_e
which,
+apr_status_t apr_get_socket_inaddr(apr_in_addr_t **addr, apr_interface_e
which,
                         apr_socket_t *sock)
 {
+    void *ipp;
+    if (*addr == NULL)
+        (*addr)=(apr_in_addr_t*)apr_pcalloc(sock->cntxt,
sizeof(apr_in_addr_t));
+
     if (which == APR_LOCAL){
         if (sock->local_interface_unknown) {
             apr_status_t rv = get_local_addr(sock);
@@ -149,12 +171,224 @@
             }
         }

-        *addr = *(apr_in_addr_t*)&sock->local_addr->sin_addr;
+        ipp = sock->local_addr->ipaddr_ptr;
+        (*addr)->family = sock->local_addr->sa.sin.sin_family;
     } else if (which == APR_REMOTE) {
-        *addr = *(apr_in_addr_t*)&sock->remote_addr->sin_addr;
+        ipp = sock->remote_addr->ipaddr_ptr;
+        (*addr)->family = sock->remote_addr->sa.sin.sin_family;
     } else {
         return APR_EINVAL;
     }
+    if ((*addr)->family == AF_INET)
+        (*addr)->u.ia = *(struct in_addr*)ipp;
+#if APR_HAVE_IPV6
+    else if ((*addr)->family == AF_INET6)
+        (*addr)->u.ia6 = *(struct in6_addr*)ipp;
+#endif
+    return APR_SUCCESS;
+}
+
+/* iXXX - This is a horrible, horrible hack!! */
+apr_status_t apr_get_v4_address(apr_uint32_t *saddr, apr_in_addr_t *ia)
+{
+    if (ia->family == AF_INET)
+        *saddr = ia->u.ia.s_addr;
+#if APR_HAVE_IPV6
+    else if (ia->family == AF_INET6){
+        if (IN6_IS_ADDR_V4COMPAT(&ia->u.ia6)){
+            /* we have an IPv4 compatible address structure, so now we can
+             * return an IPv4 int32???
+             */
+            *saddr = ia->u.ia.s_addr;
+        }
+    }
+#endif
+    else
+        return APR_EINVAL;
+    return APR_SUCCESS;
+}
+
+apr_int32_t apr_inaddr_compare(apr_in_addr_t *a, apr_in_addr_t *b)
+{
+    if (a->family == AF_INET)
+        return memcmp(&a->u, &b->u, sizeof(struct in_addr));
+#if APR_HAVE_IPV6
+    if (a->family == AF_INET6)
+        return memcmp(&a->u, &b->u, sizeof(struct in6_addr));
+#endif
+    return -1;
+}
+
+apr_status_t apr_gethostbyname(apr_socket_t *sock, apr_interface_e which,
const char *hostname)
+{
+    apr_in_addr_t *ipp;
+    int family, errnum;
+    struct hostent *he;
+
+    if (which == APR_LOCAL){
+        ipp = sock->local_addr->ipaddr_ptr;
+        family = sock->local_addr->sa.sin.sin_family;
+    } else if (which == APR_REMOTE) {
+        ipp = sock->remote_addr->ipaddr_ptr;
+        family = sock->remote_addr->sa.sin.sin_family;
+    } else
+        return APR_EINVAL;
+
+    /* If we have getipnodebyname we'll use it... */
+#if HAVE_GETIPNODEBYNAME
+    he = getipnodebyname(hostname, family, AI_DEFAULT, &errnum);
+#else
+  #ifndef GETHOSTBYNAME_HANDLES_NAS
+    if (*hostname >= '0' && *hostname <= '9' &&
+        strspn(hostname, "0123456789.") == strlen(hostname)) {
+        apr_socket_inet_pton(sock, APR_REMOTE, hostname);
+    }
+    else {
+  #endif
+
+    he = gethostbyname(hostname);
+    errnum = h_errno;
+  #ifndef GETHOSTBYNAME_HANDLES_NAS
+    }
+  #endif
+#endif
+
+    if (!he) {
+        return (errnum + APR_OS_START_SYSERR);
+    }
+
+    memcpy(ipp, he->h_addr_list[0], he->h_length);
+
+    if (which == APR_LOCAL)
+        sock->local_addr->ipaddr_len = he->h_length;
+    else
+        sock->remote_addr->ipaddr_len = he->h_length;
+
+    return APR_SUCCESS;
+}
+
+/* XXX - This is currently just a wrapper for inet_pton if we have it
available, but
+ * we need to add our own implementation for those platforms that don't
have one.
+ * FreeBSD's might be a good candidate?
+ */
+apr_status_t apr_socket_inet_pton(apr_socket_t *sock, apr_interface_e
which,
+                        const char* hostname)
+{
+    int family;
+    void *ipp;
+    int rv;
+
+    if (which == APR_LOCAL){
+        ipp = sock->local_addr->ipaddr_ptr;
+        family = sock->local_addr->sa.sin.sin_family;
+    } else if (which == APR_REMOTE) {
+        ipp = sock->remote_addr->ipaddr_ptr;
+        family = sock->remote_addr->sa.sin.sin_family;
+    } else
+        return APR_EINVAL;
+
+#if HAVE_INET_PTON
+    if ((rv = inet_pton(family, hostname, ipp)) != 1){
+        if (rv == 0)
+            return APR_EINVAL;
+        else
+            return errno;
+    }
+#else
+    ipp = inet_addr(hostname);
+#endif
+    return APR_SUCCESS;
+}
+
+
+/* XXX - this is just a wrapper for inet_ntop on those systems that have
it, but
+ * we need to add our own implementation for those platforms that don't
have one
+ * of their own.  FreeBSD's code could be a good candidate?
+ */
+apr_status_t apr_socket_inet_ntop(char **addr, apr_interface_e which,
apr_socket_t *sock)
+{
+    int family;
+    void *ipp;
+    int strlen;
+
+    if (which == APR_LOCAL){
+        family = sock->local_addr->sa.sin.sin_family;
+        ipp = sock->local_addr->ipaddr_ptr;
+        strlen = sock->local_addr->addr_str_len;
+    } else if (which == APR_REMOTE){
+        family = sock->local_addr->sa.sin.sin_family;
+        ipp = sock->remote_addr->ipaddr_ptr;
+        strlen = sock->remote_addr->addr_str_len;
+    } else
+        return APR_EINVAL;
+
+#if HAVE_INET_NTOP
+    (*addr) = apr_pcalloc(sock->cntxt, sizeof(char*) * strlen);
+    if (inet_ntop(family, ipp, (*addr), strlen) == NULL)
+        return errno;
+#else
+    (*addr) = apr_pstrdup(sock->cntxt, inet_ntoa(family, ippi));
+#endif
+
+    return APR_SUCCESS;
+}
+
+/* XXX - this is just a wrapper for inet_ntop on those systems that have
it, but
+ * we need to add our own implementation for those platforms that don't
have one
+ * of their own.  FreeBSD's code could be a good candidate?
+ */
+apr_status_t apr_inet_ntop(char **addr, apr_in_addr_t *sa, apr_pool_t *p)
+{
+    int strlen;
+    if (sa->family == AF_INET)
+        strlen = 16;
+#if APR_HAVE_IPV6
+    else if (sa->family == AF_INET6)
+        strlen = 46;
+#endif
+    else
+        return APR_EINVAL;
+
+#if HAVE_INET_NTOP
+    (*addr) = apr_pcalloc(p, sizeof(char*) * strlen);
+    if (inet_ntop(sa->family, &sa->u, (*addr), strlen) == NULL)
+        return errno;
+#else
+    (*addr) = inet_ntoa(sa->family, sa->u.ia);
+#endif
+
     return APR_SUCCESS;
+}
+
+apr_status_t apr_check_reverse_lookup(apr_socket_t *sock)
+{
+    apr_status_t rv;
+    struct hostent *he;
+    int errnum;
+    char **haddr;
+
+    if (sock->remote_addr->hostname == NULL){
+        if ((rv = apr_get_hostname(&sock->remote_addr->hostname,
APR_REMOTE, sock)) != APR_SUCCESS)
+            return rv;
+    }
+
+#if HAVE_GETIPNODEBYNAME
+    he = getipnodebyname(sock->remote_addr->hostname,
sock->remote_addr->sa.sin.sin_family, AI_DEFAULT,
+                     &errnum);
+#else
+    he = gethostbyname(sock->remote_addr->hostname);
+    errnum = h_errno;
+#endif
+
+    if (!he)
+        return (errnum + APR_OS_START_SYSERR);
+
+    for (haddr = he->h_addr_list; *haddr; haddr++){
+        if (memcmp((apr_in_addr_t*)(*haddr), sock->remote_addr->ipaddr_ptr,
+                      sock->remote_addr->ipaddr_len) == 0)
+            return APR_SUCCESS;
+    }
+
+    return APR_EINVAL;
 }

Index: lib/apr/network_io/unix/sockaddr.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sockaddr.c,v
retrieving revision 1.19
diff -u -r1.19 sockaddr.c
--- lib/apr/network_io/unix/sockaddr.c 2000/11/09 15:01:26 1.19
+++ lib/apr/network_io/unix/sockaddr.c 2000/11/12 21:05:05
@@ -57,9 +57,9 @@

 static apr_status_t get_local_addr(apr_socket_t *sock)
 {
-    apr_socklen_t namelen = sizeof(*sock->local_addr);
+    apr_socklen_t namelen = sock->addr_len;

-    if (getsockname(sock->socketdes, (struct sockaddr *)sock->local_addr,
+    if (getsockname(sock->socketdes, (struct sockaddr
*)&sock->local_addr->sa,
                     &namelen) < 0) {
         return errno;
     }
@@ -78,9 +78,9 @@
     struct sockaddr_in* sa_ptr;

     if (which == APR_LOCAL)
-        sa_ptr = sock->local_addr;
+        sa_ptr = sock->local_addr->ipaddr_ptr;
     else if (which == APR_REMOTE)
-        sa_ptr = sock->remote_addr;
+        sa_ptr = sock->remote_addr->ipaddr_ptr;
     else
         return APR_EINVAL;

@@ -100,25 +100,24 @@
 }

 #if APR_HAVE_NETINET_IN_H
-apr_status_t apr_get_local_name(struct sockaddr_in **name, apr_socket_t
*sock)
+apr_status_t apr_get_name(apr_sockaddr_t **name, apr_interface_e which,
+                           apr_socket_t *sock)
 {
-    if (sock->local_port_unknown || sock->local_interface_unknown) {
-        apr_status_t rv = get_local_addr(sock);
-
-        if (rv != APR_SUCCESS) {
-            return rv;
+    if (which == APR_LOCAL){
+        if (sock->local_port_unknown || sock->local_interface_unknown) {
+            apr_status_t rv = get_local_addr(sock);
+
+            if (rv != APR_SUCCESS) {
+                return rv;
+            }
         }
-    }
-
-    *name = sock->local_addr;
-    return APR_SUCCESS;
-}
-
-
-
-apr_status_t apr_get_remote_name(struct sockaddr_in **name, apr_socket_t
*sock)
-{
-    *name = sock->remote_addr;
+
+        *name = sock->local_addr;
+    } else if (which == APR_REMOTE)
+        *name = sock->remote_addr;
+    else
+        return APR_EINVAL;
     return APR_SUCCESS;
 }
 #endif
+
Index: lib/apr/network_io/unix/sockets.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sockets.c,v
retrieving revision 1.54
diff -u -r1.54 sockets.c
--- lib/apr/network_io/unix/sockets.c 2000/11/02 03:02:49 1.54
+++ lib/apr/network_io/unix/sockets.c 2000/11/12 21:05:06
@@ -54,7 +54,46 @@

 #include "networkio.h"
 #include "apr_portable.h"
+#include "apr_strings.h"

+static void set_socket_vars(apr_socket_t *sock)
+{
+    /* Do we need to worry about local_addr being AF_INET and remote_addr
being AF_INET6???
+     * I've worried about it here, but this could be simplified if we don't
have to
+     * worry about it...
+     * Of course if we do then the sock->addr_len is bogus!
+     */
+    if (sock->local_addr->sa.sin.sin_family == AF_INET){
+        sock->addr_len = sizeof(struct sockaddr_in);
+        sock->local_addr->addr_str_len = 16;
+        sock->local_addr->ipaddr_ptr =
&(sock->local_addr->sa.sin.sin_addr);
+        sock->local_addr->ipaddr_len = sizeof(struct in_addr);
+    }
+#if APR_HAVE_IPV6
+    else if (sock->local_addr->sa.sin.sin_family == AF_INET6){
+        sock->addr_len = sizeof(struct sockaddr_in6);
+        sock->local_addr->addr_str_len = 46;
+        sock->local_addr->ipaddr_ptr =
&(sock->local_addr->sa.sin6.sin6_addr);
+        sock->local_addr->ipaddr_len = sizeof(struct in6_addr);
+    }
+#endif
+
+    if (sock->remote_addr->sa.sin.sin_family == AF_INET){
+        sock->addr_len = sizeof(struct sockaddr_in);
+        sock->remote_addr->addr_str_len = 16;
+        sock->remote_addr->ipaddr_ptr =
&(sock->remote_addr->sa.sin.sin_addr);
+        sock->remote_addr->ipaddr_len = sizeof(struct in_addr);
+    }
+#if APR_HAVE_IPV6
+    else if (sock->local_addr->sa.sin.sin_family == AF_INET6){
+        sock->addr_len = sizeof(struct sockaddr_in6);
+        sock->remote_addr->addr_str_len = 46;
+        sock->remote_addr->ipaddr_ptr =
&(sock->remote_addr->sa.sin6.sin6_addr);
+        sock->remote_addr->ipaddr_len = sizeof(struct in6_addr);
+    }
+#endif
+}
+
 static apr_status_t socket_cleanup(void *sock)
 {
     apr_socket_t *thesocket = sock;
@@ -69,31 +108,35 @@

 apr_status_t apr_create_tcp_socket(apr_socket_t **new, apr_pool_t *cont)
 {
+    int family = AF_INET;
+    int proto = IPPROTO_TCP;
+    int type = SOCK_STREAM;
+
     (*new) = (apr_socket_t *)apr_pcalloc(cont, sizeof(apr_socket_t));

     if ((*new) == NULL) {
         return APR_ENOMEM;
     }
     (*new)->cntxt = cont;
-    (*new)->local_addr = (struct sockaddr_in *)apr_pcalloc((*new)->cntxt,
-                         sizeof(struct sockaddr_in));
-    (*new)->remote_addr = (struct sockaddr_in *)apr_pcalloc((*new)->cntxt,
-                          sizeof(struct sockaddr_in));
+    (*new)->local_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->cntxt,
+                         sizeof(apr_sockaddr_t));
+    (*new)->remote_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->cntxt,
+                          sizeof(apr_sockaddr_t));

     if ((*new)->local_addr == NULL || (*new)->remote_addr == NULL) {
         return APR_ENOMEM;
     }

-    (*new)->socketdes = socket(AF_INET ,SOCK_STREAM, IPPROTO_TCP);
-
-    (*new)->local_addr->sin_family = AF_INET;
-    (*new)->remote_addr->sin_family = AF_INET;
+    (*new)->socketdes = socket(family ,type, proto);

-    (*new)->addr_len = sizeof(*(*new)->local_addr);
-
     if ((*new)->socketdes < 0) {
         return errno;
     }
+
+    (*new)->local_addr->sa.sin.sin_family = family;
+    (*new)->remote_addr->sa.sin.sin_family = family;
+    set_socket_vars((*new));
+
     (*new)->timeout = -1;
     apr_register_cleanup((*new)->cntxt, (void *)(*new),
                         socket_cleanup, apr_null_cleanup);
@@ -113,10 +156,10 @@

 apr_status_t apr_bind(apr_socket_t *sock)
 {
-    if (bind(sock->socketdes, (struct sockaddr *)sock->local_addr,
sock->addr_len) == -1)
+    if (bind(sock->socketdes, (struct sockaddr *)&sock->local_addr->sa,
sock->addr_len) == -1)
         return errno;
     else {
-        if (sock->local_addr->sin_port == 0) { /* no need for ntohs() when
comparing w/ 0 */
+        if (sock->local_addr->sa.sin.sin_port == 0) { /* no need for
ntohs() when comparing w/ 0 */
             sock->local_port_unknown = 1; /* kernel got us an ephemeral
port */
         }
         return APR_SUCCESS;
@@ -137,18 +180,22 @@
                             sizeof(apr_socket_t));

     (*new)->cntxt = connection_context;
-    (*new)->local_addr = (struct sockaddr_in *)apr_pcalloc((*new)->cntxt,
-                 sizeof(struct sockaddr_in));
+    (*new)->local_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->cntxt,
+                 sizeof(struct apr_sockaddr_t));
+
+    (*new)->remote_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->cntxt,
+                 sizeof(struct apr_sockaddr_t));
+    (*new)->local_addr->sa.sin.sin_family =
sock->local_addr->sa.sin.sin_family;
+    (*new)->remote_addr->sa.sin.sin_family =
sock->remote_addr->sa.sin.sin_family;
+    set_socket_vars((*new));
+

-    (*new)->remote_addr = (struct sockaddr_in *)apr_pcalloc((*new)->cntxt,
-                 sizeof(struct sockaddr_in));
-    (*new)->addr_len = sizeof(struct sockaddr_in);
 #ifndef HAVE_POLL
     (*new)->connected = 1;
 #endif
     (*new)->timeout = -1;

-    (*new)->socketdes = accept(sock->socketdes, (struct sockaddr
*)(*new)->remote_addr,
+    (*new)->socketdes = accept(sock->socketdes, (struct sockaddr
*)&(*new)->remote_addr->sa,
                         &(*new)->addr_len);

     if ((*new)->socketdes < 0) {
@@ -162,16 +209,26 @@
         (*new)->local_port_unknown = 1;
     }

-    if (sock->local_interface_unknown ||
-        sock->local_addr->sin_addr.s_addr == 0) {
-        /* If the interface address inside the listening socket's
local_addr wasn't
-         * up-to-date, we don't know local interface of the connected
socket either.
-         *
-         * If the listening socket was not bound to a specific interface,
we
-         * don't know the local_addr of the connected socket.
-         */
-        (*new)->local_interface_unknown = 1;
+    if (sock->local_addr->sa.sin.sin_family == AF_INET){
+        if (sock->local_interface_unknown ||
+            sock->local_addr->sa.sin.sin_addr.s_addr == 0) {
+            /* If the interface address inside the listening socket's
local_addr wasn't
+             * up-to-date, we don't know local interface of the connected
socket either.
+             *
+             * If the listening socket was not bound to a specific
interface, we
+             * don't know the local_addr of the connected socket.
+             */
+            (*new)->local_interface_unknown = 1;
+        }
     }
+#if APR_HAVE_IPV6
+    else if (sock->local_addr->sa.sin.sin_family == AF_INET6){
+        if (sock->local_interface_unknown ||
+            IN6_IS_ADDR_UNSPECIFIED((struct
in6_addr*)sock->local_addr->ipaddr_ptr)){
+            (*new)->local_interface_unknown = 1;
+        }
+    }
+#endif

     apr_register_cleanup((*new)->cntxt, (void *)(*new),
                         socket_cleanup, apr_null_cleanup);
@@ -180,53 +237,43 @@

 apr_status_t apr_connect(apr_socket_t *sock, const char *hostname)
 {
-    struct hostent *hp;
-
     if ((sock->socketdes < 0) || (!sock->remote_addr)) {
         return APR_ENOTSOCK;
     }
-    if (hostname != NULL) {
-#ifndef GETHOSTBYNAME_HANDLES_NAS
-        if (*hostname >= '0' && *hostname <= '9' &&
-            strspn(hostname, "0123456789.") == strlen(hostname)) {
-            sock->remote_addr->sin_addr.s_addr = inet_addr(hostname);
-            sock->addr_len = sizeof(*sock->remote_addr);
-        }
-        else {
-#endif
-        hp = gethostbyname(hostname);

-        if (!hp)  {
-            return (h_errno + APR_OS_START_SYSERR);
-        }
-
-        memcpy((char *)&sock->remote_addr->sin_addr, hp->h_addr_list[0],
-               hp->h_length);
-
-        sock->addr_len = sizeof(*sock->remote_addr);
-#ifndef GETHOSTBYNAME_HANDLES_NAS
-        }
-#endif
+    if (hostname != NULL) {
+        apr_status_t rv;
+        if ((rv = apr_gethostbyname(sock, APR_REMOTE, hostname)) !=
APR_SUCCESS)
+            return rv;
     }

-    if ((connect(sock->socketdes, (const struct sockaddr
*)sock->remote_addr,
+    if ((connect(sock->socketdes, (const struct sockaddr
*)&sock->remote_addr->sa,
         sock->addr_len) < 0) && (errno != EINPROGRESS)) {
         return errno;
     }
     else {
-        if (sock->local_addr->sin_port == 0) {
+        if (sock->local_addr->sa.sin.sin_port == 0) {
             /* connect() got us an ephemeral port */
             sock->local_port_unknown = 1;
         }
-        if (sock->local_addr->sin_addr.s_addr == 0) {
-            /* not bound to specific local interface; connect() had to
assign
-             * one for the socket
-             */
-            sock->local_interface_unknown = 1;
+        if (sock->local_addr->sa.sin.sin_family == AF_INET){
+            if (sock->local_addr->sa.sin.sin_addr.s_addr == 0) {
+                sock->local_interface_unknown = 1;
+            }
         }
+#if APR_HAVE_IPV6
+        else if (sock->local_addr->sa.sin.sin_family == AF_INET6){
+            if (IN6_IS_ADDR_UNSPECIFIED((struct
in6_addr*)sock->local_addr->ipaddr_ptr)){
+                sock->local_interface_unknown = 1;
+            }
+        }
+#endif
+
 #ifndef HAVE_POLL
  sock->connected=1;
 #endif
+
+        sock->remote_addr->hostname = apr_pstrdup(sock->cntxt, hostname);
         return APR_SUCCESS;
     }
 }
@@ -254,16 +301,22 @@
     if ((*sock) == NULL) {
         (*sock) = (apr_socket_t *)apr_pcalloc(cont, sizeof(apr_socket_t));
         (*sock)->cntxt = cont;
-        (*sock)->local_addr = (struct sockaddr_in
*)apr_pcalloc((*sock)->cntxt,
-                             sizeof(struct sockaddr_in));
-        (*sock)->remote_addr = (struct sockaddr_in
*)apr_pcalloc((*sock)->cntxt,
-                              sizeof(struct sockaddr_in));
+        (*sock)->local_addr = (apr_sockaddr_t *)apr_pcalloc((*sock)->cntxt,
+                             sizeof(struct apr_sockaddr_t));
+        (*sock)->remote_addr = (apr_sockaddr_t
*)apr_pcalloc((*sock)->cntxt,
+                              sizeof(struct apr_sockaddr_t));

         if ((*sock)->local_addr == NULL || (*sock)->remote_addr == NULL) {
             return APR_ENOMEM;
         }

-        (*sock)->addr_len = sizeof(*(*sock)->local_addr);
+        /* XXX - This is very bogus!
+         * we need to check what family socket we get...
+         */
+        (*sock)->local_addr->sa.sin.sin_family = AF_INET;
+        (*sock)->remote_addr->sa.sin.sin_family = AF_INET;
+        set_socket_vars((*sock));
+
         (*sock)->timeout = -1;
     }
     (*sock)->local_port_unknown = (*sock)->local_interface_unknown = 1;
Index: lib/apr/network_io/unix/sockopt.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/unix/sockopt.c,v
retrieving revision 1.36
diff -u -r1.36 sockopt.c
--- lib/apr/network_io/unix/sockopt.c 2000/11/10 16:11:13 1.36
+++ lib/apr/network_io/unix/sockopt.c 2000/11/12 21:05:06
@@ -205,26 +205,42 @@
 apr_status_t apr_get_hostname(char **name, apr_interface_e which,
apr_socket_t *sock)
 {
     struct hostent *hptr;
-    apr_in_addr_t sa_ptr;
+    apr_in_addr_t *sa_ptr = NULL;
+    int errnum;
+    int family = AF_INET;
+    int iplen;

-    if (which == APR_LOCAL)
-        sa_ptr = sock->local_addr->sin_addr;
-    else if (which == APR_REMOTE)
-        sa_ptr = sock->remote_addr->sin_addr;
-    else
+    if (which == APR_LOCAL){
+        sa_ptr = sock->local_addr->ipaddr_ptr;
+        family = sock->local_addr->sa.sin.sin_family;
+        iplen = sock->local_addr->ipaddr_len;
+    } else if (which == APR_REMOTE){
+        sa_ptr = sock->remote_addr->ipaddr_ptr;
+        family = sock->remote_addr->sa.sin.sin_family;
+        iplen = sock->remote_addr->ipaddr_len;
+    }else
         return APR_EINVAL;

-    hptr = gethostbyaddr((char *)&sa_ptr, sizeof(struct in_addr), AF_INET);
+    /* getipnodebyaddr is threadsafe and works with IPv6 so use it if we
can */
+#if HAVE_GETIPNODEBYADDR
+    hptr = getipnodebyaddr(sa_ptr, iplen, family, &errnum);
+#else
+    hptr = gethostbyaddr((char *)sa_ptr, sock->addr_len, AF_INET);
+    errnum = h_errno;
+#endif

     if (hptr != NULL) {
         *name = apr_pstrdup(sock->cntxt, hptr->h_name);
+#if HAVE_GETIPNODEBYADDR
+        freehostent(hptr);
+#endif
+
         if (*name) {
             return APR_SUCCESS;
         }
         return APR_ENOMEM;
     }

-    /* XXX - Is referencing h_errno threadsafe? */
-    return (h_errno + APR_OS_START_SYSERR);
+    return (errnum + APR_OS_START_SYSERR);
 }

Index: lib/apr/network_io/win32/sockaddr.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/sockaddr.c,v
retrieving revision 1.18
diff -u -r1.18 sockaddr.c
--- lib/apr/network_io/win32/sockaddr.c 2000/11/11 06:05:59 1.18
+++ lib/apr/network_io/win32/sockaddr.c 2000/11/12 21:05:07
@@ -74,24 +74,23 @@

 /* Include this here so we have get_local_addr defined... */
 #include "../unix/sa_common.c"
-
 apr_status_t apr_set_ipaddr(apr_socket_t *sock, apr_interface_e which,
const char *addr)
 {
     u_long ipaddr;
-    struct sockaddr_in *ptr;
+    struct sockaddr_in* sa_ptr;

     if (which == APR_LOCAL)
-        ptr = sock->local_addr;
+        sa_ptr = sock->local_addr->ipaddr_ptr;
     else if (which == APR_REMOTE)
-        ptr = sock->remote_addr;
+        sa_ptr = sock->remote_addr->ipaddr_ptr;
     else
         return APR_EINVAL;
-
+
     if (!strcmp(addr, APR_ANYADDR)) {
-        ptr->sin_addr.s_addr = htonl(INADDR_ANY);
+        sa_ptr->sin_addr.s_addr = htonl(INADDR_ANY);
         return APR_SUCCESS;
     }
-
+
     ipaddr = inet_addr(addr);

     if (ipaddr == APR_INADDR_NONE) {
@@ -102,24 +101,23 @@
     return APR_SUCCESS;
 }

-apr_status_t apr_get_local_name(struct sockaddr_in **name, apr_socket_t
*sock)
+apr_status_t apr_get_name(apr_sockaddr_t **name, apr_interface_e which,
+                           apr_socket_t *sock)
 {
-    if (sock->local_port_unknown || sock->local_interface_unknown) {
-        apr_status_t rv = get_local_addr(sock);
-
-        if (rv != APR_SUCCESS) {
-            return rv;
+    if (which == APR_LOCAL){
+        if (sock->local_port_unknown || sock->local_interface_unknown) {
+            apr_status_t rv = get_local_addr(sock);
+
+            if (rv != APR_SUCCESS) {
+                return rv;
+            }
         }
-    }

-    *name = sock->local_addr;
+        *name = sock->local_addr;
+    } else if (which == APR_REMOTE)
+        *name = sock->remote_addr;
+    else
+        return APR_EINVAL;
     return APR_SUCCESS;
 }

-
-
-apr_status_t apr_get_remote_name(struct sockaddr_in **name, apr_socket_t
*sock)
-{
-    *name = sock->remote_addr;
-    return APR_SUCCESS;
-}
Index: lib/apr/network_io/win32/sockets.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/sockets.c,v
retrieving revision 1.39
diff -u -r1.39 sockets.c
--- lib/apr/network_io/win32/sockets.c 2000/11/02 03:02:50 1.39
+++ lib/apr/network_io/win32/sockets.c 2000/11/12 21:05:07
@@ -59,6 +59,43 @@
 #include "apr_portable.h"
 #include <string.h>

+static void set_socket_vars(apr_socket_t *sock)
+{
+    /* Do we need to worry about local_addr being AF_INET and remote_addr
being AF_INET6???
+     * I've worried about it here, but this could be simplified if we don't
have to
+     * worry about it...
+     * Of course if we do then the sock->addr_len is bogus!
+     */
+    if (sock->local_addr->sa.sin.sin_family == AF_INET){
+        sock->addr_len = sizeof(struct sockaddr_in);
+        sock->local_addr->addr_str_len = 16;
+        sock->local_addr->ipaddr_ptr =
&(sock->local_addr->sa.sin.sin_addr);
+        sock->local_addr->ipaddr_len = sizeof(struct in_addr);
+    }
+#if APR_HAVE_IPV6
+    else if (sock->local_addr->sa.sin.sin_family == AF_INET6){
+        sock->addr_len = sizeof(struct sockaddr_in6);
+        sock->local_addr->addr_str_len = 46;
+        sock->local_addr->ipaddr_ptr =
&(sock->local_addr->sa.sin6.sin6_addr);
+        sock->local_addr->ipaddr_len = sizeof(struct in6_addr);
+    }
+#endif
+
+    if (sock->remote_addr->sa.sin.sin_family == AF_INET){
+        sock->addr_len = sizeof(struct sockaddr_in);
+        sock->remote_addr->addr_str_len = 16;
+        sock->remote_addr->ipaddr_ptr =
&(sock->remote_addr->sa.sin.sin_addr);
+        sock->remote_addr->ipaddr_len = sizeof(struct in_addr);
+    }
+#if APR_HAVE_IPV6
+    else if (sock->local_addr->sa.sin.sin_family == AF_INET6){
+        sock->addr_len = sizeof(struct sockaddr_in6);
+        sock->remote_addr->addr_str_len = 46;
+        sock->remote_addr->ipaddr_ptr =
&(sock->remote_addr->sa.sin6.sin6_addr);
+        sock->remote_addr->ipaddr_len = sizeof(struct in6_addr);
+    }
+#endif
+}

 static apr_status_t socket_cleanup(void *sock)
 {
@@ -81,10 +118,10 @@
         return APR_ENOMEM;
     }
     (*new)->cntxt = cont;
-    (*new)->local_addr = (struct sockaddr_in *)apr_pcalloc((*new)->cntxt,
-                                                          sizeof(struct
sockaddr_in));
-    (*new)->remote_addr = (struct sockaddr_in *)apr_pcalloc((*new)->cntxt,
-                          sizeof(struct sockaddr_in));
+    (*new)->local_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->cntxt,
+                         sizeof(apr_sockaddr_t));
+    (*new)->remote_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->cntxt,
+                          sizeof(apr_sockaddr_t));

     if (((*new)->local_addr == NULL) || ((*new)->remote_addr == NULL)) {
         return APR_ENOMEM;
@@ -97,13 +134,12 @@
         return apr_get_netos_error();
     }

-    (*new)->local_addr->sin_family = AF_INET;
-    (*new)->remote_addr->sin_family = AF_INET;
+    (*new)->local_addr->sa.sin.sin_family = family;
+    (*new)->remote_addr->sa.sin.sin_family = family;
+    set_socket_vars((*new));

-    (*new)->addr_len = sizeof(*(*new)->local_addr);
+    (*new)->local_addr->sa.sin.sin_port = 0;

-    (*new)->local_addr->sin_port = 0;
-
     (*new)->timeout = -1;
     (*new)->disconnected = 0;

@@ -147,11 +183,11 @@

 apr_status_t apr_bind(apr_socket_t *sock)
 {
-    if (bind(sock->sock, (struct sockaddr *)sock->local_addr,
sock->addr_len) == -1) {
+    if (bind(sock->socketdes, (struct sockaddr *)&sock->local_addr->sa,
sock->addr_len) == -1)
         return apr_get_netos_error();
     }
     else {
-        if (sock->local_addr->sin_port == 0) {
+        if (sock->local_addr->sa.sin.sin_port == 0)

             sock->local_port_unknown = 1; /* ephemeral port */
         }
         return APR_SUCCESS;
@@ -172,17 +208,21 @@
                             sizeof(apr_socket_t));

     (*new)->cntxt = connection_context;
-    (*new)->local_addr = (struct sockaddr_in *)apr_pcalloc((*new)->cntxt,
-                 sizeof(struct sockaddr_in));
-    (*new)->remote_addr = (struct sockaddr_in *)apr_pcalloc((*new)->cntxt,
-                 sizeof(struct sockaddr_in));
-    memcpy((*new)->local_addr, sock->local_addr, sizeof(struct
sockaddr_in));
+    (*new)->local_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->cntxt,
+                 sizeof(struct apr_sockaddr_t));
+
+    (*new)->remote_addr = (apr_sockaddr_t *)apr_pcalloc((*new)->cntxt,
+                 sizeof(struct apr_sockaddr_t));
+    (*new)->local_addr->sa.sin.sin_family =
sock->local_addr->sa.sin.sin_family;
+    (*new)->remote_addr->sa.sin.sin_family =
sock->remote_addr->sa.sin.sin_family;
+    set_socket_vars((*new));

-    (*new)->addr_len = sizeof(struct sockaddr_in);
+    memcpy((*new)->local_addr, sock->local_addr, sizeof(struct
apr_sockaddr_t));
+
     (*new)->timeout = -1;
     (*new)->disconnected = 0;

-    (*new)->sock = accept(sock->sock, (struct sockaddr
*)(*new)->local_addr,
+    (*new)->socketdes = accept(sock->socketdes, (struct sockaddr
*)&(*new)->remote_addr->sa,
                         &(*new)->addr_len);

     if ((*new)->sock == INVALID_SOCKET) {
@@ -196,16 +236,20 @@
         (*new)->local_port_unknown = 1;
     }

-    if (sock->local_interface_unknown ||
-        sock->local_addr->sin_addr.s_addr == 0) {
-        /* If the interface address inside the listening socket's
local_addr wasn't
-         * up-to-date, we don't know local interface of the connected
socket either.
-         *
-         * If the listening socket was not bound to a specific interface,
we
-         * don't know the local_addr of the connected socket.
-         */
-        (*new)->local_interface_unknown = 1;
+    if (sock->local_addr->sa.sin.sin_family == AF_INET){
+        if (sock->local_interface_unknown ||
+            sock->local_addr->sa.sin.sin_addr.s_addr == 0) {
+            (*new)->local_interface_unknown = 1;
+        }
+    }
+#if APR_HAVE_IPV6
+    else if (sock->local_addr->sa.sin.sin_family == AF_INET6){
+        if (sock->local_interface_unknown ||
+            IN6_IS_ADDR_UNSPECIFIED((struct
in6_addr*)sock->local_addr->ipaddr_ptr)){
+            (*new)->local_interface_unknown = 1;
+        }
     }
+#endif

     apr_register_cleanup((*new)->cntxt, (void *)(*new),
                         socket_cleanup, apr_null_cleanup);
@@ -223,23 +267,14 @@
     }

     if (hostname != NULL) {
-        if (*hostname >= '0' && *hostname <= '9' &&
-            strspn(hostname, "0123456789.") == strlen(hostname)) {
-            sock->remote_addr->sin_addr.s_addr = inet_addr(hostname);
-        }
-        else {
-            hp = gethostbyname(hostname);
-            if (!hp)  {
-                return apr_get_netos_error();
-            }
-            memcpy((char *)&sock->remote_addr->sin_addr,
hp->h_addr_list[0], hp->h_length);
-            sock->addr_len = sizeof(*sock->remote_addr);
-        }
+        apr_status_t rv;
+        if ((rv = apr_gethostbyname(sock, APR_REMOTE, hostname)) !=
APR_SUCCESS)
+            return rv;
     }
-
+
     sock->remote_addr->sin_family = AF_INET;

-    if (connect(sock->sock, (const struct sockaddr *)sock->remote_addr,
+    if ((connect(sock->socketdes, (const struct sockaddr
*)&sock->remote_addr->sa,
                 sock->addr_len) == SOCKET_ERROR) {
         lasterror = apr_get_netos_error();
         if (lasterror != APR_FROM_OS_ERROR(WSAEWOULDBLOCK)) {
@@ -260,6 +295,7 @@
         /* must be using free-range port */
         sock->local_interface_unknown = 1;
     }
+    sock->remote_addr->hostname = apr_pstrdup(sock->cntxt, hostname);
     return APR_SUCCESS;
 }

@@ -289,16 +325,21 @@
     if ((*sock) == NULL) {
         (*sock) = (apr_socket_t *)apr_pcalloc(cont, sizeof(apr_socket_t));
         (*sock)->cntxt = cont;
-        (*sock)->local_addr = (struct sockaddr_in
*)apr_pcalloc((*sock)->cntxt,
-                             sizeof(struct sockaddr_in));
-        (*sock)->remote_addr = (struct sockaddr_in
*)apr_pcalloc((*sock)->cntxt,
-                              sizeof(struct sockaddr_in));
+        (*sock)->local_addr = (apr_sockaddr_t *)apr_pcalloc((*sock)->cntxt,
+                             sizeof(struct apr_sockaddr_t));
+        (*sock)->remote_addr = (apr_sockaddr_t
*)apr_pcalloc((*sock)->cntxt,
+                              sizeof(struct apr_sockaddr_t));

         if ((*sock)->local_addr == NULL || (*sock)->remote_addr == NULL) {
             return APR_ENOMEM;
         }
-
-        (*sock)->addr_len = sizeof(*(*sock)->local_addr);
+        /* XXX - This is very bogus!
+         * we need to check what family socket we get...
+         */
+        (*sock)->local_addr->sa.sin.sin_family = AF_INET;
+        (*sock)->remote_addr->sa.sin.sin_family = AF_INET;
+        set_socket_vars((*sock));
+
         (*sock)->timeout = -1;
         (*sock)->disconnected = 0;
     }
Index: lib/apr/network_io/win32/sockopt.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/network_io/win32/sockopt.c,v
retrieving revision 1.28
diff -u -r1.28 sockopt.c
--- lib/apr/network_io/win32/sockopt.c 2000/11/10 20:17:24 1.28
+++ lib/apr/network_io/win32/sockopt.c 2000/11/12 21:05:08
@@ -204,19 +204,35 @@
 apr_status_t apr_get_hostname(char **name, apr_interface_e which,
apr_socket_t *sock)
 {
     struct hostent *hptr;
-    apr_in_addr_t sa_ptr;
+    apr_in_addr_t *sa_ptr = NULL;
+    int errnum;
+    int family = AF_INET;
+    int iplen;

-    if (which == APR_LOCAL)
-        sa_ptr = sock->local_addr->sin_addr;
-    else if (which == APR_REMOTE)
-        sa_ptr = sock->remote_addr->sin_addr;
-    else
+    if (which == APR_LOCAL){
+        sa_ptr = sock->local_addr->ipaddr_ptr;
+        family = sock->local_addr->sa.sin.sin_family;
+        iplen = sock->local_addr->ipaddr_len;
+    } else if (which == APR_REMOTE){
+        sa_ptr = sock->remote_addr->ipaddr_ptr;
+        family = sock->remote_addr->sa.sin.sin_family;
+        iplen = sock->remote_addr->ipaddr_len;
+    }else
         return APR_EINVAL;

-    hptr = gethostbyaddr((char *)&sa_ptr, sizeof(struct in_addr), AF_INET);
+    /* getipnodebyaddr is threadsafe and works with IPv6 so use it if we
can */
+#if HAVE_GETIPNODEBYADDR
+    hptr = getipnodebyaddr(sa_ptr, iplen, family, &errnum);
+#else
+    hptr = gethostbyaddr((char *)sa_ptr, sock->addr_len, AF_INET);
+    errnum = h_errno;
+#endif

     if (hptr != NULL) {
         *name = apr_pstrdup(sock->cntxt, hptr->h_name);
+#if HAVE_GETIPNODEBYADDR
+        freehostent(hptr);
+#endif
         if (*name) {
             return APR_SUCCESS;
         }
Index: lib/apr/test/client.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/test/client.c,v
retrieving revision 1.17
diff -u -r1.17 client.c
--- lib/apr/test/client.c 2000/11/09 15:01:35 1.17
+++ lib/apr/test/client.c 2000/11/12 21:05:08
@@ -142,6 +142,12 @@
     apr_get_port(&local_port, APR_LOCAL, sock);
     fprintf(stdout, "\tClient socket: %s:%u -> %s:%u\n", local_ipaddr,
local_port, remote_ipaddr, remote_port);

+    fprintf(stdout, "\tClient:  Doing reverse lookup.................");
+    if (apr_check_reverse_lookup(sock) != APR_SUCCESS)
+        fprintf(stdout,"Failed!!!\n");
+    else
+        fprintf(stdout,"OK\n");
+
     fprintf(stdout, "\tClient:  Trying to send data over socket.......");
     length = STRLEN;
     if (apr_send(sock, datasend, &length) != APR_SUCCESS) {
Index: lib/apr/test/server.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/test/server.c,v
retrieving revision 1.16
diff -u -r1.16 server.c
--- lib/apr/test/server.c 2000/11/09 15:01:35 1.16
+++ lib/apr/test/server.c 2000/11/12 21:05:09
@@ -193,7 +193,7 @@
     }
     fprintf(stdout, "OK\n");

-    fprintf(stdout, "\tServer:  Shutting down accepte socket.......");
+    fprintf(stdout, "\tServer:  Shutting down accepted socket.......");
     if (apr_shutdown(sock2, APR_SHUTDOWN_READ) != APR_SUCCESS) {
         apr_close_socket(sock);
         apr_close_socket(sock2);
Index: main/http_config.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/main/http_config.c,v
retrieving revision 1.84
diff -u -r1.84 http_config.c
--- main/http_config.c 2000/11/02 20:05:00 1.84
+++ main/http_config.c 2000/11/12 21:05:13
@@ -1645,7 +1645,7 @@
     s->next = NULL;
     s->addrs = apr_pcalloc(p, sizeof(server_addr_rec));
     /* NOT virtual host; don't match any real network interface */
-    s->addrs->host_addr.s_addr = htonl(INADDR_ANY);
+    apr_get_inaddr(&s->addrs->host_addr, "*", p);
     s->addrs->host_port = 0; /* matches any port */
     s->addrs->virthost = ""; /* must be non-NULL */
     s->names = s->wild_names = NULL;
Index: main/http_connection.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/main/http_connection.c,v
retrieving revision 1.61
diff -u -r1.61 http_connection.c
--- main/http_connection.c 2000/11/09 15:09:50 1.61
+++ main/http_connection.c 2000/11/12 21:05:14
@@ -283,12 +283,16 @@
     conn->notes = apr_make_table(p, 5);

     conn->pool = p;
+/*
     conn->local_addr = *saddr;
+*/
     apr_get_ipaddr(&conn->local_ip, APR_LOCAL, inout);
     conn->base_server = server;
     conn->client_socket = inout;

+/*
     conn->remote_addr = *remaddr;
+*/
     apr_get_ipaddr(&conn->remote_ip, APR_REMOTE, inout);
     conn->id = id;

@@ -300,9 +304,13 @@
 conn_rec *ap_new_apr_connection(apr_pool_t *p, server_rec *server,
                                 apr_socket_t *conn_socket, long id)
 {
+
     struct sockaddr_in *sa_local, *sa_remote;
+

-    apr_get_local_name(&sa_local, conn_socket);
-    apr_get_remote_name(&sa_remote, conn_socket);
+/* XXX - Do we still need this???
+    apr_get_name(&sa_local, APR_LOCAL, conn_socket);
+    apr_get_name(&sa_remote, APR_REMOTE, conn_socket);
+*/
     return ap_new_connection(p, server, conn_socket, sa_remote, sa_local,
id);
 }
Index: main/http_core.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/main/http_core.c,v
retrieving revision 1.213
diff -u -r1.213 http_core.c
--- main/http_core.c 2000/11/10 16:11:13 1.213
+++ main/http_core.c 2000/11/12 21:05:21
@@ -578,11 +578,12 @@
     return conf->response_code_strings[error_index];
 }

-
+/* This code has now moved to APR, but it's here just in case :) */
 /* Code from Harald Hanche-Olsen <hanche@imf.unit.no> */
 static apr_inline void do_double_reverse (conn_rec *conn)
 {
     struct hostent *hptr;
+    apr_in_addr_t *ia = NULL;

     if (conn->double_reverse) {
  /* already done */
@@ -593,13 +594,16 @@
  conn->double_reverse = -1;
  return;
     }
+    /* XXX - This needs fixing for IPv6... APR?? */
     hptr = gethostbyname(conn->remote_host);
     if (hptr)

  char **haddr;
+        apr_uint32_t ipaddr;

  for (haddr = hptr->h_addr_list; *haddr; haddr++) {
-     if (((struct in_addr *)(*haddr))->s_addr
-  == conn->remote_addr.sin_addr.s_addr) {
+            apr_get_socket_inaddr(&ia, APR_REMOTE, conn->client_socket);
+     apr_get_v4_address(&ipaddr, ia);
+            if (((struct in_addr *)(*haddr))->s_addr == ipaddr){
   conn->double_reverse = 1;
   return;
      }
@@ -636,9 +640,11 @@
      ap_str_tolower(conn->remote_host);

      if (hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
-  do_double_reverse(conn);
-  if (conn->double_reverse != 1) {
-      conn->remote_host = NULL;
+  if (apr_check_reverse_lookup(conn->client_socket) != APR_SUCCESS){
+                    conn->double_reverse = -1;
+                    conn->remote_host = NULL;
+  } else {
+                    conn->double_reverse = 1;
   }
      }
  }
@@ -648,10 +654,12 @@
  }
     }
     if (type == REMOTE_DOUBLE_REV) {
- do_double_reverse(conn);
- if (conn->double_reverse == -1) {
+ if(apr_check_reverse_lookup(conn->client_socket) != APR_SUCCESS){
+     conn->double_reverse = -1;
      return NULL;
- }
+ } else {
+            conn->double_reverse = 1;
+        }
     }

 /*
Index: main/http_vhost.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/main/http_vhost.c,v
retrieving revision 1.38
diff -u -r1.38 http_vhost.c
--- main/http_vhost.c 2000/11/10 16:11:14 1.38
+++ main/http_vhost.c 2000/11/12 21:05:23
@@ -186,7 +186,7 @@
 static const char *get_addresses(apr_pool_t *p, const char *w_,
      server_addr_rec ***paddr, apr_port_t port)
 {
-    apr_in_addr_t my_addr;
+    apr_in_addr_t *my_addr = NULL;
     server_addr_rec *sar;
     char *t;
     int i;
@@ -210,15 +210,10 @@
  *t = 0;
     }

-    if (strcasecmp(w, "_default_") == 0
-        || strcmp(w, "255.255.255.255") == 0) {
-        my_addr.s_addr = DEFAULT_VHOST_ADDR;
-    } else {
-        if (apr_get_inaddr(&my_addr, w) != APR_SUCCESS) {
-            ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, NULL,
-                "Cannot resolve host name %s --- ignoring!", w);
-            return NULL;
-        }
+    if (apr_get_inaddr(&my_addr, w, p) != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, NULL,
+            "Cannot resolve host name %s --- ignoring!", w);
+        return NULL;
     }

     sar = apr_pcalloc(p, sizeof(server_addr_rec));
@@ -372,11 +367,11 @@
     unsigned addr;

     /* scan the hash apr_table_t for an exact match first */
-    addr = server_ip->s_addr;
+    apr_get_v4_address(&addr, server_ip);
     bucket = hash_inaddr(addr);
     for (trav = iphash_table[bucket]; trav; trav = trav->next) {
  server_addr_rec *sar = trav->sar;
- if ((sar->host_addr.s_addr == addr)
+ if (apr_inaddr_compare(sar->host_addr, server_ip) == 0
      && (sar->host_port == 0 || sar->host_port == port
   || port == 0)) {
      return trav;
@@ -406,18 +401,20 @@
     name_chain *nc;
     int len;
     char buf[MAX_STRING_LEN];
-
-    if (ic->sar->host_addr.s_addr == DEFAULT_VHOST_ADDR) {
+    apr_uint32_t addr;
+    apr_get_v4_address(&addr, ic->sar->host_addr);
+
+    if (addr == DEFAULT_VHOST_ADDR) {
  len = apr_snprintf(buf, sizeof(buf), "_default_:%u",
   ic->sar->host_port);
     }
-    else if (ic->sar->host_addr.s_addr == INADDR_ANY) {
+    else if (addr == INADDR_ANY) {
  len = apr_snprintf(buf, sizeof(buf), "*:%u",
   ic->sar->host_port);
     }
     else {
  len = apr_snprintf(buf, sizeof(buf), "%pA:%u",
-  &ic->sar->host_addr, ic->sar->host_port);
+  ic->sar->host_addr, ic->sar->host_port);
     }
     if (ic->sar->host_port == 0) {
  buf[len-1] = '*';
@@ -546,10 +543,14 @@
      * 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);
- ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
+ apr_uint32_t addr;
+        unsigned bucket;
+        ipaddr_chain *ic;
+        apr_get_v4_address(&addr, sar->host_addr);
+        bucket = hash_inaddr(addr);
+ ic = new_ipaddr_chain(p, NULL, sar);

- if (sar->host_addr.s_addr != INADDR_ANY) {
+ if (addr != INADDR_ANY) {
      *iphash_table_tail[bucket] = ic;
      iphash_table_tail[bucket] = &ic->next;
  }
@@ -576,9 +577,10 @@
  has_default_vhost_addr = 0;
  for (sar = s->addrs; sar; sar = sar->next) {
      ipaddr_chain *ic;
-
-     if (sar->host_addr.s_addr == DEFAULT_VHOST_ADDR
-  || sar->host_addr.s_addr == INADDR_ANY) {
+            apr_uint32_t addr;
+            apr_get_v4_address(&addr, sar->host_addr);
+     if (addr == DEFAULT_VHOST_ADDR
+  || 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) {
@@ -594,10 +596,10 @@
      }
      else {
   /* see if it matches something we've already got */
-  ic = find_ipaddr(&sar->host_addr, sar->host_port);
+  ic = find_ipaddr(sar->host_addr, sar->host_port);

   if (!ic) {
-      unsigned bucket = hash_inaddr(sar->host_addr.s_addr);
+      unsigned bucket = hash_inaddr(addr);

       ic = new_ipaddr_chain(p, s, sar);
       ic->next = *iphash_table_tail[bucket];
@@ -640,13 +642,14 @@
       s->server_hostname = apr_pstrdup(p, (char *) h->h_name);
   }
   else {
+                    char *sname;
+                    apr_inet_ntop(&sname, s->addrs->host_addr, p);
       /* again, what can we do?  They didn't specify a
          ServerName, and their DNS isn't working. -djg */
       ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
        "Failed to resolve server name "
        "for %s (check DNS) -- or specify an explicit "
-       "ServerName",
-       inet_ntoa(s->addrs->host_addr));
+       "ServerName", sname);
       s->server_hostname =
    apr_pstrdup(p, "bogus_host_without_reverse_dns");
   }
@@ -962,10 +965,12 @@
 {
     ipaddr_chain *trav;
     apr_port_t port;
+    apr_in_addr_t *ia = NULL;
     apr_get_port(&port, APR_LOCAL, conn->client_socket);
+    apr_get_socket_inaddr(&ia, APR_LOCAL, conn->client_socket);

     /* scan the hash apr_table_t for an exact match first */
-    trav = find_ipaddr(&conn->local_addr.sin_addr, port);
+    trav = find_ipaddr(ia, port);
     if (trav) {
  /* save the name_chain for later in case this is a name-vhost */
  conn->vhost_lookup_data = trav->names;
Index: modules/standard/mod_access.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/modules/standard/mod_access.c,v
retrieving revision 1.21
diff -u -r1.21 mod_access.c
--- modules/standard/mod_access.c 2000/11/11 06:06:00 1.21
+++ modules/standard/mod_access.c 2000/11/12 21:05:24
@@ -318,6 +318,8 @@
     int i;
     int gothost = 0;
     const char *remotehost = NULL;
+    apr_in_addr_t *ia;
+    apr_uint32_t ipaddr;

     for (i = 0; i < a->nelts; ++i) {
  if (!(mmask & ap[i].limited))
@@ -334,8 +336,10 @@
      return 1;

  case T_IP:
-     if (ap[i].x.ip.net != APR_INADDR_NONE
-  && (r->connection->remote_addr.sin_addr.s_addr
+            apr_get_socket_inaddr(&ia, APR_REMOTE,
r->connection->client_socket);
+     apr_get_v4_address(&ipaddr, ia);
+            if (ap[i].x.ip.net != APR_INADDR_NONE
+  && (ipaddr
       & ap[i].x.ip.mask) == ap[i].x.ip.net) {
   return 1;
      }





Mime
View raw message