]> sjero.net Git - wget/commitdiff
[svn] Improve handling of numeric hosts when ENABLE_IPV6.
authorhniksic <devnull@localhost>
Fri, 4 Mar 2005 19:21:02 +0000 (11:21 -0800)
committerhniksic <devnull@localhost>
Fri, 4 Mar 2005 19:21:02 +0000 (11:21 -0800)
Published in <87psyr6jn7.fsf@xemacs.org>.

ChangeLog
aclocal.m4
configure.in
src/ChangeLog
src/host.c
src/host.h
src/url.c

index 218fd9ef50517180c611308eaeada8091ae856a4..5f1cbb08a01af3b3e612bc8f42a64139195a88d7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2003-02-24  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * configure.in: Don't check for AI_ADDRCONFIG here, it is checked
+       for in the source directly.
+
 2003-02-25  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * libtool.m4, ltmain.sh, config.sub, config.guess: Upgrade to
index 9a2a0666621613f8dfb0f2add4816a9224727300..805c4bbb552032b276a9bafc0ccefe28c52d0629 100644 (file)
@@ -239,30 +239,6 @@ AC_DEFUN([PROTO_INET6],[
 ])
 
 
-AC_DEFUN([GETADDRINFO_AI_ADDRCONFIG],[
-  AC_CACHE_CHECK([if getaddrinfo supports AI_ADDRCONFIG],
-    [wget_cv_gai_ai_addrconfig],[
-    AC_TRY_CPP([
-#include <netdb.h>
-
-#ifndef AI_ADDRCONFIG
- #error Missing AI_ADDRCONFIG
-#endif
-    ],[
-      wget_cv_gai_ai_addrconfig=yes
-    ],[
-      wget_cv_gai_ai_addrconfig=no
-    ])
-  ])
-
-  if test "X$wget_cv_gai_ai_addrconfig" = "Xyes"; then :
-    $1
-  else :
-    $2
-  fi
-])
-
-
 AC_DEFUN([WGET_STRUCT_SOCKADDR_STORAGE],[
   AC_CHECK_TYPES([struct sockaddr_storage],[], [], [
 #include <sys/types.h>
index f2872f78cf86727647e539f3e6f4cebbb3bf318f..03dd4342c12614ace4a0e237c0f408119924cbac 100644 (file)
@@ -494,14 +494,7 @@ AC_ARG_ENABLE(ipv6,
 )
 
 if test "X$ipv6" = "Xyes" || test "X$check_for_ipv6" = "Xyes"; then
-  AC_CHECK_FUNCS(getaddrinfo, [
-    GETADDRINFO_AI_ADDRCONFIG([
-      AC_DEFINE(
-        [HAVE_GETADDRINFO_AI_ADDRCONFIG], 1, 
-        [Define if the system headers support the AI_ADDRCONFIG flag.]
-      )
-    ])
-  ], [
+  AC_CHECK_FUNCS(getaddrinfo, [], [
     AC_MSG_NOTICE([Disabling IPv6 support: your system does not support getaddrinfo(3)])
     ipv6=no
   ])
index 9c250660e9707c2a5a5a25888b8f519f4ca39ef3..90a79d4dcd26a6c4960f46c62d2783df93c6de96 100644 (file)
@@ -1,3 +1,15 @@
+2005-02-24  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * host.c (lookup_host): Test for AI_ADDRCONFIG directly, instead
+       of checking for HAVE_GETADDRINFO_AI_ADDRCONFIG.
+
+2005-02-23  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * host.c (is_valid_ipv6_address): Move here from url.c.
+       (lookup_host): If the address is numeric, don't print the
+       "resolving..." line, don't set up DNS timeouts, and set the
+       AI_NUMERICHOST hint, where available.
+
 2005-02-26  Gisle Vanem  <giva@bgnett.no>
 
        * utils.c: Use the nnnLL syntax under GCC.  Define struct_stat to
index 9d83e038119c9c4f946d51fec0f4e8a2b7b7178d..6f96845c63689008af0447e75349f22587bee44f 100644 (file)
@@ -428,6 +428,149 @@ pretty_print_address (const ip_address *addr)
   abort ();
   return NULL;
 }
+
+/* The following two functions were adapted from glibc. */
+
+static int
+is_valid_ipv4_address (const char *str, const char *end)
+{
+  int saw_digit = 0;
+  int octets = 0;
+  int val = 0;
+
+  while (str < end)
+    {
+      int ch = *str++;
+
+      if (ch >= '0' && ch <= '9')
+       {
+         val = val * 10 + (ch - '0');
+
+         if (val > 255)
+           return 0;
+         if (saw_digit == 0)
+           {
+             if (++octets > 4)
+               return 0;
+             saw_digit = 1;
+           }
+       }
+      else if (ch == '.' && saw_digit == 1)
+       {
+         if (octets == 4)
+           return 0;
+         val = 0;
+         saw_digit = 0;
+       }
+      else
+       return 0;
+    }
+  if (octets < 4)
+    return 0;
+  
+  return 1;
+}
+
+int
+is_valid_ipv6_address (const char *str, const char *end)
+{
+  enum {
+    NS_INADDRSZ  = 4,
+    NS_IN6ADDRSZ = 16,
+    NS_INT16SZ   = 2
+  };
+
+  const char *curtok;
+  int tp;
+  const char *colonp;
+  int saw_xdigit;
+  unsigned int val;
+
+  tp = 0;
+  colonp = NULL;
+
+  if (str == end)
+    return 0;
+  
+  /* Leading :: requires some special handling. */
+  if (*str == ':')
+    {
+      ++str;
+      if (str == end || *str != ':')
+       return 0;
+    }
+
+  curtok = str;
+  saw_xdigit = 0;
+  val = 0;
+
+  while (str < end)
+    {
+      int ch = *str++;
+
+      /* if ch is a number, add it to val. */
+      if (ISXDIGIT (ch))
+       {
+         val <<= 4;
+         val |= XDIGIT_TO_NUM (ch);
+         if (val > 0xffff)
+           return 0;
+         saw_xdigit = 1;
+         continue;
+       }
+
+      /* if ch is a colon ... */
+      if (ch == ':')
+       {
+         curtok = str;
+         if (saw_xdigit == 0)
+           {
+             if (colonp != NULL)
+               return 0;
+             colonp = str + tp;
+             continue;
+           }
+         else if (str == end)
+           return 0;
+         if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
+           return 0;
+         tp += NS_INT16SZ;
+         saw_xdigit = 0;
+         val = 0;
+         continue;
+       }
+
+      /* if ch is a dot ... */
+      if (ch == '.' && (tp <= NS_IN6ADDRSZ - NS_INADDRSZ)
+         && is_valid_ipv4_address (curtok, end) == 1)
+       {
+         tp += NS_INADDRSZ;
+         saw_xdigit = 0;
+         break;
+       }
+    
+      return 0;
+    }
+
+  if (saw_xdigit == 1)
+    {
+      if (tp > NS_IN6ADDRSZ - NS_INT16SZ) 
+       return 0;
+      tp += NS_INT16SZ;
+    }
+
+  if (colonp != NULL)
+    {
+      if (tp == NS_IN6ADDRSZ) 
+       return 0;
+      tp = NS_IN6ADDRSZ;
+    }
+
+  if (tp != NS_IN6ADDRSZ)
+    return 0;
+
+  return 1;
+}
 \f
 /* Simple host cache, used by lookup_host to speed up resolving.  The
    cache doesn't handle TTL because Wget is a fairly short-lived
@@ -521,12 +664,14 @@ lookup_host (const char *host, int flags)
   struct address_list *al;
   int silent = flags & LH_SILENT;
   int use_cache;
+  int numeric_address = 0;
+  double timeout = opt.dns_timeout;
 
 #ifndef ENABLE_IPV6
   /* If we're not using getaddrinfo, first check if HOST specifies a
-     numeric IPv4 address.  gethostbyname is not required to accept
-     dotted-decimal IPv4 addresses, and some implementations (e.g. the
-     Ultrix one and possibly Winsock) indeed don't.  */
+     numeric IPv4 address.  Some implementations of gethostbyname
+     (e.g. the Ultrix one and possibly Winsock) don't accept
+     dotted-decimal IPv4 addresses.  */
   {
     uint32_t addr_ipv4 = (uint32_t)inet_addr (host);
     if (addr_ipv4 != (uint32_t) -1)
@@ -539,13 +684,24 @@ lookup_host (const char *host, int flags)
        return address_list_from_ipv4_addresses (vec);
       }
   }
+#else  /* ENABLE_IPV6 */
+  /* If we're using getaddrinfo, at least check whether the address is
+     already numeric, in which case there is no need to print the
+     "Resolving..." output.  (This comes at no additional cost since
+     the is_valid_ipv*_address are already required for
+     url_parse.)  */
+  {
+    const char *end = host + strlen (host);
+    if (is_valid_ipv4_address (host, end) || is_valid_ipv6_address (host, end))
+      numeric_address = 1;
+  }
 #endif
 
   /* Cache is normally on, but can be turned off with --no-dns-cache.
      Don't cache passive lookups under IPv6.  */
   use_cache = opt.dns_cache;
 #ifdef ENABLE_IPV6
-  if (flags & LH_BIND)
+  if ((flags & LH_BIND) || numeric_address)
     use_cache = 0;
 #endif
 
@@ -566,7 +722,7 @@ lookup_host (const char *host, int flags)
 
   /* No luck with the cache; resolve HOST. */
 
-  if (!silent)
+  if (!silent && !numeric_address)
     logprintf (LOG_VERBOSE, _("Resolving %s... "), host);
 
 #ifdef ENABLE_IPV6
@@ -583,7 +739,7 @@ lookup_host (const char *host, int flags)
     else
       {
        hints.ai_family = AF_UNSPEC;
-#ifdef HAVE_GETADDRINFO_AI_ADDRCONFIG
+#ifdef AI_ADDRCONFIG
        hints.ai_flags |= AI_ADDRCONFIG;
 #else
        /* On systems without AI_ADDRCONFIG, emulate it by manually
@@ -595,7 +751,19 @@ lookup_host (const char *host, int flags)
     if (flags & LH_BIND)
       hints.ai_flags |= AI_PASSIVE;
 
-    err = getaddrinfo_with_timeout (host, NULL, &hints, &res, opt.dns_timeout);
+#ifdef AI_NUMERICHOST
+    if (numeric_address)
+      {
+       /* Where available, the AI_NUMERICHOST hint can prevent costly
+          access to DNS servers.  */
+       hints.ai_flags |= AI_NUMERICHOST;
+       timeout = 0;            /* no timeout needed when "resolving"
+                                  numeric hosts -- avoid setting up
+                                  signal handlers and such. */
+      }
+#endif
+
+    err = getaddrinfo_with_timeout (host, NULL, &hints, &res, timeout);
     if (err != 0 || res == NULL)
       {
        if (!silent)
@@ -612,9 +780,9 @@ lookup_host (const char *host, int flags)
        return NULL;
       }
   }
-#else
+#else  /* not ENABLE_IPV6 */
   {
-    struct hostent *hptr = gethostbyname_with_timeout (host, opt.dns_timeout);
+    struct hostent *hptr = gethostbyname_with_timeout (host, timeout);
     if (!hptr)
       {
        if (!silent)
@@ -630,11 +798,11 @@ lookup_host (const char *host, int flags)
     /* Do older systems have h_addr_list?  */
     al = address_list_from_ipv4_addresses (hptr->h_addr_list);
   }
-#endif
+#endif /* not ENABLE_IPV6 */
 
   /* Print the addresses determined by DNS lookup, but no more than
      three.  */
-  if (!silent)
+  if (!silent && !numeric_address)
     {
       int i;
       int printmax = al->count <= 3 ? al->count : 3;
index abe086b936a333be13702ba406e170bd917eec6e..495f701df003dcb0b705fded24c9700d432b176f 100644 (file)
@@ -108,6 +108,9 @@ int address_list_connected_p PARAMS ((const struct address_list *));
 void address_list_release PARAMS ((struct address_list *));
 
 const char *pretty_print_address PARAMS ((const ip_address *));
+#ifdef ENABLE_IPV6
+int is_valid_ipv6_address PARAMS ((const char *, const char *));
+#endif
 
 int accept_domain PARAMS ((struct url *));
 int sufmatch PARAMS ((const char **, const char *));
index 8aed967d7722441c402e1ebafa972e1a84e869de..7762473f5c067944fff17a68ea7d1644117c8b61 100644 (file)
--- a/src/url.c
+++ b/src/url.c
@@ -47,6 +47,7 @@ so, delete this exception statement from your version.  */
 #include "wget.h"
 #include "utils.h"
 #include "url.h"
+#include "host.h"  /* for is_valid_ipv6_address */
 
 #ifndef errno
 extern int errno;
@@ -655,151 +656,6 @@ static const char *parse_errors[] = {
   N_("Invalid IPv6 numeric address")
 };
 
-#ifdef ENABLE_IPV6
-/* The following two functions were adapted from glibc. */
-
-static int
-is_valid_ipv4_address (const char *str, const char *end)
-{
-  int saw_digit = 0;
-  int octets = 0;
-  int val = 0;
-
-  while (str < end)
-    {
-      int ch = *str++;
-
-      if (ch >= '0' && ch <= '9')
-       {
-         val = val * 10 + (ch - '0');
-
-         if (val > 255)
-           return 0;
-         if (saw_digit == 0)
-           {
-             if (++octets > 4)
-               return 0;
-             saw_digit = 1;
-           }
-       }
-      else if (ch == '.' && saw_digit == 1)
-       {
-         if (octets == 4)
-           return 0;
-         val = 0;
-         saw_digit = 0;
-       }
-      else
-       return 0;
-    }
-  if (octets < 4)
-    return 0;
-  
-  return 1;
-}
-
-static int
-is_valid_ipv6_address (const char *str, const char *end)
-{
-  enum {
-    NS_INADDRSZ  = 4,
-    NS_IN6ADDRSZ = 16,
-    NS_INT16SZ   = 2
-  };
-
-  const char *curtok;
-  int tp;
-  const char *colonp;
-  int saw_xdigit;
-  unsigned int val;
-
-  tp = 0;
-  colonp = NULL;
-
-  if (str == end)
-    return 0;
-  
-  /* Leading :: requires some special handling. */
-  if (*str == ':')
-    {
-      ++str;
-      if (str == end || *str != ':')
-       return 0;
-    }
-
-  curtok = str;
-  saw_xdigit = 0;
-  val = 0;
-
-  while (str < end)
-    {
-      int ch = *str++;
-
-      /* if ch is a number, add it to val. */
-      if (ISXDIGIT (ch))
-       {
-         val <<= 4;
-         val |= XDIGIT_TO_NUM (ch);
-         if (val > 0xffff)
-           return 0;
-         saw_xdigit = 1;
-         continue;
-       }
-
-      /* if ch is a colon ... */
-      if (ch == ':')
-       {
-         curtok = str;
-         if (saw_xdigit == 0)
-           {
-             if (colonp != NULL)
-               return 0;
-             colonp = str + tp;
-             continue;
-           }
-         else if (str == end)
-           return 0;
-         if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
-           return 0;
-         tp += NS_INT16SZ;
-         saw_xdigit = 0;
-         val = 0;
-         continue;
-       }
-
-      /* if ch is a dot ... */
-      if (ch == '.' && (tp <= NS_IN6ADDRSZ - NS_INADDRSZ)
-         && is_valid_ipv4_address (curtok, end) == 1)
-       {
-         tp += NS_INADDRSZ;
-         saw_xdigit = 0;
-         break;
-       }
-    
-      return 0;
-    }
-
-  if (saw_xdigit == 1)
-    {
-      if (tp > NS_IN6ADDRSZ - NS_INT16SZ) 
-       return 0;
-      tp += NS_INT16SZ;
-    }
-
-  if (colonp != NULL)
-    {
-      if (tp == NS_IN6ADDRSZ) 
-       return 0;
-      tp = NS_IN6ADDRSZ;
-    }
-
-  if (tp != NS_IN6ADDRSZ)
-    return 0;
-
-  return 1;
-}
-#endif
-
 /* Parse a URL.
 
    Return a new struct url if successful, NULL on error.  In case of