X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/b975ba52a239bbf56b61a8af88d480bf07c20d81..b08b24c880b30c34f3ed5f4c59a286fdefb1c0f5:/src/src/host.c diff --git a/src/src/host.c b/src/src/host.c index 46c57683a..8cc239b0f 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/host.c,v 1.4 2004/12/29 10:16:53 ph10 Exp $ */ +/* $Cambridge: exim/src/src/host.c,v 1.8 2005/01/25 14:16:33 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2004 */ +/* Copyright (c) University of Cambridge 1995 - 2005 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or @@ -493,7 +493,7 @@ ip_address_item *next; while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL) { int port = host_extract_port(s); /* Leaves just the IP address */ - if (!string_is_ip_address(s, NULL)) + if (string_is_ip_address(s, NULL) == 0) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Malformed IP address \"%s\" in %s", s, name); @@ -735,9 +735,10 @@ host_aton(uschar *address, int *bin) int x[4]; int v4offset = 0; -/* Handle IPv6 address, which may end with an IPv4 address. This code is NOT -enclosed in #if HAVE_IPV6 in order that IPv6 addresses are recognized even if -IPv6 is not supported. */ +/* Handle IPv6 address, which may end with an IPv4 address. It may also end +with a "scope", introduced by a percent sign. This code is NOT enclosed in #if +HAVE_IPV6 in order that IPv6 addresses are recognized even if IPv6 is not +supported. */ if (Ustrchr(address, ':') != NULL) { @@ -751,17 +752,17 @@ if (Ustrchr(address, ':') != NULL) /* If the address starts with a colon, it will start with two colons. Just lose the first one, which will leave a null first component. */ - + if (*p == ':') p++; /* Split the address into components separated by colons. The input address is supposed to be checked for syntax. There was a case where this was overlooked; to guard against that happening again, check here and crash if - there is a violation. */ + there are too many components. */ - while (*p != 0) + while (*p != 0 && *p != '%') { - int len = Ustrcspn(p, ":"); + int len = Ustrcspn(p, ":%"); if (len == 0) nulloffset = ci; if (ci > 7) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Internal error: invalid IPv6 address \"%s\" passed to host_aton()", @@ -1335,9 +1336,11 @@ Returns: OK on success, the answer being placed in the global variable The variable host_lookup_msg is set to an empty string on sucess, or to a reason for the failure otherwise, in a form suitable for tagging onto an error -message, and also host_lookup_failed is set TRUE if the lookup failed. Any -dynamically constructed string for host_lookup_msg must be in permanent store, -because it might be used for several incoming messages on the same SMTP +message, and also host_lookup_failed is set TRUE if the lookup failed. If there +was a defer, host_lookup_deferred is set TRUE. + +Any dynamically constructed string for host_lookup_msg must be in permanent +store, because it might be used for several incoming messages on the same SMTP connection. */ int @@ -1354,6 +1357,8 @@ dns_record *rr; dns_answer dnsa; dns_scan dnss; +host_lookup_deferred = host_lookup_failed = FALSE; + HDEBUG(D_host_lookup) debug_printf("looking up host name for %s\n", sender_host_address); @@ -1365,6 +1370,7 @@ if (running_in_test_harness && { HDEBUG(D_host_lookup) debug_printf("Test harness: host name lookup returns DEFER\n"); + host_lookup_deferred = TRUE; return DEFER; } @@ -1454,6 +1460,7 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) { HDEBUG(D_host_lookup) debug_printf("IP address PTR lookup gave temporary error\n"); + host_lookup_deferred = TRUE; return DEFER; } } @@ -1464,9 +1471,12 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) { HDEBUG(D_host_lookup) debug_printf("IP address lookup using gethostbyaddr()\n"); - rc = host_name_lookup_byaddr(); - if (rc == DEFER) return rc; /* Can't carry on */ + if (rc == DEFER) + { + host_lookup_deferred = TRUE; + return rc; /* Can't carry on */ + } if (rc == OK) break; /* Found a name */ } } /* Loop for bydns/byaddr scanning */ @@ -1480,8 +1490,7 @@ if (sender_host_name == NULL) log_write(L_host_lookup_failed, LOG_MAIN, "no host name found for IP " "address %s", sender_host_address); host_lookup_msg = US" (failed to find host name from IP address)"; - -host_lookup_failed = TRUE; + host_lookup_failed = TRUE; return FAIL; } @@ -1569,6 +1578,7 @@ for (hname = sender_host_name; hname != NULL; hname = *aliases++) else if (rc == HOST_FIND_AGAIN) { HDEBUG(D_host_lookup) debug_printf("temporary error for host name lookup\n"); + host_lookup_deferred = TRUE; return DEFER; } else @@ -1613,7 +1623,6 @@ store_pool = POOL_PERM; host_lookup_msg = string_sprintf(" (%s does not match any IP address for %s)", sender_host_address, save_hostname); store_pool = old_pool; - host_lookup_failed = TRUE; return FAIL; } @@ -1663,6 +1672,19 @@ int i, yield, times; uschar **addrlist; host_item *last = NULL; BOOL temp_error = FALSE; +#if HAVE_IPV6 +int af; +#endif + +/* If we are in the test harness, a name ending in .test.again.dns always +forces a temporary error response. */ + +if (running_in_test_harness) + { + uschar *endname = host->name + Ustrlen(host->name); + if (Ustrcmp(endname - 14, "test.again.dns") == 0) + return HOST_FIND_AGAIN; + } /* In an IPv6 world, we need to scan for both kinds of address, so go round the loop twice. Note that we have ensured that AF_INET6 is defined even in an IPv4 @@ -1671,8 +1693,6 @@ matches the domain, we also just do IPv4 lookups here (except when testing standalone). */ #if HAVE_IPV6 - int af; - #ifndef STAND_ALONE if (dns_ipv4_lookup != NULL && match_isinlist(host->name, &dns_ipv4_lookup, 0, NULL, NULL, MCL_DOMAIN,