From b2597ce86bbd95baf56a3cf422bfd55e5d148c79 Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Wed, 11 Oct 2017 14:24:29 -0700 Subject: [PATCH] [master] ignore cache when sending 5011 refresh queries 4771. [bug] When sending RFC 5011 refresh queries, disregard cached DNSKEY rrsets. [RT #46251] --- CHANGES | 3 +++ lib/dns/include/dns/resolver.h | 1 + lib/dns/resolver.c | 5 +++++ lib/dns/zone.c | 12 +++++++++++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 5d3d40ff27..0a334814cd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4771. [bug] When sending RFC 5011 refresh queries, disregard + cached DNSKEY rrsets. [RT #46251] + 4770. [bug] Cache additional data from priming queries as glue. Previously they were ignored as unsigned non-answer data from a secure zone, and never diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h index 957a7183a9..a5735318e4 100644 --- a/lib/dns/include/dns/resolver.h +++ b/lib/dns/include/dns/resolver.h @@ -97,6 +97,7 @@ typedef enum { #define DNS_FETCHOPT_PREFETCH 0x100 /*%< Do prefetch */ #define DNS_FETCHOPT_NOCDFLAG 0x200 /*%< Don't set CD flag. */ #define DNS_FETCHOPT_NONTA 0x400 /*%< Ignore NTA table. */ +#define DNS_FETCHOPT_NOCACHED 0x800 /*%< Force cache update. */ /* Reserved in use by adb.c 0x00400000 */ #define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000 diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 66d0153561..a153817974 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -5863,6 +5863,11 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, { options = DNS_DBADD_PREFETCH; } + if ((fctx->options & + DNS_FETCHOPT_NOCACHED) != 0) + { + options |= DNS_DBADD_FORCE; + } addedrdataset = ardataset; result = dns_db_addrdataset(fctx->cache, node, NULL, now, rdataset, diff --git a/lib/dns/zone.c b/lib/dns/zone.c index d0da729750..4966de4cc3 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -9754,11 +9754,21 @@ zone_refreshkeys(dns_zone_t *zone) { namebuf); } + /* + * Use of DNS_FETCHOPT_NOCACHED is essential here. If it is + * not set and the cache still holds a non-expired, validated + * version of the RRset being queried for by the time the + * response is received, the cached RRset will be passed to + * keyfetch_done() instead of the one received in the response + * as the latter will have a lower trust level due to not being + * validated until keyfetch_done() is called. + */ result = dns_resolver_createfetch(zone->view->resolver, kname, dns_rdatatype_dnskey, NULL, NULL, NULL, DNS_FETCHOPT_NOVALIDATE| - DNS_FETCHOPT_UNSHARED, + DNS_FETCHOPT_UNSHARED| + DNS_FETCHOPT_NOCACHED, zone->task, keyfetch_done, kfetch, &kfetch->dnskeyset,