]> sjero.net Git - wget/blob - src/host.c
Fix build when libpsl is not available
[wget] / src / host.c
1 /* Host name resolution and matching.
2    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3    2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation,
4    Inc.
5
6 This file is part of GNU Wget.
7
8 GNU Wget is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12
13 GNU Wget is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
20
21 Additional permission under GNU GPL version 3 section 7
22
23 If you modify this program, or any covered work, by linking or
24 combining it with the OpenSSL project's OpenSSL library (or a
25 modified version of that library), containing parts covered by the
26 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
27 grants you additional permission to convey the resulting work.
28 Corresponding Source for a non-source form of such a combination
29 shall include the source code for the parts of OpenSSL used as well
30 as that of the covered work.  */
31
32 #include "wget.h"
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <assert.h>
38
39 #ifndef WINDOWS
40 # include <sys/types.h>
41 # include <sys/socket.h>
42 # include <netinet/in.h>
43 # ifndef __BEOS__
44 #  include <arpa/inet.h>
45 # endif
46 # ifdef __VMS
47 #  include "vms_ip.h"
48 # else /* def __VMS */
49 #  include <netdb.h>
50 # endif /* def __VMS [else] */
51 # define SET_H_ERRNO(err) ((void)(h_errno = (err)))
52 #else  /* WINDOWS */
53 # include <winsock2.h>
54 # include <ws2tcpip.h>
55 # define SET_H_ERRNO(err) WSASetLastError (err)
56 #endif /* WINDOWS */
57
58 #include <errno.h>
59
60 #include "utils.h"
61 #include "host.h"
62 #include "url.h"
63 #include "hash.h"
64
65 #ifndef NO_ADDRESS
66 # define NO_ADDRESS NO_DATA
67 #endif
68
69 #if !HAVE_DECL_H_ERRNO && !defined(WINDOWS)
70 extern int h_errno;
71 #endif
72
73
74 /* Lists of IP addresses that result from running DNS queries.  See
75    lookup_host for details.  */
76
77 struct address_list {
78   int count;                    /* number of adrresses */
79   ip_address *addresses;        /* pointer to the string of addresses */
80
81   int faulty;                   /* number of addresses known not to work. */
82   bool connected;               /* whether we were able to connect to
83                                    one of the addresses in the list,
84                                    at least once. */
85
86   int refcount;                 /* reference count; when it drops to
87                                    0, the entry is freed. */
88 };
89
90 /* Get the bounds of the address list.  */
91
92 void
93 address_list_get_bounds (const struct address_list *al, int *start, int *end)
94 {
95   *start = al->faulty;
96   *end   = al->count;
97 }
98
99 /* Return a pointer to the address at position POS.  */
100
101 const ip_address *
102 address_list_address_at (const struct address_list *al, int pos)
103 {
104   assert (pos >= al->faulty && pos < al->count);
105   return al->addresses + pos;
106 }
107
108 /* Return true if AL contains IP, false otherwise.  */
109
110 bool
111 address_list_contains (const struct address_list *al, const ip_address *ip)
112 {
113   int i;
114   switch (ip->family)
115     {
116     case AF_INET:
117       for (i = 0; i < al->count; i++)
118         {
119           ip_address *cur = al->addresses + i;
120           if (cur->family == AF_INET
121               && (cur->data.d4.s_addr == ip->data.d4.s_addr))
122             return true;
123         }
124       return false;
125 #ifdef ENABLE_IPV6
126     case AF_INET6:
127       for (i = 0; i < al->count; i++)
128         {
129           ip_address *cur = al->addresses + i;
130           if (cur->family == AF_INET6
131 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
132               && cur->ipv6_scope == ip->ipv6_scope
133 #endif
134               && IN6_ARE_ADDR_EQUAL (&cur->data.d6, &ip->data.d6))
135             return true;
136         }
137       return false;
138 #endif /* ENABLE_IPV6 */
139     default:
140       abort ();
141     }
142 }
143
144 /* Mark the INDEXth element of AL as faulty, so that the next time
145    this address list is used, the faulty element will be skipped.  */
146
147 void
148 address_list_set_faulty (struct address_list *al, int index)
149 {
150   /* We assume that the address list is traversed in order, so that a
151      "faulty" attempt is always preceded with all-faulty addresses,
152      and this is how Wget uses it.  */
153   assert (index == al->faulty);
154
155   ++al->faulty;
156   if (al->faulty >= al->count)
157     /* All addresses have been proven faulty.  Since there's not much
158        sense in returning the user an empty address list the next
159        time, we'll rather make them all clean, so that they can be
160        retried anew.  */
161     al->faulty = 0;
162 }
163
164 /* Set the "connected" flag to true.  This flag used by connect.c to
165    see if the host perhaps needs to be resolved again.  */
166
167 void
168 address_list_set_connected (struct address_list *al)
169 {
170   al->connected = true;
171 }
172
173 /* Return the value of the "connected" flag. */
174
175 bool
176 address_list_connected_p (const struct address_list *al)
177 {
178   return al->connected;
179 }
180
181 #ifdef ENABLE_IPV6
182
183 /* Create an address_list from the addresses in the given struct
184    addrinfo.  */
185
186 static struct address_list *
187 address_list_from_addrinfo (const struct addrinfo *ai)
188 {
189   struct address_list *al;
190   const struct addrinfo *ptr;
191   int cnt;
192   ip_address *ip;
193
194   cnt = 0;
195   for (ptr = ai; ptr != NULL ; ptr = ptr->ai_next)
196     if (ptr->ai_family == AF_INET || ptr->ai_family == AF_INET6)
197       ++cnt;
198   if (cnt == 0)
199     return NULL;
200
201   al = xnew0 (struct address_list);
202   al->addresses = xnew_array (ip_address, cnt);
203   al->count     = cnt;
204   al->refcount  = 1;
205
206   ip = al->addresses;
207   for (ptr = ai; ptr != NULL; ptr = ptr->ai_next)
208     if (ptr->ai_family == AF_INET6)
209       {
210         const struct sockaddr_in6 *sin6 =
211           (const struct sockaddr_in6 *)ptr->ai_addr;
212         ip->family = AF_INET6;
213         ip->data.d6 = sin6->sin6_addr;
214 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
215         ip->ipv6_scope = sin6->sin6_scope_id;
216 #endif
217         ++ip;
218       }
219     else if (ptr->ai_family == AF_INET)
220       {
221         const struct sockaddr_in *sin =
222           (const struct sockaddr_in *)ptr->ai_addr;
223         ip->family = AF_INET;
224         ip->data.d4 = sin->sin_addr;
225         ++ip;
226       }
227   assert (ip - al->addresses == cnt);
228   return al;
229 }
230
231 #define IS_IPV4(addr) (((const ip_address *) addr)->family == AF_INET)
232
233 /* Compare two IP addresses by family, giving preference to the IPv4
234    address (sorting it first).  In other words, return -1 if ADDR1 is
235    IPv4 and ADDR2 is IPv6, +1 if ADDR1 is IPv6 and ADDR2 is IPv4, and
236    0 otherwise.
237
238    This is intended to be used as the comparator arg to a qsort-like
239    sorting function, which is why it accepts generic pointers.  */
240
241 static int
242 cmp_prefer_ipv4 (const void *addr1, const void *addr2)
243 {
244   return !IS_IPV4 (addr1) - !IS_IPV4 (addr2);
245 }
246
247 #define IS_IPV6(addr) (((const ip_address *) addr)->family == AF_INET6)
248
249 /* Like the above, but give preference to the IPv6 address.  */
250
251 static int
252 cmp_prefer_ipv6 (const void *addr1, const void *addr2)
253 {
254   return !IS_IPV6 (addr1) - !IS_IPV6 (addr2);
255 }
256
257 #else  /* not ENABLE_IPV6 */
258
259 /* Create an address_list from a NULL-terminated vector of IPv4
260    addresses.  This kind of vector is returned by gethostbyname.  */
261
262 static struct address_list *
263 address_list_from_ipv4_addresses (char **vec)
264 {
265   int count, i;
266   struct address_list *al = xnew0 (struct address_list);
267
268   count = 0;
269   while (vec[count])
270     ++count;
271   assert (count > 0);
272
273   al->addresses = xnew_array (ip_address, count);
274   al->count     = count;
275   al->refcount  = 1;
276
277   for (i = 0; i < count; i++)
278     {
279       ip_address *ip = &al->addresses[i];
280       ip->family = AF_INET;
281       memcpy (IP_INADDR_DATA (ip), vec[i], 4);
282     }
283
284   return al;
285 }
286
287 #endif /* not ENABLE_IPV6 */
288
289 static void
290 address_list_delete (struct address_list *al)
291 {
292   xfree (al->addresses);
293   xfree (al);
294 }
295
296 /* Mark the address list as being no longer in use.  This will reduce
297    its reference count which will cause the list to be freed when the
298    count reaches 0.  */
299
300 void
301 address_list_release (struct address_list *al)
302 {
303   --al->refcount;
304   DEBUGP (("Releasing 0x%0*lx (new refcount %d).\n", PTR_FORMAT (al),
305            al->refcount));
306   if (al->refcount <= 0)
307     {
308       DEBUGP (("Deleting unused 0x%0*lx.\n", PTR_FORMAT (al)));
309       address_list_delete (al);
310     }
311 }
312 \f
313 /* Versions of gethostbyname and getaddrinfo that support timeout. */
314
315 #ifndef ENABLE_IPV6
316
317 struct ghbnwt_context {
318   const char *host_name;
319   struct hostent *hptr;
320 };
321
322 static void
323 gethostbyname_with_timeout_callback (void *arg)
324 {
325   struct ghbnwt_context *ctx = (struct ghbnwt_context *)arg;
326   ctx->hptr = gethostbyname (ctx->host_name);
327 }
328
329 /* Just like gethostbyname, except it times out after TIMEOUT seconds.
330    In case of timeout, NULL is returned and errno is set to ETIMEDOUT.
331    The function makes sure that when NULL is returned for reasons
332    other than timeout, errno is reset.  */
333
334 static struct hostent *
335 gethostbyname_with_timeout (const char *host_name, double timeout)
336 {
337   struct ghbnwt_context ctx;
338   ctx.host_name = host_name;
339   if (run_with_timeout (timeout, gethostbyname_with_timeout_callback, &ctx))
340     {
341       SET_H_ERRNO (HOST_NOT_FOUND);
342       errno = ETIMEDOUT;
343       return NULL;
344     }
345   if (!ctx.hptr)
346     errno = 0;
347   return ctx.hptr;
348 }
349
350 /* Print error messages for host errors.  */
351 static const char *
352 host_errstr (int error)
353 {
354   /* Can't use switch since some of these constants can be equal,
355      which makes the compiler complain about duplicate case
356      values.  */
357   if (error == HOST_NOT_FOUND
358       || error == NO_RECOVERY
359       || error == NO_DATA
360       || error == NO_ADDRESS)
361     return _("Unknown host");
362   else if (error == TRY_AGAIN)
363     /* Message modeled after what gai_strerror returns in similar
364        circumstances.  */
365     return _("Temporary failure in name resolution");
366   else
367     return _("Unknown error");
368 }
369
370 #else  /* ENABLE_IPV6 */
371
372 struct gaiwt_context {
373   const char *node;
374   const char *service;
375   const struct addrinfo *hints;
376   struct addrinfo **res;
377   int exit_code;
378 };
379
380 static void
381 getaddrinfo_with_timeout_callback (void *arg)
382 {
383   struct gaiwt_context *ctx = (struct gaiwt_context *)arg;
384   ctx->exit_code = getaddrinfo (ctx->node, ctx->service, ctx->hints, ctx->res);
385 }
386
387 /* Just like getaddrinfo, except it times out after TIMEOUT seconds.
388    In case of timeout, the EAI_SYSTEM error code is returned and errno
389    is set to ETIMEDOUT.  */
390
391 static int
392 getaddrinfo_with_timeout (const char *node, const char *service,
393                           const struct addrinfo *hints, struct addrinfo **res,
394                           double timeout)
395 {
396   struct gaiwt_context ctx;
397   ctx.node = node;
398   ctx.service = service;
399   ctx.hints = hints;
400   ctx.res = res;
401
402   if (run_with_timeout (timeout, getaddrinfo_with_timeout_callback, &ctx))
403     {
404       errno = ETIMEDOUT;
405       return EAI_SYSTEM;
406     }
407   return ctx.exit_code;
408 }
409
410 #endif /* ENABLE_IPV6 */
411 \f
412 /* Return a textual representation of ADDR, i.e. the dotted quad for
413    IPv4 addresses, and the colon-separated list of hex words (with all
414    zeros omitted, etc.) for IPv6 addresses.  */
415
416 const char *
417 print_address (const ip_address *addr)
418 {
419 #ifdef ENABLE_IPV6
420   static char buf[64];
421   if (!inet_ntop (addr->family, IP_INADDR_DATA (addr), buf, sizeof buf))
422     snprintf (buf, sizeof buf, "<error: %s>", strerror (errno));
423   return buf;
424 #else
425   return inet_ntoa (addr->data.d4);
426 #endif
427 }
428
429 /* The following two functions were adapted from glibc's
430    implementation of inet_pton, written by Paul Vixie. */
431
432 static bool
433 is_valid_ipv4_address (const char *str, const char *end)
434 {
435   bool saw_digit = false;
436   int octets = 0;
437   int val = 0;
438
439   while (str < end)
440     {
441       int ch = *str++;
442
443       if (ch >= '0' && ch <= '9')
444         {
445           val = val * 10 + (ch - '0');
446
447           if (val > 255)
448             return false;
449           if (!saw_digit)
450             {
451               if (++octets > 4)
452                 return false;
453               saw_digit = true;
454             }
455         }
456       else if (ch == '.' && saw_digit)
457         {
458           if (octets == 4)
459             return false;
460           val = 0;
461           saw_digit = false;
462         }
463       else
464         return false;
465     }
466   if (octets < 4)
467     return false;
468
469   return true;
470 }
471
472 bool
473 is_valid_ipv6_address (const char *str, const char *end)
474 {
475   /* Use lower-case for these to avoid clash with system headers.  */
476   enum {
477     ns_inaddrsz  = 4,
478     ns_in6addrsz = 16,
479     ns_int16sz   = 2
480   };
481
482   const char *curtok;
483   int tp;
484   const char *colonp;
485   bool saw_xdigit;
486   unsigned int val;
487
488   tp = 0;
489   colonp = NULL;
490
491   if (str == end)
492     return false;
493
494   /* Leading :: requires some special handling. */
495   if (*str == ':')
496     {
497       ++str;
498       if (str == end || *str != ':')
499         return false;
500     }
501
502   curtok = str;
503   saw_xdigit = false;
504   val = 0;
505
506   while (str < end)
507     {
508       int ch = *str++;
509
510       /* if ch is a number, add it to val. */
511       if (c_isxdigit (ch))
512         {
513           val <<= 4;
514           val |= XDIGIT_TO_NUM (ch);
515           if (val > 0xffff)
516             return false;
517           saw_xdigit = true;
518           continue;
519         }
520
521       /* if ch is a colon ... */
522       if (ch == ':')
523         {
524           curtok = str;
525           if (!saw_xdigit)
526             {
527               if (colonp != NULL)
528                 return false;
529               colonp = str + tp;
530               continue;
531             }
532           else if (str == end)
533             return false;
534           if (tp > ns_in6addrsz - ns_int16sz)
535             return false;
536           tp += ns_int16sz;
537           saw_xdigit = false;
538           val = 0;
539           continue;
540         }
541
542       /* if ch is a dot ... */
543       if (ch == '.' && (tp <= ns_in6addrsz - ns_inaddrsz)
544           && is_valid_ipv4_address (curtok, end) == 1)
545         {
546           tp += ns_inaddrsz;
547           saw_xdigit = false;
548           break;
549         }
550
551       return false;
552     }
553
554   if (saw_xdigit)
555     {
556       if (tp > ns_in6addrsz - ns_int16sz)
557         return false;
558       tp += ns_int16sz;
559     }
560
561   if (colonp != NULL)
562     {
563       if (tp == ns_in6addrsz)
564         return false;
565       tp = ns_in6addrsz;
566     }
567
568   if (tp != ns_in6addrsz)
569     return false;
570
571   return true;
572 }
573 \f
574 /* Simple host cache, used by lookup_host to speed up resolving.  The
575    cache doesn't handle TTL because Wget is a fairly short-lived
576    application.  Refreshing is attempted when connect fails, though --
577    see connect_to_host.  */
578
579 /* Mapping between known hosts and to lists of their addresses. */
580 static struct hash_table *host_name_addresses_map;
581
582
583 /* Return the host's resolved addresses from the cache, if
584    available.  */
585
586 static struct address_list *
587 cache_query (const char *host)
588 {
589   struct address_list *al;
590   if (!host_name_addresses_map)
591     return NULL;
592   al = hash_table_get (host_name_addresses_map, host);
593   if (al)
594     {
595       DEBUGP (("Found %s in host_name_addresses_map (%p)\n", host, al));
596       ++al->refcount;
597       return al;
598     }
599   return NULL;
600 }
601
602 /* Cache the DNS lookup of HOST.  Subsequent invocations of
603    lookup_host will return the cached value.  */
604
605 static void
606 cache_store (const char *host, struct address_list *al)
607 {
608   if (!host_name_addresses_map)
609     host_name_addresses_map = make_nocase_string_hash_table (0);
610
611   ++al->refcount;
612   hash_table_put (host_name_addresses_map, xstrdup_lower (host), al);
613
614   IF_DEBUG
615     {
616       int i;
617       debug_logprintf ("Caching %s =>", host);
618       for (i = 0; i < al->count; i++)
619         debug_logprintf (" %s", print_address (al->addresses + i));
620       debug_logprintf ("\n");
621     }
622 }
623
624 /* Remove HOST from the DNS cache.  Does nothing is HOST is not in
625    the cache.  */
626
627 static void
628 cache_remove (const char *host)
629 {
630   struct address_list *al;
631   if (!host_name_addresses_map)
632     return;
633   al = hash_table_get (host_name_addresses_map, host);
634   if (al)
635     {
636       address_list_release (al);
637       hash_table_remove (host_name_addresses_map, host);
638     }
639 }
640 \f
641 /* Look up HOST in DNS and return a list of IP addresses.
642
643    This function caches its result so that, if the same host is passed
644    the second time, the addresses are returned without DNS lookup.
645    (Use LH_REFRESH to force lookup, or set opt.dns_cache to 0 to
646    globally disable caching.)
647
648    The order of the returned addresses is affected by the setting of
649    opt.prefer_family: if it is set to prefer_ipv4, IPv4 addresses are
650    placed at the beginning; if it is prefer_ipv6, IPv6 ones are placed
651    at the beginning; otherwise, the order is left intact.  The
652    relative order of addresses with the same family is left
653    undisturbed in either case.
654
655    FLAGS can be a combination of:
656      LH_SILENT  - don't print the "resolving ... done" messages.
657      LH_BIND    - resolve addresses for use with bind, which under
658                   IPv6 means to use AI_PASSIVE flag to getaddrinfo.
659                   Passive lookups are not cached under IPv6.
660      LH_REFRESH - if HOST is cached, remove the entry from the cache
661                   and resolve it anew.  */
662
663 struct address_list *
664 lookup_host (const char *host, int flags)
665 {
666   struct address_list *al;
667   bool silent = !!(flags & LH_SILENT);
668   bool use_cache;
669   bool numeric_address = false;
670   double timeout = opt.dns_timeout;
671
672 #ifndef ENABLE_IPV6
673   /* If we're not using getaddrinfo, first check if HOST specifies a
674      numeric IPv4 address.  Some implementations of gethostbyname
675      (e.g. the Ultrix one and possibly Winsock) don't accept
676      dotted-decimal IPv4 addresses.  */
677   {
678     uint32_t addr_ipv4 = (uint32_t)inet_addr (host);
679     if (addr_ipv4 != (uint32_t) -1)
680       {
681         /* No need to cache host->addr relation, just return the
682            address.  */
683         char *vec[2];
684         vec[0] = (char *)&addr_ipv4;
685         vec[1] = NULL;
686         return address_list_from_ipv4_addresses (vec);
687       }
688   }
689 #else  /* ENABLE_IPV6 */
690   /* If we're using getaddrinfo, at least check whether the address is
691      already numeric, in which case there is no need to print the
692      "Resolving..." output.  (This comes at no additional cost since
693      the is_valid_ipv*_address are already required for
694      url_parse.)  */
695   {
696     const char *end = host + strlen (host);
697     if (is_valid_ipv4_address (host, end) || is_valid_ipv6_address (host, end))
698       numeric_address = true;
699   }
700 #endif
701
702   /* Cache is normally on, but can be turned off with --no-dns-cache.
703      Don't cache passive lookups under IPv6.  */
704   use_cache = opt.dns_cache;
705 #ifdef ENABLE_IPV6
706   if ((flags & LH_BIND) || numeric_address)
707     use_cache = false;
708 #endif
709
710   /* Try to find the host in the cache so we don't need to talk to the
711      resolver.  If LH_REFRESH is requested, remove HOST from the cache
712      instead.  */
713   if (use_cache)
714     {
715       if (!(flags & LH_REFRESH))
716         {
717           al = cache_query (host);
718           if (al)
719             return al;
720         }
721       else
722         cache_remove (host);
723     }
724
725   /* No luck with the cache; resolve HOST. */
726
727   if (!silent && !numeric_address)
728     {
729       char *str = NULL, *name;
730
731       if (opt.enable_iri && (name = idn_decode ((char *) host)) != NULL)
732         {
733           int len = strlen (host) + strlen (name) + 4;
734           str = xmalloc (len);
735           snprintf (str, len, "%s (%s)", name, host);
736           str[len-1] = '\0';
737           xfree (name);
738         }
739
740       logprintf (LOG_VERBOSE, _("Resolving %s... "),
741                  quotearg_style (escape_quoting_style, str ? str : host));
742
743       if (str)
744         xfree (str);
745     }
746
747 #ifdef ENABLE_IPV6
748   {
749     int err;
750     struct addrinfo hints, *res;
751
752     xzero (hints);
753     hints.ai_socktype = SOCK_STREAM;
754     if (opt.ipv4_only)
755       hints.ai_family = AF_INET;
756     else if (opt.ipv6_only)
757       hints.ai_family = AF_INET6;
758     else
759       /* We tried using AI_ADDRCONFIG, but removed it because: it
760          misinterprets IPv6 loopbacks, it is broken on AIX 5.1, and
761          it's unneeded since we sort the addresses anyway.  */
762         hints.ai_family = AF_UNSPEC;
763
764     if (flags & LH_BIND)
765       hints.ai_flags |= AI_PASSIVE;
766
767 #ifdef AI_NUMERICHOST
768     if (numeric_address)
769       {
770         /* Where available, the AI_NUMERICHOST hint can prevent costly
771            access to DNS servers.  */
772         hints.ai_flags |= AI_NUMERICHOST;
773         timeout = 0;            /* no timeout needed when "resolving"
774                                    numeric hosts -- avoid setting up
775                                    signal handlers and such. */
776       }
777 #endif
778
779     err = getaddrinfo_with_timeout (host, NULL, &hints, &res, timeout);
780     if (err != 0 || res == NULL)
781       {
782         if (!silent)
783           logprintf (LOG_VERBOSE, _("failed: %s.\n"),
784                      err != EAI_SYSTEM ? gai_strerror (err) : strerror (errno));
785         return NULL;
786       }
787     al = address_list_from_addrinfo (res);
788     freeaddrinfo (res);
789     if (!al)
790       {
791         logprintf (LOG_VERBOSE,
792                    _("failed: No IPv4/IPv6 addresses for host.\n"));
793         return NULL;
794       }
795
796     /* Reorder addresses so that IPv4 ones (or IPv6 ones, as per
797        --prefer-family) come first.  Sorting is stable so the order of
798        the addresses with the same family is undisturbed.  */
799     if (al->count > 1 && opt.prefer_family != prefer_none)
800       stable_sort (al->addresses, al->count, sizeof (ip_address),
801                    opt.prefer_family == prefer_ipv4
802                    ? cmp_prefer_ipv4 : cmp_prefer_ipv6);
803   }
804 #else  /* not ENABLE_IPV6 */
805   {
806     struct hostent *hptr = gethostbyname_with_timeout (host, timeout);
807     if (!hptr)
808       {
809         if (!silent)
810           {
811             if (errno != ETIMEDOUT)
812               logprintf (LOG_VERBOSE, _("failed: %s.\n"),
813                          host_errstr (h_errno));
814             else
815               logputs (LOG_VERBOSE, _("failed: timed out.\n"));
816           }
817         return NULL;
818       }
819     /* Do older systems have h_addr_list?  */
820     al = address_list_from_ipv4_addresses (hptr->h_addr_list);
821   }
822 #endif /* not ENABLE_IPV6 */
823
824   /* Print the addresses determined by DNS lookup, but no more than
825      three if show_all_dns_entries is not specified.  */
826   if (!silent && !numeric_address)
827     {
828       int i;
829       int printmax = al->count;
830
831       if (!opt.show_all_dns_entries && printmax > 3)
832           printmax = 3;
833
834       for (i = 0; i < printmax; i++)
835         {
836           logputs (LOG_VERBOSE, print_address (al->addresses + i));
837           if (i < printmax - 1)
838             logputs (LOG_VERBOSE, ", ");
839         }
840       if (printmax != al->count)
841         logputs (LOG_VERBOSE, ", ...");
842       logputs (LOG_VERBOSE, "\n");
843     }
844
845   /* Cache the lookup information. */
846   if (use_cache)
847     cache_store (host, al);
848
849   return al;
850 }
851 \f
852 /* Determine whether a URL is acceptable to be followed, according to
853    a list of domains to accept.  */
854 bool
855 accept_domain (struct url *u)
856 {
857   assert (u->host != NULL);
858   if (opt.domains)
859     {
860       if (!sufmatch ((const char **)opt.domains, u->host))
861         return false;
862     }
863   if (opt.exclude_domains)
864     {
865       if (sufmatch ((const char **)opt.exclude_domains, u->host))
866         return false;
867     }
868   return true;
869 }
870
871 /* Check whether WHAT is matched in LIST, each element of LIST being a
872    pattern to match WHAT against, using backward matching (see
873    match_backwards() in utils.c).
874
875    If an element of LIST matched, 1 is returned, 0 otherwise.  */
876 bool
877 sufmatch (const char **list, const char *what)
878 {
879   int i, j, k, lw;
880
881   lw = strlen (what);
882   for (i = 0; list[i]; i++)
883     {
884       if (list[i][0] == '\0')
885         continue;
886
887       for (j = strlen (list[i]), k = lw; j >= 0 && k >= 0; j--, k--)
888         if (c_tolower (list[i][j]) != c_tolower (what[k]))
889           break;
890       /* The domain must be first to reach to beginning.  */
891       if (j == -1)
892         return true;
893     }
894   return false;
895 }
896
897 void
898 host_cleanup (void)
899 {
900   if (host_name_addresses_map)
901     {
902       hash_table_iterator iter;
903       for (hash_table_iterate (host_name_addresses_map, &iter);
904            hash_table_iter_next (&iter);
905            )
906         {
907           char *host = iter.key;
908           struct address_list *al = iter.value;
909           xfree (host);
910           assert (al->refcount == 1);
911           address_list_delete (al);
912         }
913       hash_table_destroy (host_name_addresses_map);
914       host_name_addresses_map = NULL;
915     }
916 }
917
918 bool
919 is_valid_ip_address (const char *name)
920 {
921   const char *endp;
922
923   endp = name + strlen(name);
924   if (is_valid_ipv4_address (name, endp))
925     return true;
926 #ifdef ENABLE_IPV6
927   if (is_valid_ipv6_address (name, endp))
928     return true;
929 #endif
930   return false;
931 }