summaryrefslogtreecommitdiff
path: root/lib/dns/adb.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/adb.c')
-rw-r--r--lib/dns/adb.c112
1 files changed, 69 insertions, 43 deletions
diff --git a/lib/dns/adb.c b/lib/dns/adb.c
index 4fb3be4a..7e1cd984 100644
--- a/lib/dns/adb.c
+++ b/lib/dns/adb.c
@@ -15,7 +15,7 @@
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: adb.c,v 1.181.2.4.4.2 2003/02/17 07:05:07 marka Exp $ */
+/* $Id: adb.c,v 1.181.2.11 2003/07/25 04:36:45 marka Exp $ */
/*
* Implementation notes
@@ -87,6 +87,7 @@
*/
#define ADB_CACHE_MINIMUM 10 /* seconds */
#define ADB_CACHE_MAXIMUM 86400 /* seconds (86400 = 24 hours) */
+#define ADB_ENTRY_WINDOW 1800 /* seconds */
/*
* Wake up every CLEAN_SECONDS and clean CLEAN_BUCKETS buckets, so that all
@@ -341,7 +342,7 @@ static isc_result_t dbfind_a6(dns_adbname_t *, isc_stdtime_t);
#define NAME_IS_DEAD 0x40000000
#define NAME_HINT_OK DNS_ADBFIND_HINTOK
#define NAME_GLUE_OK DNS_ADBFIND_GLUEOK
-#define NAME_STARTATROOT DNS_ADBFIND_STARTATROOT
+#define NAME_STARTATZONE DNS_ADBFIND_STARTATZONE
#define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0)
#define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0)
#define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0)
@@ -382,7 +383,7 @@ static isc_result_t dbfind_a6(dns_adbname_t *, isc_stdtime_t);
#define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
#define FIND_AVOIDFETCHES(fn) (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) \
!= 0)
-#define FIND_STARTATROOT(fn) (((fn)->options & DNS_ADBFIND_STARTATROOT) \
+#define FIND_STARTATZONE(fn) (((fn)->options & DNS_ADBFIND_STARTATZONE) \
!= 0)
#define FIND_HINTOK(fn) (((fn)->options & DNS_ADBFIND_HINTOK) != 0)
#define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0)
@@ -406,8 +407,8 @@ static isc_result_t dbfind_a6(dns_adbname_t *, isc_stdtime_t);
#define GLUE_OK(nf, o) (!NAME_GLUEOK(nf) || (((o) & DNS_ADBFIND_GLUEOK) != 0))
#define HINT_OK(nf, o) (!NAME_HINTOK(nf) || (((o) & DNS_ADBFIND_HINTOK) != 0))
#define GLUEHINT_OK(nf, o) (GLUE_OK(nf, o) || HINT_OK(nf, o))
-#define STARTATROOT_MATCHES(nf, o) (((nf)->flags & NAME_STARTATROOT) == \
- ((o) & DNS_ADBFIND_STARTATROOT))
+#define STARTATZONE_MATCHES(nf, o) (((nf)->flags & NAME_STARTATZONE) == \
+ ((o) & DNS_ADBFIND_STARTATZONE))
#define ENTER_LEVEL 50
#define EXIT_LEVEL ENTER_LEVEL
@@ -496,6 +497,7 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
isc_result_t result;
dns_adb_t *adb;
dns_adbnamehook_t *nh;
+ dns_adbnamehook_t *anh;
dns_rdata_t rdata = DNS_RDATA_INIT;
struct in_addr ina;
struct in6_addr in6a;
@@ -561,17 +563,26 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
link_entry(adb, addr_bucket, entry);
} else {
- foundentry->refcnt++;
- nh->entry = foundentry;
+ for (anh = ISC_LIST_HEAD(adbname->v4);
+ anh != NULL;
+ anh = ISC_LIST_NEXT(anh, plink))
+ if (anh->entry == foundentry)
+ break;
+ if (anh == NULL) {
+ foundentry->refcnt++;
+ nh->entry = foundentry;
+ } else
+ free_adbnamehook(adb, &nh);
}
new_addresses_added = ISC_TRUE;
- if (rdtype == dns_rdatatype_a)
- ISC_LIST_APPEND(adbname->v4, nh, plink);
- else
- ISC_LIST_APPEND(adbname->v6, nh, plink);
+ if (nh != NULL) {
+ if (rdtype == dns_rdatatype_a)
+ ISC_LIST_APPEND(adbname->v4, nh, plink);
+ else
+ ISC_LIST_APPEND(adbname->v6, nh, plink);
+ }
nh = NULL;
-
result = dns_rdataset_next(rdataset);
}
@@ -582,7 +593,11 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
if (addr_bucket != DNS_ADB_INVALIDBUCKET)
UNLOCK(&adb->entrylocks[addr_bucket]);
- rdataset->ttl = ttlclamp(rdataset->ttl);
+ if (rdataset->trust == dns_trust_glue ||
+ rdataset->trust == dns_trust_additional)
+ rdataset->ttl = ADB_CACHE_MINIMUM;
+ else
+ rdataset->ttl = ttlclamp(rdataset->ttl);
if (rdtype == dns_rdatatype_a) {
DP(NCACHE_LEVEL, "expire_v4 set to MIN(%u,%u) import_rdataset",
@@ -749,6 +764,7 @@ check_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) {
name->partial_result &= ~DNS_ADBFIND_INET;
}
name->expire_v4 = INT_MAX;
+ name->fetch_err = FIND_ERR_UNEXPECTED;
}
/*
@@ -761,6 +777,7 @@ check_expire_namehooks(dns_adbname_t *name, isc_stdtime_t now) {
name->partial_result &= ~DNS_ADBFIND_INET6;
}
name->expire_v6 = INT_MAX;
+ name->fetch6_err = FIND_ERR_UNEXPECTED;
}
/*
@@ -1775,7 +1792,7 @@ find_name_and_lock(dns_adb_t *adb, dns_name_t *name,
dns_adbname_t *adbname;
int bucket;
- bucket = dns_name_hash(name, ISC_FALSE) % NBUCKETS;
+ bucket = dns_fullname_hash(name, ISC_FALSE) % NBUCKETS;
if (*bucketp == DNS_ADB_INVALIDBUCKET) {
LOCK(&adb->namelocks[bucket]);
@@ -1791,7 +1808,7 @@ find_name_and_lock(dns_adb_t *adb, dns_name_t *name,
if (!NAME_DEAD(adbname)) {
if (dns_name_equal(name, &adbname->name)
&& GLUEHINT_OK(adbname, options)
- && STARTATROOT_MATCHES(adbname, options))
+ && STARTATZONE_MATCHES(adbname, options))
return (adbname);
}
adbname = ISC_LIST_NEXT(adbname, plink);
@@ -2452,7 +2469,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
dns_adbfind_t *find;
dns_adbname_t *adbname;
int bucket;
- isc_boolean_t want_event, start_at_root, alias, have_address;
+ isc_boolean_t want_event, start_at_zone, alias, have_address;
isc_result_t result;
unsigned int wanted_addresses;
unsigned int wanted_fetches;
@@ -2474,7 +2491,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
wanted_fetches = 0;
query_pending = 0;
want_event = ISC_FALSE;
- start_at_root = ISC_FALSE;
+ start_at_zone = ISC_FALSE;
alias = ISC_FALSE;
if (now == 0)
@@ -2544,8 +2561,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
adbname->flags |= NAME_HINT_OK;
if (FIND_GLUEOK(find))
adbname->flags |= NAME_GLUE_OK;
- if (FIND_STARTATROOT(find))
- adbname->flags |= NAME_STARTATROOT;
+ if (FIND_STARTATZONE(find))
+ adbname->flags |= NAME_STARTATZONE;
}
/*
@@ -2572,8 +2589,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
* start fetches. First try looking for an A record
* in the database.
*/
- if (!NAME_HAS_V4(adbname) && !NAME_FETCH_V4(adbname)
- && EXPIRE_OK(adbname->expire_v4, now)
+ if (!NAME_HAS_V4(adbname) && EXPIRE_OK(adbname->expire_v4, now)
&& WANT_INET(wanted_addresses)) {
result = dbfind_name(adbname, now, dns_rdatatype_a);
if (result == ISC_R_SUCCESS) {
@@ -2608,12 +2624,12 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
else if (NXRRSET_RESULT(result))
goto v6;
- wanted_fetches |= DNS_ADBFIND_INET;
+ if (!NAME_FETCH_V4(adbname))
+ wanted_fetches |= DNS_ADBFIND_INET;
}
v6:
- if (!NAME_HAS_V6(adbname) && !NAME_FETCH_V6(adbname)
- && EXPIRE_OK(adbname->expire_v6, now)
+ if (!NAME_HAS_V6(adbname) && EXPIRE_OK(adbname->expire_v6, now)
&& WANT_INET6(wanted_addresses)) {
result = dbfind_a6(adbname, now);
if (result == ISC_R_SUCCESS) {
@@ -2669,7 +2685,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
if (NCACHE_RESULT(result) || AUTH_NX(result))
goto fetch;
- wanted_fetches |= DNS_ADBFIND_INET6;
+ if (!NAME_FETCH_V6(adbname))
+ wanted_fetches |= DNS_ADBFIND_INET6;
}
fetch:
@@ -2687,14 +2704,14 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
* be acceptable so we have to launch fetches.
*/
- if (FIND_STARTATROOT(find))
- start_at_root = ISC_TRUE;
+ if (FIND_STARTATZONE(find))
+ start_at_zone = ISC_TRUE;
/*
* Start V4.
*/
if (WANT_INET(wanted_fetches) &&
- fetch_name_v4(adbname, start_at_root) == ISC_R_SUCCESS) {
+ fetch_name_v4(adbname, start_at_zone) == ISC_R_SUCCESS) {
DP(DEF_LEVEL,
"dns_adb_createfind: started A fetch for name %p",
adbname);
@@ -2704,7 +2721,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
* Start V6.
*/
if (WANT_INET6(wanted_fetches) &&
- fetch_name_a6(adbname, start_at_root) == ISC_R_SUCCESS) {
+ fetch_name_a6(adbname, start_at_zone) == ISC_R_SUCCESS) {
DP(DEF_LEVEL,
"dns_adb_createfind: started A6 fetch for name %p",
adbname);
@@ -3285,7 +3302,6 @@ dbfind_a6(dns_adbname_t *adbname, isc_stdtime_t now) {
INSIST(DNS_ADBNAME_VALID(adbname));
adb = adbname->adb;
INSIST(DNS_ADB_VALID(adb));
- INSIST(!NAME_FETCH_V6(adbname));
result = ISC_R_UNEXPECTED;
@@ -3731,10 +3747,11 @@ fetch_callback_a6(isc_task_t *task, isc_event_t *ev) {
}
static isc_result_t
-fetch_name_v4(dns_adbname_t *adbname, isc_boolean_t start_at_root) {
+fetch_name_v4(dns_adbname_t *adbname, isc_boolean_t start_at_zone) {
isc_result_t result;
dns_adbfetch_t *fetch = NULL;
dns_adb_t *adb;
+ dns_fixedname_t fixed;
dns_name_t *name;
dns_rdataset_t rdataset;
dns_rdataset_t *nameservers;
@@ -3753,12 +3770,14 @@ fetch_name_v4(dns_adbname_t *adbname, isc_boolean_t start_at_root) {
dns_rdataset_init(&rdataset);
options = 0;
- if (start_at_root) {
- DP(50, "fetch_name_v4: starting at DNS root for name %p",
+ if (start_at_zone) {
+ DP(50, "fetch_name_v4: starting at zone for name %p",
adbname);
- name = dns_rootname;
- result = dns_view_simplefind(adb->view, name, dns_rdatatype_ns,
- 0, 0, ISC_TRUE, &rdataset, NULL);
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+ result = dns_view_findzonecut2(adb->view, &adbname->name, name,
+ 0, 0, ISC_TRUE, ISC_FALSE,
+ &rdataset, NULL);
if (result != ISC_R_SUCCESS && result != DNS_R_HINT)
goto cleanup;
nameservers = &rdataset;
@@ -3833,10 +3852,11 @@ fetch_name_aaaa(dns_adbname_t *adbname) {
}
static isc_result_t
-fetch_name_a6(dns_adbname_t *adbname, isc_boolean_t start_at_root) {
+fetch_name_a6(dns_adbname_t *adbname, isc_boolean_t start_at_zone) {
isc_result_t result;
dns_adbfetch6_t *fetch = NULL;
dns_adb_t *adb;
+ dns_fixedname_t fixed;
dns_name_t *name;
dns_rdataset_t rdataset;
dns_rdataset_t *nameservers;
@@ -3855,12 +3875,14 @@ fetch_name_a6(dns_adbname_t *adbname, isc_boolean_t start_at_root) {
dns_rdataset_init(&rdataset);
options = 0;
- if (start_at_root) {
- DP(50, "fetch_name_a6: starting at DNS root for name %p",
+ if (start_at_zone) {
+ DP(50, "fetch_name_a6: starting at zone for name %p",
adbname);
- name = dns_rootname;
- result = dns_view_simplefind(adb->view, name, dns_rdatatype_ns,
- 0, 0, ISC_TRUE, &rdataset, NULL);
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+ result = dns_view_findzonecut2(adb->view, &adbname->name, name,
+ 0, 0, ISC_TRUE, ISC_FALSE,
+ &rdataset, NULL);
if (result != ISC_R_SUCCESS && result != DNS_R_HINT)
goto cleanup;
nameservers = &rdataset;
@@ -3930,6 +3952,7 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
{
int bucket;
unsigned int new_srtt;
+ isc_stdtime_t now;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
@@ -3947,6 +3970,9 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
addr->entry->srtt = new_srtt;
addr->srtt = new_srtt;
+ isc_stdtime_get(&now);
+ addr->entry->expires = now + ADB_ENTRY_WINDOW;
+
UNLOCK(&adb->entrylocks[bucket]);
}
@@ -4044,7 +4070,7 @@ dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
- entry->expires = now + 1800; /* XXXRTH */
+ entry->expires = now + ADB_ENTRY_WINDOW;
want_check_exit = dec_entry_refcnt(adb, entry, ISC_FALSE);