resolved: add new DnsAnswerFlags indicating originating section when parsing

Let's beef up our parser a bit: let's store in the DnsAnswerFlags field
(that is stored as part of DnsAnswerItem) which DNS packet section (i.e.
answer, authoritative, additional) an RR originates from.

This is useful when propagating answers from an upstream DNS server
eventually, as we can place the data in the right sections downstream
too.
This commit is contained in:
Lennart Poettering
2020-11-04 21:17:26 +01:00
parent 9c5fcb8ac7
commit fa4e74b8ff
3 changed files with 30 additions and 15 deletions

View File

@@ -807,6 +807,12 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f) {
fputs(" cache-flush", f);
if (item->flags & DNS_ANSWER_GOODBYE)
fputs(" goodbye", f);
if (item->flags & DNS_ANSWER_SECTION_ANSWER)
fputs(" section-answer", f);
if (item->flags & DNS_ANSWER_SECTION_AUTHORITY)
fputs(" section-authority", f);
if (item->flags & DNS_ANSWER_SECTION_ADDITIONAL)
fputs(" section-additional", f);
fputc('\n', f);
}

View File

@@ -8,19 +8,20 @@ typedef struct DnsAnswerItem DnsAnswerItem;
#include "resolved-dns-rr.h"
#include "set.h"
/* A simple array of resource records. We keep track of the
* originating ifindex for each RR where that makes sense, so that we
* can qualify A and AAAA RRs referring to a local link with the
* right ifindex.
/* A simple array of resource records. We keep track of the originating ifindex for each RR where that makes
* sense, so that we can qualify A and AAAA RRs referring to a local link with the right ifindex.
*
* Note that we usually encode the empty DnsAnswer object as a simple NULL. */
typedef enum DnsAnswerFlags {
DNS_ANSWER_AUTHENTICATED = 1 << 0, /* Item has been authenticated */
DNS_ANSWER_CACHEABLE = 1 << 1, /* Item is subject to caching */
DNS_ANSWER_SHARED_OWNER = 1 << 2, /* For mDNS: RRset may be owner by multiple peers */
DNS_ANSWER_CACHE_FLUSH = 1 << 3, /* For mDNS: sets cache-flush bit in the rrclass of response records */
DNS_ANSWER_GOODBYE = 1 << 4, /* For mDNS: item is subject to disappear */
DNS_ANSWER_AUTHENTICATED = 1 << 0, /* Item has been authenticated */
DNS_ANSWER_CACHEABLE = 1 << 1, /* Item is subject to caching */
DNS_ANSWER_SHARED_OWNER = 1 << 2, /* For mDNS: RRset may be owner by multiple peers */
DNS_ANSWER_CACHE_FLUSH = 1 << 3, /* For mDNS: sets cache-flush bit in the rrclass of response records */
DNS_ANSWER_GOODBYE = 1 << 4, /* For mDNS: item is subject to disappear */
DNS_ANSWER_SECTION_ANSWER = 1 << 5, /* When parsing: RR originates from answer section */
DNS_ANSWER_SECTION_AUTHORITY = 1 << 6, /* When parsing: RR originates from authority section */
DNS_ANSWER_SECTION_ADDITIONAL = 1 << 7, /* When parsing: RR originates from additional section */
} DnsAnswerFlags;
struct DnsAnswerItem {

View File

@@ -2322,12 +2322,20 @@ static int dns_packet_extract_answer(DnsPacket *p, DnsAnswer **ret_answer) {
assert(p->rindex >= start);
p->opt_size = p->rindex - start;
} else {
/* According to RFC 4795, section 2.9. only the RRs from the Answer section
* shall be cached. Hence mark only those RRs as cacheable by default, but
* not the ones from the Additional or Authority sections. */
DnsAnswerFlags flags =
(i < DNS_PACKET_ANCOUNT(p) ? DNS_ANSWER_CACHEABLE : 0) |
(p->protocol == DNS_PROTOCOL_MDNS && !cache_flush ? DNS_ANSWER_SHARED_OWNER : 0);
DnsAnswerFlags flags = 0;
if (p->protocol == DNS_PROTOCOL_MDNS && !cache_flush)
flags |= DNS_ANSWER_SHARED_OWNER;
/* According to RFC 4795, section 2.9. only the RRs from the Answer section shall be
* cached. Hence mark only those RRs as cacheable by default, but not the ones from
* the Additional or Authority sections. */
if (i < DNS_PACKET_ANCOUNT(p))
flags |= DNS_ANSWER_CACHEABLE|DNS_ANSWER_SECTION_ANSWER;
else if (i < DNS_PACKET_ANCOUNT(p) + DNS_PACKET_NSCOUNT(p))
flags |= DNS_ANSWER_SECTION_AUTHORITY;
else
flags |= DNS_ANSWER_SECTION_ADDITIONAL;
r = dns_answer_add(answer, rr, p->ifindex, flags);
if (r < 0)