dead/needs_poke are flags for adbnames, merge in Bob's changes

This commit is contained in:
Michael Graff
1999-10-30 01:58:02 +00:00
parent 67125500ac
commit 4281fe4a80
2 changed files with 129 additions and 29 deletions

View File

@@ -150,7 +150,7 @@ struct dns_adbname {
dns_adb_t *adb;
unsigned int partial_result;
unsigned int query_pending;
isc_boolean_t dead;
unsigned int flags;
int lock_bucket;
isc_stdtime_t expire_v4;
isc_stdtime_t expire_v6;
@@ -271,7 +271,8 @@ static inline void dec_entry_refcnt(dns_adb_t *, dns_adbentry_t *,
isc_boolean_t);
static inline void violate_locking_hierarchy(isc_mutex_t *, isc_mutex_t *);
static void clean_namehooks(dns_adb_t *, dns_adbnamehooklist_t *);
static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t);
static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t,
unsigned int);
static void check_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
static void cancel_fetches_at_name(dns_adb_t *, dns_adbname_t *);
static isc_result_t dbfind_name(dns_adbfind_t *, dns_name_t *,
@@ -288,12 +289,19 @@ static inline void unlink_name(dns_adb_t *, dns_adbname_t *);
static void kill_name(dns_adbname_t **, isc_eventtype_t ev);
static void fetch_callback_a6(isc_task_t *task, isc_event_t *ev);
#define FIND_EVENT_SENT 0x00000001
#define FIND_EVENT_FREED 0x00000002
/*
* MUST NOT overlap DNS_ADBFIND_* flags!
*/
#define FIND_EVENT_SENT 0x40000000
#define FIND_EVENT_FREED 0x80000000
#define EVENT_SENT(h) (((h)->flags & FIND_EVENT_SENT) != 0)
#define EVENT_FREED(h) (((h)->flags & FIND_EVENT_FREED) != 0)
#define NAME_NEEDS_POKE 0x80000000
#define NAME_IS_DEAD 0x40000000
#define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0)
#define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0)
#define WANTEVENT(x) (((x) & DNS_ADBFIND_WANTEVENT) != 0)
#define WANTEMPTYEVENT(x) (((x) & DNS_ADBFIND_EMPTYEVENT) != 0)
#define HAVE_INET(n) (!ISC_LIST_EMPTY((n)->v4))
@@ -422,8 +430,7 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
if (addr_bucket != DNS_ADB_INVALIDBUCKET)
UNLOCK(&adb->entrylocks[addr_bucket]);
if (now + rdataset->ttl < adbname->expire_v4)
adbname->expire_v4 = now + rdataset->ttl;
adbname->expire_v4 = ISC_MIN(adbname->expire_v4, now + rdataset->ttl);
/*
* Lie a little here. This is more or less so code that cares
@@ -435,6 +442,79 @@ import_rdataset(dns_adbname_t *adbname, dns_rdataset_t *rdataset,
return (result);
}
static void
import_v6(void *arg, struct in6_addr *address)
{
dns_adbname_t *name;
dns_adb_t *adb;
dns_adbnamehook_t *nh;
dns_adbentry_t *foundentry; /* NO CLEAN UP! */
isc_stdtime_t now;
isc_stdtime_t expire_time;
isc_result_t result;
isc_boolean_t address_added;
int addr_bucket;
isc_sockaddr_t sockaddr;
name = arg;
INSIST(DNS_ADBNAME_VALID(name));
adb = name->adb;
INSIST(DNS_ADB_VALID(adb));
address_added = ISC_FALSE;
/*
* XXX Once the time is passed in to us, this can go away.
*/
result = isc_stdtime_get(&now);
if (result != ISC_R_SUCCESS)
return;
expire_time = now + 30; /* XXX 30 seconds */
nh = new_adbnamehook(adb, NULL);
if (nh == NULL) {
name->partial_result |= DNS_ADBFIND_INET6; /* clear for AAAA */
goto fail;
}
isc_sockaddr_fromin6(&sockaddr, address, 53);
foundentry = find_entry_and_lock(adb, &sockaddr, &addr_bucket);
if (foundentry == NULL) {
dns_adbentry_t *entry;
entry = new_adbentry(adb);
if (entry == NULL) {
name->partial_result |= DNS_ADBFIND_INET6;
goto fail;
}
entry->sockaddr = sockaddr;
entry->refcnt = 1;
entry->lock_bucket = addr_bucket;
nh->entry = entry;
ISC_LIST_APPEND(adb->entries[addr_bucket], entry, plink);
} else {
foundentry->refcnt++;
nh->entry = foundentry;
}
address_added = ISC_TRUE;
ISC_LIST_APPEND(name->v6, nh, plink);
nh = NULL;
fail:
if (nh != NULL)
free_adbnamehook(adb, &nh);
if (addr_bucket != DNS_ADB_INVALIDBUCKET)
UNLOCK(&adb->entrylocks[addr_bucket]);
name->expire_v6 = ISC_MIN(name->expire_v6, expire_time);
if (address_added)
name->flags |= NAME_NEEDS_POKE;
}
/*
* Requires the name's bucket be locked.
*/
@@ -457,7 +537,7 @@ kill_name(dns_adbname_t **n, isc_eventtype_t ev)
* If we're dead already, just check to see if we should go
* away now or not.
*/
if (name->dead && NO_FETCHES(name)) {
if (NAME_DEAD(name) && NO_FETCHES(name)) {
unlink_name(adb, name);
free_adbname(adb, &name);
return;
@@ -467,7 +547,7 @@ kill_name(dns_adbname_t **n, isc_eventtype_t ev)
* Clean up the name's various lists. These two are destructive
* in that they will always empty the list.
*/
clean_finds_at_name(name, ev);
clean_finds_at_name(name, ev, DNS_ADBFIND_ADDRESSMASK);
clean_namehooks(adb, &name->v4);
clean_namehooks(adb, &name->v6);
@@ -479,7 +559,7 @@ kill_name(dns_adbname_t **n, isc_eventtype_t ev)
unlink_name(adb, name);
free_adbname(adb, &name);
} else {
name->dead = ISC_TRUE;
name->flags |= NAME_IS_DEAD;
cancel_fetches_at_name(adb, name);
}
}
@@ -679,16 +759,31 @@ event_free(isc_event_t *event)
* Assumes the name bucket is locked.
*/
static void
clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype)
clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype,
unsigned int addrs)
{
isc_event_t *ev;
isc_task_t *task;
dns_adbfind_t *find;
dns_adbfind_t *next_find;
find = ISC_LIST_HEAD(name->finds);
while (find != NULL) {
LOCK(&find->lock);
next_find = ISC_LIST_NEXT(find, plink);
/*
* If this is a successful poke, we want to match only
* finds that are interested in the address family.
* If it is an unsuccessful poke (kill all names, etc)
* match everything that matches the "addrs" mask.
*/
find->options &= ~addrs;
if (evtype != DNS_EVENT_ADBMOREADDRESSES) {
if ((find->options & DNS_ADBFIND_ADDRESSMASK) != 0)
goto next;
}
/*
* Unlink the find from the name, letting the caller
* call dns_adb_destroyfind() on it to clean it up later.
@@ -711,9 +806,9 @@ clean_finds_at_name(dns_adbname_t *name, isc_eventtype_t evtype)
isc_task_sendanddetach(&task, &ev);
next:
UNLOCK(&find->lock);
find = ISC_LIST_HEAD(name->finds);
find = next_find;
}
}
@@ -845,7 +940,7 @@ new_adbname(dns_adb_t *adb, dns_name_t *dnsname)
name->adb = adb;
name->partial_result = 0;
name->query_pending = 0;
name->dead = ISC_FALSE;
name->flags = 0;
name->expire_v4 = INT_MAX;
name->expire_v6 = INT_MAX;
name->chains = 0;
@@ -1338,7 +1433,7 @@ find_name_and_lock(dns_adb_t *adb, dns_name_t *name, int *bucketp)
adbname = ISC_LIST_HEAD(adb->names[bucket]);
while (adbname != NULL) {
if (adbname->dead != ISC_TRUE) {
if (!NAME_DEAD(adbname)) {
if (dns_name_equal(name, &adbname->name))
return (adbname);
}
@@ -1637,6 +1732,7 @@ destroy(dns_adb_t *adb)
isc_mempool_destroy(&adb->ahmp);
isc_mempool_destroy(&adb->aimp);
isc_mempool_destroy(&adb->afmp);
isc_mempool_destroy(&adb->af6mp);
isc_mutexblock_destroy(adb->entrylocks, DNS_ADBENTRYLIST_LENGTH);
isc_mutexblock_destroy(adb->namelocks, DNS_ADBNAMELIST_LENGTH);
@@ -1686,6 +1782,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
adb->ahmp = NULL;
adb->aimp = NULL;
adb->afmp = NULL;
adb->af6mp = NULL;
adb->task = NULL;
adb->timer = NULL;
adb->mctx = mem;
@@ -1797,8 +1894,10 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
isc_mempool_destroy(&adb->ahmp);
if (adb->aimp != NULL)
isc_mempool_destroy(&adb->aimp);
if (adb->aimp != NULL)
if (adb->afmp != NULL)
isc_mempool_destroy(&adb->afmp);
if (adb->af6mp != NULL)
isc_mempool_destroy(&adb->af6mp);
isc_mutex_destroy(&adb->mplock);
fail0c:
@@ -1890,6 +1989,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
* Remember what types of addresses we are interested in.
*/
find->options = options;
find->flags |= wanted_addresses;
/*
* Try to see if we know anything about this name at all.
@@ -2021,6 +2121,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
}
}
dns_adb_dumpfind(find, stderr);
if (bucket != DNS_ADB_INVALIDBUCKET)
UNLOCK(&adb->namelocks[bucket]);
@@ -2643,7 +2745,7 @@ fetch_callback_v4(isc_task_t *task, isc_event_t *ev)
* If this name is marked as dead, clean up, throwing away
* potentially good data.
*/
if (name->dead) {
if (NAME_DEAD(name)) {
isc_boolean_t decr_adbrefcnt;
free_adbfetch(adb, &fetch);
@@ -2683,7 +2785,7 @@ fetch_callback_v4(isc_task_t *task, isc_event_t *ev)
free_adbfetch(adb, &fetch);
isc_event_free(&ev);
clean_finds_at_name(name, ev_status);
clean_finds_at_name(name, ev_status, DNS_ADBFIND_INET);
name->query_pending &= ~DNS_ADBFIND_INET;
UNLOCK(&adb->namelocks[bucket]);
@@ -2738,7 +2840,7 @@ fetch_callback_aaaa(isc_task_t *task, isc_event_t *ev)
* If this name is marked as dead, clean up, throwing away
* potentially good data.
*/
if (name->dead) {
if (NAME_DEAD(name)) {
isc_boolean_t decr_adbrefcnt;
free_adbfetch(adb, &fetch);
@@ -2778,7 +2880,7 @@ fetch_callback_aaaa(isc_task_t *task, isc_event_t *ev)
free_adbfetch(adb, &fetch);
isc_event_free(&ev);
clean_finds_at_name(name, ev_status);
clean_finds_at_name(name, ev_status, DNS_ADBFIND_INET6);
name->query_pending &= ~DNS_ADBFIND_INET6;
UNLOCK(&adb->namelocks[bucket]);
@@ -2808,7 +2910,7 @@ fetch_callback_a6(isc_task_t *task, isc_event_t *ev)
bucket = name->lock_bucket;
LOCK(&adb->namelocks[bucket]);
/* XXX INSIST(needs_poke == 0) */
INSIST(!NAME_NEEDSPOKE(name));
for (fetch = ISC_LIST_HEAD(name->fetches_a6);
fetch != NULL;
@@ -2833,7 +2935,7 @@ fetch_callback_a6(isc_task_t *task, isc_event_t *ev)
* If this name is marked as dead, clean up, throwing away
* potentially good data.
*/
if (name->dead) {
if (NAME_DEAD(name)) {
isc_boolean_t decr_adbrefcnt;
free_adbfetch6(adb, &fetch);
@@ -2872,8 +2974,7 @@ fetch_callback_a6(isc_task_t *task, isc_event_t *ev)
free_adbfetch6(adb, &fetch);
isc_event_free(&ev);
#ifdef notyet
if (needs_poke)
if (NAME_NEEDSPOKE(name))
clean_finds_at_name(name, DNS_EVENT_ADBMOREADDRESSES,
DNS_ADBFIND_INET6);
else if (ISC_LIST_EMPTY(name->fetches_a6)) {
@@ -2881,9 +2982,8 @@ fetch_callback_a6(isc_task_t *task, isc_event_t *ev)
DNS_ADBFIND_INET6);
name->query_pending &= ~DNS_ADBFIND_INET6;
}
#endif
/* XXX clear needs poke */
name->flags &= ~NAME_NEEDS_POKE;
UNLOCK(&adb->namelocks[bucket]);

View File

@@ -124,7 +124,7 @@ struct dns_adbfind {
unsigned int query_pending; /* RO: partial list */
unsigned int partial_result; /* RO: addrs missing */
unsigned int options; /* RO: options */
ISC_LINK(dns_adbfind_t) publink; /* RW: client use */
ISC_LINK(dns_adbfind_t) publink; /* RW: client use */
/* Private */
isc_mutex_t lock; /* locks all below */
@@ -140,8 +140,8 @@ struct dns_adbfind {
#define DNS_ADBFIND_INET6 0x00000002
#define DNS_ADBFIND_ADDRESSMASK 0x00000003
#define DNS_ADBFIND_EMPTYEVENT 0x40000000
#define DNS_ADBFIND_WANTEVENT 0x80000000
#define DNS_ADBFIND_EMPTYEVENT 0x00000004
#define DNS_ADBFIND_WANTEVENT 0x00000008
/* dns_adbaddr_t
*