1
0
mirror of https://github.com/moparisthebest/wget synced 2024-07-03 16:38:41 -04:00

[svn] Split passive host lookups to a separate function.

This commit is contained in:
hniksic 2003-11-09 17:38:09 -08:00
parent 4a960c0a4c
commit 8ccc51e5af
5 changed files with 110 additions and 65 deletions

View 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="...">.

View File

@ -166,28 +166,41 @@ sockaddr_size (const struct sockaddr *sa)
}
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! */
al = lookup_host (host, flags | LH_SILENT | LH_PASSIVE);
if (al == NULL)
/* 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)
{
/* #### We should print the error message here. */
if (should_bind)
sockaddr_set_data (sa, &ip, 0);
return should_bind;
}
called = 1;
al = lookup_host_passive (opt.bind_address);
if (!al)
{
/* #### 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;
}
@ -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;

View 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

View 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
/* 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
}
/* 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)
{

View 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 *));