From 320fe6140189f08168dce2deca19821b4237e747 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 8 May 2021 23:07:34 +0100 Subject: [PATCH] DNS: Better handling of SOA when negative-caching lookups --- src/src/dns.c | 73 ++++++++++++++++++++---------------------------- src/src/string.c | 2 +- test/stderr/0277 | 4 +++ test/stderr/0469 | 1 + test/stderr/2202 | 2 ++ 5 files changed, 39 insertions(+), 43 deletions(-) diff --git a/src/src/dns.c b/src/src/dns.c index 217fe5f87..490eb883d 100644 --- a/src/src/dns.c +++ b/src/src/dns.c @@ -730,37 +730,37 @@ dns_expire_from_soa(dns_answer * dnsa, int type) { dns_scan dnss; -if (!fake_dnsa_len_for_fail(dnsa, type)) return 0; +if (fake_dnsa_len_for_fail(dnsa, type)) + for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY); + rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT) + ) if (rr->type == T_SOA) + { + const uschar * p = rr->data; + uschar discard_buf[256]; + int len; + unsigned long ttl; + + /* Skip the mname & rname strings */ + + if ((len = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen, + p, (DN_EXPAND_ARG4_TYPE)discard_buf, 256)) < 0) + break; + p += len; + if ((len = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen, + p, (DN_EXPAND_ARG4_TYPE)discard_buf, 256)) < 0) + break; + p += len; + + /* Skip the SOA serial, refresh, retry & expire. Grab the TTL */ + + if (p > dnsa->answer + dnsa->answerlen - 5 * INT32SZ) + break; + p += 4 * INT32SZ; + GETLONG(ttl, p); + + return time(NULL) + ttl; + } -for (dns_record * rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY); - rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT) - ) if (rr->type == T_SOA) - { - const uschar * p = rr->data; - uschar discard_buf[256]; - int len; - unsigned long ttl; - - /* Skip the mname & rname strings */ - - if ((len = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen, - p, (DN_EXPAND_ARG4_TYPE)discard_buf, 256)) < 0) - break; - p += len; - if ((len = dn_expand(dnsa->answer, dnsa->answer + dnsa->answerlen, - p, (DN_EXPAND_ARG4_TYPE)discard_buf, 256)) < 0) - break; - p += len; - - /* Skip the SOA serial, refresh, retry & expire. Grab the TTL */ - - if (p > dnsa->answer + dnsa->answerlen - 5 * INT32SZ) - break; - p += 4 * INT32SZ; - GETLONG(ttl, p); - - return time(NULL) + ttl; - } DEBUG(D_dns) debug_printf("DNS: no SOA record found for neg-TTL\n"); return 0; } @@ -1205,18 +1205,7 @@ switch (type) If the TLD and the 2LD exist but the explicit CSA record lookup failed, then the AUTHORITY SOA will be the 2LD's or a subdomain thereof. */ - if (rc == DNS_NOMATCH) - { - if (!fake_dnsa_len_for_fail(dnsa, T_CSA)) return DNS_NOMATCH; - - for (rr = dns_next_rr(dnsa, &dnss, RESET_AUTHORITY); - rr; rr = dns_next_rr(dnsa, &dnss, RESET_NEXT) - ) - if (rr->type != T_SOA) continue; - else if (strcmpic(rr->name, US"") == 0 || - strcmpic(rr->name, tld) == 0) return DNS_NOMATCH; - else break; - } + if (rc == DNS_NOMATCH) return DNS_NOMATCH; for (i = 0; i < limit; i++) { diff --git a/src/src/string.c b/src/src/string.c index fbb19537c..cb9132420 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -960,7 +960,7 @@ else && (g->ptr == 1 || g->s[g->ptr-2] != '\\') ) g->ptr--; buffer = string_from_gstring(g); - gstring_release_unused_trc(g, func, line); + gstring_release_unused_trc(g, CCS func, line); } /* Update the current pointer and return the new string */ diff --git a/test/stderr/0277 b/test/stderr/0277 index 0cbd2a987..9f606b932 100644 --- a/test/stderr/0277 +++ b/test/stderr/0277 @@ -19,6 +19,7 @@ DNS lookup of 4.3.2.V4NET.in-addr.arpa (PTR) using fakens DNS lookup of 4.3.2.V4NET.in-addr.arpa (PTR) gave HOST_NOT_FOUND returning DNS_NOMATCH DNS: couldn't fake dnsa len +DNS: no SOA record found for neg-TTL writing neg-cache entry for 4.3.2.V4NET.in-addr.arpa-PTR-xxxx, ttl -1 LOG: host_lookup_failed MAIN no host name found for IP address V4NET.2.3.4 @@ -97,6 +98,7 @@ DNS lookup of 12.11.10.V4NET.in-addr.arpa (PTR) using fakens DNS lookup of 12.11.10.V4NET.in-addr.arpa (PTR) gave HOST_NOT_FOUND returning DNS_NOMATCH DNS: couldn't fake dnsa len +DNS: no SOA record found for neg-TTL writing neg-cache entry for 12.11.10.V4NET.in-addr.arpa-PTR-xxxx, ttl -1 LOG: host_lookup_failed MAIN no host name found for IP address V4NET.10.11.12 @@ -142,6 +144,7 @@ DNS lookup of 1.1.1.V4NET.in-addr.arpa (PTR) using fakens DNS lookup of 1.1.1.V4NET.in-addr.arpa (PTR) gave HOST_NOT_FOUND returning DNS_NOMATCH DNS: couldn't fake dnsa len +DNS: no SOA record found for neg-TTL writing neg-cache entry for 1.1.1.V4NET.in-addr.arpa-PTR-xxxx, ttl -1 LOG: host_lookup_failed MAIN no host name found for IP address V4NET.1.1.1 @@ -187,6 +190,7 @@ DNS lookup of 2.2.2.V4NET.in-addr.arpa (PTR) using fakens DNS lookup of 2.2.2.V4NET.in-addr.arpa (PTR) gave HOST_NOT_FOUND returning DNS_NOMATCH DNS: couldn't fake dnsa len +DNS: no SOA record found for neg-TTL writing neg-cache entry for 2.2.2.V4NET.in-addr.arpa-PTR-xxxx, ttl -1 LOG: host_lookup_failed MAIN no host name found for IP address V4NET.2.2.2 diff --git a/test/stderr/0469 b/test/stderr/0469 index f3b559327..4f6d216d2 100644 --- a/test/stderr/0469 +++ b/test/stderr/0469 @@ -25,6 +25,7 @@ DNS lookup of dontqualify (A) using fakens DNS lookup of dontqualify (A) gave NO_DATA returning DNS_NODATA DNS: couldn't fake dnsa len +DNS: no SOA record found for neg-TTL writing neg-cache entry for dontqualify-A-xxxx, ttl -1 fully qualified name = mxt1c.test.ex host_find_bydns yield = HOST_FIND_FAILED (0); returned hosts: diff --git a/test/stderr/2202 b/test/stderr/2202 index a7c78ea3a..3ce137682 100644 --- a/test/stderr/2202 +++ b/test/stderr/2202 @@ -43,6 +43,7 @@ DNS lookup of cioce.test.again.dns (MX) gave TRY_AGAIN cioce.test.again.dns in dns_again_means_nonexist? yes (matched "*") cioce.test.again.dns is in dns_again_means_nonexist: returning DNS_NOMATCH DNS: couldn't fake dnsa len +DNS: no SOA record found for neg-TTL writing neg-cache entry for cioce.test.again.dns-MX-xxxx, ttl -1 creating new cache entry lookup failed @@ -66,6 +67,7 @@ DNS lookup of cioce.test.again.dns (A) gave TRY_AGAIN cioce.test.again.dns in dns_again_means_nonexist? yes (matched "*") cioce.test.again.dns is in dns_again_means_nonexist: returning DNS_NOMATCH DNS: couldn't fake dnsa len +DNS: no SOA record found for neg-TTL writing neg-cache entry for cioce.test.again.dns-A-xxxx, ttl -1 host_fake_gethostbyname(af=inet) returned 1 (HOST_NOT_FOUND) no IP address found for host cioce.test.again.dns (during SMTP connection from the.local.host.name [ip4.ip4.ip4.ip4]) -- 2.30.2