diff options
Diffstat (limited to 'src/resolve/resolved-dns-cache.c')
-rw-r--r-- | src/resolve/resolved-dns-cache.c | 109 |
1 files changed, 51 insertions, 58 deletions
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index eb51b4b895..efc407dbc6 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -458,6 +458,10 @@ int dns_cache_put( if (r > 0) continue; + /* See https://tools.ietf.org/html/rfc2308, which + * say that a matching SOA record in the packet + * is used to to enable negative caching. */ + r = dns_answer_find_soa(answer, q->keys[i], &soa); if (r < 0) goto fail; @@ -483,72 +487,65 @@ fail: return r; } -int dns_cache_lookup(DnsCache *c, DnsQuestion *q, int *rcode, DnsAnswer **ret) { +int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **ret) { _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL; - unsigned i, n = 0; + unsigned n = 0; int r; bool nxdomain = false; + _cleanup_free_ char *key_str = NULL; + DnsCacheItem *j, *first; assert(c); - assert(q); + assert(key); assert(rcode); assert(ret); - if (q->n_keys <= 0) { - *ret = NULL; - *rcode = 0; - return 0; - } + if (key->type == DNS_TYPE_ANY || + key->class == DNS_CLASS_ANY) { - for (i = 0; i < q->n_keys; i++) { - _cleanup_free_ char *key_str = NULL; - DnsCacheItem *j; + /* If we have ANY lookups we simply refresh */ - if (q->keys[i]->type == DNS_TYPE_ANY || - q->keys[i]->class == DNS_CLASS_ANY) { - /* If we have ANY lookups we simply refresh */ + r = dns_resource_key_to_string(key, &key_str); + if (r < 0) + return r; - r = dns_resource_key_to_string(q->keys[i], &key_str); - if (r < 0) - return r; + log_debug("Ignoring cache for ANY lookup: %s", key_str); - log_debug("Ignoring cache for ANY lookup: %s", key_str); + *ret = NULL; + *rcode = DNS_RCODE_SUCCESS; + return 0; + } - *ret = NULL; - *rcode = 0; - return 0; - } + first = hashmap_get(c->by_key, key); + if (!first) { + /* If one question cannot be answered we need to refresh */ - j = hashmap_get(c->by_key, q->keys[i]); - if (!j) { - /* If one question cannot be answered we need to refresh */ + r = dns_resource_key_to_string(key, &key_str); + if (r < 0) + return r; - r = dns_resource_key_to_string(q->keys[i], &key_str); - if (r < 0) - return r; + log_debug("Cache miss for %s", key_str); - log_debug("Cache miss for %s", key_str); + *ret = NULL; + *rcode = DNS_RCODE_SUCCESS; + return 0; + } - *ret = NULL; - *rcode = 0; - return 0; - } else { - r = dns_resource_key_to_string(j->key, &key_str); - if (r < 0) - return r; + LIST_FOREACH(by_key, j, first) { + if (j->rr) + n++; + else if (j->type == DNS_CACHE_NXDOMAIN) + nxdomain = true; + } - log_debug("%s cache hit for %s", - j->type == DNS_CACHE_POSITIVE ? "Positive" : - (j->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN"), key_str); - } + r = dns_resource_key_to_string(key, &key_str); + if (r < 0) + return r; - LIST_FOREACH(by_key, j, j) { - if (j->rr) - n++; - else if (j->type == DNS_CACHE_NXDOMAIN) - nxdomain = true; - } - } + log_debug("%s cache hit for %s", + nxdomain ? "NXDOMAIN" : + n > 0 ? "Positive" : "NODATA", + key_str); if (n <= 0) { *ret = NULL; @@ -560,17 +557,13 @@ int dns_cache_lookup(DnsCache *c, DnsQuestion *q, int *rcode, DnsAnswer **ret) { if (!answer) return -ENOMEM; - for (i = 0; i < q->n_keys; i++) { - DnsCacheItem *j; - - j = hashmap_get(c->by_key, q->keys[i]); - LIST_FOREACH(by_key, j, j) { - if (j->rr) { - r = dns_answer_add(answer, j->rr, 0); - if (r < 0) - return r; - } - } + LIST_FOREACH(by_key, j, first) { + if (!j->rr) + continue; + + r = dns_answer_add(answer, j->rr, 0); + if (r < 0) + return r; } *ret = answer; |