--- /dev/null
+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";
+};
--- /dev/null
+$TTL 300
+. IN SOA dnshoster.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
--- /dev/null
+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";
+};
--- /dev/null
+$TTL 300
+@ IN SOA hoster.tld. ns.tld. (
+ 2010 ; serial
+ 600 ; refresh
+ 600 ; retry
+ 1200 ; expire
+ 600 ; minimum
+ )
+
+ NS ns
+ns A 10.52.0.2
+
+example NS ns.example
+
+ns.example A 10.53.0.20
+ns.example A 10.53.0.21
+ns.example A 10.53.0.22
+ns.example A 10.53.0.23
+ns.example A 10.53.0.24
+ns.example A 10.53.0.25
+ns.example A 10.53.0.26
+ns.example A 10.53.0.27
+ns.example A 10.53.0.28
+ns.example A 10.53.0.29
+ns.example A 10.53.0.30
+ns.example A 10.53.0.31
+ns.example A 10.53.0.32
+ns.example A 10.53.0.33
+ns.example A 10.53.0.34
+ns.example A 10.53.0.35
+ns.example A 10.53.0.36
+ns.example A 10.53.0.37
+ns.example A 10.53.0.38
+ns.example A 10.53.0.39
+ns.example A 10.53.0.40
+ns.example A 10.53.0.41
+ns.example A 10.53.0.42
+ns.example A 10.53.0.43
+
+ns.example AAAA 2001:db8::20
+ns.example AAAA 2001:db8::21
+ns.example AAAA 2001:db8::22
+ns.example AAAA 2001:db8::23
+ns.example AAAA 2001:db8::24
+ns.example AAAA 2001:db8::25
+ns.example AAAA 2001:db8::26
+ns.example AAAA 2001:db8::27
+ns.example AAAA 2001:db8::28
+ns.example AAAA 2001:db8::29
+ns.example AAAA 2001:db8::30
+ns.example AAAA 2001:db8::31
+ns.example AAAA 2001:db8::32
+ns.example AAAA 2001:db8::33
+ns.example AAAA 2001:db8::34
+ns.example AAAA 2001:db8::35
+ns.example AAAA 2001:db8::36
+ns.example AAAA 2001:db8::37
+ns.example AAAA 2001:db8::38
+ns.example AAAA 2001:db8::39
+ns.example AAAA 2001:db8::40
+ns.example AAAA 2001:db8::41
+ns.example AAAA 2001:db8::42
+ns.example AAAA 2001:db8::43
--- /dev/null
+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 yes;
+ dnssec-validation no;
+};
+
+server 10.53.0.2 {
+ // Avoid truncation of the additional section without TC, because some
+ // mandatory glues would already be in the additional section, thus the
+ // resolver wouldn't try again using TCP by itself.
+ tcp-only yes;
+};
+
+zone "." {
+ type hint;
+ file "root.hint";
+};
+
+key rndc_key {
+ secret "1234abcd8765";
+ algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+ inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
--- /dev/null
+$TTL 999999
+. IN NS a.root-servers.nil.
+a.root-servers.nil. IN A 10.53.0.1
--- /dev/null
+# 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 isctest
+
+
+def test_cap_glues(ns3):
+ msg = isctest.query.create("example.tld.", "A")
+ isctest.query.udp(msg, ns3.ip)
+
+ with ns3.watch_log_from_here() as watcher:
+ ns3.rndc("dumpdb -cache")
+ watcher.wait_for_line("dumpdb complete")
+ db = isctest.text.TextFile(f"{ns3.identifier}/named_dump.db")
+
+ allowed_suffixes = range(20, 40)
+ skipped_suffixes = range(40, 44)
+
+ for n in allowed_suffixes:
+ assert len(db.grep(f"10.53.0.{n}")) >= 1
+ assert len(db.grep(f"2001:db8::{n}")) >= 1
+
+ for n in skipped_suffixes:
+ assert len(db.grep(f"10.53.0.{n}")) == 0
+ assert len(db.grep(f"2001:db8::{n}")) == 0
*/
#define NS_PROCESSING_LIMIT 20
+/*
+ * Cap on the number of glue addresses cached per NS owner from a referral.
+ * The resolver only ever tries a handful of addresses per NS, so accepting
+ * more than this from a single referral is wasted memory. Each NS owner
+ * may contribute at most DELEG_MAX_GLUES_PER_NS A and DELEG_MAX_GLUES_PER_NS
+ * AAAA glue records.
+ */
+#define DELEG_MAX_GLUES_PER_NS 20
+
/* Hash table for zone counters */
#ifndef RES_DOMAIN_HASH_BITS
#define RES_DOMAIN_HASH_BITS 12
return result;
}
+/*
+ * Truncate 'rdataset' to at most 'max' rdata, by unlinking the trailing
+ * rdata from the underlying rdatalist. The rdataset must be backed by a
+ * dns_rdatalist, which is the case for rdatasets parsed from a message.
+ */
+static void
+truncate_rdataset(dns_rdataset_t *rdataset, unsigned int max) {
+ dns_rdatalist_t *rdatalist = NULL;
+ dns_rdata_t *keep = NULL;
+ dns_rdata_t *next = NULL;
+ unsigned int i;
+
+ REQUIRE(max > 0);
+
+ if (dns_rdataset_count(rdataset) <= max) {
+ return;
+ }
+
+ dns_rdatalist_fromrdataset(rdataset, &rdatalist);
+
+ keep = ISC_LIST_HEAD(rdatalist->rdata);
+ for (i = 1; i < max && keep != NULL; i++) {
+ keep = ISC_LIST_NEXT(keep, link);
+ }
+ INSIST(keep != NULL);
+
+ next = ISC_LIST_NEXT(keep, link);
+ while (next != NULL) {
+ dns_rdata_t *unlinked = next;
+ next = ISC_LIST_NEXT(next, link);
+ ISC_LIST_UNLINK(rdatalist->rdata, unlinked, link);
+ }
+}
+
static void
mark_related(dns_name_t *name, dns_rdataset_t *rdataset, bool external,
bool gluing) {
name->attributes.cache = true;
if (gluing) {
rdataset->trust = dns_trust_glue;
+ if (rdataset->type == dns_rdatatype_a ||
+ rdataset->type == dns_rdatatype_aaaa)
+ {
+ truncate_rdataset(rdataset, DELEG_MAX_GLUES_PER_NS);
+ }
+
/*
* Glue with 0 TTL causes problems. We force the TTL to
* 1 second to prevent this.