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>
|
2003-11-09 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
* html-url.c: Get URLs from <object data="...">.
|
* html-url.c: Get URLs from <object data="...">.
|
||||||
|
@ -166,28 +166,41 @@ sockaddr_size (const struct sockaddr *sa)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
resolve_bind_address (const char *host, struct sockaddr *sa, int flags)
|
resolve_bind_address (struct sockaddr *sa)
|
||||||
{
|
{
|
||||||
struct address_list *al;
|
struct address_list *al;
|
||||||
|
|
||||||
/* #### Shouldn't we do this only once? opt.bind_address won't
|
/* Make sure this is called only once. opt.bind_address doesn't
|
||||||
change during a Wget run! */
|
change during a Wget run. */
|
||||||
|
static int called, should_bind;
|
||||||
al = lookup_host (host, flags | LH_SILENT | LH_PASSIVE);
|
static ip_address ip;
|
||||||
if (al == NULL)
|
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,
|
logprintf (LOG_NOTQUIET,
|
||||||
_("%s: unable to resolve bind address `%s'; disabling bind.\n"),
|
_("%s: unable to resolve bind address `%s'; disabling bind.\n"),
|
||||||
exec_name, opt.bind_address);
|
exec_name, opt.bind_address);
|
||||||
|
should_bind = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pick the first address in the list and use it as bind address.
|
/* Pick the first address in the list and use it as bind address.
|
||||||
Perhaps we should try multiple addresses, but I don't think
|
Perhaps we should try multiple addresses in succession, but I
|
||||||
that's necessary in practice. */
|
don't think that's necessary in practice. */
|
||||||
sockaddr_set_data (sa, address_list_address_at (al, 0), 0);
|
ip = *address_list_address_at (al, 0);
|
||||||
address_list_release (al);
|
address_list_release (al);
|
||||||
|
|
||||||
|
sockaddr_set_data (sa, &ip, 0);
|
||||||
|
should_bind = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +293,7 @@ connect_to_ip (const ip_address *ip, int port, const char *print)
|
|||||||
address. */
|
address. */
|
||||||
struct sockaddr_storage bind_ss;
|
struct sockaddr_storage bind_ss;
|
||||||
struct sockaddr *bind_sa = (struct sockaddr *)&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)
|
if (bind (sock, bind_sa, sockaddr_size (bind_sa)) < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
@ -32,10 +32,6 @@ so, delete this exception statement from your version. */
|
|||||||
|
|
||||||
#include "host.h" /* for definition of ip_address */
|
#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 ENABLE_IPV6
|
||||||
# ifndef HAVE_SOCKADDR_STORAGE
|
# ifndef HAVE_SOCKADDR_STORAGE
|
||||||
# define sockaddr_storage sockaddr_in
|
# 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. */
|
/* Mapping between known hosts and to lists of their addresses. */
|
||||||
|
|
||||||
static struct hash_table *host_name_addresses_map;
|
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
|
/* Lists of addresses. This should eventually be extended to handle
|
||||||
IPv6. */
|
IPv6. */
|
||||||
@ -326,6 +333,26 @@ gethostbyname_with_timeout (const char *host_name, double timeout)
|
|||||||
return ctx.hptr;
|
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 */
|
#else /* ENABLE_IPV6 */
|
||||||
|
|
||||||
struct gaiwt_context {
|
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
|
this function, or set opt.dns_cache to 0 to globally disable
|
||||||
caching.
|
caching.
|
||||||
|
|
||||||
FLAGS can be a combination of:
|
If SILENT is non-zero, progress messages are not printed. */
|
||||||
LH_SILENT - don't print the "resolving ... done" message.
|
|
||||||
LH_IPV4_ONLY - return only IPv4 addresses.
|
|
||||||
LH_IPV6_ONLY - return only IPv6 addresses. */
|
|
||||||
|
|
||||||
struct address_list *
|
struct address_list *
|
||||||
lookup_host (const char *host, int flags)
|
lookup_host (const char *host, int silent)
|
||||||
{
|
{
|
||||||
struct address_list *al = NULL;
|
struct address_list *al = NULL;
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
int err;
|
int err;
|
||||||
struct addrinfo hints, *res;
|
struct addrinfo hints, *res;
|
||||||
|
|
||||||
xzero (hints);
|
xzero (hints);
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_family = ip_default_family;
|
||||||
/* 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;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* First, try to check whether the address is already a numeric
|
/* 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
|
#ifdef ENABLE_IPV6
|
||||||
hints.ai_flags = AI_NUMERICHOST;
|
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
|
/* No need to specify timeout, as we're not resolving HOST, but
|
||||||
merely translating it from the presentation (ASCII) to network
|
merely translating it from the presentation (ASCII) to network
|
||||||
@ -528,20 +542,18 @@ lookup_host (const char *host, int flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(flags & LH_SILENT))
|
/* No luck with the cache; resolve the host name. */
|
||||||
logprintf (LOG_VERBOSE, _("Resolving %s... "), host);
|
|
||||||
|
|
||||||
/* Host name lookup goes on below. */
|
if (!silent)
|
||||||
|
logprintf (LOG_VERBOSE, _("Resolving %s... "), host);
|
||||||
|
|
||||||
#ifdef ENABLE_IPV6
|
#ifdef ENABLE_IPV6
|
||||||
hints.ai_flags = 0;
|
hints.ai_flags = 0;
|
||||||
if (flags & LH_PASSIVE)
|
|
||||||
hints.ai_flags |= AI_PASSIVE;
|
|
||||||
|
|
||||||
err = getaddrinfo_with_timeout (host, NULL, &hints, &res, opt.dns_timeout);
|
err = getaddrinfo_with_timeout (host, NULL, &hints, &res, opt.dns_timeout);
|
||||||
if (err != 0 || res == NULL)
|
if (err != 0 || res == NULL)
|
||||||
{
|
{
|
||||||
if (!(flags & LH_SILENT))
|
if (!silent)
|
||||||
logprintf (LOG_VERBOSE, _("failed: %s.\n"),
|
logprintf (LOG_VERBOSE, _("failed: %s.\n"),
|
||||||
err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno));
|
err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -553,16 +565,16 @@ lookup_host (const char *host, int flags)
|
|||||||
struct hostent *hptr = gethostbyname_with_timeout (host, opt.dns_timeout);
|
struct hostent *hptr = gethostbyname_with_timeout (host, opt.dns_timeout);
|
||||||
if (!hptr)
|
if (!hptr)
|
||||||
{
|
{
|
||||||
if (!(flags & LH_SILENT))
|
if (!silent)
|
||||||
{
|
{
|
||||||
if (errno != ETIMEDOUT)
|
if (errno != ETIMEDOUT)
|
||||||
logprintf (LOG_VERBOSE, _("failed: %s.\n"), herrmsg (h_errno));
|
logprintf (LOG_VERBOSE, _("failed: %s.\n"),
|
||||||
|
host_errstr (h_errno));
|
||||||
else
|
else
|
||||||
logputs (LOG_VERBOSE, _("failed: timed out.\n"));
|
logputs (LOG_VERBOSE, _("failed: timed out.\n"));
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
assert (hptr->h_length == 4);
|
|
||||||
/* Do older systems have h_addr_list? */
|
/* Do older systems have h_addr_list? */
|
||||||
al = address_list_from_ipv4_addresses (hptr->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
|
/* Print the addresses determined by DNS lookup, but no more than
|
||||||
three. */
|
three. */
|
||||||
if (!(flags & LH_SILENT))
|
if (!silent)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int printmax = al->count <= 3 ? al->count : 3;
|
int printmax = al->count <= 3 ? al->count : 3;
|
||||||
@ -592,6 +604,43 @@ lookup_host (const char *host, int flags)
|
|||||||
|
|
||||||
return 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 = 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
|
/* Determine whether a URL is acceptable to be followed, according to
|
||||||
a list of domains to accept. */
|
a list of domains to accept. */
|
||||||
@ -635,22 +684,6 @@ sufmatch (const char **list, const char *what)
|
|||||||
return 0;
|
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
|
static int
|
||||||
host_cleanup_mapper (void *key, void *value, void *arg_ignored)
|
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_DATA(x) ((void *)&(x)->u.ipv6.addr)
|
||||||
#define ADDRESS_IPV6_SCOPE(x) ((x)->u.ipv6.scope_id)
|
#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 */
|
/* Function declarations */
|
||||||
struct address_list *lookup_host PARAMS ((const char *, int));
|
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 *));
|
void forget_host_lookup PARAMS ((const char *));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user