]> sjero.net Git - wget/commitdiff
[svn] Don't reuse IP addresses proven to be faulty, unless only such ones remain.
authorhniksic <devnull@localhost>
Tue, 27 Nov 2001 14:55:40 +0000 (06:55 -0800)
committerhniksic <devnull@localhost>
Tue, 27 Nov 2001 14:55:40 +0000 (06:55 -0800)
Published in <sxs8zcsfemf.fsf@florida.arsdigita.de>.

src/ChangeLog
src/connect.c
src/host.c
src/host.h

index 435e32408171d49b4ebfb2aa1ac60f83f0c981c8..3afdfbc8374b00f231963fb6a94bd91f7a58eb74 100644 (file)
@@ -1,3 +1,12 @@
+2001-11-27  Hrvoje Niksic  <hniksic@arsdigita.com>
+
+       * connect.c (connect_to_many): Use address_list_set_faulty to
+       prevent the faulty address from being reused.
+
+       * host.c (address_list_set_faulty): New function.
+       (address_list_get_bounds): New function, instead of
+       address_list_count.
+
 2001-11-27  Hrvoje Niksic  <hniksic@arsdigita.com>
 
        * url.c (convert_links): Don't translate %d-%d.
index c90c214d2c49ee55cb17af43385ffc0f258ade55..28d2f6aa3395a5b37c904a0717286ed562490661 100644 (file)
@@ -146,9 +146,10 @@ connect_to_one (const unsigned char *addr, unsigned short port, int silent)
 int
 connect_to_many (struct address_list *al, unsigned short port, int silent)
 {
-  int i;
+  int i, start, end;
 
-  for (i = 0; i < address_list_count (al); i++)
+  address_list_get_bounds (al, &start, &end);
+  for (i = start; i < end; i++)
     {
       unsigned char addr[4];
       int sock;
@@ -156,10 +157,10 @@ connect_to_many (struct address_list *al, unsigned short port, int silent)
 
       sock = connect_to_one (addr, port, silent);
       if (sock >= 0)
+       /* Success. */
        return sock;
 
-      /* Perhaps we should have a way of removing the failing entry
-        from the address list?  */
+      address_list_set_faulty (al, i);
 
       /* The attempt to connect has failed.  Continue with the loop
         and try next address. */
index c31cc05fa0cdfba7d8c6f3d883b1f49428332d30..eede86fe51064c603ec2de0910ab93a459a6b3e0 100644 (file)
@@ -72,18 +72,21 @@ struct address_list {
   int count;                   /* number of adrresses */
   unsigned char *buffer;       /* buffer which holds all of them. */
 
+  int faulty;                  /* number of addresses known not to
+                                  work. */
   int refcount;                        /* so we know whether to free it or
                                   not. */
 };
 
 #define ADDR_LOCATION(al, index) ((al)->buffer + index * IP4_ADDRESS_LENGTH)
 
-/* Return the number of addresses in the list. */
+/* Get the bounds of the address list.  */
 
-int
-address_list_count (struct address_list *al)
+void
+address_list_get_bounds (struct address_list *al, int *start, int *end)
 {
-  return al->count;
+  *start = al->faulty;
+  *end   = al->count;
 }
 
 /* Copy address number INDEX to IP_STORE.  */
@@ -92,6 +95,7 @@ void
 address_list_copy_one (struct address_list *al, int index,
                       unsigned char *ip_store)
 {
+  assert (index >= al->faulty && index < al->count);
   memcpy (ip_store, ADDR_LOCATION (al, index), IP4_ADDRESS_LENGTH);
 }
 
@@ -108,6 +112,21 @@ address_list_match_all (struct address_list *al1, struct address_list *al2)
                      al1->count * IP4_ADDRESS_LENGTH);
 }
 
+/* Mark the INDEXth element of AL as faulty, so that the next time
+   this address list is used, the faulty element will be skipped.  */
+
+void
+address_list_set_faulty (struct address_list *al, int index)
+{
+  ++al->faulty;
+  if (al->faulty >= al->count)
+    /* All addresses have been proven faulty.  Since there's not much
+       sense in returning the user an empty address list the next
+       time, we'll rather make them all clean, so that they can be
+       retried anew.  */
+    al->faulty = 0;
+}
+
 /* Create an address_list out of a NULL-terminated list of addresses,
    as returned by gethostbyname.  */
 
index c3cc1e52951fd6a5a4899bf989695f686047e91d..7cd395dcbcb25b5e3fbed93921f53675d30d6d67 100644 (file)
@@ -27,12 +27,13 @@ struct address_list;
 struct address_list *lookup_host PARAMS ((const char *, int));
 char *herrmsg PARAMS ((int));
 
-int address_list_count PARAMS ((struct address_list *));
+void address_list_get_bounds PARAMS ((struct address_list *, int *, int *));
 void address_list_copy_one PARAMS ((struct address_list *, int,
                                    unsigned char *));
-void address_list_release PARAMS ((struct address_list *));
 int address_list_match_all PARAMS ((struct address_list *,
                                    struct address_list *));
+void address_list_set_faulty PARAMS ((struct address_list *, int));
+void address_list_release PARAMS ((struct address_list *));
 
 /* This was originally going to be a macro, but then every caller
    would have to #include the netinet stuff.  */