diff --git a/CHANGES b/CHANGES index 726379d43f..3da1632ea4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4010. [cleanup] Clear the prefetchable state when initiating a prefetch. + [RT #37399] + 4009. [func] delv: added a +tcp option. [RT #37855] 4008. [contrib] Updated zkt to latest version (1.1.3). [RT #37886] diff --git a/bin/named/query.c b/bin/named/query.c index 4222b1721f..9a325523cd 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -3880,7 +3880,8 @@ query_prefetch(ns_client_t *client, dns_name_t *qname, ns_client_t *dummy = NULL; unsigned int options; - if (client->view->prefetch_trigger == 0U || + if (client->query.prefetch != NULL || + client->view->prefetch_trigger == 0U || rdataset->ttl > client->view->prefetch_trigger || (rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0) return; @@ -3893,8 +3894,6 @@ query_prefetch(ns_client_t *client, dns_name_t *qname, isc_stats_increment(ns_g_server->nsstats, dns_nsstatscounter_recursclients); } - if (client->query.prefetch != NULL) - return; tmprdataset = query_newrdataset(client); if (tmprdataset == NULL) @@ -3916,6 +3915,7 @@ query_prefetch(ns_client_t *client, dns_name_t *qname, query_putrdataset(client, &tmprdataset); ns_client_detach(&dummy); } + dns_rdataset_clearprefetch(rdataset); } static isc_result_t diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c index 06e1d8b67a..553a339bb5 100644 --- a/lib/dns/ecdb.c +++ b/lib/dns/ecdb.c @@ -113,7 +113,8 @@ static dns_rdatasetmethods_t rdataset_methods = { NULL, /* setadditional */ NULL, /* putadditional */ rdataset_settrust, /* settrust */ - NULL /* expire */ + NULL, /* expire */ + NULL /* clearprefetch */ }; typedef struct ecdb_rdatasetiter { diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h index 37b970611f..252738d075 100644 --- a/lib/dns/include/dns/rdataset.h +++ b/lib/dns/include/dns/rdataset.h @@ -114,6 +114,7 @@ typedef struct dns_rdatasetmethods { void (*settrust)(dns_rdataset_t *rdataset, dns_trust_t trust); void (*expire)(dns_rdataset_t *rdataset); + void (*clearprefetch)(dns_rdataset_t *rdataset); } dns_rdatasetmethods_t; #define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R') @@ -654,6 +655,17 @@ dns_rdataset_expire(dns_rdataset_t *rdataset); * Mark the rdataset to be expired in the backing database. */ +void +dns_rdataset_clearprefetch(dns_rdataset_t *rdataset); +/*%< + * Clear the PREFETCH attribute for the given rdataset in the + * underlying database. + * + * In the cache database, this signals that the rdataset is not + * eligible to be prefetched when the TTL is close to expiring. + * It has no function in other databases. + */ + void dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_rdata_rrsig_t *rrsig, isc_stdtime_t now, diff --git a/lib/dns/ncache.c b/lib/dns/ncache.c index bcb3d05789..53c822c37f 100644 --- a/lib/dns/ncache.c +++ b/lib/dns/ncache.c @@ -503,6 +503,7 @@ static dns_rdatasetmethods_t rdataset_methods = { NULL, NULL, rdataset_settrust, + NULL, NULL }; diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 58cb7bcba8..8ef04b2936 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -744,6 +744,7 @@ static void resign_delete(dns_rbtdb_t *rbtdb, rbtdb_version_t *version, static void prune_tree(isc_task_t *task, isc_event_t *event); static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); static void rdataset_expire(dns_rdataset_t *rdataset); +static void rdataset_clearprefetch(dns_rdataset_t *rdataset); static dns_rdatasetmethods_t rdataset_methods = { rdataset_disassociate, @@ -760,7 +761,8 @@ static dns_rdatasetmethods_t rdataset_methods = { rdataset_setadditional, rdataset_putadditional, rdataset_settrust, - rdataset_expire + rdataset_expire, + rdataset_clearprefetch }; static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); @@ -8721,6 +8723,19 @@ rdataset_expire(dns_rdataset_t *rdataset) { isc_rwlocktype_write); } +static void +rdataset_clearprefetch(dns_rdataset_t *rdataset) { + dns_rbtdb_t *rbtdb = rdataset->private1; + dns_rbtnode_t *rbtnode = rdataset->private2; + rdatasetheader_t *header = rdataset->private3; + + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); + header->attributes &= ~RDATASET_ATTR_PREFETCH; + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); +} + /* * Rdataset Iterator Methods */ diff --git a/lib/dns/rdatalist.c b/lib/dns/rdatalist.c index 63d8b116cf..9dc22f1b69 100644 --- a/lib/dns/rdatalist.c +++ b/lib/dns/rdatalist.c @@ -48,6 +48,7 @@ static dns_rdatasetmethods_t methods = { NULL, NULL, NULL, + NULL, NULL }; diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c index b7f12aa4ec..43c7b5b560 100644 --- a/lib/dns/rdataset.c +++ b/lib/dns/rdataset.c @@ -206,6 +206,7 @@ static dns_rdatasetmethods_t question_methods = { NULL, NULL, NULL, + NULL, NULL }; @@ -775,6 +776,15 @@ dns_rdataset_expire(dns_rdataset_t *rdataset) { (rdataset->methods->expire)(rdataset); } +void +dns_rdataset_clearprefetch(dns_rdataset_t *rdataset) { + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(rdataset->methods != NULL); + + if (rdataset->methods->clearprefetch != NULL) + (rdataset->methods->clearprefetch)(rdataset); +} + void dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, dns_rdata_rrsig_t *rrsig, isc_stdtime_t now, diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index 9367127d9e..e29dc8415a 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -466,6 +466,7 @@ static dns_rdatasetmethods_t rdataset_methods = { NULL, NULL, NULL, + NULL, NULL }; diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index 5556e2ca93..40e57e5cfc 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -1429,6 +1429,7 @@ static dns_rdatasetmethods_t methods = { NULL, NULL, NULL, + NULL, NULL }; diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c index 86a31f5b58..5cb143b9a3 100644 --- a/lib/dns/sdlz.c +++ b/lib/dns/sdlz.c @@ -1481,6 +1481,7 @@ static dns_rdatasetmethods_t rdataset_methods = { NULL, NULL, NULL, + NULL, NULL }; diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index 41c0c9cfda..57d5bc608d 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -608,6 +608,7 @@ dns_rdataclass_totext dns_rdatalist_init dns_rdatalist_tordataset dns_rdataset_additionaldata +dns_rdataset_clearprefetch dns_rdataset_clone dns_rdataset_count dns_rdataset_current