teknoraver / rpms / systemd

Forked from rpms/systemd 2 months ago
Clone

Blame 19009.patch

Adam Williamson 22e7d0
From 1499a0a99a0765b4b1b56f56d6712324e740911f Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 20:47:28 +0100
Adam Williamson 22e7d0
Subject: [PATCH 01/12] resolved: add new helper dns_answer_min_ttl()
Adam Williamson 22e7d0
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-answer.c | 19 +++++++++++++++++++
Adam Williamson 22e7d0
 src/resolve/resolved-dns-answer.h |  2 ++
Adam Williamson 22e7d0
 2 files changed, 21 insertions(+)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
Adam Williamson 22e7d0
index a667ab5ede4..5fbff81c255 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-answer.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-answer.c
Adam Williamson 22e7d0
@@ -963,3 +963,22 @@ void dns_answer_randomize(DnsAnswer *a) {
Adam Williamson 22e7d0
                 SWAP_TWO(a->items[i], a->items[k]);
Adam Williamson 22e7d0
         }
Adam Williamson 22e7d0
 }
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+uint32_t dns_answer_min_ttl(DnsAnswer *a) {
Adam Williamson 22e7d0
+        uint32_t ttl = UINT32_MAX;
Adam Williamson 22e7d0
+        DnsResourceRecord *rr;
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+        /* Return the smallest TTL of all RRs in this answer */
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+        DNS_ANSWER_FOREACH(rr, a) {
Adam Williamson 22e7d0
+                /* Don't consider OPT (where the TTL field is used for other purposes than an actual TTL) */
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+                if (dns_type_is_pseudo(rr->key->type) ||
Adam Williamson 22e7d0
+                    dns_class_is_pseudo(rr->key->class))
Adam Williamson 22e7d0
+                        continue;
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+                ttl = MIN(ttl, rr->ttl);
Adam Williamson 22e7d0
+        }
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+        return ttl;
Adam Williamson 22e7d0
+}
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
Adam Williamson 22e7d0
index 7d19eee4e2b..447da5d6cc3 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-answer.h
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-answer.h
Adam Williamson 22e7d0
@@ -87,6 +87,8 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
 void dns_answer_randomize(DnsAnswer *a);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
+uint32_t dns_answer_min_ttl(DnsAnswer *a);
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsAnswer*, dns_answer_unref);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
 #define _DNS_ANSWER_FOREACH(q, kk, a)                                   \
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From 3b7006cb44dd2860cb1b2e652e318d196dddf312 Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 20:47:53 +0100
Adam Williamson 22e7d0
Subject: [PATCH 02/12] resolved: rebreak a few comments
Adam Williamson 22e7d0
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-cache.c | 19 +++++++------------
Adam Williamson 22e7d0
 1 file changed, 7 insertions(+), 12 deletions(-)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
index 0bf320df880..23612a5c353 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
@@ -320,11 +320,9 @@ static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t t
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         ttl = MIN(rr->ttl, nsec_ttl);
Adam Williamson 22e7d0
         if (rr->key->type == DNS_TYPE_SOA && use_soa_minimum) {
Adam Williamson 22e7d0
-                /* If this is a SOA RR, and it is requested, clamp to
Adam Williamson 22e7d0
-                 * the SOA's minimum field. This is used when we do
Adam Williamson 22e7d0
-                 * negative caching, to determine the TTL for the
Adam Williamson 22e7d0
-                 * negative caching entry.  See RFC 2308, Section
Adam Williamson 22e7d0
-                 * 5. */
Adam Williamson 22e7d0
+                /* If this is a SOA RR, and it is requested, clamp to the SOA's minimum field. This is used
Adam Williamson 22e7d0
+                 * when we do negative caching, to determine the TTL for the negative caching entry. See RFC
Adam Williamson 22e7d0
+                 * 2308, Section 5. */
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
                 if (ttl > rr->soa.minimum)
Adam Williamson 22e7d0
                         ttl = rr->soa.minimum;
Adam Williamson 22e7d0
@@ -337,8 +335,7 @@ static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t t
Adam Williamson 22e7d0
         if (rr->expiry != USEC_INFINITY) {
Adam Williamson 22e7d0
                 usec_t left;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
-                /* Make use of the DNSSEC RRSIG expiry info, if we
Adam Williamson 22e7d0
-                 * have it */
Adam Williamson 22e7d0
+                /* Make use of the DNSSEC RRSIG expiry info, if we have it */
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
                 left = LESS_BY(rr->expiry, now(CLOCK_REALTIME));
Adam Williamson 22e7d0
                 if (u > left)
Adam Williamson 22e7d0
@@ -785,9 +782,8 @@ int dns_cache_put(
Adam Williamson 22e7d0
         if (r > 0)
Adam Williamson 22e7d0
                 return 0;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
-        /* But not if it has a matching CNAME/DNAME (the negative
Adam Williamson 22e7d0
-         * caching will be done on the canonical name, not on the
Adam Williamson 22e7d0
-         * alias) */
Adam Williamson 22e7d0
+        /* But not if it has a matching CNAME/DNAME (the negative caching will be done on the canonical name,
Adam Williamson 22e7d0
+         * not on the alias) */
Adam Williamson 22e7d0
         r = dns_answer_find_cname_or_dname(answer, key, NULL, NULL);
Adam Williamson 22e7d0
         if (r < 0)
Adam Williamson 22e7d0
                 goto fail;
Adam Williamson 22e7d0
@@ -803,8 +799,7 @@ int dns_cache_put(
Adam Williamson 22e7d0
         if (r == 0 && !weird_rcode)
Adam Williamson 22e7d0
                 return 0;
Adam Williamson 22e7d0
         if (r > 0) {
Adam Williamson 22e7d0
-                /* Refuse using the SOA data if it is unsigned, but the key is
Adam Williamson 22e7d0
-                 * signed */
Adam Williamson 22e7d0
+                /* Refuse using the SOA data if it is unsigned, but the key is signed */
Adam Williamson 22e7d0
                 if (FLAGS_SET(query_flags, SD_RESOLVED_AUTHENTICATED) &&
Adam Williamson 22e7d0
                     (flags & DNS_ANSWER_AUTHENTICATED) == 0)
Adam Williamson 22e7d0
                         return 0;
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From 77db3caee36d0241bf2153f56579a9fb952962f1 Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 20:48:18 +0100
Adam Williamson 22e7d0
Subject: [PATCH 03/12] resolved: use dns_answer_isempty() where appropriate
Adam Williamson 22e7d0
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-cache.c | 2 +-
Adam Williamson 22e7d0
 1 file changed, 1 insertion(+), 1 deletion(-)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
index 23612a5c353..8edbd5fee94 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
@@ -693,7 +693,7 @@ int dns_cache_put(
Adam Williamson 22e7d0
          * short time.) */
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         if (IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN)) {
Adam Williamson 22e7d0
-                if (dns_answer_size(answer) <= 0) {
Adam Williamson 22e7d0
+                if (dns_answer_isempty(answer)) {
Adam Williamson 22e7d0
                         if (key) {
Adam Williamson 22e7d0
                                 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From b12058e8f96a9b490e2b1ce98f81ced182add577 Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 20:48:35 +0100
Adam Williamson 22e7d0
Subject: [PATCH 04/12] resolved: fix indentation
Adam Williamson 22e7d0
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-cache.c | 2 +-
Adam Williamson 22e7d0
 1 file changed, 1 insertion(+), 1 deletion(-)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
index 8edbd5fee94..09fb8e2c883 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
@@ -808,7 +808,7 @@ int dns_cache_put(
Adam Williamson 22e7d0
         if (cache_mode == DNS_CACHE_MODE_NO_NEGATIVE) {
Adam Williamson 22e7d0
                 char key_str[DNS_RESOURCE_KEY_STRING_MAX];
Adam Williamson 22e7d0
                 log_debug("Not caching negative entry for: %s, cache mode set to no-negative",
Adam Williamson 22e7d0
-                        dns_resource_key_to_string(key, key_str, sizeof key_str));
Adam Williamson 22e7d0
+                          dns_resource_key_to_string(key, key_str, sizeof key_str));
Adam Williamson 22e7d0
                 return 0;
Adam Williamson 22e7d0
         }
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From f6d80c361d6a51972d4df264a190bf01ef7af624 Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 21:15:30 +0100
Adam Williamson 22e7d0
Subject: [PATCH 05/12] resolved: drop unnecessary local variable
Adam Williamson 22e7d0
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-cache.c | 6 +++---
Adam Williamson 22e7d0
 1 file changed, 3 insertions(+), 3 deletions(-)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
index 09fb8e2c883..0f40e0e40f4 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
@@ -416,7 +416,7 @@ static int dns_cache_put_positive(
Adam Williamson 22e7d0
         _cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
Adam Williamson 22e7d0
         DnsCacheItem *existing;
Adam Williamson 22e7d0
         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
Adam Williamson 22e7d0
-        int r, k;
Adam Williamson 22e7d0
+        int r;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         assert(c);
Adam Williamson 22e7d0
         assert(rr);
Adam Williamson 22e7d0
@@ -430,9 +430,9 @@ static int dns_cache_put_positive(
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         /* New TTL is 0? Delete this specific entry... */
Adam Williamson 22e7d0
         if (rr->ttl <= 0) {
Adam Williamson 22e7d0
-                k = dns_cache_remove_by_rr(c, rr);
Adam Williamson 22e7d0
+                r = dns_cache_remove_by_rr(c, rr);
Adam Williamson 22e7d0
                 log_debug("%s: %s",
Adam Williamson 22e7d0
-                          k > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
Adam Williamson 22e7d0
+                          r > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
Adam Williamson 22e7d0
                           dns_resource_key_to_string(rr->key, key_str, sizeof key_str));
Adam Williamson 22e7d0
                 return 0;
Adam Williamson 22e7d0
         }
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From b974211acbe419170fc56a317a1d55d07c7cb686 Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 21:18:32 +0100
Adam Williamson 22e7d0
Subject: [PATCH 06/12] resolved: take shortest TTL of all of RRs in answer as
Adam Williamson 22e7d0
 cache lifetime
Adam Williamson 22e7d0
Adam Williamson 22e7d0
We nowadays cache full answer RRset combinations instead of just the
Adam Williamson 22e7d0
exact matching rrset. This means we should not cache RRs that are not
Adam Williamson 22e7d0
immediate answers to our question for longer then their own RRs. Or in
Adam Williamson 22e7d0
other words: let's determine the shortest TTL of all RRs in the whole
Adam Williamson 22e7d0
answer, and use that as cache lifetime.
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-cache.c | 60 +++++++++++++++++++++++---------
Adam Williamson 22e7d0
 1 file changed, 44 insertions(+), 16 deletions(-)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
index 0f40e0e40f4..db2361ae363 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
@@ -312,13 +312,19 @@ static DnsCacheItem* dns_cache_get(DnsCache *c, DnsResourceRecord *rr) {
Adam Williamson 22e7d0
         return NULL;
Adam Williamson 22e7d0
 }
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
-static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t timestamp, bool use_soa_minimum) {
Adam Williamson 22e7d0
+static usec_t calculate_until(
Adam Williamson 22e7d0
+                DnsResourceRecord *rr,
Adam Williamson 22e7d0
+                uint32_t min_ttl,
Adam Williamson 22e7d0
+                uint32_t nsec_ttl,
Adam Williamson 22e7d0
+                usec_t timestamp,
Adam Williamson 22e7d0
+                bool use_soa_minimum) {
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
         uint32_t ttl;
Adam Williamson 22e7d0
         usec_t u;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         assert(rr);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
-        ttl = MIN(rr->ttl, nsec_ttl);
Adam Williamson 22e7d0
+        ttl = MIN(min_ttl, nsec_ttl);
Adam Williamson 22e7d0
         if (rr->key->type == DNS_TYPE_SOA && use_soa_minimum) {
Adam Williamson 22e7d0
                 /* If this is a SOA RR, and it is requested, clamp to the SOA's minimum field. This is used
Adam Williamson 22e7d0
                  * when we do negative caching, to determine the TTL for the negative caching entry. See RFC
Adam Williamson 22e7d0
@@ -351,6 +357,7 @@ static void dns_cache_item_update_positive(
Adam Williamson 22e7d0
                 DnsResourceRecord *rr,
Adam Williamson 22e7d0
                 DnsAnswer *answer,
Adam Williamson 22e7d0
                 DnsPacket *full_packet,
Adam Williamson 22e7d0
+                uint32_t min_ttl,
Adam Williamson 22e7d0
                 uint64_t query_flags,
Adam Williamson 22e7d0
                 bool shared_owner,
Adam Williamson 22e7d0
                 DnssecResult dnssec_result,
Adam Williamson 22e7d0
@@ -387,7 +394,7 @@ static void dns_cache_item_update_positive(
Adam Williamson 22e7d0
         dns_packet_unref(i->full_packet);
Adam Williamson 22e7d0
         i->full_packet = full_packet;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
-        i->until = calculate_until(rr, UINT32_MAX, timestamp, false);
Adam Williamson 22e7d0
+        i->until = calculate_until(rr, min_ttl, UINT32_MAX, timestamp, false);
Adam Williamson 22e7d0
         i->query_flags = query_flags & CACHEABLE_QUERY_FLAGS;
Adam Williamson 22e7d0
         i->shared_owner = shared_owner;
Adam Williamson 22e7d0
         i->dnssec_result = dnssec_result;
Adam Williamson 22e7d0
@@ -414,8 +421,9 @@ static int dns_cache_put_positive(
Adam Williamson 22e7d0
                 const union in_addr_union *owner_address) {
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         _cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
Adam Williamson 22e7d0
-        DnsCacheItem *existing;
Adam Williamson 22e7d0
         char key_str[DNS_RESOURCE_KEY_STRING_MAX];
Adam Williamson 22e7d0
+        DnsCacheItem *existing;
Adam Williamson 22e7d0
+        uint32_t min_ttl;
Adam Williamson 22e7d0
         int r;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         assert(c);
Adam Williamson 22e7d0
@@ -428,8 +436,15 @@ static int dns_cache_put_positive(
Adam Williamson 22e7d0
         if (dns_type_is_pseudo(rr->key->type))
Adam Williamson 22e7d0
                 return 0;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
+        /* Determine the minimal TTL of all RRs in the answer plus the one by the main RR we are supposed to
Adam Williamson 22e7d0
+         * cache. Since we cache whole answers to questions we should never return answers where only some
Adam Williamson 22e7d0
+         * RRs are still valid, hence find the lowest here */
Adam Williamson 22e7d0
+        min_ttl = dns_answer_min_ttl(answer);
Adam Williamson 22e7d0
+        if (rr)
Adam Williamson 22e7d0
+                min_ttl = MIN(min_ttl, rr->ttl);
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
         /* New TTL is 0? Delete this specific entry... */
Adam Williamson 22e7d0
-        if (rr->ttl <= 0) {
Adam Williamson 22e7d0
+        if (min_ttl <= 0) {
Adam Williamson 22e7d0
                 r = dns_cache_remove_by_rr(c, rr);
Adam Williamson 22e7d0
                 log_debug("%s: %s",
Adam Williamson 22e7d0
                           r > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
Adam Williamson 22e7d0
@@ -446,6 +461,7 @@ static int dns_cache_put_positive(
Adam Williamson 22e7d0
                                 rr,
Adam Williamson 22e7d0
                                 answer,
Adam Williamson 22e7d0
                                 full_packet,
Adam Williamson 22e7d0
+                                min_ttl,
Adam Williamson 22e7d0
                                 query_flags,
Adam Williamson 22e7d0
                                 shared_owner,
Adam Williamson 22e7d0
                                 dnssec_result,
Adam Williamson 22e7d0
@@ -473,7 +489,7 @@ static int dns_cache_put_positive(
Adam Williamson 22e7d0
                 .rr = dns_resource_record_ref(rr),
Adam Williamson 22e7d0
                 .answer = dns_answer_ref(answer),
Adam Williamson 22e7d0
                 .full_packet = dns_packet_ref(full_packet),
Adam Williamson 22e7d0
-                .until = calculate_until(rr, UINT32_MAX, timestamp, false),
Adam Williamson 22e7d0
+                .until = calculate_until(rr, min_ttl, UINT32_MAX, timestamp, false),
Adam Williamson 22e7d0
                 .query_flags = query_flags & CACHEABLE_QUERY_FLAGS,
Adam Williamson 22e7d0
                 .shared_owner = shared_owner,
Adam Williamson 22e7d0
                 .dnssec_result = dnssec_result,
Adam Williamson 22e7d0
@@ -575,9 +591,12 @@ static int dns_cache_put_negative(
Adam Williamson 22e7d0
                 .full_packet = dns_packet_ref(full_packet),
Adam Williamson 22e7d0
         };
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
+        /* Determine how long to cache this entry. In case we have some RRs in the answer use the lowest TTL
Adam Williamson 22e7d0
+         * of any of them. Typically that's the SOA's TTL, which is OK, but could possibly be lower because
Adam Williamson 22e7d0
+         * of some other RR. Let's better take the lowest option here than a needlessly high one */
Adam Williamson 22e7d0
         i->until =
Adam Williamson 22e7d0
                 i->type == DNS_CACHE_RCODE ? timestamp + CACHE_TTL_STRANGE_RCODE_USEC :
Adam Williamson 22e7d0
-                calculate_until(soa, nsec_ttl, timestamp, true);
Adam Williamson 22e7d0
+                calculate_until(soa, dns_answer_min_ttl(answer), nsec_ttl, timestamp, true);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         if (i->type == DNS_CACHE_NXDOMAIN) {
Adam Williamson 22e7d0
                 /* NXDOMAIN entries should apply equally to all types, so we use ANY as
Adam Williamson 22e7d0
@@ -1046,21 +1065,30 @@ int dns_cache_lookup(
Adam Williamson 22e7d0
                                 DnsAnswerItem *item;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
                                 DNS_ANSWER_FOREACH_ITEM(item, j->answer) {
Adam Williamson 22e7d0
-                                        r = answer_add_clamp_ttl(&answer, item->rr, item->ifindex, item->flags, item->rrsig, query_flags, j->until, current);
Adam Williamson 22e7d0
+                                        r = answer_add_clamp_ttl(
Adam Williamson 22e7d0
+                                                        &answer,
Adam Williamson 22e7d0
+                                                        item->rr,
Adam Williamson 22e7d0
+                                                        item->ifindex,
Adam Williamson 22e7d0
+                                                        item->flags,
Adam Williamson 22e7d0
+                                                        item->rrsig,
Adam Williamson 22e7d0
+                                                        query_flags,
Adam Williamson 22e7d0
+                                                        j->until,
Adam Williamson 22e7d0
+                                                        current);
Adam Williamson 22e7d0
                                         if (r < 0)
Adam Williamson 22e7d0
                                                 return r;
Adam Williamson 22e7d0
                                 }
Adam Williamson 22e7d0
                         }
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
                 } else if (j->rr) {
Adam Williamson 22e7d0
-                        r = answer_add_clamp_ttl(&answer,
Adam Williamson 22e7d0
-                                                 j->rr,
Adam Williamson 22e7d0
-                                                 j->ifindex,
Adam Williamson 22e7d0
-                                                 FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0,
Adam Williamson 22e7d0
-                                                 NULL,
Adam Williamson 22e7d0
-                                                 query_flags,
Adam Williamson 22e7d0
-                                                 j->until,
Adam Williamson 22e7d0
-                                                 current);
Adam Williamson 22e7d0
+                        r = answer_add_clamp_ttl(
Adam Williamson 22e7d0
+                                        &answer,
Adam Williamson 22e7d0
+                                        j->rr,
Adam Williamson 22e7d0
+                                        j->ifindex,
Adam Williamson 22e7d0
+                                        FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0,
Adam Williamson 22e7d0
+                                        NULL,
Adam Williamson 22e7d0
+                                        query_flags,
Adam Williamson 22e7d0
+                                        j->until,
Adam Williamson 22e7d0
+                                        current);
Adam Williamson 22e7d0
                         if (r < 0)
Adam Williamson 22e7d0
                                 return r;
Adam Williamson 22e7d0
                 }
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From a1acc6e332b05f6a5167bf9d0bc0657794e1342c Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 21:18:52 +0100
Adam Williamson 22e7d0
Subject: [PATCH 07/12] resolved: let's tweak how we calculate TTL left
Adam Williamson 22e7d0
MIME-Version: 1.0
Adam Williamson 22e7d0
Content-Type: text/plain; charset=UTF-8
Adam Williamson 22e7d0
Content-Transfer-Encoding: 8bit
Adam Williamson 22e7d0
Adam Williamson 22e7d0
When responding from DNS cache, let's slightly tweak how the TTL is
Adam Williamson 22e7d0
lowered: as before let's round down when converting from our internal µs
Adam Williamson 22e7d0
to the external seconds. (This is preferable, since records should
Adam Williamson 22e7d0
better be cached too short instead of too long.) Let's avoid rounding
Adam Williamson 22e7d0
down to zero though, since that has special semantics in many cases (in
Adam Williamson 22e7d0
particular mDNS). Let's just use 1s in that case.
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-cache.c | 13 +++++++++++--
Adam Williamson 22e7d0
 1 file changed, 11 insertions(+), 2 deletions(-)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
index db2361ae363..9b2e7115c0a 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-cache.c
Adam Williamson 22e7d0
@@ -937,9 +937,18 @@ static int answer_add_clamp_ttl(
Adam Williamson 22e7d0
         assert(rr);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         if (FLAGS_SET(query_flags, SD_RESOLVED_CLAMP_TTL)) {
Adam Williamson 22e7d0
+                uint32_t left_ttl;
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+                /* Let's determine how much time is left for this cache entry. Note that we round down, but
Adam Williamson 22e7d0
+                 * clamp this to be 1s at minimum, since we usually want records to remain cached better too
Adam Williamson 22e7d0
+                 * short a time than too long a time, but otoh don't want to return 0 ever, since that has
Adam Williamson 22e7d0
+                 * special semantics in various contexts — in particular in mDNS */
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+                left_ttl = MAX(1U, LESS_BY(until, current) / USEC_PER_SEC);
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
                 patched = dns_resource_record_ref(rr);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
-                r = dns_resource_record_clamp_ttl(&patched, LESS_BY(until, current) / USEC_PER_SEC);
Adam Williamson 22e7d0
+                r = dns_resource_record_clamp_ttl(&patched, left_ttl);
Adam Williamson 22e7d0
                 if (r < 0)
Adam Williamson 22e7d0
                         return r;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
@@ -947,7 +956,7 @@ static int answer_add_clamp_ttl(
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
                 if (rrsig) {
Adam Williamson 22e7d0
                         patched_rrsig = dns_resource_record_ref(rrsig);
Adam Williamson 22e7d0
-                        r = dns_resource_record_clamp_ttl(&patched_rrsig, LESS_BY(until, current) / USEC_PER_SEC);
Adam Williamson 22e7d0
+                        r = dns_resource_record_clamp_ttl(&patched_rrsig, left_ttl);
Adam Williamson 22e7d0
                         if (r < 0)
Adam Williamson 22e7d0
                                 return r;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From c4d98c3acc5901fad4a9a8e2ecd7cf9ad7b8ecb0 Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 21:36:42 +0100
Adam Williamson 22e7d0
Subject: [PATCH 08/12] resolved: use DNS_ANSWER_MASK_SECTIONS where
Adam Williamson 22e7d0
 appropriate
Adam Williamson 22e7d0
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-stub.c | 2 +-
Adam Williamson 22e7d0
 1 file changed, 1 insertion(+), 1 deletion(-)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
Adam Williamson 22e7d0
index 8e781dd7389..f8d4767e536 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-stub.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-stub.c
Adam Williamson 22e7d0
@@ -275,7 +275,7 @@ static int dns_stub_collect_answer_by_section(
Adam Williamson 22e7d0
                     dns_type_is_dnssec(item->rr->key->type))
Adam Williamson 22e7d0
                         continue;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
-                if (((item->flags ^ section) & (DNS_ANSWER_SECTION_ANSWER|DNS_ANSWER_SECTION_AUTHORITY|DNS_ANSWER_SECTION_ADDITIONAL)) != 0)
Adam Williamson 22e7d0
+                if (((item->flags ^ section) & DNS_ANSWER_MASK_SECTIONS) != 0)
Adam Williamson 22e7d0
                         continue;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
                 r = reply_add_with_rrsig(
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From 567aa5c87b4a177cd4a6ef3ed8d6814839a4ffd8 Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 22:14:43 +0100
Adam Williamson 22e7d0
Subject: [PATCH 09/12] resolved: show TTLs in answer dump
Adam Williamson 22e7d0
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-answer.c | 5 ++---
Adam Williamson 22e7d0
 1 file changed, 2 insertions(+), 3 deletions(-)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
Adam Williamson 22e7d0
index 5fbff81c255..a032ac157e0 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-answer.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-answer.c
Adam Williamson 22e7d0
@@ -879,9 +879,8 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f) {
Adam Williamson 22e7d0
                 }
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
                 fputs(t, f);
Adam Williamson 22e7d0
-
Adam Williamson 22e7d0
-                if (item->ifindex != 0 || item->rrsig || item->flags != 0)
Adam Williamson 22e7d0
-                        fputs("\t;", f);
Adam Williamson 22e7d0
+                fputs("\t;", f);
Adam Williamson 22e7d0
+                fprintf(f, " ttl=%" PRIu32, item->rr->ttl);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
                 if (item->ifindex != 0)
Adam Williamson 22e7d0
                         fprintf(f, " ifindex=%i", item->ifindex);
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From 1414b67e0d9515c23221cecbb5323d45ea2020b1 Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 22:15:06 +0100
Adam Williamson 22e7d0
Subject: [PATCH 10/12] resolved: add helper for dumping DnsQuestion, similar
Adam Williamson 22e7d0
 to what we have for DnsAnswer
Adam Williamson 22e7d0
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-question.c | 18 ++++++++++++++++++
Adam Williamson 22e7d0
 src/resolve/resolved-dns-question.h |  2 ++
Adam Williamson 22e7d0
 2 files changed, 20 insertions(+)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-question.c b/src/resolve/resolved-dns-question.c
Adam Williamson 22e7d0
index 047170899db..ef409326304 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-question.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-question.c
Adam Williamson 22e7d0
@@ -445,3 +445,21 @@ int dns_question_new_service(
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         return 0;
Adam Williamson 22e7d0
 }
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+/*
Adam Williamson 22e7d0
+ * This function is not used in the code base, but is useful when debugging. Do not delete.
Adam Williamson 22e7d0
+ */
Adam Williamson 22e7d0
+void dns_question_dump(DnsQuestion *question, FILE *f) {
Adam Williamson 22e7d0
+        DnsResourceKey *k;
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+        if (!f)
Adam Williamson 22e7d0
+                f = stdout;
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+        DNS_QUESTION_FOREACH(k, question) {
Adam Williamson 22e7d0
+                char buf[DNS_RESOURCE_KEY_STRING_MAX];
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+                fputc('\t', f);
Adam Williamson 22e7d0
+                fputs(dns_resource_key_to_string(k, buf, sizeof(buf)), f);
Adam Williamson 22e7d0
+                fputc('\n', f);
Adam Williamson 22e7d0
+        }
Adam Williamson 22e7d0
+}
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-question.h b/src/resolve/resolved-dns-question.h
Adam Williamson 22e7d0
index a6444b0baf9..8f9a84c82d9 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-question.h
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-question.h
Adam Williamson 22e7d0
@@ -33,6 +33,8 @@ int dns_question_is_equal(DnsQuestion *a, DnsQuestion *b);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
 int dns_question_cname_redirect(DnsQuestion *q, const DnsResourceRecord *cname, DnsQuestion **ret);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
+void dns_question_dump(DnsQuestion *q, FILE *f);
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
 const char *dns_question_first_name(DnsQuestion *q);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
 static inline size_t dns_question_size(DnsQuestion *q) {
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From a7c0291c104cdd9d5ae2fe3c5855273bbadae13e Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 22:15:18 +0100
Adam Williamson 22e7d0
Subject: [PATCH 11/12] resolved: match CNAME replies to right question
Adam Williamson 22e7d0
Adam Williamson 22e7d0
Previously by mistake we'd always match every single reply we get in a
Adam Williamson 22e7d0
CNAME chain to the original question from the stub client. That's
Adam Williamson 22e7d0
broken, we need to test it against the CNAME query we are currently
Adam Williamson 22e7d0
looking at.
Adam Williamson 22e7d0
Adam Williamson 22e7d0
The effect of this incorrect matching was that we'd assign the RRs to
Adam Williamson 22e7d0
the wrong section since we'd assume they'd be auxiliary answers instead
Adam Williamson 22e7d0
of primary answers.
Adam Williamson 22e7d0
Adam Williamson 22e7d0
Fixes: #18972
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-stub.c | 2 +-
Adam Williamson 22e7d0
 1 file changed, 1 insertion(+), 1 deletion(-)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
Adam Williamson 22e7d0
index f8d4767e536..b6d14b9305e 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-stub.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-stub.c
Adam Williamson 22e7d0
@@ -761,7 +761,7 @@ static void dns_stub_query_complete(DnsQuery *q) {
Adam Williamson 22e7d0
          * and keep adding all RRs in the CNAME chain. */
Adam Williamson 22e7d0
         r = dns_stub_assign_sections(
Adam Williamson 22e7d0
                         q,
Adam Williamson 22e7d0
-                        q->request_packet->question,
Adam Williamson 22e7d0
+                        dns_query_question_for_protocol(q, DNS_PROTOCOL_DNS),
Adam Williamson 22e7d0
                         dns_stub_reply_with_edns0_do(q));
Adam Williamson 22e7d0
         if (r < 0) {
Adam Williamson 22e7d0
                 log_debug_errno(r, "Failed to assign sections: %m");
Adam Williamson 22e7d0
Adam Williamson 22e7d0
From b1eea703e01da1e280e179fb119449436a0c9b8e Mon Sep 17 00:00:00 2001
Adam Williamson 22e7d0
From: Lennart Poettering <lennart@poettering.net>
Adam Williamson 22e7d0
Date: Mon, 15 Mar 2021 23:26:46 +0100
Adam Williamson 22e7d0
Subject: [PATCH 12/12] resolved: don't flush answer RRs on CNAME redirect too
Adam Williamson 22e7d0
 early
Adam Williamson 22e7d0
MIME-Version: 1.0
Adam Williamson 22e7d0
Content-Type: text/plain; charset=UTF-8
Adam Williamson 22e7d0
Content-Transfer-Encoding: 8bit
Adam Williamson 22e7d0
Adam Williamson 22e7d0
When doing a CNAME/DNAME redirect let's first check if the answer we
Adam Williamson 22e7d0
already have fully answers the redirected question already. If so, let's
Adam Williamson 22e7d0
use that. If not, let's properly restart things.
Adam Williamson 22e7d0
Adam Williamson 22e7d0
This simply removes one call to dns_answer_reset() that was placed too
Adam Williamson 22e7d0
early: instead of resetting when we detect a CNAME/DNAME redirect, do so
Adam Williamson 22e7d0
only after checking if the answer we already have doesn't match the
Adam Williamson 22e7d0
reply, and then decide to *actually* follow it. Or in other words: rely
Adam Williamson 22e7d0
on the dns_answer_reset() call in dns_query_go() which we'll call to
Adam Williamson 22e7d0
actually begin with the redirected question.
Adam Williamson 22e7d0
Adam Williamson 22e7d0
This fixes an optimization path which was broken back in 7820b320eaa608748f66f8105621640cf80e483a.
Adam Williamson 22e7d0
Adam Williamson 22e7d0
(This doesn't really matter as much as one might think, since our cache
Adam Williamson 22e7d0
stepped in anyway and answered the questions before going back to the
Adam Williamson 22e7d0
network. However, this adds noise if RRs with very short TTLs are cached
Adam Williamson 22e7d0
– which some CDNs do – and is of course relavant when people turn off
Adam Williamson 22e7d0
the local cache.)
Adam Williamson 22e7d0
---
Adam Williamson 22e7d0
 src/resolve/resolved-dns-query.c | 7 ++++---
Adam Williamson 22e7d0
 1 file changed, 4 insertions(+), 3 deletions(-)
Adam Williamson 22e7d0
Adam Williamson 22e7d0
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
Adam Williamson 22e7d0
index aa9d65d4a82..e4386c402ac 100644
Adam Williamson 22e7d0
--- a/src/resolve/resolved-dns-query.c
Adam Williamson 22e7d0
+++ b/src/resolve/resolved-dns-query.c
Adam Williamson 22e7d0
@@ -1019,7 +1019,9 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
Adam Williamson 22e7d0
         q->question_utf8 = TAKE_PTR(nq_utf8);
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         dns_query_unref_candidates(q);
Adam Williamson 22e7d0
-        dns_query_reset_answer(q);
Adam Williamson 22e7d0
+
Adam Williamson 22e7d0
+        /* Note that we do *not* reset the answer here, because the answer we previously got might already
Adam Williamson 22e7d0
+         * include everything we need, let's check that first */
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
         q->state = DNS_TRANSACTION_NULL;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
@@ -1069,8 +1071,7 @@ int dns_query_process_cname(DnsQuery *q) {
Adam Williamson 22e7d0
         if (r < 0)
Adam Williamson 22e7d0
                 return r;
Adam Williamson 22e7d0
 
Adam Williamson 22e7d0
-        /* Let's see if the answer can already answer the new
Adam Williamson 22e7d0
-         * redirected question */
Adam Williamson 22e7d0
+        /* Let's see if the answer can already answer the new redirected question */
Adam Williamson 22e7d0
         r = dns_query_process_cname(q);
Adam Williamson 22e7d0
         if (r != DNS_QUERY_NOMATCH)
Adam Williamson 22e7d0
                 return r;