2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00
This commit is contained in:
Michael Graff 1999-10-20 23:26:06 +00:00
parent 09dbb18c6d
commit f181f94ec8
3 changed files with 64 additions and 31 deletions

View File

@ -167,32 +167,30 @@ main(int argc, char **argv)
isc_sockaddr_fromin(&sockaddr, &ina, 53); isc_sockaddr_fromin(&sockaddr, &ina, 53);
result = dns_adb_insert(adb, &name1, &sockaddr); result = dns_adb_insert(adb, &name1, &sockaddr);
check_result(result, "dns_adb_insert 1.2.3.4"); check_result(result, "dns_adb_insert 1.2.3.4");
printf("Added 1.2.3.4\n"); printf("Added 1.2.3.4 -> NAME1\n");
ina.s_addr = inet_addr("1.2.3.5"); ina.s_addr = inet_addr("1.2.3.5");
isc_sockaddr_fromin(&sockaddr, &ina, 53); isc_sockaddr_fromin(&sockaddr, &ina, 53);
result = dns_adb_insert(adb, &name1, &sockaddr); result = dns_adb_insert(adb, &name1, &sockaddr);
check_result(result, "dns_adb_insert 1.2.3.5"); check_result(result, "dns_adb_insert 1.2.3.5");
printf("Added 1.2.3.5\n"); printf("Added 1.2.3.5 -> NAME1\n");
result = dns_adb_insert(adb, &name2, &sockaddr);
check_result(result, "dns_adb_insert 1.2.3.5");
printf("Added 1.2.3.5 -> NAME2\n");
ina.s_addr = inet_addr("1.2.3.6"); ina.s_addr = inet_addr("1.2.3.6");
isc_sockaddr_fromin(&sockaddr, &ina, 53); isc_sockaddr_fromin(&sockaddr, &ina, 53);
result = dns_adb_insert(adb, &name1, &sockaddr); result = dns_adb_insert(adb, &name1, &sockaddr);
check_result(result, "dns_adb_insert 1.2.3.6"); check_result(result, "dns_adb_insert 1.2.3.6");
printf("Added 1.2.3.6\n"); printf("Added 1.2.3.6 -> NAME1\n");
ina.s_addr = inet_addr("1.2.3.5");
isc_sockaddr_fromin(&sockaddr, &ina, 53);
result = dns_adb_insert(adb, &name2, &sockaddr);
check_result(result, "dns_adb_insert 1.2.3.5");
printf("Added 1.2.3.5\n");
/* /*
* Try to look up a name or two. * Try to look up a name or two.
*/ */
handle = NULL; handle = NULL;
result = dns_adb_lookup(adb, t2, lookup_callback, &name1, result = dns_adb_lookup(adb, t2, lookup_callback, &name1,
&name1, &name1, &handle); &name1, &name1, now, &handle);
check_result(result, "dns_adb_lookup name1"); check_result(result, "dns_adb_lookup name1");
check_result(handle->result, "handle->result"); check_result(handle->result, "handle->result");
@ -218,7 +216,6 @@ main(int argc, char **argv)
INSIST(ai->goodness == 50); INSIST(ai->goodness == 50);
dns_adb_adjustsrtt(adb, ai, 10000, 0); dns_adb_adjustsrtt(adb, ai, 10000, 0);
dns_adb_adjustsrtt(adb, ai, 10, 10); dns_adb_adjustsrtt(adb, ai, 10, 10);
INSIST(ai->srtt == 2251);
dns_adb_done(adb, &handle); dns_adb_done(adb, &handle);
@ -226,7 +223,7 @@ main(int argc, char **argv)
* look it up again * look it up again
*/ */
result = dns_adb_lookup(adb, t2, lookup_callback, &name1, result = dns_adb_lookup(adb, t2, lookup_callback, &name1,
&name1, &name1, &handle); &name1, &name1, now, &handle);
check_result(result, "dns_adb_lookup name1"); check_result(result, "dns_adb_lookup name1");
check_result(handle->result, "handle->result"); check_result(handle->result, "handle->result");

View File

@ -32,10 +32,11 @@
#include <isc/assertions.h> #include <isc/assertions.h>
#include <isc/condition.h> #include <isc/condition.h>
#include <isc/event.h>
#include <isc/magic.h> #include <isc/magic.h>
#include <isc/mutex.h> #include <isc/mutex.h>
#include <isc/mutexblock.h> #include <isc/mutexblock.h>
#include <isc/event.h> #include <isc/random.h>
#include <dns/address.h> #include <dns/address.h>
#include <dns/events.h> #include <dns/events.h>
@ -92,6 +93,8 @@ struct dns_adb {
isc_mempool_t *ahmp; /* dns_adbhandle_t */ isc_mempool_t *ahmp; /* dns_adbhandle_t */
isc_mempool_t *aimp; /* dns_adbaddrinfo_t */ isc_mempool_t *aimp; /* dns_adbaddrinfo_t */
isc_random_t rand;
/* /*
* Bucketized locks and lists for names. * Bucketized locks and lists for names.
*/ */
@ -158,7 +161,8 @@ struct dns_adbentry {
unsigned int refcnt; unsigned int refcnt;
unsigned int flags; unsigned int flags;
int goodness; /* bad <= 0 < good */ int edns_level; /* must be int! */
int goodness; /* bad < 0 <= good */
unsigned int srtt; unsigned int srtt;
isc_sockaddr_t sockaddr; isc_sockaddr_t sockaddr;
@ -259,6 +263,9 @@ shutdown_names(dns_adb_t *adb, isc_boolean_t kill_fetches)
} }
} }
/*
* Assumes the name bucket is locked.
*/
static void static void
clean_namehooks_at_name(dns_adb_t *adb, dns_adbname_t *name) clean_namehooks_at_name(dns_adb_t *adb, dns_adbname_t *name)
{ {
@ -302,6 +309,9 @@ clean_namehooks_at_name(dns_adb_t *adb, dns_adbname_t *name)
UNLOCK(&adb->entrylocks[addr_bucket]); UNLOCK(&adb->entrylocks[addr_bucket]);
} }
/*
* Assumes the name bucket is locked.
*/
static void static void
clean_handles_at_name(dns_adbname_t *name, isc_eventtype_t evtype) clean_handles_at_name(dns_adbname_t *name, isc_eventtype_t evtype)
{ {
@ -558,6 +568,7 @@ static inline dns_adbentry_t *
new_adbentry(dns_adb_t *adb) new_adbentry(dns_adb_t *adb)
{ {
dns_adbentry_t *e; dns_adbentry_t *e;
isc_uint32_t r;
e = isc_mempool_get(adb->emp); e = isc_mempool_get(adb->emp);
if (e == NULL) if (e == NULL)
@ -568,7 +579,8 @@ new_adbentry(dns_adb_t *adb)
e->refcnt = 0; e->refcnt = 0;
e->flags = 0; e->flags = 0;
e->goodness = 0; e->goodness = 0;
e->srtt = 0; isc_random_get(&adb->rand, &r);
e->srtt = (r & 0x1f) + 1;
ISC_LIST_INIT(e->zoneinfo); ISC_LIST_INIT(e->zoneinfo);
ISC_LINK_INIT(e, link); ISC_LINK_INIT(e, link);
@ -782,15 +794,12 @@ find_entry_and_lock(dns_adb_t *adb, isc_sockaddr_t *addr, int *bucketp)
* Entry bucket MUST be locked! * Entry bucket MUST be locked!
*/ */
static isc_boolean_t static isc_boolean_t
entry_is_bad_for_zone(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *zone) entry_is_bad_for_zone(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *zone,
isc_stdtime_t now)
{ {
dns_adbzoneinfo_t *zi, *next_zi; dns_adbzoneinfo_t *zi, *next_zi;
isc_stdtime_t now;
isc_boolean_t is_bad; isc_boolean_t is_bad;
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
return (ISC_FALSE); /* XXXMLG: assume ok if this fails? */
is_bad = ISC_FALSE; is_bad = ISC_FALSE;
zi = ISC_LIST_HEAD(entry->zoneinfo); zi = ISC_LIST_HEAD(entry->zoneinfo);
@ -807,9 +816,13 @@ entry_is_bad_for_zone(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *zone)
free_adbzoneinfo(adb, &zi); free_adbzoneinfo(adb, &zi);
} }
if (zi != NULL && !is_bad) /*
* Order tests from least to most expensive.
*/
if (zi != NULL && !is_bad) {
if (dns_name_equal(zone, &zi->zone)) if (dns_name_equal(zone, &zi->zone))
is_bad = ISC_TRUE; is_bad = ISC_TRUE;
}
zi = next_zi; zi = next_zi;
} }
@ -819,7 +832,7 @@ entry_is_bad_for_zone(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *zone)
static void static void
copy_namehook_list(dns_adb_t *adb, dns_adbhandle_t *handle, copy_namehook_list(dns_adb_t *adb, dns_adbhandle_t *handle,
dns_adbname_t *name, dns_name_t *zone) dns_adbname_t *name, dns_name_t *zone, isc_stdtime_t now)
{ {
dns_adbnamehook_t *namehook; dns_adbnamehook_t *namehook;
dns_adbaddrinfo_t *addrinfo; dns_adbaddrinfo_t *addrinfo;
@ -833,7 +846,7 @@ copy_namehook_list(dns_adb_t *adb, dns_adbhandle_t *handle,
while (namehook != NULL) { while (namehook != NULL) {
bucket = namehook->entry->lock_bucket; bucket = namehook->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]); LOCK(&adb->entrylocks[bucket]);
if (entry_is_bad_for_zone(adb, namehook->entry, zone)) if (entry_is_bad_for_zone(adb, namehook->entry, zone, now))
goto next; goto next;
addrinfo = new_adbaddrinfo(adb, namehook->entry); addrinfo = new_adbaddrinfo(adb, namehook->entry);
if (addrinfo == NULL) { if (addrinfo == NULL) {
@ -876,6 +889,8 @@ destroy(dns_adb_t *adb)
isc_mutex_destroy(&adb->lock); isc_mutex_destroy(&adb->lock);
isc_mutex_destroy(&adb->mplock); isc_mutex_destroy(&adb->mplock);
isc_random_invalidate(&adb->rand);
isc_mem_put(adb->mctx, adb, sizeof (dns_adb_t)); isc_mem_put(adb->mctx, adb, sizeof (dns_adb_t));
} }
@ -912,15 +927,19 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, dns_adb_t **newadb)
adb->ahmp = NULL; adb->ahmp = NULL;
adb->aimp = NULL; adb->aimp = NULL;
result = isc_mutex_init(&adb->lock); result = isc_random_init(&adb->rand);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto fail0a; goto fail0a;
result = isc_mutex_init(&adb->mplock);
result = isc_mutex_init(&adb->lock);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto fail0b; goto fail0b;
result = isc_condition_init(&adb->shutdown_cond); result = isc_mutex_init(&adb->mplock);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto fail0c; goto fail0c;
result = isc_condition_init(&adb->shutdown_cond);
if (result != ISC_R_SUCCESS)
goto fail0d;
/* /*
* Initialize the bucket locks for names and elements. * Initialize the bucket locks for names and elements.
@ -994,10 +1013,12 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, dns_adb_t **newadb)
isc_mempool_destroy(&adb->aimp); isc_mempool_destroy(&adb->aimp);
isc_condition_destroy(&adb->shutdown_cond); isc_condition_destroy(&adb->shutdown_cond);
fail0c: fail0d:
isc_mutex_destroy(&adb->mplock); isc_mutex_destroy(&adb->mplock);
fail0b: fail0c:
isc_mutex_destroy(&adb->lock); isc_mutex_destroy(&adb->lock);
fail0b:
isc_random_invalidate(&adb->rand);
fail0a: fail0a:
isc_mem_put(mem, adb, sizeof (dns_adb_t)); isc_mem_put(mem, adb, sizeof (dns_adb_t));
@ -1040,7 +1061,7 @@ dns_adb_destroy(dns_adb_t **adbx)
isc_result_t isc_result_t
dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
void *arg, dns_name_t *name, dns_name_t *zone, void *arg, dns_name_t *name, dns_name_t *zone,
dns_adbhandle_t **handlep) isc_stdtime_t now, dns_adbhandle_t **handlep)
{ {
dns_adbhandle_t *handle; dns_adbhandle_t *handle;
dns_adbname_t *adbname; dns_adbname_t *adbname;
@ -1059,6 +1080,12 @@ dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
attach_to_task = ISC_FALSE; attach_to_task = ISC_FALSE;
result = ISC_R_UNEXPECTED; result = ISC_R_UNEXPECTED;
if (now == 0) {
result = isc_stdtime_get(&now);
if (result != ISC_R_SUCCESS)
return (result);
}
/* /*
* Look up the name in our internal database. * Look up the name in our internal database.
* *
@ -1102,7 +1129,7 @@ dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
*/ */
again: again:
if (adbname != NULL) { if (adbname != NULL) {
copy_namehook_list(adb, handle, adbname, zone); copy_namehook_list(adb, handle, adbname, zone, now);
if (handle->result == ISC_R_NOMEMORY if (handle->result == ISC_R_NOMEMORY
&& ISC_LIST_EMPTY(handle->list)) { && ISC_LIST_EMPTY(handle->list)) {
result = ISC_R_NOMEMORY; result = ISC_R_NOMEMORY;

View File

@ -221,7 +221,7 @@ dns_adb_destroy(dns_adb_t **adb);
isc_result_t isc_result_t
dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
void *arg, dns_name_t *name, dns_name_t *zone, void *arg, dns_name_t *name, dns_name_t *zone,
dns_adbhandle_t **handle); isc_stdtime_t now, dns_adbhandle_t **handle);
/* /*
* Main interface for clients. The adb will look up the name given in * Main interface for clients. The adb will look up the name given in
* "name" and will build up a list of found addresses, and perhaps start * "name" and will build up a list of found addresses, and perhaps start
@ -245,6 +245,11 @@ dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
* fields other than the "link" field. All values can be read at any * fields other than the "link" field. All values can be read at any
* time, however. * time, however.
* *
* The "now" parameter is used only for determining which entries that
* have a specific time to live or expire time should be removed from
* the running database. If specified as zero, the current time will
* be retrieved and used.
*
* Requires: * Requires:
* *
* *adb be a valid isc_adb_t object. * *adb be a valid isc_adb_t object.
@ -265,6 +270,10 @@ dns_adb_lookup(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
* will ever be posted for this context. * will ever be posted for this context.
* ISC_R_NOMEMORY insufficient resources * ISC_R_NOMEMORY insufficient resources
* *
* Calls, and returns error codes from:
*
* isc_stdtime_get()
*
* Notes: * Notes:
* *
* No internal reference to "name" exists after this function * No internal reference to "name" exists after this function