]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix bug #425: unbound reports wrong TTL in reply, it reports a TTL
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 10 Jan 2012 09:42:32 +0000 (09:42 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 10 Jan 2012 09:42:32 +0000 (09:42 +0000)
  that would be permissible by the RFCs but it is not the TTL in the
  cache.

git-svn-id: file:///svn/unbound/trunk@2581 be551aaa-1e26-0410-a405-d3ace91eadb9

16 files changed:
daemon/cachedump.c
doc/Changelog
iterator/iter_scrub.c
iterator/iter_utils.c
iterator/iter_utils.h
iterator/iterator.c
pythonmod/pythonmod_utils.c
services/cache/dns.c
services/cache/dns.h
services/cache/rrset.c
services/cache/rrset.h
testdata/iter_domain_sale.rpl
testdata/iter_prefetch_change.rpl [new file with mode: 0644]
testdata/iter_prefetch_ns.rpl
testdata/rrset_rettl.rpl
validator/validator.c

index 41a15e266d222dc4e59db7e1a005ed47ac4977f4..e5be8564e10d3de56009ccd6b1a5f7ab6d5523b3 100644 (file)
@@ -765,7 +765,7 @@ load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker)
        if(!go_on) 
                return 1; /* skip this one, not all references satisfied */
 
-       if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0)) {
+       if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, NULL)) {
                log_warn("error out of memory");
                return 0;
        }
index 307d2ccbd16a703f2e210e001b2451566d9939a4..ea9d05443f5682a1567801c0f0398c4a2221fa3a 100644 (file)
@@ -1,3 +1,8 @@
+10 January 2012: Wouter
+       - Fix bug #425: unbound reports wrong TTL in reply, it reports a TTL
+         that would be permissible by the RFCs but it is not the TTL in the
+         cache.
+
 2 January 2012: Wouter
        - Fix to randomize hash function, based on 28c3 congress, reported
          by Peter van Dijk.
index aa6d6450dcd9d208f46b8cb7d7c03139b0938db6..6147c96a9e37eb9e0e7e18fa48d90ed299b01d88 100644 (file)
@@ -535,8 +535,7 @@ store_rrset(ldns_buffer* pkt, struct msg_parse* msg, struct module_env* env,
        ref.key = k;
        ref.id = k->id;
        /*ignore ret: it was in the cache, ref updated */
-       (void)rrset_cache_update(env->rrset_cache, &ref,
-               env->alloc, now);
+       (void)rrset_cache_update(env->rrset_cache, &ref, env->alloc, now);
 }
 
 /** Check if there are SOA records in the authority section (negative) */
index ee04339eeef2682aff0b45347b30d96282a40da4..25fda5eb38e286f3a132f80890cd0320f3cd2206 100644 (file)
@@ -425,9 +425,11 @@ dns_copy_msg(struct dns_msg* from, struct regional* region)
 
 int 
 iter_dns_store(struct module_env* env, struct query_info* msgqinf,
-       struct reply_info* msgrep, int is_referral, uint32_t leeway)
+       struct reply_info* msgrep, int is_referral, uint32_t leeway,
+       struct regional* region)
 {
-       return dns_cache_store(env, msgqinf, msgrep, is_referral, leeway);
+       return dns_cache_store(env, msgqinf, msgrep, is_referral, leeway,
+               region);
 }
 
 int 
index d048ad8a2d38802f60f518314c50a81ea317f114..6d2f862acb22a9c181673d21918c79a55d732e95 100644 (file)
@@ -121,10 +121,12 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional);
  * @param is_referral: If true, then the given message to be stored is a
  *     referral. The cache implementation may use this as a hint.
  * @param leeway: prefetch TTL leeway to expire old rrsets quicker.
+ * @param region: to copy modified (cache is better) rrs back to.
  * @return 0 on alloc error (out of memory).
  */
 int iter_dns_store(struct module_env* env, struct query_info* qinf,
-       struct reply_info* rep, int is_referral, uint32_t leeway);
+       struct reply_info* rep, int is_referral, uint32_t leeway,
+       struct regional* region);
 
 /**
  * Select randomly with n/m probability.
index efe1bcec6fde57899214cd22865d6fb2792c3aab..432fdc4773a21ed05a2b87cae2d39002548de25e 100644 (file)
@@ -260,7 +260,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
        /* do not waste time trying to validate this servfail */
        err.security = sec_status_indeterminate;
        verbose(VERB_ALGO, "store error response in message cache");
-       if(!iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0)) {
+       if(!iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, NULL)) {
                log_err("error_response_cache: could not store error (nomem)");
        }
        return error_response(qstate, id, rcode);
@@ -1832,7 +1832,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                                "nodata ANSWER"));
                }
                if(!iter_dns_store(qstate->env, &iq->response->qinfo,
-                       iq->response->rep, 0, qstate->prefetch_leeway))
+                       iq->response->rep, 0, qstate->prefetch_leeway,
+                       qstate->region))
                        return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
                /* close down outstanding requests to be discarded */
                outbound_list_clear(&iq->outlist);
@@ -1871,7 +1872,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                        /* Store the referral under the current query */
                        /* no prefetch-leeway, since its not the answer */
                        if(!iter_dns_store(qstate->env, &iq->response->qinfo,
-                               iq->response->rep, 1, 0))
+                               iq->response->rep, 1, 0, NULL))
                                return error_response(qstate, id, 
                                        LDNS_RCODE_SERVFAIL);
                        if(iq->store_parent_NS)
@@ -1957,7 +1958,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
                 * the partial query answer (CNAME only). */
                /* prefetchleeway applied because this updates answer parts */
                if(!iter_dns_store(qstate->env, &iq->response->qinfo,
-                       iq->response->rep, 1, qstate->prefetch_leeway))
+                       iq->response->rep, 1, qstate->prefetch_leeway, NULL))
                        return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
                /* set the current request's qname to the new value. */
                iq->qchase.qname = sname;
@@ -2433,7 +2434,8 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
                 * from cache does not need to be stored in the msg cache. */
                if(qstate->query_flags&BIT_RD) {
                        if(!iter_dns_store(qstate->env, &qstate->qinfo, 
-                               iq->response->rep, 0, qstate->prefetch_leeway))
+                               iq->response->rep, 0, qstate->prefetch_leeway,
+                               qstate->region))
                                return error_response(qstate, id, 
                                        LDNS_RCODE_SERVFAIL);
                }
index bd0ef3708a3f32a950887635df09c8de0f2ed509..52cfad0a6f9282ebfd4c5f3de6bff39ac51640d7 100644 (file)
@@ -66,7 +66,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, st
     }
 
     return dns_cache_store(qstate->env, qinfo, msgrep, is_referral, 
-       qstate->prefetch_leeway);
+       qstate->prefetch_leeway, NULL);
 }
 
 /*  Invalidate the message associated with query_info stored in message cache */
index 2fb8a64369bb95e39b19edc771ddd1fa8d9c6174..49234ab4154ef17548e025185cac22db77ae23ef 100644 (file)
  * @param env: module environment with caches.
  * @param rep: contains list of rrsets to store.
  * @param now: current time.
+ * @param qrep: update rrsets here if cache is better
+ * @param region: for qrep allocs.
  */
 static void
-store_rrsets(struct module_env* env, struct reply_info* rep, uint32_t now)
+store_rrsets(struct module_env* env, struct reply_info* rep, uint32_t now,
+       struct reply_info* qrep, struct regional* region)
 {
         size_t i;
         /* see if rrset already exists in cache, if not insert it. */
         for(i=0; i<rep->rrset_count; i++) {
                 rep->ref[i].key = rep->rrsets[i];
                 rep->ref[i].id = rep->rrsets[i]->id;
-                if(rrset_cache_update(env->rrset_cache, &rep->ref[i],
-                        env->alloc, now)) /* it was in the cache */
+               /* update ref if it was in the cache */ 
+               switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
+                        env->alloc, now)) {
+               case 0: /* ref unchanged, item inserted */
+                       break;
+               case 2: /* ref updated, cache is superior */
+                       if(region) {
+                               struct ub_packed_rrset_key* ck;
+                               lock_rw_rdlock(&rep->ref[i].key->entry.lock);
+                               /* if deleted rrset, do not copy it */
+                               if(rep->ref[i].key->id == 0)
+                                       ck = NULL;
+                               else    ck = packed_rrset_copy_region(
+                                       rep->ref[i].key, region, now);
+                               lock_rw_unlock(&rep->ref[i].key->entry.lock);
+                               if(ck) {
+                                       /* use cached copy if memory allows */
+                                       qrep->rrsets[i] = ck;
+                               }
+                       }
+                       /* no break: also copy key item */
+               case 1: /* ref updated, item inserted */
                         rep->rrsets[i] = rep->ref[i].key;
+               }
         }
 }
 
 void 
 dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
-       hashvalue_t hash, struct reply_info* rep, uint32_t leeway)
+       hashvalue_t hash, struct reply_info* rep, uint32_t leeway,
+       struct reply_info* qrep, struct regional* region)
 {
        struct msgreply_entry* e;
        uint32_t ttl = rep->ttl;
@@ -83,9 +108,11 @@ dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
                rep->ref[i].key = rep->rrsets[i];
                rep->ref[i].id = rep->rrsets[i]->id;
        }
-       reply_info_sortref(rep);
+
+       /* there was a reply_info_sortref(rep) here but it seems to be
+        * unnecessary, because the cache gets locked per rrset. */
        reply_info_set_ttls(rep, *env->now);
-       store_rrsets(env, rep, *env->now+leeway);
+       store_rrsets(env, rep, *env->now+leeway, qrep, region);
        if(ttl == 0) {
                /* we do not store the message, but we did store the RRs,
                 * which could be useful for delegation information */
@@ -703,7 +730,8 @@ dns_cache_lookup(struct module_env* env,
 
 int 
 dns_cache_store(struct module_env* env, struct query_info* msgqinf,
-        struct reply_info* msgrep, int is_referral, uint32_t leeway)
+        struct reply_info* msgrep, int is_referral, uint32_t leeway,
+       struct regional* region)
 {
        struct reply_info* rep = NULL;
        /* alloc, malloc properly (not in region, like msg is) */
@@ -746,7 +774,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
                rep->flags |= (BIT_RA | BIT_QR);
                rep->flags &= ~(BIT_AA | BIT_CD);
                h = query_info_hash(&qinf);
-               dns_cache_store_msg(env, &qinf, h, rep, leeway);
+               dns_cache_store_msg(env, &qinf, h, rep, leeway, msgrep, region);
                /* qname is used inside query_info_entrysetup, and set to 
                 * NULL. If it has not been used, free it. free(0) is safe. */
                free(qinf.qname);
index 561e13d6434852aa6e2a3f2def7bab58e4303070..76705ab7f012b54bb628cd060040bcbe6b31167a 100644 (file)
@@ -74,10 +74,13 @@ struct dns_msg {
  *      It will store only the RRsets, not the message.
  * @param leeway: TTL value, if not 0, other rrsets are considered expired
  *     that many seconds before actual TTL expiry.
+ * @param region: region to allocate better entries from cache into.
+ *   (used when is_referral is false).
  * @return 0 on alloc error (out of memory).
  */
 int dns_cache_store(struct module_env* env, struct query_info* qinf,
-        struct reply_info* rep, int is_referral, uint32_t leeway); 
+        struct reply_info* rep, int is_referral, uint32_t leeway,
+       struct regional* region); 
 
 /**
  * Store message in the cache. Stores in message cache and rrset cache.
@@ -92,9 +95,12 @@ int dns_cache_store(struct module_env* env, struct query_info* qinf,
  *     Adjusts the reply info TTLs to absolute time.
  * @param leeway: TTL value, if not 0, other rrsets are considered expired
  *     that many seconds before actual TTL expiry.
+ * @param qrep: message that can be altered with better rrs from cache.
+ * @param region: to allocate into for qmsg.
  */
 void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo,
-       hashvalue_t hash, struct reply_info* rep, uint32_t leeway);
+       hashvalue_t hash, struct reply_info* rep, uint32_t leeway,
+       struct reply_info* qrep, struct regional* region);
 
 /**
  * Find a delegation from the cache.
index 33660f89fb4018cff8d4718e130a621fc68cbea3..92447317dd9242025196160790a5e45d4d5709b6 100644 (file)
@@ -207,7 +207,7 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
                        /* cache is superior, return that value */
                        lock_rw_unlock(&e->lock);
                        ub_packed_rrset_parsedelete(k, alloc);
-                       return 1;
+                       return 2;
                }
                lock_rw_unlock(&e->lock);
                /* Go on and insert the passed item.
index e414107d258a65ed67eba5a0ff60afe3475f04d9..f1c34d67a350d58f3519a813908fadcffb6d4d4a 100644 (file)
@@ -125,6 +125,9 @@ void rrset_cache_touch(struct rrset_cache* r, struct ub_packed_rrset_key* key,
  * @param alloc: how to allocate (and deallocate) the special rrset key.
  * @param timenow: current time (to see if ttl in cache is expired).
  * @return: true if the passed reference is updated, false if it is unchanged.
+ *     0: reference unchanged, inserted in cache.
+ *     1: reference updated, item is inserted in cache.
+ *     2: reference updated, item in cache is considered superior.
  */
 int rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref, 
        struct alloc_cache* alloc, uint32_t timenow);
index cc46bce99c8ab6932de71ca3597ef0682a045c67..724b51dadb1151ba93489cb742094a3b582a7a35 100644 (file)
@@ -239,9 +239,9 @@ nx1.example.com. IN A
 SECTION ANSWER
 SECTION AUTHORITY
 example.com.   3600 IN SOA     a. b. 1 2 3 4 5
-example.com.   3600 IN NS      ns.example.com.
+example.com.   1800 IN NS      ns.example.com.
 SECTION ADDITIONAL
-ns.example.com.        3600    IN      A       1.2.3.4
+ns.example.com.        1800    IN      A       1.2.3.4
 ENTRY_END
 
 ; after another 1900 seconds the domain must have timed out.
diff --git a/testdata/iter_prefetch_change.rpl b/testdata/iter_prefetch_change.rpl
new file mode 100644 (file)
index 0000000..2ed70cd
--- /dev/null
@@ -0,0 +1,364 @@
+; config options
+server:
+       target-fetch-policy: "0 0 0 0 0"
+       prefetch: "yes"
+
+stub-zone:
+       name: "."
+       stub-addr: 193.0.14.129         # K.ROOT-SERVERS.NET.
+CONFIG_END
+
+SCENARIO_BEGIN Test resolver prefetch and a moved domain
+; for bug #425.
+
+; K.ROOT-SERVERS.NET.
+RANGE_BEGIN 0 500
+       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 A
+SECTION AUTHORITY
+com.   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. (before sale of domain)
+RANGE_BEGIN 0 30
+       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 subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com.   86400 IN NS     old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com.            86400 IN        A       192.168.0.1
+ENTRY_END
+RANGE_END
+
+; a.gtld-servers.net. (after sale of domain)
+RANGE_BEGIN 40 500
+       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 subdomain
+ADJUST copy_id copy_query
+REPLY QR NOERROR
+SECTION QUESTION
+example.com. IN A
+SECTION AUTHORITY
+example.com.   86400 IN NS     new-ns.example.com.
+SECTION ADDITIONAL
+new-ns.example.com.            86400 IN        A       172.16.0.1
+ENTRY_END
+RANGE_END
+
+; ns.example.com. first owner
+RANGE_BEGIN 0 500
+       ADDRESS 192.168.0.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.   86400 IN NS     old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com.            86400 IN        A       192.168.0.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A     10.1.1.1
+SECTION AUTHORITY
+example.com.   86400 IN NS     old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com.            86400 IN        A       192.168.0.1
+ENTRY_END
+RANGE_END
+
+; ns.example.com. new owner
+RANGE_BEGIN 0 500
+       ADDRESS 172.16.0.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+example.com.   86400 IN NS     new-ns.example.com.
+SECTION ADDITIONAL
+new-ns.example.com.            86400 IN        A       172.16.0.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+old-ns.example.com. IN A
+SECTION ANSWER
+old-ns.example.com. 86400 IN A 172.16.0.1
+SECTION AUTHORITY
+example.com.   86400 IN NS     new-ns.example.com.
+SECTION ADDITIONAL
+new-ns.example.com.            86400 IN        A       172.16.0.1
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com. 3600 IN A     10.2.2.2
+SECTION AUTHORITY
+example.com.   86400 IN NS     new-ns.example.com.
+SECTION ADDITIONAL
+new-ns.example.com.            86400 IN        A       172.16.0.1
+ENTRY_END
+RANGE_END
+
+STEP 1 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 10 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com.       3600 IN A       10.1.1.1
+SECTION AUTHORITY
+example.com.           86400 IN NS     old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com.    86400 IN A      192.168.0.1
+ENTRY_END
+
+; after 1800 secs still the cached answer
+STEP 20 TIME_PASSES ELAPSE 1800
+
+STEP 30 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 40 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com.       1800 IN A       10.1.1.1
+SECTION AUTHORITY
+example.com.           84600 IN NS     old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com.    84600 IN A      192.168.0.1
+ENTRY_END
+
+; after 1440 we are 360 seconds before the expiry
+; but it still contacts the old-ns
+STEP 50 TIME_PASSES ELAPSE 1440
+
+STEP 60 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 70 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com.       360 IN A        10.1.1.1
+SECTION AUTHORITY
+example.com.           83160 IN NS     old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com.    83160 IN A      192.168.0.1
+ENTRY_END
+
+STEP 80 TRAFFIC
+; let traffic flow for prefetch to happen
+
+; we updated from the old-ns.
+STEP 90 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 100 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com.       3600 IN A       10.1.1.1
+SECTION AUTHORITY
+example.com.           83160 IN NS     old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com.    83160 IN A      192.168.0.1
+ENTRY_END
+
+; the NS record is now 10% from expiry (8640 TTL left).
+; and the A record has expired completely, retry.
+STEP 110 TIME_PASSES ELAPSE 74520
+
+; the NS record should have timed out.
+; but you see the full TTL here, this is only for *this query*
+; in the cache itself its 8640, not 86400.
+STEP 120 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 130 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com.       3600 IN A       10.1.1.1
+SECTION AUTHORITY
+example.com.           8640 IN NS      old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com.    8640 IN A       192.168.0.1
+ENTRY_END
+
+; get it from cache
+STEP 140 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 150 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com.       3600 IN A       10.1.1.1
+SECTION AUTHORITY
+example.com.           8640 IN NS      old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com.    8640 IN A       192.168.0.1
+ENTRY_END
+
+; the NS record times out after 8640 seconds.
+STEP 160 TIME_PASSES ELAPSE 8641
+
+; fetch it
+STEP 170 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 180 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com.       3600 IN A       10.2.2.2
+SECTION AUTHORITY
+example.com.           86400 IN NS     new-ns.example.com.
+SECTION ADDITIONAL
+new-ns.example.com.    86400 IN A      172.16.0.1
+ENTRY_END
+
+; a reply from cache 
+STEP 190 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+www.example.com. IN A
+ENTRY_END
+; recursion happens here.
+STEP 200 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+www.example.com. IN A
+SECTION ANSWER
+www.example.com.       3600 IN A       10.2.2.2
+SECTION AUTHORITY
+example.com.           86400 IN NS     new-ns.example.com.
+SECTION ADDITIONAL
+new-ns.example.com.    86400 IN A      172.16.0.1
+ENTRY_END
+
+SCENARIO_END
index c0ffdb86c384b8117554567281e7bd7abd27ba5b..219e48396f97ae2fd60eeed34ca087203f8357ae 100644 (file)
@@ -285,9 +285,9 @@ www.example.com. IN A
 SECTION ANSWER
 www.example.com. 3600 IN A     88.88.88.88
 SECTION AUTHORITY
-example.com.   3600 IN NS      ns.example.com.
+example.com.   1240 IN NS      ns.example.com.
 SECTION ADDITIONAL
-ns.example.com.        3600    IN      A       8.8.8.8
+ns.example.com.        820     IN      A       8.8.8.8
 ENTRY_END
 
 SCENARIO_END
index b7e05eb8549943e7f5fe873ab2d9b1fc6889f9ed..2ae64e9476bb9d5ed9570dd4b255ca660c25cd81 100644 (file)
@@ -85,7 +85,7 @@ ENTRY_BEGIN
        SECTION ANSWER
        bla.example.com. IN A 10.20.30.140
        SECTION AUTHORITY
-       example.com. 200 IN NS ns.example.com.
+       example.com. 100 IN NS ns.example.com.
        SECTION ADDITIONAL
        ns.example.com. IN A 10.20.30.50
 ENTRY_END
index 0ac593d821109891ce02841bb86636ec0641dfe2..c05a8cf972881f23be9a720df81e5aaa97af7832 100644 (file)
@@ -1978,14 +1978,14 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
        /* store results in cache */
        if(qstate->query_flags&BIT_RD) {
                if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, 
-                       vq->orig_msg->rep, 0, qstate->prefetch_leeway)) {
+                       vq->orig_msg->rep, 0, qstate->prefetch_leeway, NULL)) {
                        log_err("out of memory caching validator results");
                }
        } else {
                /* for a referral, store the verified RRsets */
                /* and this does not get prefetched, so no leeway */
                if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, 
-                       vq->orig_msg->rep, 1, 0)) {
+                       vq->orig_msg->rep, 1, 0, NULL)) {
                        log_err("out of memory caching validator results");
                }
        }