Commit 3ee5ea2f authored by Mark Andrews's avatar Mark Andrews Committed by Michał Kępień

Reduce the number of fetches we make when looking up addresses

If there are more that 5 NS record for a zone only perform a
maximum of 4 address lookups for all the name servers.  This
limits the amount of remote lookup performed for server
addresses at each level for a given query.
parent e7abb070
......@@ -440,6 +440,7 @@ log_quota(dns_adbentry_t *entry, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
#define FIND_GLUEOK(fn) (((fn)->options & DNS_ADBFIND_GLUEOK) != 0)
#define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list))
#define FIND_RETURNLAME(fn) (((fn)->options & DNS_ADBFIND_RETURNLAME) != 0)
#define FIND_NOFETCH(fn) (((fn)->options & DNS_ADBFIND_NOFETCH) != 0)
/*
* These are currently used on simple unsigned ints, so they are
......@@ -3234,7 +3235,9 @@ fetch:
} else {
have_address = false;
}
if (wanted_fetches != 0 && !(FIND_AVOIDFETCHES(find) && have_address)) {
if (wanted_fetches != 0 && !(FIND_AVOIDFETCHES(find) && have_address) &&
!FIND_NOFETCH(find))
{
/*
* We're missing at least one address family. Either the
* caller hasn't instructed us to avoid fetches, or we don't
......
......@@ -205,6 +205,10 @@ struct dns_adbfind {
* lame for this query.
*/
#define DNS_ADBFIND_OVERQUOTA 0x00000400
/*%
* Don't perform a fetch even if there are no address records available.
*/
#define DNS_ADBFIND_NOFETCH 0x00000800
/*%
* The answers to queries come back as a list of these.
......
......@@ -183,6 +183,14 @@
#define DEFAULT_MAX_QUERIES 75
#endif /* ifndef DEFAULT_MAX_QUERIES */
/*
* After NS_FAIL_LIMIT attempts to fetch a name server address,
* if the number of addresses in the NS RRset exceeds NS_RR_LIMIT,
* stop trying to fetch, in order to avoid wasting resources.
*/
#define NS_FAIL_LIMIT 4
#define NS_RR_LIMIT 5
/* Number of hash buckets for zone counters */
#ifndef RES_DOMAIN_BUCKETS
#define RES_DOMAIN_BUCKETS 523
......@@ -3465,7 +3473,7 @@ sort_finds(dns_adbfindlist_t *findlist, unsigned int bias) {
static void
findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
unsigned int options, unsigned int flags, isc_stdtime_t now,
bool *overquota, bool *need_alternate) {
bool *overquota, bool *need_alternate, unsigned int *no_addresses) {
dns_adbaddrinfo_t *ai;
dns_adbfind_t *find;
dns_resolver_t *res;
......@@ -3562,6 +3570,9 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
{
*need_alternate = true;
}
if (no_addresses != NULL) {
(*no_addresses)++;
}
} else {
if ((find->options & DNS_ADBFIND_OVERQUOTA) != 0) {
if (overquota != NULL) {
......@@ -3616,6 +3627,7 @@ fctx_getaddresses(fetchctx_t *fctx, bool badcache) {
dns_rdata_ns_t ns;
bool need_alternate = false;
bool all_spilled = true;
unsigned int no_addresses = 0;
FCTXTRACE5("getaddresses", "fctx->depth=", fctx->depth);
......@@ -3792,8 +3804,13 @@ normal_nses:
continue;
}
if (no_addresses > NS_FAIL_LIMIT &&
dns_rdataset_count(&fctx->nameservers) > NS_RR_LIMIT)
{
stdoptions |= DNS_ADBFIND_NOFETCH;
}
findname(fctx, &ns.name, 0, stdoptions, 0, now, &overquota,
&need_alternate);
&need_alternate, &no_addresses);
if (!overquota) {
all_spilled = false;
......@@ -3818,7 +3835,7 @@ normal_nses:
if (!a->isaddress) {
findname(fctx, &a->_u._n.name, a->_u._n.port,
stdoptions, FCTX_ADDRINFO_FORWARDER,
now, NULL, NULL);
now, NULL, NULL, NULL);
continue;
}
if (isc_sockaddr_pf(&a->_u.addr) != family) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment