diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-02-24 17:04:55 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2021-03-26 18:21:41 +0100 |
commit | 9ddf099f306b79e74b2c60acd4c762a799d76835 (patch) | |
tree | 6b2f038fb3b26a8f6376dd27bf4103b972227003 | |
parent | use the right member to define property (diff) | |
download | systemd-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.c | 16 | ||||
-rw-r--r-- | src/resolve/resolved-dns-query.h | 3 | ||||
-rw-r--r-- | src/resolve/resolved-dns-stub.c | 2 |
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), |