...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;
