2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-29 13:38:26 +00:00

bad server support

This commit is contained in:
Bob Halley 2000-02-11 03:06:56 +00:00
parent 9e89140c97
commit 3f101f4e70

View File

@ -157,6 +157,7 @@ struct fetchctx {
dns_adbfind_t * find;
dns_adbaddrinfolist_t forwaddrs;
isc_sockaddrlist_t forwarders;
isc_sockaddrlist_t bad;
/*
* # of events we're waiting for.
*/
@ -998,6 +999,84 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
empty_bucket(res);
}
static inline isc_boolean_t
bad_server(fetchctx_t *fctx, isc_sockaddr_t *address) {
isc_sockaddr_t *sa;
for (sa = ISC_LIST_HEAD(fctx->bad);
sa != NULL;
sa = ISC_LIST_NEXT(sa, link)) {
if (isc_sockaddr_equal(sa, address))
return (ISC_TRUE);
}
return (ISC_FALSE);
}
static inline isc_boolean_t
mark_bad(fetchctx_t *fctx) {
dns_adbfind_t *curr;
dns_adbaddrinfo_t *addrinfo;
isc_boolean_t all_bad = ISC_TRUE;
/*
* Mark all known bad servers, so we don't try to talk to them
* again.
*/
/*
* Mark any bad nameservers.
*/
for (curr = ISC_LIST_HEAD(fctx->finds);
curr != NULL;
curr = ISC_LIST_NEXT(curr, publink)) {
for (addrinfo = ISC_LIST_HEAD(curr->list);
addrinfo != NULL;
addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
if (bad_server(fctx, addrinfo->sockaddr))
addrinfo->flags |= FCTX_ADDRINFO_MARK;
else
all_bad = ISC_FALSE;
}
}
/*
* Mark any bad forwarders.
*/
for (addrinfo = ISC_LIST_HEAD(fctx->forwaddrs);
addrinfo != NULL;
addrinfo = ISC_LIST_NEXT(addrinfo, publink)) {
if (bad_server(fctx, addrinfo->sockaddr))
addrinfo->flags |= FCTX_ADDRINFO_MARK;
else
all_bad = ISC_FALSE;
}
return (all_bad);
}
static void
add_bad(fetchctx_t *fctx, isc_sockaddr_t *address) {
isc_sockaddr_t *sa;
if (bad_server(fctx, address)) {
/*
* We already know this server is bad.
*/
return;
}
FCTXTRACE("add_bad");
sa = isc_mem_get(fctx->res->mctx, sizeof *sa);
if (sa == NULL)
return;
*sa = *address;
ISC_LINK_INIT(sa, link);
ISC_LIST_APPEND(fctx->bad, sa, link);
}
static void
sort_adbfind(dns_adbfind_t *find) {
dns_adbaddrinfo_t *best, *curr;
@ -1065,7 +1144,7 @@ fctx_getaddresses(fetchctx_t *fctx) {
unsigned int stdoptions, options;
isc_sockaddr_t *sa;
dns_adbaddrinfo_t *ai;
isc_boolean_t pruned;
isc_boolean_t pruned, all_bad;
FCTXTRACE("getaddresses");
@ -1216,7 +1295,15 @@ fctx_getaddresses(fetchctx_t *fctx) {
return (result);
out:
if (ISC_LIST_EMPTY(fctx->finds) && ISC_LIST_EMPTY(fctx->forwaddrs)) {
/*
* Mark all known bad servers.
*/
all_bad = mark_bad(fctx);
/*
* How are we doing?
*/
if (all_bad) {
/*
* We've got no addresses.
*/
@ -1377,6 +1464,7 @@ static isc_boolean_t
fctx_destroy(fetchctx_t *fctx) {
dns_resolver_t *res;
unsigned int bucketnum;
isc_sockaddr_t *sa, *next_sa;
/*
* Caller must be holding the bucket lock.
@ -1399,6 +1487,17 @@ fctx_destroy(fetchctx_t *fctx) {
ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link);
/*
* Free bad.
*/
for (sa = ISC_LIST_HEAD(fctx->bad);
sa != NULL;
sa = next_sa) {
next_sa = ISC_LIST_NEXT(sa, link);
ISC_LIST_UNLINK(fctx->bad, sa, link);
isc_mem_put(res->mctx, sa, sizeof *sa);
}
isc_timer_detach(&fctx->timer);
dns_message_destroy(&fctx->rmessage);
dns_message_destroy(&fctx->qmessage);
@ -1406,7 +1505,7 @@ fctx_destroy(fetchctx_t *fctx) {
dns_name_free(&fctx->domain, res->mctx);
if (dns_rdataset_isassociated(&fctx->nameservers))
dns_rdataset_disassociate(&fctx->nameservers);
dns_name_free(&fctx->name, fctx->res->mctx);
dns_name_free(&fctx->name, res->mctx);
isc_mem_put(res->mctx, fctx, sizeof *fctx);
if (res->buckets[bucketnum].exiting &&
@ -1710,6 +1809,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
ISC_LIST_INIT(fctx->finds);
ISC_LIST_INIT(fctx->forwaddrs);
ISC_LIST_INIT(fctx->forwarders);
ISC_LIST_INIT(fctx->bad);
fctx->find = NULL;
fctx->pending = 0;
fctx->validating = 0;
@ -3293,22 +3393,15 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
broken_server = ISC_TRUE;
if (broken_server) {
/*
* XXXRTH Replace "600" with a configurable
* value.
*
* Use badness instead?
* Add 500 units of "badness" to this server.
*/
if (!ISFORWARDER(addrinfo)) {
result = dns_adb_marklame(fctx->res->view->adb,
addrinfo,
&fctx->domain,
now + 600);
result = ISC_R_SUCCESS;
if (result != ISC_R_SUCCESS) {
fctx_done(fctx, result);
return;
}
}
dns_adb_adjustgoodness(fctx->res->view->adb, addrinfo,
-500);
/*
* Add this server to the list of bad servers for
* this fctx.
*/
add_bad(fctx, addrinfo->sockaddr);
}
if (get_nameservers) {