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:
parent
4a960c0a4c
commit
8ccc51e5af
@ -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="...">.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
117
src/host.c
117
src/host.c
@ -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)
|
||||
{
|
||||
|
@ -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 *));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user