summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-cache.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-12-28 01:16:28 +0100
committerLennart Poettering <lennart@poettering.net>2015-12-28 14:46:39 +0100
commitb211dc7e8368973d726af694e4165045bf0dfc52 (patch)
tree2402a5a8094805b640dd6c2e49853c4bff0ed0a6 /src/resolve/resolved-dns-cache.c
parentee3d6aff9bd73c1b23e29d1fa1fa6f7a1ef0533b (diff)
resolved: also use RRSIG expiry for negative caching
This makes sure that we also honour the RRSIG expiry for negative caching.
Diffstat (limited to 'src/resolve/resolved-dns-cache.c')
-rw-r--r--src/resolve/resolved-dns-cache.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index 413e1080d9..3193985542 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -272,28 +272,40 @@ static DnsCacheItem* dns_cache_get(DnsCache *c, DnsResourceRecord *rr) {
return NULL;
}
-static usec_t calculate_until(DnsResourceRecord *rr, usec_t timestamp) {
- usec_t ttl;
+static usec_t calculate_until(DnsResourceRecord *rr, usec_t timestamp, bool use_soa_minimum) {
+ uint32_t ttl;
+ usec_t u;
assert(rr);
- ttl = rr->ttl * USEC_PER_SEC;
+ ttl = rr->ttl;
+ if (rr->key->type == DNS_TYPE_SOA && use_soa_minimum) {
+ /* If this is a SOA RR, and it is requested, clamp to
+ * the SOA's minimum field. This is used when we do
+ * negative caching, to determine the TTL for the
+ * negative caching entry. See RFC 2308, Section
+ * 5. */
- if (ttl > CACHE_TTL_MAX_USEC)
- ttl = CACHE_TTL_MAX_USEC;
+ if (ttl > rr->soa.minimum)
+ ttl = rr->soa.minimum;
+ }
+
+ u = ttl * USEC_PER_SEC;
+ if (u > CACHE_TTL_MAX_USEC)
+ u = CACHE_TTL_MAX_USEC;
if (rr->expiry != USEC_INFINITY) {
usec_t left;
- /* Make use of the DNSSEC RRSIG expiry info, if we have it */
+ /* Make use of the DNSSEC RRSIG expiry info, if we
+ * have it */
left = LESS_BY(rr->expiry, now(CLOCK_REALTIME));
-
- if (ttl > left)
- ttl = left;
+ if (u > left)
+ u = left;
}
- return timestamp + ttl;
+ return timestamp + u;
}
static void dns_cache_item_update_positive(
@@ -326,7 +338,7 @@ static void dns_cache_item_update_positive(
dns_resource_key_unref(i->key);
i->key = dns_resource_key_ref(rr->key);
- i->until = calculate_until(rr, timestamp);
+ i->until = calculate_until(rr, timestamp, false);
i->authenticated = authenticated;
i->shared_owner = shared_owner;
@@ -407,7 +419,7 @@ static int dns_cache_put_positive(
i->type = DNS_CACHE_POSITIVE;
i->key = dns_resource_key_ref(rr->key);
i->rr = dns_resource_record_ref(rr);
- i->until = calculate_until(rr, timestamp);
+ i->until = calculate_until(rr, timestamp, false);
i->authenticated = authenticated;
i->shared_owner = shared_owner;
i->owner_family = owner_family;
@@ -436,7 +448,7 @@ static int dns_cache_put_negative(
int rcode,
bool authenticated,
usec_t timestamp,
- uint32_t soa_ttl,
+ DnsResourceRecord *soa,
int owner_family,
const union in_addr_union *owner_address) {
@@ -446,6 +458,7 @@ static int dns_cache_put_negative(
assert(c);
assert(key);
+ assert(soa);
assert(owner_address);
/* Never cache pseudo RR keys. DNS_TYPE_ANY is particularly
@@ -456,7 +469,7 @@ static int dns_cache_put_negative(
if (dns_type_is_pseudo(key->type))
return 0;
- if (soa_ttl <= 0) {
+ if (soa->soa.minimum <= 0 || soa->ttl <= 0) {
if (log_get_max_level() >= LOG_DEBUG) {
r = dns_resource_key_to_string(key, &key_str);
if (r < 0)
@@ -482,7 +495,7 @@ static int dns_cache_put_negative(
return -ENOMEM;
i->type = rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA : DNS_CACHE_NXDOMAIN;
- i->until = timestamp + MIN(soa_ttl * USEC_PER_SEC, CACHE_TTL_MAX_USEC);
+ i->until = calculate_until(soa, timestamp, true);
i->authenticated = authenticated;
i->owner_family = owner_family;
i->owner_address = *owner_address;
@@ -656,7 +669,7 @@ int dns_cache_put(
rcode,
authenticated,
timestamp,
- MIN(soa->soa.minimum, soa->ttl),
+ soa,
owner_family, owner_address);
if (r < 0)
goto fail;