From 8196a09904b12ce5878fef6833a4091afafc9a24 Mon Sep 17 00:00:00 2001 From: hniksic Date: Tue, 27 Nov 2001 06:55:40 -0800 Subject: [PATCH] [svn] Don't reuse IP addresses proven to be faulty, unless only such ones remain. Published in . --- src/ChangeLog | 9 +++++++++ src/connect.c | 9 +++++---- src/host.c | 27 +++++++++++++++++++++++---- src/host.h | 5 +++-- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 435e3240..3afdfbc8 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,12 @@ +2001-11-27 Hrvoje Niksic + + * 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 * url.c (convert_links): Don't translate %d-%d. diff --git a/src/connect.c b/src/connect.c index c90c214d..28d2f6aa 100644 --- a/src/connect.c +++ b/src/connect.c @@ -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. */ diff --git a/src/host.c b/src/host.c index c31cc05f..eede86fe 100644 --- a/src/host.c +++ b/src/host.c @@ -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. */ diff --git a/src/host.h b/src/host.h index c3cc1e52..7cd395dc 100644 --- a/src/host.h +++ b/src/host.h @@ -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. */ -- 2.39.2