* @param env: module environment with caches.
* @param rep: contains list of rrsets to store.
* @param now: current time.
+ * @param leeway: during prefetch how much leeway to update TTLs.
+ * This makes rrsets (other than type NS) timeout sooner so they get
+ * updated with a new full TTL.
+ * Type NS does not get this, because it must not be refreshed from the
+ * child domain, but keep counting down properly.
* @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,
- struct reply_info* qrep, struct regional* region)
+ uint32_t leeway, struct reply_info* qrep, struct regional* region)
{
size_t i;
/* see if rrset already exists in cache, if not insert it. */
rep->ref[i].id = rep->rrsets[i]->id;
/* update ref if it was in the cache */
switch(rrset_cache_update(env->rrset_cache, &rep->ref[i],
- env->alloc, now)) {
+ env->alloc, now + ((ntohs(rep->ref[i].key->rk.type)==
+ LDNS_RR_TYPE_NS)?0:leeway))) {
case 0: /* ref unchanged, item inserted */
break;
case 2: /* ref updated, cache is superior */
/* 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, qrep, region);
+ 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 */
ref.key = rep->rrsets[i];
ref.id = rep->rrsets[i]->id;
/*ignore ret: it was in the cache, ref updated */
+ /* no leeway for typeNS */
(void)rrset_cache_update(env->rrset_cache, &ref,
- env->alloc, *env->now + leeway);
+ env->alloc, *env->now +
+ ((ntohs(ref.key->rk.type)==LDNS_RR_TYPE_NS)?
+ 0:leeway));
}
free(rep);
return 1;
--- /dev/null
+; 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 2.
+; for slightly different query pattern.
+
+; 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. 300 IN NS old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com. 300 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. 300 IN A 10.1.1.1
+SECTION AUTHORITY
+example.com. 300 IN NS old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com. 300 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. 86400 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. 300 IN A 10.1.1.1
+SECTION AUTHORITY
+example.com. 300 IN NS old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com. 300 IN A 192.168.0.1
+ENTRY_END
+
+; after 40 secs still the cached answer
+STEP 20 TIME_PASSES ELAPSE 40
+
+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. 260 IN A 10.1.1.1
+SECTION AUTHORITY
+example.com. 260 IN NS old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com. 260 IN A 192.168.0.1
+ENTRY_END
+
+; after 230 we are 30 seconds before expiry, prefetch happens.
+STEP 50 TIME_PASSES ELAPSE 230
+
+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. 30 IN A 10.1.1.1
+SECTION AUTHORITY
+example.com. 30 IN NS old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com. 30 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. 300 IN A 10.1.1.1
+SECTION AUTHORITY
+example.com. 30 IN NS old-ns.example.com.
+SECTION ADDITIONAL
+old-ns.example.com. 300 IN A 192.168.0.1
+ENTRY_END
+
+; the NS record times out after 31 seconds.
+STEP 160 TIME_PASSES ELAPSE 31
+
+; 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. 86400 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. 86400 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
SCENARIO_BEGIN Test resolver prefetch of NS record for moved domain
; K.ROOT-SERVERS.NET.
-RANGE_BEGIN 0 100
+RANGE_BEGIN 0 200
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
STEP 80 TRAFFIC
; let traffic flow for prefetch to happen
+; check result of that prefetch
+STEP 90 QUERY
+ENTRY_BEGIN
+REPLY RD
+SECTION QUESTION
+example.com. IN NS
+ENTRY_END
+; recursion happens here.
+STEP 91 CHECK_ANSWER
+ENTRY_BEGIN
+MATCH all ttl
+REPLY QR RD RA NOERROR
+SECTION QUESTION
+example.com. IN NS
+SECTION ANSWER
+; this record is unchanged even though it now points to the
+; new registrant. Thus it keeps counting down.
+example.com. 360 IN NS ns.example.com.
+SECTION AUTHORITY
+SECTION ADDITIONAL
+ns.example.com. 3600 IN A 8.8.8.8
+ENTRY_END
+
+
; after 360 + 2000 we are after the change to new owner.
STEP 100 TIME_PASSES ELAPSE 2360
SECTION ANSWER
www.example.com. 3600 IN A 88.88.88.88
SECTION AUTHORITY
-example.com. 1240 IN NS ns.example.com.
+example.com. 3600 IN NS ns.example.com.
SECTION ADDITIONAL
-ns.example.com. 820 IN A 8.8.8.8
+ns.example.com. 1240 IN A 8.8.8.8
ENTRY_END
SCENARIO_END