From f5bdeb01e4c9f479aaa31cebfa6cfa85ae8a7336 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Dec 2015 19:22:26 +0100 Subject: resolved: when receiving a TTL=0 RR, only flush that specific RR When we receieve a TTL=0 RR, then let's only flush that specific RR and not the whole RRset. On mDNS with RRsets that a shared-owner this is how specific RRs are removed from the set, hence support this. And on non-mDNS the whole RRset will already be removed much earlier in dns_cache_put() hence there's no reason remove it again. --- src/resolve/resolved-dns-cache.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'src/resolve/resolved-dns-cache.c') diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 2e3090b32a..e8e349748a 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -100,6 +100,24 @@ void dns_cache_flush(DnsCache *c) { c->by_expiry = prioq_free(c->by_expiry); } +static bool dns_cache_remove_by_rr(DnsCache *c, DnsResourceRecord *rr) { + DnsCacheItem *first, *i; + int r; + + first = hashmap_get(c->by_key, rr->key); + LIST_FOREACH(by_key, i, first) { + r = dns_resource_record_equal(i->rr, rr); + if (r < 0) + return r; + if (r > 0) { + dns_cache_item_remove_and_free(c, i); + return true; + } + } + + return false; +} + static bool dns_cache_remove(DnsCache *c, DnsResourceKey *key) { DnsCacheItem *first, *i, *n; @@ -291,9 +309,9 @@ static int dns_cache_put_positive( if (dns_type_is_pseudo(rr->key->type)) return 0; - /* New TTL is 0? Delete the entry... */ + /* New TTL is 0? Delete this specific entry... */ if (rr->ttl <= 0) { - k = dns_cache_remove(c, rr->key); + k = dns_cache_remove_by_rr(c, rr); if (log_get_max_level() >= LOG_DEBUG) { r = dns_resource_key_to_string(rr->key, &key_str); -- cgit v1.2.3-54-g00ecf