...
 
Commits (33)
......@@ -467,6 +467,7 @@ pylint:
tarball-create:
stage: precheck
<<: *base_image
<<: *default_triggering_rules
script:
- *configure
- make -j${BUILD_PARALLEL_JOBS:-1} all V=1
......@@ -477,8 +478,6 @@ tarball-create:
needs:
- job: autoreconf
artifacts: true
only:
- tags
# Jobs for doc builds on Debian 10 "buster" (amd64)
......
5475. [bug] Fix RPZ wildcard passthru ignored when a rejection
would overwrite a passthru action matching some
rule in a previously loaded passthru rpz zone.
[GL #1619]
5474. [bug] dns_rdata_hip_next() failed to return ISC_R_NOMORE
when it should have. [GL !3880]
5473. [func] The rbt hashtable implementation has been changed
to use faster hash-function (HalfSipHash2-4) and
uses Fibonacci hashing for better distribution.
Setting the max-cache-size now preallocates fixed
size hashtable, so the rehashing doesn't cause
resolution brownouts when growing the hashtable.
[GL #1775]
5472. [func] The statistics channel has been updated to use the
new network manager. [GL #2022]
......
......@@ -15,6 +15,7 @@ AM_CPPFLAGS += \
$(LMDB_CFLAGS) \
$(MAXMINDDB_CFLAGS) \
$(DNSTAP_CFLAGS) \
$(LIBUV_CFLAGS) \
$(ZLIB_CFLAGS)
if HAVE_JSON_C
......@@ -102,6 +103,7 @@ named_LDADD = \
$(LMDB_LIBS) \
$(MAXMINDDB_LIBS) \
$(DNSTAP_LIBS) \
$(LIBUV_LIBS) \
$(LIBXML2_LIBS) \
$(ZLIB_LIBS)
......
......@@ -16,6 +16,7 @@
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#include <isc/app.h>
#include <isc/attributes.h>
......@@ -525,6 +526,9 @@ printversion(bool verbose) {
printf("linked to OpenSSL version: %s\n",
SSLeay_version(SSLEAY_VERSION));
#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
printf("compiled with libuv version: %d.%d.%d\n", UV_VERSION_MAJOR,
UV_VERSION_MINOR, UV_VERSION_PATCH);
printf("linked to libuv version: %s\n", uv_version_string());
#ifdef HAVE_LIBXML2
printf("compiled with libxml2 version: %s\n", LIBXML_DOTTED_VERSION);
printf("linked to libxml2 version: %s\n", xmlParserVersion);
......
......@@ -10116,7 +10116,7 @@ named_server_destroy(named_server_t **serverp) {
static void
fatal(named_server_t *server, const char *msg, isc_result_t result) {
if (server != NULL) {
if (server != NULL && server->task != NULL) {
/*
* Prevent races between the OpenSSL on_exit registered
* function and any other OpenSSL calls from other tasks
......
......@@ -67,7 +67,7 @@
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
<BrowseInformation>true</BrowseInformation>
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>@OPENSSL_INC@@GSSAPI_INC@@GEOIP_INC@.\;..\..\..\;@LIBXML2_INC@..\win32\include;..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\isccc\include;..\..\..\lib\isccfg\include;..\..\..\lib\bind9\include;..\..\..\lib\ns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>@LIBUV_INC@@OPENSSL_INC@@GSSAPI_INC@@GEOIP_INC@.\;..\..\..\;@LIBXML2_INC@..\win32\include;..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\isccc\include;..\..\..\lib\isccfg\include;..\..\..\lib\bind9\include;..\..\..\lib\ns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
......@@ -75,7 +75,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<OutputFile>..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt)</OutputFile>
<AdditionalLibraryDirectories>..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccc\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);..\..\..\lib\ns\win32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>@OPENSSL_LIB@@LIBXML2_LIB@@GSSAPI_LIB@@GEOIP_LIB@libisc.lib;libdns.lib;libisccc.lib;libisccfg.lib;libbind9.lib;libns.lib;version.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>@LIBUV_LIB@@OPENSSL_LIB@@LIBXML2_LIB@@GSSAPI_LIB@@GEOIP_LIB@libisc.lib;libdns.lib;libisccc.lib;libisccfg.lib;libbind9.lib;libns.lib;version.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>cd ..
......@@ -103,7 +103,7 @@ perl -e "print \";\";" &gt;&gt; xsl.c
<ObjectFileName>.\$(Configuration)\</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
<ForcedIncludeFiles>..\..\..\config.h</ForcedIncludeFiles>
<AdditionalIncludeDirectories>@OPENSSL_INC@@GSSAPI_INC@@GEOIP_INC@.\;..\..\..\;@LIBXML2_INC@..\win32\include;..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\isccc\include;..\..\..\lib\isccfg\include;..\..\..\lib\bind9\include;..\..\..\lib\ns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>@LIBUV_INC@@OPENSSL_INC@@GSSAPI_INC@@GEOIP_INC@.\;..\..\..\;@LIBXML2_INC@..\win32\include;..\include;..\..\..\lib\isc\win32;..\..\..\lib\isc\win32\include;..\..\..\lib\isc\include;..\..\..\lib\dns\include;..\..\..\lib\isccc\include;..\..\..\lib\isccfg\include;..\..\..\lib\bind9\include;..\..\..\lib\ns\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
<Link>
......@@ -114,7 +114,7 @@ perl -e "print \";\";" &gt;&gt; xsl.c
<OutputFile>..\..\..\Build\$(Configuration)\$(TargetName)$(TargetExt)</OutputFile>
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
<AdditionalLibraryDirectories>..\..\..\lib\isc\win32\$(Configuration);..\..\..\lib\dns\win32\$(Configuration);..\..\..\lib\isccc\win32\$(Configuration);..\..\..\lib\isccfg\win32\$(Configuration);..\..\..\lib\bind9\win32\$(Configuration);..\..\..\lib\ns\win32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>@OPENSSL_LIB@@LIBXML2_LIB@@GSSAPI_LIB@@GEOIP_LIB@libisc.lib;libdns.lib;libisccc.lib;libisccfg.lib;libbind9.lib;libns.lib;version.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>@LIBUV_LIB@@OPENSSL_LIB@@LIBXML2_LIB@@GSSAPI_LIB@@GEOIP_LIB@libisc.lib;libdns.lib;libisccc.lib;libisccfg.lib;libbind9.lib;libns.lib;version.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>cd ..
......
#!/bin/sh
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# 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 http://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
. $SYSTEMTESTTOP/conf.sh
$FEATURETEST --have-dlopen || {
echo_i "dlopen() not supported - skipping dlzexternal test"
exit 255
}
exit 0
......@@ -589,7 +589,8 @@ static dns_dbmethods_t sampledb_methods = {
NULL, /* getsize */
NULL, /* setservestalettl */
NULL, /* getservestalettl */
NULL /* setgluecachestats */
NULL, /* setgluecachestats */
NULL /* adjusthashsize */
};
/* Auxiliary driver functions. */
......
#!/bin/sh
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# 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 http://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
. $SYSTEMTESTTOP/conf.sh
$FEATURETEST --have-dlopen || {
echo_i "dlopen() not supported - skipping dyndb test"
exit 255
}
exit 0
......@@ -40,7 +40,6 @@ usage(void) {
fprintf(stderr, " --enable-dnsrps\n");
fprintf(stderr, " --gethostname\n");
fprintf(stderr, " --gssapi\n");
fprintf(stderr, " --have-dlopen\n");
fprintf(stderr, " --have-geoip2\n");
fprintf(stderr, " --have-libxml2\n");
fprintf(stderr, " --ipv6only=no\n");
......@@ -110,10 +109,6 @@ main(int argc, char **argv) {
#endif /* HAVE_GSSAPI */
}
if (strcmp(argv[1], "--have-dlopen") == 0) {
return (0);
}
if (strcmp(argv[1], "--have-geoip2") == 0) {
#ifdef HAVE_GEOIP2
return (0);
......
#!/bin/sh
#
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# 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 http://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
. $SYSTEMTESTTOP/conf.sh
$FEATURETEST --have-dlopen || {
echo_i "dlopen() not supported - skipping filter-aaaa test"
exit 255
}
exit 0
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; 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 http://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 3600
@ IN SOA ns.example.com. root.example.com. 1 3600 3600 3600 3600
@ NS ns.example.com.
ns.example.com. A 10.53.0.1
@ A 1.2.3.4
www A 1.2.3.5
......@@ -58,11 +58,16 @@ zone "l2.l1.l0" {
};
zone "test1.example.net" {
type master;
file "test1.example.net.db";
type master;
file "test1.example.net.db";
};
zone "test2.example.net" {
type master;
file "test2.example.net.db";
type master;
file "test2.example.net.db";
};
zone "example.com" {
type master;
file "example.com.db";
};
$ORIGIN given.zone.
$TTL 3600
@ IN SOA ns.given.zone. hostmaster.given.zone. 1 600 300 604800 3600
IN NS ns.given.zone.
ns.given.zone. IN A 127.0.0.1
; this should be ignored as it matches an earlier passthru entry.
example.com CNAME .
; this should be ignored as it matches an earlier wildcard passthru entry.
www.example.com CNAME .
$ORIGIN passthru.zone.
$TTL 3600
@ IN SOA ns.passthru.zone. hostmaster.passthru.zone. 1 600 300 604800 3600
IN NS ns.passthru.zone.
ns.passthru.zone. IN A 127.0.0.1
example.com CNAME rpz-passthru.
*.example.com CNAME rpz-passthru.
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* 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 http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
# common configuration
include "named.conf.header";
view "recursive" {
# policy configuration to be tested
response-policy {
zone "passthru.zone" policy passthru;
zone "given.zone" policy given;
} qname-wait-recurse yes
nsdname-enable yes
nsip-enable yes;
# policy zones to be tested
zone "passthru.zone" { type master; file "db.passthru"; };
zone "given.zone" { type master; file "db.given"; };
zone "." {
type hint;
file "root.hint";
};
recursion yes;
dnssec-validation yes;
};
......@@ -473,6 +473,21 @@ for mode in native dnsrps; do
status=1
}
t=`expr $t + 1`
echo_i "testing wildcard passthru before explicit drop (${t})"
add_test_marker 10.53.0.2
run_server wildcard4
$DIG $DIGOPTS example.com a @10.53.0.2 -p ${PORT} > dig.out.${t}.1
grep "status: NOERROR" dig.out.${t}.1 > /dev/null || {
echo_i "test ${t} failed"
status=1
}
$DIG $DIGOPTS www.example.com a @10.53.0.2 -p ${PORT} > dig.out.${t}.2
grep "status: NOERROR" dig.out.${t}.2 > /dev/null || {
echo_i "test ${t} failed"
status=1
}
if [ "$mode" = "native" ]; then
# Check for invalid prefix length error
t=`expr $t + 1`
......
......@@ -131,17 +131,13 @@ start_servers() {
fi
}
stop_servers_failed() {
echoinfo "I:$systest:stopping servers failed"
echofail "R:$systest:FAIL"
echoend "E:$systest:$(date_with_args)"
exit 1
}
stop_servers() {
if $stopservers; then
echoinfo "I:$systest:stopping servers"
$PERL stop.pl "$systest" || stop_servers_failed
if ! $PERL stop.pl "$systest"; then
echoinfo "I:$systest:stopping servers failed"
return 1
fi
fi
}
......@@ -217,7 +213,7 @@ if [ -r "$systest/tests.sh" ]; then
( cd "$systest" && $SHELL tests.sh "$@" )
status=$?
run=$((run+1))
stop_servers
stop_servers || status=1
fi
if [ -n "$PYTEST" ]; then
......@@ -232,7 +228,7 @@ if [ -n "$PYTEST" ]; then
test_status=$(cat "$systest/$test.status")
fi
status=$((status+test_status))
stop_servers
stop_servers || status=1
done
else
echoinfo "I:$systest:pytest not installed, skipping python tests"
......@@ -250,54 +246,64 @@ else
exit $status
fi
if [ $status != 0 ]; then
get_core_dumps() {
find "$systest/" \( -name 'core*' -or -name '*.core' \) ! -name '*.gz' ! -name '*.txt' | sort
}
core_dumps=$(get_core_dumps | tr '\n' ' ')
assertion_failures=$(find "$systest/" -name named.run -print0 | xargs -0 grep "assertion failure" | wc -l)
sanitizer_summaries=$(find "$systest/" -name 'tsan.*' | wc -l)
if [ -n "$core_dumps" ]; then
status=1
echoinfo "I:$systest:Core dump(s) found: $core_dumps"
get_core_dumps | while read -r coredump; do
export SYSTESTDIR="$systest"
echoinfo "D:$systest:backtrace from $coredump:"
echoinfo "D:$systest:--------------------------------------------------------------------------------"
binary=$(gdb --batch --core="$coredump" 2>/dev/null | sed -ne "s/Core was generated by \`//;s/ .*'.$//p;")
"${top_builddir}/libtool" --mode=execute gdb \
-batch \
-ex bt \
-core="$coredump" \
-- \
"$binary" 2>/dev/null | sed -n '/^Core was generated by/,$p' | cat_d
echoinfo "D:$systest:--------------------------------------------------------------------------------"
coredump_backtrace=$(basename "${coredump}")-backtrace.txt
echoinfo "D:$systest:full backtrace from $coredump saved in $coredump_backtrace"
"${top_builddir}/libtool" --mode=execute gdb \
-batch \
-command=run.gdb \
-core="$coredump" \
-- \
"$binary" > "$coredump_backtrace" 2>&1
echoinfo "D:$systest:core dump $coredump archived as $coredump.gz"
gzip -1 "${coredump}"
done
elif [ "$assertion_failures" -ne 0 ]; then
status=1
SYSTESTDIR="$systest"
echoinfo "I:$systest:$assertion_failures assertion failure(s) found"
find "$systest/" -name 'tsan.*' -print0 | xargs -0 grep "SUMMARY: " | sort -u | cat_d
elif [ "$sanitizer_summaries" -ne 0 ]; then
status=1
echoinfo "I:$systest:$sanitizer_summaries sanitizer report(s) found"
fi
if [ $status -ne 0 ]; then
echofail "R:$systest:FAIL"
# Do not clean up - we need the evidence.
else
core_dumps="$(find "$systest/" -name 'core*' -or -name '*.core' | sort | tr '\n' ' ')"
assertion_failures=$(find "$systest/" -name named.run -print0 | xargs -0 grep "assertion failure" | wc -l)
sanitizer_summaries=$(find "$systest/" -name 'tsan.*' | wc -l)
if [ -n "$core_dumps" ]; then
echoinfo "I:$systest:Test claims success despite crashes: $core_dumps"
echofail "R:$systest:FAIL"
# Do not clean up - we need the evidence.
find "$systest/" -name 'core*' -or -name '*.core' | while read -r coredump; do
export SYSTESTDIR="$systest"
echoinfo "D:$systest:backtrace from $coredump start"
binary=$(gdb --batch --core="$coredump" | sed -ne "s/Core was generated by \`//;s/ .*'.$//p;")
"${top_builddir}/libtool" --mode=execute gdb \
--batch \
--command=run.gdb \
--core="$coredump" \
-- \
"$binary"
echoinfo "D:$systest:backtrace from $coredump end"
done
elif [ "$assertion_failures" -ne 0 ]; then
SYSTESTDIR="$systest"
echoinfo "I:$systest:Test claims success despite $assertion_failures assertion failure(s)"
find "$systest/" -name 'tsan.*' -print0 | xargs -0 grep "SUMMARY: " | sort -u | cat_d
echofail "R:$systest:FAIL"
# Do not clean up - we need the evidence.
elif [ "$sanitizer_summaries" -ne 0 ]; then
echoinfo "I:$systest:Test claims success despite $sanitizer_summaries sanitizer reports(s)"
echofail "R:$systest:FAIL"
else
echopass "R:$systest:PASS"
if $clean
then
( cd "${systest}" && $SHELL clean.sh "$@" )
if [ "${srcdir}" != "${builddir}" ]; then
rm -rf "./${systest}" ## FIXME (this also removes compiled binaries)
fi
if test -d ${srcdir}/../../../.git
then
git status -su --ignored "${systest}" 2>/dev/null | \
sed -n -e 's|^?? \(.*\)|I:file \1 not removed|p' \
-e 's|^!! \(.*/named.run\)$|I:file \1 not removed|p' \
-e 's|^!! \(.*/named.memstats\)$|I:file \1 not removed|p'
fi
fi
echopass "R:$systest:PASS"
if $clean; then
( cd "${systest}" && $SHELL clean.sh "$@" )
if [ "${srcdir}" != "${builddir}" ]; then
rm -rf "./${systest}" ## FIXME (this also removes compiled binaries)
fi
if test -d ${srcdir}/../../../.git; then
git status -su --ignored "${systest}" 2>/dev/null | \
sed -n -e 's|^?? \(.*\)|I:file \1 not removed|p' \
-e 's|^!! \(.*/named.run\)$|I:file \1 not removed|p' \
-e 's|^!! \(.*/named.memstats\)$|I:file \1 not removed|p'
fi
fi
fi
......
......@@ -57,7 +57,7 @@ gpos01.example. 3600 IN GPOS "-22.6882" "116.8652" "250.0"
gpos02.example. 3600 IN GPOS "" "" ""
hinfo01.example. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4"
hinfo02.example. 3600 IN HINFO "PC" "NetBSD"
hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip2.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
ipseckey01.example. 3600 IN IPSECKEY 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
ipseckey02.example. 3600 IN IPSECKEY 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==
......
......@@ -66,7 +66,7 @@ isdn01.example. 3600 IN ISDN "isdn-address"
isdn02.example. 3600 IN ISDN "isdn-address" "subaddress"
isdn03.example. 3600 IN ISDN "isdn-address"
isdn04.example. 3600 IN ISDN "isdn-address" "subaddress"
hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D
hip2.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D rvs.example.com.
dnskey01.example. 3600 IN DNSKEY 512 255 1 AQMFD5raczCJHViKtLYhWGz8hMY9UGRuniJDBzC7w0aRyzWZriO6i2od GWWQVucZqKVsENW91IOW4vqudngPZsY3GvQ/xVA8/7pyFj6b7Esga60z yGW6LFe9r8n6paHrlG5ojqf0BaqHT+8=
keydata.example. 3600 IN TYPE65533 \# 0
......
......@@ -650,19 +650,6 @@ AC_COMPILE_IFELSE(
AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])])
AC_MSG_CHECKING([for SipHash support])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([[#include <openssl/evp.h>
#include <openssl/opensslv.h>]],
[[#if OPENSSL_VERSION_NUMBER < 0x10101010L
#error OpenSSL >= 1.1.1a required for working SipHash initialization
#endif
EVP_PKEY *key = EVP_PKEY_new_raw_private_key(
EVP_PKEY_SIPHASH, NULL, NULL, 0);]])],
[AC_DEFINE([HAVE_OPENSSL_SIPHASH], [1], [define if OpenSSL supports SipHash])
AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])])
#
# Check for OpenSSL SHA-1 support
#
......
......@@ -39,7 +39,12 @@ New Features
Feature Changes
~~~~~~~~~~~~~~~
- None.
- BIND's cache database implementation has been updated to use a faster
hash-function with better distribution. In addition, the effective
max-cache-size (configured explicitly, defaulting to a value based on system
memory or set to 'unlimited') now pre-allocates fixed size hash tables. This
prevents interruption to query resolution when the hash tables need to be
increased in size. [GL #1775]
Bug Fixes
~~~~~~~~~
......
......@@ -756,7 +756,8 @@ grow_names(isc_task_t *task, isc_event_t *ev) {
isc_mutex_t *newnamelocks = NULL;
isc_result_t result;
unsigned int *newname_refcnt = NULL;
unsigned int i, n, bucket;
unsigned int i, n;
unsigned int bucket;
adb = ev->ev_arg;
INSIST(DNS_ADB_VALID(adb));
......@@ -4838,7 +4839,7 @@ void
dns_adb_flushname(dns_adb_t *adb, const dns_name_t *name) {
dns_adbname_t *adbname;
dns_adbname_t *nextname;
int bucket;
unsigned int bucket;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(name != NULL);
......
......@@ -285,7 +285,8 @@ dns_badcache_find(dns_badcache_t *bc, const dns_name_t *name,
dns_rdatatype_t type, uint32_t *flagp, isc_time_t *now) {
dns_bcentry_t *bad, *prev, *next;
bool answer = false;
unsigned int i, hash;
unsigned int i;
unsigned int hash;
REQUIRE(VALID_BADCACHE(bc));
REQUIRE(name != NULL);
......@@ -385,7 +386,7 @@ dns_badcache_flushname(dns_badcache_t *bc, const dns_name_t *name) {
dns_bcentry_t *bad, *prev, *next;
isc_result_t result;
isc_time_t now;
unsigned int i;
unsigned int hash;
REQUIRE(VALID_BADCACHE(bc));
REQUIRE(name != NULL);
......@@ -396,16 +397,16 @@ dns_badcache_flushname(dns_badcache_t *bc, const dns_name_t *name) {
if (result != ISC_R_SUCCESS) {
isc_time_settoepoch(&now);
}
i = dns_name_hash(name, false) % bc->size;
LOCK(&bc->tlocks[i]);
hash = dns_name_hash(name, false) % bc->size;
LOCK(&bc->tlocks[hash]);
prev = NULL;
for (bad = bc->table[i]; bad != NULL; bad = next) {
for (bad = bc->table[hash]; bad != NULL; bad = next) {
int n;
next = bad->next;
n = isc_time_compare(&bad->expire, &now);
if (n < 0 || dns_name_equal(name, &bad->name)) {
if (prev == NULL) {
bc->table[i] = bad->next;
bc->table[hash] = bad->next;
} else {
prev->next = bad->next;
}
......@@ -417,7 +418,7 @@ dns_badcache_flushname(dns_badcache_t *bc, const dns_name_t *name) {
prev = bad;
}
}
UNLOCK(&bc->tlocks[i]);
UNLOCK(&bc->tlocks[hash]);
RWUNLOCK(&bc->lock, isc_rwlocktype_read);
}
......
......@@ -956,6 +956,7 @@ dns_cache_setcachesize(dns_cache_t *cache, size_t size) {
* time, or replacing other limits).
*/
isc_mem_setwater(cache->mctx, water, cache, hiwater, lowater);
dns_db_adjusthashsize(cache->db, size);
}
}
......
......@@ -831,6 +831,17 @@ dns_db_hashsize(dns_db_t *db) {
return ((db->methods->hashsize)(db));
}
isc_result_t
dns_db_adjusthashsize(dns_db_t *db, size_t size) {
REQUIRE(DNS_DB_VALID(db));
if (db->methods->adjusthashsize != NULL) {
return ((db->methods->adjusthashsize)(db, size));
}
return (ISC_R_NOTIMPLEMENTED);
}
void
dns_db_settask(dns_db_t *db, isc_task_t *task) {
REQUIRE(DNS_DB_VALID(db));
......
......@@ -967,7 +967,8 @@ static dns_dbmethods_t rpsdb_db_methods = {
NULL, /* getsize */
NULL, /* setservestalettl */
NULL, /* getservestalettl */
NULL /* setgluecachestats */
NULL, /* setgluecachestats */
NULL /* adjusthashsize */
};
static dns_rdatasetmethods_t rpsdb_rdataset_methods = {
......
......@@ -179,6 +179,7 @@ typedef struct dns_dbmethods {
isc_result_t (*setservestalettl)(dns_db_t *db, dns_ttl_t ttl);
isc_result_t (*getservestalettl)(dns_db_t *db, dns_ttl_t *ttl);
isc_result_t (*setgluecachestats)(dns_db_t *db, isc_stats_t *stats);
isc_result_t (*adjusthashsize)(dns_db_t *db, size_t size);
} dns_dbmethods_t;
typedef isc_result_t (*dns_dbcreatefunc_t)(isc_mem_t * mctx,
......@@ -1363,6 +1364,23 @@ dns_db_hashsize(dns_db_t *db);
* 0 if not implemented.
*/
isc_result_t
dns_db_adjusthashsize(dns_db_t *db, size_t size);
/*%<
* For database implementations using a hash table, adjust
* the size of the hash table to store objects with size
* memory footprint.
*
* Requires:
*
* \li 'db' is a valid database.
* \li 'size' is maximum memory footprint of the database
*
* Returns:
* \li #ISC_R_SUCCESS The registration succeeded
* \li #ISC_R_NOMEMORY Out of memory
*/
void
dns_db_settask(dns_db_t *db, isc_task_t *task);
/*%<
......
......@@ -684,6 +684,17 @@ dns_rbt_hashsize(dns_rbt_t *rbt);
* \li rbt is a valid rbt manager.
*/
isc_result_t
dns_rbt_adjusthashsize(dns_rbt_t *rbt, size_t size);
/*%<
* Adjust the number of buckets in the 'rbt' hash table, according to the
* expected maximum size of the rbt database.
*
* Requires:
* \li rbt is a valid rbt manager.
* \li size is expected maximum memory footprint of rbt.
*/
void
dns_rbt_destroy(dns_rbt_t **rbtp);
isc_result_t
......
......@@ -464,7 +464,8 @@ dns_name_hash(const dns_name_t *name, bool case_sensitive) {
length = 16;
}
return (isc_hash_function(name->ndata, length, case_sensitive));
/* High bits are more random. */
return (isc_hash32(name->ndata, length, case_sensitive));
}
unsigned int
......@@ -478,7 +479,8 @@ dns_name_fullhash(const dns_name_t *name, bool case_sensitive) {
return (0);
}
return (isc_hash_function(name->ndata, name->length, case_sensitive));
/* High bits are more random. */
return (isc_hash32(name->ndata, name->length, case_sensitive));
}
dns_namereln_t
......
......@@ -59,13 +59,27 @@
#define CHAIN_MAGIC ISC_MAGIC('0', '-', '0', '-')
#define VALID_CHAIN(chain) ISC_MAGIC_VALID(chain, CHAIN_MAGIC)
#define RBT_HASH_SIZE 64
#define RBT_HASH_MIN_BITS 16
#define RBT_HASH_MAX_BITS 32
#define RBT_HASH_OVERCOMMIT 3
#define RBT_HASH_BUCKETSIZE 4096 /* FIXME: What would be a good value here? */
#ifdef RBT_MEM_TEST
#undef RBT_HASH_SIZE
#define RBT_HASH_SIZE 2 /*%< To give the reallocation code a workout. */
#endif /* ifdef RBT_MEM_TEST */
#define GOLDEN_RATIO_32 0x61C88647
#define HASHSIZE(bits) (UINT64_C(1) << (bits))
static inline uint32_t
hash_32(uint32_t val, unsigned int bits) {
REQUIRE(bits <= RBT_HASH_MAX_BITS);
/* High bits are more random. */
return (val * GOLDEN_RATIO_32 >> (32 - bits));
}
struct dns_rbt {
unsigned int magic;
isc_mem_t *mctx;
......@@ -73,7 +87,8 @@ struct dns_rbt {
void (*data_deleter)(void *, void *);
void *deleter_arg;
unsigned int nodecount;
size_t hashsize;
uint16_t hashbits;
uint16_t maxhashbits;
dns_rbtnode_t **hashtable;
void *mmap_location;
};
......@@ -384,8 +399,12 @@ hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node, const dns_name_t *name);
static inline void
unhash_node(dns_rbt_t *rbt, dns_rbtnode_t *node);
static uint32_t
rehash_bits(dns_rbt_t *rbt, size_t newcount);
static void
rehash(dns_rbt_t *rbt, unsigned int newcount);
rehash(dns_rbt_t *rbt, uint32_t newbits);
static void
maybe_rehash(dns_rbt_t *rbt, size_t size);
static inline void
rotate_left(dns_rbtnode_t *node, dns_rbtnode_t **rootp);
......@@ -920,7 +939,7 @@ dns_rbt_deserialize_tree(void *base_address, size_t filesize,
result = ISC_R_INVALIDFILE;
goto cleanup;
}
rehash(rbt, header->nodecount);
maybe_rehash(rbt, header->nodecount);
CHECK(treefix(rbt, base_address, filesize, rbt->root, dns_rootname,
datafixer, fixer_arg, &crc));
......@@ -980,7 +999,8 @@ dns_rbt_create(isc_mem_t *mctx, dns_rbtdeleter_t deleter, void *deleter_arg,
rbt->root = NULL;
rbt->nodecount = 0;
rbt->hashtable = NULL;
rbt->hashsize = 0;
rbt->hashbits = 0;
rbt->maxhashbits = RBT_HASH_MAX_BITS;
rbt->mmap_location = NULL;
result = inithash(rbt);
......@@ -1024,8 +1044,8 @@ dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum) {
rbt->mmap_location = NULL;
if (rbt->hashtable != NULL) {
isc_mem_put(rbt->mctx, rbt->hashtable,
rbt->hashsize * sizeof(dns_rbtnode_t *));
size_t size = HASHSIZE(rbt->hashbits) * sizeof(dns_rbtnode_t *);
isc_mem_put(rbt->mctx, rbt->hashtable, size);
}
rbt->magic = 0;
......@@ -1045,7 +1065,20 @@ size_t
dns_rbt_hashsize(dns_rbt_t *rbt) {
REQUIRE(VALID_RBT(rbt));
return (rbt->hashsize);
return (1 << rbt->hashbits);
}
isc_result_t
dns_rbt_adjusthashsize(dns_rbt_t *rbt, size_t size) {
REQUIRE(VALID_RBT(rbt));
size_t newsize = size / RBT_HASH_BUCKETSIZE;
rbt->maxhashbits = rehash_bits(rbt, newsize);
maybe_rehash(rbt, newsize);
return (ISC_R_SUCCESS);
}
static inline isc_result_t
......@@ -1544,7 +1577,7 @@ dns_rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
dns_rbtnode_t *up_current;
unsigned int nlabels;
unsigned int tlabels = 1;
unsigned int hash;
uint32_t hash;
/*
* The case of current not being a subtree root,
......@@ -1587,7 +1620,8 @@ dns_rbt_findnode(dns_rbt_t *rbt, const dns_name_t *name, dns_name_t *foundname,
* Walk all the nodes in the hash bucket pointed
* by the computed hash value.
*/
for (hnode = rbt->hashtable[hash % rbt->hashsize];
for (hnode = rbt->hashtable[hash_32(hash,
rbt->hashbits)];
hnode != NULL; hnode = hnode->hashnext)
{
dns_name_t hnode_name;
......@@ -2267,13 +2301,13 @@ create_node(isc_mem_t *mctx, const dns_name_t *name, dns_rbtnode_t **nodep) {
*/
static inline void
hash_add_node(dns_rbt_t *rbt, dns_rbtnode_t *node, const dns_name_t *name) {
unsigned int hash;
uint32_t hash;
REQUIRE(name != NULL);
HASHVAL(node) = dns_name_fullhash(name, false);
hash = HASHVAL(node) % rbt->hashsize;
hash = hash_32(HASHVAL(node), rbt->hashbits);
HASHNEXT(node) = rbt->hashtable[hash];
rbt->hashtable[hash] = node;
......@@ -2284,45 +2318,56 @@ hash_add_node(dns_rbt_t *rbt, dns_rbtnode_t *node, const dns_name_t *name) {
*/
static isc_result_t
inithash(dns_rbt_t *rbt) {
unsigned int bytes;
rbt->hashsize = RBT_HASH_SIZE;
bytes = (unsigned int)rbt->hashsize * sizeof(dns_rbtnode_t *);
rbt->hashtable = isc_mem_get(rbt->mctx, bytes);
size_t size;
memset(rbt->hashtable, 0, bytes);
rbt->hashbits = RBT_HASH_MIN_BITS;
size = HASHSIZE(rbt->hashbits) * sizeof(dns_rbtnode_t *);
rbt->hashtable = isc_mem_get(rbt->mctx, size);
memset(rbt->hashtable, 0, size);
return (ISC_R_SUCCESS);
}
static uint32_t
rehash_bits(dns_rbt_t *rbt, size_t newcount) {
uint32_t oldbits = rbt->hashbits;
uint32_t newbits = oldbits;
while (newcount >= HASHSIZE(newbits) && newbits <= rbt->maxhashbits) {
newbits += 1;
}
return (newbits);
}
/*
* Rebuild the hashtable to reduce the load factor
*/
static void
rehash(dns_rbt_t *rbt, unsigned int newcount) {
unsigned int oldsize;
rehash(dns_rbt_t *rbt, uint32_t newbits) {
uint32_t oldbits;
size_t oldsize;
dns_rbtnode_t **oldtable;
dns_rbtnode_t *node;
dns_rbtnode_t *nextnode;
unsigned int hash;
unsigned int i;
size_t newsize;
oldsize = (unsigned int)rbt->hashsize;
REQUIRE(rbt->hashbits <= rbt->maxhashbits);
REQUIRE(newbits <= rbt->maxhashbits);
oldbits = rbt->hashbits;
oldsize = HASHSIZE(oldbits);
oldtable = rbt->hashtable;
do {
INSIST((rbt->hashsize * 2 + 1) > rbt->hashsize);
rbt->hashsize = rbt->hashsize * 2 + 1;
} while (newcount >= (rbt->hashsize * 3));
rbt->hashtable = isc_mem_get(rbt->mctx,
rbt->hashsize * sizeof(dns_rbtnode_t *));
for (i = 0; i < rbt->hashsize; i++) {
rbt->hashtable[i] = NULL;
}
rbt->hashbits = newbits;
newsize = HASHSIZE(rbt->hashbits);
rbt->hashtable = isc_mem_get(rbt->mctx,
newsize * sizeof(dns_rbtnode_t *));
memset(rbt->hashtable, 0, newsize * sizeof(dns_rbtnode_t *));
for (i = 0; i < oldsize; i++) {
for (size_t i = 0; i < oldsize; i++) {
dns_rbtnode_t *node;
dns_rbtnode_t *nextnode;
for (node = oldtable[i]; node != NULL; node = nextnode) {
hash = HASHVAL(node) % rbt->hashsize;
uint32_t hash = hash_32(HASHVAL(node), rbt->hashbits);
nextnode = HASHNEXT(node);
HASHNEXT(node) = rbt->hashtable[hash];
rbt->hashtable[hash] = node;
......@@ -2332,6 +2377,14 @@ rehash(dns_rbt_t *rbt, unsigned int newcount) {
isc_mem_put(rbt->mctx, oldtable, oldsize * sizeof(dns_rbtnode_t *));
}
static void
maybe_rehash(dns_rbt_t *rbt, size_t newcount) {
uint32_t newbits = rehash_bits(rbt, newcount);
if (rbt->hashbits < newbits && newbits <= RBT_HASH_MAX_BITS) {
rehash(rbt, newbits);
}
}
/*
* Add a node to the hash table. Rehash the hashtable if the node count
* rises above a critical level.
......@@ -2340,8 +2393,8 @@ static inline void
hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node, const dns_name_t *name) {
REQUIRE(DNS_RBTNODE_VALID(node));
if (rbt->nodecount >= (rbt->hashsize * 3)) {
rehash(rbt, rbt->nodecount);
if (rbt->nodecount >= (HASHSIZE(rbt->hashbits) * RBT_HASH_OVERCOMMIT)) {
maybe_rehash(rbt, rbt->nodecount);
}
hash_add_node(rbt, node, name);
......@@ -2352,12 +2405,12 @@ hash_node(dns_rbt_t *rbt, dns_rbtnode_t *node, const dns_name_t *name) {
*/
static inline void
unhash_node(dns_rbt_t *rbt, dns_rbtnode_t *node) {
unsigned int bucket;
uint32_t bucket;
dns_rbtnode_t *bucket_node;
REQUIRE(DNS_RBTNODE_VALID(node));
bucket = HASHVAL(node) % rbt->hashsize;
bucket = hash_32(HASHVAL(node), rbt->hashbits);
bucket_node = rbt->hashtable[bucket];
if (bucket_node == node) {
......
......@@ -7987,6 +7987,22 @@ hashsize(dns_db_t *db) {
return (size);
}
static isc_result_t
adjusthashsize(dns_db_t *db, size_t size) {
isc_result_t result;
dns_rbtdb_t *rbtdb;
rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
result = dns_rbt_adjusthashsize(rbtdb->tree, size);
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
return (result);
}
static void
settask(dns_db_t *db, isc_task_t *task) {
dns_rbtdb_t *rbtdb;
......@@ -8392,7 +8408,8 @@ static dns_dbmethods_t zone_methods = { attach,
getsize,
NULL, /* setservestalettl */
NULL, /* getservestalettl */
setgluecachestats };
setgluecachestats,
adjusthashsize };
static dns_dbmethods_t cache_methods = { attach,
detach,
......@@ -8441,7 +8458,8 @@ static dns_dbmethods_t cache_methods = { attach,
NULL, /* getsize */
setservestalettl,
getservestalettl,
NULL };
NULL,
adjusthashsize };
isc_result_t
dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
......
......@@ -165,7 +165,9 @@ totext_hip(ARGS_TOTEXT) {
region.length = key_len;
RETERR(isc_base64_totext(&region, 1, "", target));
region.length = length - key_len;
RETERR(str_totext(tctx->linebreak, target));
if (region.length > 0) {
RETERR(str_totext(tctx->linebreak, target));
}
/*
* Rendezvous Servers.
......@@ -441,7 +443,7 @@ dns_rdata_hip_next(dns_rdata_hip_t *hip) {
dns_name_fromregion(&name, &region);
hip->offset += name.length;
INSIST(hip->offset <= hip->servers_len);
return (ISC_R_SUCCESS);
return (hip->offset < hip->servers_len ? ISC_R_SUCCESS : ISC_R_NOMORE);
}
void
......
......@@ -2746,6 +2746,7 @@ dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
nmnode = NULL;
result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, &chain,
DNS_RBTFIND_EMPTYDATA, NULL, NULL);
switch (result) {
case ISC_R_SUCCESS:
nm_data = nmnode->data;
......@@ -2760,7 +2761,42 @@ dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
case DNS_R_PARTIALMATCH:
i = chain.level_matches;
while (i >= 0 && (nmnode = chain.levels[i]) != NULL) {
nmnode = chain.levels[chain.level_matches];
/*
* Whenever an exact match is found by dns_rbt_findnode(),
* the highest level node in the chain will not be put into
* chain->levels[] array, but instead the chain->end
* pointer will be adjusted to point to that node.
*
* Suppose we have the following entries in a rpz zone:
* example.com CNAME rpz-passthru.
* *.example.com CNAME rpz-passthru.
*
* A query for www.example.com would result in the
* following chain object returned by dns_rbt_findnode():
* chain->level_count = 2
* chain->level_matches = 2
* chain->levels[0] = .
* chain->levels[1] = example.com
* chain->levels[2] = NULL
* chain->end = www
*
* Since exact matches only care for testing rpz set bits,
* we need to test for rpz wild bits through iterating the
* nodechain, and that includes testing the rpz wild bits
* in the highest level node found. In the case of an exact
* match, chain->levels[chain->level_matches] will be NULL,
* to address that we must use chain->end as the start
* point, then iterate over the remaining levels in the
* chain.
*/
if (nmnode == NULL) {
--i;
nmnode = chain.end;
}
while (nmnode != NULL) {
nm_data = nmnode->data;
if (nm_data != NULL) {
if (rpz_type == DNS_RPZ_TYPE_QNAME) {
......@@ -2769,7 +2805,13 @@ dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
found_zbits |= nm_data->wild.ns;
}
}
i--;
if (i >= 0) {
nmnode = chain.levels[i];
--i;
} else {
break;
}
}
break;
......
......@@ -954,7 +954,7 @@ make_log_buf(dns_rrl_t *rrl, dns_rrl_entry_t *e, const char *str1,
(void)dns_rdatatype_totext(e->key.s.qtype, &lb);
}
}
snprintf(strbuf, sizeof(strbuf), " (%08x)",
snprintf(strbuf, sizeof(strbuf), " (%08" PRIx32 ")",
e->key.s.qname_hash);
add_log_str(&lb, strbuf, strlen(strbuf));
}
......
......@@ -1309,7 +1309,8 @@ static dns_dbmethods_t sdb_methods = {
NULL, /* getsize */
NULL, /* setservestalettl */
NULL, /* getservestalettl */
NULL /* setgluecachestats */
NULL, /* setgluecachestats */
NULL /* adjusthashsize */
};
static isc_result_t
......
......@@ -1281,7 +1281,8 @@ static dns_dbmethods_t sdlzdb_methods = {
NULL, /* getsize */
NULL, /* setservestalettl */
NULL, /* getservestalettl */
NULL /* setgluecachestats */
NULL, /* setgluecachestats */
NULL /* adjusthashsize */
};
/*
......
......@@ -75,6 +75,7 @@ typedef struct text_ok {
const char *text_in; /* text passed to fromtext_*() */
const char *text_out; /* text expected from totext_*();
* NULL indicates text_in is invalid */
unsigned int loop;
} text_ok_t;
/*
......@@ -84,6 +85,7 @@ typedef struct wire_ok {
unsigned char data[512]; /* RDATA in wire format */
size_t len; /* octets of data to parse */
bool ok; /* is this RDATA valid? */
unsigned int loop;
} wire_ok_t;
#define COMPARE(r1, r2, answer) \
......@@ -97,32 +99,41 @@ typedef struct wire_ok {
#define TEXT_VALID_CHANGED(data_in, data_out) \
{ \
data_in, data_out \
data_in, data_out, 0 \
}
#define TEXT_VALID(data) \
{ \
data, data \
#define TEXT_VALID(data) \
{ \
data, data, 0 \
}
#define TEXT_INVALID(data) \
{ \
data, NULL \
#define TEXT_VALID_LOOP(loop, data) \
{ \
data, data, loop \
}
#define TEXT_VALID_LOOPCHG(loop, data_in, data_out) \
{ \
data_in, data_out, loop \
}
#define TEXT_INVALID(data) \
{ \
data, NULL, 0 \
}
#define TEXT_SENTINEL() TEXT_INVALID(NULL)
#define VARGC(...) (sizeof((unsigned char[]){ __VA_ARGS__ }))
#define WIRE_TEST(ok, ...) \
{ \
{ __VA_ARGS__ }, VARGC(__VA_ARGS__), ok \
#define WIRE_TEST(ok, loop, ...) \
{ \
{ __VA_ARGS__ }, VARGC(__VA_ARGS__), ok, loop \
}
#define WIRE_VALID(...) WIRE_TEST(true, __VA_ARGS__)
#define WIRE_VALID(...) WIRE_TEST(true, 0, __VA_ARGS__)
#define WIRE_VALID_LOOP(loop, ...) WIRE_TEST(true, loop, __VA_ARGS__)
/*
* WIRE_INVALID() test cases must always have at least one octet specified to
* distinguish them from WIRE_SENTINEL(). Use the 'empty_ok' parameter passed
* to check_wire_ok() for indicating whether empty RDATA is allowed for a given
* RR type or not.
*/
#define WIRE_INVALID(FIRST, ...) WIRE_TEST(false, FIRST, __VA_ARGS__)
#define WIRE_SENTINEL() WIRE_TEST(false)
#define WIRE_INVALID(FIRST, ...) WIRE_TEST(false, 0, FIRST, __VA_ARGS__)
#define WIRE_SENTINEL() WIRE_TEST(false, 0)
/*
* Call dns_rdata_fromwire() for data in 'src', which is 'srclen' octets in
......@@ -252,13 +263,15 @@ rdata_checknames(dns_rdata_t *rdata) {
* check_text_ok_single() and check_wire_ok_single().
*/
static void
check_struct_conversions(dns_rdata_t *rdata, size_t structsize) {
check_struct_conversions(dns_rdata_t *rdata, size_t structsize,
unsigned int loop) {
dns_rdataclass_t rdclass = rdata->rdclass;
dns_rdatatype_t type = rdata->type;
isc_result_t result;
isc_buffer_t target;
void *rdata_struct;
char buf[1024];
unsigned int count = 0;
rdata_struct = isc_mem_allocate(dt_mctx, structsize);
assert_non_null(rdata_struct);
......@@ -284,6 +297,29 @@ check_struct_conversions(dns_rdata_t *rdata, size_t structsize) {
assert_memory_equal(buf, rdata->data, rdata->length);
/*
* Check that one can walk hip rendezvous servers.
*/
switch (type) {
case dns_rdatatype_hip: {
dns_rdata_hip_t *hip = rdata_struct;
for (result = dns_rdata_hip_first(hip); result == ISC_R_SUCCESS;
result = dns_rdata_hip_next(hip))
{
dns_name_t name;
dns_name_init(&name, NULL);
dns_rdata_hip_current(hip, &name);
assert_int_not_equal(dns_name_countlabels(&name), 0);
assert_true(dns_name_isabsolute(&name));
count++;
}
assert_int_equal(result, ISC_R_NOMORE);
assert_int_equal(count, loop);
break;
}
}
isc_mem_free(dt_mctx, rdata_struct);
}
......@@ -382,7 +418,7 @@ check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
* Perform two-way conversion checks between uncompressed wire form and
* type-specific struct.
*/
check_struct_conversions(&rdata, structsize);
check_struct_conversions(&rdata, structsize, text_ok->loop);
}
/*
......@@ -521,7 +557,7 @@ check_wire_ok_single(const wire_ok_t *wire_ok, dns_rdataclass_t rdclass,
* - uncompressed wire form and text form,
* - uncompressed wire form and multi-line text form.
*/
check_struct_conversions(&rdata, structsize);
check_struct_conversions(&rdata, structsize, wire_ok->loop);
if (!dns_rdatatype_ismeta(rdata.type)) {
check_text_conversions(&rdata);
check_multiline_text_conversions(&rdata);
......@@ -576,7 +612,7 @@ check_text_ok(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
static void
check_wire_ok(const wire_ok_t *wire_ok, bool empty_ok, dns_rdataclass_t rdclass,
dns_rdatatype_t type, size_t structsize) {
wire_ok_t empty_wire = WIRE_TEST(empty_ok);
wire_ok_t empty_wire = WIRE_TEST(empty_ok, 0);
size_t i;
/*
......@@ -1755,6 +1791,33 @@ eid(void **state) {
*/
static void
hip(void **state) {
text_ok_t text_ok[] = {
/* RFC 8005 examples. */
TEXT_VALID_LOOP(0, "2 200100107B1A74DF365639CC39F1D578 "
"AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cI"
"vM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbW"
"Iy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+b"
"SRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWx"
"Z48AWkskmdHaVDP4BcelrTI3rMXdXF5D"),
TEXT_VALID_LOOP(1, "2 200100107B1A74DF365639CC39F1D578 "
"AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cI"
"vM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbW"
"Iy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+b"
"SRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWx"
"Z48AWkskmdHaVDP4BcelrTI3rMXdXF5D "
"rvs1.example.com."),
TEXT_VALID_LOOP(2, "2 200100107B1A74DF365639CC39F1D578 "
"AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cI"
"vM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbW"
"Iy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+b"
"SRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWx"
"Z48AWkskmdHaVDP4BcelrTI3rMXdXF5D "
"rvs1.example.com. rvs2.example.com."),
/*
* Sentinel.
*/
TEXT_SENTINEL()
};
unsigned char hipwire[DNS_RDATA_MAXLENGTH] = { 0x01, 0x00, 0x00, 0x01,
0x00, 0x00, 0x04, 0x41,
0x42, 0x43, 0x44, 0x00 };
......@@ -1776,6 +1839,8 @@ hip(void **state) {
result = wire_to_rdata(hipwire, sizeof(hipwire), dns_rdataclass_in,
dns_rdatatype_hip, buf, sizeof(buf), &rdata);
assert_int_equal(result, DNS_R_FORMERR);
check_text_ok(text_ok, dns_rdataclass_in, dns_rdatatype_hip,
sizeof(dns_rdata_hip_t));
}
/*
......
......@@ -1706,7 +1706,7 @@ dns_view_flushnode(dns_view_t *view, const dns_name_t *name, bool tree) {
isc_result_t
dns_view_adddelegationonly(dns_view_t *view, const dns_name_t *name) {
dns_name_t *item;
uint32_t hash;
unsigned int hash;
REQUIRE(DNS_VIEW_VALID(view));
......@@ -1736,7 +1736,7 @@ dns_view_adddelegationonly(dns_view_t *view, const dns_name_t *name) {
isc_result_t
dns_view_excludedelegationonly(dns_view_t *view, const dns_name_t *name) {
dns_name_t *item;
uint32_t hash;
unsigned int hash;
REQUIRE(DNS_VIEW_VALID(view));
......@@ -1766,7 +1766,7 @@ dns_view_excludedelegationonly(dns_view_t *view, const dns_name_t *name) {
bool
dns_view_isdelegationonly(dns_view_t *view, const dns_name_t *name) {
dns_name_t *item;
uint32_t hash;
unsigned int hash;
REQUIRE(DNS_VIEW_VALID(view));
......
......@@ -169,6 +169,7 @@ dns_compress_setmethods
dns_compress_setsensitive
dns_counter_fromtext
dns_db_addrdataset
dns_db_adjusthashsize
dns_db_allrdatasets
dns_db_attach
dns_db_attachnode
......@@ -749,6 +750,7 @@ dns_private_chains
dns_private_totext
dns_rbt_addname
dns_rbt_addnode
dns_rbt_adjusthashsize
dns_rbt_create
dns_rbt_deletename
dns_rbt_deletenode
......
......@@ -9,10 +9,6 @@
* information regarding copyright ownership.
*/
/*
* 32 bit Fowler/Noll/Vo FNV-1a hash code with modification for BIND
*/
#include <inttypes.h>
#include <stdbool.h>