mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
Merge branch '3405-security-limit-the-number-of-resource-records-in-rrset' into 'v9.20.0-release'
Limit the number of RRs in RRSets See merge request isc-private/bind9!694
This commit is contained in:
commit
24e8cc7b38
16
CHANGES
16
CHANGES
@ -1,3 +1,19 @@
|
||||
6401. [security] An excessively large number of rrtypes per owner can
|
||||
slow down database query processing, so a limit has been
|
||||
placed on the number of rrtypes that can be stored per
|
||||
owner (node) in a cache or zone database. This is
|
||||
configured with the new "max-rrtypes-per-name" option,
|
||||
and defaults to 100. (CVE-2024-1737)
|
||||
[GL #3403] [GL #4548]
|
||||
|
||||
6400. [security] Excessively large rdatasets can slow down database
|
||||
query processing, so a limit has been placed on the
|
||||
number of records that can be stored per rdataset
|
||||
in a cache or zone database. This is configured
|
||||
with the new "max-records-per-type" option, and
|
||||
defaults to 100. (CVE-2024-1737)
|
||||
[GL #497] [GL #3405]
|
||||
|
||||
6399. [security] Malicious DNS client that sends many queries over
|
||||
TCP but never reads responses can cause server to
|
||||
respond slowly or not respond at all for other
|
||||
|
@ -222,8 +222,10 @@ options {\n\
|
||||
ixfr-from-differences false;\n\
|
||||
max-journal-size default;\n\
|
||||
max-records 0;\n\
|
||||
max-records-per-type 100;\n\
|
||||
max-refresh-time 2419200; /* 4 weeks */\n\
|
||||
max-retry-time 1209600; /* 2 weeks */\n\
|
||||
max-types-per-name 100;\n\
|
||||
max-transfer-idle-in 60;\n\
|
||||
max-transfer-idle-out 60;\n\
|
||||
max-transfer-time-in 120;\n\
|
||||
|
@ -5454,6 +5454,24 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config,
|
||||
dns_resolver_setclientsperquery(view->resolver, cfg_obj_asuint32(obj),
|
||||
max_clients_per_query);
|
||||
|
||||
/*
|
||||
* This is used for the cache and also as a default value
|
||||
* for zone databases.
|
||||
*/
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "max-records-per-type", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
dns_view_setmaxrrperset(view, cfg_obj_asuint32(obj));
|
||||
|
||||
/*
|
||||
* This is used for the cache and also as a default value
|
||||
* for zone databases.
|
||||
*/
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "max-types-per-name", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
dns_view_setmaxtypepername(view, cfg_obj_asuint32(obj));
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "max-recursion-depth", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
|
@ -1074,6 +1074,22 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
|
||||
dns_zone_setmaxrecords(zone, 0);
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "max-records-per-type", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
dns_zone_setmaxrrperset(mayberaw, cfg_obj_asuint32(obj));
|
||||
if (zone != mayberaw) {
|
||||
dns_zone_setmaxrrperset(zone, 0);
|
||||
}
|
||||
|
||||
obj = NULL;
|
||||
result = named_config_get(maps, "max-types-per-name", &obj);
|
||||
INSIST(result == ISC_R_SUCCESS && obj != NULL);
|
||||
dns_zone_setmaxtypepername(mayberaw, cfg_obj_asuint32(obj));
|
||||
if (zone != mayberaw) {
|
||||
dns_zone_setmaxtypepername(zone, 0);
|
||||
}
|
||||
|
||||
if (raw != NULL && filename != NULL) {
|
||||
#define SIGNED ".signed"
|
||||
size_t signedlen = strlen(filename) + sizeof(SIGNED);
|
||||
|
@ -98,6 +98,7 @@ options {
|
||||
tcp-initial-timeout 1200;
|
||||
transfers-in 100;
|
||||
transfers-out 100;
|
||||
max-records-per-type 0;
|
||||
};
|
||||
|
||||
trust-anchors { };
|
||||
|
@ -52,6 +52,7 @@ options {
|
||||
ixfr-from-differences yes;
|
||||
check-integrity no;
|
||||
dnssec-validation yes;
|
||||
max-records-per-type 0;
|
||||
transfers-in 100;
|
||||
transfers-out 100;
|
||||
};
|
||||
|
@ -44,6 +44,7 @@ options {
|
||||
ixfr-from-differences yes;
|
||||
check-integrity no;
|
||||
dnssec-validation yes;
|
||||
max-records-per-type 0;
|
||||
};
|
||||
|
||||
trust-anchors { };
|
||||
|
@ -52,6 +52,7 @@ options {
|
||||
ixfr-from-differences yes;
|
||||
check-integrity no;
|
||||
dnssec-validation yes;
|
||||
max-records-per-type 0;
|
||||
};
|
||||
|
||||
trust-anchors { };
|
||||
|
@ -40,6 +40,7 @@ options {
|
||||
ixfr-from-differences yes;
|
||||
check-integrity no;
|
||||
dnssec-validation yes;
|
||||
max-records-per-type 0;
|
||||
};
|
||||
|
||||
trust-anchors { };
|
||||
|
@ -23,6 +23,7 @@ options {
|
||||
notify yes;
|
||||
minimal-responses no;
|
||||
dnssec-validation no;
|
||||
max-records-per-type 0;
|
||||
};
|
||||
|
||||
zone "." {
|
||||
|
@ -26,7 +26,12 @@ $CHECKZONE -D -F raw=0 -o example.db.compat example-compat \
|
||||
example.db >/dev/null 2>&1
|
||||
$CHECKZONE -D -F raw -L 3333 -o example.db.serial.raw example \
|
||||
example.db >/dev/null 2>&1
|
||||
$CHECKZONE -D -F raw -o large.db.raw large large.db >/dev/null 2>&1
|
||||
$CHECKZONE -D -F raw -o under-limit.db.raw under-limit under-limit.db >/dev/null 2>&1
|
||||
$CHECKZONE -D -F raw -o under-limit-kasp.db.raw under-limit-kasp under-limit-kasp.db >/dev/null 2>&1
|
||||
$CHECKZONE -D -F raw -o on-limit.db.raw on-limit on-limit.db >/dev/null 2>&1
|
||||
$CHECKZONE -D -F raw -o on-limit-kasp.db.raw on-limit-kasp on-limit-kasp.db >/dev/null 2>&1
|
||||
$CHECKZONE -D -F raw -o over-limit.db.raw over-limit over-limit.db >/dev/null 2>&1
|
||||
$CHECKZONE -D -F raw -o 255types.db.raw 255types 255types.db >/dev/null 2>&1
|
||||
|
||||
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK signed >/dev/null 2>&1
|
||||
$KEYGEN -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" signed >/dev/null 2>&1
|
||||
|
@ -23,6 +23,8 @@ options {
|
||||
session-keyfile "session.key";
|
||||
servfail-ttl 0;
|
||||
dnssec-validation no;
|
||||
max-records-per-type 2050;
|
||||
max-types-per-name 500;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
@ -78,9 +80,48 @@ zone "transfer4" {
|
||||
};
|
||||
|
||||
|
||||
zone "large" {
|
||||
zone "under-limit" {
|
||||
type primary;
|
||||
file "large.db.raw";
|
||||
file "under-limit.db.raw";
|
||||
masterfile-format raw;
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
||||
zone "under-limit-kasp" {
|
||||
type primary;
|
||||
file "under-limit-kasp.db.raw";
|
||||
masterfile-format raw;
|
||||
dnssec-policy masterformat;
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
||||
zone "on-limit" {
|
||||
type primary;
|
||||
file "on-limit.db.raw";
|
||||
masterfile-format raw;
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
||||
zone "on-limit-kasp" {
|
||||
type primary;
|
||||
file "on-limit-kasp.db.raw";
|
||||
masterfile-format raw;
|
||||
dnssec-policy masterformat;
|
||||
inline-signing no;
|
||||
allow-update { any; };
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
||||
zone "over-limit" {
|
||||
type primary;
|
||||
file "over-limit.db.raw";
|
||||
masterfile-format raw;
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
||||
zone "255types" {
|
||||
type primary;
|
||||
file "255types.db.raw";
|
||||
masterfile-format raw;
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
@ -22,6 +22,8 @@ options {
|
||||
notify no;
|
||||
servfail-ttl 0;
|
||||
dnssec-validation no;
|
||||
max-records-per-type 2000;
|
||||
max-types-per-name 200;
|
||||
};
|
||||
|
||||
zone "example" {
|
||||
@ -56,9 +58,37 @@ zone "transfer4" {
|
||||
file "transfer.db.full";
|
||||
};
|
||||
|
||||
zone "large" {
|
||||
zone "under-limit" {
|
||||
type secondary;
|
||||
primaries { 10.53.0.1; };
|
||||
masterfile-format raw;
|
||||
file "large.bk";
|
||||
file "under-limit.bk";
|
||||
};
|
||||
|
||||
zone "under-limit-kasp" {
|
||||
type secondary;
|
||||
primaries { 10.53.0.1; };
|
||||
masterfile-format raw;
|
||||
file "under-limit-kasp.bk";
|
||||
};
|
||||
|
||||
zone "on-limit" {
|
||||
type secondary;
|
||||
primaries { 10.53.0.1; };
|
||||
masterfile-format raw;
|
||||
file "on-limit.bk";
|
||||
};
|
||||
|
||||
zone "on-limit-kasp" {
|
||||
type secondary;
|
||||
primaries { 10.53.0.1; };
|
||||
masterfile-format raw;
|
||||
file "on-limit-kasp.bk";
|
||||
};
|
||||
|
||||
zone "255types" {
|
||||
type secondary;
|
||||
primaries { 10.53.0.1; };
|
||||
masterfile-format raw;
|
||||
file "255types.bk";
|
||||
};
|
||||
|
21
bin/tests/system/masterformat/ns4/compile.sh
Executable file
21
bin/tests/system/masterformat/ns4/compile.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
# 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.
|
||||
|
||||
# shellcheck source=conf.sh
|
||||
. ../../conf.sh
|
||||
|
||||
for zone in kasp-max-records-per-type \
|
||||
kasp-max-records-per-type-dnskey \
|
||||
kasp-max-types-per-name; do
|
||||
$CHECKZONE -D -F raw -o $zone.db.raw $zone template.db >/dev/null 2>&1
|
||||
done
|
28
bin/tests/system/masterformat/ns4/kasp.db
Normal file
28
bin/tests/system/masterformat/ns4/kasp.db
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.
|
||||
|
||||
$TTL 1D
|
||||
|
||||
@ IN SOA ns hostmaster (
|
||||
1
|
||||
3600
|
||||
1800
|
||||
1814400
|
||||
3
|
||||
)
|
||||
NS ns
|
||||
ns A 10.53.0.1
|
||||
mx MX 10 mail
|
||||
a A 10.53.0.1
|
||||
aaaa AAAA 2001:db8::53
|
||||
cname CNAME cname-target
|
||||
dname DNAME dname-target
|
||||
txt TXT "this is text"
|
89
bin/tests/system/masterformat/ns4/named1.conf.in
Normal file
89
bin/tests/system/masterformat/ns4/named1.conf.in
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.
|
||||
*/
|
||||
|
||||
// NS4
|
||||
|
||||
options {
|
||||
pid-file "named.pid";
|
||||
listen-on port @PORT@ { 10.53.0.4; };
|
||||
port @PORT@;
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
notify no;
|
||||
session-keyfile "session.key";
|
||||
servfail-ttl 0;
|
||||
dnssec-validation no;
|
||||
|
||||
/* Ridicously low on purpose */
|
||||
max-records-per-type 1;
|
||||
max-types-per-name 11;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
dnssec-policy "masterformat" {
|
||||
keys {
|
||||
ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
|
||||
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* This one should be okay, since the default policy only introduces one DNSKEY
|
||||
* and each signature covering a different type is considered a separate RRset.
|
||||
*/
|
||||
zone "kasp-max-records-per-type" {
|
||||
type primary;
|
||||
file "kasp-max-records-per-type.db.raw";
|
||||
masterfile-format raw;
|
||||
dnssec-policy "default";
|
||||
inline-signing no;
|
||||
allow-update { any; };
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
||||
/*
|
||||
* This one uses a ZSK / KSK, so that is two records in one RRset,
|
||||
* thus it should fail to sign.
|
||||
*/
|
||||
zone "kasp-max-records-per-type-dnskey" {
|
||||
type primary;
|
||||
file "kasp-max-records-per-type-dnskey.db.raw";
|
||||
masterfile-format raw;
|
||||
dnssec-policy "masterformat";
|
||||
inline-signing no;
|
||||
allow-update { any; };
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
||||
/*
|
||||
* The template zone is fine and should be possible to sign, but when
|
||||
* adding an extra type to the apex the max-types-per-name will be exceeded,
|
||||
* meaning the update should fail.
|
||||
*/
|
||||
zone "kasp-max-types-per-name" {
|
||||
type primary;
|
||||
file "kasp-max-types-per-name.db.raw";
|
||||
masterfile-format raw;
|
||||
dnssec-policy "default";
|
||||
inline-signing no;
|
||||
allow-update { any; };
|
||||
allow-transfer { any; };
|
||||
};
|
53
bin/tests/system/masterformat/ns4/named2.conf.in
Normal file
53
bin/tests/system/masterformat/ns4/named2.conf.in
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// NS4
|
||||
|
||||
options {
|
||||
pid-file "named.pid";
|
||||
listen-on port @PORT@ { 10.53.0.4; };
|
||||
port @PORT@;
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
notify no;
|
||||
session-keyfile "session.key";
|
||||
servfail-ttl 0;
|
||||
dnssec-validation no;
|
||||
|
||||
/* Ridicously low on purpose */
|
||||
max-records-per-type 1;
|
||||
max-types-per-name 9;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
/*
|
||||
* The template zone is fine, but when adding the DNSSEC records to the apex,
|
||||
* the max-types-per-name will be exceeded, meaning signing should fail.
|
||||
*/
|
||||
zone "kasp-max-types-per-name" {
|
||||
type primary;
|
||||
file "kasp-max-types-per-name.db.raw";
|
||||
masterfile-format raw;
|
||||
dnssec-policy "default";
|
||||
inline-signing no;
|
||||
allow-update { any; };
|
||||
allow-transfer { any; };
|
||||
};
|
28
bin/tests/system/masterformat/ns4/template.db
Normal file
28
bin/tests/system/masterformat/ns4/template.db
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.
|
||||
|
||||
$TTL 1D
|
||||
|
||||
@ IN SOA ns hostmaster (
|
||||
1
|
||||
3600
|
||||
1800
|
||||
1814400
|
||||
3
|
||||
)
|
||||
NS ns
|
||||
ns A 10.53.0.1
|
||||
mx MX 10 mail
|
||||
a A 10.53.0.1
|
||||
aaaa AAAA 2001:db8::53
|
||||
cname CNAME cname-target
|
||||
dname DNAME dname-target
|
||||
txt TXT "this is text"
|
@ -19,13 +19,44 @@ $SHELL clean.sh
|
||||
copy_setports ns1/named.conf.in ns1/named.conf
|
||||
copy_setports ns2/named.conf.in ns2/named.conf
|
||||
copy_setports ns3/named.conf.in ns3/named.conf
|
||||
copy_setports ns4/named1.conf.in ns4/named.conf
|
||||
|
||||
cp ns1/example.db ns2/
|
||||
cp ns2/formerly-text.db.in ns2/formerly-text.db
|
||||
cp ns1/large.db.in ns1/large.db
|
||||
cp ns1/empty.db.in ns1/under-limit.db
|
||||
|
||||
# counts are set with respect to these limits in named.conf:
|
||||
# max-records-per-type 2050;
|
||||
# max-types-per-name 500;
|
||||
awk 'END {
|
||||
for (i = 0; i < 512; i++ ) { print "a TXT", i; }
|
||||
for (i = 0; i < 1024; i++ ) { print "b TXT", i; }
|
||||
for (i = 0; i < 2000; i++ ) { print "c TXT", i; }
|
||||
}' </dev/null >>ns1/large.db
|
||||
cd ns1 && $SHELL compile.sh
|
||||
for (i = 0; i < 500; i++ ) { print "500-txt TXT", i; }
|
||||
for (i = 0; i < 1000; i++ ) { print "1000-txt TXT", i; }
|
||||
for (i = 0; i < 2000; i++ ) { print "2000-txt TXT", i; }
|
||||
}' </dev/null >>ns1/under-limit.db
|
||||
cp ns1/under-limit.db ns1/under-limit-kasp.db
|
||||
|
||||
cp ns1/empty.db.in ns1/on-limit.db
|
||||
awk 'END {
|
||||
for (i = 0; i < 500; i++ ) { print "500-txt TXT", i; }
|
||||
for (i = 0; i < 1000; i++ ) { print "1000-txt TXT", i; }
|
||||
for (i = 0; i < 2000; i++ ) { print "2000-txt TXT", i; }
|
||||
for (i = 0; i < 2050; i++ ) { print "2050-txt TXT", i; }
|
||||
}' </dev/null >>ns1/on-limit.db
|
||||
cp ns1/on-limit.db ns1/on-limit-kasp.db
|
||||
|
||||
cp ns1/empty.db.in ns1/over-limit.db
|
||||
awk 'END {
|
||||
for (i = 0; i < 500; i++ ) { print "500-txt TXT", i; }
|
||||
for (i = 0; i < 1000; i++ ) { print "1000-txt TXT", i; }
|
||||
for (i = 0; i < 2000; i++ ) { print "2000-txt TXT", i; }
|
||||
for (i = 0; i < 2050; i++ ) { print "2050-txt TXT", i; }
|
||||
for (i = 0; i < 2100; i++ ) { print "2100-txt TXT", i; }
|
||||
}' </dev/null >>ns1/over-limit.db
|
||||
|
||||
cp ns1/empty.db.in ns1/255types.db
|
||||
for ntype in $(seq 65280 65534); do
|
||||
echo "m TYPE${ntype} \# 0"
|
||||
done >>ns1/255types.db
|
||||
echo "m TXT bunny" >>ns1/255types.db
|
||||
(cd ns1 && $SHELL compile.sh)
|
||||
(cd ns4 && $SHELL compile.sh)
|
||||
|
@ -134,7 +134,7 @@ n=$((n + 1))
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "waiting for transfers to complete"
|
||||
for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
test -f ns2/transfer.db.raw -a -f ns2/transfer.db.txt && break
|
||||
sleep 1
|
||||
done
|
||||
@ -162,7 +162,7 @@ n=$((n + 1))
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that secondary formerly in text format is now raw ($n)"
|
||||
for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
israw ns2/formerly-text.db >/dev/null 2>&1 || ret=1
|
||||
[ "$(rawversion ns2/formerly-text.db)" -eq 1 ] || ret=1
|
||||
@ -173,12 +173,12 @@ n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that large rdatasets loaded ($n)"
|
||||
for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
echo_i "checking that under-limit rdatasets loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for a in a b c; do
|
||||
$DIG +tcp txt "${a}.large" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns2.test$n" >/dev/null || ret=1
|
||||
for rrcount in 500-txt 1000-txt 2000-txt; do
|
||||
$DIG +tcp txt "${rrcount}.under-limit" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$rrcount.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
@ -187,6 +187,253 @@ n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that under-limit rdatasets transfered ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrcount in 500-txt 1000-txt 2000-txt; do
|
||||
$DIG +tcp txt "${rrcount}.under-limit" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.$rrcount.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns2.$rrcount.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that under-limit-kasp dnskeys loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
|
||||
$DIG +tcp +dnssec dnskey "under-limit-kasp" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.dnskey.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns1.dnskey.test$n" >/dev/null || ret=1
|
||||
grep "RRSIG" "dig.out.ns1.dnskey.test$n" >/dev/null || ret=1
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that under-limit-kasp rdatasets loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrcount in 500-txt 1000-txt 2000-txt; do
|
||||
$DIG +tcp +dnssec txt "${rrcount}.under-limit-kasp" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$rrcount.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
|
||||
grep "RRSIG" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that under-limit-kasp rdatasets transfered ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrcount in 500-txt 1000-txt 2000-txt; do
|
||||
$DIG +tcp +dnssec txt "${rrcount}.under-limit-kasp" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.$rrcount.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns2.$rrcount.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that on-limit rdatasets loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrcount in 500-txt 1000-txt 2000-txt 2050-txt; do
|
||||
$DIG +tcp txt "${rrcount}.on-limit" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$rrcount.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that on-limit rdatasets not transfered ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrcount in 500-txt 1000-txt 2000-txt 2050-txt; do
|
||||
$DIG +tcp txt "${rrcount}.on-limit" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.$rrcount.test$n"
|
||||
grep "status: SERVFAIL" "dig.out.ns2.$rrcount.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that on-limit-kasp rdatasets loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrcount in 500-txt 1000-txt 2000-txt 2050-txt; do
|
||||
$DIG +tcp +dnssec txt "${rrcount}.on-limit-kasp" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$rrcount.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
|
||||
grep "RRSIG" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that on-limit-kasp rdatasets not transfered ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrcount in 500-txt 1000-txt 2000-txt 2050-txt; do
|
||||
$DIG +tcp +dnssec txt "${rrcount}.on-limit-kasp" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.$rrcount.test$n"
|
||||
grep "status: SERVFAIL" "dig.out.ns2.$rrcount.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that over-limit rdatasets not loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrcount in 500-txt 1000-txt 2000-txt 2050-txt 2100-txt; do
|
||||
$DIG +tcp txt "${rrcount}.over-limit" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$rrcount.test$n"
|
||||
grep "status: SERVFAIL" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that kasp-max-records-per-type rdatasets loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrtype in soa dnskey ns; do
|
||||
$DIG +tcp +dnssec $rrtype "kasp-max-records-per-type" @10.53.0.4 -p "${PORT}" >"dig.out.ns4.$rrtype.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns4.$rrtype.test$n" >/dev/null || ret=1
|
||||
grep "RRSIG" "dig.out.ns4.$rrtype.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that kasp-max-records-per-type-dnskey rdatasets not signed ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrtype in soa dnskey ns; do
|
||||
$DIG +tcp +dnssec $rrtype "kasp-max-records-per-type-dnskey" @10.53.0.4 -p "${PORT}" >"dig.out.ns4.$rrtype.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns4.$rrtype.test$n" >/dev/null || ret=1
|
||||
grep "RRSIG" "dig.out.ns4.$rrtype.test$n" >/dev/null && ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that kasp-max-types-per-name rdatasets loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrtype in soa dnskey ns; do
|
||||
$DIG +tcp +dnssec $rrtype "kasp-max-types-per-name" @10.53.0.4 -p "${PORT}" >"dig.out.ns4.$rrtype.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns4.$rrtype.test$n" >/dev/null || ret=1
|
||||
grep "RRSIG" "dig.out.ns4.$rrtype.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
# Update zone with nsupdate.
|
||||
n=$((n + 1))
|
||||
echo_i "add new type to zone and check that it fails ($n)"
|
||||
ret=0
|
||||
(
|
||||
echo zone kasp-max-types-per-name.
|
||||
echo server 10.53.0.4 "$PORT"
|
||||
echo update add kasp-max-types-per-name. 300 TXT KAPUTT
|
||||
echo send
|
||||
) | $NSUPDATE && ret=1
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that kasp-max-types-per-name rdatasets loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrtype in soa dnskey ns txt; do
|
||||
$DIG +tcp +dnssec $rrtype "kasp-max-types-per-name" @10.53.0.4 -p "${PORT}" >"dig.out.ns4.$rrtype.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns4.$rrtype.test$n" >/dev/null || ret=1
|
||||
grep "KAPUTT" "dig.out.ns4.$rrtype.test$n" >/dev/null && ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
# Reconfigure ns4
|
||||
echo_i "reconfigure ns4"
|
||||
stop_server ns4
|
||||
copy_setports ns4/named2.conf.in ns4/named.conf
|
||||
# Recompile zone
|
||||
$CHECKZONE -D -F raw -o ns4/kasp.db.raw kasp-max-types-per-name ns4/template.db >/dev/null 2>&1
|
||||
start_server --noclean --restart --port "${PORT}" ns4
|
||||
|
||||
echo_i "checking that kasp-max-types-per-name rdatasets not loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrtype in soa dnskey ns; do
|
||||
$DIG +tcp +dnssec $rrtype "kasp-max-types-per-name" @10.53.0.4 -p "${PORT}" >"dig.out.ns4.$rrtype.test$n"
|
||||
grep "status: SERVFAIL" "dig.out.ns4.$rrtype.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that 255 types are loaded ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
$DIG +tcp TXT "m.255types" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns1.test$n" >/dev/null || ret=1
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that 255 types types are not transfered ($n)"
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
$DIG +tcp TXT "m.255types" @10.53.0.2 -p "${PORT}" >"dig.out.ns2.test$n"
|
||||
grep "status: SERVFAIL" "dig.out.ns2.test$n" >/dev/null || ret=1
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking format transitions: text->raw->text ($n)"
|
||||
ret=0
|
||||
$CHECKZONE -D -f text -F text -o baseline.txt example.nil ns1/example.db >/dev/null
|
||||
@ -240,7 +487,7 @@ stop_server --use-rndc --port ${CONTROLPORT} ns3
|
||||
rm ns3/*.jnl
|
||||
restart
|
||||
#shellcheck disable=SC2034
|
||||
for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
lret=0
|
||||
dig_with_opts +comm @10.53.0.3 moretext.dynamic txt >"dig.out.dynamic2.ns3.test$n"
|
||||
grep "more text" "dig.out.dynamic2.ns3.test$n" >/dev/null 2>&1 || lret=1
|
||||
@ -273,5 +520,24 @@ n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "checking that on-limit-kasp rdatasets loaded after re-sign and re-start ($n)"
|
||||
ret=0
|
||||
stop_server ns1
|
||||
start_server --noclean --restart --port "${PORT}" ns1
|
||||
|
||||
for _attempt in 0 1 2 3 4 5 6 7 8 9; do
|
||||
ret=0
|
||||
for rrcount in 500-txt 1000-txt 2000-txt 2050-txt; do
|
||||
$DIG +tcp +dnssec txt "${rrcount}.on-limit-kasp" @10.53.0.1 -p "${PORT}" >"dig.out.ns1.$rrcount.test$n"
|
||||
grep "status: NOERROR" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
|
||||
grep "RRSIG" "dig.out.ns1.$rrcount.test$n" >/dev/null || ret=1
|
||||
done
|
||||
[ $ret -eq 0 ] && break
|
||||
sleep 1
|
||||
done
|
||||
n=$((n + 1))
|
||||
[ $ret -eq 0 ] || echo_i "failed"
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
|
2771
bin/tests/system/reclimit/ns1/big.db
Normal file
2771
bin/tests/system/reclimit/ns1/big.db
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,13 @@ options {
|
||||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
dnssec-validation no;
|
||||
max-records-per-type 0;
|
||||
max-types-per-name 0;
|
||||
};
|
||||
|
||||
zone "." { type primary; file "root.db"; };
|
||||
|
||||
zone "big." {
|
||||
type primary;
|
||||
file "big.db";
|
||||
};
|
||||
|
@ -19,3 +19,6 @@ example.net. 60 IN NS direct.example.net.
|
||||
direct.example.net. 60 IN A 10.53.0.2
|
||||
example.com. 60 IN NS direct.example.com.
|
||||
direct.example.com. 60 IN A 10.53.0.4
|
||||
|
||||
big. in NS ns.big.
|
||||
ns.big. 60 IN A 10.53.0.1
|
||||
|
43
bin/tests/system/reclimit/ns3/named5.conf.in
Normal file
43
bin/tests/system/reclimit/ns3/named5.conf.in
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 {
|
||||
directory ".";
|
||||
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; };
|
||||
listen-on-v6 { none; };
|
||||
servfail-ttl 0;
|
||||
qname-minimization disabled;
|
||||
max-recursion-depth 12;
|
||||
recursion yes;
|
||||
dnssec-validation yes;
|
||||
max-records-per-type 0;
|
||||
max-types-per-name 10;
|
||||
};
|
||||
|
||||
trust-anchors { };
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
zone "." { type hint; file "hints.db"; };
|
43
bin/tests/system/reclimit/ns3/named6.conf.in
Normal file
43
bin/tests/system/reclimit/ns3/named6.conf.in
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 {
|
||||
directory ".";
|
||||
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; };
|
||||
listen-on-v6 { none; };
|
||||
servfail-ttl 0;
|
||||
qname-minimization disabled;
|
||||
max-recursion-depth 12;
|
||||
recursion yes;
|
||||
dnssec-validation yes;
|
||||
max-records-per-type 0;
|
||||
max-types-per-name 0;
|
||||
};
|
||||
|
||||
trust-anchors { };
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
zone "." { type hint; file "hints.db"; };
|
@ -222,6 +222,50 @@ eval count=$(cat dig.out.3.test$n)
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
#grep "duplicate query" ns3/named.run
|
||||
n=$((n + 1))
|
||||
echo_i "checking RRset that exceeds max-records-per-type ($n)"
|
||||
ret=0
|
||||
$DIG $DIGOPTS @10.53.0.3 biganswer.big >dig.out.1.test$n || ret=1
|
||||
grep 'status: SERVFAIL' dig.out.1.test$n >/dev/null || ret=1
|
||||
ns3_reset ns3/named5.conf.in
|
||||
$DIG $DIGOPTS @10.53.0.3 biganswer.big >dig.out.2.test$n || ret=1
|
||||
grep 'status: NOERROR' dig.out.2.test$n >/dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
check_manytypes() (
|
||||
i=$1
|
||||
type=$2
|
||||
expected=$3
|
||||
|
||||
$DIG $DIGOPTS @10.53.0.3 IN $type manytypes.big >dig.out.$i.$type.test$n || exit 1
|
||||
grep 'status: '"${expected}"'' dig.out.$i.$type.test$n >/dev/null || exit 1
|
||||
|
||||
exit 0
|
||||
)
|
||||
|
||||
n=$((n + 1))
|
||||
echo_i "checking name that exceeds max-types-per-name ($n)"
|
||||
ret=0
|
||||
|
||||
# Limited to 10 types - these should be fine
|
||||
for ntype in $(seq 65280 65289); do
|
||||
check_manytypes 1 "TYPE${ntype}" NOERROR || ret=1
|
||||
done
|
||||
# Everything on top of that should SERVFAIL
|
||||
for ntype in $(seq 65290 65534); do
|
||||
check_manytypes 1 "TYPE${ntype}" SERVFAIL || ret=1
|
||||
done
|
||||
|
||||
# Lift the limit
|
||||
ns3_reset ns3/named6.conf.in
|
||||
|
||||
for ntype in $(seq 65280 65534); do
|
||||
check_manytypes 2 "TYPE${ntype}" NOERROR || ret=1
|
||||
done
|
||||
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=$((status + ret))
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
|
@ -3681,6 +3681,36 @@ system.
|
||||
This sets the maximum number of records permitted in a zone. The default is
|
||||
zero, which means the maximum is unlimited.
|
||||
|
||||
.. namedconf:statement:: max-records-per-type
|
||||
:tags: server
|
||||
:short: Sets the maximum number of records that can be stored in an RRset
|
||||
|
||||
This sets the maximum number of resource records that can be stored
|
||||
in an RRset in a database. When configured in :namedconf:ref:`options`
|
||||
or :namedconf:ref:`view`, it controls the cache database; it also sets
|
||||
the default value for zone databases, which can be overridden by setting
|
||||
it at the :namedconf:ref:`zone` level.
|
||||
|
||||
If set to a positive value, any attempt to cache or to add to a zone
|
||||
an RRset with more than the specified number of records will result in
|
||||
a failure. If set to 0, there is no cap on RRset size. The default is
|
||||
100.
|
||||
|
||||
.. namedconf:statement:: max-types-per-name
|
||||
:tags: server
|
||||
:short: Sets the maximum number of RR types that can be stored for an owner name
|
||||
|
||||
This sets the maximum number of resource record types that can be stored
|
||||
for a single owner name in a database. When configured in :namedconf:ref:`options`
|
||||
or :namedconf:ref:`view`, it controls the cache database, and also sets
|
||||
the default value for zone databases, which can be overridden by setting
|
||||
it at the :namedconf:ref:`zone` level
|
||||
|
||||
If set to a positive value, any attempt to cache or to add to a zone an owner
|
||||
name with more than the specified number of resource record types will result
|
||||
in a failure. If set to 0, there is no cap on RR types number. The default is
|
||||
100.
|
||||
|
||||
.. namedconf:statement:: recursive-clients
|
||||
:tags: query
|
||||
:short: Specifies the maximum number of concurrent recursive queries the server can perform.
|
||||
|
@ -16,12 +16,14 @@ zone <string> [ <class> ] {
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-records <integer>;
|
||||
max-records-per-type <integer>;
|
||||
max-refresh-time <integer>;
|
||||
max-retry-time <integer>;
|
||||
max-transfer-idle-in <integer>;
|
||||
max-transfer-idle-out <integer>;
|
||||
max-transfer-time-in <integer>;
|
||||
max-transfer-time-out <integer>;
|
||||
max-types-per-name <integer>;
|
||||
min-refresh-time <integer>;
|
||||
min-retry-time <integer>;
|
||||
multi-master <boolean>;
|
||||
|
@ -183,6 +183,7 @@ options {
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-ncache-ttl <duration>;
|
||||
max-records <integer>;
|
||||
max-records-per-type <integer>;
|
||||
max-recursion-depth <integer>;
|
||||
max-recursion-queries <integer>;
|
||||
max-refresh-time <integer>;
|
||||
@ -193,6 +194,7 @@ options {
|
||||
max-transfer-idle-out <integer>;
|
||||
max-transfer-time-in <integer>;
|
||||
max-transfer-time-out <integer>;
|
||||
max-types-per-name <integer>;
|
||||
max-udp-size <integer>;
|
||||
max-validation-failures-per-fetch <integer>; // experimental
|
||||
max-validations-per-fetch <integer>; // experimental
|
||||
@ -468,6 +470,7 @@ view <string> [ <class> ] {
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-ncache-ttl <duration>;
|
||||
max-records <integer>;
|
||||
max-records-per-type <integer>;
|
||||
max-recursion-depth <integer>;
|
||||
max-recursion-queries <integer>;
|
||||
max-refresh-time <integer>;
|
||||
@ -477,6 +480,7 @@ view <string> [ <class> ] {
|
||||
max-transfer-idle-out <integer>;
|
||||
max-transfer-time-in <integer>;
|
||||
max-transfer-time-out <integer>;
|
||||
max-types-per-name <integer>;
|
||||
max-udp-size <integer>;
|
||||
max-validation-failures-per-fetch <integer>; // experimental
|
||||
max-validations-per-fetch <integer>; // experimental
|
||||
|
@ -37,8 +37,10 @@ zone <string> [ <class> ] {
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-records <integer>;
|
||||
max-records-per-type <integer>;
|
||||
max-transfer-idle-out <integer>;
|
||||
max-transfer-time-out <integer>;
|
||||
max-types-per-name <integer>;
|
||||
max-zone-ttl ( unlimited | <duration> ); // deprecated
|
||||
notify ( explicit | master-only | primary-only | <boolean> );
|
||||
notify-delay <integer>;
|
||||
|
@ -7,6 +7,8 @@ zone <string> [ <class> ] {
|
||||
masterfile-format ( raw | text );
|
||||
masterfile-style ( full | relative );
|
||||
max-records <integer>;
|
||||
max-records-per-type <integer>;
|
||||
max-types-per-name <integer>;
|
||||
max-zone-ttl ( unlimited | <duration> ); // deprecated
|
||||
primaries [ port <integer> ] [ source ( <ipv4_address> | * ) ] [ source-v6 ( <ipv6_address> | * ) ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||
zone-statistics ( full | terse | none | <boolean> );
|
||||
|
@ -28,12 +28,14 @@ zone <string> [ <class> ] {
|
||||
max-ixfr-ratio ( unlimited | <percentage> );
|
||||
max-journal-size ( default | unlimited | <sizeval> );
|
||||
max-records <integer>;
|
||||
max-records-per-type <integer>;
|
||||
max-refresh-time <integer>;
|
||||
max-retry-time <integer>;
|
||||
max-transfer-idle-in <integer>;
|
||||
max-transfer-idle-out <integer>;
|
||||
max-transfer-time-in <integer>;
|
||||
max-transfer-time-out <integer>;
|
||||
max-types-per-name <integer>;
|
||||
min-refresh-time <integer>;
|
||||
min-retry-time <integer>;
|
||||
multi-master <boolean>;
|
||||
|
@ -5,6 +5,8 @@ zone <string> [ <class> ] {
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
max-records <integer>;
|
||||
max-records-per-type <integer>;
|
||||
max-types-per-name <integer>;
|
||||
server-addresses { ( <ipv4_address> | <ipv6_address> ); ... };
|
||||
server-names { <string>; ... };
|
||||
zone-statistics ( full | terse | none | <boolean> );
|
||||
|
@ -11,10 +11,12 @@ zone <string> [ <class> ] {
|
||||
masterfile-format ( raw | text );
|
||||
masterfile-style ( full | relative );
|
||||
max-records <integer>;
|
||||
max-records-per-type <integer>;
|
||||
max-refresh-time <integer>;
|
||||
max-retry-time <integer>;
|
||||
max-transfer-idle-in <integer>;
|
||||
max-transfer-time-in <integer>;
|
||||
max-types-per-name <integer>;
|
||||
min-refresh-time <integer>;
|
||||
min-retry-time <integer>;
|
||||
multi-master <boolean>;
|
||||
|
@ -19,6 +19,21 @@ Security Fixes
|
||||
responses can cause server to respond slowly or not respond at all for other
|
||||
clients. :cve:`2024-0760` :gl:`#4481`
|
||||
|
||||
- Excessively large resource record sets can be crafted to slow down
|
||||
database processing. This has been addressed by adding a configurable
|
||||
limit to the number of records that can be stored per name and type in
|
||||
a cache or zone database. The default is 100, but it can be tuned with
|
||||
the new ``max-records-per-type`` option. :gl:`#497` :gl:`#3405`
|
||||
|
||||
An excessively large number of resource record types for a single owner name can
|
||||
be crafted to slow down database processing. This has been addressed by adding
|
||||
a configurable limit to the number of records that can be stored per name and
|
||||
type in a cache or zone database. The default is 100, and can be tuned with
|
||||
the new ``max-rrtypes-per-name`` option. :cve:`2024-1737` :gl:`#3403`
|
||||
|
||||
ISC would like to thank Toshifumi Sakaguchi who independently discovered
|
||||
and responsibly reported the issue to ISC. :gl:`#4548`
|
||||
|
||||
New Features
|
||||
~~~~~~~~~~~~
|
||||
|
||||
|
@ -80,6 +80,8 @@ struct dns_cache {
|
||||
dns_ttl_t serve_stale_ttl;
|
||||
dns_ttl_t serve_stale_refresh;
|
||||
isc_stats_t *stats;
|
||||
uint32_t maxrrperset;
|
||||
uint32_t maxtypepername;
|
||||
};
|
||||
|
||||
/***
|
||||
@ -128,6 +130,8 @@ cache_create_db(dns_cache_t *cache, dns_db_t **dbp, isc_mem_t **tmctxp,
|
||||
|
||||
dns_db_setservestalettl(db, cache->serve_stale_ttl);
|
||||
dns_db_setservestalerefresh(db, cache->serve_stale_refresh);
|
||||
dns_db_setmaxrrperset(db, cache->maxrrperset);
|
||||
dns_db_setmaxtypepername(db, cache->maxtypepername);
|
||||
|
||||
/*
|
||||
* XXX this is only used by the RBT cache, and can
|
||||
@ -546,6 +550,26 @@ dns_cache_updatestats(dns_cache_t *cache, isc_result_t result) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_cache_setmaxrrperset(dns_cache_t *cache, uint32_t value) {
|
||||
REQUIRE(VALID_CACHE(cache));
|
||||
|
||||
cache->maxrrperset = value;
|
||||
if (cache->db != NULL) {
|
||||
dns_db_setmaxrrperset(cache->db, value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_cache_setmaxtypepername(dns_cache_t *cache, uint32_t value) {
|
||||
REQUIRE(VALID_CACHE(cache));
|
||||
|
||||
cache->maxtypepername = value;
|
||||
if (cache->db != NULL) {
|
||||
dns_db_setmaxtypepername(cache->db, value);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: Much of the following code has been copied in from statschannel.c.
|
||||
* We should refactor this into a generic function in stats.c that can be
|
||||
|
18
lib/dns/db.c
18
lib/dns/db.c
@ -1170,3 +1170,21 @@ dns_db_nodefullname(dns_db_t *db, dns_dbnode_t *node, dns_name_t *name) {
|
||||
}
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
void
|
||||
dns_db_setmaxrrperset(dns_db_t *db, uint32_t value) {
|
||||
REQUIRE(DNS_DB_VALID(db));
|
||||
|
||||
if (db->methods->setmaxrrperset != NULL) {
|
||||
(db->methods->setmaxrrperset)(db, value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_db_setmaxtypepername(dns_db_t *db, uint32_t value) {
|
||||
REQUIRE(DNS_DB_VALID(db));
|
||||
|
||||
if (db->methods->setmaxtypepername != NULL) {
|
||||
(db->methods->setmaxtypepername)(db, value);
|
||||
}
|
||||
}
|
||||
|
@ -246,6 +246,18 @@ dns_cache_updatestats(dns_cache_t *cache, isc_result_t result);
|
||||
* Update cache statistics based on result code in 'result'
|
||||
*/
|
||||
|
||||
void
|
||||
dns_cache_setmaxrrperset(dns_cache_t *cache, uint32_t value);
|
||||
/*%<
|
||||
* Set the maximum resource records per RRSet that can be cached.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_cache_setmaxtypepername(dns_cache_t *cache, uint32_t value);
|
||||
/*%<
|
||||
* Set the maximum resource record types per owner name that can be cached.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_LIBXML2
|
||||
int
|
||||
dns_cache_renderxml(dns_cache_t *cache, void *writer0);
|
||||
|
@ -183,6 +183,8 @@ typedef struct dns_dbmethods {
|
||||
void (*deletedata)(dns_db_t *db, dns_dbnode_t *node, void *data);
|
||||
isc_result_t (*nodefullname)(dns_db_t *db, dns_dbnode_t *node,
|
||||
dns_name_t *name);
|
||||
void (*setmaxrrperset)(dns_db_t *db, uint32_t value);
|
||||
void (*setmaxtypepername)(dns_db_t *db, uint32_t value);
|
||||
} dns_dbmethods_t;
|
||||
|
||||
typedef isc_result_t (*dns_dbcreatefunc_t)(isc_mem_t *mctx,
|
||||
@ -1800,4 +1802,23 @@ dns_db_nodefullname(dns_db_t *db, dns_dbnode_t *node, dns_name_t *name);
|
||||
* \li 'db' is a valid database
|
||||
* \li 'node' and 'name' are not NULL
|
||||
*/
|
||||
|
||||
void
|
||||
dns_db_setmaxrrperset(dns_db_t *db, uint32_t value);
|
||||
/*%<
|
||||
* Set the maximum permissible number of RRs per RRset.
|
||||
*
|
||||
* If 'value' is nonzero, then any subsequent attempt to add an rdataset
|
||||
* with more than 'value' RRs will return ISC_R_TOOMANYRECORDS.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_db_setmaxtypepername(dns_db_t *db, uint32_t value);
|
||||
/*%<
|
||||
* Set the maximum permissible number of RR types per owner name.
|
||||
*
|
||||
* If 'value' is nonzero, and if there are already 'value' RR types
|
||||
* stored at a given node, then any subsequent attempt to add an rdataset
|
||||
* with a new RR type will return ISC_R_TOOMANYRECORDS.
|
||||
*/
|
||||
ISC_LANG_ENDDECLS
|
||||
|
@ -169,7 +169,8 @@ extern dns_rdatasetmethods_t dns_rdataslab_rdatasetmethods;
|
||||
|
||||
isc_result_t
|
||||
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
|
||||
isc_region_t *region, unsigned int reservelen);
|
||||
isc_region_t *region, unsigned int reservelen,
|
||||
uint32_t limit);
|
||||
/*%<
|
||||
* Slabify a rdataset. The slab area will be allocated and returned
|
||||
* in 'region'.
|
||||
@ -225,7 +226,8 @@ isc_result_t
|
||||
dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
||||
unsigned int reservelen, isc_mem_t *mctx,
|
||||
dns_rdataclass_t rdclass, dns_rdatatype_t type,
|
||||
unsigned int flags, unsigned char **tslabp);
|
||||
unsigned int flags, uint32_t maxrrperset,
|
||||
unsigned char **tslabp);
|
||||
/*%<
|
||||
* Merge 'oslab' and 'nslab'.
|
||||
*/
|
||||
|
@ -183,6 +183,8 @@ struct dns_view {
|
||||
uint32_t fail_ttl;
|
||||
dns_badcache_t *failcache;
|
||||
unsigned int udpsize;
|
||||
uint32_t maxrrperset;
|
||||
uint32_t maxtypepername;
|
||||
|
||||
/*
|
||||
* Configurable data for server use only,
|
||||
@ -1242,6 +1244,18 @@ dns_view_getresolver(dns_view_t *view, dns_resolver_t **resolverp);
|
||||
* Return the resolver associated with the view.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_setmaxrrperset(dns_view_t *view, uint32_t value);
|
||||
/*%<
|
||||
* Set the maximum resource records per RRSet that can be cached.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_setmaxtypepername(dns_view_t *view, uint32_t value);
|
||||
/*%<
|
||||
* Set the maximum resource record types per owner name that can be cached.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_view_setudpsize(dns_view_t *view, uint16_t udpsize);
|
||||
/*%<
|
||||
|
@ -366,6 +366,32 @@ dns_zone_getmaxrecords(dns_zone_t *zone);
|
||||
*\li uint32_t maxrecords.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t maxrrperset);
|
||||
/*%<
|
||||
* Sets the maximum number of records per rrset permitted in a zone.
|
||||
* 0 implies unlimited.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'zone' to be valid initialised zone.
|
||||
*
|
||||
* Returns:
|
||||
*\li void
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setmaxtypepername(dns_zone_t *zone, uint32_t maxtypepername);
|
||||
/*%<
|
||||
* Sets the maximum number of resource record types per owner name
|
||||
* permitted in a zone. 0 implies unlimited.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'zone' to be valid initialised zone.
|
||||
*
|
||||
* Returns:
|
||||
*\li void
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setmaxttl(dns_zone_t *zone, uint32_t maxttl);
|
||||
/*%<
|
||||
|
@ -217,6 +217,9 @@ struct qpcache {
|
||||
/* Locked by lock. */
|
||||
unsigned int active;
|
||||
|
||||
uint32_t maxrrperset; /* Maximum RRs per RRset */
|
||||
uint32_t maxtypepername; /* Maximum number of RR types per owner */
|
||||
|
||||
/*
|
||||
* The time after a failed lookup, where stale answers from cache
|
||||
* may be used directly in a DNS response without attempting a
|
||||
@ -2883,6 +2886,7 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode,
|
||||
dns_typepair_t negtype = 0, sigtype;
|
||||
dns_trust_t trust;
|
||||
int idx;
|
||||
uint32_t ntypes;
|
||||
|
||||
if ((options & DNS_DBADD_FORCE) != 0) {
|
||||
trust = dns_trust_ultimate;
|
||||
@ -2915,6 +2919,7 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode,
|
||||
{
|
||||
mark_ancient(topheader);
|
||||
}
|
||||
ntypes = 0; /* Always add the negative entry */
|
||||
goto find_header;
|
||||
}
|
||||
/*
|
||||
@ -2938,9 +2943,11 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode,
|
||||
* check for an extant non-ancient NODATA ncache
|
||||
* entry which covers the same type as the RRSIG.
|
||||
*/
|
||||
ntypes = 0;
|
||||
for (topheader = qpnode->data; topheader != NULL;
|
||||
topheader = topheader->next)
|
||||
{
|
||||
++ntypes;
|
||||
if ((topheader->type == RDATATYPE_NCACHEANY) ||
|
||||
(newheader->type == sigtype &&
|
||||
topheader->type ==
|
||||
@ -2983,9 +2990,12 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode,
|
||||
}
|
||||
}
|
||||
|
||||
ntypes = 0;
|
||||
for (topheader = qpnode->data; topheader != NULL;
|
||||
topheader = topheader->next)
|
||||
{
|
||||
++ntypes;
|
||||
|
||||
if (prio_type(topheader->type)) {
|
||||
prioheader = topheader;
|
||||
}
|
||||
@ -3253,6 +3263,14 @@ find_header:
|
||||
/*
|
||||
* No rdatasets of the given type exist at the node.
|
||||
*/
|
||||
if (trust != dns_trust_ultimate &&
|
||||
qpdb->maxtypepername > 0 &&
|
||||
ntypes >= qpdb->maxtypepername)
|
||||
{
|
||||
dns_slabheader_destroy(&newheader);
|
||||
return (DNS_R_TOOMANYRECORDS);
|
||||
}
|
||||
|
||||
INSIST(newheader->down == NULL);
|
||||
|
||||
if (prio_type(newheader->type)) {
|
||||
@ -3280,7 +3298,7 @@ find_header:
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
addnoqname(isc_mem_t *mctx, dns_slabheader_t *newheader,
|
||||
addnoqname(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
|
||||
dns_rdataset_t *rdataset) {
|
||||
isc_result_t result;
|
||||
dns_slabheader_proof_t *noqname = NULL;
|
||||
@ -3291,12 +3309,12 @@ addnoqname(isc_mem_t *mctx, dns_slabheader_t *newheader,
|
||||
result = dns_rdataset_getnoqname(rdataset, &name, &neg, &negsig);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
result = dns_rdataslab_fromrdataset(&neg, mctx, &r1, 0);
|
||||
result = dns_rdataslab_fromrdataset(&neg, mctx, &r1, 0, maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = dns_rdataslab_fromrdataset(&negsig, mctx, &r2, 0);
|
||||
result = dns_rdataslab_fromrdataset(&negsig, mctx, &r2, 0, maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
@ -3319,7 +3337,7 @@ cleanup:
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
addclosest(isc_mem_t *mctx, dns_slabheader_t *newheader,
|
||||
addclosest(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
|
||||
dns_rdataset_t *rdataset) {
|
||||
isc_result_t result;
|
||||
dns_slabheader_proof_t *closest = NULL;
|
||||
@ -3330,12 +3348,12 @@ addclosest(isc_mem_t *mctx, dns_slabheader_t *newheader,
|
||||
result = dns_rdataset_getclosest(rdataset, &name, &neg, &negsig);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
result = dns_rdataslab_fromrdataset(&neg, mctx, &r1, 0);
|
||||
result = dns_rdataslab_fromrdataset(&neg, mctx, &r1, 0, maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = dns_rdataslab_fromrdataset(&negsig, mctx, &r2, 0);
|
||||
result = dns_rdataslab_fromrdataset(&negsig, mctx, &r2, 0, maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
@ -3386,7 +3404,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
}
|
||||
|
||||
result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx,
|
||||
®ion, sizeof(dns_slabheader_t));
|
||||
®ion, sizeof(dns_slabheader_t),
|
||||
qpdb->maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
@ -3423,14 +3442,16 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
DNS_SLABHEADER_SETATTR(newheader, DNS_SLABHEADERATTR_OPTOUT);
|
||||
}
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) {
|
||||
result = addnoqname(qpdb->common.mctx, newheader, rdataset);
|
||||
result = addnoqname(qpdb->common.mctx, newheader,
|
||||
qpdb->maxrrperset, rdataset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_slabheader_destroy(&newheader);
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0) {
|
||||
result = addclosest(qpdb->common.mctx, newheader, rdataset);
|
||||
result = addclosest(qpdb->common.mctx, newheader,
|
||||
qpdb->maxrrperset, rdataset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_slabheader_destroy(&newheader);
|
||||
return (result);
|
||||
@ -4330,6 +4351,24 @@ expire_ttl_headers(qpcache_t *qpdb, unsigned int locknum,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setmaxrrperset(dns_db_t *db, uint32_t value) {
|
||||
qpcache_t *qpdb = (qpcache_t *)db;
|
||||
|
||||
REQUIRE(VALID_QPDB(qpdb));
|
||||
|
||||
qpdb->maxrrperset = value;
|
||||
}
|
||||
|
||||
static void
|
||||
setmaxtypepername(dns_db_t *db, uint32_t value) {
|
||||
qpcache_t *qpdb = (qpcache_t *)db;
|
||||
|
||||
REQUIRE(VALID_QPDB(qpdb));
|
||||
|
||||
qpdb->maxtypepername = value;
|
||||
}
|
||||
|
||||
static dns_dbmethods_t qpdb_cachemethods = {
|
||||
.destroy = qpdb_destroy,
|
||||
.findnode = findnode,
|
||||
@ -4354,6 +4393,8 @@ static dns_dbmethods_t qpdb_cachemethods = {
|
||||
.unlocknode = unlocknode,
|
||||
.expiredata = expiredata,
|
||||
.deletedata = deletedata,
|
||||
.setmaxrrperset = setmaxrrperset,
|
||||
.setmaxtypepername = setmaxtypepername,
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -178,6 +178,8 @@ struct qpzonedb {
|
||||
uint32_t current_serial;
|
||||
uint32_t least_serial;
|
||||
uint32_t next_serial;
|
||||
uint32_t maxrrperset; /* Maximum RRs per RRset */
|
||||
uint32_t maxtypepername; /* Maximum number of RR types per owner */
|
||||
qpz_version_t *current_version;
|
||||
qpz_version_t *future_version;
|
||||
qpz_versionlist_t open_versions;
|
||||
@ -1833,6 +1835,7 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
|
||||
unsigned char *merged = NULL;
|
||||
isc_result_t result;
|
||||
bool merge = false;
|
||||
uint32_t ntypes;
|
||||
|
||||
if ((options & DNS_DBADD_MERGE) != 0) {
|
||||
REQUIRE(version != NULL);
|
||||
@ -1848,9 +1851,11 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
|
||||
changed = add_changed(newheader, version DNS__DB_FLARG_PASS);
|
||||
}
|
||||
|
||||
ntypes = 0;
|
||||
for (topheader = node->data; topheader != NULL;
|
||||
topheader = topheader->next)
|
||||
{
|
||||
++ntypes;
|
||||
if (prio_type(topheader->type)) {
|
||||
prioheader = topheader;
|
||||
}
|
||||
@ -1898,7 +1903,7 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
|
||||
(unsigned int)(sizeof(*newheader)),
|
||||
qpdb->common.mctx, qpdb->common.rdclass,
|
||||
(dns_rdatatype_t)header->type, flags,
|
||||
&merged);
|
||||
qpdb->maxrrperset, &merged);
|
||||
}
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
@ -2017,6 +2022,14 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
|
||||
/*
|
||||
* No rdatasets of the given type exist at the node.
|
||||
*/
|
||||
|
||||
if (qpdb->maxtypepername > 0 &&
|
||||
ntypes >= qpdb->maxtypepername)
|
||||
{
|
||||
dns_slabheader_destroy(&newheader);
|
||||
return (DNS_R_TOOMANYRECORDS);
|
||||
}
|
||||
|
||||
INSIST(newheader->down == NULL);
|
||||
|
||||
if (prio_type(newheader->type)) {
|
||||
@ -2147,7 +2160,8 @@ loading_addrdataset(void *arg, const dns_name_t *name,
|
||||
|
||||
loading_addnode(loadctx, name, rdataset->type, rdataset->covers, &node);
|
||||
result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx,
|
||||
®ion, sizeof(dns_slabheader_t));
|
||||
®ion, sizeof(dns_slabheader_t),
|
||||
qpdb->maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
@ -4648,7 +4662,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *dbnode, dns_dbversion_t *dbversion,
|
||||
rdataset->covers != dns_rdatatype_nsec3)));
|
||||
|
||||
result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx,
|
||||
®ion, sizeof(dns_slabheader_t));
|
||||
®ion, sizeof(dns_slabheader_t),
|
||||
qpdb->maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
@ -4767,7 +4782,8 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode, dns_dbversion_t *dbversion,
|
||||
|
||||
dns_name_copy(&node->name, nodename);
|
||||
result = dns_rdataslab_fromrdataset(rdataset, qpdb->common.mctx,
|
||||
®ion, sizeof(dns_slabheader_t));
|
||||
®ion, sizeof(dns_slabheader_t),
|
||||
0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
@ -5277,6 +5293,24 @@ addglue(dns_db_t *db, dns_dbversion_t *dbversion, dns_rdataset_t *rdataset,
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
setmaxrrperset(dns_db_t *db, uint32_t value) {
|
||||
qpzonedb_t *qpdb = (qpzonedb_t *)db;
|
||||
|
||||
REQUIRE(VALID_QPZONE(qpdb));
|
||||
|
||||
qpdb->maxrrperset = value;
|
||||
}
|
||||
|
||||
static void
|
||||
setmaxtypepername(dns_db_t *db, uint32_t value) {
|
||||
qpzonedb_t *qpdb = (qpzonedb_t *)db;
|
||||
|
||||
REQUIRE(VALID_QPZONE(qpdb));
|
||||
|
||||
qpdb->maxtypepername = value;
|
||||
}
|
||||
|
||||
static dns_dbmethods_t qpdb_zonemethods = {
|
||||
.destroy = qpdb_destroy,
|
||||
.beginload = beginload,
|
||||
@ -5310,6 +5344,8 @@ static dns_dbmethods_t qpdb_zonemethods = {
|
||||
.addglue = addglue,
|
||||
.deletedata = deletedata,
|
||||
.nodefullname = nodefullname,
|
||||
.setmaxrrperset = setmaxrrperset,
|
||||
.setmaxtypepername = setmaxtypepername,
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -1582,6 +1582,8 @@ dns_dbmethods_t dns__rbtdb_cachemethods = {
|
||||
.unlocknode = dns__rbtdb_unlocknode,
|
||||
.expiredata = expiredata,
|
||||
.deletedata = dns__rbtdb_deletedata,
|
||||
.setmaxrrperset = dns__rbtdb_setmaxrrperset,
|
||||
.setmaxtypepername = dns__rbtdb_setmaxtypepername,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1749,7 +1749,8 @@ loading_addrdataset(void *arg, const dns_name_t *name,
|
||||
}
|
||||
|
||||
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
|
||||
®ion, sizeof(dns_slabheader_t));
|
||||
®ion, sizeof(dns_slabheader_t),
|
||||
rbtdb->maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
@ -2418,6 +2419,8 @@ dns_dbmethods_t dns__rbtdb_zonemethods = {
|
||||
.addglue = addglue,
|
||||
.deletedata = dns__rbtdb_deletedata,
|
||||
.nodefullname = dns__rbtdb_nodefullname,
|
||||
.setmaxrrperset = dns__rbtdb_setmaxrrperset,
|
||||
.setmaxtypepername = dns__rbtdb_setmaxtypepername,
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -2566,6 +2566,7 @@ dns__rbtdb_add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
|
||||
dns_typepair_t negtype = 0, sigtype;
|
||||
dns_trust_t trust;
|
||||
int idx;
|
||||
uint32_t ntypes = 0;
|
||||
|
||||
if ((options & DNS_DBADD_MERGE) != 0) {
|
||||
REQUIRE(rbtversion != NULL);
|
||||
@ -2618,6 +2619,7 @@ dns__rbtdb_add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
|
||||
{
|
||||
mark_ancient(topheader);
|
||||
}
|
||||
ntypes = 0; /* Always add the negative entry */
|
||||
goto find_header;
|
||||
}
|
||||
/*
|
||||
@ -2641,9 +2643,11 @@ dns__rbtdb_add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
|
||||
* check for an extant non-ancient NODATA ncache
|
||||
* entry which covers the same type as the RRSIG.
|
||||
*/
|
||||
ntypes = 0;
|
||||
for (topheader = rbtnode->data; topheader != NULL;
|
||||
topheader = topheader->next)
|
||||
{
|
||||
++ntypes;
|
||||
if ((topheader->type == RDATATYPE_NCACHEANY) ||
|
||||
(newheader->type == sigtype &&
|
||||
topheader->type ==
|
||||
@ -2686,9 +2690,11 @@ dns__rbtdb_add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
|
||||
}
|
||||
}
|
||||
|
||||
ntypes = 0;
|
||||
for (topheader = rbtnode->data; topheader != NULL;
|
||||
topheader = topheader->next)
|
||||
{
|
||||
++ntypes;
|
||||
if (prio_type(topheader->type)) {
|
||||
prioheader = topheader;
|
||||
}
|
||||
@ -2780,7 +2786,7 @@ find_header:
|
||||
rbtdb->common.mctx,
|
||||
rbtdb->common.rdclass,
|
||||
(dns_rdatatype_t)header->type, flags,
|
||||
&merged);
|
||||
rbtdb->maxrrperset, &merged);
|
||||
}
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
@ -3082,6 +3088,14 @@ find_header:
|
||||
/*
|
||||
* No rdatasets of the given type exist at the node.
|
||||
*/
|
||||
|
||||
if (rbtdb->maxtypepername > 0 &&
|
||||
ntypes >= rbtdb->maxtypepername)
|
||||
{
|
||||
dns_slabheader_destroy(&newheader);
|
||||
return (DNS_R_TOOMANYRECORDS);
|
||||
}
|
||||
|
||||
INSIST(newheader->down == NULL);
|
||||
|
||||
if (prio_type(newheader->type)) {
|
||||
@ -3141,7 +3155,7 @@ delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, dns_typepair_t type) {
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
addnoqname(isc_mem_t *mctx, dns_slabheader_t *newheader,
|
||||
addnoqname(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
|
||||
dns_rdataset_t *rdataset) {
|
||||
isc_result_t result;
|
||||
dns_slabheader_proof_t *noqname = NULL;
|
||||
@ -3152,12 +3166,12 @@ addnoqname(isc_mem_t *mctx, dns_slabheader_t *newheader,
|
||||
result = dns_rdataset_getnoqname(rdataset, &name, &neg, &negsig);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
result = dns_rdataslab_fromrdataset(&neg, mctx, &r1, 0);
|
||||
result = dns_rdataslab_fromrdataset(&neg, mctx, &r1, 0, maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = dns_rdataslab_fromrdataset(&negsig, mctx, &r2, 0);
|
||||
result = dns_rdataslab_fromrdataset(&negsig, mctx, &r2, 0, maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
@ -3180,7 +3194,7 @@ cleanup:
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
addclosest(isc_mem_t *mctx, dns_slabheader_t *newheader,
|
||||
addclosest(isc_mem_t *mctx, dns_slabheader_t *newheader, uint32_t maxrrperset,
|
||||
dns_rdataset_t *rdataset) {
|
||||
isc_result_t result;
|
||||
dns_slabheader_proof_t *closest = NULL;
|
||||
@ -3191,12 +3205,12 @@ addclosest(isc_mem_t *mctx, dns_slabheader_t *newheader,
|
||||
result = dns_rdataset_getclosest(rdataset, &name, &neg, &negsig);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
|
||||
result = dns_rdataslab_fromrdataset(&neg, mctx, &r1, 0);
|
||||
result = dns_rdataslab_fromrdataset(&neg, mctx, &r1, 0, maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = dns_rdataslab_fromrdataset(&negsig, mctx, &r2, 0);
|
||||
result = dns_rdataslab_fromrdataset(&negsig, mctx, &r2, 0, maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
@ -3272,7 +3286,8 @@ dns__rbtdb_addrdataset(dns_db_t *db, dns_dbnode_t *node,
|
||||
}
|
||||
|
||||
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
|
||||
®ion, sizeof(dns_slabheader_t));
|
||||
®ion, sizeof(dns_slabheader_t),
|
||||
rbtdb->maxrrperset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
@ -3329,7 +3344,7 @@ dns__rbtdb_addrdataset(dns_db_t *db, dns_dbnode_t *node,
|
||||
}
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) {
|
||||
result = addnoqname(rbtdb->common.mctx, newheader,
|
||||
rdataset);
|
||||
rbtdb->maxrrperset, rdataset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_slabheader_destroy(&newheader);
|
||||
return (result);
|
||||
@ -3337,7 +3352,7 @@ dns__rbtdb_addrdataset(dns_db_t *db, dns_dbnode_t *node,
|
||||
}
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0) {
|
||||
result = addclosest(rbtdb->common.mctx, newheader,
|
||||
rdataset);
|
||||
rbtdb->maxrrperset, rdataset);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
dns_slabheader_destroy(&newheader);
|
||||
return (result);
|
||||
@ -3487,7 +3502,8 @@ dns__rbtdb_subtractrdataset(dns_db_t *db, dns_dbnode_t *node,
|
||||
dns__rbtdb_nodefullname(db, node, nodename);
|
||||
|
||||
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
|
||||
®ion, sizeof(dns_slabheader_t));
|
||||
®ion, sizeof(dns_slabheader_t),
|
||||
0);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
@ -4957,3 +4973,21 @@ expire_ttl_headers(dns_rbtdb_t *rbtdb, unsigned int locknum,
|
||||
dns_expire_ttl DNS__DB_FLARG_PASS);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns__rbtdb_setmaxrrperset(dns_db_t *db, uint32_t value) {
|
||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
|
||||
rbtdb->maxrrperset = value;
|
||||
}
|
||||
|
||||
void
|
||||
dns__rbtdb_setmaxtypepername(dns_db_t *db, uint32_t maxtypepername) {
|
||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
|
||||
rbtdb->maxtypepername = maxtypepername;
|
||||
}
|
||||
|
@ -114,6 +114,8 @@ struct dns_rbtdb {
|
||||
uint32_t current_serial;
|
||||
uint32_t least_serial;
|
||||
uint32_t next_serial;
|
||||
uint32_t maxrrperset;
|
||||
uint32_t maxtypepername;
|
||||
dns_rbtdb_version_t *current_version;
|
||||
dns_rbtdb_version_t *future_version;
|
||||
rbtdb_versionlist_t open_versions;
|
||||
@ -427,6 +429,18 @@ dns__rbtdb_setttl(dns_slabheader_t *header, dns_ttl_t newttl);
|
||||
* also update the TTL heap accordingly.
|
||||
*/
|
||||
|
||||
void
|
||||
dns__rbtdb_setmaxrrperset(dns_db_t *db, uint32_t maxrrperset);
|
||||
/*%<
|
||||
* Set the max RRs per RRset limit.
|
||||
*/
|
||||
|
||||
void
|
||||
dns__rbtdb_setmaxtypepername(dns_db_t *db, uint32_t maxtypepername);
|
||||
/*%<
|
||||
* Set the max RRs per RRset limit.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Functions specific to zone databases that are also called from rbtdb.c.
|
||||
*/
|
||||
|
@ -168,7 +168,8 @@ fillin_offsets(unsigned char *offsetbase, unsigned int *offsettable,
|
||||
|
||||
isc_result_t
|
||||
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
|
||||
isc_region_t *region, unsigned int reservelen) {
|
||||
isc_region_t *region, unsigned int reservelen,
|
||||
uint32_t maxrrperset) {
|
||||
/*
|
||||
* Use &removed as a sentinel pointer for duplicate
|
||||
* rdata as rdata.data == NULL is valid.
|
||||
@ -208,6 +209,10 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
if (maxrrperset > 0 && nitems > maxrrperset) {
|
||||
return (DNS_R_TOOMANYRECORDS);
|
||||
}
|
||||
|
||||
if (nitems > 0xffff) {
|
||||
return (ISC_R_NOSPACE);
|
||||
}
|
||||
@ -515,7 +520,8 @@ isc_result_t
|
||||
dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
||||
unsigned int reservelen, isc_mem_t *mctx,
|
||||
dns_rdataclass_t rdclass, dns_rdatatype_t type,
|
||||
unsigned int flags, unsigned char **tslabp) {
|
||||
unsigned int flags, uint32_t maxrrperset,
|
||||
unsigned char **tslabp) {
|
||||
unsigned char *ocurrent = NULL, *ostart = NULL, *ncurrent = NULL;
|
||||
unsigned char *tstart = NULL, *tcurrent = NULL, *data = NULL;
|
||||
unsigned int ocount, ncount, count, olength, tlength, tcount, length;
|
||||
@ -554,6 +560,10 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
||||
#endif /* if DNS_RDATASET_FIXED */
|
||||
INSIST(ocount > 0 && ncount > 0);
|
||||
|
||||
if (maxrrperset > 0 && ocount + ncount > maxrrperset) {
|
||||
return (DNS_R_TOOMANYRECORDS);
|
||||
}
|
||||
|
||||
#if DNS_RDATASET_FIXED
|
||||
oncount = ncount;
|
||||
#endif /* if DNS_RDATASET_FIXED */
|
||||
|
@ -643,6 +643,9 @@ dns_view_setcache(dns_view_t *view, dns_cache_t *cache, bool shared) {
|
||||
dns_cache_attach(cache, &view->cache);
|
||||
dns_cache_attachdb(cache, &view->cachedb);
|
||||
INSIST(DNS_DB_VALID(view->cachedb));
|
||||
|
||||
dns_cache_setmaxrrperset(view->cache, view->maxrrperset);
|
||||
dns_cache_setmaxtypepername(view->cache, view->maxtypepername);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -2336,6 +2339,24 @@ dns_view_getresolver(dns_view_t *view, dns_resolver_t **resolverp) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_setmaxrrperset(dns_view_t *view, uint32_t value) {
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
view->maxrrperset = value;
|
||||
if (view->cache != NULL) {
|
||||
dns_cache_setmaxrrperset(view->cache, value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_setmaxtypepername(dns_view_t *view, uint32_t value) {
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
view->maxtypepername = value;
|
||||
if (view->cache != NULL) {
|
||||
dns_cache_setmaxtypepername(view->cache, value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_view_setudpsize(dns_view_t *view, uint16_t udpsize) {
|
||||
REQUIRE(DNS_VIEW_VALID(view));
|
||||
|
@ -318,6 +318,8 @@ struct dns_zone {
|
||||
uint32_t minretry;
|
||||
|
||||
uint32_t maxrecords;
|
||||
uint32_t maxrrperset;
|
||||
uint32_t maxtypepername;
|
||||
|
||||
dns_remote_t primaries;
|
||||
|
||||
@ -9741,6 +9743,7 @@ cleanup:
|
||||
}
|
||||
|
||||
dns_diff_clear(&_sig_diff);
|
||||
dns_diff_clear(&post_diff);
|
||||
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
dst_key_free(&zone_keys[i]);
|
||||
@ -12057,6 +12060,26 @@ dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
|
||||
zone->maxrecords = val;
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t val) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
zone->maxrrperset = val;
|
||||
if (zone->db != NULL) {
|
||||
dns_db_setmaxrrperset(zone->db, val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dns_zone_setmaxtypepername(dns_zone_t *zone, uint32_t val) {
|
||||
REQUIRE(DNS_ZONE_VALID(zone));
|
||||
|
||||
zone->maxtypepername = val;
|
||||
if (zone->db != NULL) {
|
||||
dns_db_setmaxtypepername(zone->db, val);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
|
||||
isc_sockaddr_t *addr, dns_tsigkey_t *key,
|
||||
@ -14458,6 +14481,9 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
|
||||
goto cleanup;
|
||||
}
|
||||
dns_db_setloop(stub->db, zone->loop);
|
||||
dns_db_setmaxrrperset(stub->db, zone->maxrrperset);
|
||||
dns_db_setmaxtypepername(stub->db,
|
||||
zone->maxtypepername);
|
||||
}
|
||||
|
||||
result = dns_db_newversion(stub->db, &stub->version);
|
||||
@ -17514,6 +17540,8 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
|
||||
}
|
||||
zone_attachdb(zone, db);
|
||||
dns_db_setloop(zone->db, zone->loop);
|
||||
dns_db_setmaxrrperset(zone->db, zone->maxrrperset);
|
||||
dns_db_setmaxtypepername(zone->db, zone->maxtypepername);
|
||||
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
@ -22470,7 +22498,11 @@ failure:
|
||||
* Something went wrong; try again in ten minutes or
|
||||
* after a key refresh interval, whichever is shorter.
|
||||
*/
|
||||
dnssec_log(zone, ISC_LOG_DEBUG(3),
|
||||
int loglevel = ISC_LOG_DEBUG(3);
|
||||
if (result != DNS_R_NOTLOADED) {
|
||||
loglevel = ISC_LOG_ERROR;
|
||||
}
|
||||
dnssec_log(zone, loglevel,
|
||||
"zone_rekey failure: %s (retry in %u seconds)",
|
||||
isc_result_totext(result),
|
||||
ISC_MIN(zone->refreshkeyinterval, 600));
|
||||
@ -24153,6 +24185,8 @@ dns_zone_makedb(dns_zone_t *zone, dns_db_t **dbp) {
|
||||
}
|
||||
|
||||
dns_db_setloop(db, zone->loop);
|
||||
dns_db_setmaxrrperset(db, zone->maxrrperset);
|
||||
dns_db_setmaxtypepername(db, zone->maxtypepername);
|
||||
|
||||
*dbp = db;
|
||||
|
||||
|
@ -2372,6 +2372,12 @@ static cfg_clausedef_t zone_clauses[] = {
|
||||
{ "max-records", &cfg_type_uint32,
|
||||
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
|
||||
CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
|
||||
{ "max-records-per-type", &cfg_type_uint32,
|
||||
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
|
||||
CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
|
||||
{ "max-types-per-name", &cfg_type_uint32,
|
||||
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
|
||||
CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
|
||||
{ "max-refresh-time", &cfg_type_uint32,
|
||||
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
|
||||
{ "max-retry-time", &cfg_type_uint32,
|
||||
|
@ -3160,9 +3160,18 @@ update_action(void *arg) {
|
||||
dns_diff_clear(&ctx.add_diff);
|
||||
goto failure;
|
||||
}
|
||||
CHECK(update_one_rr(db, ver, &diff,
|
||||
DNS_DIFFOP_ADD,
|
||||
name, ttl, &rdata));
|
||||
result = update_one_rr(
|
||||
db, ver, &diff, DNS_DIFFOP_ADD,
|
||||
name, ttl, &rdata);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, zone,
|
||||
LOGLEVEL_PROTOCOL,
|
||||
"adding an RR "
|
||||
"failed: %s",
|
||||
isc_result_totext(
|
||||
result));
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (update_class == dns_rdataclass_any) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user