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