2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 15:45:25 +00:00

fix a few bugs, and start an AAAA db lookup/query if no A6 is found

This commit is contained in:
Michael Graff
1999-11-02 00:29:45 +00:00
parent 89c250649e
commit 14b98cb34e

View File

@@ -167,6 +167,7 @@ struct dns_adbfetch {
struct dns_adbfetch6 { struct dns_adbfetch6 {
unsigned int magic; unsigned int magic;
unsigned int flags;
dns_adbnamehook_t *namehook; dns_adbnamehook_t *namehook;
dns_adbentry_t *entry; dns_adbentry_t *entry;
dns_fetch_t *fetch; dns_fetch_t *fetch;
@@ -269,12 +270,12 @@ static void clean_finds_at_name(dns_adbname_t *, isc_eventtype_t,
unsigned int); unsigned int);
static void check_expire_namehooks(dns_adbname_t *, isc_stdtime_t); static void check_expire_namehooks(dns_adbname_t *, isc_stdtime_t);
static void cancel_fetches_at_name(dns_adb_t *, dns_adbname_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 *, static isc_result_t dbfind_name(dns_adbname_t *, isc_stdtime_t,
dns_adbname_t *, int, isc_stdtime_t, isc_boolean_t, dns_rdatatype_t);
dns_rdatatype_t);
static isc_result_t fetch_name_v4(dns_adbname_t *, isc_stdtime_t); static isc_result_t fetch_name_v4(dns_adbname_t *, isc_stdtime_t);
static isc_result_t fetch_name_aaaa(dns_adbname_t *, isc_stdtime_t); static isc_result_t fetch_name_aaaa(dns_adbname_t *, isc_stdtime_t);
static isc_result_t fetch_name_a6(dns_adbname_t *, isc_stdtime_t); static isc_result_t fetch_name_a6(dns_adbname_t *, isc_stdtime_t,
isc_boolean_t);
static inline void check_exit(dns_adb_t *); static inline void check_exit(dns_adb_t *);
static void timer_cleanup(isc_task_t *, isc_event_t *); static void timer_cleanup(isc_task_t *, isc_event_t *);
static void destroy(dns_adb_t *); static void destroy(dns_adb_t *);
@@ -283,8 +284,7 @@ static inline void link_name(dns_adb_t *, int, dns_adbname_t *);
static inline void unlink_name(dns_adb_t *, dns_adbname_t *); static inline void unlink_name(dns_adb_t *, dns_adbname_t *);
static void kill_name(dns_adbname_t **, isc_eventtype_t); static void kill_name(dns_adbname_t **, isc_eventtype_t);
static void fetch_callback_a6(isc_task_t *, isc_event_t *); static void fetch_callback_a6(isc_task_t *, isc_event_t *);
static isc_result_t dbfind_a6(dns_adbfind_t *, dns_name_t *, static isc_result_t dbfind_a6(dns_adbname_t *, isc_stdtime_t, isc_boolean_t);
dns_adbname_t *, int, isc_stdtime_t);
/* /*
* MUST NOT overlap DNS_ADBFIND_* flags! * MUST NOT overlap DNS_ADBFIND_* flags!
@@ -296,8 +296,13 @@ static isc_result_t dbfind_a6(dns_adbfind_t *, dns_name_t *,
#define NAME_NEEDS_POKE 0x80000000 #define NAME_NEEDS_POKE 0x80000000
#define NAME_IS_DEAD 0x40000000 #define NAME_IS_DEAD 0x40000000
#define NAME_FIRST_A6 0x20000000
#define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0) #define NAME_DEAD(n) (((n)->flags & NAME_IS_DEAD) != 0)
#define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0) #define NAME_NEEDSPOKE(n) (((n)->flags & NAME_NEEDS_POKE) != 0)
#define NAME_FIRSTA6(n) (((n)->flags & NAME_FIRST_A6) != 0)
#define FETCH_USE_HINTS 0x80000000
#define FETCH_USEHINTS(f) (((f)->flags & FETCH_USE_HINTS) != 0)
#define WANTEVENT(x) (((x) & DNS_ADBFIND_WANTEVENT) != 0) #define WANTEVENT(x) (((x) & DNS_ADBFIND_WANTEVENT) != 0)
#define WANTEMPTYEVENT(x) (((x) & DNS_ADBFIND_EMPTYEVENT) != 0) #define WANTEMPTYEVENT(x) (((x) & DNS_ADBFIND_EMPTYEVENT) != 0)
@@ -686,6 +691,8 @@ shutdown_names(dns_adb_t *adb)
static void static void
cancel_fetches_at_name(dns_adb_t *adb, dns_adbname_t *name) cancel_fetches_at_name(dns_adb_t *adb, dns_adbname_t *name)
{ {
dns_adbfetch6_t *fetch6;
if (name->fetch_a != NULL) if (name->fetch_a != NULL)
dns_resolver_cancelfetch(adb->view->resolver, dns_resolver_cancelfetch(adb->view->resolver,
name->fetch_a->fetch); name->fetch_a->fetch);
@@ -693,6 +700,12 @@ cancel_fetches_at_name(dns_adb_t *adb, dns_adbname_t *name)
if (name->fetch_aaaa != NULL) if (name->fetch_aaaa != NULL)
dns_resolver_cancelfetch(adb->view->resolver, dns_resolver_cancelfetch(adb->view->resolver,
name->fetch_aaaa->fetch); name->fetch_aaaa->fetch);
fetch6 = ISC_LIST_HEAD(name->fetches_a6);
while (fetch6 != NULL) {
dns_resolver_cancelfetch(adb->view->resolver, fetch6->fetch);
fetch6 = ISC_LIST_NEXT(fetch6, plink);
}
} }
/* /*
@@ -1323,6 +1336,7 @@ new_adbfetch6(dns_adb_t *adb, dns_adbname_t *name, dns_a6context_t *a6ctx)
f->namehook = NULL; f->namehook = NULL;
f->entry = NULL; f->entry = NULL;
f->fetch = NULL; f->fetch = NULL;
f->flags = 0;
f->namehook = new_adbnamehook(adb, NULL); f->namehook = new_adbnamehook(adb, NULL);
if (f->namehook == NULL) if (f->namehook == NULL)
@@ -1552,8 +1566,8 @@ entry_is_bad_for_zone(dns_adb_t *adb, dns_adbentry_t *entry, dns_name_t *zone,
} }
static void static void
copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *zone,
dns_adbname_t *name, dns_name_t *zone, isc_stdtime_t now) dns_adbname_t *name, isc_stdtime_t now)
{ {
dns_adbnamehook_t *namehook; dns_adbnamehook_t *namehook;
dns_adbaddrinfo_t *addrinfo; dns_adbaddrinfo_t *addrinfo;
@@ -1969,6 +1983,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
dns_adbfind_t *find; dns_adbfind_t *find;
dns_adbname_t *adbname; dns_adbname_t *adbname;
int bucket; int bucket;
isc_boolean_t use_hints;
isc_result_t result; isc_result_t result;
isc_boolean_t attach_to_task; isc_boolean_t attach_to_task;
unsigned int wanted_addresses; unsigned int wanted_addresses;
@@ -2055,6 +2070,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
*/ */
check_expire_namehooks(adbname, now); check_expire_namehooks(adbname, now);
use_hints = dns_name_equal(zone, dns_rootname);
/* /*
* Try to populate the name from the database and/or * Try to populate the name from the database and/or
* start fetches. * start fetches.
@@ -2062,8 +2079,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
if (!HAVE_INET(adbname) if (!HAVE_INET(adbname)
&& !QUERY_INET(adbname->query_pending) && !QUERY_INET(adbname->query_pending)
&& WANT_INET(wanted_addresses)) { && WANT_INET(wanted_addresses)) {
result = dbfind_name(find, zone, adbname, bucket, now, result = dbfind_name(adbname, now, use_hints, dns_rdatatype_a);
dns_rdatatype_a);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
DP(DEF_LEVEL, DP(DEF_LEVEL,
"dns_adb_createfind: Found A for name %p in db", "dns_adb_createfind: Found A for name %p in db",
@@ -2088,7 +2104,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
if (!HAVE_INET6(adbname) if (!HAVE_INET6(adbname)
&& !QUERY_INET6(adbname->query_pending) && !QUERY_INET6(adbname->query_pending)
&& WANT_INET6(wanted_addresses)) { && WANT_INET6(wanted_addresses)) {
result = dbfind_a6(find, zone, adbname, bucket, now); result = dbfind_a6(adbname, now, use_hints);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
DP(DEF_LEVEL, DP(DEF_LEVEL,
"dns_adb_createfind: Found A6 for name %p", "dns_adb_createfind: Found A6 for name %p",
@@ -2099,7 +2115,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
/* /*
* Try to start fetches for a6. * Try to start fetches for a6.
*/ */
result = fetch_name_a6(adbname, now); adbname->flags |= NAME_FIRST_A6;
result = fetch_name_a6(adbname, now, use_hints);
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
DP(DEF_LEVEL, DP(DEF_LEVEL,
"dns_adb_createfind: Started A6 fetch for name %p", "dns_adb_createfind: Started A6 fetch for name %p",
@@ -2107,6 +2124,13 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
adbname->query_pending |= DNS_ADBFIND_INET6; adbname->query_pending |= DNS_ADBFIND_INET6;
goto copy; goto copy;
} }
/*
* If all those fail, should we then try AAAA? Note that in
* this case failure means "could not start query" or
* some sort of database error, not "no such name" in most
* cases.
*/
} }
/* /*
@@ -2114,7 +2138,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
* interested in. * interested in.
*/ */
copy: copy:
copy_namehook_lists(adb, find, adbname, zone, now); copy_namehook_lists(adb, find, zone, adbname, now);
/* /*
* Attach to the name's query list if there are queries * Attach to the name's query list if there are queries
@@ -2697,20 +2721,16 @@ print_find_list(FILE *f, dns_adbname_t *name)
* perhaps some fetches have been started. * perhaps some fetches have been started.
*/ */
static isc_result_t static isc_result_t
dbfind_name(dns_adbfind_t *find, dns_name_t *zone, dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now,
dns_adbname_t *adbname, int bucket, isc_stdtime_t now, isc_boolean_t use_hints, dns_rdatatype_t rdtype)
dns_rdatatype_t rdtype)
{ {
isc_result_t result; isc_result_t result;
isc_boolean_t use_hints;
dns_rdataset_t rdataset; dns_rdataset_t rdataset;
dns_adb_t *adb; dns_adb_t *adb;
INSIST(DNS_ADBFIND_VALID(find));
INSIST(DNS_ADBNAME_VALID(adbname)); INSIST(DNS_ADBNAME_VALID(adbname));
adb = adbname->adb; adb = adbname->adb;
INSIST(DNS_ADB_VALID(adb)); INSIST(DNS_ADB_VALID(adb));
INSIST(bucket != DNS_ADB_INVALIDBUCKET);
INSIST(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa); INSIST(rdtype == dns_rdatatype_a || rdtype == dns_rdatatype_aaaa);
if (adb->view == NULL) if (adb->view == NULL)
@@ -2718,7 +2738,6 @@ dbfind_name(dns_adbfind_t *find, dns_name_t *zone,
result = ISC_R_UNEXPECTED; result = ISC_R_UNEXPECTED;
use_hints = dns_name_equal(zone, dns_rootname);
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
result = dns_view_find(adb->view, &adbname->name, rdtype, result = dns_view_find(adb->view, &adbname->name, rdtype,
@@ -2733,10 +2752,10 @@ dbfind_name(dns_adbfind_t *find, dns_name_t *zone,
* any information, return success, or else a fetch * any information, return success, or else a fetch
* will be made, which will only make things worse. * will be made, which will only make things worse.
*/ */
(void)import_rdataset(adbname, &rdataset, now); result = import_rdataset(adbname, &rdataset, now);
result = ISC_R_SUCCESS;
break; break;
} }
/* Need to handle "no such name" XXXMLG */
if (dns_rdataset_isassociated(&rdataset)) if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset); dns_rdataset_disassociate(&rdataset);
@@ -2745,20 +2764,16 @@ dbfind_name(dns_adbfind_t *find, dns_name_t *zone,
} }
static isc_result_t static isc_result_t
dbfind_a6(dns_adbfind_t *find, dns_name_t *zone, dbfind_a6(dns_adbname_t *adbname, isc_stdtime_t now, isc_boolean_t use_hints)
dns_adbname_t *adbname, int bucket, isc_stdtime_t now)
{ {
isc_result_t result; isc_result_t result;
isc_boolean_t use_hints;
dns_rdataset_t rdataset; dns_rdataset_t rdataset;
dns_adb_t *adb; dns_adb_t *adb;
dns_a6context_t a6ctx; dns_a6context_t a6ctx;
INSIST(DNS_ADBFIND_VALID(find));
INSIST(DNS_ADBNAME_VALID(adbname)); INSIST(DNS_ADBNAME_VALID(adbname));
adb = adbname->adb; adb = adbname->adb;
INSIST(DNS_ADB_VALID(adb)); INSIST(DNS_ADB_VALID(adb));
INSIST(bucket != DNS_ADB_INVALIDBUCKET);
INSIST(NO_FETCHES_A6(adbname)); INSIST(NO_FETCHES_A6(adbname));
if (adb->view == NULL) if (adb->view == NULL)
@@ -2766,7 +2781,6 @@ dbfind_a6(dns_adbfind_t *find, dns_name_t *zone,
result = ISC_R_UNEXPECTED; result = ISC_R_UNEXPECTED;
use_hints = dns_name_equal(zone, dns_rootname);
dns_rdataset_init(&rdataset); dns_rdataset_init(&rdataset);
result = dns_view_find(adb->view, &adbname->name, dns_rdatatype_a6, result = dns_view_find(adb->view, &adbname->name, dns_rdatatype_a6,
@@ -2787,6 +2801,7 @@ dbfind_a6(dns_adbfind_t *find, dns_name_t *zone,
result = ISC_R_SUCCESS; result = ISC_R_SUCCESS;
break; break;
} }
/* Need to handle "no such name" XXXMLG */
if (dns_rdataset_isassociated(&rdataset)) if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset); dns_rdataset_disassociate(&rdataset);
@@ -3053,12 +3068,64 @@ fetch_callback_a6(isc_task_t *task, isc_event_t *ev)
} }
/* /*
* Did we get back junk? If so, and there are no more fetches * If the A6 query didn't succeed, and this is the first query
* sitting out there, tell all the finds about it. * in the A6 chain, try AAAA records instead. For later failures,
* don't do this.
*/ */
if (dev->result != ISC_R_SUCCESS) if (dev->result != ISC_R_SUCCESS) {
int result;
isc_boolean_t use_hints;
isc_stdtime_t now;
DP(DEF_LEVEL, "name %p: A6 failed, result %u",
name, dev->result);
if (FETCH_USEHINTS(fetch))
use_hints = ISC_TRUE;
else
use_hints = ISC_FALSE;
result = isc_stdtime_get(&now);
if (result != ISC_R_SUCCESS)
goto out; goto out;
if (NAME_FIRSTA6(name) && !HAVE_INET6(name)) {
name->flags &= NAME_FIRST_A6;
DP(DEF_LEVEL,
"name %p: A6 query failed, starting AAAA", name);
/*
* Since this is the very first fetch, and it
* failed, we know there are no more running.
*/
name->query_pending &= ~DNS_ADBFIND_INET6;
result = dbfind_name(name, now, use_hints,
dns_rdatatype_aaaa);
if (result == ISC_R_SUCCESS) {
DP(DEF_LEVEL,
"name %p: callback_a6: Found AAAA for",
name);
name->flags |= NAME_NEEDS_POKE;
goto out;
}
/*
* Try to start fetches for AAAA.
*/
result = fetch_name_aaaa(name, now);
if (result == ISC_R_SUCCESS) {
DP(DEF_LEVEL,
"name %p: callback_a6: Started AAAA fetch",
name);
goto out;
}
}
goto out;
}
/* /*
* We got something potentially useful. Run the A6 chain * We got something potentially useful. Run the A6 chain
* follower on this A6 rdataset. * follower on this A6 rdataset.
@@ -3074,7 +3141,7 @@ fetch_callback_a6(isc_task_t *task, isc_event_t *ev)
if (NAME_NEEDSPOKE(name)) if (NAME_NEEDSPOKE(name))
clean_finds_at_name(name, DNS_EVENT_ADBMOREADDRESSES, clean_finds_at_name(name, DNS_EVENT_ADBMOREADDRESSES,
DNS_ADBFIND_INET6); DNS_ADBFIND_INET6);
else if (ISC_LIST_EMPTY(name->fetches_a6)) { else if (NO_FETCHES_A6(name) && NO_FETCHES_AAAA(name)) {
name->query_pending &= ~DNS_ADBFIND_INET6; name->query_pending &= ~DNS_ADBFIND_INET6;
clean_finds_at_name(name, DNS_EVENT_ADBNOMOREADDRESSES, clean_finds_at_name(name, DNS_EVENT_ADBNOMOREADDRESSES,
DNS_ADBFIND_INET6); DNS_ADBFIND_INET6);
@@ -3202,7 +3269,8 @@ fetch_name_aaaa(dns_adbname_t *adbname, isc_stdtime_t now)
} }
static isc_result_t static isc_result_t
fetch_name_a6(dns_adbname_t *adbname, isc_stdtime_t now) fetch_name_a6(dns_adbname_t *adbname, isc_stdtime_t now,
isc_boolean_t use_hints)
{ {
isc_result_t result; isc_result_t result;
dns_adbfetch6_t *fetch; dns_adbfetch6_t *fetch;
@@ -3235,6 +3303,8 @@ fetch_name_a6(dns_adbname_t *adbname, isc_stdtime_t now)
result = ISC_R_NOMEMORY; result = ISC_R_NOMEMORY;
goto cleanup; goto cleanup;
} }
if (use_hints)
fetch->flags |= FETCH_USE_HINTS;
result = dns_resolver_createfetch(adb->view->resolver, &adbname->name, result = dns_resolver_createfetch(adb->view->resolver, &adbname->name,
dns_rdatatype_a6, &fname, dns_rdatatype_a6, &fname,
@@ -3258,6 +3328,10 @@ fetch_name_a6(dns_adbname_t *adbname, isc_stdtime_t now)
return (result); return (result);
} }
/* XXXMLG
* Needs to take a find argument and an address info, no zone or adb, since
* these can be extracted from the find itself.
*/
isc_result_t isc_result_t
dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *zone, dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *zone,
isc_stdtime_t expire_time) isc_stdtime_t expire_time)