Backporting these changes is expected to work around a bizarro
resolver glitch on z/OS and it ought to save worthless lookups for a
number of people.  (Apache httpd proxy, anyone?)

Is there any particular reason this wasn't already backported to 0.9? 
Any objections, assuming that I ensure that the backport works fine on
a few platforms?
Index: network_io/unix/sockaddr.c
===================================================================
--- network_io/unix/sockaddr.c  (revision 395559)
+++ network_io/unix/sockaddr.c  (working copy)
@@ -336,6 +336,14 @@
     memset(&hints, 0, sizeof(hints));
     hints.ai_family = family;
     hints.ai_socktype = SOCK_STREAM;
+#ifdef HAVE_GAI_ADDRCONFIG
+    if (family == APR_UNSPEC) {
+        /* By default, only look up addresses using address types for
+         * which a local interface is configured, i.e. no IPv6 if no
+         * IPv6 interfaces configured. */
+        hints.ai_flags = AI_ADDRCONFIG;
+    }
+#endif
     if(hostname == NULL) {
 #ifdef AI_PASSIVE 
         /* If hostname is NULL, assume we are trying to bind to all
@@ -358,6 +366,13 @@
         servname = apr_itoa(p, port);
     }
     error = getaddrinfo(hostname, servname, &hints, &ai_list);
+#ifdef HAVE_GAI_ADDRCONFIG
+    if (error == EAI_BADFLAGS && family == APR_UNSPEC) {
+        /* Retry with no flags if AI_ADDRCONFIG was rejected. */
+        hints.ai_flags = 0;
+        error = getaddrinfo(hostname, servname, &hints, &ai_list);
+    }
+#endif
     if (error) {
 #ifndef WIN32
         if (error == EAI_SYSTEM) {
@@ -384,7 +399,7 @@
         apr_sockaddr_t *new_sa;
 
         /* Ignore anything bogus: getaddrinfo in some old versions of
-         * glibc will return AF_UNIX entries for AF_UNSPEC+AI_PASSIVE
+         * glibc will return AF_UNIX entries for APR_UNSPEC+AI_PASSIVE
          * lookups. */
         if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
             ai = ai->ai_next;
@@ -560,7 +575,7 @@
 
     if ((masked = flags & (APR_IPV4_ADDR_OK | APR_IPV6_ADDR_OK))) {
         if (!hostname ||
-            family != AF_UNSPEC ||
+            family != APR_UNSPEC ||
             masked == (APR_IPV4_ADDR_OK | APR_IPV6_ADDR_OK)) {
             return APR_EINVAL;
         }
Index: configure.in
===================================================================
--- configure.in        (revision 395559)
+++ configure.in        (working copy)
@@ -1821,6 +1821,7 @@
         if test "x$have_sockaddr_in6" = "x1"; then
             if test "x$ac_cv_working_getaddrinfo" = "xyes"; then
                 if test "x$ac_cv_working_getnameinfo" = "xyes"; then
+                    APR_CHECK_GETADDRINFO_ADDRCONFIG
                     have_ipv6="1"
                     ipv6_result="yes"
                 else
Index: build/apr_network.m4
===================================================================
--- build/apr_network.m4        (revision 395559)
+++ build/apr_network.m4        (working copy)
@@ -57,6 +57,40 @@
 fi
 ])
 
+dnl Check whether the AI_ADDRCONFIG flag can be used with getaddrinfo
+AC_DEFUN([APR_CHECK_GETADDRINFO_ADDRCONFIG], [
+  AC_CACHE_CHECK(for working AI_ADDRCONFIG, apr_cv_gai_addrconfig, [
+  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
+
+int main(int argc, char **argv) {
+    struct addrinfo hints, *ai;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_ADDRCONFIG;
+    return getaddrinfo("localhost", NULL, &hints, &ai) != 0;
+}], [apr_cv_gai_addrconfig=yes], 
+    [apr_cv_gai_addrconfig=no],
+    [apr_cv_gai_addrconfig=no])])
+
+if test $apr_cv_gai_addrconfig = yes; then
+   AC_DEFINE(HAVE_GAI_ADDRCONFIG, 1, [Define if getaddrinfo accepts the 
AI_ADDRCONFIG flag])
+fi
+])
+
 dnl
 dnl check for working getnameinfo()
 dnl



Reply via email to