mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
[9.20] chg: dev: Implement Fisher-Yates shuffle for nameserver selection
Replace the two-pass "random start index and wrap around" logic in fctx_getaddresses_nameservers() with a statistically sound partial Fisher-Yates shuffle. The previous implementation picked a random starting node and did two passes over the linked list to find query candidates. The new logic introduces fctx_getaddresses_nsorder() to perform an in-place randomization of indices into a bounded, stack-allocated lookup array (nsorder) representing the "winning" fetch slots. The nameserver dataset is now traversed in exactly one sequential pass: 1. Every nameserver is evaluated for local cached data. 2. If the current nameserver's sequential index exists in the randomized nsorder array, it is permitted to launch an outgoing network fetch. 3. If not, it is restricted to local lookups via DNS_ADBFIND_NOFETCH. This guarantees a fair random distribution for outbound queries while maximizing local cache hits, entirely within O(1) memory and without the overhead of linked-list pointer shuffling or dynamic allocation. Closes #5695 Backport of MR !11604 Merge branch 'backport-5695-refactor-the-random-NS-selection-9.20' into 'bind-9.20' See merge request isc-projects/bind9!11606
This commit is contained in:
commit
dd453590a0
11 changed files with 425 additions and 64 deletions
39
bin/tests/system/nsprocessinglimit/ns1/named.conf.j2
Normal file
39
bin/tests/system/nsprocessinglimit/ns1/named.conf.j2
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.1;
|
||||
notify-source 10.53.0.1;
|
||||
transfer-source 10.53.0.1;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.1; };
|
||||
recursion no;
|
||||
dnssec-validation no;
|
||||
};
|
||||
|
||||
view "default" {
|
||||
zone "." {
|
||||
type primary;
|
||||
file "root.db";
|
||||
};
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
24
bin/tests/system/nsprocessinglimit/ns1/root.db
Normal file
24
bin/tests/system/nsprocessinglimit/ns1/root.db
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; SPDX-License-Identifier: MPL-2.0
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$TTL 300
|
||||
. IN SOA marka.isc.org. a.root.servers.nil. (
|
||||
2010 ; serial
|
||||
600 ; refresh
|
||||
600 ; retry
|
||||
1200 ; expire
|
||||
600 ; minimum
|
||||
)
|
||||
. NS a.root-servers.nil.
|
||||
a.root-servers.nil. A 10.53.0.1
|
||||
|
||||
tld. NS ns.tld.
|
||||
ns.tld. A 10.53.0.2
|
||||
37
bin/tests/system/nsprocessinglimit/ns2/named.conf.j2
Normal file
37
bin/tests/system/nsprocessinglimit/ns2/named.conf.j2
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.2;
|
||||
notify-source 10.53.0.2;
|
||||
transfer-source 10.53.0.2;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.2; };
|
||||
recursion no;
|
||||
dnssec-validation no;
|
||||
};
|
||||
|
||||
zone "tld." {
|
||||
type primary;
|
||||
file "tld.db";
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
25
bin/tests/system/nsprocessinglimit/ns2/tld.db
Normal file
25
bin/tests/system/nsprocessinglimit/ns2/tld.db
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; SPDX-License-Identifier: MPL-2.0
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$TTL 300
|
||||
tld. IN SOA marka.isc.org. ns.tld. (
|
||||
2010 ; serial
|
||||
600 ; refresh
|
||||
600 ; retry
|
||||
1200 ; expire
|
||||
600 ; minimum
|
||||
)
|
||||
tld. NS ns.tld.
|
||||
ns.tld. A 10.53.0.2
|
||||
|
||||
example.tld. NS ns.example.tld.
|
||||
ns.example.tld. A 10.53.0.3
|
||||
|
||||
68
bin/tests/system/nsprocessinglimit/ns3/example.tld.db
Normal file
68
bin/tests/system/nsprocessinglimit/ns3/example.tld.db
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; SPDX-License-Identifier: MPL-2.0
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
$TTL 300
|
||||
example.tld. IN SOA marka.isc.org. ns.dnshoster.tld. (
|
||||
2010 ; serial
|
||||
600 ; refresh
|
||||
600 ; retry
|
||||
1200 ; expire
|
||||
600 ; minimum
|
||||
)
|
||||
example.tld. NS ns.example.tld.
|
||||
ns.example.tld. A 10.53.0.3
|
||||
sub.example.tld. NS ns01.sub.example.tld.
|
||||
sub.example.tld. NS ns02.sub.example.tld.
|
||||
sub.example.tld. NS ns03.sub.example.tld.
|
||||
sub.example.tld. NS ns04.sub.example.tld.
|
||||
sub.example.tld. NS ns05.sub.example.tld.
|
||||
sub.example.tld. NS ns06.sub.example.tld.
|
||||
sub.example.tld. NS ns07.sub.example.tld.
|
||||
sub.example.tld. NS ns08.sub.example.tld.
|
||||
sub.example.tld. NS ns09.sub.example.tld.
|
||||
sub.example.tld. NS ns10.sub.example.tld.
|
||||
sub.example.tld. NS ns11.sub.example.tld.
|
||||
sub.example.tld. NS ns12.sub.example.tld.
|
||||
sub.example.tld. NS ns12.sub.example.tld.
|
||||
sub.example.tld. NS ns12.sub.example.tld.
|
||||
sub.example.tld. NS ns13.sub.example.tld.
|
||||
sub.example.tld. NS ns14.sub.example.tld.
|
||||
sub.example.tld. NS ns15.sub.example.tld.
|
||||
sub.example.tld. NS ns16.sub.example.tld.
|
||||
sub.example.tld. NS ns17.sub.example.tld.
|
||||
sub.example.tld. NS ns18.sub.example.tld.
|
||||
sub.example.tld. NS ns19.sub.example.tld.
|
||||
sub.example.tld. NS ns20.sub.example.tld.
|
||||
sub.example.tld. NS ns21.sub.example.tld.
|
||||
sub.example.tld. NS ns22.sub.example.tld.
|
||||
sub.example.tld. NS ns23.sub.example.tld.
|
||||
ns01.sub.example.tld. A 127.0.0.1
|
||||
ns02.sub.example.tld. A 127.0.0.2
|
||||
ns03.sub.example.tld. A 127.0.0.3
|
||||
ns04.sub.example.tld. A 127.0.0.4
|
||||
ns05.sub.example.tld. A 127.0.0.5
|
||||
ns06.sub.example.tld. A 127.0.0.6
|
||||
ns07.sub.example.tld. A 127.0.0.7
|
||||
ns08.sub.example.tld. A 127.0.0.8
|
||||
ns09.sub.example.tld. A 127.0.0.9
|
||||
ns10.sub.example.tld. A 127.0.0.10
|
||||
ns11.sub.example.tld. A 127.0.0.11
|
||||
ns12.sub.example.tld. A 127.0.0.12
|
||||
ns13.sub.example.tld. A 127.0.0.13
|
||||
ns14.sub.example.tld. A 127.0.0.14
|
||||
ns15.sub.example.tld. A 127.0.0.15
|
||||
ns16.sub.example.tld. A 127.0.0.16
|
||||
ns17.sub.example.tld. A 127.0.0.17
|
||||
ns18.sub.example.tld. A 127.0.0.18
|
||||
ns19.sub.example.tld. A 127.0.0.19
|
||||
ns20.sub.example.tld. A 127.0.0.20
|
||||
ns21.sub.example.tld. A 127.0.0.21
|
||||
ns22.sub.example.tld. A 127.0.0.22
|
||||
ns23.sub.example.tld. A 127.0.0.23
|
||||
37
bin/tests/system/nsprocessinglimit/ns3/named.conf.j2
Normal file
37
bin/tests/system/nsprocessinglimit/ns3/named.conf.j2
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.3;
|
||||
notify-source 10.53.0.3;
|
||||
transfer-source 10.53.0.3;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.3; };
|
||||
recursion no;
|
||||
dnssec-validation no;
|
||||
};
|
||||
|
||||
zone "example.tld." {
|
||||
type primary;
|
||||
file "example.tld.db";
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
1
bin/tests/system/nsprocessinglimit/ns4/named.args
Normal file
1
bin/tests/system/nsprocessinglimit/ns4/named.args
Normal file
|
|
@ -0,0 +1 @@
|
|||
-D nsprocessinglimit-ns4 -m record -c named.conf -d 99 -g -T maxcachesize=2097152 -4
|
||||
39
bin/tests/system/nsprocessinglimit/ns4/named.conf.j2
Normal file
39
bin/tests/system/nsprocessinglimit/ns4/named.conf.j2
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.4;
|
||||
notify-source 10.53.0.4;
|
||||
transfer-source 10.53.0.4;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.4; };
|
||||
recursion yes;
|
||||
dnssec-validation no;
|
||||
dnstap { resolver query; };
|
||||
dnstap-output file "dnstap.out";
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type hint;
|
||||
file "root.hint";
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
14
bin/tests/system/nsprocessinglimit/ns4/root.hint
Normal file
14
bin/tests/system/nsprocessinglimit/ns4/root.hint
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; SPDX-License-Identifier: MPL-2.0
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$TTL 999999
|
||||
. IN NS a.root-servers.nil.
|
||||
a.root-servers.nil. IN A 10.53.0.1
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
import os
|
||||
|
||||
import isctest
|
||||
import isctest.mark
|
||||
|
||||
pytestmark = [isctest.mark.with_dnstap]
|
||||
|
||||
|
||||
def line_to_ips_and_queries(line):
|
||||
# dnstap-read output line example
|
||||
# 05-Feb-2026 11:00:57.853 RQ 10.53.0.4:38507 -> 10.53.0.3:22047 TCP 56b sub.example.tld/IN/NS
|
||||
_, _, _, _, _, dst, _, _, query = line.split(" ", 9)
|
||||
ip, _ = dst.split(":", 1)
|
||||
return (ip, query)
|
||||
|
||||
|
||||
def extract_dnstap(ns, expectedlen):
|
||||
ns.rndc("dnstap -roll 1")
|
||||
path = os.path.join(ns.identifier, "dnstap.out.0")
|
||||
dnstapread = isctest.run.cmd(
|
||||
[isctest.vars.ALL["DNSTAPREAD"], path],
|
||||
)
|
||||
|
||||
lines = dnstapread.out.splitlines()
|
||||
assert expectedlen == len(lines)
|
||||
return map(line_to_ips_and_queries, lines)
|
||||
|
||||
|
||||
def expect_query(expected_query, expected_query_count, ips_and_queries):
|
||||
count = 0
|
||||
for _, query in ips_and_queries:
|
||||
if query == expected_query:
|
||||
count += 1
|
||||
assert count == expected_query_count
|
||||
|
||||
|
||||
def expect_next_ip_and_query(expected_ips_and_queries, ips_and_queries):
|
||||
for expected_ip, expected_query in expected_ips_and_queries:
|
||||
ip, query = next(ips_and_queries)
|
||||
assert ip == expected_ip
|
||||
assert query == expected_query
|
||||
|
||||
|
||||
def test_selfpointedglue_nslimit(ns4):
|
||||
msg = isctest.query.create("a.sub.example.tld.", "A")
|
||||
res = isctest.query.tcp(msg, ns4.ip)
|
||||
isctest.check.servfail(res)
|
||||
|
||||
# The 4 formers lines are request to find sub.example2.tld NSs.
|
||||
# The latest 20 are queries to sub.example2.tld NSs.
|
||||
ips_and_queries = extract_dnstap(ns4, 24)
|
||||
|
||||
# Checking the begining of the resulution
|
||||
expect_next_ip_and_query(
|
||||
[
|
||||
("10.53.0.1", "./IN/NS"),
|
||||
("10.53.0.1", "tld/IN/NS"),
|
||||
("10.53.0.2", "example.tld/IN/NS"),
|
||||
("10.53.0.3", "sub.example.tld/IN/NS"),
|
||||
],
|
||||
ips_and_queries,
|
||||
)
|
||||
expect_query("a.sub.example.tld/IN/A", 20, ips_and_queries)
|
||||
|
|
@ -3474,6 +3474,8 @@ fctx_getaddresses(fetchctx_t *fctx) {
|
|||
bool have_address = false;
|
||||
unsigned int ns_processed = 0;
|
||||
size_t fetches_allowed = 0;
|
||||
dns_rdata_t nameservers_s[NS_PROCESSING_LIMIT];
|
||||
dns_rdata_t *nameservers[NS_PROCESSING_LIMIT];
|
||||
|
||||
FCTXTRACE5("getaddresses", "fctx->depth=", fctx->depth);
|
||||
|
||||
|
|
@ -3657,73 +3659,74 @@ normal_nses:
|
|||
break;
|
||||
}
|
||||
|
||||
for (result = dns_rdataset_first(&fctx->nameservers);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(&fctx->nameservers))
|
||||
{
|
||||
dns_rdata_t *rdata = nameservers[ns_processed] =
|
||||
&nameservers_s[ns_processed];
|
||||
|
||||
dns_rdata_init(rdata);
|
||||
|
||||
dns_rdataset_current(&fctx->nameservers, rdata);
|
||||
|
||||
if (++ns_processed >= NS_PROCESSING_LIMIT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ns_processed > 1 && ns_processed > fetches_allowed) {
|
||||
/*
|
||||
* Skip the shuffle if:
|
||||
* - there's nothing to shuffle (no or one nameserver)
|
||||
* - there are less nameserver than allowed fetches as
|
||||
* we are going to start fetches for all of them.
|
||||
*/
|
||||
for (size_t i = 0; i < ns_processed - 1; i++) {
|
||||
size_t j = i + isc_random_uniform(ns_processed - i);
|
||||
|
||||
ISC_SWAP(nameservers[i], nameservers[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
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 i = 0; i < ns_processed; i++) {
|
||||
bool overquota = false;
|
||||
unsigned int static_stub = 0;
|
||||
unsigned int no_fetch = 0;
|
||||
dns_rdata_t *rdata = nameservers[i];
|
||||
|
||||
for (size_t pass = 0; pass < 2; pass++) {
|
||||
size_t curns = 0;
|
||||
|
||||
for (result = dns_rdataset_first(&fctx->nameservers);
|
||||
result == ISC_R_SUCCESS;
|
||||
result = dns_rdataset_next(&fctx->nameservers))
|
||||
{
|
||||
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_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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_alternate,
|
||||
&have_address);
|
||||
|
||||
if (!overquota) {
|
||||
all_spilled = false;
|
||||
}
|
||||
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdata_freestruct(&ns);
|
||||
|
||||
if (++ns_processed >= NS_PROCESSING_LIMIT) {
|
||||
result = ISC_R_NOMORE;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_alternate, &have_address);
|
||||
|
||||
if (!overquota) {
|
||||
all_spilled = false;
|
||||
}
|
||||
|
||||
dns_rdata_freestruct(&ns);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue