]> sjero.net Git - wget/commitdiff
[svn] Split passive host lookups to a separate function.
authorhniksic <devnull@localhost>
Mon, 10 Nov 2003 01:38:09 +0000 (17:38 -0800)
committerhniksic <devnull@localhost>
Mon, 10 Nov 2003 01:38:09 +0000 (17:38 -0800)
src/ChangeLog
src/connect.c
src/connect.h
src/host.c
src/host.h

index 52ac37a020adc106e6560f40785a18378a73a35e..3aadeb3705098bf53099fb022d6e54c6affaf8a4 100644 (file)
@@ -1,3 +1,13 @@
+2003-11-10  Hrvoje Niksic  <hniksic@xemacs.org>
+
+       * connect.c (resolve_bind_address): Call lookup_host_passive.
+       Make sure that opt.bind_address is resolved only once.
+
+       * host.c (lookup_host_passive): New function, handles "passive"
+       lookups.
+       (lookup_host): Remove the passive flags.  Remove the
+       family-related flags -- use ip_default_family instead.
+
 2003-11-09  Hrvoje Niksic  <hniksic@xemacs.org>
 
        * html-url.c: Get URLs from <object data="...">.
index 25c159622d6b89384cd69122c7c2bb1ae087de96..3ed03c71b5339f640aa7ee4a32fd2c12ca45d898 100644 (file)
@@ -166,28 +166,41 @@ sockaddr_size (const struct sockaddr *sa)
 }
 \f
 static int
-resolve_bind_address (const char *host, struct sockaddr *sa, int flags)
+resolve_bind_address (struct sockaddr *sa)
 {
   struct address_list *al;
 
-  /* #### Shouldn't we do this only once?  opt.bind_address won't
-     change during a Wget run!  */
+  /* Make sure this is called only once.  opt.bind_address doesn't
+     change during a Wget run.  */
+  static int called, should_bind;
+  static ip_address ip;
+  if (called)
+    {
+      if (should_bind)
+       sockaddr_set_data (sa, &ip, 0);
+      return should_bind;
+    }
+  called = 1;
 
-  al = lookup_host (host, flags | LH_SILENT | LH_PASSIVE);
-  if (al == NULL)
+  al = lookup_host_passive (opt.bind_address);
+  if (!al)
     {
-      /* #### We should print the error message here. */
+      /* #### We should be able to print the error message here. */
       logprintf (LOG_NOTQUIET,
                 _("%s: unable to resolve bind address `%s'; disabling bind.\n"),
                 exec_name, opt.bind_address);
+      should_bind = 0;
       return 0;
     }
 
   /* Pick the first address in the list and use it as bind address.
-     Perhaps we should try multiple addresses, but I don't think
-     that's necessary in practice.  */
-  sockaddr_set_data (sa, address_list_address_at (al, 0), 0);
+     Perhaps we should try multiple addresses in succession, but I
+     don't think that's necessary in practice.  */
+  ip = *address_list_address_at (al, 0);
   address_list_release (al);
+
+  sockaddr_set_data (sa, &ip, 0);
+  should_bind = 1;
   return 1;
 }
 \f
@@ -280,7 +293,7 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
         address.  */
       struct sockaddr_storage bind_ss;
       struct sockaddr *bind_sa = (struct sockaddr *)&bind_ss;
-      if (resolve_bind_address (opt.bind_address, bind_sa, 0))
+      if (resolve_bind_address (bind_sa))
        {
           if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0)
            goto err;
index aa485c1c6c38510e2f5d098f2605a2e53253e508..a0c830c6c5b2da5b36347e0ab9659a633220ed91 100644 (file)
@@ -32,10 +32,6 @@ so, delete this exception statement from your version.  */
 
 #include "host.h"              /* for definition of ip_address */
 
-/* bindport flags */
-#define BIND_ON_IPV4_ONLY LH_IPV4_ONLY
-#define BIND_ON_IPV6_ONLY LH_IPV6_ONLY
-
 #ifndef ENABLE_IPV6
 # ifndef HAVE_SOCKADDR_STORAGE
 #  define sockaddr_storage sockaddr_in
index 814835728af7dc7ebb65dc22b891fa759033bc9e..93a6f8f7f72d33b739f479ae4a5006cba12d094a 100644 (file)
@@ -81,6 +81,13 @@ extern int h_errno;
 /* Mapping between known hosts and to lists of their addresses. */
 
 static struct hash_table *host_name_addresses_map;
+
+#ifdef ENABLE_IPV6
+/* The default IP family for looking up host names.  This should be
+   moved to an entry in struct options when we implement the
+   --inet4/--inet6 flags.  */
+static int ip_default_family = AF_UNSPEC;
+#endif
 \f
 /* Lists of addresses.  This should eventually be extended to handle
    IPv6.  */
@@ -326,6 +333,26 @@ gethostbyname_with_timeout (const char *host_name, double timeout)
   return ctx.hptr;
 }
 
+/* Print error messages for host errors.  */
+static char *
+host_errstr (int error)
+{
+  /* Can't use switch since some of these constants can be equal,
+     which makes the compiler complain about duplicate case
+     values.  */
+  if (error == HOST_NOT_FOUND
+      || error == NO_RECOVERY
+      || error == NO_DATA
+      || error == NO_ADDRESS)
+    return _("Host not found");
+  else if (error == TRY_AGAIN)
+    /* Message modeled after what gai_strerror returns in similar
+       circumstances.  */
+    return _("Temporary failure in name resolution");
+  else
+    return _("Unknown error");
+}
+
 #else  /* ENABLE_IPV6 */
 
 struct gaiwt_context {
@@ -450,30 +477,19 @@ forget_host_lookup (const char *host)
    this function, or set opt.dns_cache to 0 to globally disable
    caching.
 
-   FLAGS can be a combination of:
-     LH_SILENT    - don't print the "resolving ... done" message.
-     LH_IPV4_ONLY - return only IPv4 addresses.
-     LH_IPV6_ONLY - return only IPv6 addresses.  */
+   If SILENT is non-zero, progress messages are not printed.  */
 
 struct address_list *
-lookup_host (const char *host, int flags)
+lookup_host (const char *host, int silent)
 {
   struct address_list *al = NULL;
 
 #ifdef ENABLE_IPV6
   int err;
   struct addrinfo hints, *res;
-
   xzero (hints);
   hints.ai_socktype = SOCK_STREAM;
-
-  /* Should we inspect opt.<something> directly?  */
-  if (flags & LH_IPV4_ONLY)
-    hints.ai_family = AF_INET;
-  else if (flags & LH_IPV6_ONLY)
-    hints.ai_family = AF_INET6;
-  else
-    hints.ai_family = AF_UNSPEC;
+  hints.ai_family = ip_default_family;
 #endif
 
   /* First, try to check whether the address is already a numeric
@@ -486,8 +502,6 @@ lookup_host (const char *host, int flags)
 
 #ifdef ENABLE_IPV6
   hints.ai_flags = AI_NUMERICHOST;
-  if (flags & LH_PASSIVE)
-    hints.ai_flags |= AI_PASSIVE;
 
   /* No need to specify timeout, as we're not resolving HOST, but
      merely translating it from the presentation (ASCII) to network
@@ -528,20 +542,18 @@ lookup_host (const char *host, int flags)
        }
     }
 
-  if (!(flags & LH_SILENT))
-    logprintf (LOG_VERBOSE, _("Resolving %s... "), host);
+  /* No luck with the cache; resolve the host name. */
 
-  /* Host name lookup goes on below. */
+  if (!silent)
+    logprintf (LOG_VERBOSE, _("Resolving %s... "), host);
 
 #ifdef ENABLE_IPV6
   hints.ai_flags = 0;
-  if (flags & LH_PASSIVE) 
-    hints.ai_flags |= AI_PASSIVE;
 
   err = getaddrinfo_with_timeout (host, NULL, &hints, &res, opt.dns_timeout);
   if (err != 0 || res == NULL)
     {
-      if (!(flags & LH_SILENT))
+      if (!silent)
        logprintf (LOG_VERBOSE, _("failed: %s.\n"),
                   err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno));
       return NULL;
@@ -553,16 +565,16 @@ lookup_host (const char *host, int flags)
     struct hostent *hptr = gethostbyname_with_timeout (host, opt.dns_timeout);
     if (!hptr)
       {
-       if (!(flags & LH_SILENT))
+       if (!silent)
          {
            if (errno != ETIMEDOUT)
-             logprintf (LOG_VERBOSE, _("failed: %s.\n"), herrmsg (h_errno));
+             logprintf (LOG_VERBOSE, _("failed: %s.\n"),
+                        host_errstr (h_errno));
            else
              logputs (LOG_VERBOSE, _("failed: timed out.\n"));
          }
        return NULL;
       }
-    assert (hptr->h_length == 4);
     /* Do older systems have h_addr_list?  */
     al = address_list_from_ipv4_addresses (hptr->h_addr_list);
   }
@@ -570,7 +582,7 @@ lookup_host (const char *host, int flags)
 
   /* Print the addresses determined by DNS lookup, but no more than
      three.  */
-  if (!(flags & LH_SILENT))
+  if (!silent)
     {
       int i;
       int printmax = al->count <= 3 ? al->count : 3;
@@ -592,6 +604,43 @@ lookup_host (const char *host, int flags)
 
   return al;
 }
+
+/* Resolve HOST to get an address for use with bind(2).  Do *not* use
+   this for sockets to be used with connect(2).
+
+   This is a function separate from lookup_host because the results it
+   returns are different -- it uses the AI_PASSIVE flag to
+   getaddrinfo.  Because of this distinction, it doesn't store the
+   results in the cache.  It prints nothing and implements no timeouts
+   because it should normally only be used with local addresses
+   (typically "localhost" or numeric addresses of different local
+   interfaces.)
+
+   Without IPv6, this function just calls lookup_host.  */
+
+struct address_list *
+lookup_host_passive (const char *host)
+{
+#ifdef ENABLE_IPV6
+  struct address_list *al = NULL;
+  int err;
+  struct addrinfo hints, *res;
+
+  xzero (hints);
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_family = ip_default_family;
+  hints.ai_flags = AI_PASSIVE;
+
+  err = getaddrinfo (host, NULL, &hints, &res);
+  if (err != 0 || res == NULL)
+    return NULL;
+  al = address_list_from_addrinfo (res);
+  freeaddrinfo (res);
+  return al;
+#else
+  return lookup_host (host, 1);
+#endif
+}
 \f
 /* Determine whether a URL is acceptable to be followed, according to
    a list of domains to accept.  */
@@ -635,22 +684,6 @@ sufmatch (const char **list, const char *what)
   return 0;
 }
 
-/* Print error messages for host errors.  */
-char *
-herrmsg (int error)
-{
-  /* Can't use switch since some constants are equal (at least on my
-     system), and the compiler signals "duplicate case value".  */
-  if (error == HOST_NOT_FOUND
-      || error == NO_RECOVERY
-      || error == NO_DATA
-      || error == NO_ADDRESS
-      || error == TRY_AGAIN)
-    return _("Host not found");
-  else
-    return _("Unknown error");
-}
-
 static int
 host_cleanup_mapper (void *key, void *value, void *arg_ignored)
 {
index 1bb514ca13e5c56a69dcd6c2af8f09632bd9bb29..8666c08c7e05112c6dd024c284a66f888230774e 100644 (file)
@@ -90,16 +90,9 @@ typedef struct {
 #define ADDRESS_IPV6_DATA(x) ((void *)&(x)->u.ipv6.addr)
 #define ADDRESS_IPV6_SCOPE(x) ((x)->u.ipv6.scope_id)
 
-
-/* Flags for lookup_host */
-#define LH_SILENT    0x0001
-#define LH_PASSIVE   0x0002
-#define LH_IPV4_ONLY 0x0004
-#define LH_IPV6_ONLY 0x0008
-
 /* Function declarations */
 struct address_list *lookup_host PARAMS ((const char *, int));
-char *herrmsg PARAMS ((int));
+struct address_list *lookup_host_passive PARAMS ((const char *));
 
 void forget_host_lookup PARAMS ((const char *));