mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-27 20:25:55 -04:00
[CVE-2026-3592] sec: usr: Limit resolver server list size
When resolving a domain with many nameservers that share overlapping IP addresses (e.g., 10 NS records all pointing at the same set of addresses), BIND could previously waste time querying duplicate addresses and build up excessively large server lists. Deduplicate addresses in the resolver's server list so that each unique IP is only queried once per resolution attempt, regardless of how many NS records point to it and cap the number of addresses stored per nameserver name to 6 (combined A and AAAA), preventing memory and CPU overhead from domains with unusually large NS/glue sets. Closes isc-projects/bind9#5641 Merge branch '5641-selfpointedglue' into 'security-main' See merge request isc-private/bind9!909
This commit is contained in:
commit
e249148d75
41 changed files with 1823 additions and 152 deletions
28
bin/tests/system/nslimit_outdomain/ns1/named.conf.j2
Normal file
28
bin/tests/system/nslimit_outdomain/ns1/named.conf.j2
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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;
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type primary;
|
||||
file "root.db";
|
||||
};
|
||||
24
bin/tests/system/nslimit_outdomain/ns1/root.db
Normal file
24
bin/tests/system/nslimit_outdomain/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 owner.root-servers.nil. 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
|
||||
33
bin/tests/system/nslimit_outdomain/ns2/dnshoster.tld.db
Normal file
33
bin/tests/system/nslimit_outdomain/ns2/dnshoster.tld.db
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
; 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
|
||||
dnshoster.tld. IN SOA owner.tld. ns.tld. (
|
||||
2010 ; serial
|
||||
600 ; refresh
|
||||
600 ; retry
|
||||
1200 ; expire
|
||||
600 ; minimum
|
||||
)
|
||||
|
||||
dnshoster.tld. NS ns1.dnshoster.tld.
|
||||
ns1.dnshoster.tld. A 10.53.0.5
|
||||
ns1.dnshoster.tld. A 10.53.0.6
|
||||
|
||||
dnshoster.tld. NS ns2.dnshoster.tld.
|
||||
ns2.dnshoster.tld. A 10.53.1.1
|
||||
ns2.dnshoster.tld. A 10.53.1.2
|
||||
|
||||
dnshoster.tld. NS ns3.dnshoster.tld.
|
||||
ns3.dnshoster.tld. A 10.53.2.1
|
||||
ns3.dnshoster.tld. A 10.53.2.2
|
||||
|
||||
|
||||
41
bin/tests/system/nslimit_outdomain/ns2/named.conf.j2
Normal file
41
bin/tests/system/nslimit_outdomain/ns2/named.conf.j2
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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;
|
||||
10.53.0.5;
|
||||
10.53.0.6;
|
||||
10.53.0.7;
|
||||
10.53.1.1;
|
||||
10.53.1.2;
|
||||
10.53.2.2;
|
||||
};
|
||||
recursion no;
|
||||
dnssec-validation no;
|
||||
};
|
||||
|
||||
zone "tld." {
|
||||
type primary;
|
||||
file "tld.db";
|
||||
};
|
||||
|
||||
zone "dnshoster.tld." {
|
||||
type primary;
|
||||
file "dnshoster.tld.db";
|
||||
};
|
||||
36
bin/tests/system/nslimit_outdomain/ns2/tld.db
Normal file
36
bin/tests/system/nslimit_outdomain/ns2/tld.db
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
; 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 owner.tld. ns.tld. (
|
||||
2010 ; serial
|
||||
600 ; refresh
|
||||
600 ; retry
|
||||
1200 ; expire
|
||||
600 ; minimum
|
||||
)
|
||||
tld. NS ns.tld.
|
||||
ns.tld. A 10.53.0.2
|
||||
|
||||
example4.tld. NS ns.example4.tld.
|
||||
ns.example4.tld. A 10.53.0.3
|
||||
|
||||
dnshoster.tld. NS ns1.dnshoster.tld.
|
||||
ns1.dnshoster.tld. A 10.53.0.5
|
||||
ns1.dnshoster.tld. A 10.53.0.6
|
||||
|
||||
dnshoster.tld. NS ns2.dnshoster.tld.
|
||||
ns2.dnshoster.tld. A 10.53.1.1
|
||||
ns2.dnshoster.tld. A 10.53.1.2
|
||||
|
||||
dnshoster.tld. NS ns3.dnshoster.tld.
|
||||
ns3.dnshoster.tld. A 10.53.2.1
|
||||
ns3.dnshoster.tld. A 10.53.2.2
|
||||
184
bin/tests/system/nslimit_outdomain/ns3/example.tld.db
Normal file
184
bin/tests/system/nslimit_outdomain/ns3/example.tld.db
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
; 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 owner.dnshoster.tld. 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.
|
||||
|
||||
ns01.sub.example.tld. A 10.53.0.5
|
||||
ns01.sub.example.tld. A 10.53.0.6
|
||||
ns01.sub.example.tld. A 10.53.0.7
|
||||
ns01.sub.example.tld. A 10.53.0.8
|
||||
ns01.sub.example.tld. A 10.53.0.9
|
||||
ns01.sub.example.tld. A 10.53.0.10
|
||||
ns01.sub.example.tld. A 10.53.1.1
|
||||
ns01.sub.example.tld. A 10.53.1.2
|
||||
ns01.sub.example.tld. A 10.53.2.1
|
||||
ns01.sub.example.tld. A 10.53.0.3
|
||||
ns01.sub.example.tld. A 127.0.0.1
|
||||
ns01.sub.example.tld. A 127.0.0.2
|
||||
; Those addresses won't be used (exceed the max-delegation-servers).
|
||||
ns01.sub.example.tld. A 127.0.0.3
|
||||
ns01.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns02.sub.example.tld. A 10.53.0.5
|
||||
ns02.sub.example.tld. A 10.53.0.6
|
||||
ns02.sub.example.tld. A 10.53.0.7
|
||||
ns02.sub.example.tld. A 10.53.0.8
|
||||
ns02.sub.example.tld. A 10.53.0.9
|
||||
ns02.sub.example.tld. A 10.53.0.10
|
||||
ns02.sub.example.tld. A 10.53.1.1
|
||||
ns02.sub.example.tld. A 10.53.1.2
|
||||
ns02.sub.example.tld. A 10.53.2.1
|
||||
ns02.sub.example.tld. A 10.53.0.3
|
||||
ns02.sub.example.tld. A 127.0.0.1
|
||||
ns02.sub.example.tld. A 127.0.0.2
|
||||
ns02.sub.example.tld. A 127.0.0.3
|
||||
ns02.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns03.sub.example.tld. A 10.53.0.5
|
||||
ns03.sub.example.tld. A 10.53.0.6
|
||||
ns03.sub.example.tld. A 10.53.0.7
|
||||
ns03.sub.example.tld. A 10.53.0.8
|
||||
ns03.sub.example.tld. A 10.53.0.9
|
||||
ns03.sub.example.tld. A 10.53.0.10
|
||||
ns03.sub.example.tld. A 10.53.1.1
|
||||
ns03.sub.example.tld. A 10.53.1.2
|
||||
ns03.sub.example.tld. A 10.53.2.1
|
||||
ns03.sub.example.tld. A 10.53.0.3
|
||||
ns03.sub.example.tld. A 127.0.0.1
|
||||
ns03.sub.example.tld. A 127.0.0.2
|
||||
ns03.sub.example.tld. A 127.0.0.3
|
||||
ns03.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns04.sub.example.tld. A 10.53.0.5
|
||||
ns04.sub.example.tld. A 10.53.0.6
|
||||
ns04.sub.example.tld. A 10.53.0.7
|
||||
ns04.sub.example.tld. A 10.53.0.8
|
||||
ns04.sub.example.tld. A 10.53.0.9
|
||||
ns04.sub.example.tld. A 10.53.0.10
|
||||
ns04.sub.example.tld. A 10.53.1.1
|
||||
ns04.sub.example.tld. A 10.53.1.2
|
||||
ns04.sub.example.tld. A 10.53.2.1
|
||||
ns04.sub.example.tld. A 10.53.0.3
|
||||
ns04.sub.example.tld. A 127.0.0.1
|
||||
ns04.sub.example.tld. A 127.0.0.2
|
||||
ns04.sub.example.tld. A 127.0.0.3
|
||||
ns04.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns05.sub.example.tld. A 10.53.0.5
|
||||
ns05.sub.example.tld. A 10.53.0.6
|
||||
ns05.sub.example.tld. A 10.53.0.7
|
||||
ns05.sub.example.tld. A 10.53.0.8
|
||||
ns05.sub.example.tld. A 10.53.0.9
|
||||
ns05.sub.example.tld. A 10.53.0.10
|
||||
ns05.sub.example.tld. A 10.53.1.1
|
||||
ns05.sub.example.tld. A 10.53.1.2
|
||||
ns05.sub.example.tld. A 10.53.2.1
|
||||
ns05.sub.example.tld. A 10.53.0.3
|
||||
ns05.sub.example.tld. A 127.0.0.1
|
||||
ns05.sub.example.tld. A 127.0.0.2
|
||||
ns05.sub.example.tld. A 127.0.0.3
|
||||
ns05.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns06.sub.example.tld. A 10.53.0.5
|
||||
ns06.sub.example.tld. A 10.53.0.6
|
||||
ns06.sub.example.tld. A 10.53.0.7
|
||||
ns06.sub.example.tld. A 10.53.0.8
|
||||
ns06.sub.example.tld. A 10.53.0.9
|
||||
ns06.sub.example.tld. A 10.53.0.10
|
||||
ns06.sub.example.tld. A 10.53.1.1
|
||||
ns06.sub.example.tld. A 10.53.1.2
|
||||
ns06.sub.example.tld. A 10.53.2.1
|
||||
ns06.sub.example.tld. A 10.53.0.3
|
||||
ns06.sub.example.tld. A 127.0.0.1
|
||||
ns06.sub.example.tld. A 127.0.0.2
|
||||
ns06.sub.example.tld. A 127.0.0.3
|
||||
ns06.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns07.sub.example.tld. A 10.53.0.5
|
||||
ns07.sub.example.tld. A 10.53.0.6
|
||||
ns07.sub.example.tld. A 10.53.0.7
|
||||
ns07.sub.example.tld. A 10.53.0.8
|
||||
ns07.sub.example.tld. A 10.53.0.9
|
||||
ns07.sub.example.tld. A 10.53.0.10
|
||||
ns07.sub.example.tld. A 10.53.1.1
|
||||
ns07.sub.example.tld. A 10.53.1.2
|
||||
ns07.sub.example.tld. A 10.53.2.1
|
||||
ns07.sub.example.tld. A 10.53.0.3
|
||||
ns07.sub.example.tld. A 127.0.0.1
|
||||
ns07.sub.example.tld. A 127.0.0.2
|
||||
ns07.sub.example.tld. A 127.0.0.3
|
||||
ns07.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns08.sub.example.tld. A 10.53.0.5
|
||||
ns08.sub.example.tld. A 10.53.0.6
|
||||
ns08.sub.example.tld. A 10.53.0.7
|
||||
ns08.sub.example.tld. A 10.53.0.8
|
||||
ns08.sub.example.tld. A 10.53.0.9
|
||||
ns08.sub.example.tld. A 10.53.0.10
|
||||
ns08.sub.example.tld. A 10.53.1.1
|
||||
ns08.sub.example.tld. A 10.53.1.2
|
||||
ns08.sub.example.tld. A 10.53.2.1
|
||||
ns08.sub.example.tld. A 10.53.0.3
|
||||
ns08.sub.example.tld. A 127.0.0.1
|
||||
ns08.sub.example.tld. A 127.0.0.2
|
||||
ns08.sub.example.tld. A 127.0.0.3
|
||||
ns08.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns09.sub.example.tld. A 10.53.0.5
|
||||
ns09.sub.example.tld. A 10.53.0.6
|
||||
ns09.sub.example.tld. A 10.53.0.7
|
||||
ns09.sub.example.tld. A 10.53.0.8
|
||||
ns09.sub.example.tld. A 10.53.0.9
|
||||
ns09.sub.example.tld. A 10.53.0.10
|
||||
ns09.sub.example.tld. A 10.53.1.1
|
||||
ns09.sub.example.tld. A 10.53.1.2
|
||||
ns09.sub.example.tld. A 10.53.2.1
|
||||
ns09.sub.example.tld. A 10.53.0.3
|
||||
ns09.sub.example.tld. A 127.0.0.1
|
||||
ns09.sub.example.tld. A 127.0.0.2
|
||||
ns09.sub.example.tld. A 127.0.0.3
|
||||
ns09.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns10.sub.example.tld. A 10.53.0.5
|
||||
ns10.sub.example.tld. A 10.53.0.6
|
||||
ns10.sub.example.tld. A 10.53.0.7
|
||||
ns10.sub.example.tld. A 10.53.0.8
|
||||
ns10.sub.example.tld. A 10.53.0.9
|
||||
ns10.sub.example.tld. A 10.53.0.10
|
||||
ns10.sub.example.tld. A 10.53.1.1
|
||||
ns10.sub.example.tld. A 10.53.1.2
|
||||
ns10.sub.example.tld. A 10.53.2.1
|
||||
ns10.sub.example.tld. A 10.53.0.3
|
||||
ns10.sub.example.tld. A 127.0.0.1
|
||||
ns10.sub.example.tld. A 127.0.0.2
|
||||
ns10.sub.example.tld. A 127.0.0.3
|
||||
ns10.sub.example.tld. A 127.0.0.4
|
||||
24
bin/tests/system/nslimit_outdomain/ns3/example4.tld.db
Normal file
24
bin/tests/system/nslimit_outdomain/ns3/example4.tld.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
|
||||
example4.tld. IN SOA owner.dnshoster.tld. ns.dnshoster.tld. (
|
||||
2010 ; serial
|
||||
600 ; refresh
|
||||
600 ; retry
|
||||
1200 ; expire
|
||||
600 ; minimum
|
||||
)
|
||||
|
||||
example4.tld. NS ns.example4.tld.
|
||||
ns.example4.tld. A 10.53.0.3
|
||||
sub.example4.tld. NS ns1.dnshoster.tld.
|
||||
sub.example4.tld. NS ns2.dnshoster.tld.
|
||||
30
bin/tests/system/nslimit_outdomain/ns3/named.conf.j2
Normal file
30
bin/tests/system/nslimit_outdomain/ns3/named.conf.j2
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 "example4.tld." {
|
||||
type primary;
|
||||
file "example4.tld.db";
|
||||
};
|
||||
1
bin/tests/system/nslimit_outdomain/ns4/named.args.j2
Normal file
1
bin/tests/system/nslimit_outdomain/ns4/named.args.j2
Normal file
|
|
@ -0,0 +1 @@
|
|||
-D selfpointedglue-ns4 -m record -c named.conf -d 99 -g -T maxcachesize=2097152 -4
|
||||
59
bin/tests/system/nslimit_outdomain/ns4/named.conf.j2
Normal file
59
bin/tests/system/nslimit_outdomain/ns4/named.conf.j2
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
{% set maxdelegationservers = maxdelegationservers | default(None) %}
|
||||
|
||||
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";
|
||||
{% if maxdelegationservers %}
|
||||
@maxdelegationservers@
|
||||
{% endif %}
|
||||
};
|
||||
|
||||
/*
|
||||
* Forcing TCP ensures that ADDITIONAL won't be truncated (responses won't have
|
||||
* the TC flag, hence the resolver won't retry using TCP by itself, see
|
||||
* https://datatracker.ietf.org/doc/html/rfc2181#section-9)
|
||||
*/
|
||||
server 10.53.0.3 { tcp-only true; };
|
||||
server 10.53.0.5 { tcp-only true; };
|
||||
server 10.53.0.6 { tcp-only true; };
|
||||
server 10.53.0.7 { tcp-only true; };
|
||||
server 10.53.0.8 { tcp-only true; };
|
||||
server 10.53.0.9 { tcp-only true; };
|
||||
server 10.53.0.10 { tcp-only true; };
|
||||
server 10.53.1.1 { tcp-only true; };
|
||||
server 10.53.1.2 { tcp-only true; };
|
||||
server 10.53.2.1 { tcp-only true; };
|
||||
|
||||
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/nslimit_outdomain/ns4/root.hint
Normal file
14
bin/tests/system/nslimit_outdomain/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
|
||||
120
bin/tests/system/nslimit_outdomain/tests_nslimit_outdomain.py
Normal file
120
bin/tests/system/nslimit_outdomain/tests_nslimit_outdomain.py
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
# 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 list(map(line_to_ips_and_queries, lines))
|
||||
|
||||
|
||||
# Because DNSTAP doesn't have ordering guarantee, the order doesn't matter here.
|
||||
def has_ip_and_query(expected_ips_and_queries, ips_and_queries):
|
||||
found_count = 0
|
||||
for expected_ip, expected_query in expected_ips_and_queries:
|
||||
for ip, query in ips_and_queries:
|
||||
if ip == expected_ip and query == expected_query:
|
||||
found_count += 1
|
||||
break
|
||||
return found_count == len(expected_ips_and_queries)
|
||||
|
||||
|
||||
# Test the max-delegation-servers limit on flow where ADB attempt
|
||||
# a lookup from an NS name rather than directly with the NS addresses.
|
||||
def test_nslimit_outdomain(ns4, templates):
|
||||
templates.render(
|
||||
"ns4/named.conf", {"maxdelegationservers": "max-delegation-servers 2;"}
|
||||
)
|
||||
with ns4.watch_log_from_here() as watcher:
|
||||
ns4.rndc("flush")
|
||||
ns4.rndc("reload")
|
||||
watcher.wait_for_line("running")
|
||||
|
||||
msg = isctest.query.create("sub.example4.tld.", "A")
|
||||
res = isctest.query.tcp(msg, ns4.ip)
|
||||
isctest.check.servfail(res)
|
||||
|
||||
ips_and_queries = extract_dnstap(ns4, 9)
|
||||
|
||||
# The resolver first resolve example4.tld. and gets the NS for sub.example.tld.
|
||||
# which is out-domain. So it resolves it.
|
||||
assert has_ip_and_query(
|
||||
[
|
||||
("10.53.0.1", "./IN/NS"),
|
||||
("10.53.0.1", "tld/IN/NS"),
|
||||
("10.53.0.2", "example4.tld/IN/NS"),
|
||||
("10.53.0.3", "sub.example4.tld/IN/A"),
|
||||
("10.53.0.2", "dnshoster.tld/IN/NS"),
|
||||
],
|
||||
ips_and_queries,
|
||||
)
|
||||
|
||||
# Then, because max-delegation-servers is 2, the resolver will try to use either
|
||||
# the NS ns1.dnshoster.tld or the NS ns2.dnshoster.tld. or the NS ns3.dnshoster.tld.
|
||||
#
|
||||
# What is important here, is that the NS of sub.example4.tld are _names_, so
|
||||
# this is going through the dns_adb_createfind() flow, and it does stop after 2
|
||||
# queries (on the two IPs of one of the NS server above) and _won't_ try another
|
||||
# NS name (becuse max-delegation-servers will be reached).
|
||||
#
|
||||
# Note that the sum of all the queries checked here is 8 and not 9. This is because
|
||||
# when dnshoster.tld has been resolved, the resolver resolved 2 names. But the IPs
|
||||
# of only one of the two names has been used. (This is checked below).
|
||||
|
||||
used_ns1 = has_ip_and_query(
|
||||
[
|
||||
("10.53.0.2", "ns1.dnshoster.tld/IN/A"),
|
||||
("10.53.0.5", "sub.example4.tld/IN/A"),
|
||||
("10.53.0.6", "sub.example4.tld/IN/A"),
|
||||
],
|
||||
ips_and_queries,
|
||||
)
|
||||
|
||||
used_ns2 = has_ip_and_query(
|
||||
[
|
||||
("10.53.0.2", "ns2.dnshoster.tld/IN/A"),
|
||||
("10.53.1.1", "sub.example4.tld/IN/A"),
|
||||
("10.53.1.2", "sub.example4.tld/IN/A"),
|
||||
],
|
||||
ips_and_queries,
|
||||
)
|
||||
|
||||
used_ns3 = has_ip_and_query(
|
||||
[
|
||||
("10.53.0.2", "ns3.dnshoster.tld/IN/A"),
|
||||
("10.53.2.1", "sub.example4.tld/IN/A"),
|
||||
("10.53.2.2", "sub.example4.tld/IN/A"),
|
||||
],
|
||||
ips_and_queries,
|
||||
)
|
||||
|
||||
assert used_ns1 or used_ns2 or used_ns3
|
||||
28
bin/tests/system/selfpointedglue/ns1/named.conf.j2
Normal file
28
bin/tests/system/selfpointedglue/ns1/named.conf.j2
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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;
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type primary;
|
||||
file "root.db";
|
||||
};
|
||||
24
bin/tests/system/selfpointedglue/ns1/root.db
Normal file
24
bin/tests/system/selfpointedglue/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 owner.root-servers.nil. 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
|
||||
28
bin/tests/system/selfpointedglue/ns2/named.conf.j2
Normal file
28
bin/tests/system/selfpointedglue/ns2/named.conf.j2
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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";
|
||||
};
|
||||
30
bin/tests/system/selfpointedglue/ns2/tld.db
Normal file
30
bin/tests/system/selfpointedglue/ns2/tld.db
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
; 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 owner.tld. 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
|
||||
|
||||
example2.tld. NS ns.example2.tld.
|
||||
ns.example2.tld. A 10.53.0.3
|
||||
|
||||
example3.tld. NS ns.example3.tld.
|
||||
ns.example3.tld. A 10.53.0.3
|
||||
184
bin/tests/system/selfpointedglue/ns3/example.tld.db
Normal file
184
bin/tests/system/selfpointedglue/ns3/example.tld.db
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
; 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 owner.dnshoster.tld. 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.
|
||||
|
||||
ns01.sub.example.tld. A 10.53.0.5
|
||||
ns01.sub.example.tld. A 10.53.0.6
|
||||
ns01.sub.example.tld. A 10.53.0.7
|
||||
ns01.sub.example.tld. A 10.53.0.8
|
||||
ns01.sub.example.tld. A 10.53.0.9
|
||||
ns01.sub.example.tld. A 10.53.0.10
|
||||
ns01.sub.example.tld. A 10.53.1.1
|
||||
ns01.sub.example.tld. A 10.53.1.2
|
||||
ns01.sub.example.tld. A 10.53.2.1
|
||||
ns01.sub.example.tld. A 10.53.0.3
|
||||
ns01.sub.example.tld. A 127.0.0.1
|
||||
ns01.sub.example.tld. A 127.0.0.2
|
||||
; Those addresses won't be used (exceed the max-delegation-servers).
|
||||
ns01.sub.example.tld. A 127.0.0.3
|
||||
ns01.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns02.sub.example.tld. A 10.53.0.5
|
||||
ns02.sub.example.tld. A 10.53.0.6
|
||||
ns02.sub.example.tld. A 10.53.0.7
|
||||
ns02.sub.example.tld. A 10.53.0.8
|
||||
ns02.sub.example.tld. A 10.53.0.9
|
||||
ns02.sub.example.tld. A 10.53.0.10
|
||||
ns02.sub.example.tld. A 10.53.1.1
|
||||
ns02.sub.example.tld. A 10.53.1.2
|
||||
ns02.sub.example.tld. A 10.53.2.1
|
||||
ns02.sub.example.tld. A 10.53.0.3
|
||||
ns02.sub.example.tld. A 127.0.0.1
|
||||
ns02.sub.example.tld. A 127.0.0.2
|
||||
ns02.sub.example.tld. A 127.0.0.3
|
||||
ns02.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns03.sub.example.tld. A 10.53.0.5
|
||||
ns03.sub.example.tld. A 10.53.0.6
|
||||
ns03.sub.example.tld. A 10.53.0.7
|
||||
ns03.sub.example.tld. A 10.53.0.8
|
||||
ns03.sub.example.tld. A 10.53.0.9
|
||||
ns03.sub.example.tld. A 10.53.0.10
|
||||
ns03.sub.example.tld. A 10.53.1.1
|
||||
ns03.sub.example.tld. A 10.53.1.2
|
||||
ns03.sub.example.tld. A 10.53.2.1
|
||||
ns03.sub.example.tld. A 10.53.0.3
|
||||
ns03.sub.example.tld. A 127.0.0.1
|
||||
ns03.sub.example.tld. A 127.0.0.2
|
||||
ns03.sub.example.tld. A 127.0.0.3
|
||||
ns03.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns04.sub.example.tld. A 10.53.0.5
|
||||
ns04.sub.example.tld. A 10.53.0.6
|
||||
ns04.sub.example.tld. A 10.53.0.7
|
||||
ns04.sub.example.tld. A 10.53.0.8
|
||||
ns04.sub.example.tld. A 10.53.0.9
|
||||
ns04.sub.example.tld. A 10.53.0.10
|
||||
ns04.sub.example.tld. A 10.53.1.1
|
||||
ns04.sub.example.tld. A 10.53.1.2
|
||||
ns04.sub.example.tld. A 10.53.2.1
|
||||
ns04.sub.example.tld. A 10.53.0.3
|
||||
ns04.sub.example.tld. A 127.0.0.1
|
||||
ns04.sub.example.tld. A 127.0.0.2
|
||||
ns04.sub.example.tld. A 127.0.0.3
|
||||
ns04.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns05.sub.example.tld. A 10.53.0.5
|
||||
ns05.sub.example.tld. A 10.53.0.6
|
||||
ns05.sub.example.tld. A 10.53.0.7
|
||||
ns05.sub.example.tld. A 10.53.0.8
|
||||
ns05.sub.example.tld. A 10.53.0.9
|
||||
ns05.sub.example.tld. A 10.53.0.10
|
||||
ns05.sub.example.tld. A 10.53.1.1
|
||||
ns05.sub.example.tld. A 10.53.1.2
|
||||
ns05.sub.example.tld. A 10.53.2.1
|
||||
ns05.sub.example.tld. A 10.53.0.3
|
||||
ns05.sub.example.tld. A 127.0.0.1
|
||||
ns05.sub.example.tld. A 127.0.0.2
|
||||
ns05.sub.example.tld. A 127.0.0.3
|
||||
ns05.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns06.sub.example.tld. A 10.53.0.5
|
||||
ns06.sub.example.tld. A 10.53.0.6
|
||||
ns06.sub.example.tld. A 10.53.0.7
|
||||
ns06.sub.example.tld. A 10.53.0.8
|
||||
ns06.sub.example.tld. A 10.53.0.9
|
||||
ns06.sub.example.tld. A 10.53.0.10
|
||||
ns06.sub.example.tld. A 10.53.1.1
|
||||
ns06.sub.example.tld. A 10.53.1.2
|
||||
ns06.sub.example.tld. A 10.53.2.1
|
||||
ns06.sub.example.tld. A 10.53.0.3
|
||||
ns06.sub.example.tld. A 127.0.0.1
|
||||
ns06.sub.example.tld. A 127.0.0.2
|
||||
ns06.sub.example.tld. A 127.0.0.3
|
||||
ns06.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns07.sub.example.tld. A 10.53.0.5
|
||||
ns07.sub.example.tld. A 10.53.0.6
|
||||
ns07.sub.example.tld. A 10.53.0.7
|
||||
ns07.sub.example.tld. A 10.53.0.8
|
||||
ns07.sub.example.tld. A 10.53.0.9
|
||||
ns07.sub.example.tld. A 10.53.0.10
|
||||
ns07.sub.example.tld. A 10.53.1.1
|
||||
ns07.sub.example.tld. A 10.53.1.2
|
||||
ns07.sub.example.tld. A 10.53.2.1
|
||||
ns07.sub.example.tld. A 10.53.0.3
|
||||
ns07.sub.example.tld. A 127.0.0.1
|
||||
ns07.sub.example.tld. A 127.0.0.2
|
||||
ns07.sub.example.tld. A 127.0.0.3
|
||||
ns07.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns08.sub.example.tld. A 10.53.0.5
|
||||
ns08.sub.example.tld. A 10.53.0.6
|
||||
ns08.sub.example.tld. A 10.53.0.7
|
||||
ns08.sub.example.tld. A 10.53.0.8
|
||||
ns08.sub.example.tld. A 10.53.0.9
|
||||
ns08.sub.example.tld. A 10.53.0.10
|
||||
ns08.sub.example.tld. A 10.53.1.1
|
||||
ns08.sub.example.tld. A 10.53.1.2
|
||||
ns08.sub.example.tld. A 10.53.2.1
|
||||
ns08.sub.example.tld. A 10.53.0.3
|
||||
ns08.sub.example.tld. A 127.0.0.1
|
||||
ns08.sub.example.tld. A 127.0.0.2
|
||||
ns08.sub.example.tld. A 127.0.0.3
|
||||
ns08.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns09.sub.example.tld. A 10.53.0.5
|
||||
ns09.sub.example.tld. A 10.53.0.6
|
||||
ns09.sub.example.tld. A 10.53.0.7
|
||||
ns09.sub.example.tld. A 10.53.0.8
|
||||
ns09.sub.example.tld. A 10.53.0.9
|
||||
ns09.sub.example.tld. A 10.53.0.10
|
||||
ns09.sub.example.tld. A 10.53.1.1
|
||||
ns09.sub.example.tld. A 10.53.1.2
|
||||
ns09.sub.example.tld. A 10.53.2.1
|
||||
ns09.sub.example.tld. A 10.53.0.3
|
||||
ns09.sub.example.tld. A 127.0.0.1
|
||||
ns09.sub.example.tld. A 127.0.0.2
|
||||
ns09.sub.example.tld. A 127.0.0.3
|
||||
ns09.sub.example.tld. A 127.0.0.4
|
||||
|
||||
ns10.sub.example.tld. A 10.53.0.5
|
||||
ns10.sub.example.tld. A 10.53.0.6
|
||||
ns10.sub.example.tld. A 10.53.0.7
|
||||
ns10.sub.example.tld. A 10.53.0.8
|
||||
ns10.sub.example.tld. A 10.53.0.9
|
||||
ns10.sub.example.tld. A 10.53.0.10
|
||||
ns10.sub.example.tld. A 10.53.1.1
|
||||
ns10.sub.example.tld. A 10.53.1.2
|
||||
ns10.sub.example.tld. A 10.53.2.1
|
||||
ns10.sub.example.tld. A 10.53.0.3
|
||||
ns10.sub.example.tld. A 127.0.0.1
|
||||
ns10.sub.example.tld. A 127.0.0.2
|
||||
ns10.sub.example.tld. A 127.0.0.3
|
||||
ns10.sub.example.tld. A 127.0.0.4
|
||||
33
bin/tests/system/selfpointedglue/ns3/example2.tld.db
Normal file
33
bin/tests/system/selfpointedglue/ns3/example2.tld.db
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
; 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
|
||||
example2.tld. IN SOA owner.dnshoster.tld. ns.dnshoster.tld. (
|
||||
2010 ; serial
|
||||
600 ; refresh
|
||||
600 ; retry
|
||||
1200 ; expire
|
||||
600 ; minimum
|
||||
)
|
||||
|
||||
example2.tld. NS ns.example2.tld.
|
||||
ns.example2.tld. A 10.53.0.3
|
||||
|
||||
sub.example2.tld. NS ns01.sub.example2.tld.
|
||||
sub.example2.tld. NS ns02.sub.example2.tld.
|
||||
sub.example2.tld. NS ns03.sub.example2.tld.
|
||||
|
||||
ns01.sub.example2.tld. A 10.53.1.1
|
||||
ns01.sub.example2.tld. A 10.53.0.5
|
||||
ns02.sub.example2.tld. A 10.53.1.2
|
||||
ns02.sub.example2.tld. A 10.53.0.6
|
||||
ns03.sub.example2.tld. A 10.53.2.1
|
||||
ns03.sub.example2.tld. A 10.53.0.7
|
||||
63
bin/tests/system/selfpointedglue/ns3/example3.tld.db
Normal file
63
bin/tests/system/selfpointedglue/ns3/example3.tld.db
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
; 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
|
||||
example3.tld. IN SOA owner.dnshoster.tld. ns.dnshoster.tld. (
|
||||
2010 ; serial
|
||||
600 ; refresh
|
||||
600 ; retry
|
||||
1200 ; expire
|
||||
600 ; minimum
|
||||
)
|
||||
|
||||
example3.tld. NS ns.example3.tld.
|
||||
ns.example3.tld. A 10.53.0.3
|
||||
|
||||
sub.example3.tld. NS ns01.sub.example3.tld.
|
||||
sub.example3.tld. NS ns02.sub.example3.tld.
|
||||
sub.example3.tld. NS ns03.sub.example3.tld.
|
||||
sub.example3.tld. NS ns04.sub.example3.tld.
|
||||
sub.example3.tld. NS ns05.sub.example3.tld.
|
||||
sub.example3.tld. NS ns06.sub.example3.tld.
|
||||
sub.example3.tld. NS ns07.sub.example3.tld.
|
||||
sub.example3.tld. NS ns08.sub.example3.tld.
|
||||
sub.example3.tld. NS ns09.sub.example3.tld.
|
||||
sub.example3.tld. NS ns10.sub.example3.tld.
|
||||
|
||||
ns01.sub.example3.tld. A 10.53.0.5
|
||||
ns01.sub.example3.tld. A 10.53.0.6
|
||||
|
||||
ns02.sub.example3.tld. A 10.53.0.5
|
||||
ns02.sub.example3.tld. A 10.53.0.6
|
||||
|
||||
ns03.sub.example3.tld. A 10.53.0.5
|
||||
ns03.sub.example3.tld. A 10.53.0.6
|
||||
|
||||
ns04.sub.example3.tld. A 10.53.0.5
|
||||
ns04.sub.example3.tld. A 10.53.0.6
|
||||
|
||||
ns05.sub.example3.tld. A 10.53.0.5
|
||||
ns05.sub.example3.tld. A 10.53.0.6
|
||||
|
||||
ns06.sub.example3.tld. A 10.53.0.5
|
||||
ns06.sub.example3.tld. A 10.53.0.6
|
||||
|
||||
ns07.sub.example3.tld. A 10.53.0.5
|
||||
ns07.sub.example3.tld. A 10.53.0.6
|
||||
|
||||
ns08.sub.example3.tld. A 10.53.0.5
|
||||
ns08.sub.example3.tld. A 10.53.0.6
|
||||
|
||||
ns09.sub.example3.tld. A 10.53.0.5
|
||||
ns09.sub.example3.tld. A 10.53.0.6
|
||||
|
||||
ns10.sub.example3.tld. A 10.53.0.5
|
||||
ns10.sub.example3.tld. A 10.53.0.6
|
||||
49
bin/tests/system/selfpointedglue/ns3/named.conf.j2
Normal file
49
bin/tests/system/selfpointedglue/ns3/named.conf.j2
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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;
|
||||
10.53.0.5;
|
||||
10.53.0.6;
|
||||
10.53.0.7;
|
||||
10.53.0.8;
|
||||
10.53.0.9;
|
||||
10.53.0.10;
|
||||
10.53.1.1;
|
||||
10.53.1.2;
|
||||
10.53.2.1;
|
||||
};
|
||||
recursion no;
|
||||
dnssec-validation no;
|
||||
};
|
||||
|
||||
zone "example.tld." {
|
||||
type primary;
|
||||
file "example.tld.db";
|
||||
};
|
||||
|
||||
zone "example2.tld." {
|
||||
type primary;
|
||||
file "example2.tld.db";
|
||||
};
|
||||
|
||||
zone "example3.tld." {
|
||||
type primary;
|
||||
file "example3.tld.db";
|
||||
};
|
||||
1
bin/tests/system/selfpointedglue/ns4/named.args.j2
Normal file
1
bin/tests/system/selfpointedglue/ns4/named.args.j2
Normal file
|
|
@ -0,0 +1 @@
|
|||
-D selfpointedglue-ns4 -m record -c named.conf -d 99 -g -T maxcachesize=2097152 -4
|
||||
59
bin/tests/system/selfpointedglue/ns4/named.conf.j2
Normal file
59
bin/tests/system/selfpointedglue/ns4/named.conf.j2
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
{% set maxdelegationservers = maxdelegationservers | default(None) %}
|
||||
|
||||
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";
|
||||
{% if maxdelegationservers %}
|
||||
@maxdelegationservers@
|
||||
{% endif %}
|
||||
};
|
||||
|
||||
/*
|
||||
* Forcing TCP ensures that ADDITIONAL won't be truncated (responses won't have
|
||||
* the TC flag, hence the resolver won't retry using TCP by itself, see
|
||||
* https://datatracker.ietf.org/doc/html/rfc2181#section-9)
|
||||
*/
|
||||
server 10.53.0.3 { tcp-only true; };
|
||||
server 10.53.0.5 { tcp-only true; };
|
||||
server 10.53.0.6 { tcp-only true; };
|
||||
server 10.53.0.7 { tcp-only true; };
|
||||
server 10.53.0.8 { tcp-only true; };
|
||||
server 10.53.0.9 { tcp-only true; };
|
||||
server 10.53.0.10 { tcp-only true; };
|
||||
server 10.53.1.1 { tcp-only true; };
|
||||
server 10.53.1.2 { tcp-only true; };
|
||||
server 10.53.2.1 { tcp-only true; };
|
||||
|
||||
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/selfpointedglue/ns4/root.hint
Normal file
14
bin/tests/system/selfpointedglue/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
|
||||
157
bin/tests/system/selfpointedglue/tests_selfpointedglue.py
Normal file
157
bin/tests/system/selfpointedglue/tests_selfpointedglue.py
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
# 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 list(map(line_to_ips_and_queries, lines))
|
||||
|
||||
|
||||
# Because DNSTAP doesn't have ordering guarantee, the order doesn't matter here.
|
||||
def expect_ip_and_query(expected_ips_and_queries, ips_and_queries):
|
||||
found_count = 0
|
||||
for expected_ip, expected_query in expected_ips_and_queries:
|
||||
found = False
|
||||
for ip, query in ips_and_queries:
|
||||
if ip == expected_ip and query == expected_query:
|
||||
found = True
|
||||
found_count += 1
|
||||
break
|
||||
assert found
|
||||
assert found_count == len(expected_ips_and_queries)
|
||||
|
||||
|
||||
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 test_selfpointedglue1(ns4):
|
||||
msg = isctest.query.create("a.sub.example.tld.", "A")
|
||||
res = isctest.query.tcp(msg, ns4.ip)
|
||||
isctest.check.servfail(res)
|
||||
|
||||
# 4 queries to get to the delegation.
|
||||
# 13 queries to delegation NS servers.
|
||||
ips_and_queries = extract_dnstap(ns4, 17)
|
||||
|
||||
# Thanks to the de-duplication, only the first 13 NS IPs are
|
||||
# queried (once sub.example.tld. NS is found) instead of 13*10
|
||||
# (13 per NS, with 10 NS).
|
||||
expect_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"),
|
||||
("10.53.0.3", "a.sub.example.tld/IN/A"),
|
||||
("10.53.0.5", "a.sub.example.tld/IN/A"),
|
||||
("10.53.0.6", "a.sub.example.tld/IN/A"),
|
||||
("10.53.0.7", "a.sub.example.tld/IN/A"),
|
||||
("10.53.0.8", "a.sub.example.tld/IN/A"),
|
||||
("10.53.0.9", "a.sub.example.tld/IN/A"),
|
||||
("10.53.0.10", "a.sub.example.tld/IN/A"),
|
||||
("10.53.1.1", "a.sub.example.tld/IN/A"),
|
||||
("10.53.1.2", "a.sub.example.tld/IN/A"),
|
||||
("10.53.2.1", "a.sub.example.tld/IN/A"),
|
||||
("10.53.0.3", "a.sub.example.tld/IN/A"),
|
||||
("127.0.0.1", "a.sub.example.tld/IN/A"),
|
||||
("127.0.0.2", "a.sub.example.tld/IN/A"),
|
||||
],
|
||||
ips_and_queries,
|
||||
)
|
||||
|
||||
|
||||
# This test is useful because the one above hits the max-delegation-servers
|
||||
# from the first NS name lookup. This one doesn't, because there is only 2
|
||||
# addresses per NS, but the deduplication avoid the explosion of duplicate
|
||||
# addresses.
|
||||
def test_selfpointedglue2(ns4):
|
||||
with ns4.watch_log_from_here() as watcher:
|
||||
ns4.rndc("flush")
|
||||
ns4.rndc("reload")
|
||||
watcher.wait_for_line("running")
|
||||
msg = isctest.query.create("a.sub.example3.tld.", "A")
|
||||
res = isctest.query.tcp(msg, ns4.ip)
|
||||
isctest.check.servfail(res)
|
||||
|
||||
# 4 queries to get to the delegation.
|
||||
# 2 queries to delegation NS servers.
|
||||
ips_and_queries = extract_dnstap(ns4, 6)
|
||||
|
||||
# Thanks to the de-duplication, only the first 2 NS IPs are
|
||||
# queried (once sub.example.tld. NS is found) instead of 2*10
|
||||
# (2 per NS with 10 NS).
|
||||
expect_ip_and_query(
|
||||
[
|
||||
("10.53.0.1", "./IN/NS"),
|
||||
("10.53.0.1", "tld/IN/NS"),
|
||||
("10.53.0.2", "example3.tld/IN/NS"),
|
||||
("10.53.0.3", "sub.example3.tld/IN/NS"),
|
||||
("10.53.0.5", "a.sub.example3.tld/IN/A"),
|
||||
("10.53.0.6", "a.sub.example3.tld/IN/A"),
|
||||
],
|
||||
ips_and_queries,
|
||||
)
|
||||
|
||||
|
||||
def test_selfpointedglue_nslimit(ns4, templates):
|
||||
templates.render(
|
||||
"ns4/named.conf", {"maxdelegationservers": "max-delegation-servers 2;"}
|
||||
)
|
||||
with ns4.watch_log_from_here() as watcher:
|
||||
ns4.rndc("flush")
|
||||
ns4.rndc("reload")
|
||||
watcher.wait_for_line("running")
|
||||
|
||||
msg = isctest.query.create("a.sub.example2.tld.", "A")
|
||||
res = isctest.query.tcp(msg, ns4.ip)
|
||||
isctest.check.servfail(res)
|
||||
|
||||
ips_and_queries = extract_dnstap(ns4, 6)
|
||||
|
||||
# Checking the beginning of the resolution
|
||||
expect_ip_and_query(
|
||||
[
|
||||
("10.53.0.1", "./IN/NS"),
|
||||
("10.53.0.1", "tld/IN/NS"),
|
||||
("10.53.0.2", "example2.tld/IN/NS"),
|
||||
("10.53.0.3", "sub.example2.tld/IN/NS"),
|
||||
],
|
||||
ips_and_queries,
|
||||
)
|
||||
|
||||
expect_query("a.sub.example2.tld/IN/A", 2, ips_and_queries)
|
||||
18
bin/tests/system/srtt/README
Normal file
18
bin/tests/system/srtt/README
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
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.
|
||||
|
||||
ns1 is root
|
||||
|
||||
ans{2-5} simulates four NS servers making authority on the same domain
|
||||
`example.`. ans2 is the quickest to answer, followed by ans3, then ans4, with
|
||||
ans5 being the slowest.
|
||||
|
||||
ns6 is a resolver
|
||||
36
bin/tests/system/srtt/ans2/ans.py
Normal file
36
bin/tests/system/srtt/ans2/ans.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"""
|
||||
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 dns.rcode
|
||||
|
||||
from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
|
||||
|
||||
from ..srtt_ans import DelayedQnameRangeHandler
|
||||
|
||||
|
||||
class Foo1ToFoo99Handler(DelayedQnameRangeHandler):
|
||||
max_qname = 99
|
||||
delay = 0.0
|
||||
|
||||
|
||||
def main() -> None:
|
||||
server = AsyncDnsServer(default_aa=True, default_rcode=dns.rcode.NOERROR)
|
||||
server.install_response_handlers(
|
||||
Foo1ToFoo99Handler(),
|
||||
IgnoreAllQueries(),
|
||||
)
|
||||
server.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
36
bin/tests/system/srtt/ans3/ans.py
Normal file
36
bin/tests/system/srtt/ans3/ans.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"""
|
||||
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 dns.rcode
|
||||
|
||||
from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
|
||||
|
||||
from ..srtt_ans import DelayedQnameRangeHandler
|
||||
|
||||
|
||||
class Foo1ToFoo199Handler(DelayedQnameRangeHandler):
|
||||
max_qname = 199
|
||||
delay = 0.03
|
||||
|
||||
|
||||
def main() -> None:
|
||||
server = AsyncDnsServer(default_aa=True, default_rcode=dns.rcode.NOERROR)
|
||||
server.install_response_handlers(
|
||||
Foo1ToFoo199Handler(),
|
||||
IgnoreAllQueries(),
|
||||
)
|
||||
server.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
36
bin/tests/system/srtt/ans4/ans.py
Normal file
36
bin/tests/system/srtt/ans4/ans.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"""
|
||||
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 dns.rcode
|
||||
|
||||
from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
|
||||
|
||||
from ..srtt_ans import DelayedQnameRangeHandler
|
||||
|
||||
|
||||
class Foo1ToFoo299Handler(DelayedQnameRangeHandler):
|
||||
max_qname = 299
|
||||
delay = 0.08
|
||||
|
||||
|
||||
def main() -> None:
|
||||
server = AsyncDnsServer(default_aa=True, default_rcode=dns.rcode.NOERROR)
|
||||
server.install_response_handlers(
|
||||
Foo1ToFoo299Handler(),
|
||||
IgnoreAllQueries(),
|
||||
)
|
||||
server.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
36
bin/tests/system/srtt/ans5/ans.py
Normal file
36
bin/tests/system/srtt/ans5/ans.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"""
|
||||
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 dns.rcode
|
||||
|
||||
from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
|
||||
|
||||
from ..srtt_ans import DelayedQnameRangeHandler
|
||||
|
||||
|
||||
class Foo1ToFoo399Handler(DelayedQnameRangeHandler):
|
||||
max_qname = 399
|
||||
delay = 0.15
|
||||
|
||||
|
||||
def main() -> None:
|
||||
server = AsyncDnsServer(default_aa=True, default_rcode=dns.rcode.NOERROR)
|
||||
server.install_response_handlers(
|
||||
Foo1ToFoo399Handler(),
|
||||
IgnoreAllQueries(),
|
||||
)
|
||||
server.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
29
bin/tests/system/srtt/ns1/named.conf.j2
Normal file
29
bin/tests/system/srtt/ns1/named.conf.j2
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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; };
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
notify yes;
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type primary;
|
||||
file "root.db";
|
||||
};
|
||||
36
bin/tests/system/srtt/ns1/root.db
Normal file
36
bin/tests/system/srtt/ns1/root.db
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
; 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 owner.root-servers.nil. a.root-servers.nil. (
|
||||
2000042100 ; serial
|
||||
600 ; refresh
|
||||
600 ; retry
|
||||
1200 ; expire
|
||||
600 ; minimum
|
||||
)
|
||||
. NS a.root-servers.nil.
|
||||
a.root-servers.nil. A 10.53.0.1
|
||||
|
||||
; The idea is that the resolver would do 2 ADB lookups, so there would be 2
|
||||
; find list, both with 2 IPs in it. ns1 (which is actually ans2 and ans5) would
|
||||
; have both the slowest and fastest addresses. ns2 (which is actually ans3 and
|
||||
; ans4) would have two addresses in the middle.
|
||||
|
||||
example. NS ns1.example.
|
||||
example. NS ns1.example.
|
||||
example. NS ns2.example.
|
||||
example. NS ns2.example.
|
||||
|
||||
ns1.example. A 10.53.0.2 ; delay is 0
|
||||
ns1.example. A 10.53.0.5 ; delay is 0.15
|
||||
ns2.example. A 10.53.0.4 ; delay is 0.08
|
||||
ns2.example. A 10.53.0.3 ; delay is 0.03
|
||||
1
bin/tests/system/srtt/ns6/named.args
Normal file
1
bin/tests/system/srtt/ns6/named.args
Normal file
|
|
@ -0,0 +1 @@
|
|||
-D srtt-ns6 -m record -c named.conf -d 99 -g -T maxcachesize=2097152 -4
|
||||
41
bin/tests/system/srtt/ns6/named.conf.j2
Normal file
41
bin/tests/system/srtt/ns6/named.conf.j2
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.6;
|
||||
notify-source 10.53.0.6;
|
||||
transfer-source 10.53.0.6;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.6; };
|
||||
listen-on-v6 { none; };
|
||||
recursion yes;
|
||||
dnssec-validation no;
|
||||
dnstap { resolver query; };
|
||||
dnstap-output file "dnstap.out";
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type hint;
|
||||
file "../../_common/root.hint";
|
||||
};
|
||||
59
bin/tests/system/srtt/srtt_ans.py
Normal file
59
bin/tests/system/srtt/srtt_ans.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
"""
|
||||
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.
|
||||
"""
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
|
||||
import abc
|
||||
|
||||
import dns.rdataclass
|
||||
import dns.rdatatype
|
||||
import dns.rrset
|
||||
|
||||
from isctest.asyncserver import DnsResponseSend, QnameQtypeHandler, QueryContext
|
||||
|
||||
|
||||
class DelayedQnameRangeHandler(QnameQtypeHandler):
|
||||
"""
|
||||
Respond to queries for QNAMEs "foo1.example." through "foo<N>.example."
|
||||
with QTYPE=A, where <N> must be defined by the subclass. Every response is
|
||||
delayed by a fixed amount of time, which must also be defined (in seconds)
|
||||
by the subclass.
|
||||
"""
|
||||
|
||||
@property
|
||||
def qnames(self) -> list[str]:
|
||||
return [f"foo{x}.example." for x in range(1, self.max_qname + 1)]
|
||||
|
||||
qtypes = [dns.rdatatype.A]
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def max_qname(self) -> int:
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
@abc.abstractmethod
|
||||
def delay(self) -> float:
|
||||
raise NotImplementedError
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.__class__.__name__}(foo[1-{self.max_qname}].example/A)"
|
||||
|
||||
async def get_responses(
|
||||
self, qctx: QueryContext
|
||||
) -> AsyncGenerator[DnsResponseSend, None]:
|
||||
a_rrset = dns.rrset.from_text(
|
||||
qctx.qname, 300, dns.rdataclass.IN, dns.rdatatype.A, "10.53.9.9"
|
||||
)
|
||||
qctx.response.answer.append(a_rrset)
|
||||
yield DnsResponseSend(qctx.response, delay=self.delay)
|
||||
89
bin/tests/system/srtt/tests_srtt.py
Normal file
89
bin/tests/system/srtt/tests_srtt.py
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# 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_dst_ips(line):
|
||||
# dnstap-read output line example
|
||||
# 05-Feb-2026 11:00:57.853 RQ 10.53.0.6:38507 -> 10.53.0.3:22047 TCP 56b fooXXX.example./IN/NS
|
||||
_, _, _, _, _, dst, _, _, _ = line.split(" ", 9)
|
||||
ip, _ = dst.split(":", 1)
|
||||
return ip
|
||||
|
||||
|
||||
def extract_dnstap(ns):
|
||||
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()
|
||||
return map(line_to_dst_ips, lines)
|
||||
|
||||
|
||||
def assert_used_auth(ns, authip):
|
||||
ips = extract_dnstap(ns)
|
||||
queries = 0
|
||||
matches = 0
|
||||
for ip in ips:
|
||||
queries += 1
|
||||
if ip == authip:
|
||||
matches += 1
|
||||
assert matches > 85
|
||||
assert queries <= 115
|
||||
|
||||
|
||||
def test_srtt(ns6):
|
||||
for i in range(1, 100):
|
||||
msg = isctest.query.create(f"foo{i}.example.", "A")
|
||||
res = isctest.query.udp(msg, ns6.ip)
|
||||
isctest.check.noerror(res)
|
||||
assert len(res.answer[0]) == 1
|
||||
res.answer[0].ttl = 300
|
||||
assert str(res.answer[0]) == f"foo{i}.example. 300 IN A 10.53.9.9"
|
||||
|
||||
assert_used_auth(ns6, "10.53.0.2")
|
||||
|
||||
for i in range(100, 200):
|
||||
msg = isctest.query.create(f"foo{i}.example.", "A")
|
||||
res = isctest.query.udp(msg, ns6.ip)
|
||||
isctest.check.noerror(res)
|
||||
assert len(res.answer[0]) == 1
|
||||
res.answer[0].ttl = 300
|
||||
assert str(res.answer[0]) == f"foo{i}.example. 300 IN A 10.53.9.9"
|
||||
|
||||
assert_used_auth(ns6, "10.53.0.3")
|
||||
|
||||
for i in range(200, 300):
|
||||
msg = isctest.query.create(f"foo{i}.example.", "A")
|
||||
res = isctest.query.udp(msg, ns6.ip)
|
||||
isctest.check.noerror(res)
|
||||
assert len(res.answer[0]) == 1
|
||||
res.answer[0].ttl = 300
|
||||
assert str(res.answer[0]) == f"foo{i}.example. 300 IN A 10.53.9.9"
|
||||
|
||||
assert_used_auth(ns6, "10.53.0.4")
|
||||
|
||||
for i in range(300, 400):
|
||||
msg = isctest.query.create(f"foo{i}.example.", "A")
|
||||
res = isctest.query.udp(msg, ns6.ip)
|
||||
isctest.check.noerror(res)
|
||||
assert len(res.answer[0]) == 1
|
||||
res.answer[0].ttl = 300
|
||||
assert str(res.answer[0]) == f"foo{i}.example. 300 IN A 10.53.9.9"
|
||||
assert_used_auth(ns6, "10.53.0.5")
|
||||
|
|
@ -4187,14 +4187,11 @@ Tuning
|
|||
|
||||
.. namedconf:statement:: max-delegation-servers
|
||||
:tags: server
|
||||
:short: Configure the maximum number of nameserver names considered for a delegation
|
||||
:short: Configure the maximum number of nameservers considered for a delegation
|
||||
|
||||
When looking up remote nameservers for a delegation, the list of nameserver
|
||||
names is sorted according to Canonical RR Ordering within an RRset (see
|
||||
:rfc:`4034` Section 6.3), and the number of names for which :iscman:`named`
|
||||
looks up IP addresses is capped at :any:`max-delegation-servers`.
|
||||
|
||||
This capped list of nameserver names is then randomly shuffled every time
|
||||
:rfc:`4034` Section 6.3). This list is then randomly shuffled every time
|
||||
:iscman:`named` needs additional remote addresses for those nameservers.
|
||||
This randomized selection works around situations where the first few
|
||||
nameserver names in the zone are unresponsive.
|
||||
|
|
@ -4207,6 +4204,12 @@ Tuning
|
|||
outgoing DNS query is initiated only if the DNS resolver does not already have
|
||||
existing IP addresses for any of the nameserver names in the cache.
|
||||
|
||||
The known NS addresses for an NS name (cached from a previous resolution, or
|
||||
the NS name has glues, or it is defined from a local zone or hints) are
|
||||
counted as delegation servers. Thus, the maximum queries the resolver does
|
||||
to resolve a name at a delegation point is capped at
|
||||
:any:`max-delegation-servers`.
|
||||
|
||||
The default and recommended value is ``13``. This limit prevents excessive
|
||||
resource use while processing large or misconfigured delegations. The default
|
||||
value should only be increased in controlled environments where a remote
|
||||
|
|
|
|||
|
|
@ -1370,8 +1370,10 @@ log_quota(dns_adbentry_t *entry, const char *fmt, ...) {
|
|||
}
|
||||
|
||||
static void
|
||||
copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_adbname_t *name) {
|
||||
copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_adbname_t *name,
|
||||
size_t maxfindlen, size_t *findlen) {
|
||||
dns_adbentry_t *entry = NULL;
|
||||
size_t count = 0;
|
||||
|
||||
if ((find->options & DNS_ADBFIND_INET) != 0) {
|
||||
ISC_LIST_FOREACH(name->v4, namehook, name_link) {
|
||||
|
|
@ -1391,6 +1393,12 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_adbname_t *name) {
|
|||
* Found a valid entry. Add it to the find's list.
|
||||
*/
|
||||
ISC_LIST_APPEND(find->list, addrinfo, publink);
|
||||
|
||||
count++;
|
||||
if (maxfindlen - count == 0) {
|
||||
SET_IF_NOT_NULL(findlen, count);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1412,8 +1420,16 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_adbname_t *name) {
|
|||
* Found a valid entry. Add it to the find's list.
|
||||
*/
|
||||
ISC_LIST_APPEND(find->list, addrinfo, publink);
|
||||
|
||||
count++;
|
||||
if (maxfindlen - count == 0) {
|
||||
SET_IF_NOT_NULL(findlen, count);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SET_IF_NOT_NULL(findlen, count);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1735,7 +1751,7 @@ out:
|
|||
void
|
||||
dns_adb_createaddrinfosfind(dns_adb_t *adb, isc_netaddrlist_t *addrs,
|
||||
in_port_t port, unsigned int options,
|
||||
isc_stdtime_t now, size_t maxaddrs,
|
||||
isc_stdtime_t now, size_t maxfindlen,
|
||||
dns_adbfind_t **findp, size_t *findlen) {
|
||||
dns_adbfind_t *find = NULL;
|
||||
isc_sockaddr_t sockaddr = {};
|
||||
|
|
@ -1743,7 +1759,7 @@ dns_adb_createaddrinfosfind(dns_adb_t *adb, isc_netaddrlist_t *addrs,
|
|||
REQUIRE(DNS_ADB_VALID(adb));
|
||||
REQUIRE(addrs != NULL);
|
||||
REQUIRE(findp != NULL && *findp == NULL);
|
||||
REQUIRE(maxaddrs > 0);
|
||||
REQUIRE(maxfindlen > 0);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
|
|
@ -1794,7 +1810,7 @@ dns_adb_createaddrinfosfind(dns_adb_t *adb, isc_netaddrlist_t *addrs,
|
|||
ISC_LIST_APPEND(find->list, addrinfo, publink);
|
||||
(*findlen)++;
|
||||
|
||||
if (maxaddrs - *findlen == 0) {
|
||||
if (maxfindlen - *findlen == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1825,7 +1841,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
|
|||
const dns_name_t *name, unsigned int options,
|
||||
isc_stdtime_t now, in_port_t port, unsigned int depth,
|
||||
isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t *parent,
|
||||
dns_adbfind_t **findp) {
|
||||
size_t maxfindlen, dns_adbfind_t **findp, size_t *findlen) {
|
||||
isc_result_t result = ISC_R_UNEXPECTED;
|
||||
dns_adbfind_t *find = NULL;
|
||||
dns_adbname_t *adbname = NULL;
|
||||
|
|
@ -1844,6 +1860,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
|
|||
}
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(findp != NULL && *findp == NULL);
|
||||
REQUIRE(maxfindlen > 0);
|
||||
|
||||
REQUIRE((options & DNS_ADBFIND_ADDRESSMASK) != 0);
|
||||
|
||||
|
|
@ -2056,7 +2073,7 @@ fetch:
|
|||
* Run through the name and copy out the bits we are
|
||||
* interested in.
|
||||
*/
|
||||
copy_namehook_lists(adb, find, adbname);
|
||||
copy_namehook_lists(adb, find, adbname, maxfindlen, findlen);
|
||||
|
||||
post_copy:
|
||||
if (NAME_FETCH_A(adbname)) {
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
|
|||
const dns_name_t *name, unsigned int options,
|
||||
isc_stdtime_t now, in_port_t port, unsigned int depth,
|
||||
isc_counter_t *qc, isc_counter_t *gqc, fetchctx_t *parent,
|
||||
dns_adbfind_t **find);
|
||||
size_t maxfindlen, dns_adbfind_t **find, size_t *findlen);
|
||||
/*%<
|
||||
* Main interface for clients. The adb will look up the name given in
|
||||
* "name" and will build up a list of found addresses, and perhaps start
|
||||
|
|
@ -333,6 +333,8 @@ dns_adb_createfind(dns_adb_t *adb, isc_loop_t *loop, isc_job_cb cb, void *cbarg,
|
|||
*
|
||||
*\li find != NULL && *find == NULL.
|
||||
*
|
||||
*\li findlen is optional, if not NULL, it will be set to the length of find.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
*\li #ISC_R_SUCCESS Addresses might have been returned, and events will be
|
||||
|
|
|
|||
|
|
@ -761,9 +761,10 @@ dns_notify_find_address(dns_notify_t *notify) {
|
|||
goto destroy;
|
||||
}
|
||||
|
||||
result = dns_adb_createfind(adb, loop, process_notify_adb_event, notify,
|
||||
¬ify->ns, options, 0, notify->port, 0,
|
||||
NULL, NULL, NULL, ¬ify->find);
|
||||
result = dns_adb_createfind(
|
||||
adb, loop, process_notify_adb_event, notify, ¬ify->ns,
|
||||
options, 0, notify->port, 0, NULL, NULL, NULL,
|
||||
view->max_delegation_servers, ¬ify->find, NULL);
|
||||
dns_adb_detach(&adb);
|
||||
|
||||
/* Something failed? */
|
||||
|
|
|
|||
|
|
@ -368,7 +368,16 @@ struct fetchctx {
|
|||
dns_message_t *qmessage;
|
||||
ISC_LIST(resquery_t) queries;
|
||||
dns_adbfindlist_t finds;
|
||||
dns_adbfind_t *find;
|
||||
/*
|
||||
* This is a state to keep track of the latest upstream server which is
|
||||
* being queried. See `nextaddress()`.
|
||||
*
|
||||
* `addrinfo` is basically a copy of `foundaddrinfo` but came from the
|
||||
* response of the query, so fields like the SRTT/timing might have been
|
||||
* altered. So it might be possible (?) to wrap those two in an union
|
||||
* for clarity (and memory saving).
|
||||
*/
|
||||
dns_adbaddrinfo_t *foundaddrinfo;
|
||||
/*
|
||||
* altfinds are names and/or addresses of dual stack servers that
|
||||
* should be used when iterative resolution to a server is not
|
||||
|
|
@ -1409,7 +1418,7 @@ fctx_cleanup(fetchctx_t *fctx) {
|
|||
dns_adb_destroyfind(&find);
|
||||
fetchctx_unref(fctx);
|
||||
}
|
||||
fctx->find = NULL;
|
||||
fctx->foundaddrinfo = NULL;
|
||||
|
||||
ISC_LIST_FOREACH(fctx->altfinds, find, publink) {
|
||||
ISC_LIST_UNLINK(fctx->altfinds, find, publink);
|
||||
|
|
@ -3251,89 +3260,6 @@ add_bad(fetchctx_t *fctx, dns_message_t *rmessage, dns_adbaddrinfo_t *addrinfo,
|
|||
classbuf, addrbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort addrinfo list by RTT.
|
||||
*/
|
||||
static void
|
||||
sort_adbfind(dns_adbfind_t *find, unsigned int bias) {
|
||||
dns_adbaddrinfo_t *best, *curr;
|
||||
dns_adbaddrinfolist_t sorted;
|
||||
|
||||
/* Lame N^2 bubble sort. */
|
||||
ISC_LIST_INIT(sorted);
|
||||
while (!ISC_LIST_EMPTY(find->list)) {
|
||||
unsigned int best_srtt;
|
||||
best = ISC_LIST_HEAD(find->list);
|
||||
best_srtt = best->srtt;
|
||||
if (isc_sockaddr_pf(&best->sockaddr) != AF_INET6) {
|
||||
best_srtt += bias;
|
||||
}
|
||||
curr = ISC_LIST_NEXT(best, publink);
|
||||
while (curr != NULL) {
|
||||
unsigned int curr_srtt = curr->srtt;
|
||||
if (isc_sockaddr_pf(&curr->sockaddr) != AF_INET6) {
|
||||
curr_srtt += bias;
|
||||
}
|
||||
if (curr_srtt < best_srtt) {
|
||||
best = curr;
|
||||
best_srtt = curr_srtt;
|
||||
}
|
||||
curr = ISC_LIST_NEXT(curr, publink);
|
||||
}
|
||||
ISC_LIST_UNLINK(find->list, best, publink);
|
||||
ISC_LIST_APPEND(sorted, best, publink);
|
||||
}
|
||||
find->list = sorted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort a list of finds by server RTT.
|
||||
*/
|
||||
static void
|
||||
sort_finds(dns_adbfindlist_t *findlist, unsigned int bias) {
|
||||
dns_adbfind_t *best = NULL;
|
||||
dns_adbfindlist_t sorted;
|
||||
dns_adbaddrinfo_t *addrinfo, *bestaddrinfo;
|
||||
|
||||
/* Sort each find's addrinfo list by SRTT. */
|
||||
ISC_LIST_FOREACH(*findlist, curr, publink) {
|
||||
sort_adbfind(curr, bias);
|
||||
}
|
||||
|
||||
/* Lame N^2 bubble sort. */
|
||||
ISC_LIST_INIT(sorted);
|
||||
while (!ISC_LIST_EMPTY(*findlist)) {
|
||||
dns_adbfind_t *curr = NULL;
|
||||
unsigned int best_srtt;
|
||||
|
||||
best = ISC_LIST_HEAD(*findlist);
|
||||
bestaddrinfo = ISC_LIST_HEAD(best->list);
|
||||
INSIST(bestaddrinfo != NULL);
|
||||
best_srtt = bestaddrinfo->srtt;
|
||||
if (isc_sockaddr_pf(&bestaddrinfo->sockaddr) != AF_INET6) {
|
||||
best_srtt += bias;
|
||||
}
|
||||
curr = ISC_LIST_NEXT(best, publink);
|
||||
while (curr != NULL) {
|
||||
unsigned int curr_srtt;
|
||||
addrinfo = ISC_LIST_HEAD(curr->list);
|
||||
INSIST(addrinfo != NULL);
|
||||
curr_srtt = addrinfo->srtt;
|
||||
if (isc_sockaddr_pf(&addrinfo->sockaddr) != AF_INET6) {
|
||||
curr_srtt += bias;
|
||||
}
|
||||
if (curr_srtt < best_srtt) {
|
||||
best = curr;
|
||||
best_srtt = curr_srtt;
|
||||
}
|
||||
curr = ISC_LIST_NEXT(curr, publink);
|
||||
}
|
||||
ISC_LIST_UNLINK(*findlist, best, publink);
|
||||
ISC_LIST_APPEND(sorted, best, publink);
|
||||
}
|
||||
*findlist = sorted;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true iff the ADB find has an already pending fetch for 'type'. This
|
||||
* is used to find out whether we're in a loop, where a fetch is waiting for a
|
||||
|
|
@ -3375,7 +3301,8 @@ already_waiting_for(dns_adbfind_t *find, dns_rdatatype_t type) {
|
|||
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 *have_address) {
|
||||
bool *overquota, bool *need_alternate, bool *have_address,
|
||||
size_t maxfindlen, size_t *findlen) {
|
||||
dns_adbfind_t *find = NULL;
|
||||
dns_resolver_t *res = fctx->res;
|
||||
bool unshared = ((fctx->options & DNS_FETCHOPT_UNSHARED) != 0);
|
||||
|
|
@ -3416,7 +3343,7 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
|
|||
result = dns_adb_createfind(fctx->adb, fctx->loop, fctx_finddone, fctx,
|
||||
name, options, now, res->view->dstport,
|
||||
fctx->depth + 1, fctx->qc, fctx->gqc, fctx,
|
||||
&find);
|
||||
maxfindlen, &find, findlen);
|
||||
|
||||
isc_log_write(DNS_LOGCATEGORY_RESOLVER, DNS_LOGMODULE_RESOLVER,
|
||||
ISC_LOG_DEBUG(3), "fctx %p(%s): createfind for %s - %s",
|
||||
|
|
@ -3458,6 +3385,7 @@ findname(fetchctx_t *fctx, const dns_name_t *name, in_port_t port,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & FCTX_ADDRINFO_DUALSTACK) != 0) {
|
||||
ISC_LIST_APPEND(fctx->altfinds, find, publink);
|
||||
} else {
|
||||
|
|
@ -3670,7 +3598,7 @@ fctx_getaddresses_addresses(fetchctx_t *fctx, isc_stdtime_t now,
|
|||
|
||||
ISC_LIST_FOREACH(fctx->delegset->delegs, deleg, link) {
|
||||
dns_adbfind_t *find = NULL;
|
||||
size_t maxaddrs = max_delegation_servers - *ns_processed;
|
||||
size_t maxfindlen = max_delegation_servers - *ns_processed;
|
||||
size_t findlen = 0;
|
||||
|
||||
if (*ns_processed >= max_delegation_servers) {
|
||||
|
|
@ -3690,7 +3618,7 @@ fctx_getaddresses_addresses(fetchctx_t *fctx, isc_stdtime_t now,
|
|||
fetchctx_ref(fctx);
|
||||
dns_adb_createaddrinfosfind(fctx->adb, &deleg->addresses,
|
||||
fctx->res->view->dstport, options,
|
||||
now, maxaddrs, &find, &findlen);
|
||||
now, maxfindlen, &find, &findlen);
|
||||
|
||||
if (find == NULL) {
|
||||
fetchctx_unref(fctx);
|
||||
|
|
@ -3778,6 +3706,12 @@ shufflens:
|
|||
unsigned int static_stub = 0;
|
||||
unsigned int no_fetch = 0;
|
||||
dns_name_t *ns = nameservers[i];
|
||||
size_t maxfindlen = max_delegation_servers - *ns_processed;
|
||||
size_t findlen = 0;
|
||||
|
||||
if (*ns_processed >= max_delegation_servers) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (fctx->delegset->staticstub &&
|
||||
dns_name_equal(ns, fctx->domain))
|
||||
|
|
@ -3794,15 +3728,15 @@ shufflens:
|
|||
}
|
||||
|
||||
findname(fctx, ns, 0, stdoptions | static_stub | no_fetch, 0,
|
||||
now, &overquota, need_alternatep, &have_address);
|
||||
now, &overquota, need_alternatep, &have_address,
|
||||
maxfindlen, &findlen);
|
||||
|
||||
if (!overquota) {
|
||||
*all_spilledp = false;
|
||||
}
|
||||
*ns_processed += findlen;
|
||||
|
||||
if (++(*ns_processed) >= max_delegation_servers) {
|
||||
break;
|
||||
}
|
||||
INSIST(*ns_processed <= max_delegation_servers);
|
||||
}
|
||||
|
||||
if (fctx->pending_running == 0 && !have_address) {
|
||||
|
|
@ -3828,7 +3762,8 @@ fctx_getaddresses_alternate(fetchctx_t *fctx, isc_stdtime_t now,
|
|||
if (!a->isaddress) {
|
||||
findname(fctx, &a->_u._n.name, a->_u._n.port,
|
||||
stdoptions, FCTX_ADDRINFO_DUALSTACK, now, NULL,
|
||||
NULL, NULL);
|
||||
NULL, NULL,
|
||||
fctx->res->view->max_delegation_servers, NULL);
|
||||
continue;
|
||||
}
|
||||
if (isc_sockaddr_pf(&a->_u.addr) != family) {
|
||||
|
|
@ -4019,8 +3954,6 @@ out:
|
|||
* We've found some addresses. We might still be
|
||||
* looking for more addresses.
|
||||
*/
|
||||
sort_finds(&fctx->finds, res->view->v6bias);
|
||||
sort_finds(&fctx->altfinds, 0);
|
||||
return ISC_R_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -4132,6 +4065,76 @@ possibly_mark(fetchctx_t *fctx, dns_adbaddrinfo_t *addr) {
|
|||
}
|
||||
}
|
||||
|
||||
static dns_adbaddrinfo_t *
|
||||
nextaddress(fetchctx_t *fctx) {
|
||||
dns_adbaddrinfo_t *prevai = fctx->foundaddrinfo, *lowestsrttai = NULL;
|
||||
unsigned int v6bias = fctx->res->view->v6bias, lowestsrtt = 0;
|
||||
|
||||
/*
|
||||
* Let's walk through the list of dns_adbaddrinfo_t to find the best
|
||||
* next server address to query. This is linear on the number of
|
||||
* dns_adbaddrinfo_t which are grouped in find list (for each ADB find).
|
||||
*/
|
||||
ISC_LIST_FOREACH(fctx->finds, find, publink) {
|
||||
ISC_LIST_FOREACH(find->list, ai, publink) {
|
||||
/*
|
||||
* This address has been marked already, skip it.
|
||||
*/
|
||||
if (!UNMARKED(ai)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* This address is the same as the previously used
|
||||
* address, it's a duplicate, mark it and skip it!
|
||||
*/
|
||||
if (prevai != NULL) {
|
||||
if (prevai->entry == ai->entry) {
|
||||
ai->flags |= FCTX_ADDRINFO_MARK;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark and skip this address if incompatible (i.e. IPv6
|
||||
* address on a v4 only server, or for ACL reason, etc.)
|
||||
*/
|
||||
possibly_mark(fctx, ai);
|
||||
if (!UNMARKED(ai)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* This address hasn't been tried yet and is a
|
||||
* good candidate. Let's keep track of it if it
|
||||
* has the lowest SRTT so far (or if there is no
|
||||
* address with lowest SRTT found yet).
|
||||
*/
|
||||
unsigned int aisrtt = ai->srtt;
|
||||
|
||||
if (isc_sockaddr_pf(&ai->sockaddr) != AF_INET6) {
|
||||
aisrtt += v6bias;
|
||||
}
|
||||
|
||||
if (lowestsrttai == NULL || aisrtt < lowestsrtt) {
|
||||
lowestsrttai = ai;
|
||||
lowestsrtt = aisrtt;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the next address to query. If this is NULL, we're done.
|
||||
*/
|
||||
if (lowestsrttai != NULL) {
|
||||
lowestsrttai->flags |= FCTX_ADDRINFO_MARK;
|
||||
}
|
||||
fctx->foundaddrinfo = lowestsrttai;
|
||||
|
||||
return lowestsrttai;
|
||||
}
|
||||
|
||||
static dns_adbaddrinfo_t *
|
||||
fctx_nextaddress(fetchctx_t *fctx) {
|
||||
dns_adbfind_t *find = NULL, *start = NULL;
|
||||
|
|
@ -4151,7 +4154,6 @@ fctx_nextaddress(fetchctx_t *fctx) {
|
|||
possibly_mark(fctx, ai);
|
||||
if (UNMARKED(ai)) {
|
||||
ai->flags |= FCTX_ADDRINFO_MARK;
|
||||
fctx->find = NULL;
|
||||
fctx->forwarding = true;
|
||||
|
||||
/*
|
||||
|
|
@ -4172,44 +4174,7 @@ fctx_nextaddress(fetchctx_t *fctx) {
|
|||
fctx->forwarding = false;
|
||||
FCTX_ATTR_SET(fctx, FCTX_ATTR_TRIEDFIND);
|
||||
|
||||
find = fctx->find;
|
||||
if (find == NULL) {
|
||||
find = ISC_LIST_HEAD(fctx->finds);
|
||||
} else {
|
||||
find = ISC_LIST_NEXT(find, publink);
|
||||
if (find == NULL) {
|
||||
find = ISC_LIST_HEAD(fctx->finds);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the first unmarked addrinfo.
|
||||
*/
|
||||
if (find != NULL) {
|
||||
start = find;
|
||||
do {
|
||||
ISC_LIST_FOREACH(find->list, ai, publink) {
|
||||
if (!UNMARKED(ai)) {
|
||||
continue;
|
||||
}
|
||||
possibly_mark(fctx, ai);
|
||||
if (UNMARKED(ai)) {
|
||||
ai->flags |= FCTX_ADDRINFO_MARK;
|
||||
faddrinfo = ai;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (faddrinfo != NULL) {
|
||||
break;
|
||||
}
|
||||
find = ISC_LIST_NEXT(find, publink);
|
||||
if (find == NULL) {
|
||||
find = ISC_LIST_HEAD(fctx->finds);
|
||||
}
|
||||
} while (find != start);
|
||||
}
|
||||
|
||||
fctx->find = find;
|
||||
faddrinfo = nextaddress(fctx);
|
||||
if (faddrinfo != NULL) {
|
||||
return faddrinfo;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17278,9 +17278,11 @@ checkds_find_address(dns_checkds_t *checkds) {
|
|||
isc_result_t result;
|
||||
unsigned int options;
|
||||
dns_adb_t *adb = NULL;
|
||||
dns_view_t *view = NULL;
|
||||
|
||||
REQUIRE(DNS_CHECKDS_VALID(checkds));
|
||||
|
||||
view = checkds->zone->view;
|
||||
options = DNS_ADBFIND_WANTEVENT;
|
||||
if (isc_net_probeipv4() != ISC_R_DISABLED) {
|
||||
options |= DNS_ADBFIND_INET;
|
||||
|
|
@ -17289,7 +17291,7 @@ checkds_find_address(dns_checkds_t *checkds) {
|
|||
options |= DNS_ADBFIND_INET6;
|
||||
}
|
||||
|
||||
dns_view_getadb(checkds->zone->view, &adb);
|
||||
dns_view_getadb(view, &adb);
|
||||
if (adb == NULL) {
|
||||
goto destroy;
|
||||
}
|
||||
|
|
@ -17297,7 +17299,7 @@ checkds_find_address(dns_checkds_t *checkds) {
|
|||
result = dns_adb_createfind(
|
||||
adb, checkds->zone->loop, process_checkds_adb_event, checkds,
|
||||
&checkds->ns, options, 0, checkds->zone->view->dstport, 0, NULL,
|
||||
NULL, NULL, &checkds->find);
|
||||
NULL, NULL, view->max_delegation_servers, &checkds->find, NULL);
|
||||
dns_adb_detach(&adb);
|
||||
|
||||
/* Something failed? */
|
||||
|
|
|
|||
Loading…
Reference in a new issue