summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-02-24 17:04:55 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-03-26 18:21:41 +0100
commit9ddf099f306b79e74b2c60acd4c762a799d76835 (patch)
tree6b2f038fb3b26a8f6376dd27bf4103b972227003
parentuse the right member to define property (diff)
downloadsystemd-9ddf099f306b79e74b2c60acd4c762a799d76835.tar.xz
systemd-9ddf099f306b79e74b2c60acd4c762a799d76835.zip
resolved: tweak how we signal authoritative answers
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
-rw-r--r--src/resolve/resolved-dns-query.c16
-rw-r--r--src/resolve/resolved-dns-query.h3
-rw-r--r--src/resolve/resolved-dns-stub.c2
3 files changed, 16 insertions, 5 deletions
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
index 3a908a6b54..e960ac0322 100644
--- a/src/resolve/resolved-dns-query.c
+++ b/src/resolve/resolved-dns-query.c
@@ -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;
}
diff --git a/src/resolve/resolved-dns-query.h b/src/resolve/resolved-dns-query.h
index 39bf341d68..fa584fe3de 100644
--- a/src/resolve/resolved-dns-query.h
+++ b/src/resolve/resolved-dns-query.h
@@ -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);
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
index 177b88e025..602720bf50 100644
--- a/src/resolve/resolved-dns-stub.c
+++ b/src/resolve/resolved-dns-stub.c
@@ -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),