dns_rdata_ns_t ns;
bool have_address = false;
unsigned int ns_processed = 0;
+ size_t nscount = dns_rdataset_count(&fctx->nameservers);
+ size_t maxstartns = nscount > NS_PROCESSING_LIMIT ? NS_PROCESSING_LIMIT
+ : nscount;
+ size_t startns = isc_random_uniform(maxstartns);
+
+ for (size_t pass = 0; pass < 2; pass++) {
+ size_t curns = 0;
+
+ DNS_RDATASET_FOREACH(&fctx->nameservers) {
+ isc_result_t result = ISC_R_SUCCESS;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ bool overquota = false;
+ unsigned int static_stub = 0;
+ unsigned int no_fetch = 0;
+
+ if (pass == 0 && curns++ < startns) {
+ continue;
+ }
+ if (pass == 1 && curns++ >= startns) {
+ break;
+ }
- DNS_RDATASET_FOREACH(&fctx->nameservers) {
- isc_result_t result = ISC_R_SUCCESS;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- bool overquota = false;
- unsigned int static_stub = 0;
- unsigned int no_fetch = 0;
-
- dns_rdataset_current(&fctx->nameservers, &rdata);
- /*
- * Extract the name from the NS record.
- */
- result = dns_rdata_tostruct(&rdata, &ns, NULL);
- if (result != ISC_R_SUCCESS) {
- continue;
- }
+ dns_rdataset_current(&fctx->nameservers, &rdata);
+ /*
+ * Extract the name from the NS record.
+ */
+ result = dns_rdata_tostruct(&rdata, &ns, NULL);
+ if (result != ISC_R_SUCCESS) {
+ continue;
+ }
- if (STATICSTUB(&fctx->nameservers) &&
- dns_name_equal(&ns.name, fctx->domain))
- {
- static_stub = DNS_ADBFIND_STATICSTUB;
- }
+ if (STATICSTUB(&fctx->nameservers) &&
+ dns_name_equal(&ns.name, fctx->domain))
+ {
+ static_stub = DNS_ADBFIND_STATICSTUB;
+ }
- /*
- * Make sure we only launch a limited number of
- * outgoing fetches.
- */
- if (fctx->pending_running >= fetches_allowed) {
- no_fetch = DNS_ADBFIND_NOFETCH;
- }
+ /*
+ * Make sure we only launch a limited number of
+ * outgoing fetches.
+ */
+ if (fctx->pending_running >= fetches_allowed) {
+ no_fetch = DNS_ADBFIND_NOFETCH;
+ }
- findname(fctx, &ns.name, 0, stdoptions | static_stub | no_fetch,
- 0, now, &overquota, need_alternatep, &have_address);
+ findname(fctx, &ns.name, 0,
+ stdoptions | static_stub | no_fetch, 0, now,
+ &overquota, need_alternatep, &have_address);
- if (!overquota) {
- *all_spilledp = false;
- }
+ if (!overquota) {
+ *all_spilledp = false;
+ }
- dns_rdata_reset(&rdata);
- dns_rdata_freestruct(&ns);
+ dns_rdata_reset(&rdata);
+ dns_rdata_freestruct(&ns);
- if (++ns_processed >= NS_PROCESSING_LIMIT) {
- break;
+ if (++ns_processed >= NS_PROCESSING_LIMIT) {
+ break;
+ }
}
}