X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=src%2Fsrc%2Fhost.c;h=d4267429bcd449d3ccf0fb4750280ba7dbd2e502;hp=b3b8b1882a127eb473663d37df4c512949133927;hb=bce15b62182d356f86e7a0bdbb513cbb22de1a20;hpb=f988ce57300f2dcb7ddb63f767ef5ebef76b2aa4 diff --git a/src/src/host.c b/src/src/host.c index b3b8b1882..d4267429b 100644 --- a/src/src/host.c +++ b/src/src/host.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2016 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for finding hosts, either by gethostbyname(), gethostbyaddr(), or @@ -520,7 +520,9 @@ There wouldn't be two different variables if I had got all this right in the first place. Because this data may survive over more than one incoming SMTP message, it has -to be in permanent store. +to be in permanent store. However, STARTTLS has to be forgotten and redone +on a multi-message conn, so this will be called once per message then. Hence +we use malloc, so we can free. Arguments: none Returns: nothing @@ -530,13 +532,12 @@ void host_build_sender_fullhost(void) { BOOL show_helo = TRUE; -uschar *address; +uschar * address, * fullhost, * rcvhost, * reset_point; int len; -int old_pool = store_pool; -if (sender_host_address == NULL) return; +if (!sender_host_address) return; -store_pool = POOL_PERM; +reset_point = store_get(0); /* Set up address, with or without the port. After discussion, it seems that the only format that doesn't cause trouble is [aaaa]:pppp. However, we can't @@ -549,7 +550,7 @@ if (!LOGGING(incoming_port) || sender_host_port <= 0) /* If there's no EHLO/HELO data, we can't show it. */ -if (sender_helo_name == NULL) show_helo = FALSE; +if (!sender_helo_name) show_helo = FALSE; /* If HELO/EHLO was followed by an IP literal, it's messy because of two features of IPv6. Firstly, there's the "IPv6:" prefix (Exim is liberal and @@ -586,46 +587,40 @@ else if (sender_helo_name[0] == '[' && /* Host name is not verified */ -if (sender_host_name == NULL) +if (!sender_host_name) { uschar *portptr = Ustrstr(address, "]:"); - int size = 0; - int ptr = 0; + gstring * g; int adlen; /* Sun compiler doesn't like ++ in initializers */ - adlen = (portptr == NULL)? Ustrlen(address) : (++portptr - address); - sender_fullhost = (sender_helo_name == NULL)? address : - string_sprintf("(%s) %s", sender_helo_name, address); + adlen = portptr ? (++portptr - address) : Ustrlen(address); + fullhost = sender_helo_name + ? string_sprintf("(%s) %s", sender_helo_name, address) + : address; - sender_rcvhost = string_catn(NULL, &size, &ptr, address, adlen); + g = string_catn(NULL, address, adlen); - if (sender_ident != NULL || show_helo || portptr != NULL) + if (sender_ident || show_helo || portptr) { int firstptr; - sender_rcvhost = string_catn(sender_rcvhost, &size, &ptr, US" (", 2); - firstptr = ptr; + g = string_catn(g, US" (", 2); + firstptr = g->ptr; - if (portptr != NULL) - sender_rcvhost = string_append(sender_rcvhost, &size, &ptr, 2, US"port=", - portptr + 1); + if (portptr) + g = string_append(g, 2, US"port=", portptr + 1); if (show_helo) - sender_rcvhost = string_append(sender_rcvhost, &size, &ptr, 2, - (firstptr == ptr)? US"helo=" : US" helo=", sender_helo_name); + g = string_append(g, 2, + firstptr == g->ptr ? US"helo=" : US" helo=", sender_helo_name); - if (sender_ident != NULL) - sender_rcvhost = string_append(sender_rcvhost, &size, &ptr, 2, - (firstptr == ptr)? US"ident=" : US" ident=", sender_ident); + if (sender_ident) + g = string_append(g, 2, + firstptr == g->ptr ? US"ident=" : US" ident=", sender_ident); - sender_rcvhost = string_catn(sender_rcvhost, &size, &ptr, US")", 1); + g = string_catn(g, US")", 1); } - sender_rcvhost[ptr] = 0; /* string_cat() always leaves room */ - - /* Release store, because string_cat allocated a minimum of 100 bytes that - are rarely completely used. */ - - store_reset(sender_rcvhost + ptr + 1); + rcvhost = string_from_gstring(g); } /* Host name is known and verified. Unless we've already found that the HELO @@ -638,25 +633,30 @@ else if (show_helo) { - sender_fullhost = string_sprintf("%s (%s) %s", sender_host_name, + fullhost = string_sprintf("%s (%s) %s", sender_host_name, sender_helo_name, address); - sender_rcvhost = (sender_ident == NULL)? - string_sprintf("%s (%s helo=%s)", sender_host_name, - address, sender_helo_name) : - string_sprintf("%s\n\t(%s helo=%s ident=%s)", sender_host_name, - address, sender_helo_name, sender_ident); + rcvhost = sender_ident + ? string_sprintf("%s\n\t(%s helo=%s ident=%s)", sender_host_name, + address, sender_helo_name, sender_ident) + : string_sprintf("%s (%s helo=%s)", sender_host_name, + address, sender_helo_name); } else { - sender_fullhost = string_sprintf("%s %s", sender_host_name, address); - sender_rcvhost = (sender_ident == NULL)? - string_sprintf("%s (%s)", sender_host_name, address) : - string_sprintf("%s (%s ident=%s)", sender_host_name, address, - sender_ident); + fullhost = string_sprintf("%s %s", sender_host_name, address); + rcvhost = sender_ident + ? string_sprintf("%s (%s ident=%s)", sender_host_name, address, + sender_ident) + : string_sprintf("%s (%s)", sender_host_name, address); } } -store_pool = old_pool; +if (sender_fullhost) store_free(sender_fullhost); +sender_fullhost = string_copy_malloc(fullhost); +if (sender_rcvhost) store_free(sender_rcvhost); +sender_rcvhost = string_copy_malloc(rcvhost); + +store_reset(reset_point); DEBUG(D_host_lookup) debug_printf("sender_fullhost = %s\n", sender_fullhost); DEBUG(D_host_lookup) debug_printf("sender_rcvhost = %s\n", sender_rcvhost); @@ -737,16 +737,14 @@ host_build_ifacelist(const uschar *list, uschar *name) { int sep = 0; uschar *s; -uschar buffer[64]; -ip_address_item *yield = NULL; -ip_address_item *last = NULL; -ip_address_item *next; +ip_address_item * yield = NULL, * last = NULL, * next; -while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL) +while ((s = string_nextinlist(&list, &sep, NULL, 0))) { int ipv; int port = host_address_extract_port(s); /* Leaves just the IP address */ - if ((ipv = string_is_ip_address(s, NULL)) == 0) + + if (!(ipv = string_is_ip_address(s, NULL))) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Malformed IP address \"%s\" in %s", s, name); @@ -764,7 +762,9 @@ while ((s = string_nextinlist(&list, &sep, buffer, sizeof(buffer))) != NULL) next->port = port; next->v6_include_v4 = FALSE; - if (yield == NULL) yield = last = next; else + if (!yield) + yield = last = next; + else { last->next = next; last = next; @@ -919,21 +919,21 @@ if (type < 0) if (family == AF_INET6) { struct sockaddr_in6 *sk = (struct sockaddr_in6 *)arg; - yield = (uschar *)inet_ntop(family, &(sk->sin6_addr), CS addr_buffer, + yield = US inet_ntop(family, &(sk->sin6_addr), CS addr_buffer, sizeof(addr_buffer)); if (portptr != NULL) *portptr = ntohs(sk->sin6_port); } else { struct sockaddr_in *sk = (struct sockaddr_in *)arg; - yield = (uschar *)inet_ntop(family, &(sk->sin_addr), CS addr_buffer, + yield = US inet_ntop(family, &(sk->sin_addr), CS addr_buffer, sizeof(addr_buffer)); if (portptr != NULL) *portptr = ntohs(sk->sin_port); } } else { - yield = (uschar *)inet_ntop(type, arg, CS addr_buffer, sizeof(addr_buffer)); + yield = US inet_ntop(type, arg, CS addr_buffer, sizeof(addr_buffer)); } /* If the result is a mapped IPv4 address, show it in V4 format. */ @@ -1160,10 +1160,7 @@ tt--; /* lose final separator */ if (mask < 0) *tt = 0; else - { - sprintf(CS tt, "/%d", mask); - while (*tt) tt++; - } + tt += sprintf(CS tt, "/%d", mask); return tt - buffer; } @@ -1587,7 +1584,7 @@ if (hosts->h_name == NULL || hosts->h_name[0] == 0 || hosts->h_name[0] == '.') /* Copy and lowercase the name, which is in static storage in many systems. Put it in permanent memory. */ -s = (uschar *)hosts->h_name; +s = US hosts->h_name; len = Ustrlen(s) + 1; t = sender_host_name = store_get_perm(len); while (*s != 0) *t++ = tolower(*s++); @@ -1742,7 +1739,7 @@ while ((ordername = string_nextinlist(&list, &sep, buffer, sizeof(buffer)))) truncated and dn_expand may fail. */ if (dn_expand(dnsa.answer, dnsa.answer + dnsa.answerlen, - (uschar *)(rr->data), (DN_EXPAND_ARG4_TYPE)(s), ssize) < 0) + US (rr->data), (DN_EXPAND_ARG4_TYPE)(s), ssize) < 0) { log_write(0, LOG_MAIN, "host name alias list truncated for %s", sender_host_address); @@ -1831,7 +1828,7 @@ the names, and accepts only those that have the correct IP address. */ save_hostname = sender_host_name; /* Save for error messages */ aliases = sender_host_aliases; -for (hname = sender_host_name; hname != NULL; hname = *aliases++) +for (hname = sender_host_name; hname; hname = *aliases++) { int rc; BOOL ok = FALSE; @@ -1845,7 +1842,7 @@ for (hname = sender_host_name; hname != NULL; hname = *aliases++) d.request = sender_host_dnssec ? US"*" : NULL;; d.require = NULL; - if ( (rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A, + if ( (rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A | HOST_FIND_BY_AAAA, NULL, NULL, NULL, &d, NULL, NULL)) == HOST_FOUND || rc == HOST_FOUND_LOCAL ) @@ -1859,7 +1856,7 @@ for (hname = sender_host_name; hname != NULL; hname = *aliases++) h.dnssec == DS_YES ? "DNSSEC verified (AD)" : "unverified"); if (h.dnssec != DS_YES) sender_host_dnssec = FALSE; - for (hh = &h; hh != NULL; hh = hh->next) + for (hh = &h; hh; hh = hh->next) if (host_is_in_net(hh->address, sender_host_address, 0)) { HDEBUG(D_host_lookup) debug_printf(" %s OK\n", hh->address); @@ -2099,7 +2096,7 @@ for (i = 1; i <= times; if (hostdata->h_name[0] != 0 && Ustrcmp(host->name, hostdata->h_name) != 0) - host->name = string_copy_dnsdomain((uschar *)hostdata->h_name); + host->name = string_copy_dnsdomain(US hostdata->h_name); if (fully_qualified_name != NULL) *fully_qualified_name = host->name; /* Get the list of addresses. IPv4 and IPv6 addresses can be distinguished @@ -2245,9 +2242,7 @@ field set to NULL, fill in its IP address from the DNS. If it is multi-homed, create additional host items for the additional addresses, copying all the other fields, and randomizing the order. -On IPv6 systems, A6 records are sought first (but only if support for A6 is -configured - they may never become mainstream), then AAAA records are sought, -and finally A records are sought as well. +On IPv6 systems, AAAA records are sought first, then A records. The host name may be changed if the DNS returns a different name - e.g. fully qualified or changed via CNAME. If fully_qualified_name is not NULL, dns_lookup @@ -2270,9 +2265,11 @@ Arguments: to something) dnssec_request if TRUE request the AD bit dnssec_require if TRUE require the AD bit + whichrrs select ipv4, ipv6 results Returns: HOST_FIND_FAILED couldn't find A record HOST_FIND_AGAIN try again later + HOST_FIND_SECURITY dnssec required but not acheived HOST_FOUND found AAAA and/or A record(s) HOST_IGNORED found, but all IPs ignored */ @@ -2281,11 +2278,12 @@ static int set_address_from_dns(host_item *host, host_item **lastptr, const uschar *ignore_target_hosts, BOOL allow_ip, const uschar **fully_qualified_name, - BOOL dnssec_request, BOOL dnssec_require) + BOOL dnssec_request, BOOL dnssec_require, int whichrrs) { dns_record *rr; host_item *thishostlast = NULL; /* Indicates not yet filled in anything */ BOOL v6_find_again = FALSE; +BOOL dnssec_fail = FALSE; int i; /* If allow_ip is set, a name which is an IP address returns that value @@ -2295,8 +2293,8 @@ those sites that feel they have to flaunt the RFC rules. */ if (allow_ip && string_is_ip_address(host->name, NULL) != 0) { #ifndef STAND_ALONE - if (ignore_target_hosts != NULL && - verify_check_this_host(&ignore_target_hosts, NULL, host->name, + if ( ignore_target_hosts + && verify_check_this_host(&ignore_target_hosts, NULL, host->name, host->name, NULL) == OK) return HOST_IGNORED; #endif @@ -2306,16 +2304,18 @@ if (allow_ip && string_is_ip_address(host->name, NULL) != 0) } /* On an IPv6 system, unless IPv6 is disabled, go round the loop up to twice, -looking for AAAA records the first time. However, unless -doing standalone testing, we force an IPv4 lookup if the domain matches -dns_ipv4_lookup is set. On an IPv4 system, go round the -loop once only, looking only for A records. */ +looking for AAAA records the first time. However, unless doing standalone +testing, we force an IPv4 lookup if the domain matches dns_ipv4_lookup global. +On an IPv4 system, go round the loop once only, looking only for A records. */ #if HAVE_IPV6 #ifndef STAND_ALONE - if (disable_ipv6 || (dns_ipv4_lookup != NULL && - match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL, - MCL_DOMAIN, TRUE, NULL) == OK)) + if ( disable_ipv6 + || !(whichrrs & HOST_FIND_BY_AAAA) + || (dns_ipv4_lookup + && match_isinlist(host->name, CUSS &dns_ipv4_lookup, 0, NULL, NULL, + MCL_DOMAIN, TRUE, NULL) == OK) + ) i = 0; /* look up A records only */ else #endif /* STAND_ALONE */ @@ -2332,7 +2332,8 @@ for (; i >= 0; i--) { static int types[] = { T_A, T_AAAA }; int type = types[i]; - int randoffset = (i == 0)? 500 : 0; /* Ensures v6 sorts before v4 */ + int randoffset = i == (whichrrs & HOST_FIND_IPV4_FIRST ? 1 : 0) + ? 500 : 0; /* Ensures v6/4 sort order */ dns_answer dnsa; dns_scan dnss; @@ -2381,8 +2382,8 @@ for (; i >= 0; i--) { if (dnssec_require) { - log_write(L_host_lookup_failed, LOG_MAIN, - "dnssec fail on %s for %.256s", + dnssec_fail = TRUE; + DEBUG(D_host_lookup) debug_printf("dnssec fail on %s for %.256s", i>0 ? "AAAA" : "A", host->name); continue; } @@ -2504,10 +2505,14 @@ for (; i >= 0; i--) } } -/* Control gets here only if the econdookup (the A record) succeeded. +/* Control gets here only if the second lookup (the A record) succeeded. However, the address may not be filled in if it was ignored. */ -return host->address ? HOST_FOUND : HOST_IGNORED; +return host->address + ? HOST_FOUND + : dnssec_fail + ? HOST_FIND_SECURITY + : HOST_IGNORED; } @@ -2530,10 +2535,13 @@ Arguments: whichrrs flags indicating which RRs to look for: HOST_FIND_BY_SRV => look for SRV HOST_FIND_BY_MX => look for MX - HOST_FIND_BY_A => look for A or AAAA + HOST_FIND_BY_A => look for A + HOST_FIND_BY_AAAA => look for AAAA also flags indicating how the lookup is done HOST_FIND_QUALIFY_SINGLE ) passed to the HOST_FIND_SEARCH_PARENTS ) resolver + HOST_FIND_IPV4_FIRST => reverse usual result ordering + HOST_FIND_IPV4_ONLY => MX results elide ipv6 srv_service when SRV used, the service name srv_fail_domains DNS errors for these domains => assume nonexist mx_fail_domains DNS errors for these domains => assume nonexist @@ -2546,6 +2554,7 @@ Returns: HOST_FIND_FAILED Failed to find the host or domain; if there was a syntax error, host_find_failed_syntax is set. HOST_FIND_AGAIN Could not resolve at this time + HOST_FIND_SECURITY dnsssec required but not acheived HOST_FOUND Host found HOST_FOUND_LOCAL The lowest MX record points to this machine, if MX records were found, or @@ -2609,8 +2618,8 @@ if ((whichrrs & HOST_FIND_BY_SRV) != 0) DEBUG(D_dns) if ((dnssec_request || dnssec_require) - & !dns_is_secure(&dnsa) - & dns_is_aa(&dnsa)) + && !dns_is_secure(&dnsa) + && dns_is_aa(&dnsa)) debug_printf("DNS lookup of %.256s (SRV) requested AD, but got AA\n", host->name); if (dnssec_request) @@ -2652,7 +2661,7 @@ same domain. The result will be DNS_NODATA if the domain exists but has no MX records. On DNS failures, we give the "try again" error unless the domain is listed as one for which we continue. */ -if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0) +if (rc != DNS_SUCCEED && whichrrs & HOST_FIND_BY_MX) { ind_type = T_MX; dnssec = DS_UNK; @@ -2660,13 +2669,12 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0) rc = dns_lookup_timerwrap(&dnsa, host->name, ind_type, fully_qualified_name); DEBUG(D_dns) - if ((dnssec_request || dnssec_require) - & !dns_is_secure(&dnsa) - & dns_is_aa(&dnsa)) + if ( (dnssec_request || dnssec_require) + && !dns_is_secure(&dnsa) + && dns_is_aa(&dnsa)) debug_printf("DNS lookup of %.256s (MX) requested AD, but got AA\n", host->name); if (dnssec_request) - { if (dns_is_secure(&dnsa)) { DEBUG(D_host_lookup) debug_printf("%s MX DNSSEC\n", host->name); @@ -2676,7 +2684,6 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0) { dnssec = DS_NO; lookup_dnssec_authenticated = US"no"; } - } switch (rc) { @@ -2686,17 +2693,22 @@ if (rc != DNS_SUCCEED && (whichrrs & HOST_FIND_BY_MX) != 0) case DNS_SUCCEED: if (!dnssec_require || dns_is_secure(&dnsa)) break; - log_write(L_host_lookup_failed, LOG_MAIN, - "dnssec fail on MX for %.256s", host->name); + DEBUG(D_host_lookup) + debug_printf("dnssec fail on MX for %.256s", host->name); +#ifndef STAND_ALONE + if (match_isinlist(host->name, CUSS &mx_fail_domains, 0, NULL, NULL, + MCL_DOMAIN, TRUE, NULL) != OK) + { yield = HOST_FIND_SECURITY; goto out; } +#endif rc = DNS_FAIL; /*FALLTHROUGH*/ case DNS_FAIL: case DNS_AGAIN: - #ifndef STAND_ALONE +#ifndef STAND_ALONE if (match_isinlist(host->name, CUSS &mx_fail_domains, 0, NULL, NULL, MCL_DOMAIN, TRUE, NULL) != OK) - #endif +#endif { yield = HOST_FIND_AGAIN; goto out; } DEBUG(D_host_lookup) debug_printf("DNS_%s treated as DNS_NODATA " "(domain in mx_fail_domains)\n", (rc == DNS_FAIL)? "FAIL":"AGAIN"); @@ -2710,7 +2722,7 @@ host. */ if (rc != DNS_SUCCEED) { - if ((whichrrs & HOST_FIND_BY_A) == 0) + if (!(whichrrs & (HOST_FIND_BY_A | HOST_FIND_BY_AAAA))) { DEBUG(D_host_lookup) debug_printf("Address records are not being sought\n"); yield = HOST_FIND_FAILED; @@ -2723,7 +2735,7 @@ if (rc != DNS_SUCCEED) host->dnssec = DS_UNK; lookup_dnssec_authenticated = NULL; rc = set_address_from_dns(host, &last, ignore_target_hosts, FALSE, - fully_qualified_name, dnssec_request, dnssec_require); + fully_qualified_name, dnssec_request, dnssec_require, whichrrs); /* If one or more address records have been found, check that none of them are local. Since we know the host items all have their IP addresses @@ -3058,17 +3070,19 @@ for (h = host; h != last->next; h = h->next) if (h->address) continue; /* Inserted by a multihomed host */ rc = set_address_from_dns(h, &last, ignore_target_hosts, allow_mx_to_ip, - NULL, dnssec_request, dnssec_require); + NULL, dnssec_request, dnssec_require, + whichrrs & HOST_FIND_IPV4_ONLY + ? HOST_FIND_BY_A : HOST_FIND_BY_A | HOST_FIND_BY_AAAA); if (rc != HOST_FOUND) { h->status = hstatus_unusable; - if (rc == HOST_FIND_AGAIN) + switch (rc) { - yield = rc; - h->why = hwhy_deferred; + case HOST_FIND_AGAIN: yield = rc; h->why = hwhy_deferred; break; + case HOST_FIND_SECURITY: yield = rc; h->why = hwhy_insecure; break; + case HOST_IGNORED: h->why = hwhy_ignored; break; + default: h->why = hwhy_failed; break; } - else - h->why = rc == HOST_IGNORED ? hwhy_ignored : hwhy_failed; } } @@ -3077,7 +3091,7 @@ been explicitly ignored, and remove them from the list, as if they did not exist. If we end up with just a single, ignored host, flatten its fields as if nothing was found. */ -if (ignore_target_hosts != NULL) +if (ignore_target_hosts) { host_item *prev = NULL; for (h = host; h != last->next; h = h->next) @@ -3113,24 +3127,32 @@ single MX preference value, IPv6 addresses come first. This can separate the addresses of a multihomed host, but that should not matter. */ #if HAVE_IPV6 -if (h != last && !disable_ipv6) +if (h != last && !disable_ipv6) for (h = host; h != last; h = h->next) { - for (h = host; h != last; h = h->next) - { - host_item temp; - host_item *next = h->next; - if (h->mx != next->mx || /* If next is different MX */ - h->address == NULL || /* OR this one is unset */ - Ustrchr(h->address, ':') != NULL || /* OR this one is IPv6 */ - (next->address != NULL && - Ustrchr(next->address, ':') == NULL)) /* OR next is IPv4 */ - continue; /* move on to next */ - temp = *h; /* otherwise, swap */ - temp.next = next->next; - *h = *next; - h->next = next; - *next = temp; - } + host_item temp; + host_item *next = h->next; + + if ( h->mx != next->mx /* If next is different MX */ + || !h->address /* OR this one is unset */ + ) + continue; /* move on to next */ + + if ( whichrrs & HOST_FIND_IPV4_FIRST + ? !Ustrchr(h->address, ':') /* OR this one is IPv4 */ + || next->address + && Ustrchr(next->address, ':') /* OR next is IPv6 */ + + : Ustrchr(h->address, ':') /* OR this one is IPv6 */ + || next->address + && !Ustrchr(next->address, ':') /* OR next is IPv4 */ + ) + continue; /* move on to next */ + + temp = *h; /* otherwise, swap */ + temp.next = next->next; + *h = *next; + h->next = next; + *next = temp; } #endif @@ -3154,6 +3176,7 @@ DEBUG(D_host_lookup) debug_printf("host_find_bydns yield = %s (%d); returned hosts:\n", (yield == HOST_FOUND)? "HOST_FOUND" : (yield == HOST_FOUND_LOCAL)? "HOST_FOUND_LOCAL" : + (yield == HOST_FIND_SECURITY)? "HOST_FIND_SECURITY" : (yield == HOST_FIND_AGAIN)? "HOST_FIND_AGAIN" : (yield == HOST_FIND_FAILED)? "HOST_FIND_FAILED" : "?", yield); @@ -3185,7 +3208,7 @@ return yield; int main(int argc, char **cargv) { host_item h; -int whichrrs = HOST_FIND_BY_MX | HOST_FIND_BY_A; +int whichrrs = HOST_FIND_BY_MX | HOST_FIND_BY_A | HOST_FIND_BY_AAAA; BOOL byname = FALSE; BOOL qualify_single = TRUE; BOOL search_parents = FALSE; @@ -3227,15 +3250,15 @@ while (Ufgets(buffer, 256, stdin) != NULL) if (Ustrcmp(buffer, "byname") == 0) byname = TRUE; else if (Ustrcmp(buffer, "no_byname") == 0) byname = FALSE; - else if (Ustrcmp(buffer, "a_only") == 0) whichrrs = HOST_FIND_BY_A; + else if (Ustrcmp(buffer, "a_only") == 0) whichrrs = HOST_FIND_BY_A | HOST_FIND_BY_AAAA; else if (Ustrcmp(buffer, "mx_only") == 0) whichrrs = HOST_FIND_BY_MX; else if (Ustrcmp(buffer, "srv_only") == 0) whichrrs = HOST_FIND_BY_SRV; else if (Ustrcmp(buffer, "srv+a") == 0) - whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_A; + whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_A | HOST_FIND_BY_AAAA; else if (Ustrcmp(buffer, "srv+mx") == 0) whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_MX; else if (Ustrcmp(buffer, "srv+mx+a") == 0) - whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_MX | HOST_FIND_BY_A; + whichrrs = HOST_FIND_BY_SRV | HOST_FIND_BY_MX | HOST_FIND_BY_A | HOST_FIND_BY_AAAA; else if (Ustrcmp(buffer, "qualify_single") == 0) qualify_single = TRUE; else if (Ustrcmp(buffer, "no_qualify_single") == 0) qualify_single = FALSE; else if (Ustrcmp(buffer, "search_parents") == 0) search_parents = TRUE; @@ -3285,9 +3308,13 @@ while (Ufgets(buffer, 256, stdin) != NULL) : host_find_bydns(&h, NULL, flags, US"smtp", NULL, NULL, &d, &fully_qualified_name, NULL); - if (rc == HOST_FIND_FAILED) printf("Failed\n"); - else if (rc == HOST_FIND_AGAIN) printf("Again\n"); - else if (rc == HOST_FOUND_LOCAL) printf("Local\n"); + switch (rc) + { + case HOST_FIND_FAILED: printf("Failed\n"); break; + case HOST_FIND_AGAIN: printf("Again\n"); break; + case HOST_FIND_SECURITY: printf("Security\n"); break; + case HOST_FOUND_LOCAL: printf("Local\n"); break; + } } printf("\n> ");