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

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