[svn] Add support for -4/-6.

This commit is contained in:
hniksic 2003-11-14 17:49:52 -08:00
parent a2d793a321
commit 8e330fdba0
5 changed files with 110 additions and 75 deletions

View File

@ -1,3 +1,20 @@
2003-11-15 Hrvoje Niksic <hniksic@xemacs.org>
* init.c: Make sure the options are in alphabetic order!
* host.c (lookup_host): Merge lookup_host_passive and lookup_host
after all -- having both would result in some code duplication.
(lookup_host): Set hints.ai_family to AF_INET if ipv4_only is
requested. Likewise, set it to AF_INET6 for ipv6_only. Specify
AI_ADDRCONFIG where available.
(lookup_host): New flag LH_REFRESH that specifies that a cached
entry for HOST should be refreshed.
(cache_query): New function.
(cache_store): Ditto.
(cache_remove): Ditto.
(forget_host_lookup): No longer necessary, replaced with static
function cache_remove.
2003-11-14 Hrvoje Niksic <hniksic@xemacs.org>
* main.c: Enable -4 and -6 only if IPv6 is enabled.

View File

@ -182,7 +182,7 @@ resolve_bind_address (struct sockaddr *sa)
}
called = 1;
al = lookup_host_passive (opt.bind_address);
al = lookup_host (opt.bind_address, LH_BIND | LH_SILENT);
if (!al)
{
/* #### We should be able to print the error message here. */
@ -333,10 +333,11 @@ connect_to_host (const char *host, int port)
{
int i, start, end;
struct address_list *al;
int lh_flags = 0;
int sock = -1;
again:
al = lookup_host (host, 0);
al = lookup_host (host, lh_flags);
if (!al)
return E_HOST;
@ -366,7 +367,7 @@ connect_to_host (const char *host, int port)
we were previously able to connect to HOST. That might
indicate that HOST is under dynamic DNS and the addresses
we're connecting to have expired. Resolve it again. */
forget_host_lookup (host);
lh_flags |= LH_REFRESH;
goto again;
}

View File

@ -78,10 +78,6 @@ extern int h_errno;
# endif
#endif
/* Mapping between known hosts and to lists of their addresses. */
static struct hash_table *host_name_addresses_map;
/* Lists of IP addresses that result from running DNS queries. See
lookup_host for details. */
@ -431,13 +427,40 @@ pretty_print_address (const ip_address *addr)
abort ();
return NULL;
}
/* Simple host cache, used by lookup_host to speed up resolving. The
cache doesn't handle TTL because Wget is a fairly short-lived
application. Refreshing is attempted when connect fails, though --
see connect_to_host. */
/* Add host name HOST with the address ADDR_TEXT to the cache.
ADDR_LIST is a NULL-terminated list of addresses, as in struct
hostent. */
/* Mapping between known hosts and to lists of their addresses. */
static struct hash_table *host_name_addresses_map;
/* Return the host's resolved addresses from the cache, if
available. */
static struct address_list *
cache_query (const char *host)
{
struct address_list *al;
if (!host_name_addresses_map)
return NULL;
al = hash_table_get (host_name_addresses_map, host);
if (al)
{
DEBUGP (("Found %s in host_name_addresses_map (%p)\n", host, al));
++al->refcount;
return al;
}
return NULL;
}
/* Cache the DNS lookup of HOST. Subsequent invocations of
lookup_host will return the cached value. */
static void
cache_host_lookup (const char *host, struct address_list *al)
cache_store (const char *host, struct address_list *al)
{
if (!host_name_addresses_map)
host_name_addresses_map = make_nocase_string_hash_table (0);
@ -457,20 +480,23 @@ cache_host_lookup (const char *host, struct address_list *al)
#endif
}
/* Remove HOST from Wget's DNS cache. Does nothing is HOST is not in
/* Remove HOST from the DNS cache. Does nothing is HOST is not in
the cache. */
void
forget_host_lookup (const char *host)
static void
cache_remove (const char *host)
{
struct address_list *al = hash_table_get (host_name_addresses_map, host);
struct address_list *al;
if (!host_name_addresses_map)
return;
al = hash_table_get (host_name_addresses_map, host);
if (al)
{
address_list_release (al);
hash_table_remove (host_name_addresses_map, host);
}
}
/* Look up HOST in DNS and return a list of IP addresses. The
addresses in the list are in the same order in which
gethostbyname/getaddrinfo returned them.
@ -480,12 +506,20 @@ forget_host_lookup (const char *host)
you want to force lookup, call forget_host_lookup() prior to this
function, or set opt.dns_cache to 0 to globally disable caching.
If SILENT is non-zero, progress messages are not printed. */
FLAGS can be a combination of:
LH_SILENT - don't print the "resolving ... done" messages.
LH_BIND - resolve addresses for use with bind, which under
IPv6 means to use AI_PASSIVE flag to getaddrinfo.
Passive lookups are not cached under IPv6.
LH_REFRESH - if HOST is cached, remove the entry from the cache
and resolve it anew. */
struct address_list *
lookup_host (const char *host, int silent)
lookup_host (const char *host, int flags)
{
struct address_list *al = NULL;
int silent = flags & LH_SILENT;
int use_cache;
#ifndef ENABLE_IPV6
/* If we're not using getaddrinfo, first check if HOST specifies a
@ -506,20 +540,30 @@ lookup_host (const char *host, int silent)
}
#endif
/* Try to find the host in the cache. */
/* 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)
use_cache = 0;
#endif
if (host_name_addresses_map)
/* Try to find the host in the cache so we don't need to talk to the
resolver. If LH_REFRESH is requested, remove HOST from the cache
instead. */
if (use_cache)
{
al = hash_table_get (host_name_addresses_map, host);
if (al)
if (!(flags & LH_REFRESH))
{
DEBUGP (("Found %s in host_name_addresses_map (%p)\n", host, al));
++al->refcount;
return al;
al = cache_query (host);
if (al)
return al;
}
else
cache_remove (host);
}
/* No luck with the cache; resolve the host name. */
/* No luck with the cache; resolve HOST. */
if (!silent)
logprintf (LOG_VERBOSE, _("Resolving %s... "), host);
@ -531,9 +575,18 @@ lookup_host (const char *host, int silent)
xzero (hints);
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_UNSPEC; /* #### should look at opt.ipv4_only
and opt.ipv6_only */
hints.ai_flags = 0;
hints.ai_family = AF_UNSPEC;
if (opt.ipv4_only && !opt.ipv6_only)
hints.ai_family = AF_INET;
else if (opt.ipv6_only && !opt.ipv4_only)
hints.ai_family = AF_INET6;
#ifdef HAVE_GETADDRINFO_AI_ADDRCONFIG
/* Use AI_ADDRCONFIG where available. See init.c:defaults(). */
hints.ai_flags |= AI_ADDRCONFIG;
#endif
if (flags & LH_BIND)
hints.ai_flags |= AI_PASSIVE;
err = getaddrinfo_with_timeout (host, NULL, &hints, &res, opt.dns_timeout);
if (err != 0 || res == NULL)
@ -547,7 +600,8 @@ lookup_host (const char *host, int silent)
freeaddrinfo (res);
if (!al)
{
logprintf (LOG_VERBOSE, _("failed: No IPv4/IPv6 addresses.\n"));
logprintf (LOG_VERBOSE,
_("failed: No IPv4/IPv6 addresses for host.\n"));
return NULL;
}
}
@ -590,49 +644,11 @@ lookup_host (const char *host, int silent)
}
/* Cache the lookup information. */
if (opt.dns_cache)
cache_host_lookup (host, al);
if (use_cache)
cache_store (host, al);
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 = AF_UNSPEC; /* #### should look at opt.ipv4_only
and opt.ipv6_only */
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
}
/* Determine whether a URL is acceptable to be followed, according to
a list of domains to accept. */

View File

@ -90,11 +90,12 @@ typedef struct {
#define ADDRESS_IPV6_DATA(x) ((void *)&(x)->u.ipv6.addr)
#define ADDRESS_IPV6_SCOPE(x) ((x)->u.ipv6.scope_id)
/* Function declarations */
enum {
LH_SILENT = 1,
LH_BIND = 2,
LH_REFRESH = 4
};
struct address_list *lookup_host PARAMS ((const char *, int));
struct address_list *lookup_host_passive PARAMS ((const char *));
void forget_host_lookup PARAMS ((const char *));
void address_list_get_bounds PARAMS ((const struct address_list *,
int *, int *));

View File

@ -166,11 +166,11 @@ static struct {
{ "ignorelength", &opt.ignore_length, cmd_boolean },
{ "ignoretags", &opt.ignore_tags, cmd_vector },
{ "includedirectories", &opt.includes, cmd_directory_vector },
{ "input", &opt.input_filename, cmd_file },
#ifdef ENABLE_IPV6
{ "inet4only", &opt.ipv4_only, cmd_boolean },
{ "inet6only", &opt.ipv6_only, cmd_boolean },
#endif
{ "input", &opt.input_filename, cmd_file },
{ "keepsessioncookies", &opt.keep_session_cookies, cmd_boolean },
{ "killlonger", &opt.kill_longer, cmd_boolean },
{ "limitrate", &opt.limit_rate, cmd_bytes },