]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dns-rr: invalidate wire format after changing ttl
authordongshengyuan <545258830@qq.com>
Thu, 9 Jul 2026 00:35:03 +0000 (08:35 +0800)
committerdongshengyuan <545258830@qq.com>
Thu, 9 Jul 2026 00:35:03 +0000 (08:35 +0800)
dns_resource_record_clamp_ttl() may patch the TTL in place when the
record has a single reference. dnssec_fix_rrset_ttl() also updates TTLs
after canonical wire-format data may have been cached.

If a record already has cached wire-format data, that cache still
contains the old TTL and dns_resource_record_to_wire_format() will keep
reusing it.

Add a small helper to clear the cached wire-format state, and use it
whenever the TTL changes. This makes subsequent serialization match the
record fields.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
src/resolve/resolved-dns-dnssec.c
src/resolve/test-dns-rr.c
src/shared/dns-rr.c
src/shared/dns-rr.h

index 67cf991e70596d7df14906c8465d64ff34eca3fb..575f100809d04802b879715ef99defdad51c27c4 100644 (file)
@@ -554,7 +554,12 @@ static void dnssec_fix_rrset_ttl(
                 /* Pick the TTL as the minimum of the RR's TTL, the
                  * RR's original TTL according to the RRSIG and the
                  * RRSIG's own TTL, see RFC 4035, Section 5.3.3 */
-                rr->ttl = MIN3(rr->ttl, rrsig->rrsig.original_ttl, rrsig->ttl);
+                uint32_t ttl = MIN3(rr->ttl, rrsig->rrsig.original_ttl, rrsig->ttl);
+                if (ttl != rr->ttl) {
+                        rr->ttl = ttl;
+                        dns_resource_record_clear_wire_format(rr);
+                }
+
                 rr->expiry = rrsig->rrsig.expiration * USEC_PER_SEC;
 
                 /* Copy over information about the signer and wildcard source of synthesis */
index 2ded6b0ab96f9871ab0ae1a5f0f5581b284c9636..516c9011b42f0c3ccf5f35e852188c0250bac68f 100644 (file)
@@ -2443,18 +2443,29 @@ TEST(dns_resource_record_is_synthetic) {
  * ================================================================ */
 
 TEST(dns_resource_record_clamp_ttl_in_place) {
+        _cleanup_free_ void *wire_format = NULL;
         DnsResourceRecord *rr = NULL, *orig = NULL;
+        size_t wire_format_size;
 
         rr = dns_resource_record_new_full(DNS_CLASS_IN, DNS_TYPE_A, "www.example.com");
         ASSERT_NOT_NULL(rr);
         orig = rr;
         rr->ttl = 3600;
+        rr->a.in_addr.s_addr = htobe32(0xc0a8017f);
 
         ASSERT_FALSE(dns_resource_record_clamp_ttl(&rr, 4800));
         ASSERT_EQ(rr->ttl, 3600u);
 
+        ASSERT_OK(dns_resource_record_to_wire_format(rr, false));
+        ASSERT_NOT_NULL(rr->wire_format);
+        wire_format_size = rr->wire_format_size;
+        ASSERT_NOT_NULL(wire_format = memdup(rr->wire_format, wire_format_size));
+
         ASSERT_TRUE(dns_resource_record_clamp_ttl(&rr, 2400));
         ASSERT_EQ(rr->ttl, 2400u);
+        ASSERT_OK(dns_resource_record_to_wire_format(rr, false));
+        ASSERT_EQ(rr->wire_format_size, wire_format_size);
+        ASSERT_NE(memcmp(rr->wire_format, wire_format, wire_format_size), 0);
 
         ASSERT_TRUE(rr == orig);
 
index eb91910e835f819e706578266d39b68a4afef940..9ba7429a6c3befcc6e708de1b78b6dcad47a324f 100644 (file)
@@ -1466,6 +1466,15 @@ int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical) {
         return 0;
 }
 
+void dns_resource_record_clear_wire_format(DnsResourceRecord *rr) {
+        assert(rr);
+
+        rr->wire_format = mfree(rr->wire_format);
+        rr->wire_format_size = 0;
+        rr->wire_format_rdata_offset = 0;
+        rr->wire_format_canonical = false;
+}
+
 int dns_resource_record_signer(DnsResourceRecord *rr, const char **ret) {
         const char *n;
         int r;
@@ -1977,6 +1986,7 @@ int dns_resource_record_clamp_ttl(DnsResourceRecord **rr, uint32_t max_ttl) {
         if (old_rr->n_ref == 1) {
                 /* Patch in place */
                 old_rr->ttl = new_ttl;
+                dns_resource_record_clear_wire_format(old_rr);
                 return 1;
         }
 
index d747083aa8a811c38874334c28eddea7e8167e67..a3cde2f3d1eb3712e1849862ef67d035ec0b1642 100644 (file)
@@ -392,6 +392,7 @@ const char* dns_resource_record_to_string(DnsResourceRecord *rr);
 DnsResourceRecord *dns_resource_record_copy(DnsResourceRecord *rr);
 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord*, dns_resource_record_unref);
 
+void dns_resource_record_clear_wire_format(DnsResourceRecord *rr);
 int dns_resource_record_to_wire_format(DnsResourceRecord *rr, bool canonical);
 
 int dns_resource_record_signer(DnsResourceRecord *rr, const char **ret);