From 79e249313887840e0fc52f69afc0daeed754bff1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 11 Dec 2015 13:36:25 +0100 Subject: [PATCH] resolved: rework how and when the number of answer RRs to cache is determined Instead of figuring out how many RRs to cache right before we do so, determine this at the time we install the answer RRs, so that we can still alter this as we manipulate the answer during validation. The primary purpose of this is to pave the way so that we can drop unsigned RRsets from the answer and invalidate the number of RRs to cache at the same time. --- src/resolve/resolved-dns-transaction.c | 27 ++++++++++++++------------ src/resolve/resolved-dns-transaction.h | 1 + 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 5cd03bc01d..7e8f4d888b 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -351,6 +351,7 @@ static int dns_transaction_open_tcp(DnsTransaction *t) { t->server = dns_server_ref(server); t->received = dns_packet_unref(t->received); t->answer = dns_answer_unref(t->answer); + t->n_answer_cacheable = 0; t->answer_rcode = 0; t->stream->complete = on_stream_complete; t->stream->transaction = t; @@ -375,8 +376,6 @@ static void dns_transaction_next_dns_server(DnsTransaction *t) { } static void dns_transaction_cache_answer(DnsTransaction *t) { - unsigned n_cache; - assert(t); /* For mDNS we cache whenever we get the packet, rather than @@ -391,20 +390,11 @@ static void dns_transaction_cache_answer(DnsTransaction *t) { if (!DNS_PACKET_SHALL_CACHE(t->received)) return; - /* According to RFC 4795, section 2.9. only the RRs from the - * answer section shall be cached. However, if we know the - * message is authenticated, we might as well cache - * everything. */ - if (t->answer_authenticated) - n_cache = dns_answer_size(t->answer); - else - n_cache = DNS_PACKET_ANCOUNT(t->received); - dns_cache_put(&t->scope->cache, t->key, t->answer_rcode, t->answer, - n_cache, + t->n_answer_cacheable, t->answer_authenticated, 0, t->received->family, @@ -618,6 +608,15 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) { t->answer_rcode = DNS_PACKET_RCODE(p); t->answer_authenticated = t->scope->dnssec_mode == DNSSEC_TRUST && DNS_PACKET_AD(p); + /* According to RFC 4795, section 2.9. only the RRs + * from the answer section shall be cached. However, + * if we know the message is authenticated, we might + * as well cache everything. */ + if (t->answer_authenticated) + t->n_answer_cacheable = (unsigned) -1; /* everything! */ + else + t->n_answer_cacheable = DNS_PACKET_ANCOUNT(t->received); /* only the answer section */ + r = dns_transaction_request_dnssec_keys(t); if (r < 0) { dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES); @@ -770,6 +769,7 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) { t->start_usec = ts; t->received = dns_packet_unref(t->received); t->answer = dns_answer_unref(t->answer); + t->n_answer_cacheable = 0; t->answer_rcode = 0; t->answer_source = _DNS_TRANSACTION_SOURCE_INVALID; @@ -1444,6 +1444,9 @@ int dns_transaction_validate_dnssec(DnsTransaction *t) { t->answer = validated; validated = NULL; + /* Everything that's now in t->answer is known to be good, hence cacheable. */ + t->n_answer_cacheable = (unsigned) -1; /* everything! */ + t->answer_authenticated = true; t->dnssec_result = DNSSEC_VALIDATED; return 1; diff --git a/src/resolve/resolved-dns-transaction.h b/src/resolve/resolved-dns-transaction.h index 2328e7937c..1f35a4dd8f 100644 --- a/src/resolve/resolved-dns-transaction.h +++ b/src/resolve/resolved-dns-transaction.h @@ -74,6 +74,7 @@ struct DnsTransaction { DnsPacket *sent, *received; DnsAnswer *answer; + unsigned n_answer_cacheable; /* Specifies how many RRs of the answer shall be cached, from the beginning */ int answer_rcode; DnsTransactionSource answer_source; bool answer_authenticated;