Add option for maximum negative cache TTL (#1229599)

This commit is contained in:
Tomas Hozza 2015-06-15 19:20:46 +02:00
parent 6b19dd7ea5
commit 41b8e28ac9
3 changed files with 8923 additions and 1 deletions

View File

@ -0,0 +1,312 @@
From 12d6612439271b2ca5c894ab2edda5364d6c4bfa Mon Sep 17 00:00:00 2001
From: Tomas Hozza <thozza@redhat.com>
Date: Mon, 15 Jun 2015 18:42:10 +0200
Subject: [PATCH 1/2] SOA negative TTL is capped at minimumttl in its rdata
section. - cache-max-negative-ttl config option, default 3600.
git-svn-id: http://unbound.nlnetlabs.nl/svn/trunk@3431 be551aaa-1e26-0410-a405-d3ace91eadb9
Signed-off-by: Tomas Hozza <thozza@redhat.com>
---
doc/example.conf.in | 3 +++
doc/unbound-control.8.in | 3 ++-
doc/unbound.conf.5.in | 4 ++++
testcode/unitmsgparse.c | 3 +++
testdata/iter_domain_sale.rpl | 3 ++-
testdata/iter_domain_sale_nschange.rpl | 6 ++++--
util/config_file.c | 5 +++++
util/config_file.h | 2 ++
util/configlexer.lex | 1 +
util/configparser.y | 12 +++++++++++-
util/data/msgparse.h | 2 ++
util/data/msgreply.c | 29 ++++++++++++++++++++++++++---
12 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/doc/example.conf.in b/doc/example.conf.in
index 60ed5c8..31b965c 100644
--- a/doc/example.conf.in
+++ b/doc/example.conf.in
@@ -135,6 +135,9 @@ server:
# cache. Items are not cached for longer. In seconds.
# cache-max-ttl: 86400
+ # the time to live (TTL) value cap for negative responses in the cache
+ # cache-max-negative-ttl: 3600
+
# the time to live (TTL) value for cached roundtrip times, lameness and
# EDNS version information for hosts. In seconds.
# infra-host-ttl: 900
diff --git a/doc/unbound-control.8.in b/doc/unbound-control.8.in
index f6eae24..749a9fe 100644
--- a/doc/unbound-control.8.in
+++ b/doc/unbound-control.8.in
@@ -177,7 +177,8 @@ harden\-glue, harden\-dnssec\-stripped, harden\-below\-nxdomain,
harden\-referral\-path, prefetch, prefetch\-key, log\-queries,
hide\-identity, hide\-version, identity, version, val\-log\-level,
val\-log\-squelch, ignore\-cd\-flag, add\-holddown, del\-holddown,
-keep\-missing, tcp\-upstream, ssl\-upstream, max\-udp\-size.
+keep\-missing, tcp\-upstream, ssl\-upstream, max\-udp\-size,
+cache\-max\-ttl, cache\-min\-ttl, cache\-max\-negative\-ttl.
.TP
.B get_option \fIopt
Get the value of the option. Give the option name without a trailing ':'.
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
index 9b088f3..5856ae7 100644
--- a/doc/unbound.conf.5.in
+++ b/doc/unbound.conf.5.in
@@ -290,6 +290,10 @@ Zero makes sure the data in the cache is as the domain owner intended,
higher values, especially more than an hour or so, can lead to trouble as
the data in the cache does not match up with the actual data any more.
.TP
+.B cache\-max\-negative\-ttl: \fI<seconds>
+Time to live maximum for negative responses, these have a SOA in the
+authority section that is limited in time. Default is 3600.
+.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.
diff --git a/testcode/unitmsgparse.c b/testcode/unitmsgparse.c
index b33a240..d3d9359 100644
--- a/testcode/unitmsgparse.c
+++ b/testcode/unitmsgparse.c
@@ -497,9 +497,11 @@ testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc,
void msgparse_test(void)
{
+ time_t origttl = MAX_NEG_TTL;
sldns_buffer* pkt = sldns_buffer_new(65553);
sldns_buffer* out = sldns_buffer_new(65553);
struct alloc_cache super_a, alloc;
+ MAX_NEG_TTL = 86400;
/* init */
alloc_init(&super_a, NULL, 0);
alloc_init(&alloc, &super_a, 2);
@@ -536,4 +538,5 @@ void msgparse_test(void)
alloc_clear(&super_a);
sldns_buffer_free(pkt);
sldns_buffer_free(out);
+ MAX_NEG_TTL = origttl;
}
diff --git a/testdata/iter_domain_sale.rpl b/testdata/iter_domain_sale.rpl
index 724b51d..ff61278 100644
--- a/testdata/iter_domain_sale.rpl
+++ b/testdata/iter_domain_sale.rpl
@@ -238,7 +238,8 @@ SECTION QUESTION
nx1.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
-example.com. 3600 IN SOA a. b. 1 2 3 4 5
+; at TTL 5 because TTL is capped at min-ttl of 5 in rdata of SOA
+example.com. 5 IN SOA a. b. 1 2 3 4 5
example.com. 1800 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 1800 IN A 1.2.3.4
diff --git a/testdata/iter_domain_sale_nschange.rpl b/testdata/iter_domain_sale_nschange.rpl
index a7d9f11..bc396f6 100644
--- a/testdata/iter_domain_sale_nschange.rpl
+++ b/testdata/iter_domain_sale_nschange.rpl
@@ -285,7 +285,8 @@ SECTION QUESTION
nx1.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
-example.com. 3600 IN SOA a. b. 1 2 3 4 5
+; at TTL 5 because TTL capped at ttl of minttl in rdata of SOA.
+example.com. 5 IN SOA a. b. 1 2 3 4 5
example.com. 3600 IN NS nsb.example.com.
SECTION ADDITIONAL
nsb.example.com. 3600 IN A 1.2.3.4
@@ -306,7 +307,8 @@ SECTION QUESTION
nx1.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
-example.com. 3600 IN SOA a. b. 1 2 3 4 5
+; at TTL 5 because TTL capped at ttl of minttl in rdata of SOA.
+example.com. 5 IN SOA a. b. 1 2 3 4 5
example.com. 1800 IN NS nsb.example.com.
SECTION ADDITIONAL
nsb.example.com. 3600 IN A 1.2.3.4
diff --git a/util/config_file.c b/util/config_file.c
index 5c4e897..ca29a02 100644
--- a/util/config_file.c
+++ b/util/config_file.c
@@ -131,6 +131,7 @@ config_create(void)
cfg->bogus_ttl = 60;
cfg->min_ttl = 0;
cfg->max_ttl = 3600 * 24;
+ cfg->max_negative_ttl = 3600;
cfg->prefetch = 0;
cfg->prefetch_key = 0;
cfg->infra_cache_slabs = 4;
@@ -378,6 +379,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_YNO("prefetch-key:", prefetch_key)
else if(strcmp(opt, "cache-max-ttl:") == 0)
{ 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-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) {
@@ -629,6 +632,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "prefetch-key", prefetch_key)
else O_YNO(opt, "prefetch", prefetch)
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-ttl", min_ttl)
else O_DEC(opt, "infra-host-ttl", host_ttl)
else O_DEC(opt, "infra-cache-slabs", infra_cache_slabs)
@@ -1198,6 +1202,7 @@ config_apply(struct config_file* config)
{
MAX_TTL = (time_t)config->max_ttl;
MIN_TTL = (time_t)config->min_ttl;
+ MAX_NEG_TTL = (time_t)config->max_negative_ttl;
RTT_MIN_TIMEOUT = config->infra_cache_min_rtt;
EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;
MINIMAL_RESPONSES = config->minimal_responses;
diff --git a/util/config_file.h b/util/config_file.h
index ca512d7..a5cb19b 100644
--- a/util/config_file.h
+++ b/util/config_file.h
@@ -185,6 +185,8 @@ struct config_file {
int max_ttl;
/** the number of seconds minimum TTL used for RRsets and messages */
int min_ttl;
+ /** the number of seconds maximal negative TTL for SOA in auth */
+ int max_negative_ttl;
/** if prefetching of messages should be performed. */
int prefetch;
/** if prefetching of DNSKEYs should be performed. */
diff --git a/util/configlexer.lex b/util/configlexer.lex
index dbde811..1045320 100644
--- a/util/configlexer.lex
+++ b/util/configlexer.lex
@@ -239,6 +239,7 @@ msg-cache-slabs{COLON} { YDVAR(1, VAR_MSG_CACHE_SLABS) }
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-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) }
diff --git a/util/configparser.y b/util/configparser.y
index 396ea3c..825927a 100644
--- a/util/configparser.y
+++ b/util/configparser.y
@@ -118,6 +118,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
+%token VAR_CACHE_MAX_NEGATIVE_TTL
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -177,7 +178,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_minimal_responses | server_rrset_roundrobin | server_max_udp_size |
server_so_reuseport | server_delay_close | server_unblock_lan_zones |
server_dns64_prefix | server_dns64_synthall |
- server_infra_cache_min_rtt
+ server_infra_cache_min_rtt | server_cache_max_negative_ttl
;
stubstart: VAR_STUB_ZONE
{
@@ -991,6 +992,15 @@ server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG
free($2);
}
;
+server_cache_max_negative_ttl: VAR_CACHE_MAX_NEGATIVE_TTL STRING_ARG
+ {
+ OUTYY(("P(server_cache_max_negative_ttl:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("number expected");
+ else cfg_parser->cfg->max_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));
diff --git a/util/data/msgparse.h b/util/data/msgparse.h
index 221a45a..549cc2d 100644
--- a/util/data/msgparse.h
+++ b/util/data/msgparse.h
@@ -76,6 +76,8 @@ struct regional;
extern time_t MAX_TTL;
/** Minimum TTL that is allowed. */
extern time_t MIN_TTL;
+/** Maximum Negative TTL that is allowed */
+extern time_t MAX_NEG_TTL;
/** Negative cache time (for entries without any RRs.) */
#define NORR_TTL 5 /* seconds */
diff --git a/util/data/msgreply.c b/util/data/msgreply.c
index 68bcfd0..d197ad7 100644
--- a/util/data/msgreply.c
+++ b/util/data/msgreply.c
@@ -57,6 +57,8 @@
time_t MAX_TTL = 3600 * 24 * 10; /* ten days */
/** MIN TTL default for messages and rrsets */
time_t MIN_TTL = 0;
+/** MAX Negative TTL, for SOA records in authority section */
+time_t MAX_NEG_TTL = 3600; /* one hour */
/** allocate qinfo, return 0 on error */
static int
@@ -152,10 +154,23 @@ repinfo_alloc_rrset_keys(struct reply_info* rep, struct alloc_cache* alloc,
return 1;
}
+/** find the minimumttl in the rdata of SOA record */
+static time_t
+soa_find_minttl(struct rr_parse* rr)
+{
+ uint16_t rlen = sldns_read_uint16(rr->ttl_data+4);
+ if(rlen < 20)
+ return 0; /* rdata too small for SOA (dname, dname, 5*32bit) */
+ /* minimum TTL is the last 32bit value in the rdata of the record */
+ /* at position ttl_data + 4(ttl) + 2(rdatalen) + rdatalen - 4(timeval)*/
+ return (time_t)sldns_read_uint32(rr->ttl_data+6+rlen-4);
+}
+
/** do the rdata copy */
static int
rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to,
- struct rr_parse* rr, time_t* rr_ttl, uint16_t type)
+ struct rr_parse* rr, time_t* rr_ttl, uint16_t type,
+ sldns_pkt_section section)
{
uint16_t pkt_len;
const sldns_rr_descriptor* desc;
@@ -164,6 +179,14 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to,
/* RFC 2181 Section 8. if msb of ttl is set treat as if zero. */
if(*rr_ttl & 0x80000000U)
*rr_ttl = 0;
+ 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(*rr_ttl > MAX_NEG_TTL)
+ *rr_ttl = MAX_NEG_TTL;
+ }
if(*rr_ttl < MIN_TTL)
*rr_ttl = MIN_TTL;
if(*rr_ttl < data->ttl)
@@ -253,7 +276,7 @@ parse_rr_copy(sldns_buffer* pkt, struct rrset_parse* pset,
data->rr_data[i] = nextrdata;
nextrdata += rr->size;
if(!rdata_copy(pkt, data, data->rr_data[i], rr,
- &data->rr_ttl[i], pset->type))
+ &data->rr_ttl[i], pset->type, pset->section))
return 0;
rr = rr->next;
}
@@ -264,7 +287,7 @@ parse_rr_copy(sldns_buffer* pkt, struct rrset_parse* pset,
data->rr_data[i] = nextrdata;
nextrdata += rr->size;
if(!rdata_copy(pkt, data, data->rr_data[i], rr,
- &data->rr_ttl[i], LDNS_RR_TYPE_RRSIG))
+ &data->rr_ttl[i], LDNS_RR_TYPE_RRSIG, pset->section))
return 0;
rr = rr->next;
}
--
2.4.3

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@
Summary: Validating, recursive, and caching DNS(SEC) resolver Summary: Validating, recursive, and caching DNS(SEC) resolver
Name: unbound Name: unbound
Version: 1.5.3 Version: 1.5.3
Release: 6%{?extra_version:.%{extra_version}}%{?dist} Release: 7%{?extra_version:.%{extra_version}}%{?dist}
License: BSD License: BSD
Url: http://www.nlnetlabs.nl/unbound/ Url: http://www.nlnetlabs.nl/unbound/
Source: http://www.unbound.net/downloads/%{name}-%{version}%{?extra_version}.tar.gz Source: http://www.unbound.net/downloads/%{name}-%{version}%{?extra_version}.tar.gz
@ -49,6 +49,10 @@ Patch0: 0001-Use-print_function-also-for-Python2.patch
Patch1: 0002-libunbound-examples-produce-sorted-output.patch Patch1: 0002-libunbound-examples-produce-sorted-output.patch
Patch2: 0003-libunbound-Python-libldns-is-not-used-anymore.patch Patch2: 0003-libunbound-Python-libldns-is-not-used-anymore.patch
Patch3: 0004-Resolve-Python-3-incompatibilities-in-libunbound-and.patch Patch3: 0004-Resolve-Python-3-incompatibilities-in-libunbound-and.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1229599
# https://www.nlnetlabs.nl/bugs-script/show_bug.cgi?id=675
Patch4: 0001-SOA-negative-TTL-is-capped-at-minimumttl-in-its-rdat.patch
Patch5: 0002-Maximum-negative-TTL-patch-configparser-regeneration.patch
Group: System Environment/Daemons Group: System Environment/Daemons
BuildRequires: flex, openssl-devel BuildRequires: flex, openssl-devel
@ -152,6 +156,8 @@ pushd %{pkgname}_python2
%patch1 -p1 %patch1 -p1
%patch2 -p1 %patch2 -p1
%patch3 -p1 %patch3 -p1
%patch4 -p1
%patch5 -p1
autoreconf -iv autoreconf -iv
@ -436,6 +442,9 @@ popd
%changelog %changelog
* Mon Jun 15 2015 Tomas Hozza <thozza@redhat.com> - 1.5.3-7
- Add option for maximum negative cache TTL (#1229599)
* Tue May 26 2015 Tomas Hozza <thozza@redhat.com> - 1.5.3-6 * Tue May 26 2015 Tomas Hozza <thozza@redhat.com> - 1.5.3-6
- Removed usage of DLV from the default configuration (#1223363) - Removed usage of DLV from the default configuration (#1223363)