summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2015-12-03 19:53:35 +0100
committerTom Gundersen <teg@jklm.no>2015-12-10 17:06:26 +0100
commit71e136699ce8882d5749b794add7cbb9d282adaa (patch)
tree2eac7547ed3f22a81bcbabc531d31d7c55a5cb87
parent5d27351f8546530cf779847b0b04b0172c09f9d0 (diff)
resolved: cache - don't cache NXDOMAIN by TYPE
An NXDOMAIN entry means there are no RRs of any type for a name, so only cache by CLASS + NAME, rather than CLASS + NAME + TYPE.
-rw-r--r--src/resolve/resolved-dns-cache.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index 008277ab09..9ffbf1d1a6 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -364,6 +364,8 @@ static int dns_cache_put_negative(
if (key->class == DNS_CLASS_ANY)
return 0;
if (key->type == DNS_TYPE_ANY)
+ /* This is particularly important to filter out as we use this as a
+ * pseudo-type for NXDOMAIN entries */
return 0;
if (soa_ttl <= 0) {
r = dns_resource_key_to_string(key, &key_str);
@@ -389,13 +391,21 @@ static int dns_cache_put_negative(
return -ENOMEM;
i->type = rcode == DNS_RCODE_SUCCESS ? DNS_CACHE_NODATA : DNS_CACHE_NXDOMAIN;
- i->key = dns_resource_key_ref(key);
i->until = timestamp + MIN(soa_ttl * USEC_PER_SEC, CACHE_TTL_MAX_USEC);
i->prioq_idx = PRIOQ_IDX_NULL;
i->owner_family = owner_family;
i->owner_address = *owner_address;
i->authenticated = authenticated;
+ if (i->type == DNS_CACHE_NXDOMAIN) {
+ /* NXDOMAIN entries should apply equally to all types, so we use ANY as
+ * a pseudo type for this purpose here. */
+ i->key = dns_resource_key_new(key->class, DNS_TYPE_ANY, DNS_RESOURCE_KEY_NAME(key));
+ if (!i->key)
+ return -ENOMEM;
+ } else
+ i->key = dns_resource_key_ref(key);
+
r = dns_cache_link_item(c, i);
if (r < 0)
return r;
@@ -534,6 +544,12 @@ static DnsCacheItem *dns_cache_get_by_key_follow_cname_dname_nsec(DnsCache *c, D
n = DNS_RESOURCE_KEY_NAME(k);
+ /* Check if we have an NXDOMAIN cache item for the name, notice that we use
+ * the pseudo-type ANY for NXDOMAIN cache items. */
+ i = hashmap_get(c->by_key, &DNS_RESOURCE_KEY_CONST(k->class, DNS_TYPE_ANY, n));
+ if (i && i->type == DNS_CACHE_NXDOMAIN)
+ return i;
+
/* Check if we have an NSEC record instead for the name. */
i = hashmap_get(c->by_key, &DNS_RESOURCE_KEY_CONST(k->class, DNS_TYPE_NSEC, n));
if (i)