]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolved: tweak how we signal authoritative answers
authorLennart Poettering <lennart@poettering.net>
Wed, 24 Feb 2021 16:04:55 +0000 (17:04 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 26 Mar 2021 17:21:41 +0000 (18:21 +0100)
let's make sure we set the "aa" bit in the stub only if we answer with
fully authoritative data. For this ensure:

1. Either all data is synthetic, including all CNAME/DNAME redirects

2. Or all data comes from the local trust anchor or the local zones
   (i.e. not the network or the cache)

Follow-up for 4ad017cda57b04b9d65e7da962806cfcc50b5f0c

src/resolve/resolved-dns-query.c
src/resolve/resolved-dns-query.h
src/resolve/resolved-dns-stub.c

index 3a908a6b54ea3c4bce88edca357711e86304f5cc..e960ac0322730b062d301c11e641c42ea84b952a 100644 (file)
@@ -1122,6 +1122,8 @@ int dns_query_process_cname_one(DnsQuery *q) {
                 q->previous_redirect_unauthenticated = true;
         if (!FLAGS_SET(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL))
                 q->previous_redirect_non_confidential = true;
+        if (!FLAGS_SET(q->answer_query_flags, SD_RESOLVED_SYNTHETIC))
+                q->previous_redirect_non_synthetic = true;
 
         /* OK, let's actually follow the CNAME */
         r = dns_query_cname_redirect(q, cname);
@@ -1244,9 +1246,17 @@ bool dns_query_fully_confidential(DnsQuery *q) {
         return FLAGS_SET(q->answer_query_flags, SD_RESOLVED_CONFIDENTIAL) && !q->previous_redirect_non_confidential;
 }
 
-bool dns_query_fully_synthetic(DnsQuery *q) {
+bool dns_query_fully_authoritative(DnsQuery *q) {
         assert(q);
 
-        return (q->answer_query_flags & (SD_RESOLVED_SYNTHETIC | SD_RESOLVED_FROM_TRUST_ANCHOR)) &&
-                !(q->answer_query_flags & SD_RESOLVED_FROM_MASK & ~SD_RESOLVED_FROM_TRUST_ANCHOR);
+        /* We are authoritative for everything synthetic (except if a previous CNAME/DNAME) wasn't
+         * synthetic. (Note: SD_RESOLVED_SYNTHETIC is reset on each CNAME/DNAME, hence the explicit check for
+         * previous synthetic DNAME/CNAME redirections.)*/
+        if ((q->answer_query_flags & SD_RESOLVED_SYNTHETIC) && !q->previous_redirect_non_synthetic)
+                return true;
+
+        /* We are also authoritative for everything coming only from the trust anchor and the local
+         * zones. (Note: the SD_RESOLVED_FROM_xyz flags we merge on each redirect, hence no need to
+         * explicitly check previous redirects here.)*/
+        return (q->answer_query_flags & SD_RESOLVED_FROM_MASK & ~(SD_RESOLVED_FROM_TRUST_ANCHOR | SD_RESOLVED_FROM_ZONE)) == 0;
 }
index 39bf341d681779d4fb58dc89c6c1219d5b0ae248..fa584fe3de9d884853d3564042476bc1614246fb 100644 (file)
@@ -80,6 +80,7 @@ struct DnsQuery {
         int answer_errno; /* if state is DNS_TRANSACTION_ERRNO */
         bool previous_redirect_unauthenticated;
         bool previous_redirect_non_confidential;
+        bool previous_redirect_non_synthetic;
         DnsPacket *answer_full_packet;
 
         /* Bus + Varlink client information */
@@ -142,7 +143,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQuery*, dns_query_free);
 
 bool dns_query_fully_authenticated(DnsQuery *q);
 bool dns_query_fully_confidential(DnsQuery *q);
-bool dns_query_fully_synthetic(DnsQuery *q);
+bool dns_query_fully_authoritative(DnsQuery *q);
 
 static inline uint64_t dns_query_reply_flags_make(DnsQuery *q) {
         assert(q);
index 177b88e025994f9bb701a3a8f872f158a061a7dd..602720bf505d6decee5845c2b9953e9cf3076e45 100644 (file)
@@ -580,7 +580,7 @@ static int dns_stub_send_reply(
                         DNS_PACKET_ID(q->request_packet),
                         rcode,
                         truncated,
-                        dns_query_fully_synthetic(q),
+                        dns_query_fully_authoritative(q),
                         !!q->request_packet->opt,
                         edns0_do,
                         DNS_PACKET_AD(q->request_packet) && dns_query_fully_authenticated(q),