diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-12-18 14:37:06 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-12-18 14:48:50 +0100 |
commit | 105e151299dc1208855380be2b22d0db2d66ebc6 (patch) | |
tree | 254ef03b5b77375bfb11a483e5c6030eb6ed86e7 /src/resolve/resolved-dns-cache.c | |
parent | aae6a86e1af88db640180de824e064069a448aeb (diff) |
resolved: add support NSEC3 proofs, as well as proofs for domains that are OK to be unsigned
This large patch adds a couple of mechanisms to ensure we get NSEC3 and
proof-of-unsigned support into place. Specifically:
- Each item in an DnsAnswer gets two bit flags now:
DNS_ANSWER_AUTHENTICATED and DNS_ANSWER_CACHEABLE. The former is
necessary since DNS responses might contain signed as well as unsigned
RRsets in one, and we need to remember which ones are signed and which
ones aren't. The latter is necessary, since not we need to keep track
which RRsets may be cached and which ones may not be, even while
manipulating DnsAnswer objects.
- The .n_answer_cachable of DnsTransaction is dropped now (it used to
store how many of the first DnsAnswer entries are cachable), and
replaced by the DNS_ANSWER_CACHABLE flag instead.
- NSEC3 proofs are implemented now (lacking support for the wildcard
part, to be added in a later commit).
- Support for the "AD" bit has been dropped. It's unsafe, and now that
we have end-to-end authentication we don't need it anymore.
- An auxiliary DnsTransaction of a DnsTransactions is now kept around as
least as long as the latter stays around. We no longer remove the
auxiliary DnsTransaction as soon as it completed. THis is necessary,
as we now are interested not only in the RRsets it acquired but also
in its authentication status.
Diffstat (limited to 'src/resolve/resolved-dns-cache.c')
-rw-r--r-- | src/resolve/resolved-dns-cache.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c index 62713b5a6a..a8d612794c 100644 --- a/src/resolve/resolved-dns-cache.c +++ b/src/resolve/resolved-dns-cache.c @@ -436,14 +436,14 @@ int dns_cache_put( DnsResourceKey *key, int rcode, DnsAnswer *answer, - unsigned max_rrs, bool authenticated, usec_t timestamp, int owner_family, const union in_addr_union *owner_address) { DnsResourceRecord *soa = NULL, *rr; - unsigned cache_keys, i; + DnsAnswerFlags flags; + unsigned cache_keys; int r; assert(c); @@ -468,9 +468,13 @@ int dns_cache_put( return 0; } - DNS_ANSWER_FOREACH(rr, answer) + DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) { + if ((flags & DNS_ANSWER_CACHEABLE) == 0) + continue; + if (rr->key->cache_flush) dns_cache_remove(c, rr->key); + } /* We only care for positive replies and NXDOMAINs, on all * other replies we will simply flush the respective entries, @@ -480,7 +484,6 @@ int dns_cache_put( return 0; cache_keys = answer->n_rrs; - if (key) cache_keys ++; @@ -491,10 +494,12 @@ int dns_cache_put( timestamp = now(clock_boottime_or_monotonic()); /* Second, add in positive entries for all contained RRs */ - for (i = 0; i < MIN(max_rrs, answer->n_rrs); i++) { - rr = answer->items[i].rr; - r = dns_cache_put_positive(c, rr, authenticated, timestamp, owner_family, owner_address); + DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) { + if ((flags & DNS_ANSWER_CACHEABLE) == 0) + continue; + + r = dns_cache_put_positive(c, rr, flags & DNS_ANSWER_AUTHENTICATED, timestamp, owner_family, owner_address); if (r < 0) goto fail; } @@ -503,7 +508,7 @@ int dns_cache_put( return 0; /* Third, add in negative entries if the key has no RR */ - r = dns_answer_match_key(answer, key); + r = dns_answer_match_key(answer, key, NULL); if (r < 0) goto fail; if (r > 0) @@ -512,7 +517,7 @@ int dns_cache_put( /* But not if it has a matching CNAME/DNAME (the negative * caching will be done on the canonical name, not on the * alias) */ - r = dns_answer_find_cname_or_dname(answer, key, NULL); + r = dns_answer_find_cname_or_dname(answer, key, NULL, NULL); if (r < 0) goto fail; if (r > 0) @@ -541,8 +546,12 @@ fail: if (key) dns_cache_remove(c, key); - for (i = 0; i < answer->n_rrs; i++) - dns_cache_remove(c, answer->items[i].rr->key); + DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) { + if ((flags & DNS_ANSWER_CACHEABLE) == 0) + continue; + + dns_cache_remove(c, rr->key); + } return r; } @@ -722,7 +731,7 @@ int dns_cache_lookup(DnsCache *c, DnsResourceKey *key, int *rcode, DnsAnswer **r if (!j->rr) continue; - r = dns_answer_add(answer, j->rr, 0); + r = dns_answer_add(answer, j->rr, 0, have_authenticated && !have_non_authenticated ? DNS_ANSWER_AUTHENTICATED : 0); if (r < 0) return r; } |