diff --git a/bin/named/config.c b/bin/named/config.c index 53a60d7..ff198e6 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -187,6 +187,8 @@ options {\n\ max-recursion-depth 7;\n\ max-recursion-queries 75;\n\ message-compression yes;\n\ + min-ncache-ttl 0; /* 0 hours */\n\ + min-cache-ttl 0; /* 0 seconds */\n\ # min-roots ;\n\ minimal-any false;\n\ minimal-responses false;\n\ diff --git a/bin/named/server.c b/bin/named/server.c index 4300330..1bbdaf9 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -3731,6 +3731,18 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, if (view->maxncachettl > 7 * 24 * 3600) view->maxncachettl = 7 * 24 * 3600; + obj = NULL; + result = ns_config_get(maps, "min-cache-ttl", &obj); + INSIST(result == ISC_R_SUCCESS); + view->mincachettl = cfg_obj_asuint32(obj); + + obj = NULL; + result = ns_config_get(maps, "min-ncache-ttl", &obj); + INSIST(result == ISC_R_SUCCESS); + view->minncachettl = cfg_obj_asuint32(obj); + if (view->minncachettl > 7 * 24 * 3600) + view->minncachettl = 7 * 24 * 3600; + /* * Configure the view's cache. * diff --git a/bin/tests/named.conf b/bin/tests/named.conf index 5673e98..34435b6 100644 --- a/bin/tests/named.conf +++ b/bin/tests/named.conf @@ -46,6 +46,7 @@ options { memstatistics-file "named.memstats"; // _PATH_MEMSTATS max-cache-ttl 999; + min-cache-ttl 666; auth-nxdomain yes; // always set AA on NXDOMAIN. // don't set this to 'no' unless // you know what you're doing -- older @@ -148,6 +149,7 @@ options { min-refresh-time 777; max-ncache-ttl 333; + min-ncache-ttl 222; min-roots 15; serial-queries 34; diff --git a/lib/dns/include/dns/ncache.h b/lib/dns/include/dns/ncache.h index 2942c26..c2e1e7b 100644 --- a/lib/dns/include/dns/ncache.h +++ b/lib/dns/include/dns/ncache.h @@ -56,12 +56,14 @@ ISC_LANG_BEGINDECLS isc_result_t dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, + dns_rdatatype_t covers, isc_stdtime_t now, + dns_ttl_t minttl, dns_ttl_t maxttl, dns_rdataset_t *addedrdataset); isc_result_t dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, - isc_stdtime_t now, dns_ttl_t maxttl, + isc_stdtime_t now, + dns_ttl_t minttl, dns_ttl_t maxttl, bool optout, dns_rdataset_t *addedrdataset); /*%< * Convert the authority data from 'message' into a negative cache diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index c849dec..2c69acd 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -153,6 +153,8 @@ struct dns_view { bool sendcookie; dns_ttl_t maxcachettl; dns_ttl_t maxncachettl; + dns_ttl_t mincachettl; + dns_ttl_t minncachettl; uint32_t nta_lifetime; uint32_t nta_recheck; char *nta_file; diff --git a/lib/dns/ncache.c b/lib/dns/ncache.c index d71f0d8..7cfb16e 100644 --- a/lib/dns/ncache.c +++ b/lib/dns/ncache.c @@ -45,7 +45,8 @@ static isc_result_t addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, + dns_rdatatype_t covers, isc_stdtime_t now, + dns_ttl_t minttl, dns_ttl_t maxttl, bool optout, bool secure, dns_rdataset_t *addedrdataset); @@ -95,26 +96,29 @@ copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) { isc_result_t dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, + dns_rdatatype_t covers, isc_stdtime_t now, + dns_ttl_t minttl, dns_ttl_t maxttl, dns_rdataset_t *addedrdataset) { - return (addoptout(message, cache, node, covers, now, maxttl, + return (addoptout(message, cache, node, covers, now, minttl, maxttl, false, false, addedrdataset)); } isc_result_t dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, - isc_stdtime_t now, dns_ttl_t maxttl, + isc_stdtime_t now, + dns_ttl_t minttl, dns_ttl_t maxttl, bool optout, dns_rdataset_t *addedrdataset) { - return (addoptout(message, cache, node, covers, now, maxttl, + return (addoptout(message, cache, node, covers, now, minttl, maxttl, optout, true, addedrdataset)); } static isc_result_t addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, + dns_rdatatype_t covers, isc_stdtime_t now, + dns_ttl_t minttl, dns_ttl_t maxttl, bool optout, bool secure, dns_rdataset_t *addedrdataset) { @@ -181,6 +185,8 @@ addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, type == dns_rdatatype_nsec3) { if (ttl > rdataset->ttl) ttl = rdataset->ttl; + if (ttl < minttl) + ttl = minttl; if (trust > rdataset->trust) trust = rdataset->trust; /* diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index e24499e..2cf1645 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -565,7 +565,9 @@ static bool fctx_unlink(fetchctx_t *fctx); static isc_result_t ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, - isc_stdtime_t now, dns_ttl_t maxttl, + isc_stdtime_t now, + dns_ttl_t minttl, + dns_ttl_t maxttl, bool optout, bool secure, dns_rdataset_t *ardataset, @@ -5072,7 +5074,7 @@ validated(isc_task_t *task, isc_event_t *event) { ttl = 0; result = ncache_adderesult(fctx->rmessage, fctx->cache, node, - covers, now, ttl, vevent->optout, + covers, now, fctx->res->view->minncachettl, ttl, vevent->optout, vevent->secure, ardataset, &eresult); if (result != ISC_R_SUCCESS) goto noanswer_response; @@ -5540,6 +5542,12 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo, rdataset->ttl = res->view->maxcachettl; } + /* + * Enforce configured minimum cache TTL. + */ + if (rdataset->ttl < res->view->mincachettl) + rdataset->ttl = res->view->mincachettl; + /* * Mark the rdataset as being prefetch eligible. */ @@ -5928,7 +5936,8 @@ cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now) */ static isc_result_t ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, - dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl, + dns_rdatatype_t covers, isc_stdtime_t now, + dns_ttl_t minttl, dns_ttl_t maxttl, bool optout, bool secure, dns_rdataset_t *ardataset, isc_result_t *eresultp) { @@ -5941,10 +5950,10 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, } if (secure) result = dns_ncache_addoptout(message, cache, node, covers, - now, maxttl, optout, ardataset); + now, minttl, maxttl, optout, ardataset); else result = dns_ncache_add(message, cache, node, covers, now, - maxttl, ardataset); + minttl, maxttl, ardataset); if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) { /* * If the cache now contains a negative entry and we @@ -6119,7 +6128,8 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, ttl = 0; result = ncache_adderesult(fctx->rmessage, fctx->cache, node, - covers, now, ttl, false, + covers, now, ttl, + fctx->res->view->minncachettl, false, false, ardataset, &eresult); if (result != ISC_R_SUCCESS) goto unlock; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 03890a3..2d99ead 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1780,6 +1780,8 @@ view_clauses[] = { { "max-recursion-queries", &cfg_type_uint32, 0 }, { "max-udp-size", &cfg_type_uint32, 0 }, { "message-compression", &cfg_type_boolean, 0 }, + { "min-cache-ttl", &cfg_type_uint32, 0 }, + { "min-ncache-ttl", &cfg_type_uint32, 0 }, { "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP }, { "minimal-any", &cfg_type_boolean, 0 }, { "minimal-responses", &cfg_type_minimal, 0 },