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_adbfind_t * find;
dns_adbaddrinfolist_t forwaddrs; dns_adbaddrinfolist_t forwaddrs;
isc_sockaddrlist_t forwarders; isc_sockaddrlist_t forwarders;
isc_sockaddrlist_t bad;
/* /*
* # of events we're waiting for. * # of events we're waiting for.
*/ */
@ -998,6 +999,84 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
empty_bucket(res); 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 static void
sort_adbfind(dns_adbfind_t *find) { sort_adbfind(dns_adbfind_t *find) {
dns_adbaddrinfo_t *best, *curr; dns_adbaddrinfo_t *best, *curr;
@ -1065,7 +1144,7 @@ fctx_getaddresses(fetchctx_t *fctx) {
unsigned int stdoptions, options; unsigned int stdoptions, options;
isc_sockaddr_t *sa; isc_sockaddr_t *sa;
dns_adbaddrinfo_t *ai; dns_adbaddrinfo_t *ai;
isc_boolean_t pruned; isc_boolean_t pruned, all_bad;
FCTXTRACE("getaddresses"); FCTXTRACE("getaddresses");
@ -1216,7 +1295,15 @@ fctx_getaddresses(fetchctx_t *fctx) {
return (result); return (result);
out: 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. * We've got no addresses.
*/ */
@ -1377,6 +1464,7 @@ static isc_boolean_t
fctx_destroy(fetchctx_t *fctx) { fctx_destroy(fetchctx_t *fctx) {
dns_resolver_t *res; dns_resolver_t *res;
unsigned int bucketnum; unsigned int bucketnum;
isc_sockaddr_t *sa, *next_sa;
/* /*
* Caller must be holding the bucket lock. * 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); 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); isc_timer_detach(&fctx->timer);
dns_message_destroy(&fctx->rmessage); dns_message_destroy(&fctx->rmessage);
dns_message_destroy(&fctx->qmessage); dns_message_destroy(&fctx->qmessage);
@ -1406,7 +1505,7 @@ fctx_destroy(fetchctx_t *fctx) {
dns_name_free(&fctx->domain, res->mctx); dns_name_free(&fctx->domain, res->mctx);
if (dns_rdataset_isassociated(&fctx->nameservers)) if (dns_rdataset_isassociated(&fctx->nameservers))
dns_rdataset_disassociate(&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); isc_mem_put(res->mctx, fctx, sizeof *fctx);
if (res->buckets[bucketnum].exiting && 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->finds);
ISC_LIST_INIT(fctx->forwaddrs); ISC_LIST_INIT(fctx->forwaddrs);
ISC_LIST_INIT(fctx->forwarders); ISC_LIST_INIT(fctx->forwarders);
ISC_LIST_INIT(fctx->bad);
fctx->find = NULL; fctx->find = NULL;
fctx->pending = 0; fctx->pending = 0;
fctx->validating = 0; fctx->validating = 0;
@ -3293,22 +3393,15 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
broken_server = ISC_TRUE; broken_server = ISC_TRUE;
if (broken_server) { if (broken_server) {
/* /*
* XXXRTH Replace "600" with a configurable * Add 500 units of "badness" to this server.
* value.
*
* Use badness instead?
*/ */
if (!ISFORWARDER(addrinfo)) { dns_adb_adjustgoodness(fctx->res->view->adb, addrinfo,
result = dns_adb_marklame(fctx->res->view->adb, -500);
addrinfo, /*
&fctx->domain, * Add this server to the list of bad servers for
now + 600); * this fctx.
result = ISC_R_SUCCESS; */
if (result != ISC_R_SUCCESS) { add_bad(fctx, addrinfo->sockaddr);
fctx_done(fctx, result);
return;
}
}
} }
if (get_nameservers) { if (get_nameservers) {