mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] Improve handling of numeric hosts when ENABLE_IPV6.
Published in <87psyr6jn7.fsf@xemacs.org>.
This commit is contained in:
parent
3d04bb3a2c
commit
16c53cdf93
@ -1,3 +1,8 @@
|
||||
2003-02-24 Hrvoje Niksic <hniksic@xemacs.org>
|
||||
|
||||
* configure.in: Don't check for AI_ADDRCONFIG here, it is checked
|
||||
for in the source directly.
|
||||
|
||||
2003-02-25 Hrvoje Niksic <hniksic@xemacs.org>
|
||||
|
||||
* libtool.m4, ltmain.sh, config.sub, config.guess: Upgrade to
|
||||
|
24
aclocal.m4
vendored
24
aclocal.m4
vendored
@ -239,30 +239,6 @@ AC_DEFUN([PROTO_INET6],[
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([GETADDRINFO_AI_ADDRCONFIG],[
|
||||
AC_CACHE_CHECK([if getaddrinfo supports AI_ADDRCONFIG],
|
||||
[wget_cv_gai_ai_addrconfig],[
|
||||
AC_TRY_CPP([
|
||||
#include <netdb.h>
|
||||
|
||||
#ifndef AI_ADDRCONFIG
|
||||
#error Missing AI_ADDRCONFIG
|
||||
#endif
|
||||
],[
|
||||
wget_cv_gai_ai_addrconfig=yes
|
||||
],[
|
||||
wget_cv_gai_ai_addrconfig=no
|
||||
])
|
||||
])
|
||||
|
||||
if test "X$wget_cv_gai_ai_addrconfig" = "Xyes"; then :
|
||||
$1
|
||||
else :
|
||||
$2
|
||||
fi
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([WGET_STRUCT_SOCKADDR_STORAGE],[
|
||||
AC_CHECK_TYPES([struct sockaddr_storage],[], [], [
|
||||
#include <sys/types.h>
|
||||
|
@ -494,14 +494,7 @@ AC_ARG_ENABLE(ipv6,
|
||||
)
|
||||
|
||||
if test "X$ipv6" = "Xyes" || test "X$check_for_ipv6" = "Xyes"; then
|
||||
AC_CHECK_FUNCS(getaddrinfo, [
|
||||
GETADDRINFO_AI_ADDRCONFIG([
|
||||
AC_DEFINE(
|
||||
[HAVE_GETADDRINFO_AI_ADDRCONFIG], 1,
|
||||
[Define if the system headers support the AI_ADDRCONFIG flag.]
|
||||
)
|
||||
])
|
||||
], [
|
||||
AC_CHECK_FUNCS(getaddrinfo, [], [
|
||||
AC_MSG_NOTICE([Disabling IPv6 support: your system does not support getaddrinfo(3)])
|
||||
ipv6=no
|
||||
])
|
||||
|
@ -1,3 +1,15 @@
|
||||
2005-02-24 Hrvoje Niksic <hniksic@xemacs.org>
|
||||
|
||||
* host.c (lookup_host): Test for AI_ADDRCONFIG directly, instead
|
||||
of checking for HAVE_GETADDRINFO_AI_ADDRCONFIG.
|
||||
|
||||
2005-02-23 Hrvoje Niksic <hniksic@xemacs.org>
|
||||
|
||||
* host.c (is_valid_ipv6_address): Move here from url.c.
|
||||
(lookup_host): If the address is numeric, don't print the
|
||||
"resolving..." line, don't set up DNS timeouts, and set the
|
||||
AI_NUMERICHOST hint, where available.
|
||||
|
||||
2005-02-26 Gisle Vanem <giva@bgnett.no>
|
||||
|
||||
* utils.c: Use the nnnLL syntax under GCC. Define struct_stat to
|
||||
|
190
src/host.c
190
src/host.c
@ -428,6 +428,149 @@ pretty_print_address (const ip_address *addr)
|
||||
abort ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The following two functions were adapted from glibc. */
|
||||
|
||||
static int
|
||||
is_valid_ipv4_address (const char *str, const char *end)
|
||||
{
|
||||
int saw_digit = 0;
|
||||
int octets = 0;
|
||||
int val = 0;
|
||||
|
||||
while (str < end)
|
||||
{
|
||||
int ch = *str++;
|
||||
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
val = val * 10 + (ch - '0');
|
||||
|
||||
if (val > 255)
|
||||
return 0;
|
||||
if (saw_digit == 0)
|
||||
{
|
||||
if (++octets > 4)
|
||||
return 0;
|
||||
saw_digit = 1;
|
||||
}
|
||||
}
|
||||
else if (ch == '.' && saw_digit == 1)
|
||||
{
|
||||
if (octets == 4)
|
||||
return 0;
|
||||
val = 0;
|
||||
saw_digit = 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
if (octets < 4)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
is_valid_ipv6_address (const char *str, const char *end)
|
||||
{
|
||||
enum {
|
||||
NS_INADDRSZ = 4,
|
||||
NS_IN6ADDRSZ = 16,
|
||||
NS_INT16SZ = 2
|
||||
};
|
||||
|
||||
const char *curtok;
|
||||
int tp;
|
||||
const char *colonp;
|
||||
int saw_xdigit;
|
||||
unsigned int val;
|
||||
|
||||
tp = 0;
|
||||
colonp = NULL;
|
||||
|
||||
if (str == end)
|
||||
return 0;
|
||||
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*str == ':')
|
||||
{
|
||||
++str;
|
||||
if (str == end || *str != ':')
|
||||
return 0;
|
||||
}
|
||||
|
||||
curtok = str;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
|
||||
while (str < end)
|
||||
{
|
||||
int ch = *str++;
|
||||
|
||||
/* if ch is a number, add it to val. */
|
||||
if (ISXDIGIT (ch))
|
||||
{
|
||||
val <<= 4;
|
||||
val |= XDIGIT_TO_NUM (ch);
|
||||
if (val > 0xffff)
|
||||
return 0;
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if ch is a colon ... */
|
||||
if (ch == ':')
|
||||
{
|
||||
curtok = str;
|
||||
if (saw_xdigit == 0)
|
||||
{
|
||||
if (colonp != NULL)
|
||||
return 0;
|
||||
colonp = str + tp;
|
||||
continue;
|
||||
}
|
||||
else if (str == end)
|
||||
return 0;
|
||||
if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
|
||||
return 0;
|
||||
tp += NS_INT16SZ;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if ch is a dot ... */
|
||||
if (ch == '.' && (tp <= NS_IN6ADDRSZ - NS_INADDRSZ)
|
||||
&& is_valid_ipv4_address (curtok, end) == 1)
|
||||
{
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (saw_xdigit == 1)
|
||||
{
|
||||
if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
|
||||
return 0;
|
||||
tp += NS_INT16SZ;
|
||||
}
|
||||
|
||||
if (colonp != NULL)
|
||||
{
|
||||
if (tp == NS_IN6ADDRSZ)
|
||||
return 0;
|
||||
tp = NS_IN6ADDRSZ;
|
||||
}
|
||||
|
||||
if (tp != NS_IN6ADDRSZ)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Simple host cache, used by lookup_host to speed up resolving. The
|
||||
cache doesn't handle TTL because Wget is a fairly short-lived
|
||||
@ -521,12 +664,14 @@ lookup_host (const char *host, int flags)
|
||||
struct address_list *al;
|
||||
int silent = flags & LH_SILENT;
|
||||
int use_cache;
|
||||
int numeric_address = 0;
|
||||
double timeout = opt.dns_timeout;
|
||||
|
||||
#ifndef ENABLE_IPV6
|
||||
/* If we're not using getaddrinfo, first check if HOST specifies a
|
||||
numeric IPv4 address. gethostbyname is not required to accept
|
||||
dotted-decimal IPv4 addresses, and some implementations (e.g. the
|
||||
Ultrix one and possibly Winsock) indeed don't. */
|
||||
numeric IPv4 address. Some implementations of gethostbyname
|
||||
(e.g. the Ultrix one and possibly Winsock) don't accept
|
||||
dotted-decimal IPv4 addresses. */
|
||||
{
|
||||
uint32_t addr_ipv4 = (uint32_t)inet_addr (host);
|
||||
if (addr_ipv4 != (uint32_t) -1)
|
||||
@ -539,13 +684,24 @@ lookup_host (const char *host, int flags)
|
||||
return address_list_from_ipv4_addresses (vec);
|
||||
}
|
||||
}
|
||||
#else /* ENABLE_IPV6 */
|
||||
/* If we're using getaddrinfo, at least check whether the address is
|
||||
already numeric, in which case there is no need to print the
|
||||
"Resolving..." output. (This comes at no additional cost since
|
||||
the is_valid_ipv*_address are already required for
|
||||
url_parse.) */
|
||||
{
|
||||
const char *end = host + strlen (host);
|
||||
if (is_valid_ipv4_address (host, end) || is_valid_ipv6_address (host, end))
|
||||
numeric_address = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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)
|
||||
if ((flags & LH_BIND) || numeric_address)
|
||||
use_cache = 0;
|
||||
#endif
|
||||
|
||||
@ -566,7 +722,7 @@ lookup_host (const char *host, int flags)
|
||||
|
||||
/* No luck with the cache; resolve HOST. */
|
||||
|
||||
if (!silent)
|
||||
if (!silent && !numeric_address)
|
||||
logprintf (LOG_VERBOSE, _("Resolving %s... "), host);
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
@ -583,7 +739,7 @@ lookup_host (const char *host, int flags)
|
||||
else
|
||||
{
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
#ifdef HAVE_GETADDRINFO_AI_ADDRCONFIG
|
||||
#ifdef AI_ADDRCONFIG
|
||||
hints.ai_flags |= AI_ADDRCONFIG;
|
||||
#else
|
||||
/* On systems without AI_ADDRCONFIG, emulate it by manually
|
||||
@ -595,7 +751,19 @@ lookup_host (const char *host, int flags)
|
||||
if (flags & LH_BIND)
|
||||
hints.ai_flags |= AI_PASSIVE;
|
||||
|
||||
err = getaddrinfo_with_timeout (host, NULL, &hints, &res, opt.dns_timeout);
|
||||
#ifdef AI_NUMERICHOST
|
||||
if (numeric_address)
|
||||
{
|
||||
/* Where available, the AI_NUMERICHOST hint can prevent costly
|
||||
access to DNS servers. */
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
timeout = 0; /* no timeout needed when "resolving"
|
||||
numeric hosts -- avoid setting up
|
||||
signal handlers and such. */
|
||||
}
|
||||
#endif
|
||||
|
||||
err = getaddrinfo_with_timeout (host, NULL, &hints, &res, timeout);
|
||||
if (err != 0 || res == NULL)
|
||||
{
|
||||
if (!silent)
|
||||
@ -612,9 +780,9 @@ lookup_host (const char *host, int flags)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#else /* not ENABLE_IPV6 */
|
||||
{
|
||||
struct hostent *hptr = gethostbyname_with_timeout (host, opt.dns_timeout);
|
||||
struct hostent *hptr = gethostbyname_with_timeout (host, timeout);
|
||||
if (!hptr)
|
||||
{
|
||||
if (!silent)
|
||||
@ -630,11 +798,11 @@ lookup_host (const char *host, int flags)
|
||||
/* Do older systems have h_addr_list? */
|
||||
al = address_list_from_ipv4_addresses (hptr->h_addr_list);
|
||||
}
|
||||
#endif
|
||||
#endif /* not ENABLE_IPV6 */
|
||||
|
||||
/* Print the addresses determined by DNS lookup, but no more than
|
||||
three. */
|
||||
if (!silent)
|
||||
if (!silent && !numeric_address)
|
||||
{
|
||||
int i;
|
||||
int printmax = al->count <= 3 ? al->count : 3;
|
||||
|
@ -108,6 +108,9 @@ int address_list_connected_p PARAMS ((const struct address_list *));
|
||||
void address_list_release PARAMS ((struct address_list *));
|
||||
|
||||
const char *pretty_print_address PARAMS ((const ip_address *));
|
||||
#ifdef ENABLE_IPV6
|
||||
int is_valid_ipv6_address PARAMS ((const char *, const char *));
|
||||
#endif
|
||||
|
||||
int accept_domain PARAMS ((struct url *));
|
||||
int sufmatch PARAMS ((const char **, const char *));
|
||||
|
146
src/url.c
146
src/url.c
@ -47,6 +47,7 @@ so, delete this exception statement from your version. */
|
||||
#include "wget.h"
|
||||
#include "utils.h"
|
||||
#include "url.h"
|
||||
#include "host.h" /* for is_valid_ipv6_address */
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
@ -655,151 +656,6 @@ static const char *parse_errors[] = {
|
||||
N_("Invalid IPv6 numeric address")
|
||||
};
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
/* The following two functions were adapted from glibc. */
|
||||
|
||||
static int
|
||||
is_valid_ipv4_address (const char *str, const char *end)
|
||||
{
|
||||
int saw_digit = 0;
|
||||
int octets = 0;
|
||||
int val = 0;
|
||||
|
||||
while (str < end)
|
||||
{
|
||||
int ch = *str++;
|
||||
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
val = val * 10 + (ch - '0');
|
||||
|
||||
if (val > 255)
|
||||
return 0;
|
||||
if (saw_digit == 0)
|
||||
{
|
||||
if (++octets > 4)
|
||||
return 0;
|
||||
saw_digit = 1;
|
||||
}
|
||||
}
|
||||
else if (ch == '.' && saw_digit == 1)
|
||||
{
|
||||
if (octets == 4)
|
||||
return 0;
|
||||
val = 0;
|
||||
saw_digit = 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
if (octets < 4)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
is_valid_ipv6_address (const char *str, const char *end)
|
||||
{
|
||||
enum {
|
||||
NS_INADDRSZ = 4,
|
||||
NS_IN6ADDRSZ = 16,
|
||||
NS_INT16SZ = 2
|
||||
};
|
||||
|
||||
const char *curtok;
|
||||
int tp;
|
||||
const char *colonp;
|
||||
int saw_xdigit;
|
||||
unsigned int val;
|
||||
|
||||
tp = 0;
|
||||
colonp = NULL;
|
||||
|
||||
if (str == end)
|
||||
return 0;
|
||||
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*str == ':')
|
||||
{
|
||||
++str;
|
||||
if (str == end || *str != ':')
|
||||
return 0;
|
||||
}
|
||||
|
||||
curtok = str;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
|
||||
while (str < end)
|
||||
{
|
||||
int ch = *str++;
|
||||
|
||||
/* if ch is a number, add it to val. */
|
||||
if (ISXDIGIT (ch))
|
||||
{
|
||||
val <<= 4;
|
||||
val |= XDIGIT_TO_NUM (ch);
|
||||
if (val > 0xffff)
|
||||
return 0;
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if ch is a colon ... */
|
||||
if (ch == ':')
|
||||
{
|
||||
curtok = str;
|
||||
if (saw_xdigit == 0)
|
||||
{
|
||||
if (colonp != NULL)
|
||||
return 0;
|
||||
colonp = str + tp;
|
||||
continue;
|
||||
}
|
||||
else if (str == end)
|
||||
return 0;
|
||||
if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
|
||||
return 0;
|
||||
tp += NS_INT16SZ;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if ch is a dot ... */
|
||||
if (ch == '.' && (tp <= NS_IN6ADDRSZ - NS_INADDRSZ)
|
||||
&& is_valid_ipv4_address (curtok, end) == 1)
|
||||
{
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (saw_xdigit == 1)
|
||||
{
|
||||
if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
|
||||
return 0;
|
||||
tp += NS_INT16SZ;
|
||||
}
|
||||
|
||||
if (colonp != NULL)
|
||||
{
|
||||
if (tp == NS_IN6ADDRSZ)
|
||||
return 0;
|
||||
tp = NS_IN6ADDRSZ;
|
||||
}
|
||||
|
||||
if (tp != NS_IN6ADDRSZ)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Parse a URL.
|
||||
|
||||
Return a new struct url if successful, NULL on error. In case of
|
||||
|
Loading…
Reference in New Issue
Block a user