max-recursion-queries 75;\n\
max-stale-ttl 604800; /* 1 week */\n\
message-compression yes;\n\
+ min-ncache-ttl 0; /* 0 hours */\n\
+ min-cache-ttl 0; /* 0 seconds */\n\
# min-roots <obsolete>;\n\
minimal-any false;\n\
minimal-responses no-auth-recursive;\n\
result = named_config_get(maps, "max-ncache-ttl", &obj);
INSIST(result == ISC_R_SUCCESS);
view->maxncachettl = cfg_obj_asuint32(obj);
- if (view->maxncachettl > 7 * 24 * 3600)
- view->maxncachettl = 7 * 24 * 3600;
+
+ obj = NULL;
+ result = named_config_get(maps, "min-cache-ttl", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ view->mincachettl = cfg_obj_asuint32(obj);
+
+ obj = NULL;
+ result = named_config_get(maps, "min-ncache-ttl", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ view->minncachettl = cfg_obj_asuint32(obj);
obj = NULL;
result = named_config_get(maps, "synth-from-dnssec", &obj);
memstatistics-file "named.memstats"; // _PATH_MEMSTATS
max-cache-ttl 999;
+ min-cache-ttl 66;
auth-nxdomain yes; // always set AA on NXDOMAIN.
// don't set this to 'no' unless
// you know what you're doing -- older
min-refresh-time 777;
max-ncache-ttl 333;
+ min-ncache-ttl 22;
min-roots 15;
serial-queries 34;
uint32_t lifetime = 3600;
const char *ccalg = "aes";
+ /*
+ * { "name", scale, value }
+ * (scale * value) <= UINT32_MAX
+ */
static intervaltable intervals[] = {
- { "cleaning-interval", 60, 28 * 24 * 60 }, /* 28 days */
- { "heartbeat-interval", 60, 28 * 24 * 60 }, /* 28 days */
- { "interface-interval", 60, 28 * 24 * 60 }, /* 28 days */
- { "max-transfer-idle-in", 60, 28 * 24 * 60 }, /* 28 days */
- { "max-transfer-idle-out", 60, 28 * 24 * 60 }, /* 28 days */
- { "max-transfer-time-in", 60, 28 * 24 * 60 }, /* 28 days */
- { "max-transfer-time-out", 60, 28 * 24 * 60 }, /* 28 days */
- { "statistics-interval", 60, 28 * 24 * 60 }, /* 28 days */
+ { "cleaning-interval", 60, 28 * 24 * 60 }, /* 28 days */
+ { "heartbeat-interval", 60, 28 * 24 * 60 }, /* 28 days */
+ { "interface-interval", 60, 28 * 24 * 60 }, /* 28 days */
+ { "max-transfer-idle-in", 60, 28 * 24 * 60 }, /* 28 days */
+ { "max-transfer-idle-out", 60, 28 * 24 * 60 }, /* 28 days */
+ { "max-transfer-time-in", 60, 28 * 24 * 60 }, /* 28 days */
+ { "max-transfer-time-out", 60, 28 * 24 * 60 }, /* 28 days */
+ { "statistics-interval", 60, 28 * 24 * 60 }, /* 28 days */
+
+ /* minimum and maximum cache and negative cache TTLs */
+ { "min-cache-ttl", 1, MAX_MIN_CACHE_TTL }, /* 90 secs */
+ { "max-cache-ttl", 1, UINT32_MAX }, /* no limit */
+ { "min-ncache-ttl", 1, MAX_MIN_NCACHE_TTL}, /* 90 secs */
+ { "max-ncache-ttl", 1, MAX_MAX_NCACHE_TTL }, /* 7 days */
};
static const char *server_contact[] = {
#include <isccfg/cfg.h>
+#ifndef MAX_MIN_CACHE_TTL
+#define MAX_MIN_CACHE_TTL 90
+#endif /* MAX_MIN_CACHE_TTL */
+
+#ifndef MAX_MIN_NCACHE_TTL
+#define MAX_MIN_NCACHE_TTL 90
+#endif /* MAX_MIN_NCACHE_TTL */
+
+#ifndef MAX_MAX_NCACHE_TTL
+#define MAX_MAX_NCACHE_TTL 7 * 24 * 3600
+#endif /* MAX_MAX_NCACHE_TTL */
+
ISC_LANG_BEGINDECLS
isc_result_t
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
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;
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);
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)
{
if (type == dns_rdatatype_soa ||
type == dns_rdatatype_nsec ||
type == dns_rdatatype_nsec3) {
- if (ttl > rdataset->ttl)
+ if (ttl > rdataset->ttl) {
ttl = rdataset->ttl;
- if (trust > rdataset->trust)
+ }
+ if (ttl < minttl) {
+ ttl = minttl;
+ }
+ if (trust > rdataset->trust) {
trust = rdataset->trust;
+ }
/*
* Copy the owner name to the buffer.
*/
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,
ttl = 0;
result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
- covers, now, ttl, vevent->optout,
- vevent->secure, ardataset, &eresult);
+ covers, now,
+ fctx->res->view->minncachettl, ttl,
+ vevent->optout, vevent->secure,
+ ardataset, &eresult);
if (result != ISC_R_SUCCESS)
goto noanswer_response;
goto answer_response;
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.
*/
*/
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)
{
}
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
ttl = 0;
result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
- covers, now, ttl, false,
- false, ardataset, &eresult);
+ covers, now,
+ fctx->res->view->minncachettl, ttl,
+ false, false, ardataset, &eresult);
if (result != ISC_R_SUCCESS)
goto unlock;
{ "max-stale-ttl", &cfg_type_ttlval, 0 },
{ "max-udp-size", &cfg_type_uint32, 0 },
{ "message-compression", &cfg_type_boolean, 0 },
+ { "min-cache-ttl", &cfg_type_ttlval, 0 },
+ { "min-ncache-ttl", &cfg_type_ttlval, 0 },
{ "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP },
{ "minimal-any", &cfg_type_boolean, 0 },
{ "minimal-responses", &cfg_type_minimal, 0 },