diff -Naur bind-9.9.6-P1.orig/lib/dns/adb.c bind-9.9.6-P1.new/lib/dns/adb.c
--- bind-9.9.6-P1.orig/lib/dns/adb.c	2014-11-21 00:59:27.000000000 +0100
+++ bind-9.9.6-P1.new/lib/dns/adb.c	2020-06-09 12:05:09.465976000 +0200
@@ -375,14 +375,13 @@
  */
 #define FIND_WANTEVENT(fn)      (((fn)->options & DNS_ADBFIND_WANTEVENT) != 0)
 #define FIND_WANTEMPTYEVENT(fn) (((fn)->options & DNS_ADBFIND_EMPTYEVENT) != 0)
-#define FIND_AVOIDFETCHES(fn)   (((fn)->options & DNS_ADBFIND_AVOIDFETCHES) \
-				 != 0)
-#define FIND_STARTATZONE(fn)    (((fn)->options & DNS_ADBFIND_STARTATZONE) \
-				 != 0)
-#define FIND_HINTOK(fn)         (((fn)->options & DNS_ADBFIND_HINTOK) != 0)
-#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_AVOIDFETCHES(fn)	(((fn)->options & DNS_ADBFIND_AVOIDFETCHES) != 0)
+#define FIND_STARTATZONE(fn)	(((fn)->options & DNS_ADBFIND_STARTATZONE) != 0)
+#define FIND_HINTOK(fn)		(((fn)->options & DNS_ADBFIND_HINTOK) != 0)
+#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
@@ -3014,21 +3013,25 @@
 		 * Listen to negative cache hints, and don't start
 		 * another query.
 		 */
-		if (NCACHE_RESULT(result) || AUTH_NX(result))
+		if (NCACHE_RESULT(result) || AUTH_NX(result)) {
 			goto fetch;
+		}
 
-		if (!NAME_FETCH_V6(adbname))
+		if (!NAME_FETCH_V6(adbname)) {
 			wanted_fetches |= DNS_ADBFIND_INET6;
+		}
 	}
 
  fetch:
 	if ((WANT_INET(wanted_addresses) && NAME_HAS_V4(adbname)) ||
-	    (WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname)))
+	    (WANT_INET6(wanted_addresses) && NAME_HAS_V6(adbname))) {
 		have_address = ISC_TRUE;
-	else
+	} else {
 		have_address = ISC_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
@@ -3036,8 +3039,9 @@
 		 * be acceptable so we have to launch fetches.
 		 */
 
-		if (FIND_STARTATZONE(find))
+		if (FIND_STARTATZONE(find)) {
 			start_at_zone = ISC_TRUE;
+		}
 
 		/*
 		 * Start V4.
diff -Naur bind-9.9.6-P1.orig/lib/dns/include/dns/adb.h bind-9.9.6-P1.new/lib/dns/include/dns/adb.h
--- bind-9.9.6-P1.orig/lib/dns/include/dns/adb.h	2014-11-21 00:59:27.000000000 +0100
+++ bind-9.9.6-P1.new/lib/dns/include/dns/adb.h	2020-06-09 14:36:02.406335000 +0200
@@ -207,6 +207,12 @@
  */
 #define DNS_ADBFIND_LAMEPRUNED		0x00000200
 
+#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.
  */
diff -Naur bind-9.9.6-P1.orig/lib/dns/resolver.c bind-9.9.6-P1.new/lib/dns/resolver.c
--- bind-9.9.6-P1.orig/lib/dns/resolver.c	2020-06-09 14:31:53.218332000 +0200
+++ bind-9.9.6-P1.new/lib/dns/resolver.c	2020-06-09 14:37:19.579308000 +0200
@@ -142,6 +142,14 @@
 #define DEFAULT_MAX_QUERIES 50
 #endif
 
+/*
+ * 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
+
 /*%
  * Maximum EDNS0 input packet size.
  */
@@ -2476,7 +2484,7 @@
 static void
 findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
 	 unsigned int options, unsigned int flags, isc_stdtime_t now,
-	 isc_boolean_t *need_alternate)
+	 isc_boolean_t *need_alternate, unsigned int *no_addresses)
 {
 	dns_adbaddrinfo_t *ai;
 	dns_adbfind_t *find;
@@ -2557,7 +2565,12 @@
 			      find->result_v6 != DNS_R_NXDOMAIN) ||
 			     (res->dispatchv6 == NULL &&
 			      find->result_v4 != DNS_R_NXDOMAIN)))
+			      {
 				*need_alternate = ISC_TRUE;
+			      }
+			      if (no_addresses != NULL) {
+				(*no_addresses)++;
+			      }
 		} else {
 			if ((find->options & DNS_ADBFIND_LAMEPRUNED) != 0)
 				fctx->lamecount++; /* cached lame server */
@@ -2602,6 +2615,7 @@
 	isc_boolean_t all_bad;
 	dns_rdata_ns_t ns;
 	isc_boolean_t need_alternate = ISC_FALSE;
+	unsigned int no_addresses = 0;
 
 	FCTXTRACE("getaddresses");
 
@@ -2746,16 +2760,24 @@
 		 * Extract the name from the NS record.
 		 */
 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
-		if (result != ISC_R_SUCCESS)
+		if (result != ISC_R_SUCCESS) {
 			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,
-			 &need_alternate);
+			 &need_alternate, &no_addresses);
+ 
 		dns_rdata_reset(&rdata);
 		dns_rdata_freestruct(&ns);
 	}
-	if (result != ISC_R_NOMORE)
+	if (result != ISC_R_NOMORE) {
 		return (result);
+	}
 
 	/*
 	 * Do we need to use 6 to 4?
@@ -2770,7 +2792,7 @@
 			if (!a->isaddress) {
 				findname(fctx, &a->_u._n.name, a->_u._n.port,
 					 stdoptions, FCTX_ADDRINFO_FORWARDER,
-					 now, NULL);
+					 now, NULL, NULL);
 				continue;
 			}
 			if (isc_sockaddr_pf(&a->_u.addr) != family)
