tidying
[exim.git] / src / src / host.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) University of Cambridge 1995 - 2018 */
6 /* See the file NOTICE for conditions of use and distribution. */
7
8 /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or
9 directly via the DNS. When IPv6 is supported, getipnodebyname() and
10 getipnodebyaddr() may be used instead of gethostbyname() and gethostbyaddr(),
11 if the newer functions are available. This module also contains various other
12 functions concerned with hosts and addresses, and a random number function,
13 used for randomizing hosts with equal MXs but available for use in other parts
14 of Exim. */
15
16
17 #include "exim.h"
18
19
20 /* Static variable for preserving the list of interface addresses in case it is
21 used more than once. */
22
23 static ip_address_item *local_interface_data = NULL;
24
25
26 #ifdef USE_INET_NTOA_FIX
27 /*************************************************
28 *         Replacement for broken inet_ntoa()     *
29 *************************************************/
30
31 /* On IRIX systems, gcc uses a different structure passing convention to the
32 native libraries. This causes inet_ntoa() to always yield 0.0.0.0 or
33 255.255.255.255. To get round this, we provide a private version of the
34 function here. It is used only if USE_INET_NTOA_FIX is set, which should happen
35 only when gcc is in use on an IRIX system. Code send to me by J.T. Breitner,
36 with these comments:
37
38   code by Stuart Levy
39   as seen in comp.sys.sgi.admin
40
41 August 2005: Apparently this is also needed for AIX systems; USE_INET_NTOA_FIX
42 should now be set for them as well.
43
44 Arguments:  sa  an in_addr structure
45 Returns:        pointer to static text string
46 */
47
48 char *
49 inet_ntoa(struct in_addr sa)
50 {
51 static uschar addr[20];
52 sprintf(addr, "%d.%d.%d.%d",
53         (US &sa.s_addr)[0],
54         (US &sa.s_addr)[1],
55         (US &sa.s_addr)[2],
56         (US &sa.s_addr)[3]);
57   return addr;
58 }
59 #endif
60
61
62
63 /*************************************************
64 *              Random number generator           *
65 *************************************************/
66
67 /* This is a simple pseudo-random number generator. It does not have to be
68 very good for the uses to which it is put. When running the regression tests,
69 start with a fixed seed.
70
71 If you need better, see vaguely_random_number() which is potentially stronger,
72 if a crypto library is available, but might end up just calling this instead.
73
74 Arguments:
75   limit:    one more than the largest number required
76
77 Returns:    a pseudo-random number in the range 0 to limit-1
78 */
79
80 int
81 random_number(int limit)
82 {
83 if (limit < 1)
84   return 0;
85 if (random_seed == 0)
86   {
87   if (f.running_in_test_harness) random_seed = 42; else
88     {
89     int p = (int)getpid();
90     random_seed = (int)time(NULL) ^ ((p << 16) | p);
91     }
92   }
93 random_seed = 1103515245 * random_seed + 12345;
94 return (unsigned int)(random_seed >> 16) % limit;
95 }
96
97 /*************************************************
98 *      Wrappers for logging lookup times         *
99 *************************************************/
100
101 /* When the 'slow_lookup_log' variable is enabled, these wrappers will
102 write to the log file all (potential) dns lookups that take more than
103 slow_lookup_log milliseconds
104 */
105
106 static void
107 log_long_lookup(const uschar * type, const uschar * data, unsigned long msec)
108 {
109 log_write(0, LOG_MAIN, "Long %s lookup for '%s': %lu msec",
110   type, data, msec);
111 }
112
113
114 /* returns the current system epoch time in milliseconds. */
115 static unsigned long
116 get_time_in_ms()
117 {
118 struct timeval tmp_time;
119 unsigned long seconds, microseconds;
120
121 gettimeofday(&tmp_time, NULL);
122 seconds = (unsigned long) tmp_time.tv_sec;
123 microseconds = (unsigned long) tmp_time.tv_usec;
124 return seconds*1000 + microseconds/1000;
125 }
126
127
128 static int
129 dns_lookup_timerwrap(dns_answer *dnsa, const uschar *name, int type,
130   const uschar **fully_qualified_name)
131 {
132 int retval;
133 unsigned long time_msec;
134
135 if (!slow_lookup_log)
136   return dns_lookup(dnsa, name, type, fully_qualified_name);
137
138 time_msec = get_time_in_ms();
139 retval = dns_lookup(dnsa, name, type, fully_qualified_name);
140 if ((time_msec = get_time_in_ms() - time_msec) > slow_lookup_log)
141   log_long_lookup(US"name", name, time_msec);
142 return retval;
143 }
144
145
146 /*************************************************
147 *       Replace gethostbyname() when testing     *
148 *************************************************/
149
150 /* This function is called instead of gethostbyname(), gethostbyname2(), or
151 getipnodebyname() when running in the test harness. . It also
152 recognizes an unqualified "localhost" and forces it to the appropriate loopback
153 address. IP addresses are treated as literals. For other names, it uses the DNS
154 to find the host name. In the test harness, this means it will access only the
155 fake DNS resolver.
156
157 Arguments:
158   name          the host name or a textual IP address
159   af            AF_INET or AF_INET6
160   error_num     where to put an error code:
161                 HOST_NOT_FOUND/TRY_AGAIN/NO_RECOVERY/NO_DATA
162
163 Returns:        a hostent structure or NULL for an error
164 */
165
166 static struct hostent *
167 host_fake_gethostbyname(const uschar *name, int af, int *error_num)
168 {
169 #if HAVE_IPV6
170 int alen = (af == AF_INET)? sizeof(struct in_addr):sizeof(struct in6_addr);
171 #else
172 int alen = sizeof(struct in_addr);
173 #endif
174
175 int ipa;
176 const uschar *lname = name;
177 uschar *adds;
178 uschar **alist;
179 struct hostent *yield;
180 dns_answer dnsa;
181 dns_scan dnss;
182 dns_record *rr;
183
184 DEBUG(D_host_lookup)
185   debug_printf("using host_fake_gethostbyname for %s (%s)\n", name,
186     (af == AF_INET)? "IPv4" : "IPv6");
187
188 /* Handle unqualified "localhost" */
189
190 if (Ustrcmp(name, "localhost") == 0)
191   lname = (af == AF_INET)? US"127.0.0.1" : US"::1";
192
193 /* Handle a literal IP address */
194
195 ipa = string_is_ip_address(lname, NULL);
196 if (ipa != 0)
197   {
198   if ((ipa == 4 && af == AF_INET) ||
199       (ipa == 6 && af == AF_INET6))
200     {
201     int i, n;
202     int x[4];
203     yield = store_get(sizeof(struct hostent));
204     alist = store_get(2 * sizeof(char *));
205     adds  = store_get(alen);
206     yield->h_name = CS name;
207     yield->h_aliases = NULL;
208     yield->h_addrtype = af;
209     yield->h_length = alen;
210     yield->h_addr_list = CSS alist;
211     *alist++ = adds;
212     n = host_aton(lname, x);
213     for (i = 0; i < n; i++)
214       {
215       int y = x[i];
216       *adds++ = (y >> 24) & 255;
217       *adds++ = (y >> 16) & 255;
218       *adds++ = (y >> 8) & 255;
219       *adds++ = y & 255;
220       }
221     *alist = NULL;
222     }
223
224   /* Wrong kind of literal address */
225
226   else
227     {
228     *error_num = HOST_NOT_FOUND;
229     return NULL;
230     }
231   }
232
233 /* Handle a host name */
234
235 else
236   {
237   int type = (af == AF_INET)? T_A:T_AAAA;
238   int rc = dns_lookup_timerwrap(&dnsa, lname, type, NULL);
239   int count = 0;
240
241   lookup_dnssec_authenticated = NULL;
242
243   switch(rc)
244     {
245     case DNS_SUCCEED: break;
246     case DNS_NOMATCH: *error_num = HOST_NOT_FOUND; return NULL;
247     case DNS_NODATA:  *error_num = NO_DATA; return NULL;
248     case DNS_AGAIN:   *error_num = TRY_AGAIN; return NULL;
249     default:
250     case DNS_FAIL:    *error_num = NO_RECOVERY; return NULL;
251     }
252
253   for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
254        rr;
255        rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
256     if (rr->type == type)
257       count++;
258
259   yield = store_get(sizeof(struct hostent));
260   alist = store_get((count + 1) * sizeof(char *));
261   adds  = store_get(count *alen);
262
263   yield->h_name = CS name;
264   yield->h_aliases = NULL;
265   yield->h_addrtype = af;
266   yield->h_length = alen;
267   yield->h_addr_list = CSS alist;
268
269   for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
270        rr;
271        rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
272     {
273     int i, n;
274     int x[4];
275     dns_address *da;
276     if (rr->type != type) continue;
277     if (!(da = dns_address_from_rr(&dnsa, rr))) break;
278     *alist++ = adds;
279     n = host_aton(da->address, x);
280     for (i = 0; i < n; i++)
281       {
282       int y = x[i];
283       *adds++ = (y >> 24) & 255;
284       *adds++ = (y >> 16) & 255;
285       *adds++ = (y >> 8) & 255;
286       *adds++ = y & 255;
287       }
288     }
289   *alist = NULL;
290   }
291
292 return yield;
293 }
294
295
296
297 /*************************************************
298 *       Build chain of host items from list      *
299 *************************************************/
300
301 /* This function builds a chain of host items from a textual list of host
302 names. It does not do any lookups. If randomize is true, the chain is build in
303 a randomized order. There may be multiple groups of independently randomized
304 hosts; they are delimited by a host name consisting of just "+".
305
306 Arguments:
307   anchor      anchor for the chain
308   list        text list
309   randomize   TRUE for randomizing
310
311 Returns:      nothing
312 */
313
314 void
315 host_build_hostlist(host_item **anchor, const uschar *list, BOOL randomize)
316 {
317 int sep = 0;
318 int fake_mx = MX_NONE;          /* This value is actually -1 */
319 uschar *name;
320
321 if (!list) return;
322 if (randomize) fake_mx--;       /* Start at -2 for randomizing */
323
324 *anchor = NULL;
325
326 while ((name = string_nextinlist(&list, &sep, NULL, 0)))
327   {
328   host_item *h;
329
330   if (name[0] == '+' && name[1] == 0)   /* "+" delimits a randomized group */
331     {                                   /* ignore if not randomizing */
332     if (randomize) fake_mx--;
333     continue;
334     }
335
336   h = store_get(sizeof(host_item));
337   h->name = name;
338   h->address = NULL;
339   h->port = PORT_NONE;
340   h->mx = fake_mx;
341   h->sort_key = randomize? (-fake_mx)*1000 + random_number(1000) : 0;
342   h->status = hstatus_unknown;
343   h->why = hwhy_unknown;
344   h->last_try = 0;
345
346   if (!*anchor)
347     {
348     h->next = NULL;
349     *anchor = h;
350     }
351   else
352     {
353     host_item *hh = *anchor;
354     if (h->sort_key < hh->sort_key)
355       {
356       h->next = hh;
357       *anchor = h;
358       }
359     else
360       {
361       while (hh->next && h->sort_key >= hh->next->sort_key)
362         hh = hh->next;
363       h->next = hh->next;
364       hh->next = h;
365       }
366     }
367   }
368 }
369
370
371
372
373
374 /*************************************************
375 *        Extract port from address string        *
376 *************************************************/
377
378 /* In the spool file, and in the -oMa and -oMi options, a host plus port is
379 given as an IP address followed by a dot and a port number. This function
380 decodes this.
381
382 An alternative format for the -oMa and -oMi options is [ip address]:port which
383 is what Exim 4 uses for output, because it seems to becoming commonly used,
384 whereas the dot form confuses some programs/people. So we recognize that form
385 too.
386
387 Argument:
388   address    points to the string; if there is a port, the '.' in the string
389              is overwritten with zero to terminate the address; if the string
390              is in the [xxx]:ppp format, the address is shifted left and the
391              brackets are removed
392
393 Returns:     0 if there is no port, else the port number. If there's a syntax
394              error, leave the incoming address alone, and return 0.
395 */
396
397 int
398 host_address_extract_port(uschar *address)
399 {
400 int port = 0;
401 uschar *endptr;
402
403 /* Handle the "bracketed with colon on the end" format */
404
405 if (*address == '[')
406   {
407   uschar *rb = address + 1;
408   while (*rb != 0 && *rb != ']') rb++;
409   if (*rb++ == 0) return 0;        /* Missing ]; leave invalid address */
410   if (*rb == ':')
411     {
412     port = Ustrtol(rb + 1, &endptr, 10);
413     if (*endptr != 0) return 0;    /* Invalid port; leave invalid address */
414     }
415   else if (*rb != 0) return 0;     /* Bad syntax; leave invalid address */
416   memmove(address, address + 1, rb - address - 2);
417   rb[-2] = 0;
418   }
419
420 /* Handle the "dot on the end" format */
421
422 else
423   {
424   int skip = -3;                   /* Skip 3 dots in IPv4 addresses */
425   address--;
426   while (*(++address) != 0)
427     {
428     int ch = *address;
429     if (ch == ':') skip = 0;       /* Skip 0 dots in IPv6 addresses */
430       else if (ch == '.' && skip++ >= 0) break;
431     }
432   if (*address == 0) return 0;
433   port = Ustrtol(address + 1, &endptr, 10);
434   if (*endptr != 0) return 0;      /* Invalid port; leave invalid address */
435   *address = 0;
436   }
437
438 return port;
439 }
440
441
442 /*************************************************
443 *         Get port from a host item's name       *
444 *************************************************/
445
446 /* This function is called when finding the IP address for a host that is in a
447 list of hosts explicitly configured, such as in the manualroute router, or in a
448 fallback hosts list. We see if there is a port specification at the end of the
449 host name, and if so, remove it. A minimum length of 3 is required for the
450 original name; nothing shorter is recognized as having a port.
451
452 We test for a name ending with a sequence of digits; if preceded by colon we
453 have a port if the character before the colon is ] and the name starts with [
454 or if there are no other colons in the name (i.e. it's not an IPv6 address).
455
456 Arguments:  pointer to the host item
457 Returns:    a port number or PORT_NONE
458 */
459
460 int
461 host_item_get_port(host_item *h)
462 {
463 const uschar *p;
464 int port, x;
465 int len = Ustrlen(h->name);
466
467 if (len < 3 || (p = h->name + len - 1, !isdigit(*p))) return PORT_NONE;
468
469 /* Extract potential port number */
470
471 port = *p-- - '0';
472 x = 10;
473
474 while (p > h->name + 1 && isdigit(*p))
475   {
476   port += (*p-- - '0') * x;
477   x *= 10;
478   }
479
480 /* The smallest value of p at this point is h->name + 1. */
481
482 if (*p != ':') return PORT_NONE;
483
484 if (p[-1] == ']' && h->name[0] == '[')
485   h->name = string_copyn(h->name + 1, p - h->name - 2);
486 else if (Ustrchr(h->name, ':') == p)
487   h->name = string_copyn(h->name, p - h->name);
488 else return PORT_NONE;
489
490 DEBUG(D_route|D_host_lookup) debug_printf("host=%s port=%d\n", h->name, port);
491 return port;
492 }
493
494
495
496 #ifndef STAND_ALONE    /* Omit when standalone testing */
497
498 /*************************************************
499 *     Build sender_fullhost and sender_rcvhost   *
500 *************************************************/
501
502 /* This function is called when sender_host_name and/or sender_helo_name
503 have been set. Or might have been set - for a local message read off the spool
504 they won't be. In that case, do nothing. Otherwise, set up the fullhost string
505 as follows:
506
507 (a) No sender_host_name or sender_helo_name: "[ip address]"
508 (b) Just sender_host_name: "host_name [ip address]"
509 (c) Just sender_helo_name: "(helo_name) [ip address]" unless helo is IP
510             in which case: "[ip address}"
511 (d) The two are identical: "host_name [ip address]" includes helo = IP
512 (e) The two are different: "host_name (helo_name) [ip address]"
513
514 If log_incoming_port is set, the sending host's port number is added to the IP
515 address.
516
517 This function also builds sender_rcvhost for use in Received: lines, whose
518 syntax is a bit different. This value also includes the RFC 1413 identity.
519 There wouldn't be two different variables if I had got all this right in the
520 first place.
521
522 Because this data may survive over more than one incoming SMTP message, it has
523 to be in permanent store.  However, STARTTLS has to be forgotten and redone
524 on a multi-message conn, so this will be called once per message then.  Hence
525 we use malloc, so we can free.
526
527 Arguments:  none
528 Returns:    nothing
529 */
530
531 void
532 host_build_sender_fullhost(void)
533 {
534 BOOL show_helo = TRUE;
535 uschar * address, * fullhost, * rcvhost, * reset_point;
536 int len;
537
538 if (!sender_host_address) return;
539
540 reset_point = store_get(0);
541
542 /* Set up address, with or without the port. After discussion, it seems that
543 the only format that doesn't cause trouble is [aaaa]:pppp. However, we can't
544 use this directly as the first item for Received: because it ain't an RFC 2822
545 domain. Sigh. */
546
547 address = string_sprintf("[%s]:%d", sender_host_address, sender_host_port);
548 if (!LOGGING(incoming_port) || sender_host_port <= 0)
549   *(Ustrrchr(address, ':')) = 0;
550
551 /* If there's no EHLO/HELO data, we can't show it. */
552
553 if (!sender_helo_name) show_helo = FALSE;
554
555 /* If HELO/EHLO was followed by an IP literal, it's messy because of two
556 features of IPv6. Firstly, there's the "IPv6:" prefix (Exim is liberal and
557 doesn't require this, for historical reasons). Secondly, IPv6 addresses may not
558 be given in canonical form, so we have to canonicalize them before comparing. As
559 it happens, the code works for both IPv4 and IPv6. */
560
561 else if (sender_helo_name[0] == '[' &&
562          sender_helo_name[(len=Ustrlen(sender_helo_name))-1] == ']')
563   {
564   int offset = 1;
565   uschar *helo_ip;
566
567   if (strncmpic(sender_helo_name + 1, US"IPv6:", 5) == 0) offset += 5;
568   if (strncmpic(sender_helo_name + 1, US"IPv4:", 5) == 0) offset += 5;
569
570   helo_ip = string_copyn(sender_helo_name + offset, len - offset - 1);
571
572   if (string_is_ip_address(helo_ip, NULL) != 0)
573     {
574     int x[4], y[4];
575     int sizex, sizey;
576     uschar ipx[48], ipy[48];    /* large enough for full IPv6 */
577
578     sizex = host_aton(helo_ip, x);
579     sizey = host_aton(sender_host_address, y);
580
581     (void)host_nmtoa(sizex, x, -1, ipx, ':');
582     (void)host_nmtoa(sizey, y, -1, ipy, ':');
583
584     if (strcmpic(ipx, ipy) == 0) show_helo = FALSE;
585     }
586   }
587
588 /* Host name is not verified */
589
590 if (!sender_host_name)
591   {
592   uschar *portptr = Ustrstr(address, "]:");
593   gstring * g;
594   int adlen;    /* Sun compiler doesn't like ++ in initializers */
595
596   adlen = portptr ? (++portptr - address) : Ustrlen(address);
597   fullhost = sender_helo_name
598     ? string_sprintf("(%s) %s", sender_helo_name, address)
599     : address;
600
601   g = string_catn(NULL, address, adlen);
602
603   if (sender_ident || show_helo || portptr)
604     {
605     int firstptr;
606     g = string_catn(g, US" (", 2);
607     firstptr = g->ptr;
608
609     if (portptr)
610       g = string_append(g, 2, US"port=", portptr + 1);
611
612     if (show_helo)
613       g = string_append(g, 2,
614         firstptr == g->ptr ? US"helo=" : US" helo=", sender_helo_name);
615
616     if (sender_ident)
617       g = string_append(g, 2,
618         firstptr == g->ptr ? US"ident=" : US" ident=", sender_ident);
619
620     g = string_catn(g, US")", 1);
621     }
622
623   rcvhost = string_from_gstring(g);
624   }
625
626 /* Host name is known and verified. Unless we've already found that the HELO
627 data matches the IP address, compare it with the name. */
628
629 else
630   {
631   if (show_helo && strcmpic(sender_host_name, sender_helo_name) == 0)
632     show_helo = FALSE;
633
634   if (show_helo)
635     {
636     fullhost = string_sprintf("%s (%s) %s", sender_host_name,
637       sender_helo_name, address);
638     rcvhost = sender_ident
639       ?  string_sprintf("%s\n\t(%s helo=%s ident=%s)", sender_host_name,
640         address, sender_helo_name, sender_ident)
641       : string_sprintf("%s (%s helo=%s)", sender_host_name,
642         address, sender_helo_name);
643     }
644   else
645     {
646     fullhost = string_sprintf("%s %s", sender_host_name, address);
647     rcvhost = sender_ident
648       ?  string_sprintf("%s (%s ident=%s)", sender_host_name, address,
649         sender_ident)
650       : string_sprintf("%s (%s)", sender_host_name, address);
651     }
652   }
653
654 if (sender_fullhost) store_free(sender_fullhost);
655 sender_fullhost = string_copy_malloc(fullhost);
656 if (sender_rcvhost) store_free(sender_rcvhost);
657 sender_rcvhost = string_copy_malloc(rcvhost);
658
659 store_reset(reset_point);
660
661 DEBUG(D_host_lookup) debug_printf("sender_fullhost = %s\n", sender_fullhost);
662 DEBUG(D_host_lookup) debug_printf("sender_rcvhost = %s\n", sender_rcvhost);
663 }
664
665
666
667 /*************************************************
668 *          Build host+ident message              *
669 *************************************************/
670
671 /* Used when logging rejections and various ACL and SMTP incidents. The text
672 return depends on whether sender_fullhost and sender_ident are set or not:
673
674   no ident, no host   => U=unknown
675   no ident, host set  => H=sender_fullhost
676   ident set, no host  => U=ident
677   ident set, host set => H=sender_fullhost U=ident
678
679 Arguments:
680   useflag   TRUE if first item to be flagged (H= or U=); if there are two
681               items, the second is always flagged
682
683 Returns:    pointer to a string in big_buffer
684 */
685
686 uschar *
687 host_and_ident(BOOL useflag)
688 {
689 if (!sender_fullhost)
690   (void)string_format(big_buffer, big_buffer_size, "%s%s", useflag ? "U=" : "",
691      sender_ident ? sender_ident : US"unknown");
692 else
693   {
694   uschar * flag = useflag ? US"H=" : US"";
695   uschar * iface = US"";
696   if (LOGGING(incoming_interface) && interface_address)
697     iface = string_sprintf(" I=[%s]:%d", interface_address, interface_port);
698   if (sender_ident)
699     (void)string_format(big_buffer, big_buffer_size, "%s%s%s U=%s",
700       flag, sender_fullhost, iface, sender_ident);
701   else
702     (void)string_format(big_buffer, big_buffer_size, "%s%s%s",
703       flag, sender_fullhost, iface);
704   }
705 return big_buffer;
706 }
707
708 #endif   /* STAND_ALONE */
709
710
711
712
713 /*************************************************
714 *         Build list of local interfaces         *
715 *************************************************/
716
717 /* This function interprets the contents of the local_interfaces or
718 extra_local_interfaces options, and creates an ip_address_item block for each
719 item on the list. There is no special interpretation of any IP addresses; in
720 particular, 0.0.0.0 and ::0 are returned without modification. If any address
721 includes a port, it is set in the block. Otherwise the port value is set to
722 zero.
723
724 Arguments:
725   list        the list
726   name        the name of the option being expanded
727
728 Returns:      a chain of ip_address_items, each containing to a textual
729               version of an IP address, and a port number (host order) or
730               zero if no port was given with the address
731 */
732
733 ip_address_item *
734 host_build_ifacelist(const uschar *list, uschar *name)
735 {
736 int sep = 0;
737 uschar *s;
738 ip_address_item * yield = NULL, * last = NULL, * next;
739
740 while ((s = string_nextinlist(&list, &sep, NULL, 0)))
741   {
742   int ipv;
743   int port = host_address_extract_port(s);            /* Leaves just the IP address */
744
745   if (!(ipv = string_is_ip_address(s, NULL)))
746     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Malformed IP address \"%s\" in %s",
747       s, name);
748
749   /* Skip IPv6 addresses if IPv6 is disabled. */
750
751   if (disable_ipv6 && ipv == 6) continue;
752
753   /* This use of strcpy() is OK because we have checked that s is a valid IP
754   address above. The field in the ip_address_item is large enough to hold an
755   IPv6 address. */
756
757   next = store_get(sizeof(ip_address_item));
758   next->next = NULL;
759   Ustrcpy(next->address, s);
760   next->port = port;
761   next->v6_include_v4 = FALSE;
762
763   if (!yield)
764     yield = last = next;
765   else
766     {
767     last->next = next;
768     last = next;
769     }
770   }
771
772 return yield;
773 }
774
775
776
777
778
779 /*************************************************
780 *         Find addresses on local interfaces     *
781 *************************************************/
782
783 /* This function finds the addresses of local IP interfaces. These are used
784 when testing for routing to the local host. As the function may be called more
785 than once, the list is preserved in permanent store, pointed to by a static
786 variable, to save doing the work more than once per process.
787
788 The generic list of interfaces is obtained by calling host_build_ifacelist()
789 for local_interfaces and extra_local_interfaces. This list scanned to remove
790 duplicates (which may exist with different ports - not relevant here). If
791 either of the wildcard IP addresses (0.0.0.0 and ::0) are encountered, they are
792 replaced by the appropriate (IPv4 or IPv6) list of actual local interfaces,
793 obtained from os_find_running_interfaces().
794
795 Arguments:    none
796 Returns:      a chain of ip_address_items, each containing to a textual
797               version of an IP address; the port numbers are not relevant
798 */
799
800
801 /* First, a local subfunction to add an interface to a list in permanent store,
802 but only if there isn't a previous copy of that address on the list. */
803
804 static ip_address_item *
805 add_unique_interface(ip_address_item *list, ip_address_item *ipa)
806 {
807 ip_address_item *ipa2;
808 for (ipa2 = list; ipa2 != NULL; ipa2 = ipa2->next)
809   if (Ustrcmp(ipa2->address, ipa->address) == 0) return list;
810 ipa2 = store_get_perm(sizeof(ip_address_item));
811 *ipa2 = *ipa;
812 ipa2->next = list;
813 return ipa2;
814 }
815
816
817 /* This is the globally visible function */
818
819 ip_address_item *
820 host_find_interfaces(void)
821 {
822 ip_address_item *running_interfaces = NULL;
823
824 if (local_interface_data == NULL)
825   {
826   void *reset_item = store_get(0);
827   ip_address_item *dlist = host_build_ifacelist(CUS local_interfaces,
828     US"local_interfaces");
829   ip_address_item *xlist = host_build_ifacelist(CUS extra_local_interfaces,
830     US"extra_local_interfaces");
831   ip_address_item *ipa;
832
833   if (dlist == NULL) dlist = xlist; else
834     {
835     for (ipa = dlist; ipa->next != NULL; ipa = ipa->next);
836     ipa->next = xlist;
837     }
838
839   for (ipa = dlist; ipa != NULL; ipa = ipa->next)
840     {
841     if (Ustrcmp(ipa->address, "0.0.0.0") == 0 ||
842         Ustrcmp(ipa->address, "::0") == 0)
843       {
844       ip_address_item *ipa2;
845       BOOL ipv6 = ipa->address[0] == ':';
846       if (running_interfaces == NULL)
847         running_interfaces = os_find_running_interfaces();
848       for (ipa2 = running_interfaces; ipa2 != NULL; ipa2 = ipa2->next)
849         {
850         if ((Ustrchr(ipa2->address, ':') != NULL) == ipv6)
851           local_interface_data = add_unique_interface(local_interface_data,
852           ipa2);
853         }
854       }
855     else
856       {
857       local_interface_data = add_unique_interface(local_interface_data, ipa);
858       DEBUG(D_interface)
859         {
860         debug_printf("Configured local interface: address=%s", ipa->address);
861         if (ipa->port != 0) debug_printf(" port=%d", ipa->port);
862         debug_printf("\n");
863         }
864       }
865     }
866   store_reset(reset_item);
867   }
868
869 return local_interface_data;
870 }
871
872
873
874
875
876 /*************************************************
877 *        Convert network IP address to text      *
878 *************************************************/
879
880 /* Given an IPv4 or IPv6 address in binary, convert it to a text
881 string and return the result in a piece of new store. The address can
882 either be given directly, or passed over in a sockaddr structure. Note
883 that this isn't the converse of host_aton() because of byte ordering
884 differences. See host_nmtoa() below.
885
886 Arguments:
887   type       if < 0 then arg points to a sockaddr, else
888              either AF_INET or AF_INET6
889   arg        points to a sockaddr if type is < 0, or
890              points to an IPv4 address (32 bits), or
891              points to an IPv6 address (128 bits),
892              in both cases, in network byte order
893   buffer     if NULL, the result is returned in gotten store;
894              else points to a buffer to hold the answer
895   portptr    points to where to put the port number, if non NULL; only
896              used when type < 0
897
898 Returns:     pointer to character string
899 */
900
901 uschar *
902 host_ntoa(int type, const void *arg, uschar *buffer, int *portptr)
903 {
904 uschar *yield;
905
906 /* The new world. It is annoying that we have to fish out the address from
907 different places in the block, depending on what kind of address it is. It
908 is also a pain that inet_ntop() returns a const uschar *, whereas the IPv4
909 function inet_ntoa() returns just uschar *, and some picky compilers insist
910 on warning if one assigns a const uschar * to a uschar *. Hence the casts. */
911
912 #if HAVE_IPV6
913 uschar addr_buffer[46];
914 if (type < 0)
915   {
916   int family = ((struct sockaddr *)arg)->sa_family;
917   if (family == AF_INET6)
918     {
919     struct sockaddr_in6 *sk = (struct sockaddr_in6 *)arg;
920     yield = US inet_ntop(family, &(sk->sin6_addr), CS addr_buffer,
921       sizeof(addr_buffer));
922     if (portptr != NULL) *portptr = ntohs(sk->sin6_port);
923     }
924   else
925     {
926     struct sockaddr_in *sk = (struct sockaddr_in *)arg;
927     yield = US inet_ntop(family, &(sk->sin_addr), CS addr_buffer,
928       sizeof(addr_buffer));
929     if (portptr != NULL) *portptr = ntohs(sk->sin_port);
930     }
931   }
932 else
933   {
934   yield = US inet_ntop(type, arg, CS addr_buffer, sizeof(addr_buffer));
935   }
936
937 /* If the result is a mapped IPv4 address, show it in V4 format. */
938
939 if (Ustrncmp(yield, "::ffff:", 7) == 0) yield += 7;
940
941 #else  /* HAVE_IPV6 */
942
943 /* The old world */
944
945 if (type < 0)
946   {
947   yield = US inet_ntoa(((struct sockaddr_in *)arg)->sin_addr);
948   if (portptr != NULL) *portptr = ntohs(((struct sockaddr_in *)arg)->sin_port);
949   }
950 else
951   yield = US inet_ntoa(*((struct in_addr *)arg));
952 #endif
953
954 /* If there is no buffer, put the string into some new store. */
955
956 if (buffer == NULL) return string_copy(yield);
957
958 /* Callers of this function with a non-NULL buffer must ensure that it is
959 large enough to hold an IPv6 address, namely, at least 46 bytes. That's what
960 makes this use of strcpy() OK. */
961
962 Ustrcpy(buffer, yield);
963 return buffer;
964 }
965
966
967
968
969 /*************************************************
970 *         Convert address text to binary         *
971 *************************************************/
972
973 /* Given the textual form of an IP address, convert it to binary in an
974 array of ints. IPv4 addresses occupy one int; IPv6 addresses occupy 4 ints.
975 The result has the first byte in the most significant byte of the first int. In
976 other words, the result is not in network byte order, but in host byte order.
977 As a result, this is not the converse of host_ntoa(), which expects network
978 byte order. See host_nmtoa() below.
979
980 Arguments:
981   address    points to the textual address, checked for syntax
982   bin        points to an array of 4 ints
983
984 Returns:     the number of ints used
985 */
986
987 int
988 host_aton(const uschar *address, int *bin)
989 {
990 int x[4];
991 int v4offset = 0;
992
993 /* Handle IPv6 address, which may end with an IPv4 address. It may also end
994 with a "scope", introduced by a percent sign. This code is NOT enclosed in #if
995 HAVE_IPV6 in order that IPv6 addresses are recognized even if IPv6 is not
996 supported. */
997
998 if (Ustrchr(address, ':') != NULL)
999   {
1000   const uschar *p = address;
1001   const uschar *component[8];
1002   BOOL ipv4_ends = FALSE;
1003   int ci = 0;
1004   int nulloffset = 0;
1005   int v6count = 8;
1006   int i;
1007
1008   /* If the address starts with a colon, it will start with two colons.
1009   Just lose the first one, which will leave a null first component. */
1010
1011   if (*p == ':') p++;
1012
1013   /* Split the address into components separated by colons. The input address
1014   is supposed to be checked for syntax. There was a case where this was
1015   overlooked; to guard against that happening again, check here and crash if
1016   there are too many components. */
1017
1018   while (*p != 0 && *p != '%')
1019     {
1020     int len = Ustrcspn(p, ":%");
1021     if (len == 0) nulloffset = ci;
1022     if (ci > 7) log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1023       "Internal error: invalid IPv6 address \"%s\" passed to host_aton()",
1024       address);
1025     component[ci++] = p;
1026     p += len;
1027     if (*p == ':') p++;
1028     }
1029
1030   /* If the final component contains a dot, it is a trailing v4 address.
1031   As the syntax is known to be checked, just set up for a trailing
1032   v4 address and restrict the v6 part to 6 components. */
1033
1034   if (Ustrchr(component[ci-1], '.') != NULL)
1035     {
1036     address = component[--ci];
1037     ipv4_ends = TRUE;
1038     v4offset = 3;
1039     v6count = 6;
1040     }
1041
1042   /* If there are fewer than 6 or 8 components, we have to insert some
1043   more empty ones in the middle. */
1044
1045   if (ci < v6count)
1046     {
1047     int insert_count = v6count - ci;
1048     for (i = v6count-1; i > nulloffset + insert_count; i--)
1049       component[i] = component[i - insert_count];
1050     while (i > nulloffset) component[i--] = US"";
1051     }
1052
1053   /* Now turn the components into binary in pairs and bung them
1054   into the vector of ints. */
1055
1056   for (i = 0; i < v6count; i += 2)
1057     bin[i/2] = (Ustrtol(component[i], NULL, 16) << 16) +
1058       Ustrtol(component[i+1], NULL, 16);
1059
1060   /* If there was no terminating v4 component, we are done. */
1061
1062   if (!ipv4_ends) return 4;
1063   }
1064
1065 /* Handle IPv4 address */
1066
1067 (void)sscanf(CS address, "%d.%d.%d.%d", x, x+1, x+2, x+3);
1068 bin[v4offset] = ((uint)x[0] << 24) + (x[1] << 16) + (x[2] << 8) + x[3];
1069 return v4offset+1;
1070 }
1071
1072
1073 /*************************************************
1074 *           Apply mask to an IP address          *
1075 *************************************************/
1076
1077 /* Mask an address held in 1 or 4 ints, with the ms bit in the ms bit of the
1078 first int, etc.
1079
1080 Arguments:
1081   count        the number of ints
1082   binary       points to the ints to be masked
1083   mask         the count of ms bits to leave, or -1 if no masking
1084
1085 Returns:       nothing
1086 */
1087
1088 void
1089 host_mask(int count, int *binary, int mask)
1090 {
1091 int i;
1092 if (mask < 0) mask = 99999;
1093 for (i = 0; i < count; i++)
1094   {
1095   int wordmask;
1096   if (mask == 0) wordmask = 0;
1097   else if (mask < 32)
1098     {
1099     wordmask = (uint)(-1) << (32 - mask);
1100     mask = 0;
1101     }
1102   else
1103     {
1104     wordmask = -1;
1105     mask -= 32;
1106     }
1107   binary[i] &= wordmask;
1108   }
1109 }
1110
1111
1112
1113
1114 /*************************************************
1115 *     Convert masked IP address in ints to text  *
1116 *************************************************/
1117
1118 /* We can't use host_ntoa() because it assumes the binary values are in network
1119 byte order, and these are the result of host_aton(), which puts them in ints in
1120 host byte order. Also, we really want IPv6 addresses to be in a canonical
1121 format, so we output them with no abbreviation. In a number of cases we can't
1122 use the normal colon separator in them because it terminates keys in lsearch
1123 files, so we want to use dot instead. There's an argument that specifies what
1124 to use for IPv6 addresses.
1125
1126 Arguments:
1127   count       1 or 4 (number of ints)
1128   binary      points to the ints
1129   mask        mask value; if < 0 don't add to result
1130   buffer      big enough to hold the result
1131   sep         component separator character for IPv6 addresses
1132
1133 Returns:      the number of characters placed in buffer, not counting
1134               the final nul.
1135 */
1136
1137 int
1138 host_nmtoa(int count, int *binary, int mask, uschar *buffer, int sep)
1139 {
1140 int i, j;
1141 uschar *tt = buffer;
1142
1143 if (count == 1)
1144   {
1145   j = binary[0];
1146   for (i = 24; i >= 0; i -= 8)
1147     tt += sprintf(CS tt, "%d.", (j >> i) & 255);
1148   }
1149 else
1150   for (i = 0; i < 4; i++)
1151     {
1152     j = binary[i];
1153     tt += sprintf(CS tt, "%04x%c%04x%c", (j >> 16) & 0xffff, sep, j & 0xffff, sep);
1154     }
1155
1156 tt--;   /* lose final separator */
1157
1158 if (mask < 0)
1159   *tt = 0;
1160 else
1161   tt += sprintf(CS tt, "/%d", mask);
1162
1163 return tt - buffer;
1164 }
1165
1166
1167 /* Like host_nmtoa() but: ipv6-only, canonical output, no mask
1168
1169 Arguments:
1170   binary      points to the ints
1171   buffer      big enough to hold the result
1172
1173 Returns:      the number of characters placed in buffer, not counting
1174               the final nul.
1175 */
1176
1177 int
1178 ipv6_nmtoa(int * binary, uschar * buffer)
1179 {
1180 int i, j, k;
1181 uschar * c = buffer;
1182 uschar * d = NULL;      /* shut insufficiently "clever" compiler up */
1183
1184 for (i = 0; i < 4; i++)
1185   {                     /* expand to text */
1186   j = binary[i];
1187   c += sprintf(CS c, "%x:%x:", (j >> 16) & 0xffff, j & 0xffff);
1188   }
1189
1190 for (c = buffer, k = -1, i = 0; i < 8; i++)
1191   {                     /* find longest 0-group sequence */
1192   if (*c == '0')        /* must be "0:" */
1193     {
1194     uschar * s = c;
1195     j = i;
1196     while (c[2] == '0') i++, c += 2;
1197     if (i-j > k)
1198       {
1199       k = i-j;          /* length of sequence */
1200       d = s;            /* start of sequence */
1201       }
1202     }
1203   while (*++c != ':') ;
1204   c++;
1205   }
1206
1207 c[-1] = '\0';   /* drop trailing colon */
1208
1209 /* debug_printf("%s: D k %d <%s> <%s>\n", __FUNCTION__, k, d, d + 2*(k+1)); */
1210 if (k >= 0)
1211   {                     /* collapse */
1212   c = d + 2*(k+1);
1213   if (d == buffer) c--; /* need extra colon */
1214   *d++ = ':';   /* 1st 0 */
1215   while ((*d++ = *c++)) ;
1216   }
1217 else
1218   d = c;
1219
1220 return d - buffer;
1221 }
1222
1223
1224
1225 /*************************************************
1226 *        Check port for tls_on_connect           *
1227 *************************************************/
1228
1229 /* This function checks whether a given incoming port is configured for tls-
1230 on-connect. It is called from the daemon and from inetd handling. If the global
1231 option tls_on_connect is already set, all ports operate this way. Otherwise, we
1232 check the tls_on_connect_ports option for a list of ports.
1233
1234 Argument:  a port number
1235 Returns:   TRUE or FALSE
1236 */
1237
1238 BOOL
1239 host_is_tls_on_connect_port(int port)
1240 {
1241 int sep = 0;
1242 uschar buffer[32];
1243 const uschar *list = tls_in.on_connect_ports;
1244 uschar *s;
1245 uschar *end;
1246
1247 if (tls_in.on_connect) return TRUE;
1248
1249 while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
1250   if (Ustrtol(s, &end, 10) == port)
1251     return TRUE;
1252
1253 return FALSE;
1254 }
1255
1256
1257
1258 /*************************************************
1259 *        Check whether host is in a network      *
1260 *************************************************/
1261
1262 /* This function checks whether a given IP address matches a pattern that
1263 represents either a single host, or a network (using CIDR notation). The caller
1264 of this function must check the syntax of the arguments before calling it.
1265
1266 Arguments:
1267   host        string representation of the ip-address to check
1268   net         string representation of the network, with optional CIDR mask
1269   maskoffset  offset to the / that introduces the mask in the key
1270               zero if there is no mask
1271
1272 Returns:
1273   TRUE   the host is inside the network
1274   FALSE  the host is NOT inside the network
1275 */
1276
1277 BOOL
1278 host_is_in_net(const uschar *host, const uschar *net, int maskoffset)
1279 {
1280 int i;
1281 int address[4];
1282 int incoming[4];
1283 int mlen;
1284 int size = host_aton(net, address);
1285 int insize;
1286
1287 /* No mask => all bits to be checked */
1288
1289 if (maskoffset == 0) mlen = 99999;    /* Big number */
1290   else mlen = Uatoi(net + maskoffset + 1);
1291
1292 /* Convert the incoming address to binary. */
1293
1294 insize = host_aton(host, incoming);
1295
1296 /* Convert IPv4 addresses given in IPv6 compatible mode, which represent
1297    connections from IPv4 hosts to IPv6 hosts, that is, addresses of the form
1298    ::ffff:<v4address>, to IPv4 format. */
1299
1300 if (insize == 4 && incoming[0] == 0 && incoming[1] == 0 &&
1301     incoming[2] == 0xffff)
1302   {
1303   insize = 1;
1304   incoming[0] = incoming[3];
1305   }
1306
1307 /* No match if the sizes don't agree. */
1308
1309 if (insize != size) return FALSE;
1310
1311 /* Else do the masked comparison. */
1312
1313 for (i = 0; i < size; i++)
1314   {
1315   int mask;
1316   if (mlen == 0) mask = 0;
1317   else if (mlen < 32)
1318     {
1319     mask = (uint)(-1) << (32 - mlen);
1320     mlen = 0;
1321     }
1322   else
1323     {
1324     mask = -1;
1325     mlen -= 32;
1326     }
1327   if ((incoming[i] & mask) != (address[i] & mask)) return FALSE;
1328   }
1329
1330 return TRUE;
1331 }
1332
1333
1334
1335 /*************************************************
1336 *       Scan host list for local hosts           *
1337 *************************************************/
1338
1339 /* Scan through a chain of addresses and check whether any of them is the
1340 address of an interface on the local machine. If so, remove that address and
1341 any previous ones with the same MX value, and all subsequent ones (which will
1342 have greater or equal MX values) from the chain. Note: marking them as unusable
1343 is NOT the right thing to do because it causes the hosts not to be used for
1344 other domains, for which they may well be correct.
1345
1346 The hosts may be part of a longer chain; we only process those between the
1347 initial pointer and the "last" pointer.
1348
1349 There is also a list of "pseudo-local" host names which are checked against the
1350 host names. Any match causes that host item to be treated the same as one which
1351 matches a local IP address.
1352
1353 If the very first host is a local host, then all MX records had a precedence
1354 greater than or equal to that of the local host. Either there's a problem in
1355 the DNS, or an apparently remote name turned out to be an abbreviation for the
1356 local host. Give a specific return code, and let the caller decide what to do.
1357 Otherwise, give a success code if at least one host address has been found.
1358
1359 Arguments:
1360   host        pointer to the first host in the chain
1361   lastptr     pointer to pointer to the last host in the chain (may be updated)
1362   removed     if not NULL, set TRUE if some local addresses were removed
1363                 from the list
1364
1365 Returns:
1366   HOST_FOUND       if there is at least one host with an IP address on the chain
1367                      and an MX value less than any MX value associated with the
1368                      local host
1369   HOST_FOUND_LOCAL if a local host is among the lowest-numbered MX hosts; when
1370                      the host addresses were obtained from A records or
1371                      gethostbyname(), the MX values are set to -1.
1372   HOST_FIND_FAILED if no valid hosts with set IP addresses were found
1373 */
1374
1375 int
1376 host_scan_for_local_hosts(host_item *host, host_item **lastptr, BOOL *removed)
1377 {
1378 int yield = HOST_FIND_FAILED;
1379 host_item *last = *lastptr;
1380 host_item *prev = NULL;
1381 host_item *h;
1382
1383 if (removed != NULL) *removed = FALSE;
1384
1385 if (local_interface_data == NULL) local_interface_data = host_find_interfaces();
1386
1387 for (h = host; h != last->next; h = h->next)
1388   {
1389   #ifndef STAND_ALONE
1390   if (hosts_treat_as_local != NULL)
1391     {
1392     int rc;
1393     const uschar *save = deliver_domain;
1394     deliver_domain = h->name;   /* set $domain */
1395     rc = match_isinlist(string_copylc(h->name), CUSS &hosts_treat_as_local, 0,
1396       &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL);
1397     deliver_domain = save;
1398     if (rc == OK) goto FOUND_LOCAL;
1399     }
1400   #endif
1401
1402   /* It seems that on many operating systems, 0.0.0.0 is treated as a synonym
1403   for 127.0.0.1 and refers to the local host. We therefore force it always to
1404   be treated as local. */
1405
1406   if (h->address != NULL)
1407     {
1408     ip_address_item *ip;
1409     if (Ustrcmp(h->address, "0.0.0.0") == 0) goto FOUND_LOCAL;
1410     for (ip = local_interface_data; ip != NULL; ip = ip->next)
1411       if (Ustrcmp(h->address, ip->address) == 0) goto FOUND_LOCAL;
1412     yield = HOST_FOUND;  /* At least one remote address has been found */
1413     }
1414
1415   /* Update prev to point to the last host item before any that have
1416   the same MX value as the one we have just considered. */
1417
1418   if (h->next == NULL || h->next->mx != h->mx) prev = h;
1419   }
1420
1421 return yield;  /* No local hosts found: return HOST_FOUND or HOST_FIND_FAILED */
1422
1423 /* A host whose IP address matches a local IP address, or whose name matches
1424 something in hosts_treat_as_local has been found. */
1425
1426 FOUND_LOCAL:
1427
1428 if (prev == NULL)
1429   {
1430   HDEBUG(D_host_lookup) debug_printf((h->mx >= 0)?
1431     "local host has lowest MX\n" :
1432     "local host found for non-MX address\n");
1433   return HOST_FOUND_LOCAL;
1434   }
1435
1436 HDEBUG(D_host_lookup)
1437   {
1438   debug_printf("local host in host list - removed hosts:\n");
1439   for (h = prev->next; h != last->next; h = h->next)
1440     debug_printf("  %s %s %d\n", h->name, h->address, h->mx);
1441   }
1442
1443 if (removed != NULL) *removed = TRUE;
1444 prev->next = last->next;
1445 *lastptr = prev;
1446 return yield;
1447 }
1448
1449
1450
1451
1452 /*************************************************
1453 *        Remove duplicate IPs in host list       *
1454 *************************************************/
1455
1456 /* You would think that administrators could set up their DNS records so that
1457 one ended up with a list of unique IP addresses after looking up A or MX
1458 records, but apparently duplication is common. So we scan such lists and
1459 remove the later duplicates. Note that we may get lists in which some host
1460 addresses are not set.
1461
1462 Arguments:
1463   host        pointer to the first host in the chain
1464   lastptr     pointer to pointer to the last host in the chain (may be updated)
1465
1466 Returns:      nothing
1467 */
1468
1469 static void
1470 host_remove_duplicates(host_item *host, host_item **lastptr)
1471 {
1472 while (host != *lastptr)
1473   {
1474   if (host->address != NULL)
1475     {
1476     host_item *h = host;
1477     while (h != *lastptr)
1478       {
1479       if (h->next->address != NULL &&
1480           Ustrcmp(h->next->address, host->address) == 0)
1481         {
1482         DEBUG(D_host_lookup) debug_printf("duplicate IP address %s (MX=%d) "
1483           "removed\n", host->address, h->next->mx);
1484         if (h->next == *lastptr) *lastptr = h;
1485         h->next = h->next->next;
1486         }
1487       else h = h->next;
1488       }
1489     }
1490   /* If the last item was removed, host may have become == *lastptr */
1491   if (host != *lastptr) host = host->next;
1492   }
1493 }
1494
1495
1496
1497
1498 /*************************************************
1499 *    Find sender host name by gethostbyaddr()    *
1500 *************************************************/
1501
1502 /* This used to be the only way it was done, but it turns out that not all
1503 systems give aliases for calls to gethostbyaddr() - or one of the modern
1504 equivalents like getipnodebyaddr(). Fortunately, multiple PTR records are rare,
1505 but they can still exist. This function is now used only when a DNS lookup of
1506 the IP address fails, in order to give access to /etc/hosts.
1507
1508 Arguments:   none
1509 Returns:     OK, DEFER, FAIL
1510 */
1511
1512 static int
1513 host_name_lookup_byaddr(void)
1514 {
1515 int len;
1516 uschar *s, *t;
1517 struct hostent *hosts;
1518 struct in_addr addr;
1519 unsigned long time_msec = 0;    /* init to quieten dumb static analysis */
1520
1521 if (slow_lookup_log) time_msec = get_time_in_ms();
1522
1523 /* Lookup on IPv6 system */
1524
1525 #if HAVE_IPV6
1526 if (Ustrchr(sender_host_address, ':') != NULL)
1527   {
1528   struct in6_addr addr6;
1529   if (inet_pton(AF_INET6, CS sender_host_address, &addr6) != 1)
1530     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "unable to parse \"%s\" as an "
1531       "IPv6 address", sender_host_address);
1532   #if HAVE_GETIPNODEBYADDR
1533   hosts = getipnodebyaddr(CS &addr6, sizeof(addr6), AF_INET6, &h_errno);
1534   #else
1535   hosts = gethostbyaddr(CS &addr6, sizeof(addr6), AF_INET6);
1536   #endif
1537   }
1538 else
1539   {
1540   if (inet_pton(AF_INET, CS sender_host_address, &addr) != 1)
1541     log_write(0, LOG_MAIN|LOG_PANIC_DIE, "unable to parse \"%s\" as an "
1542       "IPv4 address", sender_host_address);
1543   #if HAVE_GETIPNODEBYADDR
1544   hosts = getipnodebyaddr(CS &addr, sizeof(addr), AF_INET, &h_errno);
1545   #else
1546   hosts = gethostbyaddr(CS &addr, sizeof(addr), AF_INET);
1547   #endif
1548   }
1549
1550 /* Do lookup on IPv4 system */
1551
1552 #else
1553 addr.s_addr = (S_ADDR_TYPE)inet_addr(CS sender_host_address);
1554 hosts = gethostbyaddr(CS(&addr), sizeof(addr), AF_INET);
1555 #endif
1556
1557 if (  slow_lookup_log
1558    && (time_msec = get_time_in_ms() - time_msec) > slow_lookup_log
1559    )
1560   log_long_lookup(US"name", sender_host_address, time_msec);
1561
1562 /* Failed to look up the host. */
1563
1564 if (hosts == NULL)
1565   {
1566   HDEBUG(D_host_lookup) debug_printf("IP address lookup failed: h_errno=%d\n",
1567     h_errno);
1568   return (h_errno == TRY_AGAIN || h_errno == NO_RECOVERY) ? DEFER : FAIL;
1569   }
1570
1571 /* It seems there are some records in the DNS that yield an empty name. We
1572 treat this as non-existent. In some operating systems, this is returned as an
1573 empty string; in others as a single dot. */
1574
1575 if (hosts->h_name == NULL || hosts->h_name[0] == 0 || hosts->h_name[0] == '.')
1576   {
1577   HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an empty name: "
1578     "treated as non-existent host name\n");
1579   return FAIL;
1580   }
1581
1582 /* Copy and lowercase the name, which is in static storage in many systems.
1583 Put it in permanent memory. */
1584
1585 s = US hosts->h_name;
1586 len = Ustrlen(s) + 1;
1587 t = sender_host_name = store_get_perm(len);
1588 while (*s != 0) *t++ = tolower(*s++);
1589 *t = 0;
1590
1591 /* If the host has aliases, build a copy of the alias list */
1592
1593 if (hosts->h_aliases != NULL)
1594   {
1595   int count = 1;
1596   uschar **aliases, **ptr;
1597   for (aliases = USS hosts->h_aliases; *aliases != NULL; aliases++) count++;
1598   ptr = sender_host_aliases = store_get_perm(count * sizeof(uschar *));
1599   for (aliases = USS hosts->h_aliases; *aliases != NULL; aliases++)
1600     {
1601     uschar *s = *aliases;
1602     int len = Ustrlen(s) + 1;
1603     uschar *t = *ptr++ = store_get_perm(len);
1604     while (*s != 0) *t++ = tolower(*s++);
1605     *t = 0;
1606     }
1607   *ptr = NULL;
1608   }
1609
1610 return OK;
1611 }
1612
1613
1614
1615 /*************************************************
1616 *        Find host name for incoming call        *
1617 *************************************************/
1618
1619 /* Put the name in permanent store, pointed to by sender_host_name. We also set
1620 up a list of alias names, pointed to by sender_host_alias. The list is
1621 NULL-terminated. The incoming address is in sender_host_address, either in
1622 dotted-quad form for IPv4 or in colon-separated form for IPv6.
1623
1624 This function does a thorough check that the names it finds point back to the
1625 incoming IP address. Any that do not are discarded. Note that this is relied on
1626 by the ACL reverse_host_lookup check.
1627
1628 On some systems, get{host,ipnode}byaddr() appears to do this internally, but
1629 this it not universally true. Also, for release 4.30, this function was changed
1630 to do a direct DNS lookup first, by default[1], because it turns out that that
1631 is the only guaranteed way to find all the aliases on some systems. My
1632 experiments indicate that Solaris gethostbyaddr() gives the aliases for but
1633 Linux does not.
1634
1635 [1] The actual order is controlled by the host_lookup_order option.
1636
1637 Arguments:    none
1638 Returns:      OK on success, the answer being placed in the global variable
1639                 sender_host_name, with any aliases in a list hung off
1640                 sender_host_aliases
1641               FAIL if no host name can be found
1642               DEFER if a temporary error was encountered
1643
1644 The variable host_lookup_msg is set to an empty string on success, or to a
1645 reason for the failure otherwise, in a form suitable for tagging onto an error
1646 message, and also host_lookup_failed is set TRUE if the lookup failed. If there
1647 was a defer, host_lookup_deferred is set TRUE.
1648
1649 Any dynamically constructed string for host_lookup_msg must be in permanent
1650 store, because it might be used for several incoming messages on the same SMTP
1651 connection. */
1652
1653 int
1654 host_name_lookup(void)
1655 {
1656 int old_pool, rc;
1657 int sep = 0;
1658 uschar *hname, *save_hostname;
1659 uschar **aliases;
1660 uschar buffer[256];
1661 uschar *ordername;
1662 const uschar *list = host_lookup_order;
1663 dns_record *rr;
1664 dns_answer dnsa;
1665 dns_scan dnss;
1666
1667 sender_host_dnssec = host_lookup_deferred = host_lookup_failed = FALSE;
1668
1669 HDEBUG(D_host_lookup)
1670   debug_printf("looking up host name for %s\n", sender_host_address);
1671
1672 /* For testing the case when a lookup does not complete, we have a special
1673 reserved IP address. */
1674
1675 if (f.running_in_test_harness &&
1676     Ustrcmp(sender_host_address, "99.99.99.99") == 0)
1677   {
1678   HDEBUG(D_host_lookup)
1679     debug_printf("Test harness: host name lookup returns DEFER\n");
1680   host_lookup_deferred = TRUE;
1681   return DEFER;
1682   }
1683
1684 /* Do lookups directly in the DNS or via gethostbyaddr() (or equivalent), in
1685 the order specified by the host_lookup_order option. */
1686
1687 while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))))
1688   {
1689   if (strcmpic(ordername, US"bydns") == 0)
1690     {
1691     dns_init(FALSE, FALSE, FALSE);    /* dnssec ctrl by dns_dnssec_ok glbl */
1692     dns_build_reverse(sender_host_address, buffer);
1693     rc = dns_lookup_timerwrap(&dnsa, buffer, T_PTR, NULL);
1694
1695     /* The first record we come across is used for the name; others are
1696     considered to be aliases. We have to scan twice, in order to find out the
1697     number of aliases. However, if all the names are empty, we will behave as
1698     if failure. (PTR records that yield empty names have been encountered in
1699     the DNS.) */
1700
1701     if (rc == DNS_SUCCEED)
1702       {
1703       uschar **aptr = NULL;
1704       int ssize = 264;
1705       int count = 0;
1706       int old_pool = store_pool;
1707
1708       sender_host_dnssec = dns_is_secure(&dnsa);
1709       DEBUG(D_dns)
1710         debug_printf("Reverse DNS security status: %s\n",
1711             sender_host_dnssec ? "DNSSEC verified (AD)" : "unverified");
1712
1713       store_pool = POOL_PERM;        /* Save names in permanent storage */
1714
1715       for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
1716            rr;
1717            rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
1718         if (rr->type == T_PTR)
1719           count++;
1720
1721       /* Get store for the list of aliases. For compatibility with
1722       gethostbyaddr, we make an empty list if there are none. */
1723
1724       aptr = sender_host_aliases = store_get(count * sizeof(uschar *));
1725
1726       /* Re-scan and extract the names */
1727
1728       for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
1729            rr;
1730            rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
1731         {
1732         uschar *s = NULL;
1733         if (rr->type != T_PTR) continue;
1734         s = store_get(ssize);
1735
1736         /* If an overlong response was received, the data will have been
1737         truncated and dn_expand may fail. */
1738
1739         if (dn_expand(dnsa.answer, dnsa.answer + dnsa.answerlen,
1740              US (rr->data), (DN_EXPAND_ARG4_TYPE)(s), ssize) < 0)
1741           {
1742           log_write(0, LOG_MAIN, "host name alias list truncated for %s",
1743             sender_host_address);
1744           break;
1745           }
1746
1747         store_reset(s + Ustrlen(s) + 1);
1748         if (s[0] == 0)
1749           {
1750           HDEBUG(D_host_lookup) debug_printf("IP address lookup yielded an "
1751             "empty name: treated as non-existent host name\n");
1752           continue;
1753           }
1754         if (!sender_host_name) sender_host_name = s;
1755         else *aptr++ = s;
1756         while (*s != 0) { *s = tolower(*s); s++; }
1757         }
1758
1759       *aptr = NULL;            /* End of alias list */
1760       store_pool = old_pool;   /* Reset store pool */
1761
1762       /* If we've found a names, break out of the "order" loop */
1763
1764       if (sender_host_name != NULL) break;
1765       }
1766
1767     /* If the DNS lookup deferred, we must also defer. */
1768
1769     if (rc == DNS_AGAIN)
1770       {
1771       HDEBUG(D_host_lookup)
1772         debug_printf("IP address PTR lookup gave temporary error\n");
1773       host_lookup_deferred = TRUE;
1774       return DEFER;
1775       }
1776     }
1777
1778   /* Do a lookup using gethostbyaddr() - or equivalent */
1779
1780   else if (strcmpic(ordername, US"byaddr") == 0)
1781     {
1782     HDEBUG(D_host_lookup)
1783       debug_printf("IP address lookup using gethostbyaddr()\n");
1784     rc = host_name_lookup_byaddr();
1785     if (rc == DEFER)
1786       {
1787       host_lookup_deferred = TRUE;
1788       return rc;                       /* Can't carry on */
1789       }
1790     if (rc == OK) break;               /* Found a name */
1791     }
1792   }      /* Loop for bydns/byaddr scanning */
1793
1794 /* If we have failed to find a name, return FAIL and log when required.
1795 NB host_lookup_msg must be in permanent store.  */
1796
1797 if (!sender_host_name)
1798   {
1799   if (host_checking || !f.log_testing_mode)
1800     log_write(L_host_lookup_failed, LOG_MAIN, "no host name found for IP "
1801       "address %s", sender_host_address);
1802   host_lookup_msg = US" (failed to find host name from IP address)";
1803   host_lookup_failed = TRUE;
1804   return FAIL;
1805   }
1806
1807 HDEBUG(D_host_lookup)
1808   {
1809   uschar **aliases = sender_host_aliases;
1810   debug_printf("IP address lookup yielded \"%s\"\n", sender_host_name);
1811   while (*aliases != NULL) debug_printf("  alias \"%s\"\n", *aliases++);
1812   }
1813
1814 /* We need to verify that a forward lookup on the name we found does indeed
1815 correspond to the address. This is for security: in principle a malefactor who
1816 happened to own a reverse zone could set it to point to any names at all.
1817
1818 This code was present in versions of Exim before 3.20. At that point I took it
1819 out because I thought that gethostbyaddr() did the check anyway. It turns out
1820 that this isn't always the case, so it's coming back in at 4.01. This version
1821 is actually better, because it also checks aliases.
1822
1823 The code was made more robust at release 4.21. Prior to that, it accepted all
1824 the names if any of them had the correct IP address. Now the code checks all
1825 the names, and accepts only those that have the correct IP address. */
1826
1827 save_hostname = sender_host_name;   /* Save for error messages */
1828 aliases = sender_host_aliases;
1829 for (hname = sender_host_name; hname; hname = *aliases++)
1830   {
1831   int rc;
1832   BOOL ok = FALSE;
1833   host_item h = { .next = NULL, .name = hname, .mx = MX_NONE, .address = NULL };
1834   dnssec_domains d =
1835     { .request = sender_host_dnssec ? US"*" : NULL, .require = NULL };
1836
1837   if (  (rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A | HOST_FIND_BY_AAAA,
1838           NULL, NULL, NULL, &d, NULL, NULL)) == HOST_FOUND
1839      || rc == HOST_FOUND_LOCAL
1840      )
1841     {
1842     host_item *hh;
1843     HDEBUG(D_host_lookup) debug_printf("checking addresses for %s\n", hname);
1844
1845     /* If the forward lookup was not secure we cancel the is-secure variable */
1846
1847     DEBUG(D_dns) debug_printf("Forward DNS security status: %s\n",
1848           h.dnssec == DS_YES ? "DNSSEC verified (AD)" : "unverified");
1849     if (h.dnssec != DS_YES) sender_host_dnssec = FALSE;
1850
1851     for (hh = &h; hh; hh = hh->next)
1852       if (host_is_in_net(hh->address, sender_host_address, 0))
1853         {
1854         HDEBUG(D_host_lookup) debug_printf("  %s OK\n", hh->address);
1855         ok = TRUE;
1856         break;
1857         }
1858       else
1859         HDEBUG(D_host_lookup) debug_printf("  %s\n", hh->address);
1860
1861     if (!ok) HDEBUG(D_host_lookup)
1862       debug_printf("no IP address for %s matched %s\n", hname,
1863         sender_host_address);
1864     }
1865   else if (rc == HOST_FIND_AGAIN)
1866     {
1867     HDEBUG(D_host_lookup) debug_printf("temporary error for host name lookup\n");
1868     host_lookup_deferred = TRUE;
1869     sender_host_name = NULL;
1870     return DEFER;
1871     }
1872   else
1873     HDEBUG(D_host_lookup) debug_printf("no IP addresses found for %s\n", hname);
1874
1875   /* If this name is no good, and it's the sender name, set it null pro tem;
1876   if it's an alias, just remove it from the list. */
1877
1878   if (!ok)
1879     {
1880     if (hname == sender_host_name) sender_host_name = NULL; else
1881       {
1882       uschar **a;                              /* Don't amalgamate - some */
1883       a = --aliases;                           /* compilers grumble */
1884       while (*a != NULL) { *a = a[1]; a++; }
1885       }
1886     }
1887   }
1888
1889 /* If sender_host_name == NULL, it means we didn't like the name. Replace
1890 it with the first alias, if there is one. */
1891
1892 if (sender_host_name == NULL && *sender_host_aliases != NULL)
1893   sender_host_name = *sender_host_aliases++;
1894
1895 /* If we now have a main name, all is well. */
1896
1897 if (sender_host_name != NULL) return OK;
1898
1899 /* We have failed to find an address that matches. */
1900
1901 HDEBUG(D_host_lookup)
1902   debug_printf("%s does not match any IP address for %s\n",
1903     sender_host_address, save_hostname);
1904
1905 /* This message must be in permanent store */
1906
1907 old_pool = store_pool;
1908 store_pool = POOL_PERM;
1909 host_lookup_msg = string_sprintf(" (%s does not match any IP address for %s)",
1910   sender_host_address, save_hostname);
1911 store_pool = old_pool;
1912 host_lookup_failed = TRUE;
1913 return FAIL;
1914 }
1915
1916
1917
1918
1919 /*************************************************
1920 *    Find IP address(es) for host by name        *
1921 *************************************************/
1922
1923 /* The input is a host_item structure with the name filled in and the address
1924 field set to NULL. We use gethostbyname() or getipnodebyname() or
1925 gethostbyname2(), as appropriate. Of course, these functions may use the DNS,
1926 but they do not do MX processing. It appears, however, that in some systems the
1927 current setting of resolver options is used when one of these functions calls
1928 the resolver. For this reason, we call dns_init() at the start, with arguments
1929 influenced by bits in "flags", just as we do for host_find_bydns().
1930
1931 The second argument provides a host list (usually an IP list) of hosts to
1932 ignore. This makes it possible to ignore IPv6 link-local addresses or loopback
1933 addresses in unreasonable places.
1934
1935 The lookup may result in a change of name. For compatibility with the dns
1936 lookup, return this via fully_qualified_name as well as updating the host item.
1937 The lookup may also yield more than one IP address, in which case chain on
1938 subsequent host_item structures.
1939
1940 Arguments:
1941   host                   a host item with the name and MX filled in;
1942                            the address is to be filled in;
1943                            multiple IP addresses cause other host items to be
1944                              chained on.
1945   ignore_target_hosts    a list of hosts to ignore
1946   flags                  HOST_FIND_QUALIFY_SINGLE   ) passed to
1947                          HOST_FIND_SEARCH_PARENTS   )   dns_init()
1948   fully_qualified_name   if not NULL, set to point to host name for
1949                          compatibility with host_find_bydns
1950   local_host_check       TRUE if a check for the local host is wanted
1951
1952 Returns:                 HOST_FIND_FAILED  Failed to find the host or domain
1953                          HOST_FIND_AGAIN   Try again later
1954                          HOST_FOUND        Host found - data filled in
1955                          HOST_FOUND_LOCAL  Host found and is the local host
1956 */
1957
1958 int
1959 host_find_byname(host_item *host, const uschar *ignore_target_hosts, int flags,
1960   const uschar **fully_qualified_name, BOOL local_host_check)
1961 {
1962 int i, yield, times;
1963 uschar **addrlist;
1964 host_item *last = NULL;
1965 BOOL temp_error = FALSE;
1966 #if HAVE_IPV6
1967 int af;
1968 #endif
1969
1970 /* Make sure DNS options are set as required. This appears to be necessary in
1971 some circumstances when the get..byname() function actually calls the DNS. */
1972
1973 dns_init((flags & HOST_FIND_QUALIFY_SINGLE) != 0,
1974          (flags & HOST_FIND_SEARCH_PARENTS) != 0,
1975          FALSE);                /* Cannot retrieve dnssec status so do not request */
1976
1977 /* In an IPv6 world, unless IPv6 has been disabled, we need to scan for both
1978 kinds of address, so go round the loop twice. Note that we have ensured that
1979 AF_INET6 is defined even in an IPv4 world, which makes for slightly tidier
1980 code. However, if dns_ipv4_lookup matches the domain, we also just do IPv4
1981 lookups here (except when testing standalone). */
1982
1983 #if HAVE_IPV6
1984   #ifdef STAND_ALONE
1985   if (disable_ipv6)
1986   #else
1987   if (disable_ipv6 ||
1988     (dns_ipv4_lookup != NULL &&
1989         match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
1990           MCL_DOMAIN, TRUE, NULL) == OK))
1991   #endif
1992
1993     { af = AF_INET; times = 1; }
1994   else
1995     { af = AF_INET6; times = 2; }
1996
1997 /* No IPv6 support */
1998
1999 #else   /* HAVE_IPV6 */
2000   times = 1;
2001 #endif  /* HAVE_IPV6 */
2002
2003 /* Initialize the flag that gets set for DNS syntax check errors, so that the
2004 interface to this function can be similar to host_find_bydns. */
2005
2006 f.host_find_failed_syntax = FALSE;
2007
2008 /* Loop to look up both kinds of address in an IPv6 world */
2009
2010 for (i = 1; i <= times;
2011      #if HAVE_IPV6
2012        af = AF_INET,     /* If 2 passes, IPv4 on the second */
2013      #endif
2014      i++)
2015   {
2016   BOOL ipv4_addr;
2017   int error_num = 0;
2018   struct hostent *hostdata;
2019   unsigned long time_msec = 0;  /* compiler quietening */
2020
2021   #ifdef STAND_ALONE
2022   printf("Looking up: %s\n", host->name);
2023   #endif
2024
2025   if (slow_lookup_log) time_msec = get_time_in_ms();
2026
2027   #if HAVE_IPV6
2028   if (f.running_in_test_harness)
2029     hostdata = host_fake_gethostbyname(host->name, af, &error_num);
2030   else
2031     {
2032     #if HAVE_GETIPNODEBYNAME
2033     hostdata = getipnodebyname(CS host->name, af, 0, &error_num);
2034     #else
2035     hostdata = gethostbyname2(CS host->name, af);
2036     error_num = h_errno;
2037     #endif
2038     }
2039
2040   #else    /* not HAVE_IPV6 */
2041   if (f.running_in_test_harness)
2042     hostdata = host_fake_gethostbyname(host->name, AF_INET, &error_num);
2043   else
2044     {
2045     hostdata = gethostbyname(CS host->name);
2046     error_num = h_errno;
2047     }
2048   #endif   /* HAVE_IPV6 */
2049
2050   if (   slow_lookup_log
2051       && (time_msec = get_time_in_ms() - time_msec) > slow_lookup_log)
2052     log_long_lookup(US"name", host->name, time_msec);
2053
2054   if (hostdata == NULL)
2055     {
2056     uschar *error;
2057     switch (error_num)
2058       {
2059       case HOST_NOT_FOUND: error = US"HOST_NOT_FOUND"; break;
2060       case TRY_AGAIN:      error = US"TRY_AGAIN"; break;
2061       case NO_RECOVERY:    error = US"NO_RECOVERY"; break;
2062       case NO_DATA:        error = US"NO_DATA"; break;
2063       #if NO_DATA != NO_ADDRESS
2064       case NO_ADDRESS:     error = US"NO_ADDRESS"; break;
2065       #endif
2066       default: error = US"?"; break;
2067       }
2068
2069     DEBUG(D_host_lookup) debug_printf("%s returned %d (%s)\n",
2070       #if HAVE_IPV6
2071         #if HAVE_GETIPNODEBYNAME
2072         (af == AF_INET6)? "getipnodebyname(af=inet6)" : "getipnodebyname(af=inet)",
2073         #else
2074         (af == AF_INET6)? "gethostbyname2(af=inet6)" : "gethostbyname2(af=inet)",
2075         #endif
2076       #else
2077       "gethostbyname",
2078       #endif
2079       error_num, error);
2080
2081     if (error_num == TRY_AGAIN || error_num == NO_RECOVERY) temp_error = TRUE;
2082     continue;
2083     }
2084   if ((hostdata->h_addr_list)[0] == NULL) continue;
2085
2086   /* Replace the name with the fully qualified one if necessary, and fill in
2087   the fully_qualified_name pointer. */
2088
2089   if (hostdata->h_name[0] != 0 &&
2090       Ustrcmp(host->name, hostdata->h_name) != 0)
2091     host->name = string_copy_dnsdomain(US hostdata->h_name);
2092   if (fully_qualified_name != NULL) *fully_qualified_name = host->name;
2093
2094   /* Get the list of addresses. IPv4 and IPv6 addresses can be distinguished
2095   by their different lengths. Scan the list, ignoring any that are to be
2096   ignored, and build a chain from the rest. */
2097
2098   ipv4_addr = hostdata->h_length == sizeof(struct in_addr);
2099
2100   for (addrlist = USS hostdata->h_addr_list; *addrlist != NULL; addrlist++)
2101     {
2102     uschar *text_address =
2103       host_ntoa(ipv4_addr? AF_INET:AF_INET6, *addrlist, NULL, NULL);
2104
2105     #ifndef STAND_ALONE
2106     if (ignore_target_hosts != NULL &&
2107         verify_check_this_host(&ignore_target_hosts, NULL, host->name,
2108           text_address, NULL) == OK)
2109       {
2110       DEBUG(D_host_lookup)
2111         debug_printf("ignored host %s [%s]\n", host->name, text_address);
2112       continue;
2113       }
2114     #endif
2115
2116     /* If this is the first address, last == NULL and we put the data in the
2117     original block. */
2118
2119     if (last == NULL)
2120       {
2121       host->address = text_address;
2122       host->port = PORT_NONE;
2123       host->status = hstatus_unknown;
2124       host->why = hwhy_unknown;
2125       host->dnssec = DS_UNK;
2126       last = host;
2127       }
2128
2129     /* Else add further host item blocks for any other addresses, keeping
2130     the order. */
2131
2132     else
2133       {
2134       host_item *next = store_get(sizeof(host_item));
2135       next->name = host->name;
2136       next->mx = host->mx;
2137       next->address = text_address;
2138       next->port = PORT_NONE;
2139       next->status = hstatus_unknown;
2140       next->why = hwhy_unknown;
2141       next->dnssec = DS_UNK;
2142       next->last_try = 0;
2143       next->next = last->next;
2144       last->next = next;
2145       last = next;
2146       }
2147     }
2148   }
2149
2150 /* If no hosts were found, the address field in the original host block will be
2151 NULL. If temp_error is set, at least one of the lookups gave a temporary error,
2152 so we pass that back. */
2153
2154 if (host->address == NULL)
2155   {
2156   uschar *msg =
2157     #ifndef STAND_ALONE
2158     (message_id[0] == 0 && smtp_in != NULL)?
2159       string_sprintf("no IP address found for host %s (during %s)", host->name,
2160           smtp_get_connection_info()) :
2161     #endif
2162     string_sprintf("no IP address found for host %s", host->name);
2163
2164   HDEBUG(D_host_lookup) debug_printf("%s\n", msg);
2165   if (temp_error) goto RETURN_AGAIN;
2166   if (host_checking || !f.log_testing_mode)
2167     log_write(L_host_lookup_failed, LOG_MAIN, "%s", msg);
2168   return HOST_FIND_FAILED;
2169   }
2170
2171 /* Remove any duplicate IP addresses, then check to see if this is the local
2172 host if required. */
2173
2174 host_remove_duplicates(host, &last);
2175 yield = local_host_check?
2176   host_scan_for_local_hosts(host, &last, NULL) : HOST_FOUND;
2177
2178 HDEBUG(D_host_lookup)
2179   {
2180   const host_item *h;
2181   if (fully_qualified_name != NULL)
2182     debug_printf("fully qualified name = %s\n", *fully_qualified_name);
2183   debug_printf("%s looked up these IP addresses:\n",
2184     #if HAVE_IPV6
2185       #if HAVE_GETIPNODEBYNAME
2186       "getipnodebyname"
2187       #else
2188       "gethostbyname2"
2189       #endif
2190     #else
2191     "gethostbyname"
2192     #endif
2193     );
2194   for (h = host; h != last->next; h = h->next)
2195     debug_printf("  name=%s address=%s\n", h->name,
2196       (h->address == NULL)? US"<null>" : h->address);
2197   }
2198
2199 /* Return the found status. */
2200
2201 return yield;
2202
2203 /* Handle the case when there is a temporary error. If the name matches
2204 dns_again_means_nonexist, return permanent rather than temporary failure. */
2205
2206 RETURN_AGAIN:
2207   {
2208   #ifndef STAND_ALONE
2209   int rc;
2210   const uschar *save = deliver_domain;
2211   deliver_domain = host->name;  /* set $domain */
2212   rc = match_isinlist(host->name, CUSS &dns_again_means_nonexist, 0, NULL, NULL,
2213     MCL_DOMAIN, TRUE, NULL);
2214   deliver_domain = save;
2215   if (rc == OK)
2216     {
2217     DEBUG(D_host_lookup) debug_printf("%s is in dns_again_means_nonexist: "
2218       "returning HOST_FIND_FAILED\n", host->name);
2219     return HOST_FIND_FAILED;
2220     }
2221   #endif
2222   return HOST_FIND_AGAIN;
2223   }
2224 }
2225
2226
2227
2228 /*************************************************
2229 *        Fill in a host address from the DNS     *
2230 *************************************************/
2231
2232 /* Given a host item, with its name, port and mx fields set, and its address
2233 field set to NULL, fill in its IP address from the DNS. If it is multi-homed,
2234 create additional host items for the additional addresses, copying all the
2235 other fields, and randomizing the order.
2236
2237 On IPv6 systems, AAAA records are sought first, then A records.
2238
2239 The host name may be changed if the DNS returns a different name - e.g. fully
2240 qualified or changed via CNAME. If fully_qualified_name is not NULL, dns_lookup
2241 ensures that it points to the fully qualified name. However, this is the fully
2242 qualified version of the original name; if a CNAME is involved, the actual
2243 canonical host name may be different again, and so we get it directly from the
2244 relevant RR. Note that we do NOT change the mx field of the host item in this
2245 function as it may be called to set the addresses of hosts taken from MX
2246 records.
2247
2248 Arguments:
2249   host                  points to the host item we're filling in
2250   lastptr               points to pointer to last host item in a chain of
2251                           host items (may be updated if host is last and gets
2252                           extended because multihomed)
2253   ignore_target_hosts   list of hosts to ignore
2254   allow_ip              if TRUE, recognize an IP address and return it
2255   fully_qualified_name  if not NULL, return fully qualified name here if
2256                           the contents are different (i.e. it must be preset
2257                           to something)
2258   dnssec_request        if TRUE request the AD bit
2259   dnssec_require        if TRUE require the AD bit
2260   whichrrs              select ipv4, ipv6 results
2261
2262 Returns:       HOST_FIND_FAILED     couldn't find A record
2263                HOST_FIND_AGAIN      try again later
2264                HOST_FIND_SECURITY   dnssec required but not acheived
2265                HOST_FOUND           found AAAA and/or A record(s)
2266                HOST_IGNORED         found, but all IPs ignored
2267 */
2268
2269 static int
2270 set_address_from_dns(host_item *host, host_item **lastptr,
2271   const uschar *ignore_target_hosts, BOOL allow_ip,
2272   const uschar **fully_qualified_name,
2273   BOOL dnssec_request, BOOL dnssec_require, int whichrrs)
2274 {
2275 dns_record *rr;
2276 host_item *thishostlast = NULL;    /* Indicates not yet filled in anything */
2277 BOOL v6_find_again = FALSE;
2278 BOOL dnssec_fail = FALSE;
2279 int i;
2280
2281 /* If allow_ip is set, a name which is an IP address returns that value
2282 as its address. This is used for MX records when allow_mx_to_ip is set, for
2283 those sites that feel they have to flaunt the RFC rules. */
2284
2285 if (allow_ip && string_is_ip_address(host->name, NULL) != 0)
2286   {
2287   #ifndef STAND_ALONE
2288   if (  ignore_target_hosts
2289      && verify_check_this_host(&ignore_target_hosts, NULL, host->name,
2290         host->name, NULL) == OK)
2291     return HOST_IGNORED;
2292   #endif
2293
2294   host->address = host->name;
2295   return HOST_FOUND;
2296   }
2297
2298 /* On an IPv6 system, unless IPv6 is disabled, go round the loop up to twice,
2299 looking for AAAA records the first time. However, unless doing standalone
2300 testing, we force an IPv4 lookup if the domain matches dns_ipv4_lookup global.
2301 On an IPv4 system, go round the loop once only, looking only for A records. */
2302
2303 #if HAVE_IPV6
2304   #ifndef STAND_ALONE
2305     if (  disable_ipv6
2306        || !(whichrrs & HOST_FIND_BY_AAAA)
2307        || (dns_ipv4_lookup
2308           && match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL,
2309               MCL_DOMAIN, TRUE, NULL) == OK)
2310        )
2311       i = 0;    /* look up A records only */
2312     else
2313   #endif        /* STAND_ALONE */
2314
2315   i = 1;        /* look up AAAA and A records */
2316
2317 /* The IPv4 world */
2318
2319 #else           /* HAVE_IPV6 */
2320   i = 0;        /* look up A records only */
2321 #endif          /* HAVE_IPV6 */
2322
2323 for (; i >= 0; i--)
2324   {
2325   static int types[] = { T_A, T_AAAA };
2326   int type = types[i];
2327   int randoffset = i == (whichrrs & HOST_FIND_IPV4_FIRST ? 1 : 0)
2328     ? 500 : 0;  /* Ensures v6/4 sort order */
2329   dns_answer dnsa;
2330   dns_scan dnss;
2331
2332   int rc = dns_lookup_timerwrap(&dnsa, host->name, type, fully_qualified_name);
2333   lookup_dnssec_authenticated = !dnssec_request ? NULL
2334     : dns_is_secure(&dnsa) ? US"yes" : US"no";
2335
2336   DEBUG(D_dns)
2337     if (  (dnssec_request || dnssec_require)
2338        && !dns_is_secure(&dnsa)
2339        && dns_is_aa(&dnsa)
2340        )
2341       debug_printf("DNS lookup of %.256s (A/AAAA) requested AD, but got AA\n", host->name);
2342
2343   /* We want to return HOST_FIND_AGAIN if one of the A or AAAA lookups
2344   fails or times out, but not if another one succeeds. (In the early
2345   IPv6 days there are name servers that always fail on AAAA, but are happy
2346   to give out an A record. We want to proceed with that A record.) */
2347
2348   if (rc != DNS_SUCCEED)
2349     {
2350     if (i == 0)  /* Just tried for an A record, i.e. end of loop */
2351       {
2352       if (host->address != NULL) return HOST_FOUND;  /* AAAA was found */
2353       if (rc == DNS_AGAIN || rc == DNS_FAIL || v6_find_again)
2354         return HOST_FIND_AGAIN;
2355       return HOST_FIND_FAILED;    /* DNS_NOMATCH or DNS_NODATA */
2356       }
2357
2358     /* Tried for an AAAA record: remember if this was a temporary
2359     error, and look for the next record type. */
2360
2361     if (rc != DNS_NOMATCH && rc != DNS_NODATA) v6_find_again = TRUE;
2362     continue;
2363     }
2364
2365   if (dnssec_request)
2366     {
2367     if (dns_is_secure(&dnsa))
2368       {
2369       DEBUG(D_host_lookup) debug_printf("%s A DNSSEC\n", host->name);
2370       if (host->dnssec == DS_UNK) /* set in host_find_bydns() */
2371         host->dnssec = DS_YES;
2372       }
2373     else
2374       {
2375       if (dnssec_require)
2376         {
2377         dnssec_fail = TRUE;
2378         DEBUG(D_host_lookup) debug_printf("dnssec fail on %s for %.256s",
2379                 i>0 ? "AAAA" : "A", host->name);
2380         continue;
2381         }
2382       if (host->dnssec == DS_YES) /* set in host_find_bydns() */
2383         {
2384         DEBUG(D_host_lookup) debug_printf("%s A cancel DNSSEC\n", host->name);
2385         host->dnssec = DS_NO;
2386         lookup_dnssec_authenticated = US"no";
2387         }
2388       }
2389     }
2390
2391   /* Lookup succeeded: fill in the given host item with the first non-ignored
2392   address found; create additional items for any others. A single A6 record
2393   may generate more than one address.  The lookup had a chance to update the
2394   fqdn; we do not want any later times round the loop to do so. */
2395
2396   fully_qualified_name = NULL;
2397
2398   for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
2399        rr;
2400        rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT))
2401     {
2402     if (rr->type == type)
2403       {
2404       dns_address *da = dns_address_from_rr(&dnsa, rr);
2405
2406       DEBUG(D_host_lookup)
2407         if (!da) debug_printf("no addresses extracted from A6 RR for %s\n",
2408             host->name);
2409
2410       /* This loop runs only once for A and AAAA records, but may run
2411       several times for an A6 record that generated multiple addresses. */
2412
2413       for (; da; da = da->next)
2414         {
2415         #ifndef STAND_ALONE
2416         if (ignore_target_hosts != NULL &&
2417               verify_check_this_host(&ignore_target_hosts, NULL,
2418                 host->name, da->address, NULL) == OK)
2419           {
2420           DEBUG(D_host_lookup)
2421             debug_printf("ignored host %s [%s]\n", host->name, da->address);
2422           continue;
2423           }
2424         #endif
2425
2426         /* If this is the first address, stick it in the given host block,
2427         and change the name if the returned RR has a different name. */
2428
2429         if (thishostlast == NULL)
2430           {
2431           if (strcmpic(host->name, rr->name) != 0)
2432             host->name = string_copy_dnsdomain(rr->name);
2433           host->address = da->address;
2434           host->sort_key = host->mx * 1000 + random_number(500) + randoffset;
2435           host->status = hstatus_unknown;
2436           host->why = hwhy_unknown;
2437           thishostlast = host;
2438           }
2439
2440         /* Not the first address. Check for, and ignore, duplicates. Then
2441         insert in the chain at a random point. */
2442
2443         else
2444           {
2445           int new_sort_key;
2446           host_item *next;
2447
2448           /* End of our local chain is specified by "thishostlast". */
2449
2450           for (next = host;; next = next->next)
2451             {
2452             if (Ustrcmp(CS da->address, next->address) == 0) break;
2453             if (next == thishostlast) { next = NULL; break; }
2454             }
2455           if (next != NULL) continue;  /* With loop for next address */
2456
2457           /* Not a duplicate */
2458
2459           new_sort_key = host->mx * 1000 + random_number(500) + randoffset;
2460           next = store_get(sizeof(host_item));
2461
2462           /* New address goes first: insert the new block after the first one
2463           (so as not to disturb the original pointer) but put the new address
2464           in the original block. */
2465
2466           if (new_sort_key < host->sort_key)
2467             {
2468             *next = *host;                                  /* Copies port */
2469             host->next = next;
2470             host->address = da->address;
2471             host->sort_key = new_sort_key;
2472             if (thishostlast == host) thishostlast = next;  /* Local last */
2473             if (*lastptr == host) *lastptr = next;          /* Global last */
2474             }
2475
2476           /* Otherwise scan down the addresses for this host to find the
2477           one to insert after. */
2478
2479           else
2480             {
2481             host_item *h = host;
2482             while (h != thishostlast)
2483               {
2484               if (new_sort_key < h->next->sort_key) break;
2485               h = h->next;
2486               }
2487             *next = *h;                                 /* Copies port */
2488             h->next = next;
2489             next->address = da->address;
2490             next->sort_key = new_sort_key;
2491             if (h == thishostlast) thishostlast = next; /* Local last */
2492             if (h == *lastptr) *lastptr = next;         /* Global last */
2493             }
2494           }
2495         }
2496       }
2497     }
2498   }
2499
2500 /* Control gets here only if the second lookup (the A record) succeeded.
2501 However, the address may not be filled in if it was ignored. */
2502
2503 return host->address
2504   ? HOST_FOUND
2505   : dnssec_fail
2506   ? HOST_FIND_SECURITY
2507   : HOST_IGNORED;
2508 }
2509
2510
2511
2512
2513 /*************************************************
2514 *    Find IP addresses and host names via DNS    *
2515 *************************************************/
2516
2517 /* The input is a host_item structure with the name field filled in and the
2518 address field set to NULL. This may be in a chain of other host items. The
2519 lookup may result in more than one IP address, in which case we must created
2520 new host blocks for the additional addresses, and insert them into the chain.
2521 The original name may not be fully qualified. Use the fully_qualified_name
2522 argument to return the official name, as returned by the resolver.
2523
2524 Arguments:
2525   host                  point to initial host item
2526   ignore_target_hosts   a list of hosts to ignore
2527   whichrrs              flags indicating which RRs to look for:
2528                           HOST_FIND_BY_SRV  => look for SRV
2529                           HOST_FIND_BY_MX   => look for MX
2530                           HOST_FIND_BY_A    => look for A
2531                           HOST_FIND_BY_AAAA => look for AAAA
2532                         also flags indicating how the lookup is done
2533                           HOST_FIND_QUALIFY_SINGLE   ) passed to the
2534                           HOST_FIND_SEARCH_PARENTS   )   resolver
2535                           HOST_FIND_IPV4_FIRST => reverse usual result ordering
2536                           HOST_FIND_IPV4_ONLY  => MX results elide ipv6
2537   srv_service           when SRV used, the service name
2538   srv_fail_domains      DNS errors for these domains => assume nonexist
2539   mx_fail_domains       DNS errors for these domains => assume nonexist
2540   dnssec_d.request =>   make dnssec request: domainlist
2541   dnssec_d.require =>   ditto and nonexist failures
2542   fully_qualified_name  if not NULL, return fully-qualified name
2543   removed               set TRUE if local host was removed from the list
2544
2545 Returns:                HOST_FIND_FAILED  Failed to find the host or domain;
2546                                           if there was a syntax error,
2547                                           host_find_failed_syntax is set.
2548                         HOST_FIND_AGAIN   Could not resolve at this time
2549                         HOST_FIND_SECURITY dnsssec required but not acheived
2550                         HOST_FOUND        Host found
2551                         HOST_FOUND_LOCAL  The lowest MX record points to this
2552                                           machine, if MX records were found, or
2553                                           an A record that was found contains
2554                                           an address of the local host
2555 */
2556
2557 int
2558 host_find_bydns(host_item *host, const uschar *ignore_target_hosts, int whichrrs,
2559   uschar *srv_service, uschar *srv_fail_domains, uschar *mx_fail_domains,
2560   const dnssec_domains *dnssec_d,
2561   const uschar **fully_qualified_name, BOOL *removed)
2562 {
2563 host_item *h, *last;
2564 dns_record *rr;
2565 int rc = DNS_FAIL;
2566 int ind_type = 0;
2567 int yield;
2568 dns_answer dnsa;
2569 dns_scan dnss;
2570 BOOL dnssec_require = dnssec_d
2571                     && match_isinlist(host->name, CUSS &dnssec_d->require,
2572                                     0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK;
2573 BOOL dnssec_request = dnssec_require
2574                     || (  dnssec_d
2575                        && match_isinlist(host->name, CUSS &dnssec_d->request,
2576                                     0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) == OK);
2577 dnssec_status_t dnssec;
2578
2579 /* Set the default fully qualified name to the incoming name, initialize the
2580 resolver if necessary, set up the relevant options, and initialize the flag
2581 that gets set for DNS syntax check errors. */
2582
2583 if (fully_qualified_name != NULL) *fully_qualified_name = host->name;
2584 dns_init((whichrrs & HOST_FIND_QUALIFY_SINGLE) != 0,
2585          (whichrrs & HOST_FIND_SEARCH_PARENTS) != 0,
2586          dnssec_request);
2587 f.host_find_failed_syntax = FALSE;
2588
2589 /* First, if requested, look for SRV records. The service name is given; we
2590 assume TCP protocol. DNS domain names are constrained to a maximum of 256
2591 characters, so the code below should be safe. */
2592
2593 if (whichrrs & HOST_FIND_BY_SRV)
2594   {
2595   gstring * g;
2596   uschar * temp_fully_qualified_name;
2597   int prefix_length;
2598
2599   g = string_fmt_append(NULL, "_%s._tcp.%n%.256s",
2600         srv_service, &prefix_length, host->name);
2601   temp_fully_qualified_name = string_from_gstring(g);
2602   ind_type = T_SRV;
2603
2604   /* Search for SRV records. If the fully qualified name is different to
2605   the input name, pass back the new original domain, without the prepended
2606   magic. */
2607
2608   dnssec = DS_UNK;
2609   lookup_dnssec_authenticated = NULL;
2610   rc = dns_lookup_timerwrap(&dnsa, temp_fully_qualified_name, ind_type,
2611         CUSS &temp_fully_qualified_name);
2612
2613   DEBUG(D_dns)
2614     if ((dnssec_request || dnssec_require)
2615         && !dns_is_secure(&dnsa)
2616         && dns_is_aa(&dnsa))
2617       debug_printf("DNS lookup of %.256s (SRV) requested AD, but got AA\n", host->name);
2618
2619   if (dnssec_request)
2620     {
2621     if (dns_is_secure(&dnsa))
2622       { dnssec = DS_YES; lookup_dnssec_authenticated = US"yes"; }
2623     else
2624       { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; }
2625     }
2626
2627   if (temp_fully_qualified_name != g->s && fully_qualified_name != NULL)
2628     *fully_qualified_name = temp_fully_qualified_name + prefix_length;
2629
2630   /* On DNS failures, we give the "try again" error unless the domain is
2631   listed as one for which we continue. */
2632
2633   if (rc == DNS_SUCCEED && dnssec_require && !dns_is_secure(&dnsa))
2634     {
2635     log_write(L_host_lookup_failed, LOG_MAIN,
2636                 "dnssec fail on SRV for %.256s", host->name);
2637     rc = DNS_FAIL;
2638     }
2639   if (rc == DNS_FAIL || rc == DNS_AGAIN)
2640     {
2641     #ifndef STAND_ALONE
2642     if (match_isinlist(host->name, CUSS &srv_fail_domains, 0, NULL, NULL,
2643         MCL_DOMAIN, TRUE, NULL) != OK)
2644     #endif
2645       { yield = HOST_FIND_AGAIN; goto out; }
2646     DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA "
2647       "(domain in srv_fail_domains)\n", (rc == DNS_FAIL)? "FAIL":"AGAIN");
2648     }
2649   }
2650
2651 /* If we did not find any SRV records, search the DNS for MX records, if
2652 requested to do so. If the result is DNS_NOMATCH, it means there is no such
2653 domain, and there's no point in going on to look for address records with the
2654 same domain. The result will be DNS_NODATA if the domain exists but has no MX
2655 records. On DNS failures, we give the "try again" error unless the domain is
2656 listed as one for which we continue. */
2657
2658 if (rc != DNS_SUCCEED  &&  whichrrs & HOST_FIND_BY_MX)
2659   {
2660   ind_type = T_MX;
2661   dnssec = DS_UNK;
2662   lookup_dnssec_authenticated = NULL;
2663   rc = dns_lookup_timerwrap(&dnsa, host->name, ind_type, fully_qualified_name);
2664
2665   DEBUG(D_dns)
2666     if (  (dnssec_request || dnssec_require)
2667        && !dns_is_secure(&dnsa)
2668        && dns_is_aa(&dnsa))
2669       debug_printf("DNS lookup of %.256s (MX) requested AD, but got AA\n", host->name);
2670
2671   if (dnssec_request)
2672     if (dns_is_secure(&dnsa))
2673       {
2674       DEBUG(D_host_lookup) debug_printf("%s MX DNSSEC\n", host->name);
2675       dnssec = DS_YES; lookup_dnssec_authenticated = US"yes";
2676       }
2677     else
2678       {
2679       dnssec = DS_NO; lookup_dnssec_authenticated = US"no";
2680       }
2681
2682   switch (rc)
2683     {
2684     case DNS_NOMATCH:
2685       yield = HOST_FIND_FAILED; goto out;
2686
2687     case DNS_SUCCEED:
2688       if (!dnssec_require || dns_is_secure(&dnsa))
2689         break;
2690       DEBUG(D_host_lookup)
2691         debug_printf("dnssec fail on MX for %.256s", host->name);
2692 #ifndef STAND_ALONE
2693       if (match_isinlist(host->name, CUSS &mx_fail_domains, 0, NULL, NULL,
2694           MCL_DOMAIN, TRUE, NULL) != OK)
2695         { yield = HOST_FIND_SECURITY; goto out; }
2696 #endif
2697       rc = DNS_FAIL;
2698       /*FALLTHROUGH*/
2699
2700     case DNS_FAIL:
2701     case DNS_AGAIN:
2702 #ifndef STAND_ALONE
2703       if (match_isinlist(host->name, CUSS &mx_fail_domains, 0, NULL, NULL,
2704           MCL_DOMAIN, TRUE, NULL) != OK)
2705 #endif
2706         { yield = HOST_FIND_AGAIN; goto out; }
2707       DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA "
2708         "(domain in mx_fail_domains)\n", (rc == DNS_FAIL)? "FAIL":"AGAIN");
2709       break;
2710     }
2711   }
2712
2713 /* If we haven't found anything yet, and we are requested to do so, try for an
2714 A or AAAA record. If we find it (or them) check to see that it isn't the local
2715 host. */
2716
2717 if (rc != DNS_SUCCEED)
2718   {
2719   if (!(whichrrs & (HOST_FIND_BY_A | HOST_FIND_BY_AAAA)))
2720     {
2721     DEBUG(D_host_lookup) debug_printf("Address records are not being sought\n");
2722     yield = HOST_FIND_FAILED;
2723     goto out;
2724     }
2725
2726   last = host;        /* End of local chainlet */
2727   host->mx = MX_NONE;
2728   host->port = PORT_NONE;
2729   host->dnssec = DS_UNK;
2730   lookup_dnssec_authenticated = NULL;
2731   rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE,
2732     fully_qualified_name, dnssec_request, dnssec_require, whichrrs);
2733
2734   /* If one or more address records have been found, check that none of them
2735   are local. Since we know the host items all have their IP addresses
2736   inserted, host_scan_for_local_hosts() can only return HOST_FOUND or
2737   HOST_FOUND_LOCAL. We do not need to scan for duplicate IP addresses here,
2738   because set_address_from_dns() removes them. */
2739
2740   if (rc == HOST_FOUND)
2741     rc = host_scan_for_local_hosts(host, &last, removed);
2742   else
2743     if (rc == HOST_IGNORED) rc = HOST_FIND_FAILED;  /* No special action */
2744
2745   DEBUG(D_host_lookup)
2746     {
2747     host_item *h;
2748     if (host->address != NULL)
2749       {
2750       if (fully_qualified_name != NULL)
2751         debug_printf("fully qualified name = %s\n", *fully_qualified_name);
2752       for (h = host; h != last->next; h = h->next)
2753         debug_printf("%s %s mx=%d sort=%d %s\n", h->name,
2754           (h->address == NULL)? US"<null>" : h->address, h->mx, h->sort_key,
2755           (h->status >= hstatus_unusable)? US"*" : US"");
2756       }
2757     }
2758
2759   yield = rc;
2760   goto out;
2761   }
2762
2763 /* We have found one or more MX or SRV records. Sort them according to
2764 precedence. Put the data for the first one into the existing host block, and
2765 insert new host_item blocks into the chain for the remainder. For equal
2766 precedences one is supposed to randomize the order. To make this happen, the
2767 sorting is actually done on the MX value * 1000 + a random number. This is put
2768 into a host field called sort_key.
2769
2770 In the case of hosts with both IPv6 and IPv4 addresses, we want to choose the
2771 IPv6 address in preference. At this stage, we don't know what kind of address
2772 the host has. We choose a random number < 500; if later we find an A record
2773 first, we add 500 to the random number. Then for any other address records, we
2774 use random numbers in the range 0-499 for AAAA records and 500-999 for A
2775 records.
2776
2777 At this point we remove any duplicates that point to the same host, retaining
2778 only the one with the lowest precedence. We cannot yet check for precedence
2779 greater than that of the local host, because that test cannot be properly done
2780 until the addresses have been found - an MX record may point to a name for this
2781 host which is not the primary hostname. */
2782
2783 last = NULL;    /* Indicates that not even the first item is filled yet */
2784
2785 for (rr = dns_next_rr(&dnsa, &dnss, RESET_ANSWERS);
2786      rr;
2787      rr = dns_next_rr(&dnsa, &dnss, RESET_NEXT)) if (rr->type == ind_type)
2788   {
2789   int precedence, weight;
2790   int port = PORT_NONE;
2791   const uschar * s = rr->data;  /* MUST be unsigned for GETSHORT */
2792   uschar data[256];
2793
2794   GETSHORT(precedence, s);      /* Pointer s is advanced */
2795
2796   /* For MX records, we use a random "weight" which causes multiple records of
2797   the same precedence to sort randomly. */
2798
2799   if (ind_type == T_MX)
2800     weight = random_number(500);
2801   else
2802     {
2803     /* SRV records are specified with a port and a weight. The weight is used
2804     in a special algorithm. However, to start with, we just use it to order the
2805     records of equal priority (precedence). */
2806     GETSHORT(weight, s);
2807     GETSHORT(port, s);
2808     }
2809
2810   /* Get the name of the host pointed to. */
2811
2812   (void)dn_expand(dnsa.answer, dnsa.answer + dnsa.answerlen, s,
2813     (DN_EXPAND_ARG4_TYPE)data, sizeof(data));
2814
2815   /* Check that we haven't already got this host on the chain; if we have,
2816   keep only the lower precedence. This situation shouldn't occur, but you
2817   never know what junk might get into the DNS (and this case has been seen on
2818   more than one occasion). */
2819
2820   if (last)       /* This is not the first record */
2821     {
2822     host_item *prev = NULL;
2823
2824     for (h = host; h != last->next; prev = h, h = h->next)
2825       if (strcmpic(h->name, data) == 0)
2826         {
2827         DEBUG(D_host_lookup)
2828           debug_printf("discarded duplicate host %s (MX=%d)\n", data,
2829             precedence > h->mx ? precedence : h->mx);
2830         if (precedence >= h->mx) goto NEXT_MX_RR; /* Skip greater precedence */
2831         if (h == host)                            /* Override first item */
2832           {
2833           h->mx = precedence;
2834           host->sort_key = precedence * 1000 + weight;
2835           goto NEXT_MX_RR;
2836           }
2837
2838         /* Unwanted host item is not the first in the chain, so we can get
2839         get rid of it by cutting it out. */
2840
2841         prev->next = h->next;
2842         if (h == last) last = prev;
2843         break;
2844         }
2845     }
2846
2847   /* If this is the first MX or SRV record, put the data into the existing host
2848   block. Otherwise, add a new block in the correct place; if it has to be
2849   before the first block, copy the first block's data to a new second block. */
2850
2851   if (!last)
2852     {
2853     host->name = string_copy_dnsdomain(data);
2854     host->address = NULL;
2855     host->port = port;
2856     host->mx = precedence;
2857     host->sort_key = precedence * 1000 + weight;
2858     host->status = hstatus_unknown;
2859     host->why = hwhy_unknown;
2860     host->dnssec = dnssec;
2861     last = host;
2862     }
2863   else
2864
2865   /* Make a new host item and seek the correct insertion place */
2866     {
2867     int sort_key = precedence * 1000 + weight;
2868     host_item *next = store_get(sizeof(host_item));
2869     next->name = string_copy_dnsdomain(data);
2870     next->address = NULL;
2871     next->port = port;
2872     next->mx = precedence;
2873     next->sort_key = sort_key;
2874     next->status = hstatus_unknown;
2875     next->why = hwhy_unknown;
2876     next->dnssec = dnssec;
2877     next->last_try = 0;
2878
2879     /* Handle the case when we have to insert before the first item. */
2880
2881     if (sort_key < host->sort_key)
2882       {
2883       host_item htemp;
2884       htemp = *host;
2885       *host = *next;
2886       *next = htemp;
2887       host->next = next;
2888       if (last == host) last = next;
2889       }
2890     else
2891
2892     /* Else scan down the items we have inserted as part of this exercise;
2893     don't go further. */
2894       {
2895       for (h = host; h != last; h = h->next)
2896         if (sort_key < h->next->sort_key)
2897           {
2898           next->next = h->next;
2899           h->next = next;
2900           break;
2901           }
2902
2903       /* Join on after the last host item that's part of this
2904       processing if we haven't stopped sooner. */
2905
2906       if (h == last)
2907         {
2908         next->next = last->next;
2909         last->next = next;
2910         last = next;
2911         }
2912       }
2913     }
2914
2915   NEXT_MX_RR: continue;
2916   }
2917
2918 if (!last)      /* No rr of correct type; give up */
2919   {
2920   yield = HOST_FIND_FAILED;
2921   goto out;
2922   }
2923
2924 /* If the list of hosts was obtained from SRV records, there are two things to
2925 do. First, if there is only one host, and it's name is ".", it means there is
2926 no SMTP service at this domain. Otherwise, we have to sort the hosts of equal
2927 priority according to their weights, using an algorithm that is defined in RFC
2928 2782. The hosts are currently sorted by priority and weight. For each priority
2929 group we have to pick off one host and put it first, and then repeat for any
2930 remaining in the same priority group. */
2931
2932 if (ind_type == T_SRV)
2933   {
2934   host_item **pptr;
2935
2936   if (host == last && host->name[0] == 0)
2937     {
2938     DEBUG(D_host_lookup) debug_printf("the single SRV record is \".\"\n");
2939     yield = HOST_FIND_FAILED;
2940     goto out;
2941     }
2942
2943   DEBUG(D_host_lookup)
2944     {
2945     debug_printf("original ordering of hosts from SRV records:\n");
2946     for (h = host; h != last->next; h = h->next)
2947       debug_printf("  %s P=%d W=%d\n", h->name, h->mx, h->sort_key % 1000);
2948     }
2949
2950   for (pptr = &host, h = host; h != last; pptr = &h->next, h = h->next)
2951     {
2952     int sum = 0;
2953     host_item *hh;
2954
2955     /* Find the last following host that has the same precedence. At the same
2956     time, compute the sum of the weights and the running totals. These can be
2957     stored in the sort_key field. */
2958
2959     for (hh = h; hh != last; hh = hh->next)
2960       {
2961       int weight = hh->sort_key % 1000;   /* was precedence * 1000 + weight */
2962       sum += weight;
2963       hh->sort_key = sum;
2964       if (hh->mx != hh->next->mx) break;
2965       }
2966
2967     /* If there's more than one host at this precedence (priority), we need to
2968     pick one to go first. */
2969
2970     if (hh != h)
2971       {
2972       host_item *hhh;
2973       host_item **ppptr;
2974       int randomizer = random_number(sum + 1);
2975
2976       for (ppptr = pptr, hhh = h;
2977            hhh != hh;
2978            ppptr = &hhh->next, hhh = hhh->next)
2979         if (hhh->sort_key >= randomizer)
2980           break;
2981
2982       /* hhh now points to the host that should go first; ppptr points to the
2983       place that points to it. Unfortunately, if the start of the minilist is
2984       the start of the entire list, we can't just swap the items over, because
2985       we must not change the value of host, since it is passed in from outside.
2986       One day, this could perhaps be changed.
2987
2988       The special case is fudged by putting the new item *second* in the chain,
2989       and then transferring the data between the first and second items. We
2990       can't just swap the first and the chosen item, because that would mean
2991       that an item with zero weight might no longer be first. */
2992
2993       if (hhh != h)
2994         {
2995         *ppptr = hhh->next;          /* Cuts it out of the chain */
2996
2997         if (h == host)
2998           {
2999           host_item temp = *h;
3000           *h = *hhh;
3001           *hhh = temp;
3002           hhh->next = temp.next;
3003           h->next = hhh;
3004           }
3005         else
3006           {
3007           hhh->next = h;               /* The rest of the chain follows it */
3008           *pptr = hhh;                 /* It takes the place of h */
3009           h = hhh;                     /* It's now the start of this minilist */
3010           }
3011         }
3012       }
3013
3014     /* A host has been chosen to be first at this priority and h now points
3015     to this host. There may be others at the same priority, or others at a
3016     different priority. Before we leave this host, we need to put back a sort
3017     key of the traditional MX kind, in case this host is multihomed, because
3018     the sort key is used for ordering the multiple IP addresses. We do not need
3019     to ensure that these new sort keys actually reflect the order of the hosts,
3020     however. */
3021
3022     h->sort_key = h->mx * 1000 + random_number(500);
3023     }   /* Move on to the next host */
3024   }
3025
3026 /* Now we have to find IP addresses for all the hosts. We have ensured above
3027 that the names in all the host items are unique. Before release 4.61 we used to
3028 process records from the additional section in the DNS packet that returned the
3029 MX or SRV records. However, a DNS name server is free to drop any resource
3030 records from the additional section. In theory, this has always been a
3031 potential problem, but it is exacerbated by the advent of IPv6. If a host had
3032 several IPv4 addresses and some were not in the additional section, at least
3033 Exim would try the others. However, if a host had both IPv4 and IPv6 addresses
3034 and all the IPv4 (say) addresses were absent, Exim would try only for a IPv6
3035 connection, and never try an IPv4 address. When there was only IPv4
3036 connectivity, this was a disaster that did in practice occur.
3037
3038 So, from release 4.61 onwards, we always search for A and AAAA records
3039 explicitly. The names shouldn't point to CNAMES, but we use the general lookup
3040 function that handles them, just in case. If any lookup gives a soft error,
3041 change the default yield.
3042
3043 For these DNS lookups, we must disable qualify_single and search_parents;
3044 otherwise invalid host names obtained from MX or SRV records can cause trouble
3045 if they happen to match something local. */
3046
3047 yield = HOST_FIND_FAILED;    /* Default yield */
3048 dns_init(FALSE, FALSE,       /* Disable qualify_single and search_parents */
3049          dnssec_request || dnssec_require);
3050
3051 for (h = host; h != last->next; h = h->next)
3052   {
3053   if (h->address) continue;  /* Inserted by a multihomed host */
3054
3055   rc = set_address_from_dns(h, &last, ignore_target_hosts, allow_mx_to_ip,
3056     NULL, dnssec_request, dnssec_require,
3057     whichrrs & HOST_FIND_IPV4_ONLY
3058     ?  HOST_FIND_BY_A  :  HOST_FIND_BY_A | HOST_FIND_BY_AAAA);
3059   if (rc != HOST_FOUND)
3060     {
3061     h->status = hstatus_unusable;
3062     switch (rc)
3063       {
3064       case HOST_FIND_AGAIN:     yield = rc; h->why = hwhy_deferred; break;
3065       case HOST_FIND_SECURITY:  yield = rc; h->why = hwhy_insecure; break;
3066       case HOST_IGNORED:        h->why = hwhy_ignored; break;
3067       default:                  h->why = hwhy_failed; break;
3068       }
3069     }
3070   }
3071
3072 /* Scan the list for any hosts that are marked unusable because they have
3073 been explicitly ignored, and remove them from the list, as if they did not
3074 exist. If we end up with just a single, ignored host, flatten its fields as if
3075 nothing was found. */
3076
3077 if (ignore_target_hosts)
3078   {
3079   host_item *prev = NULL;
3080   for (h = host; h != last->next; h = h->next)
3081     {
3082     REDO:
3083     if (h->why != hwhy_ignored)        /* Non ignored host, just continue */
3084       prev = h;
3085     else if (prev == NULL)             /* First host is ignored */
3086       {
3087       if (h != last)                   /* First is not last */
3088         {
3089         if (h->next == last) last = h; /* Overwrite it with next */
3090         *h = *(h->next);               /* and reprocess it. */
3091         goto REDO;                     /* C should have redo, like Perl */
3092         }
3093       }
3094     else                               /* Ignored host is not first - */
3095       {                                /*   cut it out */
3096       prev->next = h->next;
3097       if (h == last) last = prev;
3098       }
3099     }
3100
3101   if (host->why == hwhy_ignored) host->address = NULL;
3102   }
3103
3104 /* There is still one complication in the case of IPv6. Although the code above
3105 arranges that IPv6 addresses take precedence over IPv4 addresses for multihomed
3106 hosts, it doesn't do this for addresses that apply to different hosts with the
3107 same MX precedence, because the sorting on MX precedence happens first. So we
3108 have to make another pass to check for this case. We ensure that, within a
3109 single MX preference value, IPv6 addresses come first. This can separate the
3110 addresses of a multihomed host, but that should not matter. */
3111
3112 #if HAVE_IPV6
3113 if (h != last && !disable_ipv6) for (h = host; h != last; h = h->next)
3114   {
3115   host_item temp;
3116   host_item *next = h->next;
3117
3118   if (  h->mx != next->mx                       /* If next is different MX */
3119      || !h->address                             /* OR this one is unset */
3120      )
3121     continue;                                   /* move on to next */
3122
3123   if (  whichrrs & HOST_FIND_IPV4_FIRST
3124      ?     !Ustrchr(h->address, ':')            /* OR this one is IPv4 */
3125         || next->address
3126            && Ustrchr(next->address, ':')       /* OR next is IPv6 */
3127
3128      :     Ustrchr(h->address, ':')             /* OR this one is IPv6 */
3129         || next->address
3130            && !Ustrchr(next->address, ':')      /* OR next is IPv4 */
3131      )
3132     continue;                                /* move on to next */
3133
3134   temp = *h;                                 /* otherwise, swap */
3135   temp.next = next->next;
3136   *h = *next;
3137   h->next = next;
3138   *next = temp;
3139   }
3140 #endif
3141
3142 /* Remove any duplicate IP addresses and then scan the list of hosts for any
3143 whose IP addresses are on the local host. If any are found, all hosts with the
3144 same or higher MX values are removed. However, if the local host has the lowest
3145 numbered MX, then HOST_FOUND_LOCAL is returned. Otherwise, if at least one host
3146 with an IP address is on the list, HOST_FOUND is returned. Otherwise,
3147 HOST_FIND_FAILED is returned, but in this case do not update the yield, as it
3148 might have been set to HOST_FIND_AGAIN just above here. If not, it will already
3149 be HOST_FIND_FAILED. */
3150
3151 host_remove_duplicates(host, &last);
3152 rc = host_scan_for_local_hosts(host, &last, removed);
3153 if (rc != HOST_FIND_FAILED) yield = rc;
3154
3155 DEBUG(D_host_lookup)
3156   {
3157   if (fully_qualified_name != NULL)
3158     debug_printf("fully qualified name = %s\n", *fully_qualified_name);
3159   debug_printf("host_find_bydns yield = %s (%d); returned hosts:\n",
3160     (yield == HOST_FOUND)? "HOST_FOUND" :
3161     (yield == HOST_FOUND_LOCAL)? "HOST_FOUND_LOCAL" :
3162     (yield == HOST_FIND_SECURITY)? "HOST_FIND_SECURITY" :
3163     (yield == HOST_FIND_AGAIN)? "HOST_FIND_AGAIN" :
3164     (yield == HOST_FIND_FAILED)? "HOST_FIND_FAILED" : "?",
3165     yield);
3166   for (h = host; h != last->next; h = h->next)
3167     {
3168     debug_printf("  %s %s MX=%d %s", h->name,
3169       !h->address ? US"<null>" : h->address, h->mx,
3170       h->dnssec == DS_YES ? US"DNSSEC " : US"");
3171     if (h->port != PORT_NONE) debug_printf("port=%d ", h->port);
3172     if (h->status >= hstatus_unusable) debug_printf("*");
3173     debug_printf("\n");
3174     }
3175   }
3176
3177 out:
3178
3179 dns_init(FALSE, FALSE, FALSE);  /* clear the dnssec bit for getaddrbyname */
3180 return yield;
3181 }
3182
3183 /*************************************************
3184 **************************************************
3185 *             Stand-alone test program           *
3186 **************************************************
3187 *************************************************/
3188
3189 #ifdef STAND_ALONE
3190
3191 int main(int argc, char **cargv)
3192 {
3193 host_item h;
3194 int whichrrs = HOST_FIND_BY_MX | HOST_FIND_BY_A | HOST_FIND_BY_AAAA;
3195 BOOL byname = FALSE;
3196 BOOL qualify_single = TRUE;
3197 BOOL search_parents = FALSE;
3198 BOOL request_dnssec = FALSE;
3199 BOOL require_dnssec = FALSE;
3200 uschar **argv = USS cargv;
3201 uschar buffer[256];
3202
3203 disable_ipv6 = FALSE;
3204 primary_hostname = US"";
3205 store_pool = POOL_MAIN;
3206 debug_selector = D_host_lookup|D_interface;
3207 debug_file = stdout;
3208 debug_fd = fileno(debug_file);
3209
3210 printf("Exim stand-alone host functions test\n");
3211
3212 host_find_interfaces();
3213 debug_selector = D_host_lookup | D_dns;
3214
3215 if (argc > 1) primary_hostname = argv[1];
3216
3217 /* So that debug level changes can be done first */
3218
3219 dns_init(qualify_single, search_parents, FALSE);
3220
3221 printf("Testing host lookup\n");
3222 printf("> ");
3223 while (Ufgets(buffer, 256, stdin) != NULL)
3224   {
3225   int rc;
3226   int len = Ustrlen(buffer);
3227   uschar *fully_qualified_name;
3228
3229   while (len > 0 && isspace(buffer[len-1])) len--;
3230   buffer[len] = 0;
3231
3232   if (Ustrcmp(buffer, "q") == 0) break;
3233
3234   if (Ustrcmp(buffer, "byname") == 0) byname = TRUE;
3235   else if (Ustrcmp(buffer, "no_byname") == 0) byname = FALSE;
3236   else if (Ustrcmp(buffer, "a_only") == 0) whichrrs = HOST_FIND_BY_A | HOST_FIND_BY_AAAA;
3237   else if (Ustrcmp(buffer, "mx_only") == 0) whichrrs = HOST_FIND_BY_MX;
3238   else if (Ustrcmp(buffer, "srv_only") == 0) whichrrs = HOST_FIND_BY_SRV;
3239   else if (Ustrcmp(buffer, "srv+a") == 0)
3240     whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_A | HOST_FIND_BY_AAAA;
3241   else if (Ustrcmp(buffer, "srv+mx") == 0)
3242     whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_MX;
3243   else if (Ustrcmp(buffer, "srv+mx+a") == 0)
3244     whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_MX | HOST_FIND_BY_A | HOST_FIND_BY_AAAA;
3245   else if (Ustrcmp(buffer, "qualify_single")    == 0) qualify_single = TRUE;
3246   else if (Ustrcmp(buffer, "no_qualify_single") == 0) qualify_single = FALSE;
3247   else if (Ustrcmp(buffer, "search_parents")    == 0) search_parents = TRUE;
3248   else if (Ustrcmp(buffer, "no_search_parents") == 0) search_parents = FALSE;
3249   else if (Ustrcmp(buffer, "request_dnssec")    == 0) request_dnssec = TRUE;
3250   else if (Ustrcmp(buffer, "no_request_dnssec") == 0) request_dnssec = FALSE;
3251   else if (Ustrcmp(buffer, "require_dnssec")    == 0) require_dnssec = TRUE;
3252   else if (Ustrcmp(buffer, "no_require_dnssec") == 0) require_dnssec = FALSE;
3253   else if (Ustrcmp(buffer, "test_harness") == 0)
3254     f.running_in_test_harness = !f.running_in_test_harness;
3255   else if (Ustrcmp(buffer, "ipv6") == 0) disable_ipv6 = !disable_ipv6;
3256   else if (Ustrcmp(buffer, "res_debug") == 0)
3257     {
3258     _res.options ^= RES_DEBUG;
3259     }
3260   else if (Ustrncmp(buffer, "retrans", 7) == 0)
3261     {
3262     (void)sscanf(CS(buffer+8), "%d", &dns_retrans);
3263     _res.retrans = dns_retrans;
3264     }
3265   else if (Ustrncmp(buffer, "retry", 5) == 0)
3266     {
3267     (void)sscanf(CS(buffer+6), "%d", &dns_retry);
3268     _res.retry = dns_retry;
3269     }
3270   else
3271     {
3272     int flags = whichrrs;
3273     dnssec_domains d;
3274
3275     h.name = buffer;
3276     h.next = NULL;
3277     h.mx = MX_NONE;
3278     h.port = PORT_NONE;
3279     h.status = hstatus_unknown;
3280     h.why = hwhy_unknown;
3281     h.address = NULL;
3282
3283     if (qualify_single) flags |= HOST_FIND_QUALIFY_SINGLE;
3284     if (search_parents) flags |= HOST_FIND_SEARCH_PARENTS;
3285
3286     d.request = request_dnssec ? &h.name : NULL;
3287     d.require = require_dnssec ? &h.name : NULL;
3288
3289     rc = byname
3290       ? host_find_byname(&h, NULL, flags, &fully_qualified_name, TRUE)
3291       : host_find_bydns(&h, NULL, flags, US"smtp", NULL, NULL,
3292                         &d, &fully_qualified_name, NULL);
3293
3294     switch (rc)
3295       {
3296       case HOST_FIND_FAILED:    printf("Failed\n");     break;
3297       case HOST_FIND_AGAIN:     printf("Again\n");      break;
3298       case HOST_FIND_SECURITY:  printf("Security\n");   break;
3299       case HOST_FOUND_LOCAL:    printf("Local\n");      break;
3300       }
3301     }
3302
3303   printf("\n> ");
3304   }
3305
3306 printf("Testing host_aton\n");
3307 printf("> ");
3308 while (Ufgets(buffer, 256, stdin) != NULL)
3309   {
3310   int i;
3311   int x[4];
3312   int len = Ustrlen(buffer);
3313
3314   while (len > 0 && isspace(buffer[len-1])) len--;
3315   buffer[len] = 0;
3316
3317   if (Ustrcmp(buffer, "q") == 0) break;
3318
3319   len = host_aton(buffer, x);
3320   printf("length = %d ", len);
3321   for (i = 0; i < len; i++)
3322     {
3323     printf("%04x ", (x[i] >> 16) & 0xffff);
3324     printf("%04x ", x[i] & 0xffff);
3325     }
3326   printf("\n> ");
3327   }
3328
3329 printf("\n");
3330
3331 printf("Testing host_name_lookup\n");
3332 printf("> ");
3333 while (Ufgets(buffer, 256, stdin) != NULL)
3334   {
3335   int len = Ustrlen(buffer);
3336   while (len > 0 && isspace(buffer[len-1])) len--;
3337   buffer[len] = 0;
3338   if (Ustrcmp(buffer, "q") == 0) break;
3339   sender_host_address = buffer;
3340   sender_host_name = NULL;
3341   sender_host_aliases = NULL;
3342   host_lookup_msg = US"";
3343   host_lookup_failed = FALSE;
3344   if (host_name_lookup() == FAIL)  /* Debug causes printing */
3345     printf("Lookup failed:%s\n", host_lookup_msg);
3346   printf("\n> ");
3347   }
3348
3349 printf("\n");
3350
3351 return 0;
3352 }
3353 #endif  /* STAND_ALONE */
3354
3355 /* vi: aw ai sw=2
3356 */
3357 /* End of host.c */