From a5166d5fce30e5924f279d3e92d1f20b9fb7b4dc Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 4 Nov 2011 03:38:44 +0000 Subject: [PATCH] 3202. [bug] NOEDNS caching on timeout was too agressive. [RT #26416] --- CHANGES | 3 +++ lib/dns/include/dns/resolver.h | 5 ++++- lib/dns/resolver.c | 39 +++++++++++++++++++++++++--------- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 0808b39d81..f9b9a91f7c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3202. [bug] NOEDNS caching on timeout was too agressive. + [RT #26416] + 3201. [func] 'rndc querylog' can now be given an on/off parameter instead of only being used as a toggle. [RT #18351] diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h index cbf63dff5e..ec676ee888 100644 --- a/lib/dns/include/dns/resolver.h +++ b/lib/dns/include/dns/resolver.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.h,v 1.69 2011/02/03 12:18:11 tbox Exp $ */ +/* $Id: resolver.h,v 1.70 2011/11/04 03:38:44 marka Exp $ */ #ifndef DNS_RESOLVER_H #define DNS_RESOLVER_H 1 @@ -96,6 +96,9 @@ typedef struct dns_fetchevent { #define DNS_FETCHOPT_EDNS512 0x40 /*%< Advertise a 512 byte UDP buffer. */ #define DNS_FETCHOPT_WANTNSID 0x80 /*%< Request NSID */ +#define DNS_FETCHOPT_CACHENOEDNS 0x100A /*%< This is a candidate + for setting NOEDNS + in adb. */ #define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000 #define DNS_FETCHOPT_EDNSVERSIONMASK 0xff000000 diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index d0269535ec..99bd7bd011 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.438 2011/11/02 23:42:33 marka Exp $ */ +/* $Id: resolver.c,v 1.439 2011/11/04 03:38:44 marka Exp $ */ /*! \file */ @@ -1846,6 +1846,7 @@ resquery_send(resquery_t *query) { fctx->timeouts > MAX_EDNS0_TIMEOUTS) && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { query->options |= DNS_FETCHOPT_NOEDNS0; + query->options |= DNS_FETCHOPT_CACHENOEDNS; fctx->reason = "disabling EDNS"; } else if ((triededns(fctx, &query->addrinfo->sockaddr) || fctx->timeouts >= 1) && @@ -1917,21 +1918,18 @@ resquery_send(resquery_t *query) { goto cleanup_message; } - if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) + if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { add_triededns(fctx, &query->addrinfo->sockaddr); - if ((query->options & DNS_FETCHOPT_EDNS512) != 0) - add_triededns512(fctx, &query->addrinfo->sockaddr); + if ((query->options & DNS_FETCHOPT_EDNS512) != 0) + add_triededns512(fctx, &query->addrinfo->sockaddr); + } /* - * Clear CD if EDNS is not in use and set NOEDNS0 in adb. + * Clear CD if EDNS is not in use. */ - if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0) { + if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0) fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD; - dns_adb_changeflags(fctx->adb, query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); - } /* * Add TSIG record tailored to the current recipient. @@ -6580,6 +6578,23 @@ resquery_response(isc_task_t *task, isc_event_t *event) { } } goto done; + } else if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0 && + (query->options & DNS_FETCHOPT_CACHENOEDNS) != 0 && + triededns512(fctx, &query->addrinfo->sockaddr)) { + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, + sizeof(addrbuf)); + /* + * We had a successful response to a DNS_FETCHOPT_NOEDNS0 + * query. + */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED, + DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, + "%s: setting NOEDNS flag in adb cache for '%s'", + fctx->info, addrbuf); + dns_adb_changeflags(fctx->adb, query->addrinfo, + DNS_FETCHOPT_NOEDNS0, + DNS_FETCHOPT_NOEDNS0); } message = fctx->rmessage; @@ -6723,6 +6738,10 @@ resquery_response(isc_task_t *task, isc_event_t *event) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, sizeof(addrbuf)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED, + DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, + "%s: changed rcode: setting NOEDNS flag in " + "adb cache for '%s'", fctx->info, addrbuf); dns_adb_changeflags(fctx->adb, query->addrinfo, DNS_FETCHOPT_NOEDNS0, DNS_FETCHOPT_NOEDNS0);