Compare commits

..
Author SHA1 Message Date
Evan Hunt 6f289188a3 clean up flies in addzone system test
some generated files were not cleaned up after running the test.
2023-12-21 00:04:59 -08:00
54 changed files with 477 additions and 1255 deletions
-64
View File
@@ -1,63 +1,3 @@
--- 9.18.25 released ---
6356. [bug] Create the pruning task in the dns_cache_flush(), so
the cache pruning still works after the flush.
[GL #4621]
6353. [bug] Improve the TTL-based cleaning by removing the expired
headers from the heap, so they don't block the next
cleaning round and clean more than a single item for
each new addition to the RBTDB. [GL #4591]
6352. [bug] Revert change 6319 and decrease lock contention during
RBTDB tree pruning by not cleaning up nodes recursively
within a single prune_tree() call. [GL #4596]
6350. [bug] Address use after free in expire_lru_headers. [GL #4495]
--- 9.18.24 released ---
6343. [bug] Fix case insensitive setting for isc_ht hashtable.
[GL #4568]
--- 9.18.23 released ---
6322. [security] Specific DNS answers could cause a denial-of-service
condition due to DNS validation taking a long time.
(CVE-2023-50387) [GL #4424]
6321. [security] Change 6315 inadvertently introduced regressions that
could cause named to crash. [GL #4234]
6320. [bug] Under some circumstances, the DoT code in client
mode could process more than one message at a time when
that was not expected. That has been fixed. [GL #4487]
--- 9.18.22 released ---
6319. [func] Limit isc_task_send() overhead for RBTDB tree pruning.
[GL #4383]
6317. [security] Restore DNS64 state when handling a serve-stale timeout.
(CVE-2023-5679) [GL #4334]
6316. [security] Specific queries could trigger an assertion check with
nxdomain-redirect enabled. (CVE-2023-5517) [GL #4281]
6315. [security] Speed up parsing of DNS messages with many different
names. (CVE-2023-4408) [GL #4234]
6314. [bug] Address race conditions in dns_tsigkey_find().
[GL #4182]
6312. [bug] Conversion from NSEC3 signed to NSEC signed could
temporarily put the zone into a state where it was
treated as unsigned until the NSEC chain was built.
Additionally conversion from one set of NSEC3 parameters
to another could also temporarily put the zone into a
state where it was treated as unsigned until the new
NSEC3 chain was built. [GL #1794] [GL #4495]
6310. [bug] Memory leak in zone.c:sign_zone. When named signed a
zone it could leak dst_keys due to a misplaced
'continue'. [GL #4488]
@@ -74,10 +14,6 @@
message that was emitted even when the feature was
explicitly disabled. [GL #4497]
6300. [bug] Fix statistics export to use full 64 bit signed numbers
instead of truncating values to unsigned 32 bits.
[GL #4467]
6299. [port] NetBSD has added 'hmac' to libc which collides with our
use of 'hmac'. [GL #4478]
+3 -1
View File
@@ -39,6 +39,8 @@ rm -f ./ns1/redirect.db
rm -f ./ns2/redirect.db
rm -f ./ns2/redirect.bk
rm -f ./ns3/redirect.db
rm -f ./ns*/managed-keys.bind* ns*/*.mkeys*
rm -f ./ns*/managed-keys.bind* ./ns*/*.mkeys*
rm -f ./ns*/*.jnl
rm -f ./ns*/K*.key ./ns*/K*.private ./ns*/K*.state
rm -f ./nzd2nzf.out.*
rm -f ./wait_for_message.*
-8
View File
@@ -192,14 +192,6 @@ $KEYGEN -q -a $DEFAULT_ALGORITHM -fk $zone >kg.out 2>&1 || dumpit kg.out
$KEYGEN -q -a $DEFAULT_ALGORITHM $zone >kg.out 2>&1 || dumpit kg.out
$SIGNER -S -3 beef -A -o $zone -f $zonefile $infile >s.out || dumpit s.out
#
# NSEC3->NSEC3 transition test zone.
#
setup nsec3-to-nsec3.example
$KEYGEN -q -a $DEFAULT_ALGORITHM -fk $zone >kg.out 2>&1 || dumpit kg.out
$KEYGEN -q -a $DEFAULT_ALGORITHM $zone >kg.out 2>&1 || dumpit kg.out
$SIGNER -S -3 beef -A -o $zone -f $zonefile $infile >s.out || dumpit s.out
#
# secure-to-insecure transition test zone; used to test removal of
# keys via nsupdate
@@ -186,14 +186,6 @@ zone "secure-to-insecure2.example" {
dnssec-secure-to-insecure yes;
};
zone "nsec3-to-nsec3.example" {
type primary;
file "nsec3-to-nsec3.example.db";
allow-update { any; };
inline-signing no;
max-journal-size 10M;
};
zone "oldsigs.example" {
type primary;
file "oldsigs.example.db";
@@ -1,26 +0,0 @@
; 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 ; 5 minutes
@ IN SOA mname1. . (
2009102722 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns
ns A 10.53.0.3
a A 10.0.0.1
b A 10.0.0.2
d A 10.0.0.4
x CNAME a
+1 -32
View File
@@ -177,9 +177,6 @@ status=$((status + ret))
echo_i "Convert optout-with-ent from nsec to nsec3"
($RNDCCMD 10.53.0.2 signing -nsec3param 1 1 1 - optout-with-ent 2>&1 | sed 's/^/ns2 /' | cat_i) || ret=1
echo_i "Convert nsec3-to-nsec3.example from having salt 'beef' to no salt"
($RNDCCMD 10.53.0.3 signing -nsec3param 1 1 1 - nsec3-to-nsec3.example 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1
echo_i "Initial counts of RRSIG expiry fields values for auto signed zones"
for z in .; do
echo_i zone $z
@@ -1183,8 +1180,7 @@ checkprivate private.secure.example 10.53.0.3 2 || ret=1 # pre-signed
checkprivate nsec3.example 10.53.0.3 || ret=1
checkprivate nsec3.nsec3.example 10.53.0.3 || ret=1
checkprivate nsec3.optout.example 10.53.0.3 || ret=1
checkprivate nsec3-to-nsec.example 10.53.0.3 2 || ret=1 # automatically removed
checkprivate nsec3-to-nsec3.example 10.53.0.3 2 || ret=1 # automatically removed
checkprivate nsec3-to-nsec.example 10.53.0.3 2 || ret=1 # automatically removed
if $SHELL ../testcrypto.sh -q RSASHA1; then
checkprivate nsec-only.example 10.53.0.3 || ret=1
fi
@@ -1810,32 +1806,5 @@ n=$((n + 1))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "check that NSEC3 to NSEC builds the NSEC chain first ($n)"
ret=0
$JOURNALPRINT ns3/nsec3-to-nsec.example.db.jnl \
| awk 'BEGIN { nsec3param=0; nsec=0 }
$1 == "del" && $5 == "SOA" { if (nsec3param || nsec) { if (nsec3param && !nsec) { exit(1); } else { exit(0); } } }
$1 == "del" && $5 == "NSEC3PARAM" { nsec3param=1 }
$1 == "add" && $2 == "nsec3-to-nsec.example." && $5 == "NSEC" { nsec=1 }
END { if (nsec3param || nsec) { if (nsec3param && !nsec) { exit(1); } else { exit(0); } } else { exit(1); } }
' || ret=1
n=$((n + 1))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "check that NSEC3 to NSEC3 builds the new NSEC3 chain first ($n)"
ret=0
$JOURNALPRINT ns3/nsec3-to-nsec3.example.db.jnl \
| awk 'BEGIN { addnsec3param=0; delnsec3param=0; nsec3=0 }
$1 == "del" && $5 == "SOA" { if (delnsec3param || nsec3 || addnsec3param) { if (delnsec3param && (!nsec3 || !addnsec3param)) { exit(1); } else { exit(0); } } }
$1 == "del" && $5 == "NSEC3PARAM" { delnsec3param=1 }
$1 == "add" && $5 == "NSEC3PARAM" { addnsec3param=1 }
$1 == "add" && $5 == "NSEC3" { nsec3=1 }
END { if (delnsec3param || nsec3 || addnsec3param) { if (delnsec3param && (!nsec3 || !addnsec3param)) { exit(1); } else { exit(0); } } else { exit(1); } }
' || ret=1
n=$((n + 1))
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
+2 -14
View File
@@ -22,14 +22,9 @@ my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!";
print $pidf "$$\n" or die "cannot write pid file: $!";
$pidf->close or die "cannot close pid file: $!";
sub rmpid { unlink "ans.pid"; exit 1; };
sub term { };
$SIG{INT} = \&rmpid;
if ($Net::DNS::VERSION > 1.41) {
$SIG{TERM} = \&term;
} else {
$SIG{TERM} = \&rmpid;
}
$SIG{TERM} = \&rmpid;
my $localaddr = "10.53.0.3";
@@ -133,11 +128,4 @@ my $ns = Net::DNS::Nameserver->new(
Verbose => $verbose,
);
if ($Net::DNS::VERSION >= 1.42) {
$ns->start_server();
select(undef, undef, undef, undef);
$ns->stop_server();
unlink "ans.pid";
} else {
$ns->main_loop;
}
$ns->main_loop;
@@ -47,8 +47,3 @@ rrsigonly A 10.0.0.29
cnameandkey CNAME @
cnamenokey CNAME @
dnameandkey DNAME @
mixedcase A 10.0.0.30
mixedCASE TXT "mixed case"
MIXEDcase AAAA 2002::
mIxEdCaSe LOC 37 52 56.788 N 121 54 55.02 W 1120m 10m 100m 10m
+1 -3
View File
@@ -87,9 +87,7 @@ keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone
cat "$infile" "$cnameandkey.key" "$dnameandkey.key" "$keyname.key" >"$zonefile"
"$SIGNER" -z -D -o "$zone" "$zonefile" >/dev/null
cat "$zonefile" "$zonefile".signed >"$zonefile".tmp
mv "$zonefile".tmp "$zonefile".signed
"$SIGNER" -z -o "$zone" "$zonefile" >/dev/null
zone=bogus.example.
infile=bogus.example.db.in
+2 -17
View File
@@ -766,21 +766,6 @@ n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_i "checking mixed-case positive validation ($n)"
ret=0
for type in a txt aaaa loc; do
dig_with_opts +noauth mixedcase.secure.example. \
@10.53.0.3 $type >dig.out.$type.ns3.test$n || ret=1
dig_with_opts +noauth mixedcase.secure.example. \
@10.53.0.4 $type >dig.out.$type.ns4.test$n || ret=1
digcomp --lc dig.out.$type.ns3.test$n dig.out.$type.ns4.test$n || ret=1
grep "status: NOERROR" dig.out.$type.ns4.test$n >/dev/null || ret=1
grep "flags:.*ad.*QUERY" dig.out.$type.ns4.test$n >/dev/null || ret=1
done
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_i "checking multi-stage positive validation NSEC/NSEC3 ($n)"
ret=0
dig_with_opts +noauth a.nsec3.example. \
@@ -2735,7 +2720,7 @@ rndccmd 10.53.0.3 signing -nsec3param 1 0 0 auto inline.example >/dev/null 2>&1
rndccmd 10.53.0.3 status >/dev/null || ret=1
for i in 1 2 3 4 5 6 7 8 9 10; do
salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}')
[ "$salt" != "-" ] && [ "${#salt}" -eq 16 ] && break
[ -n "$salt" ] && [ "$salt" != "-" ] && break
echo_i "sleeping ...."
sleep 1
done
@@ -2752,7 +2737,7 @@ rndccmd 10.53.0.3 signing -nsec3param 1 0 0 auto inline.example >/dev/null 2>&1
rndccmd 10.53.0.3 status >/dev/null || ret=1
for i in 1 2 3 4 5 6 7 8 9 10; do
salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}')
[ "$salt" != "$oldsalt" ] && [ "${#salt}" -eq 16 ] && break
[ -n "$salt" ] && [ "$salt" != "$oldsalt" ] && break
echo_i "sleeping ...."
sleep 1
done
+2 -2
View File
@@ -420,12 +420,12 @@ overmem(dns_db_t *db, bool over) {
}
static void
settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
settask(dns_db_t *db, isc_task_t *task) {
sampledb_t *sampledb = (sampledb_t *)db;
REQUIRE(VALID_SAMPLEDB(sampledb));
dns_db_settask(sampledb->rbtdb, task, prunetask);
dns_db_settask(sampledb->rbtdb, task);
}
static isc_result_t
+2 -14
View File
@@ -22,14 +22,9 @@ my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!";
print $pidf "$$\n" or die "cannot write pid file: $!";
$pidf->close or die "cannot close pid file: $!";
sub rmpid { unlink "ans.pid"; exit 1; };
sub term { };
$SIG{INT} = \&rmpid;
if ($Net::DNS::VERSION >= 1.42) {
$SIG{TERM} = \&term;
} else {
$SIG{TERM} = \&rmpid;
}
$SIG{TERM} = \&rmpid;
my $count = 0;
@@ -78,11 +73,4 @@ my $ns = Net::DNS::Nameserver->new(
Verbose => $verbose,
);
if ($Net::DNS::VERSION >= 1.42) {
$ns->start_server();
select(undef, undef, undef, undef);
$ns->stop_server();
unlink "ans.pid";
} else {
$ns->main_loop;
}
$ns->main_loop;
+2 -2
View File
@@ -16,8 +16,8 @@
#
m4_define([bind_VERSION_MAJOR], 9)dnl
m4_define([bind_VERSION_MINOR], 18)dnl
m4_define([bind_VERSION_PATCH], 25)dnl
m4_define([bind_VERSION_EXTRA], )dnl
m4_define([bind_VERSION_PATCH], 22)dnl
m4_define([bind_VERSION_EXTRA], -dev)dnl
m4_define([bind_DESCRIPTION], [(Extended Support Version)])dnl
m4_define([bind_SRCID], [m4_esyscmd_s([git rev-parse --short HEAD | cut -b1-7])])dnl
m4_define([bind_PKG_VERSION], [[bind_VERSION_MAJOR.bind_VERSION_MINOR.bind_VERSION_PATCH]bind_VERSION_EXTRA])dnl
+4 -6
View File
@@ -347,18 +347,18 @@ if changes_added_lines:
# MR.
release_notes_regex = re.compile(r"doc/(arm|notes)/notes-.*\.(rst|xml)")
release_notes_changed = list(filter(release_notes_regex.match, affected_files))
release_notes_changed = list(filter(release_notes_regex.match, modified_files))
release_notes_label_set = "Release Notes" in mr_labels
if not release_notes_changed:
if release_notes_label_set:
fail(
"This merge request has the *Release Notes* label set. "
"Update release notes or unset the *Release Notes* label."
"Add a release note or unset the *Release Notes* label."
)
elif "Customer" in mr_labels:
warn(
"This merge request has the *Customer* label set. "
"Update release notes unless the changes introduced are trivial."
"Add a release note unless the changes introduced are trivial."
)
if release_notes_changed and not release_notes_label_set:
fail(
@@ -367,9 +367,7 @@ if release_notes_changed and not release_notes_label_set:
)
if release_notes_changed:
modified_or_new_files = danger.git.modified_files + danger.git.created_files
release_notes_added = list(filter(release_notes_regex.match, modified_or_new_files))
notes_added_lines = added_lines(target_branch, release_notes_added)
notes_added_lines = added_lines(target_branch, release_notes_changed)
identifiers_found = filter(relnotes_issue_or_mr_id_regex.search, notes_added_lines)
if notes_added_lines and not any(identifiers_found):
warn("No valid issue/MR identifiers found in added release notes.")
+1 -4
View File
@@ -35,10 +35,7 @@ information about each release, and source code.
.. include:: ../notes/notes-known-issues.rst
.. include:: ../notes/notes-9.18.25.rst
.. include:: ../notes/notes-9.18.24.rst
.. include:: ../notes/notes-9.18.23.rst
.. include:: ../notes/notes-9.18.22.rst
.. include:: ../notes/notes-current.rst
.. include:: ../notes/notes-9.18.21.rst
.. include:: ../notes/notes-9.18.20.rst
.. include:: ../notes/notes-9.18.19.rst
+2 -2
View File
@@ -1,5 +1,5 @@
# Make Read the Docs use the exact same package versions as in
# registry.gitlab.isc.org/isc-projects/images/bind9:debian-bookworm-amd64
Sphinx==7.2.6
docutils==0.20.1
sphinx_rtd_theme==2.0.0
docutils==0.18.1
sphinx_rtd_theme==1.3.0
-20
View File
@@ -1,20 +0,0 @@
.. 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.
Notes for BIND 9.18.23
----------------------
.. note::
The BIND 9.18.23 release was withdrawn after the discovery of a
regression in a security fix in it during pre-release testing. ISC
would like to acknowledge the assistance of Vinzenz Vogel and Daniel
Stirnimann of SWITCH.
-65
View File
@@ -1,65 +0,0 @@
.. 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.
Notes for BIND 9.18.24
----------------------
Security Fixes
~~~~~~~~~~~~~~
- Validating DNS messages containing a lot of DNSSEC signatures could
cause excessive CPU load, leading to a denial-of-service condition.
This has been fixed. :cve:`2023-50387`
ISC would like to thank Elias Heftrig, Haya Schulmann, Niklas Vogel,
and Michael Waidner from the German National Research Center for
Applied Cybersecurity ATHENE for bringing this vulnerability to our
attention. :gl:`#4424`
- Preparing an NSEC3 closest encloser proof could cause excessive CPU
load, leading to a denial-of-service condition. This has been fixed.
:cve:`2023-50868` :gl:`#4459`
- Parsing DNS messages with many different names could cause excessive
CPU load. This has been fixed. :cve:`2023-4408`
ISC would like to thank Shoham Danino from Reichman University, Anat
Bremler-Barr from Tel-Aviv University, Yehuda Afek from Tel-Aviv
University, and Yuval Shavitt from Tel-Aviv University for bringing
this vulnerability to our attention. :gl:`#4234`
- Specific queries could cause :iscman:`named` to crash with an
assertion failure when :any:`nxdomain-redirect` was enabled. This has
been fixed. :cve:`2023-5517` :gl:`#4281`
- A bad interaction between DNS64 and serve-stale could cause
:iscman:`named` to crash with an assertion failure, when both of these
features were enabled. This has been fixed. :cve:`2023-5679`
:gl:`#4334`
- Under certain circumstances, the DNS-over-TLS client code incorrectly
attempted to process more than one DNS message at a time, which could
cause :iscman:`named` to crash with an assertion failure. This has
been fixed. :gl:`#4487`
Bug Fixes
~~~~~~~~~
- The counters exported via the statistics channel were changed back to
64-bit signed values; they were being inadvertently truncated to
unsigned 32-bit values since BIND 9.15.0. :gl:`#4467`
Known Issues
~~~~~~~~~~~~
- There are no new known issues with this release. See :ref:`above
<relnotes_known_issues>` for a list of all known issues affecting this
BIND 9 branch.
-44
View File
@@ -1,44 +0,0 @@
.. 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.
Notes for BIND 9.18.25
----------------------
Bug Fixes
~~~~~~~~~
- A regression in cache-cleaning code enabled memory use to grow
significantly more quickly than before, until the configured
:any:`max-cache-size` limit was reached. This has been fixed.
:gl:`#4596`
- Using :option:`rndc flush` inadvertently caused cache cleaning to
become less effective. This could ultimately lead to the configured
:any:`max-cache-size` limit being exceeded and has now been fixed.
:gl:`#4621`
- The logic for cleaning up expired cached DNS records was
tweaked to be more aggressive. This change helps with enforcing
:any:`max-cache-ttl` and :any:`max-ncache-ttl` in a timely manner.
:gl:`#4591`
- It was possible to trigger a use-after-free assertion when the overmem cache
cleaning was initiated. This has been fixed. :gl:`#4595`
ISC would like to thank Jinmei Tatuya of Infoblox for bringing
this issue to our attention.
Known Issues
~~~~~~~~~~~~
- There are no new known issues with this release. See :ref:`above
<relnotes_known_issues>` for a list of all known issues affecting this
BIND 9 branch.
@@ -12,8 +12,34 @@
Notes for BIND 9.18.22
----------------------
.. note::
Security Fixes
~~~~~~~~~~~~~~
The BIND 9.18.22 release was withdrawn after the discovery of a
regression in a security fix in it during pre-release testing. ISC
would like to acknowledge the assistance of Curtis Tuplin of SaskTel.
- None.
New Features
~~~~~~~~~~~~
- None.
Removed Features
~~~~~~~~~~~~~~~~
- None.
Feature Changes
~~~~~~~~~~~~~~~
- None.
Bug Fixes
~~~~~~~~~
- None.
Known Issues
~~~~~~~~~~~~
- There are no new known issues with this release. See :ref:`above
<relnotes_known_issues>` for a list of all known issues affecting this
BIND 9 branch.
+16 -51
View File
@@ -129,7 +129,6 @@ struct dns_cache {
isc_mutex_t lock;
isc_mem_t *mctx; /* Main cache memory */
isc_mem_t *hmctx; /* Heap memory */
isc_taskmgr_t *taskmgr;
char *name;
isc_refcount_t references;
isc_refcount_t live_tasks;
@@ -170,47 +169,13 @@ water(void *arg, int mark);
static isc_result_t
cache_create_db(dns_cache_t *cache, dns_db_t **db) {
isc_result_t result;
isc_task_t *dbtask = NULL;
isc_task_t *prunetask = NULL;
result = dns_db_create(cache->mctx, cache->db_type, dns_rootname,
dns_dbtype_cache, cache->rdclass, cache->db_argc,
cache->db_argv, db);
if (result != ISC_R_SUCCESS) {
return (result);
if (result == ISC_R_SUCCESS) {
dns_db_setservestalettl(*db, cache->serve_stale_ttl);
dns_db_setservestalerefresh(*db, cache->serve_stale_refresh);
}
dns_db_setservestalettl(*db, cache->serve_stale_ttl);
dns_db_setservestalerefresh(*db, cache->serve_stale_refresh);
if (cache->taskmgr == NULL) {
return (ISC_R_SUCCESS);
}
result = isc_task_create(cache->taskmgr, 1, &dbtask);
if (result != ISC_R_SUCCESS) {
goto cleanup_db;
}
isc_task_setname(dbtask, "cache_dbtask", NULL);
result = isc_task_create(cache->taskmgr, UINT_MAX, &prunetask);
if (result != ISC_R_SUCCESS) {
goto cleanup_dbtask;
}
isc_task_setname(prunetask, "cache_prunetask", NULL);
dns_db_settask(*db, dbtask, prunetask);
isc_task_detach(&prunetask);
isc_task_detach(&dbtask);
return (ISC_R_SUCCESS);
cleanup_dbtask:
isc_task_detach(&dbtask);
cleanup_db:
dns_db_detach(db);
return (result);
}
@@ -222,12 +187,12 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
isc_result_t result;
dns_cache_t *cache;
int i, extra = 0;
isc_task_t *dbtask;
REQUIRE(cachep != NULL);
REQUIRE(*cachep == NULL);
REQUIRE(cmctx != NULL);
REQUIRE(hmctx != NULL);
REQUIRE(taskmgr != NULL || strcmp(db_type, "rbt") != 0);
REQUIRE(cachename != NULL);
cache = isc_mem_get(cmctx, sizeof(*cache));
@@ -236,11 +201,6 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
isc_mem_attach(cmctx, &cache->mctx);
isc_mem_attach(hmctx, &cache->hmctx);
cache->taskmgr = NULL;
if (taskmgr != NULL) {
isc_taskmgr_attach(taskmgr, &cache->taskmgr);
}
cache->name = NULL;
if (cachename != NULL) {
cache->name = isc_mem_strdup(cmctx, cachename);
@@ -297,6 +257,18 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
if (result != ISC_R_SUCCESS) {
goto cleanup_dbargv;
}
if (taskmgr != NULL) {
dbtask = NULL;
result = isc_task_create(taskmgr, 1, &dbtask);
if (result != ISC_R_SUCCESS) {
goto cleanup_db;
}
isc_task_setname(dbtask, "cache_dbtask", NULL);
dns_db_settask(cache->db, dbtask);
isc_task_detach(&dbtask);
}
cache->magic = CACHE_MAGIC;
/*
@@ -340,9 +312,6 @@ cleanup_lock:
if (cache->name != NULL) {
isc_mem_free(cmctx, cache->name);
}
if (cache->taskmgr != NULL) {
isc_taskmgr_detach(&cache->taskmgr);
}
isc_mem_detach(&cache->hmctx);
isc_mem_putanddetach(&cache->mctx, cache, sizeof(*cache));
return (result);
@@ -409,10 +378,6 @@ cache_free(dns_cache_t *cache) {
isc_stats_detach(&cache->stats);
}
if (cache->taskmgr != NULL) {
isc_taskmgr_detach(&cache->taskmgr);
}
isc_mutex_destroy(&cache->lock);
cache->magic = 0;
+2 -2
View File
@@ -829,10 +829,10 @@ dns_db_hashsize(dns_db_t *db) {
}
void
dns_db_settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
dns_db_settask(dns_db_t *db, isc_task_t *task) {
REQUIRE(DNS_DB_VALID(db));
(db->methods->settask)(db, task, prunetask);
(db->methods->settask)(db, task);
}
isc_result_t
+8 -19
View File
@@ -164,8 +164,7 @@ computeid(dst_key_t *key);
static isc_result_t
frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
unsigned int protocol, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
dst_key_t **keyp);
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
static isc_result_t
algorithm_status(unsigned int alg);
@@ -754,13 +753,6 @@ dst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
isc_result_t
dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) {
return (dst_key_fromdns_ex(name, rdclass, source, mctx, false, keyp));
}
isc_result_t
dst_key_fromdns_ex(const dns_name_t *name, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
dst_key_t **keyp) {
uint8_t alg, proto;
uint32_t flags, extflags;
dst_key_t *key = NULL;
@@ -791,7 +783,7 @@ dst_key_fromdns_ex(const dns_name_t *name, dns_rdataclass_t rdclass,
}
result = frombuffer(name, alg, flags, proto, rdclass, source, mctx,
no_rdata, &key);
&key);
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -812,7 +804,7 @@ dst_key_frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
REQUIRE(dst_initialized);
result = frombuffer(name, alg, flags, protocol, rdclass, source, mctx,
false, &key);
&key);
if (result != ISC_R_SUCCESS) {
return (result);
}
@@ -2359,8 +2351,7 @@ computeid(dst_key_t *key) {
static isc_result_t
frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
unsigned int protocol, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
dst_key_t **keyp) {
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) {
dst_key_t *key;
isc_result_t ret;
@@ -2385,12 +2376,10 @@ frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
return (DST_R_UNSUPPORTEDALG);
}
if (!no_rdata) {
ret = key->func->fromdns(key, source);
if (ret != ISC_R_SUCCESS) {
dst_key_free(&key);
return (ret);
}
ret = key->func->fromdns(key, source);
if (ret != ISC_R_SUCCESS) {
dst_key_free(&key);
return (ret);
}
}
+14 -9
View File
@@ -61,20 +61,25 @@ dns_cache_create(isc_mem_t *cmctx, isc_mem_t *hmctx, isc_taskmgr_t *taskmgr,
const char *cachename, const char *db_type,
unsigned int db_argc, char **db_argv, dns_cache_t **cachep);
/*%<
* Create a new named DNS cache using two separate memory contexts, one for
* cache data which can be cleaned and a separate one for memory allocated for
* the heap (which can grow without an upper limit and has no mechanism for
* shrinking).
* Create a new DNS cache.
*
* dns_cache_create2() will create a named cache.
*
* dns_cache_create3() will create a named cache using two separate memory
* contexts, one for cache data which can be cleaned and a separate one for
* memory allocated for the heap (which can grow without an upper limit and
* has no mechanism for shrinking).
*
* dns_cache_create() is a backward compatible version that internally
* specifies an empty cache name and a single memory context.
*
* Requires:
*
*\li 'cmctx' and 'hmctx' are valid memory contexts.
*
*\li 'taskmgr' is a valid task manager (if 'db_type' is "rbt").
*\li 'cmctx' (and 'hmctx' if applicable) is a valid memory context.
*
*\li 'taskmgr' is a valid task manager and 'timermgr' is a valid timer
* manager, or both are NULL (if 'db_type' is not "rbt"). If NULL, no
* periodic cleaning of the cache will take place.
* manager, or both are NULL. If NULL, no periodic cleaning of the
* cache will take place.
*
*\li 'cachename' is a valid string. This must not be NULL.
*
+3 -4
View File
@@ -139,7 +139,7 @@ typedef struct dns_dbmethods {
unsigned int (*nodecount)(dns_db_t *db, dns_dbtree_t);
bool (*ispersistent)(dns_db_t *db);
void (*overmem)(dns_db_t *db, bool overmem);
void (*settask)(dns_db_t *db, isc_task_t *, isc_task_t *);
void (*settask)(dns_db_t *db, isc_task_t *);
isc_result_t (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep);
void (*transfernode)(dns_db_t *db, dns_dbnode_t **sourcep,
dns_dbnode_t **targetp);
@@ -1389,14 +1389,13 @@ dns_db_hashsize(dns_db_t *db);
*/
void
dns_db_settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask);
dns_db_settask(dns_db_t *db, isc_task_t *task);
/*%<
* If task is set then the final detach maybe performed asynchronously.
*
* Requires:
* \li 'db' is a valid database.
* \li 'task' to be valid or NULL (default task to send events to).
* \li 'prunetask' to be valid or NULL (task to send tree-pruning events to).
* \li 'task' to be valid or NULL.
*/
bool
+38
View File
@@ -856,6 +856,44 @@ dns_message_findtype(const dns_name_t *name, dns_rdatatype_t type,
*\li #ISC_R_NOTFOUND -- the desired type does not exist.
*/
isc_result_t
dns_message_find(const dns_name_t *name, dns_rdataclass_t rdclass,
dns_rdatatype_t type, dns_rdatatype_t covers,
dns_rdataset_t **rdataset);
/*%<
* Search the name for the specified rdclass and type. If it is found,
* *rdataset is filled in with a pointer to that rdataset.
*
* Requires:
*\li if '**rdataset' is non-NULL, *rdataset needs to be NULL.
*
*\li 'type' be a valid type, and NOT dns_rdatatype_any.
*
*\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
* Otherwise it should be 0.
*
* Returns:
*\li #ISC_R_SUCCESS -- all is well.
*\li #ISC_R_NOTFOUND -- the desired type does not exist.
*/
void
dns_message_movename(dns_message_t *msg, dns_name_t *name,
dns_section_t fromsection, dns_section_t tosection);
/*%<
* Move a name from one section to another.
*
* Requires:
*
*\li 'msg' be valid.
*
*\li 'name' must be a name already in 'fromsection'.
*
*\li 'fromsection' must be a valid section.
*
*\li 'tosection' must be a valid section.
*/
void
dns_message_addname(dns_message_t *msg, dns_name_t *name,
dns_section_t section);
+20 -17
View File
@@ -68,7 +68,6 @@
#include <stdbool.h>
#include <stdio.h>
#include <isc/ht.h>
#include <isc/lang.h>
#include <isc/magic.h>
#include <isc/region.h> /* Required for storage size of dns_label_t. */
@@ -112,7 +111,6 @@ struct dns_name {
isc_buffer_t *buffer;
ISC_LINK(dns_name_t) link;
ISC_LIST(dns_rdataset_t) list;
isc_ht_t *ht;
};
#define DNS_NAME_MAGIC ISC_MAGIC('D', 'N', 'S', 'n')
@@ -168,24 +166,30 @@ extern const dns_name_t *dns_wildcardname;
* unsigned char offsets[] = { 0, 6 };
* dns_name_t value = DNS_NAME_INITABSOLUTE(data, offsets);
*/
#define DNS_NAME_INITNONABSOLUTE(A, B) \
{ \
DNS_NAME_MAGIC, A, (sizeof(A) - 1), sizeof(B), \
DNS_NAMEATTR_READONLY, B, NULL, \
{ (void *)-1, (void *)-1 }, { NULL, NULL }, NULL \
#define DNS_NAME_INITNONABSOLUTE(A, B) \
{ \
DNS_NAME_MAGIC, A, (sizeof(A) - 1), sizeof(B), \
DNS_NAMEATTR_READONLY, B, NULL, \
{ (void *)-1, (void *)-1 }, { \
NULL, NULL \
} \
}
#define DNS_NAME_INITABSOLUTE(A, B) \
{ \
DNS_NAME_MAGIC, A, sizeof(A), sizeof(B), \
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, B, \
NULL, { (void *)-1, (void *)-1 }, { NULL, NULL }, NULL \
#define DNS_NAME_INITABSOLUTE(A, B) \
{ \
DNS_NAME_MAGIC, A, sizeof(A), sizeof(B), \
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE, B, \
NULL, { (void *)-1, (void *)-1 }, { \
NULL, NULL \
} \
}
#define DNS_NAME_INITEMPTY \
{ \
DNS_NAME_MAGIC, NULL, 0, 0, 0, NULL, NULL, \
{ (void *)-1, (void *)-1 }, { NULL, NULL }, NULL \
#define DNS_NAME_INITEMPTY \
{ \
DNS_NAME_MAGIC, NULL, 0, 0, 0, NULL, NULL, \
{ (void *)-1, (void *)-1 }, { \
NULL, NULL \
} \
}
/*%
@@ -1326,7 +1330,6 @@ ISC_LANG_ENDDECLS
_n->buffer = NULL; \
ISC_LINK_INIT(_n, link); \
ISC_LIST_INIT(_n->list); \
_n->ht = NULL; \
} while (0)
#define DNS_NAME_RESET(n) \
-1
View File
@@ -148,7 +148,6 @@ struct dns_validator {
unsigned int depth;
unsigned int authcount;
unsigned int authfail;
bool failed;
isc_stdtime_t start;
};
-4
View File
@@ -482,10 +482,6 @@ dst_key_tofile(const dst_key_t *key, int type, const char *directory);
*/
isc_result_t
dst_key_fromdns_ex(const dns_name_t *name, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
dst_key_t **keyp);
isc_result_t
dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
/*%<
+133 -239
View File
@@ -22,8 +22,6 @@
#include <stdbool.h>
#include <isc/buffer.h>
#include <isc/hash.h>
#include <isc/ht.h>
#include <isc/mem.h>
#include <isc/print.h>
#include <isc/result.h>
@@ -495,11 +493,9 @@ msgresetsigs(dns_message_t *msg, bool replying) {
} else {
dns_rdataset_disassociate(msg->tsig);
isc_mempool_put(msg->rdspool, msg->tsig);
msg->tsig = NULL;
if (msg->querytsig != NULL) {
dns_rdataset_disassociate(msg->querytsig);
isc_mempool_put(msg->rdspool, msg->querytsig);
msg->querytsig = NULL;
}
}
dns_message_puttempname(msg, &msg->tsigname);
@@ -794,18 +790,6 @@ dns_message_detach(dns_message_t **messagep) {
}
}
static isc_result_t
name_hash_add(isc_ht_t *ht, dns_name_t *name, dns_name_t **foundp) {
isc_result_t result = isc_ht_find(ht, name->ndata, name->length,
(void **)foundp);
if (result == ISC_R_SUCCESS) {
return (ISC_R_EXISTS);
}
result = isc_ht_add(ht, name->ndata, name->length, (void *)name);
INSIST(result == ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
}
static isc_result_t
findname(dns_name_t **foundname, const dns_name_t *target,
dns_namelist_t *section) {
@@ -825,26 +809,29 @@ findname(dns_name_t **foundname, const dns_name_t *target,
return (ISC_R_NOTFOUND);
}
typedef struct __attribute__((__packed__)) rds_key {
dns_rdataclass_t rdclass;
dns_rdatatype_t type;
dns_rdatatype_t covers;
} rds_key_t;
isc_result_t
dns_message_find(const dns_name_t *name, dns_rdataclass_t rdclass,
dns_rdatatype_t type, dns_rdatatype_t covers,
dns_rdataset_t **rdataset) {
dns_rdataset_t *curr;
static isc_result_t
rds_hash_add(isc_ht_t *ht, dns_rdataset_t *rds, dns_rdataset_t **foundp) {
rds_key_t key = { .rdclass = rds->rdclass,
.type = rds->type,
.covers = rds->covers };
isc_result_t result = isc_ht_find(ht, (const unsigned char *)&key,
sizeof(key), (void **)foundp);
if (result == ISC_R_SUCCESS) {
return (ISC_R_EXISTS);
REQUIRE(name != NULL);
REQUIRE(rdataset == NULL || *rdataset == NULL);
for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
curr = ISC_LIST_PREV(curr, link))
{
if (curr->rdclass == rdclass && curr->type == type &&
curr->covers == covers)
{
if (rdataset != NULL) {
*rdataset = curr;
}
return (ISC_R_SUCCESS);
}
}
result = isc_ht_add(ht, (const unsigned char *)&key, sizeof(key),
(void *)rds);
INSIST(result == ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
return (ISC_R_NOTFOUND);
}
isc_result_t
@@ -971,18 +958,6 @@ getrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
} \
} while (0)
static void
cleanup_name_hashmaps(dns_namelist_t *section) {
dns_name_t *name = NULL;
for (name = ISC_LIST_HEAD(*section); name != NULL;
name = ISC_LIST_NEXT(name, link))
{
if (name->ht != NULL) {
isc_ht_destroy(&name->ht);
}
}
}
static isc_result_t
getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
unsigned int options) {
@@ -992,19 +967,13 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
dns_name_t *name2 = NULL;
dns_rdataset_t *rdataset = NULL;
dns_rdatalist_t *rdatalist = NULL;
isc_result_t result = ISC_R_SUCCESS;
isc_result_t result;
dns_rdatatype_t rdtype;
dns_rdataclass_t rdclass;
dns_namelist_t *section = &msg->sections[DNS_SECTION_QUESTION];
bool best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0);
bool seen_problem = false;
bool free_name = false;
bool free_ht = false;
isc_ht_t *name_map = NULL;
if (msg->counts[DNS_SECTION_QUESTION] > 1) {
isc_ht_init(&name_map, msg->mctx, 1, ISC_HT_CASE_INSENSITIVE);
}
for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) {
name = NULL;
@@ -1025,19 +994,13 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
goto cleanup;
}
/* If there is only one QNAME, skip the duplicity checks */
if (name_map == NULL) {
result = ISC_R_SUCCESS;
goto skip_name_check;
}
/*
* Run through the section, looking to see if this name
* is already there. If it is found, put back the allocated
* name since we no longer need it, and set our name pointer
* to point to the name we found.
*/
result = name_hash_add(name_map, name, &name2);
result = findname(&name2, name, section);
/*
* If it is the first name in the section, accept it.
@@ -1049,25 +1012,19 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
* this should be legal or not. In either case we no longer
* need this name pointer.
*/
skip_name_check:
switch (result) {
case ISC_R_SUCCESS:
if (result != ISC_R_SUCCESS) {
if (!ISC_LIST_EMPTY(*section)) {
DO_ERROR(DNS_R_FORMERR);
}
ISC_LIST_APPEND(*section, name, link);
break;
case ISC_R_EXISTS:
free_name = false;
} else {
dns_message_puttempname(msg, &name);
name = name2;
name2 = NULL;
break;
default:
UNREACHABLE();
free_name = false;
}
free_name = false;
/*
* Get type and class.
*/
@@ -1097,6 +1054,14 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
msg->tkey = 1;
}
/*
* Can't ask the same question twice.
*/
result = dns_message_find(name, rdclass, rdtype, 0, NULL);
if (result == ISC_R_SUCCESS) {
DO_ERROR(DNS_R_FORMERR);
}
/*
* Allocate a new rdatalist.
*/
@@ -1106,7 +1071,6 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
goto cleanup;
}
rdataset = isc_mempool_get(msg->rdspool);
dns_rdataset_init(rdataset);
/*
* Convert rdatalist to rdataset, and attach the latter to
@@ -1114,6 +1078,8 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
*/
rdatalist->type = rdtype;
rdatalist->rdclass = rdclass;
dns_rdataset_init(rdataset);
result = dns_rdatalist_tordataset(rdatalist, rdataset);
if (result != ISC_R_SUCCESS) {
goto cleanup;
@@ -1121,66 +1087,24 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
/*
* Skip the duplicity check for first rdataset
*/
if (ISC_LIST_EMPTY(name->list)) {
result = ISC_R_SUCCESS;
goto skip_rds_check;
}
/*
* Can't ask the same question twice.
*/
if (name->ht == NULL) {
isc_ht_init(&name->ht, msg->mctx, 1,
ISC_HT_CASE_SENSITIVE);
free_ht = true;
INSIST(ISC_LIST_HEAD(name->list) ==
ISC_LIST_TAIL(name->list));
dns_rdataset_t *old_rdataset =
ISC_LIST_HEAD(name->list);
result = rds_hash_add(name->ht, old_rdataset, NULL);
INSIST(result == ISC_R_SUCCESS);
}
result = rds_hash_add(name->ht, rdataset, NULL);
if (result == ISC_R_EXISTS) {
DO_ERROR(DNS_R_FORMERR);
}
skip_rds_check:
ISC_LIST_APPEND(name->list, rdataset, link);
rdataset = NULL;
}
if (seen_problem) {
result = DNS_R_RECOVERABLE;
return (DNS_R_RECOVERABLE);
}
return (ISC_R_SUCCESS);
cleanup:
if (rdataset != NULL) {
if (dns_rdataset_isassociated(rdataset)) {
dns_rdataset_disassociate(rdataset);
}
INSIST(!dns_rdataset_isassociated(rdataset));
isc_mempool_put(msg->rdspool, rdataset);
}
if (free_name) {
dns_message_puttempname(msg, &name);
}
if (free_ht) {
cleanup_name_hashmaps(section);
}
if (name_map != NULL) {
isc_ht_destroy(&name_map);
}
return (result);
}
@@ -1260,24 +1184,17 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
dns_name_t *name = NULL;
dns_name_t *name2 = NULL;
dns_rdataset_t *rdataset = NULL;
dns_rdataset_t *found_rdataset = NULL;
dns_rdatalist_t *rdatalist = NULL;
isc_result_t result = ISC_R_SUCCESS;
isc_result_t result;
dns_rdatatype_t rdtype, covers;
dns_rdataclass_t rdclass;
dns_rdata_t *rdata = NULL;
dns_ttl_t ttl;
dns_namelist_t *section = &msg->sections[sectionid];
bool free_name = false, seen_problem = false;
bool free_ht = false;
bool free_name = false, free_rdataset = false, seen_problem = false;
bool preserve_order = ((options & DNS_MESSAGEPARSE_PRESERVEORDER) != 0);
bool best_effort = ((options & DNS_MESSAGEPARSE_BESTEFFORT) != 0);
bool isedns, issigzero, istsig;
isc_ht_t *name_map = NULL;
if (msg->counts[sectionid] > 1) {
isc_ht_init(&name_map, msg->mctx, 1, ISC_HT_CASE_INSENSITIVE);
}
for (count = 0; count < msg->counts[sectionid]; count++) {
int recstart = source->current;
@@ -1285,10 +1202,10 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
skip_name_search = false;
skip_type_search = false;
free_rdataset = false;
isedns = false;
issigzero = false;
istsig = false;
found_rdataset = NULL;
name = NULL;
result = dns_message_gettempname(msg, &name);
@@ -1328,8 +1245,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
if (msg->rdclass_set == 0 &&
rdtype != dns_rdatatype_opt && /* class is UDP SIZE */
rdtype != dns_rdatatype_tsig && /* class is ANY */
rdtype != dns_rdatatype_tkey) /* class is undefined */
{
rdtype != dns_rdatatype_tkey)
{ /* class is undefined */
msg->rdclass = rdclass;
msg->rdclass_set = 1;
}
@@ -1436,6 +1353,10 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
* Then put the meta-class back into the finished rdata.
*/
rdata = newrdata(msg);
if (rdata == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
if (msg->opcode == dns_opcode_update &&
update(sectionid, rdclass))
{
@@ -1524,62 +1445,34 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
free_name = false;
}
} else {
if (name_map == NULL) {
result = ISC_R_SUCCESS;
goto skip_name_check;
}
/*
* Run through the section, looking to see if this name
* is already there. If it is found, put back the
* allocated name since we no longer need it, and set
* our name pointer to point to the name we found.
*/
result = name_hash_add(name_map, name, &name2);
result = findname(&name2, name, section);
/*
* If it is a new name, append to the section.
*/
skip_name_check:
switch (result) {
case ISC_R_SUCCESS:
ISC_LIST_APPEND(*section, name, link);
break;
case ISC_R_EXISTS:
if (result == ISC_R_SUCCESS) {
dns_message_puttempname(msg, &name);
name = name2;
name2 = NULL;
break;
default:
UNREACHABLE();
} else {
ISC_LIST_APPEND(*section, name, link);
}
free_name = false;
}
rdatalist = newrdatalist(msg);
rdatalist->type = rdtype;
rdatalist->covers = covers;
rdatalist->rdclass = rdclass;
rdatalist->ttl = ttl;
dns_message_gettemprdataset(msg, &rdataset);
RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) ==
ISC_R_SUCCESS);
dns_rdataset_setownercase(rdataset, name);
rdatalist = NULL;
/*
* Search name for the particular type and class.
* Skip this stage if in update mode or this is a meta-type.
*/
if (isedns || istsig || issigzero) {
/* Skip adding the rdataset to the tables */
} else if (preserve_order || msg->opcode == dns_opcode_update ||
skip_type_search)
if (preserve_order || msg->opcode == dns_opcode_update ||
skip_type_search)
{
result = ISC_R_SUCCESS;
ISC_LIST_APPEND(name->list, rdataset, link);
result = ISC_R_NOTFOUND;
} else {
/*
* If this is a type that can only occur in
@@ -1589,71 +1482,59 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
DO_ERROR(DNS_R_FORMERR);
}
if (ISC_LIST_EMPTY(name->list)) {
result = ISC_R_SUCCESS;
goto skip_rds_check;
}
if (name->ht == NULL) {
isc_ht_init(&name->ht, msg->mctx, 1,
ISC_HT_CASE_SENSITIVE);
free_ht = true;
INSIST(ISC_LIST_HEAD(name->list) ==
ISC_LIST_TAIL(name->list));
dns_rdataset_t *old_rdataset =
ISC_LIST_HEAD(name->list);
result = rds_hash_add(name->ht, old_rdataset,
NULL);
INSIST(result == ISC_R_SUCCESS);
}
found_rdataset = NULL;
result = rds_hash_add(name->ht, rdataset,
&found_rdataset);
/*
* If we found an rdataset that matches, we need to
* append this rdata to that set. If we did not, we
* need to create a new rdatalist, store the important
* bits there, convert it to an rdataset, and link the
* latter to the name. Yuck. When appending, make
* certain that the type isn't a singleton type, such as
* SOA or CNAME.
*
* Note that this check will be bypassed when preserving
* order, the opcode is an update, or the type search is
* skipped.
*/
skip_rds_check:
switch (result) {
case ISC_R_EXISTS:
/* Free the rdataset we used as the key */
dns_rdataset_disassociate(rdataset);
isc_mempool_put(msg->rdspool, rdataset);
result = ISC_R_SUCCESS;
rdataset = found_rdataset;
if (!dns_rdatatype_issingleton(rdtype)) {
break;
}
rdataset = NULL;
result = dns_message_find(name, rdclass, rdtype, covers,
&rdataset);
}
/*
* If we found an rdataset that matches, we need to
* append this rdata to that set. If we did not, we need
* to create a new rdatalist, store the important bits there,
* convert it to an rdataset, and link the latter to the name.
* Yuck. When appending, make certain that the type isn't
* a singleton type, such as SOA or CNAME.
*
* Note that this check will be bypassed when preserving order,
* the opcode is an update, or the type search is skipped.
*/
if (result == ISC_R_SUCCESS) {
if (dns_rdatatype_issingleton(rdtype)) {
dns_rdata_t *first;
dns_rdatalist_fromrdataset(rdataset,
&rdatalist);
dns_rdata_t *first =
ISC_LIST_HEAD(rdatalist->rdata);
first = ISC_LIST_HEAD(rdatalist->rdata);
INSIST(first != NULL);
if (dns_rdata_compare(rdata, first) != 0) {
DO_ERROR(DNS_R_FORMERR);
}
break;
case ISC_R_SUCCESS:
}
}
if (result == ISC_R_NOTFOUND) {
rdataset = isc_mempool_get(msg->rdspool);
free_rdataset = true;
rdatalist = newrdatalist(msg);
if (rdatalist == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup;
}
rdatalist->type = rdtype;
rdatalist->covers = covers;
rdatalist->rdclass = rdclass;
rdatalist->ttl = ttl;
dns_rdataset_init(rdataset);
RUNTIME_CHECK(
dns_rdatalist_tordataset(rdatalist, rdataset) ==
ISC_R_SUCCESS);
dns_rdataset_setownercase(rdataset, name);
if (!isedns && !istsig && !issigzero) {
ISC_LIST_APPEND(name->list, rdataset, link);
break;
default:
UNREACHABLE();
free_rdataset = false;
}
}
@@ -1688,6 +1569,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
dns_rcode_t ercode;
msg->opt = rdataset;
rdataset = NULL;
free_rdataset = false;
ercode = (dns_rcode_t)((msg->opt->ttl &
DNS_MESSAGE_EDNSRCODE_MASK) >>
20);
@@ -1698,6 +1581,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
msg->sig0 = rdataset;
msg->sig0name = name;
msg->sigstart = recstart;
rdataset = NULL;
free_rdataset = false;
free_name = false;
} else if (istsig) {
msg->tsig = rdataset;
@@ -1707,17 +1592,22 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
* Windows doesn't like TSIG names to be compressed.
*/
msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
rdataset = NULL;
free_rdataset = false;
free_name = false;
}
rdataset = NULL;
if (seen_problem) {
if (free_name) {
dns_message_puttempname(msg, &name);
}
free_name = false;
if (free_rdataset) {
isc_mempool_put(msg->rdspool, rdataset);
}
free_name = free_rdataset = false;
}
INSIST(!free_name);
INSIST(!free_rdataset);
}
/*
@@ -1735,24 +1625,16 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
}
if (seen_problem) {
result = DNS_R_RECOVERABLE;
return (DNS_R_RECOVERABLE);
}
return (ISC_R_SUCCESS);
cleanup:
if (rdataset != NULL && rdataset != found_rdataset) {
dns_rdataset_disassociate(rdataset);
isc_mempool_put(msg->rdspool, rdataset);
}
if (free_name) {
dns_message_puttempname(msg, &name);
}
if (free_ht) {
cleanup_name_hashmaps(section);
}
if (name_map != NULL) {
isc_ht_destroy(&name_map);
if (free_rdataset) {
isc_mempool_put(msg->rdspool, rdataset);
}
return (result);
@@ -2570,7 +2452,7 @@ dns_message_findname(dns_message_t *msg, dns_section_t section,
const dns_name_t *target, dns_rdatatype_t type,
dns_rdatatype_t covers, dns_name_t **name,
dns_rdataset_t **rdataset) {
dns_name_t *foundname = NULL;
dns_name_t *foundname;
isc_result_t result;
/*
@@ -2617,6 +2499,22 @@ dns_message_findname(dns_message_t *msg, dns_section_t section,
return (result);
}
void
dns_message_movename(dns_message_t *msg, dns_name_t *name,
dns_section_t fromsection, dns_section_t tosection) {
REQUIRE(msg != NULL);
REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
REQUIRE(name != NULL);
REQUIRE(VALID_NAMED_SECTION(fromsection));
REQUIRE(VALID_NAMED_SECTION(tosection));
/*
* Unlink the name from the old section
*/
ISC_LIST_UNLINK(msg->sections[fromsection], name, link);
ISC_LIST_APPEND(msg->sections[tosection], name, link);
}
void
dns_message_addname(dns_message_t *msg, dns_name_t *name,
dns_section_t section) {
@@ -2693,10 +2591,6 @@ dns_message_puttempname(dns_message_t *msg, dns_name_t **itemp) {
REQUIRE(!ISC_LINK_LINKED(item, link));
REQUIRE(ISC_LIST_HEAD(item->list) == NULL);
if (item->ht != NULL) {
isc_ht_destroy(&item->ht);
}
/*
* we need to check this in case dns_name_dup() was used.
*/
-1
View File
@@ -188,7 +188,6 @@ dns_name_invalidate(dns_name_t *name) {
name->offsets = NULL;
name->buffer = NULL;
ISC_LINK_INIT(name, link);
INSIST(name->ht == NULL);
}
bool
+6
View File
@@ -1138,6 +1138,12 @@ dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
dns_rdata_t private = DNS_RDATA_INIT;
dns_rdataset_current(&rdataset, &rdata);
CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
rdataset.ttl, &rdata, &tuple));
CHECK(do_one_tuple(&tuple, db, ver, diff));
INSIST(tuple == NULL);
dns_nsec3param_toprivate(&rdata, &private, privatetype, buf,
sizeof(buf));
buf[2] = DNS_NSEC3FLAG_REMOVE;
+64 -132
View File
@@ -351,14 +351,6 @@ hash_32(uint32_t val, unsigned int bits) {
#define DEFAULT_CACHE_NODE_LOCK_COUNT 17
#endif /* DNS_RBTDB_CACHE_NODE_LOCK_COUNT */
/*
* This defines the number of headers that we try to expire each time the
* expire_ttl_headers() is run. The number should be small enough, so the
* TTL-based header expiration doesn't take too long, but it should be large
* enough, so we expire enough headers if their TTL is clustered.
*/
#define DNS_RBTDB_EXPIRE_TTL_COUNT 10
typedef struct {
nodelock_t lock;
/* Protected in the refcount routines. */
@@ -462,7 +454,6 @@ struct dns_rbtdb {
rbtdb_version_t *future_version;
rbtdb_versionlist_t open_versions;
isc_task_t *task;
isc_task_t *prunetask;
dns_dbnode_t *soanode;
dns_dbnode_t *nsnode;
@@ -913,10 +904,6 @@ set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) {
} else {
isc_heap_decreased(heap, header->heap_index);
}
if (newttl == 0) {
isc_heap_delete(heap, header->heap_index);
}
}
/*%
@@ -1164,9 +1151,6 @@ free_rbtdb(dns_rbtdb_t *rbtdb, bool log, isc_event_t *event) {
if (rbtdb->task != NULL) {
isc_task_detach(&rbtdb->task);
}
if (rbtdb->prunetask != NULL) {
isc_task_detach(&rbtdb->prunetask);
}
RBTDB_DESTROYLOCK(&rbtdb->lock);
rbtdb->common.magic = 0;
@@ -1836,9 +1820,8 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
*/
static void
new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
isc_rwlocktype_t nlocktype) {
if (nlocktype == isc_rwlocktype_write &&
ISC_LINK_LINKED(node, deadlink))
isc_rwlocktype_t locktype) {
if (locktype == isc_rwlocktype_write && ISC_LINK_LINKED(node, deadlink))
{
ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum], node,
deadlink);
@@ -1854,24 +1837,24 @@ new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
* The tree lock must be held for the result to be valid.
*/
static bool
is_last_node_on_its_level(dns_rbtnode_t *node) {
is_leaf(dns_rbtnode_t *node) {
return (node->parent != NULL && node->parent->down == node &&
node->left == NULL && node->right == NULL);
}
static void
send_to_prune_tree(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
isc_rwlocktype_t nlocktype) {
isc_rwlocktype_t locktype) {
isc_event_t *ev;
dns_db_t *db;
ev = isc_event_allocate(rbtdb->common.mctx, NULL, DNS_EVENT_RBTPRUNE,
prune_tree, node, sizeof(isc_event_t));
new_reference(rbtdb, node, nlocktype);
new_reference(rbtdb, node, locktype);
db = NULL;
attach((dns_db_t *)rbtdb, &db);
ev->ev_sender = db;
isc_task_send(rbtdb->prunetask, &ev);
isc_task_send(rbtdb->task, &ev);
}
/*%
@@ -1904,7 +1887,7 @@ cleanup_dead_nodes(dns_rbtdb_t *rbtdb, int bucketnum) {
continue;
}
if (is_last_node_on_its_level(node) && rbtdb->task != NULL) {
if (is_leaf(node) && rbtdb->task != NULL) {
send_to_prune_tree(rbtdb, node, isc_rwlocktype_write);
} else if (node->down == NULL && node->data == NULL) {
/*
@@ -2088,31 +2071,29 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
if (write_locked) {
/*
* If this node is the only one left on its RBTDB level,
* attempt pruning the RBTDB (i.e. deleting empty nodes that
* are ancestors of 'node' and are not interior nodes) starting
* from this node (see prune_tree()). The main reason this is
* not done immediately, but asynchronously, is that the
* ancestors of 'node' are almost guaranteed to belong to
* different node buckets and we don't want to do juggle locks
* right now.
*
* Since prune_tree() also calls decrement_reference(), check
* the value of the 'pruning' parameter (which is only set to
* 'true' in the decrement_reference() call present in
* prune_tree()) to prevent an infinite loop and to allow a
* node sent to prune_tree() to be deleted by the delete_node()
* call in the code branch below.
* We can now delete the node.
*/
if (!pruning && is_last_node_on_its_level(node) &&
rbtdb->task != NULL)
{
/*
* If this node is the only one in the level it's in, deleting
* this node may recursively make its parent the only node in
* the parent level; if so, and if no one is currently using
* the parent node, this is almost the only opportunity to
* clean it up. But the recursive cleanup is not that trivial
* since the child and parent may be in different lock buckets,
* which would cause a lock order reversal problem. To avoid
* the trouble, we'll dispatch a separate event for batch
* cleaning. We need to check whether we're deleting the node
* as a result of pruning to avoid infinite dispatching.
* Note: pruning happens only when a task has been set for the
* rbtdb. If the user of the rbtdb chooses not to set a task,
* it's their responsibility to purge stale leaves (e.g. by
* periodic walk-through).
*/
if (!pruning && is_leaf(node) && rbtdb->task != NULL) {
send_to_prune_tree(rbtdb, node, isc_rwlocktype_write);
no_reference = false;
} else {
/*
* The node can now be deleted.
*/
delete_node(rbtdb, node);
}
} else {
@@ -2148,57 +2129,37 @@ restore_locks:
}
/*
* Prune the RBTDB tree of trees. Start by attempting to delete a node that is
* the only one left on its RBTDB level (see the send_to_prune_tree() call in
* decrement_reference()). Then, if the node has a parent (which can either
* exist on the same RBTDB level or on an upper RBTDB level), check whether the
* latter is an interior node (i.e. a node with a non-NULL 'down' pointer). If
* the parent node is not an interior node, attempt deleting the parent node as
* well and then move on to examining the parent node's parent, etc. Continue
* traversing the RBTDB tree until a node is encountered that is still an
* interior node after the previously-processed node gets deleted.
*
* It is acceptable for a node sent to this function to NOT be deleted in the
* process (e.g. if it gets reactivated in the meantime). Furthermore, node
* deletion is not a prerequisite for continuing RBTDB traversal.
*
* This function gets called once for every "starting node" and it continues
* traversing the RBTDB until the stop condition is met. In the worst case,
* the number of nodes processed by a single execution of this function is the
* number of tree levels, which is at most the maximum number of domain name
* labels (127); however, it should be much smaller in practice and deleting
* empty RBTDB nodes is critical to keeping the amount of memory used by the
* cache memory context within the configured limit anyway.
* Prune the tree by recursively cleaning-up single leaves. In the worst
* case, the number of iteration is the number of tree levels, which is at
* most the maximum number of domain name labels, i.e, 127. In practice, this
* should be much smaller (only a few times), and even the worst case would be
* acceptable for a single event.
*/
static void
prune_tree(isc_task_t *task, isc_event_t *event) {
dns_rbtdb_t *rbtdb = event->ev_sender;
dns_rbtnode_t *node = event->ev_arg;
dns_rbtnode_t *parent = NULL;
unsigned int locknum = node->locknum;
dns_rbtnode_t *parent;
unsigned int locknum;
UNUSED(task);
isc_event_free(&event);
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
locknum = node->locknum;
NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
do {
parent = node->parent;
decrement_reference(rbtdb, node, 0, isc_rwlocktype_write,
isc_rwlocktype_write, true);
/*
* Check whether the parent is an interior node. Note that it
* might have been one before the decrement_reference() call on
* the previous line, but decrementing the reference count for
* 'node' could have caused 'node->parent->down' to become
* NULL.
*/
if (parent != NULL && parent->down == NULL) {
/*
* Keep the node lock if possible; otherwise, release
* the old lock and acquire one for the parent.
* node was the only down child of the parent and has
* just been removed. We'll then need to examine the
* parent. Keep the lock if possible; otherwise,
* release the old lock and acquire one for the parent.
*/
if (parent->locknum != locknum) {
NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
@@ -2209,9 +2170,13 @@ prune_tree(isc_task_t *task, isc_event_t *event) {
}
/*
* We need to gain a reference to the parent node
* before decrementing it in the next iteration.
* We need to gain a reference to the node before
* decrementing it in the next iteration.
*/
if (ISC_LINK_LINKED(parent, deadlink)) {
ISC_LIST_UNLINK(rbtdb->deadnodes[locknum],
parent, deadlink);
}
new_reference(rbtdb, parent, isc_rwlocktype_write);
} else {
parent = NULL;
@@ -6862,10 +6827,6 @@ rdataset_size(rdatasetheader_t *header) {
return (sizeof(*header));
}
static void
expire_ttl_headers(dns_rbtdb_t *rbtdb, unsigned int locknum, bool tree_locked,
isc_stdtime_t now);
static isc_result_t
addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
@@ -6875,6 +6836,7 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
rbtdb_version_t *rbtversion = version;
isc_region_t region;
rdatasetheader_t *newheader;
rdatasetheader_t *header;
isc_result_t result;
bool delegating;
bool newnsec;
@@ -7047,7 +7009,20 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
cleanup_dead_nodes(rbtdb, rbtnode->locknum);
}
expire_ttl_headers(rbtdb, rbtnode->locknum, tree_locked, now);
header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
if (header != NULL) {
dns_ttl_t rdh_ttl = header->rdh_ttl;
/* Only account for stale TTL if cache is not overmem */
if (!cache_is_overmem) {
rdh_ttl += STALE_TTL(header, rbtdb);
}
if (rdh_ttl < now - RBTDB_VIRTUAL) {
expire_header(rbtdb, header, tree_locked,
expire_ttl);
}
}
/*
* If we've been holding a write lock on the tree just for
@@ -7767,7 +7742,7 @@ hashsize(dns_db_t *db) {
}
static void
settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
settask(dns_db_t *db, isc_task_t *task) {
dns_rbtdb_t *rbtdb;
rbtdb = (dns_rbtdb_t *)db;
@@ -7781,12 +7756,6 @@ settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
if (task != NULL) {
isc_task_attach(task, &rbtdb->task);
}
if (rbtdb->prunetask != NULL) {
isc_task_detach(&rbtdb->prunetask);
}
if (prunetask != NULL) {
isc_task_attach(prunetask, &rbtdb->prunetask);
}
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
}
@@ -8464,7 +8433,6 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
isc_refcount_init(&rbtdb->references, 1);
rbtdb->attributes = 0;
rbtdb->task = NULL;
rbtdb->prunetask = NULL;
rbtdb->serve_stale_ttl = 0;
/*
@@ -10196,21 +10164,22 @@ update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, isc_stdtime_t now) {
static size_t
expire_lru_headers(dns_rbtdb_t *rbtdb, unsigned int locknum, size_t purgesize,
bool tree_locked) {
rdatasetheader_t *header;
rdatasetheader_t *header, *header_prev;
size_t purged = 0;
for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]);
header != NULL &&
header->last_used <= atomic_load(&rbtdb->last_used) &&
purged <= purgesize;
header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]))
header = header_prev)
{
header_prev = ISC_LIST_PREV(header, link);
/*
* Unlink the entry at this point to avoid checking it
* again even if it's currently used someone else and
* cannot be purged at this moment. This entry won't be
* referenced any more (so unlinking is safe) since the
* TTL will be reset to 0.
* TTL was reset to 0.
*/
ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header, link);
size_t header_size = rdataset_size(header);
@@ -10322,40 +10291,3 @@ expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, bool tree_locked,
}
}
}
/*
* Caller must be holding the node write lock.
*/
static void
expire_ttl_headers(dns_rbtdb_t *rbtdb, unsigned int locknum, bool tree_locked,
isc_stdtime_t now) {
isc_heap_t *heap = rbtdb->heaps[locknum];
for (size_t i = 0; i < DNS_RBTDB_EXPIRE_TTL_COUNT; i++) {
rdatasetheader_t *header = isc_heap_element(heap, 1);
if (header == NULL) {
/* No headers left on this TTL heap; exit cleaning */
return;
}
dns_ttl_t ttl = header->rdh_ttl;
if (!isc_mem_isovermem(rbtdb->common.mctx)) {
/* Only account for stale TTL if cache is not overmem */
ttl += STALE_TTL(header, rbtdb);
}
if (ttl >= now - RBTDB_VIRTUAL) {
/*
* The header at the top of this TTL heap is not yet
* eligible for expiry, so none of the other headers on
* the same heap can be eligible for expiry, either;
* exit cleaning.
*/
return;
}
expire_header(rbtdb, header, tree_locked, expire_ttl);
}
}
+2 -2
View File
@@ -10408,8 +10408,8 @@ dns_resolver_create(dns_view_t *view, isc_taskmgr_t *taskmgr,
* Since we have a pool of tasks we bind them to task
* queues to spread the load evenly
*/
result = isc_task_create_bound(
taskmgr, 0, &res->buckets[i].task, ISC_NM_TASK_SLOW(i));
result = isc_task_create_bound(taskmgr, 0,
&res->buckets[i].task, i);
if (result != ISC_R_SUCCESS) {
ntasks = i;
isc_mutex_destroy(&res->buckets[i].lock);
+1 -2
View File
@@ -1263,10 +1263,9 @@ overmem(dns_db_t *db, bool over) {
}
static void
settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
settask(dns_db_t *db, isc_task_t *task) {
UNUSED(db);
UNUSED(task);
UNUSED(prunetask);
}
static dns_dbmethods_t sdb_methods = {
+1 -2
View File
@@ -1213,10 +1213,9 @@ overmem(dns_db_t *db, bool over) {
}
static void
settask(dns_db_t *db, isc_task_t *task, isc_task_t *prunetask) {
settask(dns_db_t *db, isc_task_t *task) {
UNUSED(db);
UNUSED(task);
UNUSED(prunetask);
}
/*
+8 -14
View File
@@ -1757,9 +1757,8 @@ isc_result_t
dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name,
const dns_name_t *algorithm, dns_tsig_keyring_t *ring) {
dns_tsigkey_t *key;
isc_result_t result;
isc_rwlocktype_t locktype = isc_rwlocktype_read;
isc_stdtime_t now;
isc_result_t result;
REQUIRE(tsigkey != NULL);
REQUIRE(*tsigkey == NULL);
@@ -1771,30 +1770,25 @@ dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name,
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
isc_stdtime_get(&now);
again:
RWLOCK(&ring->lock, locktype);
RWLOCK(&ring->lock, isc_rwlocktype_read);
key = NULL;
result = dns_rbt_findname(ring->keys, name, 0, NULL, (void *)&key);
if (result == DNS_R_PARTIALMATCH || result == ISC_R_NOTFOUND) {
RWUNLOCK(&ring->lock, locktype);
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
return (ISC_R_NOTFOUND);
}
if (algorithm != NULL && !dns_name_equal(key->algorithm, algorithm)) {
RWUNLOCK(&ring->lock, locktype);
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
return (ISC_R_NOTFOUND);
}
if (key->inception != key->expire && isc_serial_lt(key->expire, now)) {
/*
* The key has expired.
*/
if (locktype == isc_rwlocktype_read) {
RWUNLOCK(&ring->lock, locktype);
locktype = isc_rwlocktype_write;
goto again;
}
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
RWLOCK(&ring->lock, isc_rwlocktype_write);
remove_fromring(key);
RWUNLOCK(&ring->lock, locktype);
RWUNLOCK(&ring->lock, isc_rwlocktype_write);
return (ISC_R_NOTFOUND);
}
#if 0
@@ -1809,7 +1803,7 @@ again:
}
#endif /* if 0 */
isc_refcount_increment(&key->refs);
RWUNLOCK(&ring->lock, locktype);
RWUNLOCK(&ring->lock, isc_rwlocktype_read);
adjust_lru(key);
*tsigkey = key;
return (ISC_R_SUCCESS);
+38 -31
View File
@@ -1104,8 +1104,8 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
* 'rdataset'. If found, build a dst_key_t for it and point val->key at
* it.
*
* If val->key is already non-NULL, start searching from the next position in
* 'rdataset' to find the *next* key that could have signed 'siginfo', then
* If val->key is already non-NULL, locate it in the rdataset and then
* search past it for the *next* key that could have signed 'siginfo', then
* set val->key to that.
*
* Returns ISC_R_SUCCESS if a possible matching key has been found,
@@ -1118,59 +1118,59 @@ select_signing_key(dns_validator_t *val, dns_rdataset_t *rdataset) {
isc_buffer_t b;
dns_rdata_t rdata = DNS_RDATA_INIT;
dst_key_t *oldkey = val->key;
bool no_rdata = false;
bool foundold;
if (oldkey == NULL) {
result = dns_rdataset_first(rdataset);
foundold = true;
} else {
dst_key_free(&oldkey);
foundold = false;
val->key = NULL;
result = dns_rdataset_next(rdataset);
}
if (result != ISC_R_SUCCESS) {
goto done;
}
result = dns_rdataset_first(rdataset);
if (result != ISC_R_SUCCESS) {
goto failure;
}
do {
dns_rdataset_current(rdataset, &rdata);
isc_buffer_init(&b, rdata.data, rdata.length);
isc_buffer_add(&b, rdata.length);
INSIST(val->key == NULL);
result = dst_key_fromdns_ex(&siginfo->signer, rdata.rdclass, &b,
val->view->mctx, no_rdata,
&val->key);
result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b,
val->view->mctx, &val->key);
if (result == ISC_R_SUCCESS) {
if (siginfo->algorithm ==
(dns_secalg_t)dst_key_alg(val->key) &&
siginfo->keyid ==
(dns_keytag_t)dst_key_id(val->key) &&
(dst_key_flags(val->key) & DNS_KEYFLAG_REVOKE) ==
0 &&
dst_key_iszonekey(val->key))
{
if (no_rdata) {
/* Retry with full key */
dns_rdata_reset(&rdata);
dst_key_free(&val->key);
no_rdata = false;
continue;
if (foundold) {
/*
* This is the key we're looking for.
*/
return (ISC_R_SUCCESS);
} else if (dst_key_compare(oldkey, val->key)) {
foundold = true;
dst_key_free(&oldkey);
}
/* This is the key we're looking for. */
goto done;
}
dst_key_free(&val->key);
}
dns_rdata_reset(&rdata);
result = dns_rdataset_next(rdataset);
no_rdata = true;
} while (result == ISC_R_SUCCESS);
done:
if (result == ISC_R_NOMORE) {
result = ISC_R_NOTFOUND;
}
failure:
if (oldkey != NULL) {
dst_key_free(&oldkey);
}
return (result);
}
@@ -1589,9 +1589,20 @@ validate_answer(dns_validator_t *val, bool resume) {
continue;
}
vresult = verify(val, val->key, &rdata, val->siginfo->keyid);
do {
isc_result_t tresult;
vresult = verify(val, val->key, &rdata,
val->siginfo->keyid);
if (vresult == ISC_R_SUCCESS) {
break;
}
tresult = select_signing_key(val, val->keyset);
if (tresult != ISC_R_SUCCESS) {
break;
}
} while (1);
if (vresult != ISC_R_SUCCESS) {
val->failed = true;
validator_log(val, ISC_LOG_DEBUG(3),
"failed to verify rdataset");
} else {
@@ -1628,13 +1639,9 @@ validate_answer(dns_validator_t *val, bool resume) {
} else {
validator_log(val, ISC_LOG_DEBUG(3),
"verify failure: %s",
isc_result_totext(vresult));
isc_result_totext(result));
resume = false;
}
if (val->failed) {
result = ISC_R_NOMORE;
break;
}
}
if (result != ISC_R_NOMORE) {
validator_log(val, ISC_LOG_DEBUG(3),
+4 -4
View File
@@ -2339,7 +2339,7 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
isc_result_totext(result));
goto cleanup;
}
dns_db_settask(db, zone->task, zone->task);
dns_db_settask(db, zone->task);
if (zone->type == dns_zone_primary ||
zone->type == dns_zone_secondary || zone->type == dns_zone_mirror)
@@ -14791,7 +14791,7 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
isc_result_totext(result));
goto cleanup;
}
dns_db_settask(stub->db, zone->task, zone->task);
dns_db_settask(stub->db, zone->task);
}
result = dns_db_newversion(stub->db, &stub->version);
@@ -16235,7 +16235,7 @@ dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
isc_task_attach(task, &zone->task);
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
if (zone->db != NULL) {
dns_db_settask(zone->db, zone->task, zone->task);
dns_db_settask(zone->db, zone->task);
}
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
UNLOCK_ZONE(zone);
@@ -17508,7 +17508,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
zone_detachdb(zone);
}
zone_attachdb(zone, db);
dns_db_settask(zone->db, zone->task, zone->task);
dns_db_settask(zone->db, zone->task);
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
return (ISC_R_SUCCESS);
+4 -51
View File
@@ -93,54 +93,11 @@ maybe_rehash(isc_ht_t *ht, size_t newcount);
static isc_result_t
isc__ht_iter_next(isc_ht_iter_t *it);
static uint8_t maptolower[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
0xfc, 0xfd, 0xfe, 0xff
};
static int
memcasecmp(const void *vs1, const void *vs2, size_t len) {
uint8_t const *s1 = vs1;
uint8_t const *s2 = vs2;
for (size_t i = 0; i < len; i++) {
uint8_t u1 = s1[i];
uint8_t u2 = s2[i];
int U1 = maptolower[u1];
int U2 = maptolower[u2];
int diff = U1 - U2;
if (diff) {
return diff;
}
}
return 0;
}
static bool
isc__ht_node_match(isc_ht_node_t *node, const uint32_t hashval,
const uint8_t *key, uint32_t keysize, bool case_sensitive) {
const uint8_t *key, uint32_t keysize) {
return (node->hashval == hashval && node->keysize == keysize &&
(case_sensitive ? (memcmp(node->key, key, keysize) == 0)
: (memcasecmp(node->key, key, keysize) == 0)));
memcmp(node->key, key, keysize) == 0);
}
static uint32_t
@@ -384,9 +341,7 @@ nexttable:
for (isc_ht_node_t *node = ht->table[findex][hash]; node != NULL;
node = node->next)
{
if (isc__ht_node_match(node, hashval, key, keysize,
ht->case_sensitive))
{
if (isc__ht_node_match(node, hashval, key, keysize)) {
return (node);
}
}
@@ -435,9 +390,7 @@ isc__ht_delete(isc_ht_t *ht, const unsigned char *key, const uint32_t keysize,
for (isc_ht_node_t *node = ht->table[idx][hash]; node != NULL;
prev = node, node = node->next)
{
if (isc__ht_node_match(node, hashval, key, keysize,
ht->case_sensitive))
{
if (isc__ht_node_match(node, hashval, key, keysize)) {
if (prev == NULL) {
ht->table[idx][hash] = node->next;
} else {
-3
View File
@@ -750,9 +750,6 @@ isc_nm_verify_tls_peer_result_string(const isc_nmhandle_t *handle);
* \li 'handle' is a valid netmgr handle object.
*/
#define ISC_NM_TASK_SLOW_OFFSET -2
#define ISC_NM_TASK_SLOW(i) (ISC_NM_TASK_SLOW_OFFSET - 1 - i)
void
isc_nm_task_enqueue(isc_nm_t *mgr, isc_task_t *task, int threadid);
/*%<
+4 -6
View File
@@ -13,7 +13,6 @@
#pragma once
#include <isc/atomic.h>
#include <isc/result.h>
/*! \file isc/types.h
@@ -75,11 +74,10 @@ typedef struct isc_rwlock isc_rwlock_t; /*%< Read Write Lock */
typedef struct isc_sockaddr isc_sockaddr_t; /*%< Socket Address */
typedef ISC_LIST(isc_sockaddr_t) isc_sockaddrlist_t; /*%< Socket Address List
* */
typedef struct isc_stats isc_stats_t; /*%< Statistics */
typedef int_fast64_t isc_statscounter_t;
typedef atomic_int_fast64_t isc_atomic_statscounter_t;
typedef struct isc_symtab isc_symtab_t; /*%< Symbol Table */
typedef struct isc_task isc_task_t; /*%< Task */
typedef struct isc_stats isc_stats_t; /*%< Statistics */
typedef int_fast64_t isc_statscounter_t;
typedef struct isc_symtab isc_symtab_t; /*%< Symbol Table */
typedef struct isc_task isc_task_t; /*%< Task */
typedef ISC_LIST(isc_task_t) isc_tasklist_t; /*%< Task List */
typedef struct isc_taskmgr isc_taskmgr_t; /*%< Task Manager */
typedef struct isc_textregion isc_textregion_t; /*%< Text Region */
+9 -9
View File
@@ -2969,7 +2969,7 @@ isc__nm_http_set_max_streams(isc_nmsocket_t *listener,
void
isc_nm_http_set_endpoints(isc_nmsocket_t *listener,
isc_nm_http_endpoints_t *eps) {
size_t nlisteners;
size_t nworkers;
REQUIRE(VALID_NMSOCK(listener));
REQUIRE(listener->type == isc_nm_httplistener);
@@ -2977,8 +2977,8 @@ isc_nm_http_set_endpoints(isc_nmsocket_t *listener,
atomic_store(&eps->in_use, true);
nlisteners = (size_t)listener->mgr->nlisteners;
for (size_t i = 0; i < nlisteners; i++) {
nworkers = (size_t)listener->mgr->nworkers;
for (size_t i = 0; i < nworkers; i++) {
isc__netievent__http_eps_t *ievent =
isc__nm_get_netievent_httpendpoints(listener->mgr,
listener, eps);
@@ -3003,20 +3003,20 @@ isc__nm_async_httpendpoints(isc__networker_t *worker, isc__netievent_t *ev0) {
static void
http_init_listener_endpoints(isc_nmsocket_t *listener,
isc_nm_http_endpoints_t *epset) {
size_t nlisteners;
size_t nworkers;
REQUIRE(VALID_NMSOCK(listener));
REQUIRE(VALID_NM(listener->mgr));
REQUIRE(VALID_HTTP_ENDPOINTS(epset));
nlisteners = (size_t)listener->mgr->nlisteners;
INSIST(nlisteners > 0);
nworkers = (size_t)listener->mgr->nworkers;
INSIST(nworkers > 0);
listener->h2.listener_endpoints =
isc_mem_get(listener->mgr->mctx,
sizeof(isc_nm_http_endpoints_t *) * nlisteners);
listener->h2.n_listener_endpoints = nlisteners;
for (size_t i = 0; i < nlisteners; i++) {
sizeof(isc_nm_http_endpoints_t *) * nworkers);
listener->h2.n_listener_endpoints = nworkers;
for (size_t i = 0; i < nworkers; i++) {
listener->h2.listener_endpoints[i] = NULL;
isc_nm_http_endpoints_attach(
epset, &listener->h2.listener_endpoints[i]);
-1
View File
@@ -776,7 +776,6 @@ struct isc_nm {
isc_refcount_t references;
isc_mem_t *mctx;
int nworkers;
int nlisteners;
isc_mutex_t lock;
isc_condition_t wkstatecond;
isc_condition_t wkpausecond;
+14 -24
View File
@@ -189,12 +189,12 @@ isc__nm_force_tid(int tid) {
}
static void
isc__nm_threadpool_initialize(uint32_t nworkers) {
isc__nm_threadpool_initialize(uint32_t workers) {
char buf[11];
int r = uv_os_getenv("UV_THREADPOOL_SIZE", buf,
&(size_t){ sizeof(buf) });
if (r == UV_ENOENT) {
snprintf(buf, sizeof(buf), "%" PRIu32, nworkers);
snprintf(buf, sizeof(buf), "%" PRIu32, workers);
uv_os_setenv("UV_THREADPOOL_SIZE", buf);
}
}
@@ -212,11 +212,11 @@ isc__nm_threadpool_initialize(uint32_t nworkers) {
#endif
void
isc__netmgr_create(isc_mem_t *mctx, uint32_t nworkers, isc_nm_t **netmgrp) {
isc__netmgr_create(isc_mem_t *mctx, uint32_t workers, isc_nm_t **netmgrp) {
isc_nm_t *mgr = NULL;
char name[32];
REQUIRE(nworkers > 0);
REQUIRE(workers > 0);
#ifdef MAXIMAL_UV_VERSION
if (uv_version() > MAXIMAL_UV_VERSION) {
@@ -234,13 +234,10 @@ isc__netmgr_create(isc_mem_t *mctx, uint32_t nworkers, isc_nm_t **netmgrp) {
uv_version_string(), UV_VERSION_STRING);
}
isc__nm_threadpool_initialize(nworkers);
isc__nm_threadpool_initialize(workers);
mgr = isc_mem_get(mctx, sizeof(*mgr));
*mgr = (isc_nm_t){
.nworkers = nworkers * 2,
.nlisteners = nworkers,
};
*mgr = (isc_nm_t){ .nworkers = workers };
isc_mem_attach(mctx, &mgr->mctx);
isc_mutex_init(&mgr->lock);
@@ -275,12 +272,11 @@ isc__netmgr_create(isc_mem_t *mctx, uint32_t nworkers, isc_nm_t **netmgrp) {
atomic_init(&mgr->keepalive, 30000);
atomic_init(&mgr->advertised, 30000);
isc_barrier_init(&mgr->pausing, mgr->nworkers);
isc_barrier_init(&mgr->resuming, mgr->nworkers);
isc_barrier_init(&mgr->pausing, workers);
isc_barrier_init(&mgr->resuming, workers);
mgr->workers = isc_mem_get(mctx,
mgr->nworkers * sizeof(isc__networker_t));
for (int i = 0; i < mgr->nworkers; i++) {
mgr->workers = isc_mem_get(mctx, workers * sizeof(isc__networker_t));
for (size_t i = 0; i < workers; i++) {
isc__networker_t *worker = &mgr->workers[i];
int r;
@@ -314,7 +310,7 @@ isc__netmgr_create(isc_mem_t *mctx, uint32_t nworkers, isc_nm_t **netmgrp) {
mgr->workers_running++;
isc_thread_create(nm_thread, &mgr->workers[i], &worker->thread);
snprintf(name, sizeof(name), "isc-net-%04d", i);
snprintf(name, sizeof(name), "isc-net-%04zu", i);
isc_thread_setname(worker->thread, name);
}
@@ -821,15 +817,9 @@ isc_nm_task_enqueue(isc_nm_t *nm, isc_task_t *task, int threadid) {
isc__networker_t *worker = NULL;
if (threadid == -1) {
tid = (int)isc_random_uniform(nm->nlisteners);
} else if (threadid == ISC_NM_TASK_SLOW_OFFSET) {
tid = nm->nlisteners +
(int)isc_random_uniform(nm->nworkers - nm->nlisteners);
} else if (threadid < ISC_NM_TASK_SLOW_OFFSET) {
tid = nm->nlisteners + (ISC_NM_TASK_SLOW(threadid) %
(nm->nworkers - nm->nlisteners));
tid = (int)isc_random_uniform(nm->nworkers);
} else {
tid = threadid % nm->nlisteners;
tid = threadid % nm->nworkers;
}
worker = &nm->workers[tid];
@@ -3788,7 +3778,7 @@ isc__nm_async_settlsctx(isc__networker_t *worker, isc__netievent_t *ev0) {
static void
set_tlsctx_workers(isc_nmsocket_t *listener, isc_tlsctx_t *tlsctx) {
/* Update the TLS context reference for every worker thread. */
for (size_t i = 0; i < (size_t)listener->mgr->nlisteners; i++) {
for (size_t i = 0; i < (size_t)listener->mgr->nworkers; i++) {
isc__netievent__tlsctx_t *ievent =
isc__nm_get_netievent_settlsctx(listener->mgr, listener,
tlsctx);
+3 -3
View File
@@ -341,7 +341,7 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
isc__nm_connectcb(sock, req, result, false);
} else {
isc__nmsocket_clearcb(sock);
sock->tid = isc_random_uniform(mgr->nlisteners);
sock->tid = isc_random_uniform(mgr->nworkers);
isc__nm_connectcb(sock, req, result, true);
}
atomic_store(&sock->closed, true);
@@ -362,7 +362,7 @@ isc_nm_tcpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
isc__nm_put_netievent_tcpconnect(mgr, ievent);
} else {
atomic_init(&sock->active, false);
sock->tid = isc_random_uniform(mgr->nlisteners);
sock->tid = isc_random_uniform(mgr->nworkers);
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
(isc__netievent_t *)ievent);
}
@@ -457,7 +457,7 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_sockaddr_t *iface,
isc__nmsocket_init(sock, mgr, isc_nm_tcplistener, iface);
atomic_init(&sock->rchildren, 0);
sock->nchildren = mgr->nlisteners;
sock->nchildren = mgr->nworkers;
children_size = sock->nchildren * sizeof(sock->children[0]);
sock->children = isc_mem_get(mgr->mctx, children_size);
memset(sock->children, 0, children_size);
+2 -9
View File
@@ -324,7 +324,7 @@ isc_nm_tcpdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
isc__nm_put_netievent_tcpdnsconnect(mgr, ievent);
} else {
atomic_init(&sock->active, false);
sock->tid = isc_random_uniform(mgr->nlisteners);
sock->tid = isc_random_uniform(mgr->nworkers);
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
(isc__netievent_t *)ievent);
}
@@ -422,7 +422,7 @@ isc_nm_listentcpdns(isc_nm_t *mgr, isc_sockaddr_t *iface,
isc__nmsocket_init(sock, mgr, isc_nm_tcpdnslistener, iface);
atomic_init(&sock->rchildren, 0);
sock->nchildren = mgr->nlisteners;
sock->nchildren = mgr->nworkers;
children_size = sock->nchildren * sizeof(sock->children[0]);
sock->children = isc_mem_get(mgr->mctx, children_size);
memset(sock->children, 0, children_size);
@@ -808,13 +808,6 @@ isc__nm_tcpdns_processbuffer(isc_nmsocket_t *sock) {
return (ISC_R_CANCELED);
}
if (sock->client && !sock->recv_read) {
/*
* We are not reading data - stop here.
*/
return (ISC_R_CANCELED);
}
req = isc__nm_get_read_req(sock, NULL);
REQUIRE(VALID_UVREQ(req));
+2 -9
View File
@@ -419,7 +419,7 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
isc__nm_put_netievent_tlsdnsconnect(mgr, ievent);
} else {
atomic_init(&sock->active, false);
sock->tid = isc_random_uniform(mgr->nlisteners);
sock->tid = isc_random_uniform(mgr->nworkers);
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
(isc__netievent_t *)ievent);
}
@@ -532,7 +532,7 @@ isc_nm_listentlsdns(isc_nm_t *mgr, isc_sockaddr_t *iface,
isc__nmsocket_init(sock, mgr, isc_nm_tlsdnslistener, iface);
atomic_init(&sock->rchildren, 0);
sock->nchildren = mgr->nlisteners;
sock->nchildren = mgr->nworkers;
children_size = sock->nchildren * sizeof(sock->children[0]);
sock->children = isc_mem_get(mgr->mctx, children_size);
memset(sock->children, 0, children_size);
@@ -1016,13 +1016,6 @@ isc__nm_tlsdns_processbuffer(isc_nmsocket_t *sock) {
return (ISC_R_CANCELED);
}
if (sock->client && !sock->recv_read) {
/*
* We are not reading data - stop here.
*/
return (ISC_R_CANCELED);
}
req = isc__nm_get_read_req(sock, NULL);
REQUIRE(VALID_UVREQ(req));
+6 -6
View File
@@ -1264,18 +1264,18 @@ isc__nm_tls_verify_tls_peer_result_string(const isc_nmhandle_t *handle) {
static void
tls_init_listener_tlsctx(isc_nmsocket_t *listener, isc_tlsctx_t *ctx) {
size_t nlisteners;
size_t nworkers;
REQUIRE(VALID_NM(listener->mgr));
REQUIRE(ctx != NULL);
nlisteners = (size_t)listener->mgr->nlisteners;
INSIST(nlisteners > 0);
nworkers = (size_t)listener->mgr->nworkers;
INSIST(nworkers > 0);
listener->tlsstream.listener_tls_ctx = isc_mem_get(
listener->mgr->mctx, sizeof(isc_tlsctx_t *) * nlisteners);
listener->tlsstream.n_listener_tls_ctx = nlisteners;
for (size_t i = 0; i < nlisteners; i++) {
listener->mgr->mctx, sizeof(isc_tlsctx_t *) * nworkers);
listener->tlsstream.n_listener_tls_ctx = nworkers;
for (size_t i = 0; i < nworkers; i++) {
listener->tlsstream.listener_tls_ctx[i] = NULL;
isc_tlsctx_attach(ctx,
&listener->tlsstream.listener_tls_ctx[i]);
+3 -3
View File
@@ -157,14 +157,14 @@ isc_nm_listenudp(isc_nm_t *mgr, isc_sockaddr_t *iface, isc_nm_recv_cb_t cb,
REQUIRE(VALID_NM(mgr));
/*
* We are creating mgr->nlisteners duplicated sockets, one
* We are creating mgr->nworkers duplicated sockets, one
* socket for each worker thread.
*/
sock = isc_mem_get(mgr->mctx, sizeof(isc_nmsocket_t));
isc__nmsocket_init(sock, mgr, isc_nm_udplistener, iface);
atomic_init(&sock->rchildren, 0);
sock->nchildren = mgr->nlisteners;
sock->nchildren = mgr->nworkers;
children_size = sock->nchildren * sizeof(sock->children[0]);
sock->children = isc_mem_get(mgr->mctx, children_size);
memset(sock->children, 0, children_size);
@@ -1037,7 +1037,7 @@ isc_nm_udpconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer,
isc__nm_put_netievent_udpconnect(mgr, event);
} else {
atomic_init(&sock->active, false);
sock->tid = isc_random_uniform(mgr->nlisteners);
sock->tid = isc_random_uniform(mgr->nworkers);
isc__nm_enqueue_ievent(&mgr->workers[sock->tid],
(isc__netievent_t *)event);
}
+8 -17
View File
@@ -28,22 +28,14 @@
#define ISC_STATS_MAGIC ISC_MAGIC('S', 't', 'a', 't')
#define ISC_STATS_VALID(x) ISC_MAGIC_VALID(x, ISC_STATS_MAGIC)
/*
* Statistics are counted with an atomic int_fast64_t but exported to functions
* taking uint64_t (isc_stats_dumper_t). A 128-bit native and fast architecture
* doesn't exist in reality so these two are the same thing in practise.
* However, a silent truncation happening silently in the future is still not
* acceptable.
*/
STATIC_ASSERT(sizeof(isc_statscounter_t) <= sizeof(uint64_t),
"Exported statistics must fit into the statistic counter size");
typedef atomic_int_fast64_t isc__atomic_statcounter_t;
struct isc_stats {
unsigned int magic;
isc_mem_t *mctx;
isc_refcount_t references;
int ncounters;
isc_atomic_statscounter_t *counters;
isc__atomic_statcounter_t *counters;
};
static isc_result_t
@@ -54,7 +46,7 @@ create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) {
REQUIRE(statsp != NULL && *statsp == NULL);
stats = isc_mem_get(mctx, sizeof(*stats));
counters_alloc_size = sizeof(isc_atomic_statscounter_t) * ncounters;
counters_alloc_size = sizeof(isc__atomic_statcounter_t) * ncounters;
stats->counters = isc_mem_get(mctx, counters_alloc_size);
isc_refcount_init(&stats->references, 1);
for (int i = 0; i < ncounters; i++) {
@@ -90,7 +82,7 @@ isc_stats_detach(isc_stats_t **statsp) {
if (isc_refcount_decrement(&stats->references) == 1) {
isc_refcount_destroy(&stats->references);
isc_mem_put(stats->mctx, stats->counters,
sizeof(isc_atomic_statscounter_t) *
sizeof(isc__atomic_statcounter_t) *
stats->ncounters);
isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats));
}
@@ -133,8 +125,7 @@ isc_stats_dump(isc_stats_t *stats, isc_stats_dumper_t dump_fn, void *arg,
REQUIRE(ISC_STATS_VALID(stats));
for (i = 0; i < stats->ncounters; i++) {
isc_statscounter_t counter =
atomic_load_acquire(&stats->counters[i]);
uint32_t counter = atomic_load_acquire(&stats->counters[i]);
if ((options & ISC_STATSDUMP_VERBOSE) == 0 && counter == 0) {
continue;
}
@@ -178,7 +169,7 @@ void
isc_stats_resize(isc_stats_t **statsp, int ncounters) {
isc_stats_t *stats;
size_t counters_alloc_size;
isc_atomic_statscounter_t *newcounters;
isc__atomic_statcounter_t *newcounters;
REQUIRE(statsp != NULL && *statsp != NULL);
REQUIRE(ISC_STATS_VALID(*statsp));
@@ -191,7 +182,7 @@ isc_stats_resize(isc_stats_t **statsp, int ncounters) {
}
/* Grow number of counters. */
counters_alloc_size = sizeof(isc_atomic_statscounter_t) * ncounters;
counters_alloc_size = sizeof(isc__atomic_statcounter_t) * ncounters;
newcounters = isc_mem_get(stats->mctx, counters_alloc_size);
for (int i = 0; i < ncounters; i++) {
atomic_init(&newcounters[i], 0);
@@ -201,7 +192,7 @@ isc_stats_resize(isc_stats_t **statsp, int ncounters) {
atomic_store_release(&newcounters[i], counter);
}
isc_mem_put(stats->mctx, stats->counters,
sizeof(isc_atomic_statscounter_t) * stats->ncounters);
sizeof(isc__atomic_statcounter_t) * stats->ncounters);
stats->counters = newcounters;
stats->ncounters = ncounters;
}
+12 -17
View File
@@ -465,10 +465,10 @@ static void
query_addnxrrsetnsec(query_ctx_t *qctx);
static isc_result_t
query_nxdomain(query_ctx_t *qctx, isc_result_t result);
query_nxdomain(query_ctx_t *qctx, isc_result_t res);
static isc_result_t
query_redirect(query_ctx_t *qctx, isc_result_t result);
query_redirect(query_ctx_t *qctx);
static isc_result_t
query_ncache(query_ctx_t *qctx, isc_result_t result);
@@ -6228,13 +6228,6 @@ query_lookup_stale(ns_client_t *client) {
query_ctx_t qctx;
qctx_init(client, NULL, client->query.qtype, &qctx);
if (DNS64(client)) {
qctx.qtype = qctx.type = dns_rdatatype_a;
qctx.dns64 = true;
}
if (DNS64EXCLUDE(client)) {
qctx.dns64_exclude = true;
}
dns_db_attach(client->view->cachedb, &qctx.db);
client->query.attributes &= ~NS_QUERYATTR_RECURSIONOK;
client->query.dboptions |= DNS_DBFIND_STALETIMEOUT;
@@ -7725,7 +7718,8 @@ query_usestale(query_ctx_t *qctx, isc_result_t result) {
* result from the search.
*/
static isc_result_t
query_gotanswer(query_ctx_t *qctx, isc_result_t result) {
query_gotanswer(query_ctx_t *qctx, isc_result_t res) {
isc_result_t result = res;
char errmsg[256];
CCTRACE(ISC_LOG_DEBUG(3), "query_gotanswer");
@@ -7801,7 +7795,7 @@ root_key_sentinel:
return (query_coveringnsec(qctx));
case DNS_R_NCACHENXDOMAIN:
result = query_redirect(qctx, result);
result = query_redirect(qctx);
if (result != ISC_R_COMPLETE) {
return (result);
}
@@ -9618,10 +9612,11 @@ query_addnxrrsetnsec(query_ctx_t *qctx) {
* Handle NXDOMAIN and empty wildcard responses.
*/
static isc_result_t
query_nxdomain(query_ctx_t *qctx, isc_result_t result) {
query_nxdomain(query_ctx_t *qctx, isc_result_t res) {
dns_section_t section;
uint32_t ttl;
bool empty_wild = (result == DNS_R_EMPTYWILD);
isc_result_t result = res;
bool empty_wild = (res == DNS_R_EMPTYWILD);
CCTRACE(ISC_LOG_DEBUG(3), "query_nxdomain");
@@ -9630,7 +9625,7 @@ query_nxdomain(query_ctx_t *qctx, isc_result_t result) {
INSIST(qctx->is_zone || REDIRECT(qctx->client));
if (!empty_wild) {
result = query_redirect(qctx, result);
result = query_redirect(qctx);
if (result != ISC_R_COMPLETE) {
return (result);
}
@@ -9718,7 +9713,7 @@ cleanup:
* redirecting, so query processing should continue past it.
*/
static isc_result_t
query_redirect(query_ctx_t *qctx, isc_result_t saved_result) {
query_redirect(query_ctx_t *qctx) {
isc_result_t result;
CCTRACE(ISC_LOG_DEBUG(3), "query_redirect");
@@ -9759,7 +9754,7 @@ query_redirect(query_ctx_t *qctx, isc_result_t saved_result) {
SAVE(qctx->client->query.redirect.rdataset, qctx->rdataset);
SAVE(qctx->client->query.redirect.sigrdataset,
qctx->sigrdataset);
qctx->client->query.redirect.result = saved_result;
qctx->client->query.redirect.result = DNS_R_NCACHENXDOMAIN;
dns_name_copy(qctx->fname, qctx->client->query.redirect.fname);
qctx->client->query.redirect.authoritative =
qctx->authoritative;
@@ -10420,7 +10415,7 @@ query_coveringnsec(query_ctx_t *qctx) {
* We now have the proof that we have an NXDOMAIN. Apply
* NXDOMAIN redirection if configured.
*/
result = query_redirect(qctx, DNS_R_COVERINGNSEC);
result = query_redirect(qctx);
if (result != ISC_R_COMPLETE) {
redirected = true;
goto cleanup;
-50
View File
@@ -312,57 +312,7 @@ ISC_RUN_TEST_IMPL(isc_ht_iterator) {
test_ht_iterator();
}
ISC_RUN_TEST_IMPL(isc_ht_case) {
isc_ht_t *ht = NULL;
void *f = NULL;
isc_result_t result = ISC_R_UNSET;
unsigned char lower[16] = { "test case" };
unsigned char same[16] = { "test case" };
unsigned char upper[16] = { "TEST CASE" };
unsigned char mixed[16] = { "tEsT CaSe" };
isc_ht_init(&ht, mctx, 8, ISC_HT_CASE_SENSITIVE);
assert_non_null(ht);
result = isc_ht_add(ht, lower, 16, (void *)lower);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_ht_add(ht, same, 16, (void *)same);
assert_int_equal(result, ISC_R_EXISTS);
result = isc_ht_add(ht, upper, 16, (void *)upper);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_ht_find(ht, mixed, 16, &f);
assert_int_equal(result, ISC_R_NOTFOUND);
assert_null(f);
isc_ht_destroy(&ht);
assert_null(ht);
isc_ht_init(&ht, mctx, 8, ISC_HT_CASE_INSENSITIVE);
assert_non_null(ht);
result = isc_ht_add(ht, lower, 16, (void *)lower);
assert_int_equal(result, ISC_R_SUCCESS);
result = isc_ht_add(ht, same, 16, (void *)same);
assert_int_equal(result, ISC_R_EXISTS);
result = isc_ht_add(ht, upper, 16, (void *)upper);
assert_int_equal(result, ISC_R_EXISTS);
result = isc_ht_find(ht, mixed, 16, &f);
assert_int_equal(result, ISC_R_SUCCESS);
assert_ptr_equal(f, &lower);
isc_ht_destroy(&ht);
assert_null(ht);
}
ISC_TEST_LIST_START
ISC_TEST_ENTRY(isc_ht_case)
ISC_TEST_ENTRY(isc_ht_20)
ISC_TEST_ENTRY(isc_ht_8)
ISC_TEST_ENTRY(isc_ht_1)
-172
View File
@@ -2401,176 +2401,6 @@ ISC_RUN_TEST_IMPL(tlsdns_recv_one) {
atomic_assert_int_eq(ssends, 0);
}
static void
tlsdns_many_listen_read_cb(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *cbarg) {
uint64_t magic = 0;
isc_nmhandle_t *sendhandle = NULL;
isc_buffer_t *send_data = (isc_buffer_t *)cbarg;
isc_region_t send_messages = { 0 };
assert_non_null(handle);
assert_non_null(send_data);
F();
if (eresult != ISC_R_SUCCESS) {
goto unref;
}
atomic_fetch_add(&sreads, 1);
assert_true(region->length >= sizeof(magic));
memmove(&magic, region->base + sizeof(uint16_t), sizeof(magic));
assert_true(magic == stop_magic || magic == send_magic);
isc_nmhandle_attach(handle, &sendhandle);
isc_refcount_increment0(&active_ssends);
isc_nmhandle_setwritetimeout(sendhandle, T_IDLE);
/* send multiple DNS messages at once */
isc_buffer_usedregion(send_data, &send_messages);
isc_nm_send(sendhandle, &send_messages, listen_send_cb, cbarg);
unref:
isc_refcount_decrement(&active_sreads);
isc_nmhandle_detach(&handle);
}
static isc_result_t
tlsdns_many_listen_accept_cb(isc_nmhandle_t *handle, isc_result_t eresult,
void *cbarg) {
isc_nmhandle_t *readhandle = NULL;
UNUSED(cbarg);
F();
if (eresult != ISC_R_SUCCESS) {
return (eresult);
}
atomic_fetch_add(&saccepts, 1);
isc_refcount_increment0(&active_sreads);
isc_nmhandle_attach(handle, &readhandle);
isc_nm_read(handle, tlsdns_many_listen_read_cb, cbarg);
return (ISC_R_SUCCESS);
}
static void
tlsdns_many_connect_read_cb(isc_nmhandle_t *handle, isc_result_t eresult,
isc_region_t *region, void *cbarg) {
isc_nmhandle_t *sendhandle = NULL;
uint64_t magic = 0;
UNUSED(cbarg);
assert_non_null(handle);
F();
if (eresult != ISC_R_SUCCESS) {
goto unref;
}
assert_true(region->length >= sizeof(magic));
atomic_fetch_add(&creads, 1);
memmove(&magic, region->base, sizeof(magic));
assert_true(magic == stop_magic || magic == send_magic);
isc_refcount_increment0(&active_csends);
isc_nmhandle_attach(handle, &sendhandle);
isc_nmhandle_setwritetimeout(handle, T_IDLE);
/*
* At this point the read is completed, so we should stop that -
* but the sending code will make a cycling through input
* attempt. When not properly handled, this situation will cause
* excessive reads.
*/
isc_nm_send(sendhandle, &send_msg, connect_send_cb, NULL);
unref:
isc_refcount_decrement(&active_creads);
isc_nmhandle_detach(&handle);
}
/*
* A unit test *VERY* specific to #4487 - it would crash the unit test
* suite without the related fix due to excessive/unexpected reads.
*
* The intention behind the test is to (needlessly ;-)) prove that the
* author of the fix is not fantasising and excessive reads are
* possible in principle. Also, it proves that there is more than one
* way to do that.
*
* It is *not* reproducing the situation from the bug report 1:1, as
* it is impossible to understand what exactly was going on with this
* custom/proprietary server without having access to it (and even in
* that case the bug was hard to reproduce to the point, where the
* reporters considered it to be fixed for a while). There are far too
* many things a play.
*/
ISC_RUN_TEST_IMPL(tlsdns_server_send_many_recv_one) {
isc_result_t result = ISC_R_SUCCESS;
isc_nmsocket_t *listen_sock = NULL;
uint8_t buf[512];
isc_buffer_t server_send_buf = { 0 };
isc_buffer_init(&server_send_buf, buf, sizeof(buf));
/*
* Prepare a buffer with three "DNS" messages which we will send
* at once (our code does not normally do that do that).
*/
isc_buffer_putuint16(&server_send_buf, (uint16_t)send_msg.length);
isc_buffer_putmem(&server_send_buf, send_msg.base, send_msg.length);
isc_buffer_putuint16(&server_send_buf, (uint16_t)send_msg.length);
isc_buffer_putmem(&server_send_buf, send_msg.base, send_msg.length);
isc_buffer_putuint16(&server_send_buf, (uint16_t)send_msg.length);
isc_buffer_putmem(&server_send_buf, send_msg.base, send_msg.length);
atomic_store(&nsends, 1);
result = isc_nm_listentls(
listen_nm, &tcp_listen_addr, tlsdns_many_listen_accept_cb,
&server_send_buf, 0, 0, NULL, tcp_listen_tlsctx, &listen_sock);
assert_int_equal(result, ISC_R_SUCCESS);
connect_readcb = tlsdns_many_connect_read_cb;
isc_refcount_increment0(&active_cconnects);
isc_nm_tlsdnsconnect(connect_nm, &tcp_connect_addr, &tcp_listen_addr,
connect_connect_cb, NULL, T_CONNECT, 0,
tcp_connect_tlsctx, tcp_tlsctx_client_sess_cache);
WAIT_FOR_EQ(cconnects, 1);
WAIT_FOR_LE(nsends, 0);
WAIT_FOR_EQ(csends, 2);
WAIT_FOR_EQ(sreads, 1);
WAIT_FOR_EQ(ssends, 1);
WAIT_FOR_EQ(creads, 1);
isc_nm_stoplistening(listen_sock);
isc_nmsocket_close(&listen_sock);
assert_null(listen_sock);
isc__netmgr_shutdown(connect_nm);
X(cconnects);
X(csends);
X(creads);
X(sreads);
X(ssends);
atomic_assert_int_eq(cconnects, 1);
atomic_assert_int_eq(csends, 2);
atomic_assert_int_eq(creads, 1);
atomic_assert_int_eq(sreads, 1);
atomic_assert_int_eq(ssends, 1);
}
ISC_RUN_TEST_IMPL(tlsdns_recv_two) {
isc_result_t result = ISC_R_SUCCESS;
isc_nmsocket_t *listen_sock = NULL;
@@ -3049,8 +2879,6 @@ ISC_TEST_ENTRY_CUSTOM(tls_half_recv_half_send_quota_sendback, setup_test,
/* TLSDNS */
ISC_TEST_ENTRY_CUSTOM(tlsdns_recv_one, setup_test, teardown_test)
ISC_TEST_ENTRY_CUSTOM(tlsdns_server_send_many_recv_one, setup_test,
teardown_test)
ISC_TEST_ENTRY_CUSTOM(tlsdns_recv_two, setup_test, teardown_test)
ISC_TEST_ENTRY_CUSTOM(tlsdns_noop, setup_test, teardown_test)
ISC_TEST_ENTRY_CUSTOM(tlsdns_noresponse, setup_test, teardown_test)