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