]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Reduce the number of fetches we make when looking up addresses
authorMark Andrews <marka@isc.org>
Thu, 6 Feb 2020 06:19:10 +0000 (17:19 +1100)
committerMichał Kępień <michal@isc.org>
Tue, 19 May 2020 10:30:29 +0000 (12:30 +0200)
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.

lib/dns/adb.c
lib/dns/include/dns/adb.h
lib/dns/resolver.c

index a2800226d1fdd7c9873e69c374e6b5d23e29a649..8df418d189dcfdce2a1d70549cdcc32b9427fcf1 100644 (file)
@@ -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
index 5895b5db3a91ba6e4e7c0ee416cbd4e8ef649c40..724f9b001acd101f1c0ab089e6622bd3204e4c17 100644 (file)
@@ -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.
index 80203d95e167b520352115560e5c1b56ad2f0f71..ed3ad58eaf3cf6f50333faca0b04f9e38d81deb0 100644 (file)
 #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) {