summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-cache.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-08-21 22:55:01 +0200
committerLennart Poettering <lennart@poettering.net>2015-08-21 22:55:01 +0200
commitf52e61da047d7fc74e83f12dbbf87e0cbcc51c73 (patch)
tree477d5ab7d178f3530699afc31b97a61b014d8e11 /src/resolve/resolved-dns-cache.c
parent9e08a6e0ce6ae37189666fd2517e643e971e45b1 (diff)
resolved: only maintain one question RR key per transaction
Let's simplify things and only maintain a single RR key per transaction object, instead of a full DnsQuestion. Unicast DNS and LLMNR don't support multiple questions per packet anway, and Multicast DNS suggests coalescing questions beyond a single dns query, across the whole system.
Diffstat (limited to 'src/resolve/resolved-dns-cache.c')
-rw-r--r--src/resolve/resolved-dns-cache.c105
1 files changed, 47 insertions, 58 deletions
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index 751e961351..efc407dbc6 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -487,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;
@@ -564,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;