summaryrefslogtreecommitdiff
path: root/src/resolve/resolved-dns-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/resolve/resolved-dns-cache.c')
-rw-r--r--src/resolve/resolved-dns-cache.c81
1 files changed, 72 insertions, 9 deletions
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index efc407dbc6..ef6b69c768 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -411,16 +411,17 @@ int dns_cache_put(
int owner_family,
const union in_addr_union *owner_address) {
- unsigned i;
+ unsigned cache_keys, i;
int r;
assert(c);
- assert(q);
- /* First, delete all matching old RRs, so that we only keep
- * complete by_key in place. */
- for (i = 0; i < q->n_keys; i++)
- dns_cache_remove(c, q->keys[i]);
+ if (q) {
+ /* First, if we were passed a question, delete all matching old RRs,
+ * so that we only keep complete by_key in place. */
+ for (i = 0; i < q->n_keys; i++)
+ dns_cache_remove(c, q->keys[i]);
+ }
if (!answer)
return 0;
@@ -435,8 +436,13 @@ int dns_cache_put(
if (!IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN))
return 0;
+ cache_keys = answer->n_rrs;
+
+ if (q)
+ cache_keys += q->n_keys;
+
/* Make some space for our new entries */
- dns_cache_make_space(c, answer->n_rrs + q->n_keys);
+ dns_cache_make_space(c, cache_keys);
if (timestamp <= 0)
timestamp = now(clock_boottime_or_monotonic());
@@ -448,6 +454,9 @@ int dns_cache_put(
goto fail;
}
+ if (!q)
+ return 0;
+
/* Third, add in negative entries for all keys with no RR */
for (i = 0; i < q->n_keys; i++) {
DnsResourceRecord *soa = NULL;
@@ -479,8 +488,11 @@ fail:
/* Adding all RRs failed. Let's clean up what we already
* added, just in case */
- for (i = 0; i < q->n_keys; i++)
- dns_cache_remove(c, q->keys[i]);
+ if (q) {
+ for (i = 0; i < q->n_keys; i++)
+ dns_cache_remove(c, q->keys[i]);
+ }
+
for (i = 0; i < answer->n_rrs; i++)
dns_cache_remove(c, answer->items[i].rr->key);
@@ -608,3 +620,54 @@ int dns_cache_check_conflicts(DnsCache *cache, DnsResourceRecord *rr, int owner_
/* There's a conflict */
return 1;
}
+
+void dns_cache_dump(DnsCache *cache, FILE *f) {
+ Iterator iterator;
+ DnsCacheItem *i;
+ int r;
+
+ if (!cache)
+ return;
+
+ if (!f)
+ f = stdout;
+
+ HASHMAP_FOREACH(i, cache->by_key, iterator) {
+ DnsCacheItem *j;
+
+ LIST_FOREACH(by_key, j, i) {
+ _cleanup_free_ char *t = NULL;
+
+ fputc('\t', f);
+
+ if (j->rr) {
+ r = dns_resource_record_to_string(j->rr, &t);
+ if (r < 0) {
+ log_oom();
+ continue;
+ }
+
+ fputs(t, f);
+ fputc('\n', f);
+ } else {
+ r = dns_resource_key_to_string(j->key, &t);
+ if (r < 0) {
+ log_oom();
+ continue;
+ }
+
+ fputs(t, f);
+ fputs(" -- ", f);
+ fputs(j->type == DNS_CACHE_NODATA ? "NODATA" : "NXDOMAIN", f);
+ fputc('\n', f);
+ }
+ }
+ }
+}
+
+bool dns_cache_is_empty(DnsCache *cache) {
+ if (!cache)
+ return true;
+
+ return hashmap_isempty(cache->by_key);
+}