Joe Orton wrote:
On Tue, May 18, 2004 at 04:58:14PM -0400, Jeff Trawick wrote:

Previously we went through this mess on older Mac OS X (DNS queries only?)

I just realized that the glibc shipping with RHAS 2.1 and 3.0 (and surely many other Linux distros) has a problem with getnameinfo() for IPv4-mapped address for something defined in host file but not in DNS.
...
Shall we just assume that the GETNAMEINFO_IPV4_MAPPED_FAILS logic can be used on all platforms (incurring the minor overhead), instead of trying to be clever?


Sounds very sensible.  The code can be simplified to avoid a pointer
dereference too...

--- network_io/unix/sockaddr.c  4 Mar 2004 16:17:25 -0000       1.49
+++ network_io/unix/sockaddr.c  19 May 2004 09:19:07 -0000

updated patch attached to remove configure-time logic and protect references to IPv6 goodies with APR_HAVE_IPV6...


any comments from the crowd before I commit to both branches?
? build-outputs.mk.python
? build-outputs.mk.tmp
? build.conf.headers
? build.conf.paths
? build.conf.platform_dirs
? gen-build.sh
? out
? stderr
? test.tar
Index: build/apr_network.m4
===================================================================
RCS file: /home/cvs/apr/build/apr_network.m4,v
retrieving revision 1.30
diff -u -r1.30 apr_network.m4
--- build/apr_network.m4        23 Dec 2003 14:54:55 -0000      1.30
+++ build/apr_network.m4        20 May 2004 11:33:55 -0000
@@ -175,80 +175,6 @@
 ])
 
 dnl
-dnl check for getnameinfo() that properly resolves IPv4-mapped IPv6 addresses
-dnl
-dnl Darwin is known not to map them correctly
-dnl
-AC_DEFUN(APR_CHECK_GETNAMEINFO_IPV4_MAPPED,[
-  AC_CACHE_CHECK(whether getnameinfo resolves IPv4-mapped IPv6 addresses,
-                 ac_cv_getnameinfo_ipv4_mapped,[
-  AC_TRY_RUN( [
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-void main(void) {
-    struct sockaddr_in6 sa = {0};
-    struct in_addr ipv4;
-#if defined(NI_MAXHOST)
-    char hbuf[NI_MAXHOST];
-#else
-    char hbuf[256];
-#endif
-    unsigned int *addr32;
-    int error;
-
-    ipv4.s_addr = inet_addr("127.0.0.1");
-
-    sa.sin6_family = AF_INET6;
-    sa.sin6_port = 0;
-
-    addr32 = (unsigned int *)&sa.sin6_addr;
-    addr32[2] = htonl(0x0000FFFF);
-    addr32[3] = ipv4.s_addr;
-
-#ifdef SIN6_LEN
-    sa.sin6_len = sizeof(sa);
-#endif
-
-    error = getnameinfo((const struct sockaddr *)&sa, sizeof(sa),
-                        hbuf, sizeof(hbuf), NULL, 0,
-                        NI_NAMEREQD);
-    if (error) {
-        exit(1);
-    } else {
-        exit(0);
-    }
-}
-],[
-  ac_cv_getnameinfo_ipv4_mapped="yes"
-],[
-  ac_cv_getnameinfo_ipv4_mapped="no"
-],[
-  ac_cv_getnameinfo_ipv4_mapped="yes"
-])])
-if test "$ac_cv_getnameinfo_ipv4_mapped" = "no"; then
-  AC_DEFINE(GETNAMEINFO_IPV4_MAPPED_FAILS, 1,
-            [Define if getnameinfo does not map IPv4 address correctly])
-fi
-])
-
-dnl
 dnl Checks the definition of gethostbyname_r and gethostbyaddr_r
 dnl which are different for glibc, solaris and assorted other operating
 dnl systems
Index: network_io/unix/sockaddr.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sockaddr.c,v
retrieving revision 1.49
diff -u -r1.49 sockaddr.c
--- network_io/unix/sockaddr.c  4 Mar 2004 16:17:25 -0000       1.49
+++ network_io/unix/sockaddr.c  20 May 2004 11:33:56 -0000
@@ -575,27 +575,26 @@
      * a numeric address string if it fails to resolve the host name;
      * that is *not* what we want here
      *
-     * Additionally, if we know getnameinfo() doesn't handle IPv4-mapped
-     * IPv6 addresses correctly, drop down to IPv4 before calling
-     * getnameinfo().
+     * For IPv4-mapped IPv6 addresses, drop down to IPv4 before calling
+     * getnameinfo() to avoid getnameinfo bugs (MacOS X, glibc).
      */
-#ifdef GETNAMEINFO_IPV4_MAPPED_FAILS
+#if APR_HAVE_IPV6
     if (sockaddr->family == AF_INET6 &&
         IN6_IS_ADDR_V4MAPPED(&sockaddr->sa.sin6.sin6_addr)) {
-        struct apr_sockaddr_t tmpsa;
-        tmpsa.sa.sin.sin_family = AF_INET;
-        tmpsa.sa.sin.sin_addr.s_addr = ((uint32_t *)sockaddr->ipaddr_ptr)[3];
+        struct sockaddr_in tmpsa;
+        tmpsa.sin_family = AF_INET;
+        tmpsa.sin_addr.s_addr = sockaddr->sa.sin6.sin6_addr.s6_addr[3];
 
-        rc = getnameinfo((const struct sockaddr *)&tmpsa.sa,
-                         sizeof(struct sockaddr_in),
+        rc = getnameinfo((const struct sockaddr *)&tmpsa, sizeof(tmpsa),
                          tmphostname, sizeof(tmphostname), NULL, 0,
                          flags != 0 ? flags : NI_NAMEREQD);
     }
     else
-#endif
-    rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen,
-                     tmphostname, sizeof(tmphostname), NULL, 0,
-                     flags != 0 ? flags : NI_NAMEREQD);
+#endif /* APR_HAVE_IPV6 */
+        rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, 
sockaddr->salen,
+                         tmphostname, sizeof(tmphostname), NULL, 0,
+                         flags != 0 ? flags : NI_NAMEREQD);
+
     if (rc != 0) {
         *hostname = NULL;
 

Reply via email to