- Introduce 'cache-min-negative-ttl' option to bound the minimum TTL for

negative answers overriding 'cache-min-ttl'.
This commit is contained in:
Yorgos Thessalonikefs 2024-03-12 11:20:44 +01:00
parent 320d0a5f1b
commit 025881d0e9
10 changed files with 466 additions and 12 deletions

View File

@ -211,6 +211,11 @@ server:
# the time to live (TTL) value cap for negative responses in the cache
# cache-max-negative-ttl: 3600
# the time to live (TTL) value lower bound, in seconds. Default 0.
# For negative responses in the cache. If disabled, default,
# cache-min-tll applies if configured.
# cache-min-negative-ttl: 0
# the time to live (TTL) value for cached roundtrip times, lameness and
# EDNS version information for hosts. In seconds.
# infra-host-ttl: 900

View File

@ -388,6 +388,15 @@ Time to live maximum for negative responses, these have a SOA in the
authority section that is limited in time. Default is 3600.
This applies to nxdomain and nodata answers.
.TP
.B cache\-min\-negative\-ttl: \fI<seconds>
Time to live minimum for negative responses, these have a SOA in the
authority section that is limited in time.
Default is 0 (disabled).
If this is disabled and \fBcache-min-ttl\fR is configured, it will take effect
instead.
In that case you can set this to 1 to honor the upstream TTL.
This applies to nxdomain and nodata answers.
.TP
.B infra\-host\-ttl: \fI<seconds>
Time to live for entries in the host cache. The host cache contains
roundtrip timing, lameness and EDNS support information. Default is 900.

206
testdata/ttl_max_negative.rpl vendored Normal file
View File

@ -0,0 +1,206 @@
; config options
server:
access-control: 127.0.0.1 allow_snoop
cache-max-ttl: 15 # This will be overriden
cache-max-negative-ttl: 10
qname-minimisation: "no"
minimal-responses: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test TTL max option for messages in the cache
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN A
SECTION ANSWER
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN A
SECTION ANSWER
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.4
SECTION AUTHORITY
example.com. IN NS ns.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. 3600 IN SOA . . 15 28800 7200 604800 3600
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. 3600 IN SOA . . 15 28800 7200 604800 3600
ENTRY_END
RANGE_END
; start by passing time ; so we are not at 0
STEP 1 TIME_PASSES ELAPSE 10
; query for the record
STEP 8 QUERY
ENTRY_BEGIN
REPLY RD CD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA CD NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
example.com. 10 IN SOA . . 15 28800 7200 604800 3600
ENTRY_END
; wait
STEP 20 TIME_PASSES ELAPSE 5
; do a lookup to check TTLs.
STEP 25 QUERY
ENTRY_BEGIN
REPLY
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 26 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RA NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
example.com. 5 IN SOA . . 15 28800 7200 604800 3600
ENTRY_END
SCENARIO_END

204
testdata/ttl_min_negative.rpl vendored Normal file
View File

@ -0,0 +1,204 @@
; config options
server:
access-control: 127.0.0.1 allow_snoop
cache-min-ttl: 5 # This will be overriden
cache-min-negative-ttl: 10
qname-minimisation: "no"
minimal-responses: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test TTL min option for messages in the cache
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN A
SECTION ANSWER
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN A
SECTION ANSWER
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
a.gtld-servers.net. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
K.ROOT-SERVERS.NET. IN AAAA
SECTION AUTHORITY
. 86400 IN SOA . . 20070304 28800 7200 604800 86400
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
SECTION ANSWER
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.4
SECTION AUTHORITY
example.com. IN NS ns.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. 1 IN SOA . . 15 28800 7200 604800 1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. 1 IN SOA . . 15 28800 7200 604800 1
ENTRY_END
RANGE_END
; start by passing time ; so we are not at 0
STEP 1 TIME_PASSES ELAPSE 10
; query for the record
STEP 8 QUERY
ENTRY_BEGIN
REPLY RD CD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA CD NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. 10 IN SOA . . 15 28800 7200 604800 1
ENTRY_END
; wait for 7 seconds
STEP 20 TIME_PASSES ELAPSE 7
; do a lookup to check TTLs.
STEP 25 QUERY
ENTRY_BEGIN
REPLY
SECTION QUESTION
www.example.com. IN A
ENTRY_END
STEP 26 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RA NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. 3 IN SOA . . 15 28800 7200 604800 1
ENTRY_END
SCENARIO_END

View File

@ -174,6 +174,7 @@ config_create(void)
cfg->min_ttl = 0;
cfg->max_ttl = 3600 * 24;
cfg->max_negative_ttl = 3600;
cfg->min_negative_ttl = 0;
cfg->prefetch = 0;
cfg->prefetch_key = 0;
cfg->deny_any = 0;
@ -615,6 +616,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
{ IS_NUMBER_OR_ZERO; cfg->max_ttl = atoi(val); MAX_TTL=(time_t)cfg->max_ttl;}
else if(strcmp(opt, "cache-max-negative-ttl:") == 0)
{ IS_NUMBER_OR_ZERO; cfg->max_negative_ttl = atoi(val); MAX_NEG_TTL=(time_t)cfg->max_negative_ttl;}
else if(strcmp(opt, "cache-min-negative-ttl:") == 0)
{ IS_NUMBER_OR_ZERO; cfg->min_negative_ttl = atoi(val); MIN_NEG_TTL=(time_t)cfg->min_negative_ttl;}
else if(strcmp(opt, "cache-min-ttl:") == 0)
{ IS_NUMBER_OR_ZERO; cfg->min_ttl = atoi(val); MIN_TTL=(time_t)cfg->min_ttl;}
else if(strcmp(opt, "infra-cache-min-rtt:") == 0) {
@ -1065,6 +1068,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "deny-any", deny_any)
else O_DEC(opt, "cache-max-ttl", max_ttl)
else O_DEC(opt, "cache-max-negative-ttl", max_negative_ttl)
else O_DEC(opt, "cache-min-negative-ttl", min_negative_ttl)
else O_DEC(opt, "cache-min-ttl", min_ttl)
else O_DEC(opt, "infra-host-ttl", host_ttl)
else O_DEC(opt, "infra-cache-slabs", infra_cache_slabs)
@ -2310,6 +2314,7 @@ config_apply(struct config_file* config)
SERVE_EXPIRED_REPLY_TTL = (time_t)config->serve_expired_reply_ttl;
SERVE_ORIGINAL_TTL = config->serve_original_ttl;
MAX_NEG_TTL = (time_t)config->max_negative_ttl;
MIN_NEG_TTL = (time_t)config->min_negative_ttl;
RTT_MIN_TIMEOUT = config->infra_cache_min_rtt;
RTT_MAX_TIMEOUT = config->infra_cache_max_rtt;
EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;

View File

@ -315,6 +315,8 @@ struct config_file {
int min_ttl;
/** the number of seconds maximal negative TTL for SOA in auth */
int max_negative_ttl;
/** the number of seconds minimal negative TTL for SOA in auth */
int min_negative_ttl;
/** if prefetching of messages should be performed. */
int prefetch;
/** if prefetching of DNSKEYs should be performed. */

View File

@ -297,6 +297,7 @@ rrset-cache-size{COLON} { YDVAR(1, VAR_RRSET_CACHE_SIZE) }
rrset-cache-slabs{COLON} { YDVAR(1, VAR_RRSET_CACHE_SLABS) }
cache-max-ttl{COLON} { YDVAR(1, VAR_CACHE_MAX_TTL) }
cache-max-negative-ttl{COLON} { YDVAR(1, VAR_CACHE_MAX_NEGATIVE_TTL) }
cache-min-negative-ttl{COLON} { YDVAR(1, VAR_CACHE_MIN_NEGATIVE_TTL) }
cache-min-ttl{COLON} { YDVAR(1, VAR_CACHE_MIN_TTL) }
infra-host-ttl{COLON} { YDVAR(1, VAR_INFRA_HOST_TTL) }
infra-lame-ttl{COLON} { YDVAR(1, VAR_INFRA_LAME_TTL) }

View File

@ -153,6 +153,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_MIN_CLIENT_SUBNET_IPV4 VAR_MIN_CLIENT_SUBNET_IPV6
%token VAR_MAX_ECS_TREE_SIZE_IPV4 VAR_MAX_ECS_TREE_SIZE_IPV6
%token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN
%token VAR_CACHE_MIN_NEGATIVE_TTL
%token VAR_QNAME_MINIMISATION VAR_QNAME_MINIMISATION_STRICT VAR_IP_FREEBIND
%token VAR_DEFINE_TAG VAR_LOCAL_ZONE_TAG VAR_ACCESS_CONTROL_TAG
%token VAR_LOCAL_ZONE_OVERRIDE VAR_ACCESS_CONTROL_TAG_ACTION
@ -298,6 +299,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_min_client_subnet_ipv4 | server_min_client_subnet_ipv6 |
server_max_ecs_tree_size_ipv4 | server_max_ecs_tree_size_ipv6 |
server_caps_whitelist | server_cache_max_negative_ttl |
server_cache_min_negative_ttl |
server_permit_small_holddown | server_qname_minimisation |
server_ip_freebind | server_define_tag | server_local_zone_tag |
server_disable_dnssec_lame_check | server_access_control_tag |
@ -2014,6 +2016,15 @@ server_cache_max_negative_ttl: VAR_CACHE_MAX_NEGATIVE_TTL STRING_ARG
free($2);
}
;
server_cache_min_negative_ttl: VAR_CACHE_MIN_NEGATIVE_TTL STRING_ARG
{
OUTYY(("P(server_cache_min_negative_ttl:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("number expected");
else cfg_parser->cfg->min_negative_ttl = atoi($2);
free($2);
}
;
server_cache_min_ttl: VAR_CACHE_MIN_TTL STRING_ARG
{
OUTYY(("P(server_cache_min_ttl:%s)\n", $2));

View File

@ -82,6 +82,8 @@ extern time_t MAX_TTL;
extern time_t MIN_TTL;
/** Maximum Negative TTL that is allowed */
extern time_t MAX_NEG_TTL;
/** Minimum Negative TTL that is allowed */
extern time_t MIN_NEG_TTL;
/** If we serve expired entries and prefetch them */
extern int SERVE_EXPIRED;
/** Time to serve records after expiration */

View File

@ -61,6 +61,8 @@ time_t MAX_TTL = 3600 * 24 * 10; /* ten days */
time_t MIN_TTL = 0;
/** MAX Negative TTL, for SOA records in authority section */
time_t MAX_NEG_TTL = 3600; /* one hour */
/** MIN Negative TTL, for SOA records in authority section */
time_t MIN_NEG_TTL = 0;
/** If we serve expired entries and prefetch them */
int SERVE_EXPIRED = 0;
/** Time to serve records after expiration */
@ -223,18 +225,25 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to,
if(type == LDNS_RR_TYPE_SOA && section == LDNS_SECTION_AUTHORITY) {
/* negative response. see if TTL of SOA record larger than the
* minimum-ttl in the rdata of the SOA record */
if(*rr_ttl > soa_find_minttl(rr))
*rr_ttl = soa_find_minttl(rr);
}
if(!SERVE_ORIGINAL_TTL && (*rr_ttl < MIN_TTL))
*rr_ttl = MIN_TTL;
if(!SERVE_ORIGINAL_TTL && (*rr_ttl > MAX_TTL))
*rr_ttl = MAX_TTL;
if(type == LDNS_RR_TYPE_SOA && section == LDNS_SECTION_AUTHORITY) {
/* max neg ttl overrides the min and max ttl of everything
* else, it is for a more specific record */
if(*rr_ttl > MAX_NEG_TTL)
*rr_ttl = MAX_NEG_TTL;
if(*rr_ttl > soa_find_minttl(rr)) *rr_ttl = soa_find_minttl(rr);
if(!SERVE_ORIGINAL_TTL) {
/* If MIN_NEG_TTL is configured skip setting MIN_TTL */
if(MIN_NEG_TTL <= 0 && *rr_ttl < MIN_TTL) {
*rr_ttl = MIN_TTL;
}
if(*rr_ttl > MAX_TTL) *rr_ttl = MAX_TTL;
}
/* MAX_NEG_TTL overrides the min and max ttl of everything
* else; it is for a more specific record */
if(*rr_ttl > MAX_NEG_TTL) *rr_ttl = MAX_NEG_TTL;
/* MIN_NEG_TTL overrides the min and max ttl of everything
* else if configured; it is for a more specific record */
if(MIN_NEG_TTL > 0 && *rr_ttl < MIN_NEG_TTL) {
*rr_ttl = MIN_NEG_TTL;
}
} else if(!SERVE_ORIGINAL_TTL) {
if(*rr_ttl < MIN_TTL) *rr_ttl = MIN_TTL;
if(*rr_ttl > MAX_TTL) *rr_ttl = MAX_TTL;
}
if(*rr_ttl < data->ttl)
data->ttl = *rr_ttl;