]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix DNAME synthesis from cache that keeps use of 0TTL
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 15 Jun 2026 14:39:34 +0000 (16:39 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Mon, 15 Jun 2026 14:39:34 +0000 (16:39 +0200)
  entries in a sliding window. It did not surpass RRSIG
  expiry. Thanks to Qifan Zhang, Palo Alto Networks, for
  the report.

daemon/remote.c
doc/Changelog
services/cache/dns.c
services/cache/rrset.c
testdata/iter_dname_ttl0_grace.rpl [new file with mode: 0644]
util/data/msgreply.c
util/data/packed_rrset.h

index 7dfee4b6d67709b904b31f999d134b23fa0a977f..09128e62a23dce1664e6e0f74884844732dc5b02 100644 (file)
@@ -2299,6 +2299,9 @@ zone_del_rrset(struct lruhash_entry* e, void* arg)
                        (struct packed_rrset_data*)e->data;
                if(d->ttl > inf->expired) {
                        d->ttl = inf->expired;
+                       if(d->ttl_add > inf->expired)
+                               d->ttl_add = inf->expired; /* for 0TTL rrsets,
+                                       means that d->ttl_add <= d->ttl */
                        inf->num_rrsets++;
                }
        }
index 6b8fbe8d64c5b9e596e2e2854575fb8d8362bf8e..474f46786387b53ad354ba519594e3ef2a66d195 100644 (file)
        - Fix log of an aliased qname, to not use freed region
          memory. Thanks to Qifan Zhang, Palo Alto Networks, for
          the report.
+       - Fix DNAME synthesis from cache that keeps use of 0TTL
+         entries in a sliding window. It did not surpass RRSIG
+         expiry. Thanks to Qifan Zhang, Palo Alto Networks, for
+         the report.
 
 12 June 2026: Wouter
        - Fix that for auth-zone and rpz zones the allow-notify
index f6ce272a5ea615b1da9d33bee0b0b72dfe46f4f8..79a23a77556fae96f5c3a08cc4b17ce851f728e1 100644 (file)
@@ -780,11 +780,16 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
        uint8_t* newname, *dtarg = NULL;
        size_t newlen, dtarglen;
        time_t rr_ttl;
+       int graceperiod = 0;
        if(TTL_IS_EXPIRED(d->ttl, now)) {
                /* Allow TTL=0 DNAME from upstream within grace period */
                if(!(rrset->rk.flags & PACKED_RRSET_UPSTREAM_0TTL))
                        return NULL;
                rr_ttl = 0;
+               /* Since PACKED_RRSET_UPSTREAM_0TTL set the flag that
+                * the grace period has been applied, this stops the rrset
+                * from getting stored back into the cache with a bigger TTL.*/
+               graceperiod = 1;
        } else {
                rr_ttl = d->ttl - now;
        }
@@ -812,6 +817,8 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
        msg->rep->rrsets[0] = packed_rrset_copy_region(rrset, region, now);
        if(!msg->rep->rrsets[0]) /* copy DNAME */
                return NULL;
+       if(graceperiod)
+               msg->rep->rrsets[0]->rk.flags |= PACKED_RRSET_0TTL_GRACE;
        /* synth CNAME rrset */
        get_cname_target(rrset, &dtarg, &dtarglen);
        if(!dtarg)
index b5a3fc0f20ff5564abec00069e3a12949ad65fac..73b3fb7abbc3fd929777477acb64b2f3bfbb7e32 100644 (file)
@@ -209,6 +209,12 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
        int equal = 0;
        log_assert(ref->id != 0 && k->id != 0);
        log_assert(k->rk.dname != NULL);
+       if((k->rk.flags&PACKED_RRSET_0TTL_GRACE) !=0) {
+               log_nametypeclass(VERB_ALGO, "rrset store of PACKED_RRSET_0TTL_GRACE rrset skipped", k->rk.dname, rrset_type, ntohs(k->rk.rrset_class));
+               return 0; /* Do not store 0TTL items after apply of
+                       the grace ttl amount.
+                       This means the ref was not changed by the call. */
+       }
        /* looks up item with a readlock - no editing! */
        if((e=slabhash_lookup(&r->table, h, k, 0)) != 0) {
                /* return id and key as they will be used in the cache
diff --git a/testdata/iter_dname_ttl0_grace.rpl b/testdata/iter_dname_ttl0_grace.rpl
new file mode 100644 (file)
index 0000000..b6b28ff
--- /dev/null
@@ -0,0 +1,378 @@
+; config options
+; Test DNAME TTL=0 grace period: synthesis from cache within 1 second
+; Island of trust at example.com, DNSSEC signed DNAME with TTL=0 (RFC 2308)
+server:
+       trust-anchor: "example.com.    3600    IN      DS      2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
+       trust-anchor: "example.net.    3600    IN      DNSKEY  256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}"
+       val-override-date: "20070916134226"
+       target-fetch-policy: "0 0 0 0 0"
+       qname-minimisation: "no"
+       fake-sha1: yes
+       trust-anchor-signaling: no
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test DNAME TTL=0 and the grace period
+; the grace period ends, and new data appears, while traffic queries the
+; store DNAME record, for synthesis.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 100
+       ADDRESS 193.0.14.129 
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+. IN NS
+SECTION ANSWER
+. IN NS        K.ROOT-SERVERS.NET.
+SECTION ADDITIONAL
+K.ROOT-SERVERS.NET.    IN      A       193.0.14.129
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION AUTHORITY
+com.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN A
+SECTION AUTHORITY
+net.   IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.    IN      A       192.5.6.30
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net.
+RANGE_BEGIN 0 100
+       ADDRESS 192.5.6.30
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+com. IN NS
+SECTION ANSWER
+com.    IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.     IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+net. IN NS
+SECTION ANSWER
+net.    IN NS   a.gtld-servers.net.
+SECTION ADDITIONAL
+a.gtld-servers.net.     IN      A       192.5.6.30
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN A
+SECTION AUTHORITY
+example.net.   IN NS   ns.example.net.
+SECTION ADDITIONAL
+ns.example.net.                IN      A       1.2.3.5
+ENTRY_END
+RANGE_END
+
+; ns.example.com. - DNAME with TTL=0 (RRSIG Original TTL=0)
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.    IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.         IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN DNSKEY
+SECTION ANSWER
+example.com.    3600    IN      DNSKEY  256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
+example.com. 3600    IN      RRSIG   DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
+SECTION AUTHORITY
+example.com.   IN NS   ns.example.com.
+example.com.    3600    IN      RRSIG   NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
+SECTION ADDITIONAL
+ns.example.com.                IN      A       1.2.3.4
+ns.example.com. 3600    IN      RRSIG   A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
+ENTRY_END
+
+; DNAME with TTL=0, RRSIG Original TTL=0 (signed with ldns-signzone)
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+foo.test-dname.example.com. IN A
+SECTION ANSWER
+test-dname.example.com.        0       IN      DNAME   example.net.
+test-dname.example.com.        0       IN      RRSIG   DNAME 3 3 0 20070926135752 20070829135752 2854 example.com. ADRb2Jl5SCTF2a9/5QFOCfwFzh4Cpt90pJptwrKc+vBHnlivGyPShrU=
+foo.test-dname.example.com. 0 IN CNAME foo.example.net.
+ENTRY_END
+
+RANGE_END
+
+; ns.example.net.
+RANGE_BEGIN 0 100
+       ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN NS
+SECTION ANSWER
+example.net.   IN NS   ns.example.net.
+example.net.    3600    IN      RRSIG   NS RSASHA1 2 3600 20070926134150 20070829134150 30899 example.net. E8JX0l4B+cSR5bkHQwOJy1pBmlLMTYCJ8EwfNMU/eCv0YhKwo26rHhn52FGisgv+Nwp7/NbhHqQ+kJgoZC94XA== ;{id = 30899}
+SECTION ADDITIONAL
+ns.example.net.                IN      A       1.2.3.5
+ns.example.net. 3600    IN      RRSIG   A RSASHA1 3 3600 20070926134150 20070829134150 30899 example.net. x+tQMC9FhzT7Fcy1pM5NrOC7E8nLd7THPI3C6ie4EwL8PrxllqlR3q/DKB0d/m0qCOPcgN6HFOYURV1s4uAcsw== ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+example.net. IN DNSKEY
+SECTION ANSWER
+example.net.    3600    IN      DNSKEY  256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
+example.net.    3600    IN      RRSIG   DNSKEY RSASHA1 2 3600 20070926134150 20070829134150 30899 example.net. hiFzlQ8VoYgCuvIsfVuxC3mfJDqsTh0yc6abs5xMx5uEcIjb0dndFQx7INOM+imlzveEN73Hqp4OLFpFhsWLlw== ;{id = 30899}
+SECTION AUTHORITY
+example.net.   IN NS   ns.example.net.
+example.net.    3600    IN      RRSIG   NS RSASHA1 2 3600 20070926134150 20070829134150 30899 example.net. E8JX0l4B+cSR5bkHQwOJy1pBmlLMTYCJ8EwfNMU/eCv0YhKwo26rHhn52FGisgv+Nwp7/NbhHqQ+kJgoZC94XA== ;{id = 30899}
+SECTION ADDITIONAL
+ns.example.net.                IN      A       1.2.3.5
+ns.example.net. 3600    IN      RRSIG   A RSASHA1 3 3600 20070926134150 20070829134150 30899 example.net. x+tQMC9FhzT7Fcy1pM5NrOC7E8nLd7THPI3C6ie4EwL8PrxllqlR3q/DKB0d/m0qCOPcgN6HFOYURV1s4uAcsw== ;{id = 30899}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+foo.example.net. IN A
+SECTION ANSWER
+foo.example.net. IN    A       11.12.13.15
+foo.example.net.       3600    IN      RRSIG   A 5 3 3600 20070926134150 20070829134150 30899 example.net. X6T6SE9UzxAD/4zKpwGOxEDyE4g7lfYYw3lvw533uwRN8mWTcBvSva0/jjyhrogJcuLO32jPHK6zGb93w2xnuA==
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+foo2.example.net. IN A
+SECTION ANSWER
+foo2.example.net. IN   A       11.12.13.16
+foo2.example.net.      3600    IN      RRSIG   A 5 3 3600 20070926134150 20070829134150 30899 example.net. BZm+GljD8m9N+pNJN8D+LlSyHqM+InNUe0+heKILR9be+Goqv6SEb7LKtX6+kj3239Y5by7u+/Cuk8kkWistEQ==
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ENTRY_END
+RANGE_END
+
+; ns.example.com. - it has retracted the DNAME
+RANGE_BEGIN 100 200
+       ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR NOERROR
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+SECTION ANSWER
+foo2.test-dname.example.com.   3600    IN      A       10.20.30.40
+foo2.test-dname.example.com.   3600    IN      RRSIG   A 3 4 3600 20070926135752 20070829135752 2854 example.com. AI9LJPn/HKBYnuSTnK3Pv9eV+m3aYOa6ogB/jtUoWASLmYHXuetNFGw=
+ENTRY_END
+RANGE_END
+
+STEP 1 TIME_PASSES ELAPSE 10
+; First query: get DNAME TTL=0 into cache
+STEP 10 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+foo.test-dname.example.com. IN A
+ENTRY_END
+
+STEP 20 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+foo.test-dname.example.com. IN A
+SECTION ANSWER
+test-dname.example.com.        0       IN      DNAME   example.net.
+test-dname.example.com.        0       IN      RRSIG   DNAME 3 3 0 20070926135752 20070829135752 2854 example.com. ADRb2Jl5SCTF2a9/5QFOCfwFzh4Cpt90pJptwrKc+vBHnlivGyPShrU=
+foo.test-dname.example.com. 0 IN CNAME foo.example.net.
+foo.example.net. IN    A       11.12.13.15
+foo.example.net.       3600    IN      RRSIG   A 5 3 3600 20070926134150 20070829134150 30899 example.net. X6T6SE9UzxAD/4zKpwGOxEDyE4g7lfYYw3lvw533uwRN8mWTcBvSva0/jjyhrogJcuLO32jPHK6zGb93w2xnuA==
+ENTRY_END
+
+STEP 29 TIME_PASSES ELAPSE 0.1
+
+; Second query: within grace period (TIME_PASSES above)
+; With cache grace: synthesis from cached TTL=0 DNAME
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+ENTRY_END
+
+; foo2.test-dname.example.com is not answered upstream
+; so this reply is synthesized by the cached (1 second grace period) DNAME
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+SECTION ANSWER
+test-dname.example.com.        0       IN      DNAME   example.net.
+test-dname.example.com.        0       IN      RRSIG   DNAME 3 3 0 20070926135752 20070829135752 2854 example.com. ADRb2Jl5SCTF2a9/5QFOCfwFzh4Cpt90pJptwrKc+vBHnlivGyPShrU=
+foo2.test-dname.example.com. 0 IN CNAME foo2.example.net.
+foo2.example.net.      3600    IN      A       11.12.13.16
+foo2.example.net.      3600    IN      RRSIG   A 5 3 3600 20070926134150 20070829134150 30899 example.net. BZm+GljD8m9N+pNJN8D+LlSyHqM+InNUe0+heKILR9be+Goqv6SEb7LKtX6+kj3239Y5by7u+/Cuk8kkWistEQ==
+ENTRY_END
+
+STEP 45 TIME_PASSES ELAPSE 0.2
+
+STEP 46 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+ENTRY_END
+
+STEP 47 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+SECTION ANSWER
+test-dname.example.com.        0       IN      DNAME   example.net.
+test-dname.example.com.        0       IN      RRSIG   DNAME 3 3 0 20070926135752 20070829135752 2854 example.com. ADRb2Jl5SCTF2a9/5QFOCfwFzh4Cpt90pJptwrKc+vBHnlivGyPShrU=
+foo2.test-dname.example.com. 0 IN CNAME foo2.example.net.
+foo2.example.net.      3600    IN      A       11.12.13.16
+foo2.example.net.      3600    IN      RRSIG   A 5 3 3600 20070926134150 20070829134150 30899 example.net. BZm+GljD8m9N+pNJN8D+LlSyHqM+InNUe0+heKILR9be+Goqv6SEb7LKtX6+kj3239Y5by7u+/Cuk8kkWistEQ==
+ENTRY_END
+
+STEP 50 TIME_PASSES ELAPSE 0.5
+
+STEP 51 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+ENTRY_END
+
+STEP 52 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+SECTION ANSWER
+test-dname.example.com.        0       IN      DNAME   example.net.
+test-dname.example.com.        0       IN      RRSIG   DNAME 3 3 0 20070926135752 20070829135752 2854 example.com. ADRb2Jl5SCTF2a9/5QFOCfwFzh4Cpt90pJptwrKc+vBHnlivGyPShrU=
+foo2.test-dname.example.com. 0 IN CNAME foo2.example.net.
+foo2.example.net.      3600    IN      A       11.12.13.16
+foo2.example.net.      3600    IN      RRSIG   A 5 3 3600 20070926134150 20070829134150 30899 example.net. BZm+GljD8m9N+pNJN8D+LlSyHqM+InNUe0+heKILR9be+Goqv6SEb7LKtX6+kj3239Y5by7u+/Cuk8kkWistEQ==
+ENTRY_END
+
+STEP 55 TIME_PASSES ELAPSE 0.5
+
+STEP 56 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+ENTRY_END
+
+STEP 57 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+SECTION ANSWER
+test-dname.example.com.        0       IN      DNAME   example.net.
+test-dname.example.com.        0       IN      RRSIG   DNAME 3 3 0 20070926135752 20070829135752 2854 example.com. ADRb2Jl5SCTF2a9/5QFOCfwFzh4Cpt90pJptwrKc+vBHnlivGyPShrU=
+foo2.test-dname.example.com. 0 IN CNAME foo2.example.net.
+foo2.example.net.      3599    IN      A       11.12.13.16
+foo2.example.net.      3599    IN      RRSIG   A 5 3 3600 20070926134150 20070829134150 30899 example.net. BZm+GljD8m9N+pNJN8D+LlSyHqM+InNUe0+heKILR9be+Goqv6SEb7LKtX6+kj3239Y5by7u+/Cuk8kkWistEQ==
+ENTRY_END
+
+; upstream has new DNAME record to check.
+STEP 110 TIME_PASSES ELAPSE 0.8
+
+STEP 111 QUERY
+ENTRY_BEGIN
+REPLY RD DO
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+ENTRY_END
+
+STEP 112 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA AD DO NOERROR
+SECTION QUESTION
+foo2.test-dname.example.com. IN A
+SECTION ANSWER
+foo2.test-dname.example.com.   3600    IN      A       10.20.30.40
+foo2.test-dname.example.com.   3600    IN      RRSIG   A 3 4 3600 20070926135752 20070829135752 2854 example.com. AI9LJPn/HKBYnuSTnK3Pv9eV+m3aYOa6ogB/jtUoWASLmYHXuetNFGw=
+ENTRY_END
+SCENARIO_END
index e0c4768a6127b29d5fd0000712bbad1d1240d98f..81f8800122209ad1d73c1694037e8c715a878ea6 100644 (file)
@@ -483,9 +483,12 @@ parse_copy_decompress_rrset(sldns_buffer* pkt, struct msg_parse* msg,
        }
        pk->entry.data = (void*)data;
        pk->entry.key = (void*)pk;
-       pk->entry.hash = pset->hash;
-       data->trust = get_rrset_trust(msg, pset);
        pk->rk.flags |= (data->ttl == 0) ? PACKED_RRSET_UPSTREAM_0TTL : 0;
+       if( (pk->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) != 0)
+               pk->entry.hash = rrset_key_hash(&pk->rk);
+       else
+               pk->entry.hash = pset->hash;
+       data->trust = get_rrset_trust(msg, pset);
        return 1;
 }
 
index 4e0911ccf0a293332d91153166b8e92169bb8f5e..454a5da4761a152dc84c253a619ea71d4596adc3 100644 (file)
@@ -72,6 +72,8 @@ typedef uint64_t rrset_id_type;
 #define PACKED_RRSET_UNVERIFIED_GLUE 0x10
 /** this rrset has a 0TTL from upstream */
 #define PACKED_RRSET_UPSTREAM_0TTL 0x20
+/** this rrset has 0TTL from upstream and also has had grace TTL applied */
+#define PACKED_RRSET_0TTL_GRACE 0x40
 
 /** number of rrs and rrsets for integer overflow protection.  More than
  * this is not really possible (64K packet has much less RRs and RRsets) in