X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Fdns.c;h=f5e8ab7384ab306ad7acea13a495a416f7ec1e15;hb=0d0e445543703d3294a16a17a4606c9eade7afcb;hp=1a940b6abdd6818ec78554385a9b42dbccfad4f2;hpb=75e0e026a196fa852a855d5148f29be29ac2d92f;p=exim.git diff --git a/src/src/dns.c b/src/src/dns.c index 1a940b6ab..f5e8ab738 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -1,10 +1,8 @@ -/* $Cambridge: exim/src/src/dns.c,v 1.14 2006/02/16 10:05:33 ph10 Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2006 */ +/* Copyright (c) University of Cambridge 1995 - 2009 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for interfacing with the DNS. */ @@ -180,6 +178,24 @@ _res.options |= (qualify_single? RES_DEFNAMES : 0) | (search_parents? RES_DNSRCH : 0); if (dns_retrans > 0) _res.retrans = dns_retrans; if (dns_retry > 0) _res.retry = dns_retry; + +#ifdef RES_USE_EDNS0 +if (dns_use_edns0 >= 0) + { + if (dns_use_edns0) + _res.options |= RES_USE_EDNS0; + else + _res.options &= ~RES_USE_EDNS0; + DEBUG(D_resolver) + debug_printf("Coerced resolver EDNS0 support %s.\n", + dns_use_edns0 ? "on" : "off"); + } +#else +if (dns_use_edns0 >= 0) + DEBUG(D_resolver) + debug_printf("Unable to %sset EDNS0 without resolver support.\n", + dns_use_edns0 ? "" : "un"); +#endif } @@ -453,6 +469,7 @@ Arguments: Returns: DNS_SUCCEED successful lookup DNS_NOMATCH name not found (NXDOMAIN) or name contains illegal characters (if checking) + or name is an IP address (for IP address lookup) DNS_NODATA domain exists, but no data for this type (NODATA) DNS_AGAIN soft failure, try again later DNS_FAIL DNS failure @@ -461,8 +478,8 @@ Returns: DNS_SUCCEED successful lookup int dns_basic_lookup(dns_answer *dnsa, uschar *name, int type) { -int rc = -1; #ifndef STAND_ALONE +int rc = -1; uschar *save; #endif @@ -504,7 +521,7 @@ For SRV records, we omit the initial _smtp._tcp. components at the start. */ #ifndef STAND_ALONE /* Omit this for stand-alone tests */ -if (check_dns_names_pattern[0] != 0 && type != T_PTR) +if (check_dns_names_pattern[0] != 0 && type != T_PTR && type != T_TXT) { uschar *checkname = name; int ovector[3*(EXPAND_MAXN+1)]; @@ -539,7 +556,20 @@ if (check_dns_names_pattern[0] != 0 && type != T_PTR) number of bytes the message would need, so we need to check for this case. The effect is to truncate overlong data. -If we are running in the test harness, instead of calling the normal resolver +On some systems, res_search() will recognize "A-for-A" queries and return +the IP address instead of returning -1 with h_error=HOST_NOT_FOUND. Some +nameservers are also believed to do this. It is, of course, contrary to the +specification of the DNS, so we lock it out. */ + +if (( + #ifdef SUPPORT_A6 + type == T_A6 || + #endif + type == T_A || type == T_AAAA) && + string_is_ip_address(name, NULL) != 0) + return DNS_NOMATCH; + +/* If we are running in the test harness, instead of calling the normal resolver (res_search), we call fakens_search(), which recognizes certain special domains, and interfaces to a fake nameserver for certain special zones. */ @@ -548,7 +578,12 @@ if (running_in_test_harness) else dnsa->answerlen = res_search(CS name, C_IN, type, dnsa->answer, MAXPACKET); -if (dnsa->answerlen > MAXPACKET) dnsa->answerlen = MAXPACKET; +if (dnsa->answerlen > MAXPACKET) + { + DEBUG(D_dns) debug_printf("DNS lookup of %s (%s) resulted in overlong packet (size %d), truncating to %d.\n", + name, dns_text_type(type), dnsa->answerlen, MAXPACKET); + dnsa->answerlen = MAXPACKET; + } if (dnsa->answerlen < 0) switch (h_errno) { @@ -677,12 +712,10 @@ for (i = 0; i < 10; i++) else if (rr->type == T_CNAME) cname_rr = *rr; } - /* If a CNAME was found, take the fully qualified name from it; otherwise - from the first data record, if present. For testing, there is a magic name - that gets its casing adjusted, because my resolver doesn't seem to pass back - upper case letters in domain names. */ + /* For the first time round this loop, if a CNAME was found, take the fully + qualified name from it; otherwise from the first data record, if present. */ - if (fully_qualified_name != NULL) + if (i == 0 && fully_qualified_name != NULL) { if (cname_rr.data != NULL) { @@ -712,6 +745,8 @@ for (i = 0; i < 10; i++) cname_rr.data, (DN_EXPAND_ARG4_TYPE)data, 256); if (datalen < 0) return DNS_FAIL; name = data; + + DEBUG(D_dns) debug_printf("CNAME found: change to %s\n", name); } /* Loop back to do another lookup */ /*Control reaches here after 10 times round the CNAME loop. Something isn't