From: Lennart Poettering Date: Wed, 4 Nov 2020 20:17:26 +0000 (+0100) Subject: resolved: add new DnsAnswerFlags indicating originating section when parsing X-Git-Tag: v248-rc1~158^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fa4e74b8ffebe032d14a39b1202f9450305accc4;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c index ca79f66c78e..8138fe595b4 100644 --- a/src/resolve/resolved-dns-answer.c +++ b/src/resolve/resolved-dns-answer.c @@ -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); } diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h index 8f91a307b67..924fe4504a8 100644 --- a/src/resolve/resolved-dns-answer.h +++ b/src/resolve/resolved-dns-answer.h @@ -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 { diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c index 79ec77e49d6..3be96e8494e 100644 --- a/src/resolve/resolved-dns-packet.c +++ b/src/resolve/resolved-dns-packet.c @@ -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)