diff options
author | Ondřej Surý <ondrej@sury.org> | 2012-02-15 21:02:28 +0100 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2012-02-15 21:02:28 +0100 |
commit | a3a4fcd0e5a4bbc54fc6f6c555b3656798f3a5aa (patch) | |
tree | adbb86088686bdeef3fae9f984f7942d1f922505 | |
parent | f855fa7608da509ea1539f861ab7eb54305443c4 (diff) | |
download | knot-a3a4fcd0e5a4bbc54fc6f6c555b3656798f3a5aa.tar.gz |
Imported Upstream version 1.0~rc1upstream/1.0_rc1
105 files changed, 9157 insertions, 3650 deletions
@@ -1,3 +1,16 @@ +Dependencies +============ +Knot DNS has several dependencies: +* libtool +* autoconf > 2.65 +* flex >= 2.5.31 +* bison >= 2.3 +* libssl >= 0.9.8 +* liburcu >= 0.5.4 (available as packages or as a sources from http://lttng.org/urcu) + +Optional packages: +* libcap-ng >= 0.6.4 for POSIX 1003.1e capabilites(7) + Installation ============ @@ -10,25 +23,23 @@ Ubuntu Server (AMD64, I386) 10.04 LTS Ubuntu Desktop (AMD64, I386) 10.04 LTS ---------------------------------------------- -$ # make the system up-to-date -$ +# Make the system up-to-date $ sudo apt-get update $ sudo apt-get upgrade -$ -$ # ensure all prerequisites are installed -$ -$ sudo apt-get install git-core autoconf libtool flex bison libssl-dev -$ -$ # the required version of liburcu is not available in the default package -$ # sources. -$ + +# Ensure all prerequisites are installed +$ sudo apt-get install git-core autoconf libtool flex bison libssl-dev liburcu-dev + +# Install optional packages (POSIX 1003.1e capabilities) +$ sudo apt-get install libcap-ng-dev + +# If the liburcu-dev package is not present, install directly $ wget http://bd.archive.ubuntu.com/ubuntu/pool/universe/libu/liburcu/liburcu0_0.5.4-1_amd64.deb $ wget http://bd.archive.ubuntu.com/ubuntu/pool/universe/libu/liburcu/liburcu-dev_0.5.4-1_amd64.deb $ sudo dpkg -i liburcu0_0.5.4-1_amd64.deb $ sudo dpkg -i liburcu-dev_0.5.4-1_amd64.deb -$ -$ # go for the real thing -$ + +# Go for the real thing $ git clone git://git.nic.cz/knot $ cd knot $ autoreconf -if @@ -38,7 +49,6 @@ $ sudo make install $ sudo ldconfig Alternative packages for I386: - $ # the required version of liburcu is not available in the default package $ # sources. $ @@ -65,6 +75,22 @@ $ autoreconf -if $ ./configure $ make && sudo make install +Installation on OpenBSD/NetBSD +============================== +Also works for OS X, if you don't want to install gcc from ports. +Prerequisites: +- liburcu needs patch for absent compiler TLS capability + - patch is located in "scripts/urcu-tls-compat.patch" +- patch compatible with liburcu-0.6.7 + +$ mkdir liburcu && cd liburcu +$ wget "http://lttng.org/files/urcu/userspace-rcu-0.6.7.tar.bz2" +$ patch -p1 < ../scripts/urcu-tls-compat.patch +$ autoconf && ./configure && make && sudo make install +$ # or follow installation instructions in INSTALL + +Knot DNS installation is the same as in previous section (Installation on BSD). + Installation on OS X ==================== @@ -1,3 +1,26 @@ +v1.0-rc1 - Feb 14, 2012 +----------------------- + +New features: + * NSID support (RFC5001). + * Root zone support. + * Automatic zone compiling on server start. + * Setting user to run Knot under in config file. + * Dropping privileges after binding to port 53. + + Support for Linux capabilities(7). + * Setting source address of outgoing transfers in config file. + * Custom PID file. + * CNAME loop detection. + * Timeout on TCP connections. + * Basic defense against DoS attacks. + +Bugfixes: + * Fixed IXFR processing. + * Patched URCU so that it compiles on architectures without TLS in compiler (NetBSD, OpenBSD). + * Fixed response to DS query at parent zone. + * A lot of other bugfixes. + + v0.9.1 - Jan 20, 2012 --------------------- @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for knot 0.9.1. +# Generated by GNU Autoconf 2.68 for knot 1.0-rc1. # # Report bugs to <knot-dns@labs.nic.cz>. # @@ -570,8 +570,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='knot' PACKAGE_TARNAME='knot' -PACKAGE_VERSION='0.9.1' -PACKAGE_STRING='knot 0.9.1' +PACKAGE_VERSION='1.0-rc1' +PACKAGE_STRING='knot 1.0-rc1' PACKAGE_BUGREPORT='knot-dns@labs.nic.cz' PACKAGE_URL='' @@ -1302,7 +1302,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures knot 0.9.1 to adapt to many kinds of systems. +\`configure' configures knot 1.0-rc1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1372,7 +1372,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of knot 0.9.1:";; + short | recursive ) echo "Configuration of knot 1.0-rc1:";; esac cat <<\_ACEOF @@ -1488,7 +1488,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -knot configure 0.9.1 +knot configure 1.0-rc1 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2038,7 +2038,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by knot $as_me 0.9.1, which was +It was created by knot $as_me 1.0-rc1, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2856,7 +2856,7 @@ fi # Define the identity of the package. PACKAGE='knot' - VERSION='0.9.1' + VERSION='1.0-rc1' cat >>confdefs.h <<_ACEOF @@ -11938,6 +11938,7 @@ CC="$lt_save_CC" + # Checks for programs. ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -13425,7 +13426,62 @@ if test "$ac_res" != no; then : fi -#AC_SEARCH_LIBS([clock_gettime], [rt], [], [AC_MSG_ERROR([librt not found])]) +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5 +$as_echo_n "checking for library containing clock_gettime... " >&6; } +if ${ac_cv_search_clock_gettime+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char clock_gettime (); +int +main () +{ +return clock_gettime (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_clock_gettime=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_clock_gettime+:} false; then : + break +fi +done +if ${ac_cv_search_clock_gettime+:} false; then : + +else + ac_cv_search_clock_gettime=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5 +$as_echo "$ac_cv_search_clock_gettime" >&6; } +ac_res=$ac_cv_search_clock_gettime +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing OpenSSL_add_all_digests" >&5 $as_echo_n "checking for library containing OpenSSL_add_all_digests... " >&6; } if ${ac_cv_search_OpenSSL_add_all_digests+:} false; then : @@ -13484,6 +13540,62 @@ else as_fn_error $? "libcrypto not found" "$LINENO" 5 fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing capng_apply" >&5 +$as_echo_n "checking for library containing capng_apply... " >&6; } +if ${ac_cv_search_capng_apply+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char capng_apply (); +int +main () +{ +return capng_apply (); + ; + return 0; +} +_ACEOF +for ac_lib in '' cap-ng; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_capng_apply=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_capng_apply+:} false; then : + break +fi +done +if ${ac_cv_search_capng_apply+:} false; then : + +else + ac_cv_search_capng_apply=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_capng_apply" >&5 +$as_echo "$ac_cv_search_capng_apply" >&6; } +ac_res=$ac_cv_search_capng_apply +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + #AC_SEARCH_LIBS([ldns_rr_list_pop_rrset], [ldns], [], [AC_MSG_ERROR([libldns not found])]) # Checks for header files. @@ -13513,7 +13625,7 @@ fi done -for ac_header in arpa/inet.h fcntl.h inttypes.h limits.h malloc.h netdb.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h syslog.h unistd.h urcu.h ev.h +for ac_header in arpa/inet.h fcntl.h inttypes.h limits.h malloc.h netdb.h netinet/in_systm.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h cap-ng.h syslog.h unistd.h urcu.h ev.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -14181,7 +14293,7 @@ $as_echo "#define HAVE_MMAP 1" >>confdefs.h fi rm -f conftest.mmap conftest.txt -for ac_func in gethostbyname gettimeofday memmove memset munmap regcomp select socket sqrt strcasecmp strchr strdup strerror strncasecmp strtol strtoul poll epoll_wait kqueue +for ac_func in gethostbyname gettimeofday clock_gettime memalign memmove memset munmap regcomp pselect select socket sqrt strcasecmp strchr strdup strerror strncasecmp strtol strtoul poll epoll_wait kqueue setgroups sendmmsg do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -14738,7 +14850,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by knot $as_me 0.9.1, which was +This file was extended by knot $as_me 1.0-rc1, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14804,7 +14916,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -knot config.status 0.9.1 +knot config.status 1.0-rc1 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 70545a5..e1fb61d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # -*- Autoconf -*- AC_PREREQ([2.65]) -AC_INIT([knot], [0.9.1], [knot-dns@labs.nic.cz]) +AC_INIT([knot], [1.0-rc1], [knot-dns@labs.nic.cz]) AM_INIT_AUTOMAKE([gnu -Wall -Werror]) AC_CONFIG_SRCDIR([src/knot/main.c]) AC_CONFIG_HEADERS([src/config.h]) @@ -13,6 +13,7 @@ AX_EXT AM_MAINTAINER_MODE([enable]) # Initialize libtool +AC_PROG_LIBTOOL LT_INIT # Checks for programs. @@ -110,13 +111,14 @@ AC_SEARCH_LIBS([pow], [m]) AC_SEARCH_LIBS([pthread_create], [pthread], [], [AC_MSG_ERROR([pthreads not found])]) AC_SEARCH_LIBS([rcu_set_pointer_sym], [urcu], [], [AC_MSG_ERROR([liburcu not found])]) AC_SEARCH_LIBS([dlopen], [dl]) -#AC_SEARCH_LIBS([clock_gettime], [rt], [], [AC_MSG_ERROR([librt not found])]) +AC_SEARCH_LIBS([clock_gettime], [rt]) AC_SEARCH_LIBS([OpenSSL_add_all_digests], [crypto],[], [AC_MSG_ERROR([libcrypto not found])]) +AC_SEARCH_LIBS([capng_apply], [cap-ng]) #AC_SEARCH_LIBS([ldns_rr_list_pop_rrset], [ldns], [], [AC_MSG_ERROR([libldns not found])]) # Checks for header files. AC_HEADER_RESOLV -AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h malloc.h netdb.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h syslog.h unistd.h urcu.h ev.h]) +AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h limits.h malloc.h netdb.h netinet/in_systm.h netinet/in.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h cap-ng.h syslog.h unistd.h urcu.h ev.h]) # Checks for typedefs, structures, and compiler characteristics. AC_HEADER_STDBOOL @@ -136,7 +138,7 @@ AC_DEFINE([DSFMT_MEXP], [521], [DSFMT parameters.]) # Checks for library functions. AC_FUNC_FORK AC_FUNC_MMAP -AC_CHECK_FUNCS([gethostbyname gettimeofday memmove memset munmap regcomp select socket sqrt strcasecmp strchr strdup strerror strncasecmp strtol strtoul poll epoll_wait kqueue]) +AC_CHECK_FUNCS([gethostbyname gettimeofday clock_gettime memalign memmove memset munmap regcomp pselect select socket sqrt strcasecmp strchr strdup strerror strncasecmp strtol strtoul poll epoll_wait kqueue setgroups sendmmsg]) AC_CONFIG_FILES([Makefile samples/Makefile diff --git a/samples/example.com.zone b/samples/example.com.zone index a1e3aef..c6a0aef 100644 --- a/samples/example.com.zone +++ b/samples/example.com.zone @@ -2,15 +2,15 @@ $TTL 1h ; The default expiration time of a resource record with $ORIGIN example.com. @ IN SOA ns.example.com. username.example.com. ( 2007120713 ; serial number of this zone file - 10 ; slave refresh (1 day) - 30 ; slave retry time in case of a problem (1 day) + 10 ; slave refresh (10 seconds) + 30 ; slave retry time in case of a problem (30 seconds) 4w ; slave expiration time (4 weeks) 1h ; minimum caching time in case of failed lookups (1 hour) ) NS ns ; ns.example.com is the nameserver for example.com NS ns.somewhere.com. ; ns.somewhere.com is a backup nameserver for example.com MX 10 mail.example.com. ; mail.example.com is the mailserver for example.com - MX 20 mail2.example.com. ; Similar to above line, but using "@" to say "use $ORIGIN" +@ MX 20 mail2.example.com. ; Similar to above line, but using "@" to say "use $ORIGIN" MX 50 mail3 ; Similar to above line, but using a host within this domain A 10.0.0.1 ; ip address for "example.com" ns A 10.0.0.2 ; ip address for "ns.example.com". Since there is no "." after ns, $ORIGIN is attached diff --git a/samples/example.com.zone.nsec3 b/samples/example.com.zone.nsec3 deleted file mode 100644 index f5bf984..0000000 --- a/samples/example.com.zone.nsec3 +++ /dev/null @@ -1,635 +0,0 @@ -; File written on Tue Mar 1 10:45:24 2011 -; dnssec_signzone version 9.7.1-P2 -example.com. 3600 IN SOA ns.example.com. username.example.com. ( - 2007120712 ; serial - 86400 ; refresh (1 day) - 86400 ; retry (1 day) - 2419200 ; expire (4 weeks) - 3600 ; minimum (1 hour) - ) - 3600 RRSIG SOA 8 2 3600 20110331084524 ( - 20110301084524 28635 example.com. - 6G4Hpl8WFCTVZN292HX+NaS1K8+oLaXK+2gr - tIp53Y1MI/A8qAD2HZ+bECnbedU+mP5PIJ8I - 4Q6STbZE3HpiaTMP8D87sJwgD6tUexHhBNgf - CPZQBdF2Gw/hP+yqeY89ZcoeJVimy6h56X+V - 7KM+JqRQ6KlGo8vLJTn/lo3pOq8= ) - 3600 NS c.a.example.com. - 3600 NS ns.example.com. - 3600 NS ns.somewhere.com. - 3600 NS ns2.example.com. - 3600 RRSIG NS 8 2 3600 20110331084524 ( - 20110301084524 28635 example.com. - 3VqU2AvI720W9frpY+jz5U6a25115tUmkC57 - tr/fvZS2CEAYhWVEpSSFWKRApb70JmQeYgvt - pvdmOriyChzq4y6phVJxChYrFeTqVYS0AvE1 - ldZ1k5xL6I0hIL6UXgMoz6nRZQ6T1qh/7G2o - Ge9Taqu0KroITTLGfn4HlyMViq4= ) - 3600 A 10.0.0.1 - 3600 RRSIG A 8 2 3600 20110331084524 ( - 20110301084524 28635 example.com. - 5tOtdUUMjX0T7QWL/YgYga+HuJOLOh8O3to8 - 3fWUvS5hmrR5/hWV1TRXSHCS0HKIaPBJCn24 - DCHM91uTPNASrpdyWlIAXTJBDqm62C0tXOKD - zn/50P0cgqHJXa7f69FQc5V+oA/OGcOb2xpV - e/ig/L8xLcRTGFoYScNMObq9tlg= ) - 3600 MX 10 mail.example.com. - 3600 MX 20 mail2.example.com. - 3600 MX 50 mail3.example.com. - 3600 RRSIG MX 8 2 3600 20110331084524 ( - 20110301084524 28635 example.com. - yX8xQLpUeZCX3Q4Aq0PTsjEO+5HUrXTWSH1k - LQ6qozQqWW/SAvnYGkjL/MILnqtTFl07DyrY - 1y++Ifh2vW5wR11lrIUiftpa0QmSUIj4eJlJ - fc78wZa3D1g6ni1VDsRClEk3Gx3sfmf2ryjN - QVa3s++ZszKolUR4WjGGJuwmbFI= ) - 3600 DNSKEY 256 3 8 ( - AwEAAdtkxsfkpMv9P3oa4FGDr+zbs5T28hC2 - G7zRsgHHSP1r3AS9JW8I3yCXI/DWJu5M0Iv3 - UuOc5Q/lNoxmiMKipIP0UZZ97sRyVIK4RWfB - quVV0GKQ08exwUvUwkej9Uu5Ub0YcWkQXAg5 - xVNpWZ5WxlVhcDVwXG/geikMJPyk6j2N - ) ; key id = 25581 - 3600 DNSKEY 256 3 8 ( - AwEAAesA9XFmAudDuFARUUn4fcYdwbPfSRYU - DVC792SMtnEl6dZBLujInZbbQiqW+OyVlo6v - kyjyQBDuS6aebN4sxO7UYz4vHxxJVuP/+H0n - /+UAyz11XYT8Rbsmpgzu3PMq5mB13jCjzZ9y - 3JBJjp5Lrk/jRjFcZapDpX/yXu0UsuuV - ) ; key id = 28635 - 3600 DNSKEY 257 3 8 ( - AwEAAddbawR+0U7Bz/2lbX1iwMGmAoYOHmb8 - sQF5Jp8gI1tEtpsDD42fW4EM1i1tx7Cyca/9 - u9MSFB14BapX+dxMMj1xJJg0RNTiswjw4DC+ - 7idLwmQHDUMhZLJBqdGkSDcgfsXm9xNEdRrs - u10wxWpmqMUFxyGStSdGneqdchSRDgr6fihu - NExHeXp884kXUPuAXSYu02xtYOLLAAhqLeEL - tQAoyi901FwmmYhyu4eYK2aWqy+ld7JCZZbQ - j4/9zdecIGETI+NbvQVoO5lSGt6GY7cKaf8m - 17L++dj2R2rTER/R3gwnjAGQ1GL/djhqbgMi - vhrxqAQ9R9Ko+6kaeqA6a60= - ) ; key id = 6190 - 3600 RRSIG DNSKEY 8 2 3600 20110331084524 ( - 20110301084524 6190 example.com. - qRB0bNPGgy4p2kGBNKbjK/03dowH3zx4fLyP - 6wv4VmJinbqe2hxqLNLGTdA1toT/82iaLJEA - Nh0GKnYRVW1rmX/YsvArYH5Z8ikrZbTYSu7Z - TVTJHHXOGIbddpx3BaEPeNJyJHf7UF5yDKkv - wM8KhkMw7zRWnuLw5dWYTqmegMVHkNekIHrH - kW389rY7gbNsZexusmsKURhl3/LhRJlZd/hP - IlAUIhEV0DZ2xmFEkCOa7QRD/PMUwuiEykxd - 0ffGm1aCzBUUWdVP7tbYbsePa9f380473m6U - xDSgNmU5/NjFRYw79/QopE68OU+7F+xTX+6S - U6bBtAvTPoG+RIBUAQ== ) - 3600 RRSIG DNSKEY 8 2 3600 20110331084524 ( - 20110301084524 28635 example.com. - MD75IQDQQtrDQTUHJV/F2cYfd49e6YkSWT7O - BuJUnTvyuYyxpqJg7Rj1H552078yrUQiNSCC - fqo9yoW6QrpxXgAsPW8wd4vT/bXRayvqZTRJ - 6ht4FMvOe1dI0cMEOEGfOnve1r4faaHBYPIo - P5sJQIkoYpQ/0FOnOLz1dIiFZpI= ) - 0 NSEC3PARAM 1 0 100 8B3F579FA62A6CE6 - 0 RRSIG NSEC3PARAM 8 2 0 20110331084524 ( - 20110301084524 28635 example.com. - Go3s7HQ1n+WLlECouJi/2P0h0F7buRYP7zSE - UcjBgBDczSucB8ZdfSI+Z9gZpJrOL+hpnhU5 - UB0xVUldoWzO3KK/Zu0YEoBNf/z1eSA8Lrt0 - kWtxDlppfYk9rMRJIBEkY4nNKJz/IlPppZ8j - TY361bbHGhoHmjJeozrdMGc6/Ls= ) -_foobar._tcp.example.com. 3600 IN SRV 0 1 9 old-slow-box.example.com. - 3600 IN SRV 0 3 9 new-fast-box.example.com. - 3600 IN SRV 1 0 9 server.example.com. - 3600 IN SRV 1 0 9 sysadmins-box.example.com. - 3600 RRSIG SRV 8 4 3600 20110331084524 ( - 20110301084524 28635 example.com. - 45kpyR6Avac84Ycv/EpLT3ScICeNpLFgQq7P - peNgEpboXrJTc7uYUtoxswq19m9czMNQNcoZ - nFKw3unQGrsfr/B38Vz6uOc9ILF/4WQbC002 - F+VGlgGvPVc9RficEYg3Wwzly7m27d4hPwk4 - pnQQaVenubmXgVHKQ+kl1c8Bqu4= ) -*._udp.example.com. 3600 IN SRV 0 0 0 . - 3600 RRSIG SRV 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - zxu5UR7j0cgvdw8q1L8eD2AvsvhkhbSvuFQH - C8a0pYCmM0OoDEiLoHj5F9Mk7LI4Mc7sESfr - roKEOQC4y6xwsuQxCjuG+V2s4xnxLbSrZwee - JqaI3e8X/gVfd3VoKycY3MqDC1432Qc8VSZC - Lz9mb68ulNEK1VrEbbA3/jTGGOM= ) -a.example.com. 3600 IN A 10.0.0.4 - 3600 RRSIG A 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - x30rkJBwLV+aiDao0J1N/FbiUWROwBqkl6lK - V3z4zHfkcEgORa7o2kNkHANPCUJj7bQSSlPD - I99dyszDxYW4bgnlNlYw9h3D+6+sK9ehREDa - IMvV1Xuup+oo6LccJhZTlEFrGFU4oUF9VXj+ - g4TDzCyCGMHnVj3SFc/+5xUXGsg= ) -c.example.com. 3600 IN CNAME c.a.example.com. - 3600 RRSIG CNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - 1sHLDUiGyabatbzRknYdhwu4CQXH+bb6+9x0 - yW/173FMudGOGowiPdfMkUFOP0Igqb/4FqVj - bg+jDdu4zFCszLQ5MC4Q6mrLL0nfUJ4JL2J9 - kScZN12/t9+P0dnLb5YYXKV8E0GtlKd4ZVr5 - 9fRJvve/OsV29Xj02vX1+sXNjoE= ) -d.example.com. 3600 IN CNAME non-existing.example.com. - 3600 RRSIG CNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - Or6i4+ez4nkhodwJC8OWJaj9TyvxJ1i6HC3u - /xjwF/kStCkTaX/Cg8d36KhVGev6z6LyT++s - SKiQ0wdPzhgfv2d386W7XUSCje7/OCRUUZwp - taQvzJsfKCBy2hYz00Anai2qk1pldKEYI3aN - P3qnSItISO9zbOcKtV2ug6B304Y= ) -e.example.com. 3600 IN DNAME bogus25.com. - 3600 RRSIG DNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - sbrGVq24p55ke3GGXkr/7IPu3fNO67SUABQW - 67VKrfL1AF5qWN7UdcEb5FZQ5302s28/mePb - c4Ubn2bpQrmHdMZm1W370J0fDQ/PBT9lKnQS - tZpAx6xPMRmLG+qvrOtGFDeuCVDqmRlK13wJ - ryCGvI2eJcfrOU7Kx98ZLgDTzbQ= ) -*._tcp.example.com. 3600 IN SRV 0 0 0 . - 3600 RRSIG SRV 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - k9YqgNDYkvF4tqiPjw0FCsL675BQ6V0mztXc - +Vfcd/bSbpD3HiMDbkmBeW68TH7g2rkqTzS2 - yjXGdVsxo7jDWdfPiGDdAUueYbPzxEF1eY3q - v7oquG86sfTrbosYFPfihLXZrnGhVDIlHmgi - L428BtZbXTINKm9XwjFwv+pZ66s= ) -g.example.com. 3600 IN CNAME www.bogus25.com. - 3600 RRSIG CNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - gwENYoTmnyn38R4sIb1wJ/uKXPNQnKOu2gfa - sWW91lrkcwQYF59XZIDme+XST4fiscDJfjPH - 9xHXs86j771L/2shVZkfh161qXMv2xWVKP14 - tXXfjcQyz/YZ4S6S6MWkUl1w5ujqJCq4PLv0 - +BucVmtjQkcxG9yR0P8F5hMZBsA= ) -*.j.k.example.com. 3600 IN A 10.0.0.22 - 3600 RRSIG A 8 4 3600 20110331084524 ( - 20110301084524 28635 example.com. - MI/Q/zFqnUrlIQmPjy4Kpq8lQ38PAi15cidP - C1ZutJUXV7aiYpJJcpmkDNRA96L+/cApfW06 - /ahv+IYrxI3qWd8agOxDXTR/bclrxWJs8Zdq - aQeM+uvhtVCua6tRcdJf1UCHwEFpqoEg6xcs - 3vR13IuPLlJrfe/AMrw1FvROfBg= ) -f.example.com. 3600 IN CNAME e.example.com. - 3600 RRSIG CNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - cvQbg2jKGDrL6dyOXSY++SaEzo31OKDPRXWe - l4pVWsJdK9YmjQ0zXdAVtqiYFdKsfS4ep5FG - VPFF3xuHF0cPzzozwQ3cyn6BRq6EVDohn5Ct - oyqSQ9jWuwDNdLxG6yCFK+R6bdlc5fxE3Jkn - qQ8hK6z7XHpHL7ZySVufRtGhMrA= ) -h.i.j.k.example.com. 3600 IN A 10.0.0.21 - 3600 RRSIG A 8 6 3600 20110331084524 ( - 20110301084524 28635 example.com. - m+FuNt4WmfnICukl82DSunja8nfoy68u+oBU - MX3nzp5AjwbqWyZTvQRaZpDa0Rsa90oHbCuv - hOYiK4tVdZjk0yd0Fx6XX/zFqD29BEI/oLu4 - u8CPLvSC9vWB8bFScOjeoCUM+hmnoLVuZ/rq - XFHz/CQmYX+mpU3u7pKSpFyQDAw= ) -mail.example.com. 3600 IN A 10.0.0.3 - 3600 RRSIG A 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - HPK9q98C16xCURI5wxP3lxUGdJr1X1TeRZ2L - tnf2s5Izmt28Y3SIbVI83prKO/m4PrpfeV7T - Ji3ErMMUe7k6Q096YaGStBHL5GWeymJCAzC8 - pJPnyzExDRZeGeknEg4bn0+WJHJz+hlVzYQx - LRaqA4O021aZf9U/sdDZhGBR0Hw= ) -*.a.example.com. 3600 IN A 10.0.0.5 - 3600 RRSIG A 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - fXOfzPtCYPPyxtw5ivLn7Kq3JlK+LR8BbYLp - Z6f/Nir3R00GURfsUM6NVbPnMOpnPE513yz7 - 1sAAO/rsOFXPZUSJF4G4zMA6O4OirjGh68bX - Ei/yrdllyPiTgtHI693MpsDvAFNIaO+pkgS6 - zt+Mk1MEau+78saWxyZVbBWCqT4= ) -*.n.example.com. 3600 IN DNAME bogus25.com. - 3600 RRSIG DNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - s/gyETQ20pNXEbhwRhTIPTMOQYMW8KhhHaSN - uOYX57dabeGuYgfXFRfNIB+Y1m3kTlxmacMS - dNIep2b4SF59/T7Ww06/I4P/qQiOosdyeBSY - X4mQeMrUh8kqxh9C4cQh5yPiiz4w/0Ui+SLP - J/7Z0AKgYKh7t+pVQfiDAKGQJXo= ) -ns.example.com. 3600 IN A 10.0.0.2 - 3600 RRSIG A 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - aPAigU/glISbY2VM8F8JpfElQ+xab12ZO7el - 5Cl3t1qiU/3iirBmaKTj7g6IhBduPx+iBgOy - 5v32FyrfHi2El6nJZxEgi52/Z/4Ohvju3jVA - hUJLGoREc20FUXOiICCftEauQp7uPM1RAQ17 - Q0pykRRQ50bn+jApSRLL696e+EY= ) -f.g.example.com. 3600 IN A 10.0.0.20 - 3600 RRSIG A 8 4 3600 20110331084524 ( - 20110301084524 28635 example.com. - EfjVvHQ/IEPdP10B+dEDfyHpCRNpmf0dV7Pb - Ia/gRDuoRg6FUbL04oycNQSMjafInBpinmx/ - WSDMenEf5HUtP3fyzZ9Fywg2QDZqm6/TJXBk - 8q+uOxPKfMlcn9Skg1k8XJGbJkAovmyCS+DA - LC2Ewp7yVUwEliZBkKzUblWE5ig= ) -ns2.example.com. 3600 IN A 10.0.0.6 - 3600 RRSIG A 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - hgX7gI1GpJeuQtTnVDCHS4esc1wRQk6zAP/8 - st6cILlYbOQkwfRVpB88Y4LDCYuWLkplKBjp - cOhL/gU+zvR8QQQHmdksUlYSK0SFEdvcpvIm - uD4KosW3wJSAPS8M3bxI2yA/CPdY6SalClbY - jM/OpPfynAqS1UdNo8vNu4pBYks= ) -o.example.com. 3600 IN CNAME a.e.example.com. - 3600 RRSIG CNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - RMRnQd17zWB6vxGUl6L+zKWchPD9XyNMaK6W - v0MfpY5E9hqSMvNp5BKf+1Fsk5aWs9aWga/a - AVFUTObelpdG4IE4oyGSUB3wCN9ZTxJ9rKqd - NVG48X2+iAb2k3tGcUQaYH20gBIezPwi2AWc - k+CHI2FTi10evykIeVJo+Paro7I= ) -old-slow-box.example.com. 3600 IN A 172.30.79.11 - 3600 RRSIG A 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - LfF5v3pRRomTjLMLqCyEqK9J9m7dbBs1V0zS - bEu9T+MPOdW4swoObFBPv/FLqr50Y6OGlovK - J0lSGo+plLw6gPMW9bzJNGeIP19TgcEmF626 - 7+hRibwn6fZvoK4qBQSDQKmNBoST1u+ZhWa6 - xpdY5bdosyQ0oM1Q6eHZsEGELvs= ) -*.l.example.com. 3600 IN CNAME c.example.com. - 3600 RRSIG CNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - l+p7hZxP1VakVXtcDE2dN+DCK9tAdZpT8i0i - IoUdRUgeTv2DcViVsK2tNjv0HIZcffhEatwi - pM7IAvqkbS22PduU+dxb3OMzcj6n/dQBcxoW - vfk56RpQcDrqPJVYn7AqVH6KXFg6oRrIYzw1 - O9uTLaHt+futcIEDvRVMTODe9os= ) -sub.example.com. 3600 IN NS ns.sub.example.com. -ns.sub.example.com. 3600 IN A 10.1.0.1 -sub2.example.com. 3600 IN NS ns.sub2.example.com. -*.sub2.example.com. 3600 IN A 10.2.0.1 -sub3.example.com. 3600 IN NS ns.sub2.example.com. -sub4.example.com. 3600 IN NS ns.example.com. -server.example.com. 3600 IN A 172.30.79.10 - 3600 RRSIG A 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - zWLeUhLq/2lU0KwPFxzJaFIiOSqwA4xQ+mwh - UYSa27N1t58m3L+XeOwj/zSE69sWl8Lbm3pV - B+4FNVVPkGzBhocJRf/7a0xc0IlQSI1hgZ3p - meFlPC/kMTmxK1p9un/dF5r35FsnnAN8ECnR - 2imbaQLIrjhHshK9bBIVCwK92Ws= ) -sysadmins-box.example.com. 3600 IN A 172.30.79.12 - 3600 RRSIG A 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - WUp7V4gH7JMyvtKURuvrNmW7rVMI1aSMZU9U - xukVAmQDaQTYXsD5XC3j7X+9gAhQJWA/JNga - pXT7wzBJpqVrJHqAfRYZFMQ9WI0rJzKJnFPI - WOlVerQMEwUpyJsX/GlJglldK5kKM0bbPjW8 - s6Vqmq3rfyjGY94HNS9jX+uqCwk= ) -new-fast-box.example.com. 3600 IN A 172.30.79.13 - 3600 RRSIG A 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - qK9x7sS736Go3vdVfYhtuEnFLOhl6djWpXVC - l4+kvvPpkAJTkfHmTcAsWbChSolB8X4UPt/P - KTnImnF4uhc2qLOhvToKqx9tVExEIWDBKA7F - JPPBYG0c6n/50j2bVmzrkhyzaLLuhsbbfm5o - eZDwwO+vuoMBvj8Z/mt0Di9rh/w= ) -www.example.com. 3600 IN CNAME ns.example.com. - 3600 RRSIG CNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - LPrX8sh5xYUfW+wKpQRg50qkf67maJRcN6tH - R+H3OwL4u9JhdK6RpdRvs4nAF8HmrUZZYtxo - 80+RMbFhynqPYWlnXd/ZH6taQN2qJYdVLdnd - dhyLajAkxJqpOWVLezr2KOPj6YzJzu15ngXD - nHnkSKsTlziq3ifLd5oJLy9UJAk= ) -0J3ID6U2GQUPOADI9B867SGMROP8U4Q0.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 18DGVBOD0NE6AJ2OV3MV9QGNBTJ39V2U SRV RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - BStj/PbAk78rRKdCf4eCvtGKYGco/i7fg54U - mlIGY/ToQwsB4f9NuDpuajdt+30QnL6w1m5u - /Hku6cZAV7PEr5S286TWtIHu1GSUfjQ2ObKC - sF9PYoQrARTNYceY8ZKPNwTk1DgfBNM1WcdW - 5zJLbQ/DfP/O1c9ZiaR5jokbRnE= ) -18DGVBOD0NE6AJ2OV3MV9QGNBTJ39V2U.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 28CVPDQCRQARAVE71745J8C1C9RR9U6A NS - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - LeQC7vW1322QqG/X08ZQ3hokSMIDB0rmGxk/ - JsmrNt6o1hmpwfz9ET1GM6LDf+SLd12SdnYa - vRZxVVeUv7KloxZI77aaZabqKYWCX+LmkoJk - LAinY3wQ6vZD3vSP/BxUZL4Ojs0GNpWqGNzs - ZOkU9EOOE/mwQFlU6GamBJoy2nU= ) -sub5.example.com. 3600 IN CNAME sub3.example.com. - 3600 RRSIG CNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - qIPaS9aKJASzy2ncqcnlyLW4npkwBW12Udvc - zGyjk/bO8Q58eKm3uBfJ3LtQVCznkBhAksXK - AXGnN1TRtaxeVBWZNqlRtHV2hgmXQsTWxoVz - Qc8Qz2LvnzfgRTjt0H1n/5aDQ3FeZ25XuwLB - W5fFHwvOmQDd3lvZhOJVfSvEKNM= ) -28CVPDQCRQARAVE71745J8C1C9RR9U6A.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 2BMOOQEUMB3KGE328CJ7B2Q65OPJM8DJ CNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - i2K6FAon2wyZnGTH35mMmjWth+czEC1cdoyL - hk6Xd3iGrN5tjPAqkMtuKDuG2boGjDP02npj - Ytv59m5IK5vSNgeOekR6TRNWdJ/S3XM9VSlv - 9R07P9WjJVjO4viGtAfvbKVNOYyLPe6+e/Na - lIjYv87EAAlV3Hot7Pzff1duRSM= ) -2BMOOQEUMB3KGE328CJ7B2Q65OPJM8DJ.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 2CIJJH4RBMAISUSA1TH02A2RAN03THDQ CNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - HWSQYMuhCxYWm6DVKRwnik/PYwQmdZhOHMmb - P+Map173RzL0kzCqGzpokaDmZBs8zZohgvMs - UYbQss8jnXJuAcyRF0dSc0IVVeJLUAaipJpi - kmzyIy/+ANxsaSeRgKvkGecFT8dnl5xNQ6F3 - vbBwGNQ34VQHNx6S4a3Qa/vBwS8= ) -wwwtest.example.com. 3600 IN CNAME www.example.com. - 3600 RRSIG CNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - 2kfR8e8X0LNbTyPg9fe7vlOknc63ksjBRECm - pCKNFqSMXJ9gd4gbB2DKHTQLarAQx1KOy3lA - OezcuJS3WKxF/ucZDqkOaiN/YGJqC5GZ1jcW - zcCahY8FAM/eJfjbZpdn8YowVQy9f/1m+agl - vsHMD00nflPUyFiRmoik1DAWoVU= ) -2CIJJH4RBMAISUSA1TH02A2RAN03THDQ.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 2E74KFMC0MPQFVMLM1UD7O7HCEUV01TQ A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - f6Gj3qbdYjC27HqDBLv3Ip5Gf/j/GJNVko3G - XIVrebHqTPUssOy81/CRElLstM1l1WzX/KTz - 9Pzu5e1qmlYk4Ym20mMAyihWON3/IJk2GI8x - TDR4tJ3DBWk37l1S4eMhjv43OSms98GlKfZl - soYKgv6hwPyX7si1FEL9gWTJjio= ) -2FIB35726VOBGISOGPQLFO6O5IRN3M0G.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 3JL9UEM86R2IO5RMPACMSD92NTVGRPNG SRV RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - xmeQ5RA8LUt1UDtfFhKdTCq6ean35+UdK0fP - OIb7XeWcp63YVS28l0uoud3+HjsB8VSF/FXi - PpJnN/kG6Xk/+sdTDGuObtqlAI1W6/dXgDcP - VdbGNo4uPcJsdkQdCgrQs0oxZCwpW2Q69LWH - yKLTVO6avq/V9DiNOPjTSG7Ix8c= ) -3JL9UEM86R2IO5RMPACMSD92NTVGRPNG.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 4F4ISAF7SLHE2FVS6IH2N1HHOCVUTMTN A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - JbwLpP6KcZ4UbuR7vmjRozuL2uoyp6U1HP9L - tRu6CH5CJwMa0crXBM6cCg7zm4PkSxyQBMSV - lt+T3lThVSx6HzxGoDAblj5SiPF/SA79zZW6 - g9qFAlLQ4doeC0CesjeOPu9bL37wtWJIZY5P - 3LhYhNN67PYAwGFl+s+3kVrLiTE= ) -p.example.com. 3600 IN CNAME a.sub.example.com. - 3600 RRSIG CNAME 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - eXmvtean3kAh6cJGtMWPfzVlOC6cjaF4IgIC - UnJruUTcL61mR57nQKxBD6Fc6/BQoVMOvP2n - Q19akZQoDvgt/p/Koo3vUozrCzLvkj1n4oSd - R0fSl7PCBl8Rf1TMuvw+7XvQeIfLq2c8INL1 - PONXmm/lkgqbYw2BJxzx5tKffcE= ) -6A3ESFQICSC9TLOHO0P20QB3T0H8DHNT.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 6T8FEOHJ6MH3O1N4B0H6AES9842FDUSS A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - kUhsVZbbmfkCczTv/wMzX8sbPn+5VbR1r+xE - x8YvzZ42zof62wIvS2JcwXCR2GvSi9LVKBQE - 3y1g548Y8n9moXC13MP4F84h+5U/VAhyaPpw - e2TJpBnMLCDjvMUXP3XQKQzkdiV3UaLFn0aP - khwT6nh+TTPYeREjcSLuyhWs8Hk= ) -74EBGC37NAC14CAFDT47M48A5JSFFSL2.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 75DLOF6I4571LIKU0GLDE5T49QMEN8IG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - MtZCtVby4Hprx3spzSglrUqmPvvreRDrKXhc - 0xaWh27f81oGsnek+jDYvaw9JIdDcOAQbonT - 2nVy6s6Jmrjt+7pWSGPkuFGPgybBrH1l0Rh3 - QmODDmVDueyTMSdEpfe+Nw7+zlq7BI1qXe3T - fBoESwb73RXgOQ4VztK0/XXk1wQ= ) -75DLOF6I4571LIKU0GLDE5T49QMEN8IG.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 7GD2384TAD22TQJ5ULAC03C93FO12QF0 A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - zukfY1bN+D7H/q3QKmPz+rRRxofgC1ECjbxL - ZdG0NBT/w2QL3wRLe5CDmy4hNsU0Iq3xxeel - 7B4f/CMkY+F7WXBbFwsi0cLf0gfN+VOMcFR9 - 700/L99AUw8ofRkH7sWNj0sfHB/CHSC38980 - u+n453MvcT31Svt6GwBVtt75ZOc= ) -7GD2384TAD22TQJ5ULAC03C93FO12QF0.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 7NS0GBBS9N6L1E3OM48637F6HOKCOLQB - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - 4nqxLigxKw86DpZ0KAo/k0507oWoind1FOCV - GDJvF+YejkSuvJFpAtfVSUrw690XZ7+zyuoV - 05e7BH07rcJV9TeSTgWe86nIGegDr+yzZBEZ - 3eGsbCwHxrR9ROieVBxNpWnfkVrA6MFqHZj1 - trAY6ajLrb/+kQEBaBdPC668tJE= ) -6T8FEOHJ6MH3O1N4B0H6AES9842FDUSS.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 74EBGC37NAC14CAFDT47M48A5JSFFSL2 DNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - i0z9WCo2snvGjQJvl2ZOkzg0PwCBuCPlDZ2U - NTbw3k/P4N90yVYu7IuJVEOuwPNaKHzBnz1u - 2vzYxM/fJHkWi4FljRFGGHC2ViBKJS+li5FK - KVUXwqZCHWlEc5tZ6lrpFTv5Q7h0zC6M3gSt - kBl8r8CZY75Yls/xGk7NZDd40R0= ) -7NS0GBBS9N6L1E3OM48637F6HOKCOLQB.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 80I3RRJLHHEFK8HQHD2A8O6VBHGKBSJ7 - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - VXcnf/ptpsoJgahBd0QYFkxBqyBE7ZOPNFJO - jT/fh6syVGIuV/FVSPY5c24RTs0pU59FPW1e - Ce1bDLWR30pyZfXBrwLmvjwn6XA+RhYtlBu2 - vE31i9zr8pSnZ3GU553zE/30J3ggO+WLQy6f - sLMmPynGnACOMz8hwvAuqATLswA= ) -9LF5T2M8139TAUL9LBR53N1RLU9BLIFG.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 9T92PKASBK46QUITTDHH5T7U73HFLO9A - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - vJJLcMmUHJIKxBS1a33EljJpocAmudNOZJ1k - KKpoHIfhN2U4b2GbaAQRbPIttDW14dmwuqZg - pi//Vm5krSx1PrVWoaCwvyn/9Fey3PcY4zWX - Rj5m/zgMrqnK8mVdnCVTcSVwlgpcJrpiYxxA - 5/Lj2MsiY9vf2Gk9kcYqyg09iqg= ) -4F4ISAF7SLHE2FVS6IH2N1HHOCVUTMTN.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 6A3ESFQICSC9TLOHO0P20QB3T0H8DHNT CNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - QO6x9M8tKx9nEwTGTLOmWJm2ReQWdDJq/s8x - CyLc8W1v38iqMgP/X0e+un2MicXkG9Xx6bn/ - KBCMVx16q9MFfpdyQaxvc3w0ZvRliAupP9iH - pFS5igBe/BAnUS7O6jjAaY03frbz+JaAmNUU - qbyEm+nfWWDWmPpVgU9qMTh4Iz8= ) -9T92PKASBK46QUITTDHH5T7U73HFLO9A.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 B939IPLCHDGHKH64CLV0F799P2QFKODM DNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - b08XgQYnvasffMbun6yS0gohnuJL2TklNPf8 - AA+2g036YcXQeLTHHMgzgxrpUTKVAnBP8G4U - gWD+xRwsys2q4Ws14oG9SAos+YEcus8AGs+7 - AFtHyOyBmRwOgP90Iu4W27bpIYf8D0mTC/vL - JDFkAVYzcL5DW7Rx+pr2F8bqY3I= ) -C8BNH0HKUBJF5F9Q6TV3BLVDP2H05C7D.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 DB9UE21NARLOFV0U06U8CMVKP4GNC10K NS - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - bxfqIBTAIogKzXbyqPnlv+MFIyoYlIT6knm7 - F6BZp9Q0VXNgVM6dEU0THhIzPvaMszn55Tg/ - lEohKrDuFWgbEbWpA9CQEm3LFLVg9QYuYl4j - 3Glym7TdGl3PDGagEpmHvLHx4gKbnqZWtN6J - uudu2UAlp8EUP4BWwsCsbnzLk2g= ) -80I3RRJLHHEFK8HQHD2A8O6VBHGKBSJ7.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 9LF5T2M8139TAUL9LBR53N1RLU9BLIFG CNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - A2sU+74sIE4X4Ai2pzJPngzssUG9q6FTrBA2 - ZcvOZtkzS1hY9OafSHoyKonqlRC9A+tX8Ny0 - by2M66eX4NvlinGyBJWdC5Ekj1b5cMy6Pcig - zcMAGsj91MZOqA8gwKiJ8xRGF/LUf1YdlQAb - qD2MLj83BSzg2m5lXl9EVMLmQwg= ) -DB9UE21NARLOFV0U06U8CMVKP4GNC10K.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 DE3D7U7081COUA3PSVT8MLFDGNGNMUTN A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - VPzYwah96Z+CrgO1cgRHzAe6DCDbn0wxGvfS - X7suIoXVhz71+PCksxmBzXCjEX8hkta8bfgy - KEweSDw/PAGeBq/gktmx4XravfhSrvcdxfyC - jaJQDfKvf//iJKujR4sP1crWnTNKXNLNO4io - AKiecOcs5L7FFLf/mG/tkRrZD4g= ) -2E74KFMC0MPQFVMLM1UD7O7HCEUV01TQ.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 2FIB35726VOBGISOGPQLFO6O5IRN3M0G A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - k4LLw681oD7qIr/GUupQFuOlbUJe0XkH5YHB - hG19hIy4BXPGYI0UEaxLnPcLsvhLgb+sdWTG - JL1JrRcCMRne0zNMY28sAzO1npbtN9pd9oK5 - ZYe5OK6wXpIvziGdJ/2eUVEmV+NrSJREgPbO - krsX8SxFss/S5i3C+UoWHQd9LoU= ) -EE6P9GRHC60PKN1E34GP2GFODTK9ABNL.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 ER30P5E30F7PBIBO9JHDUD2ATC20OKNQ NS - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - N1IBfELSSlFUJwA9WBo0CtNHwvsWrDnVTUGv - Cdfz3mp4H1CIUtKx36zX4CJeVXtwc+zWgKki - WZvpc00L+uvP6tIyMwGeshjd4etY5DqbnIuH - mCbIxGpVqgjhcAahCogG0kHBnNWkHYD37SZ7 - 9J/uwMoNHUGqpEKiy9PeIHfX3zw= ) -GDU5SE9F3JUO6HF8AONHIVJI53NAE301.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 GJPHM3J2JR55KMCICU1NPT84KMP1C4UU CNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - 1M5Lz9VF7zkSQWN+uUUHAvCIzj54/eRvqkkV - XLjviMkQ3G90qrS7Ro3FN35fbVdgn1sets/r - R87yO3TpgNwWjcBejT0KQXr3VI8me/Jr/yID - HlXpfkJZi7YfOs7Us7pKwlzXz6Ox90qtC0ce - 8WXbjdjrmdpiLAsdZxo1miQXTZA= ) -ER30P5E30F7PBIBO9JHDUD2ATC20OKNQ.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 GDU5SE9F3JUO6HF8AONHIVJI53NAE301 NS - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - TKkytnNfTi8pvoqjXO6V7CY20Zr9oosNb1/z - 3X7s5UBDZh5KR1aSDjFxt1FrY6+SJkTGHfC/ - 3pNerSIecbMJ5Y2crLJReXFt8zafrL6SLI/a - 2QwFVuqVWzacwN+0rSxCqcz1tUPcztv0KSv4 - 87yK39umtsKCQ76PaucVtj6DNYk= ) -GJPHM3J2JR55KMCICU1NPT84KMP1C4UU.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 HOJ16G88JKIIDO9ML2CJFV5SNJ8BFVEI A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - QYhzXTmXhrSEsN6ue8c0NgSTaLXVyauv8cTW - WA/Wa9MDa3+OzaI/X5VnDZOumbnAbX4p1EC3 - yHDrXC+QnQrgr6/Gj9rqCaNzyXKtmBYIGUvV - DZ4ZRayXeYc/18GgWrCx1gBTUsjsqy1ON/1K - i8R/aZhwzcUvWbqr1FlaTLSvk78= ) -HOJ16G88JKIIDO9ML2CJFV5SNJ8BFVEI.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 J2A0018O0QCSI08D608LDVJOLPTB3G96 CNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - bnvyEDA/snJUVw5jBhdMZ0ajEE4kcfiXVSM/ - P/cKiCEMgR+xhDrz4sUSWitQHz75QXLybgSj - cjU1XrjGP53kWGb3YEtWaM+JaqV/1yZEdCDH - ny+zyxcI0foYPu/4r9uqTWB9VLIRHCQol7kJ - XHu88kXYdu44hdiqQf5E0+VSdfQ= ) -J2A0018O0QCSI08D608LDVJOLPTB3G96.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 K3MJD76QQQ6H0RKERHB88S6LHEHOMJRV - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - jIknVULnzmGn8B3LoTKcuU6ELNYyRLagrI37 - XrnvlLjxWcqNk8W5aiNcVMhfEjlu6F2zLGLU - 4K4KLV1efxNfJpcp5Ki0lNS+i3HB0rkg8dP2 - j+UCsQ9wHbwzZNSbDli3/kQzEwnHvuuy9f5t - WCEXC1dwVt0QDrVu9yNVgXuW5SI= ) -N9INKG4137UMU0NL0U8V5FOTD66UJQIN.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 OBT94VQ2BVN9NBPVL65OCARNBQ92R9NS A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - P0xnjLy1AbyOUDyM1lbApfQxQILKU9m3lVIR - 6a419fA3jkFcBoB3A5ReXWFUW+lYuVGAL7cX - na/QB4J+skak7oEUz03Hoctc3eCR/ud7vobY - QULzq+cHzFsDUFC3b8ie0NWMZH8GNRGeHS0T - FtlHk4mQofYwQkF9Dbzdwn327iE= ) -OBT94VQ2BVN9NBPVL65OCARNBQ92R9NS.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 ONKAPQRU8HJED18U7QPRPJA8GGKP5RCQ CNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - uhM8yr7khK1/Ii3buLO+oHUY38t23CcSApyP - RUefb87LREQVtcNh26Oymd741/NfhvZmhop7 - Uvx0CxSICmjdV+u8Pm7/fbFK1Ha5m0/UvrUo - 0M4QNEGS8Jbs+xsshr8RbaBCpUStTCxz5og0 - E4lFekJEXuqT7wa/0TVBRyzWIQc= ) -DE3D7U7081COUA3PSVT8MLFDGNGNMUTN.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 EE6P9GRHC60PKN1E34GP2GFODTK9ABNL CNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - onPGqq1wHK4TnzDM0stR93s5SsCWFMQh0l0u - 3lVmvEh8T93G7OpfSEhRoQ9td9o5NxHSR6V0 - 4xxgDxvnjgMMbvDvgyeHLtnmRaaJhC6xL6jy - 0UQYb0Dz5S5aGocR6tvgDu8vmDgEmTx7zMV7 - 8vdwz2epzT40MX0hGAw9YhYdQGk= ) -B939IPLCHDGHKH64CLV0F799P2QFKODM.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 C8BNH0HKUBJF5F9Q6TV3BLVDP2H05C7D A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - nUn1EpD0cHWC8C9RnfBt4wBepa+DGQFU3nKU - 2+75RSeL1ltptxuuUmhmiBindtODFY10rdtP - TecPL4dsG5CXIZzx1zO0OMJalYFyN3MAnZXS - ENv/K7bWTal6OqVjxsYfrCqCcEmYW+8+0b+1 - vUhfqqaIAdCgVGYrzXMDoQ80m0A= ) -ONKAPQRU8HJED18U7QPRPJA8GGKP5RCQ.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 PO4K5TL8FC932CHVR1339QMSVCG8TFE5 SRV RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - d+sbaGrwmTVOfTajPdsD9NHEUpLXjjJ94Rpp - 9HIvdJozkwPOP4nUt2lc3lZiJ1OhK/GbMkHZ - wFlkPKmGeBPoa6FARpYuFj1DtDZhWCd+mTH/ - VMSzGiX8InCQGoTTiufT1G4aSP21oY+UtduF - KHJYikaPULyWgWjbqOpoO0OxFtM= ) -Q373J0K0LKK0NE6QLDMCDUMUS4D7N9DF.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 Q89JNCJ55KEMLN012BN386RRG5V35MGG CNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - ESQkjbD7LTon4QDSN6tZwU4ZaPopzvIXfJ5d - 3UorybWbBVrctR0AR4mvjuaY8jPuxjcn3awh - B/RwtlQ2oWrquPfFdinx60v6hmbhFJRSzIM7 - ob6tJObd6Be775r8M9N/aEi0ghtL7qv4BO0F - 3aoN1TKFHrFB58uyjmtNUBYtE2A= ) -Q89JNCJ55KEMLN012BN386RRG5V35MGG.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 S6102U94KPK3HL2EEB1KU341JC2EMML8 - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - s9GsCDhpCzdFG/lnYS1EXxD1yqW1Rs8NFsZi - ht7zt0qu+AlxFXZ5Y9rC3joPYzoVgMH6f0h5 - WItWvGHQ8gBQgjel7ZAKVSAdinYcyvXyh/g5 - XQ2xwbDHi/Gx736y3SNW3Ivr3vRRNQ/ORJgt - SQ0ECCQbhRryNCz25SlDDAxbs6w= ) -PO4K5TL8FC932CHVR1339QMSVCG8TFE5.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 Q373J0K0LKK0NE6QLDMCDUMUS4D7N9DF A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - cz7WE3bqo5gy7MGC+CCp5rQq2OmWp1T0fb4z - SA3kxsMIEh8CDG9B3ETauKSvBokyLHT+WVC1 - z96F1BiIM+ZDey0IYRDc3EGYhNBgdNGGan7N - GvyGpzTlwhBZAZNvn0Ledn9W6dI8DLBWEIbl - LFaBFwOGseR2VUp2u7yla73QTP0= ) -SEF41HBES71QEAB5G8DV253ODMLDJS10.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 VCVTKD7HV5II9DCBRH6O7O0FL9NV6O88 A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - SWIZLy2XlDbDRqN7UPOrWMxnc5MHzfw12I8A - VKGdUlXhOVcVEwVVAk4A3bXihVMP5gG5Z6WU - sLYFe5TOBmz66OjRmGNVODQNHpacdHeDvjQo - f3KcbWbl8CGH+uLxjGGkTpZ8MhJ8vm9w9cBq - urAsJbO1zFHDJi8zi9dQknmfJcQ= ) -VEK49TJCDQQ7AFSAH0A8MMF4EPP0LVFE.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 0J3ID6U2GQUPOADI9B867SGMROP8U4Q0 - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - bSvFoFDIForjpYjxvmq7au1hq0oyL5mSC5zl - V/4WXGT9lAYk7wOZUA/8jsp0BGha9deH0G64 - fTAfxt0OOuwibgqjXOEL9ioJ+xjk0ut1YQqc - lLenWNE7986fNLKihLk6CTIzXDRORqOp1cS/ - 1ZmeKTA5zT8oM7FUwGmxPYLjozc= ) -S6102U94KPK3HL2EEB1KU341JC2EMML8.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 SEF41HBES71QEAB5G8DV253ODMLDJS10 CNAME RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - LMpezs03lkHxNunfHXUIqt5nOhUVclymGgvM - JCqFIDuUyhi6pcOPm4lxK5uPjxl4H5rdBRQ8 - k0H3Ms3a4u0/wCFVgoZxsmxRBKuuYg8Hy2DY - 1wA8xshYi//tMqpSfaPn1qWOQ4H3Lmk1QQ9d - 7oS5xbj8LbxgRy2nHIMq2Tu/PLA= ) -VCVTKD7HV5II9DCBRH6O7O0FL9NV6O88.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 VEK49TJCDQQ7AFSAH0A8MMF4EPP0LVFE A NS SOA MX RRSIG DNSKEY NSEC3PARAM - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - KtSNurYbgzIR4o419h/wdNPJmiCe/N6V8Qpn - lL5L/ZE5JqnAq2MKdybxHpSwojGR2pTGehMc - GV5NEWqyK2TPN8f9stwJ0bH6N1/ab5iXe6Kt - F8zHjWXMDt/dwtKspsTt1crkXaI4qduta4Rp - IKoL0b5PqVr3vA4hvwAwqgYe/Zk= ) -K3MJD76QQQ6H0RKERHB88S6LHEHOMJRV.example.com. 3600 IN NSEC3 1 0 100 8B3F579FA62A6CE6 N9INKG4137UMU0NL0U8V5FOTD66UJQIN A RRSIG - 3600 RRSIG NSEC3 8 3 3600 20110331084524 ( - 20110301084524 28635 example.com. - zyqm5HgDE1CUqpY2D/UcceQ7GmJZvyZn2uWd - 9S9/As+NIp/Pf90E6bnhpPu5Hn6H34xubnKk - G7qH3IE8JcohHw4zRIv1kW4u0CLikBbNq+1d - rDkWz/FDjsV5QR+nxLlaGwkO12wgDQYSZwNw - ja5DoRdcCKz2T1jKcQ+NNr0j0Cg= ) diff --git a/samples/example.com.zone.signed b/samples/example.com.zone.signed index 851cc13..d57b39b 100644 --- a/samples/example.com.zone.signed +++ b/samples/example.com.zone.signed @@ -1,5 +1,5 @@ -; File written on Thu Feb 17 11:19:57 2011 -; dnssec_signzone version 9.7.1-P2 +; File written on Fri Feb 10 13:40:36 2012 +; dnssec_signzone version 9.7.3 example.com. 3600 IN SOA ns.example.com. username.example.com. ( 2007120711 ; serial 86400 ; refresh (1 day) @@ -7,50 +7,119 @@ example.com. 3600 IN SOA ns.example.com. username.example.com. ( 2419200 ; expire (4 weeks) 3600 ; minimum (1 hour) ) - 3600 RRSIG SOA 8 2 3600 20110319091957 ( - 20110217091957 20058 example.com. - T8PgPaLsdbkEfZvPHPvYV08y73yoEGqQuLOl - db4jvv48AUqt/Q/6dLMcWz6lpFDCEyf/9aCl - XVBhS+PAo3ex8lXye8MIyGvh5/yGFUveDHRM - TvigNYz3iJnJj6aK8nkSM29DUe92pkx2m76O - sT97uSoh+8FX8Vz4qRRBD6NwVIQ= ) + 3600 RRSIG SOA 7 2 3600 20120311113926 ( + 20120210113926 13760 example.com. + qeUEedzQrkf6Cjz94WT1EGT3WjqM8h3Sk7x0 + 6Yh9KILdnT5pb+Vr7cbqtd2OWl2Pje6qxNnH + w2ZIZN8f7DADz55BhYlT0Fvo8UBc6MaLDp3k + /8d18oNMEyRSd5/pJkjoJaJNAkHRQ/Mov6rT + 9fSUgAnJK7muHZanbgLN+WMIGlM= ) + 3600 RRSIG SOA 7 2 3600 20120311114013 ( + 20120210114013 59507 example.com. + hFSbRH5nZGOZMGhTsKDoAweBLwyoO1OweuMi + CWg/ABcOl/RkLsSvoPgDl8SITMi6r2l6Sc7B + TOktcW9BGfHY6XOOx/fGZK8lICGStsGGSs5q + owbDFFDaBffVbMjJueOMx8vF5FFKQ2A2L/2F + TQTduwav0Q2GJlMsmj3SGcCmUeo= ) + 3600 RRSIG SOA 7 2 3600 20120311114036 ( + 20120210114036 58574 example.com. + JJrtIed56dztpBx9xesWIAX1kRDtxJsUkzrh + a2BB2LhkjZDyhdQSX8kBhBzp6du9w3DDL5au + sG8mhAX14FOPdtGS/CRY3MmLZrTU2R75N7u0 + aRt3PSH5tYCj7Vhvyk+7XQyXVjh3OzPhTxju + oJVX2W6dfe8yTXDHwbRKnPmfEq4= ) 3600 NS c.a.example.com. 3600 NS ns.example.com. 3600 NS ns.somewhere.com. 3600 NS ns2.example.com. - 3600 RRSIG NS 8 2 3600 20110319091957 ( - 20110217091957 20058 example.com. - U8RogXPsS5rAUPbG0d8Wcvdk2NJ5ccvK4pda - jEfvIXXgZIib3T+gR+PwDuK4sMV2rQxsmcrr - qz3Vc15SQhyt+DAXVsrTojT8iu0NJXEZSr/H - ntPu2/BfVcHbq2wTu01QW1g9/ub0yUltbkcv - Mt8ZGiIyF5AoChy04SmZVlmuHSI= ) + 3600 RRSIG NS 7 2 3600 20120311113926 ( + 20120210113926 13760 example.com. + NddhSfnU9UdLkyD64EtrEuNiIuAupw8elpyf + 2jouZOcbhW/ZKQUvbIMhU3a3I28LqG3fxlcr + uTR2C163Qei1r3rvq9+dUEDzb5J15orGCpP1 + bSeca64RQ0ptda3tMJHiDuq1i6evocFFBnAH + YChMxdfMet4mRZD866ge+E7W08w= ) + 3600 RRSIG NS 7 2 3600 20120311114013 ( + 20120210114013 59507 example.com. + Q/7tyQTriPFc6SQYKv7nDylu8CiaPlOq973I + N5YGUCVflEnoRbL8f55bMUhllQqa/4RX8sS1 + ZzM8vuXlwfeP/7qtGgLt5kElUYjS2bUDRJJM + g83HlX/9dfwGKdXIU6GUsJ6jvW5mZO9ahTLI + oAqw8vVyb3+nwJAheW/6BaiOMJk= ) + 3600 RRSIG NS 7 2 3600 20120311114036 ( + 20120210114036 58574 example.com. + iA72EF8VQy04OUVZs4xf/GG8qKGOGTwgzQXZ + he7CnZHNjZ6wTUA1D8FoH71ZiLOiTJds9Im+ + HoxaynVnTSogxs5i0/HDdxtDonv5o81kf+aJ + XgRtsoE69Nl+54/xKePizzH7hgetcHca4lNe + uDMh186bBjzRobYICghSMuCrVZU= ) 3600 A 10.0.0.1 - 3600 RRSIG A 8 2 3600 20110319091957 ( - 20110217091957 20058 example.com. - RXbKPkFlSJLiKoliNUC+tlPKru2UZfdksz63 - Jdla5qf+prYU5HZlvMLD/Fs3dSmK7vx5S6gh - 4pzWAtI0NZ7NoHSsxk/aztoASeal0On55yCt - 9lXRQ+Avzl7Z41fyFTTdu3GF+tOfAoPuTegL - qDLokpWQTRfABy8zFIQvVvLWAHY= ) + 3600 RRSIG A 7 2 3600 20120311113926 ( + 20120210113926 13760 example.com. + F9Xe34UUok3PMJd/gfI+zwKZA574ndjaRLXc + iI++XwiuvIF65D6qiXsTKj/a3xwzNewo7HW0 + u465laJZkVeJwoB1lvWLXEo+6Ay/6hYM9UrZ + rqsZvKLENRwZnbCijgq3r27FZG28KV7KO7gR + KgneNutPNOk/acfQ86XhlPHmGgw= ) + 3600 RRSIG A 7 2 3600 20120311114013 ( + 20120210114013 59507 example.com. + F5LZdgZKg4+uJ06pf5FTcLuH3h65NGtxXcKH + /KazE+YiXBxYJLdEZvOtxqDtaoDtjTRer2O/ + lMO0MiLyY5CBDMB30U5GvfM8GfK+LTPa96k4 + fF7fFAOj1HlgoxQHgU2wvqG2V/2Pht6MRnSw + Wnd20BNvh2Qn/RbXf612bcMT5Xg= ) + 3600 RRSIG A 7 2 3600 20120311114036 ( + 20120210114036 58574 example.com. + ud19/QunaJLw5n0JFlbsBoKO/biKmOFG+EE1 + 5fP3cSP78ecZTDjyReuOxQRphxXal+msogRr + xVs655a1Auwe8e4SwLkVoBZXaPdwB05H7Uv5 + 6bfTx5CghzU2PhOqh/b6WSp2nE+98x9qmfXi + zyv5ZWWmxtUzBq75DJ8AEicvH/E= ) 3600 MX 10 mail.example.com. 3600 MX 20 mail2.example.com. 3600 MX 50 mail3.example.com. - 3600 RRSIG MX 8 2 3600 20110319091957 ( - 20110217091957 20058 example.com. - Skb7nbpNawsKpBZBC/4vVXUxioxbrPggr+Pv - EZzxrVcZN4PNL1vLQxWLKaZf9p0VWjFUh6Y7 - pyup5y8kL/y5PBM75jTIx+L95FlnB+Cef24c - z4f5eqGTteWxqBhp25ZNGNxs5lI6wWJkIObU - 2PHjtoZyXEGcYYQHtC5LQVQndbI= ) - 3600 NSEC *._tcp.example.com. A NS SOA MX RRSIG NSEC DNSKEY - 3600 RRSIG NSEC 8 2 3600 20110319091957 ( - 20110217091957 20058 example.com. - cM0Oa8GL61RYfdbLp3P6dH0gU2Yp1hsPvpkw - IBCcJ+0MNbZRxCTBnMBxt6VyBBAu9PPsTkgN - 1TdFmu1kD0fBP2bYAHrVg7xul7n9xoCKhWhx - x5Kj3bQCKlWL1AfhdH0fkXGyY4D8ufe4yItK - svm1y0TsIHnXO8aUrh+DOxyp4rE= ) + 3600 RRSIG MX 7 2 3600 20120311113926 ( + 20120210113926 13760 example.com. + g4iyNVNDBUD7SpiJIfm/BMlLvYj7Y/1cm6vs + 15zX82fUwxKPMEzVicrTwyvQPBs1G1KOxyGx + e0jMIIs/WDD9ZzG+xYBrct/pnGZFm/ztgKE0 + vcc9dW6On1qUcH4+VcOvauN2IpJELM3oyJil + 0QDO1xYwEzfcEsBmPnRDXPr+PzU= ) + 3600 RRSIG MX 7 2 3600 20120311114013 ( + 20120210114013 59507 example.com. + qsyCaJyTlST5swZgPFDWu4L7p7iNsg4ZUBH8 + /VxM+0WWkbKEg9uUoQouiA+3R89n64uzNFAp + tZS43DZ7G/P0JflxmSZT9Yiqb9uLYlRlx8JX + mvz6RXRkiJIBOwkDyZ2NBzrHRR/O5babTOzW + pg4le1zbH/QlhhiCdOtTbJoPxpU= ) + 3600 RRSIG MX 7 2 3600 20120311114036 ( + 20120210114036 58574 example.com. + lGiTwXcAu50SDtxLHCcKHjkNdK22mFjJzFmU + aPa7Rx+ZtGioKBNkRH6sfLmGmckAeotCu79u + ZZzuSksQd0fj4TwmjuHyw1SRoAuWmpR3BeKk + 0s3anU/wl0F686JJA9VPUB/VmZpVJJnIyUki + 6eX9rC25SSPENZz6r7LyNlB7JRk= ) + 3600 DNSKEY 256 3 7 ( + AwEAAar2/5Ofpjw0RYuiet7Vzmqp2eCchCkP + 0qfud2TF19PtGPu1tXkHd+NL+ZhnM+EDgYUh + H7V9mkBV6pv0Scjv3dre/vjrIl/doNvlrbjH + y1k3Jb8SfnwsCldzwZ3KHROre3XL8uMiuShK + TtwjHaCoOYNA0h1mIMsHd5o54NzGn5Q5 + ) ; key id = 13760 + 3600 DNSKEY 256 3 7 ( + AwEAAbvwMH12OejpiaI8weXipEquyNyzOffu + Dv/GGDJ4UiJqZSPb0YWzuG6LcL4BB+X4npDQ + SZQGOb26uiQnML2H3ZWsbKu+7qh2YDonSRKi + yqLnlv/oFbbz26HNVWjl+rGaIRcmw7IxTJcI + kk5DXClzeuYs7NQzxN7asDdFkE++qVCX + ) ; key id = 58574 + 3600 DNSKEY 256 3 7 ( + AwEAAdq9WVhtJHuVPUvhkH8BFw6JVCQC9r8K + ti/sRDFtJPbX9wKtONBjbzD7lw/6myXZC0Qm + BK3rRYG3EkpH1lbfqnXxe7A9qiniOsr2QqEO + hN8iQY92tib3TaIBQH38P7irejPbMFbeHYB3 + O3iZkYnnr/TpnyD3Oob/CNX2Dg6Jb8/7 + ) ; key id = 59507 3600 DNSKEY 256 3 8 ( AwEAAbns20HerHdgnwqTXVG1a3764I7hVAzp ahf9AF2dq+f+/aC8CWwow9BxU2uUSxDGj33c @@ -65,6 +134,42 @@ example.com. 3600 IN SOA ns.example.com. username.example.com. ( xTV9Qky/ZRwO7Le/LbhsYgzw6eSE8d1xOUrb 3w9PL8Zn5/059TE4yjmO8W73AZakgMtL ) ; key id = 20058 + 3600 DNSKEY 257 3 7 ( + AwEAAbteFDeDikHmJRer5eXnEPdkbSOyrg4I + qOYl9eTUEyFxxGBuNBwpQ69iDLsBeznnTJSe + 6vbywUwBzEkm3g3APYSkQthXjYm7c4D+XK3h + GIEhX0GpCQfHVfhcxgB2NidLQTNm7SiZSSYM + m29MM6wfJaSRtq5uclRZcEwDQXfAFP24QT4g + oi4bsyoeh+3n/AuAi7KXy4e8sAGJqdJTjuCZ + DWCUpz6yBeLQBPihn0/6VnIjlioMTuaIeHEV + qhDp2OaLrFScy7A7n5fzCNRUsdZYdv3JsgN5 + p/bTx3Uep9nlSXmpAFzESHSVnSElCF47t2ww + 4Og1SxsPhUcHiBMw1ftMYdM= + ) ; key id = 12624 + 3600 DNSKEY 257 3 7 ( + AwEAAb+dffUyUGEOYSUc6GFnm1m7Mq57YEpz + knSMY+US+7RWnzw5pPoGI8vEqVdFJ/q4pzVH + lgNAnVFxaWRE94c29RCjdX9RF8FY4g1/nEQ8 + 5ZlAgSK/HKBrS+mOumjkx6hVHH7ZPVt2RM4D + /6qTqEQJ/9S5UB/k2CPL2tGJg5t5AeljiiTt + gNVsVR2BAKnQw1cGuUoKsdEtPNg02uB1b4uC + DDfLb8pJcJPWneW8a5iPJaL/MsDf41BxUxXe + /f2T3Zq00p/UL6iiJBifQs0oFuz+zOfkBAwV + hc8ABzb+gdeMqYhfTROXSLPL1F8iG/6Yxhou + s1KPPGhr/wHxEckGXNX+cpk= + ) ; key id = 58515 + 3600 DNSKEY 257 3 7 ( + AwEAAeUpOTLiCuENRlyGBJLs14RUY2vyBDrY + tjd4y6SzbnSpAMxFcv8Lk+ehhOIYnk6fcF41 + nGpr9+UsFadfQ6gUQj/7Zw3Tb3vGXzT16X/C + cVOwC1f5qzgNdVeHJtpV3xv5+4Mjh0LCsJlT + tF2qsMwOBqELm78+RK+11NlmYA2zI/lsvSci + f1CIYX769oWR7ZX6E4jpgvEsSpqGpI+RgZa+ + E4yrwxnPRsRXE9WCLvykIhmftg77/8G8olYD + +/3S7iHecIqKaJ2mgZWpub8rryJOFfzXT8+T + ZCTo8fJ3qoyEscT3OyBzPqV64rluexzHdXaw + u+nNPps38uYchpCOS2wxWwk= + ) ; key id = 47859 3600 DNSKEY 257 3 8 ( AwEAAdA0zDQsBM+2/OI8I1lAmAvdf8cB5jiS wyyrjRjpWHlMQYiNXNTigb7fZdTx1SfX05Vf @@ -77,495 +182,1505 @@ example.com. 3600 IN SOA ns.example.com. username.example.com. ( WNsrCmbQE3zpwZsa7pCC8LW7YQowTtbjOIhZ DsatvWPhGGUaCemoTt2ceH0= ) ; key id = 49540 - 3600 RRSIG DNSKEY 8 2 3600 20110319091957 ( - 20110217091957 20058 example.com. - RW5kvcZuCmlM8DEb8teYpTRv8BCT87cvrlv2 - eJHlnIT03wjUVJx5pLr9gYrL1fjua4zGPLc6 - 8MjssdVoiHbYt7pZ9JVnGgrfTSMW5emkyu3+ - FazMDmCpMhy8GN6QyUADS9c12JkanNR+ugwW - i2IuR6VSZbBEbgK7wizdmu3yt58= ) - 3600 RRSIG DNSKEY 8 2 3600 20110319091957 ( - 20110217091957 49540 example.com. - AFg593dFrLP8EWKnKVQCpt+/rufL8mCTe/Ks - NozsesatF/B0LXkztK41wEFczeciTJOMlqcp - tbuaTUyiC0Lnz8yzAt1PRRxxZrjr8CVbwHDn - SodKElpfRA9MEFHEvphD7s8gnzCEVCQEw2zo - 8IbDapCNAADx8pDE976/ixKWca1XNbXGUUwv - LSKZ/pbNd4FCd8DqG3B7vcmVv8k5bGcJXdlU - v8OlI2rJXr9yVs4Tb/LgncLcDHOHg4TCKE5e - ssQ3qnAwC+PtJGMl+UF2Ar5Ue2JZXijkcgxx - fYYqB3yFaoxfn7neRE5CdALY+kMwv9ySkXWz - 1+D0NCjZGKIdnZCAcg== ) -*._tcp.example.com. 3600 IN SRV 0 0 0 . - 3600 RRSIG SRV 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - SZqwbOWOrGh0PB0st0OwVICwishDYIwM/VE1 - 3yp3/WboQFWESfrpv9QOfPD19yet97Zi17C/ - vQ7YifNWm/pKHOfvlgAMd5Y+Vku0Y7W85M5j - SsqjfDoiS6jPWKtHswVq8MRHIpRrCyLY7ZTM - fGp2A9SRGTa/vFyCgbvu76ampbs= ) - 3600 NSEC _foobar._tcp.example.com. SRV RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - B7lFuz7YrWCvuTs5wb0dA7a+FaKhzQnOYSAr - 4myC1mVFpRtTsk50n/NkUBTSDBoHjfDdlYU9 - DRBBct0PZTmRRv5EX0Eiw1BVs4mDa7WlYfFq - Xkc9nhY2jjOFbt8HTLsOdAahXV7VxQBHn8/w - ewrh0BvaM2Z/r4OHUqc2DVsgr2U= ) -a.example.com. 3600 IN A 10.0.0.4 - 3600 RRSIG A 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - KMwO1EvPdjDW7LJaKY85TPtUogFWA4IWQPvw - SKNX2aADOanzu/gnY2tVOhDq7mWJ9tQXlMtx - TwsAzcp+1PdEKCUjEBC53YQI/L1s3opKBl4S - HTLgGCKw5KhcALeWKGVJp4bbuuDFzmkpP3dw - DX41E74bR1qFeVofwcjuvQw45hw= ) - 3600 NSEC *.a.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - p09gsGkMo8QSE1ujTblgmpKqaOk6X5RXsIsi - 8oiOgpNiMfBIMAYNd4T8OqyAEoygvkqw4h/U - GuRSlSI1vFUzcsua+lVd9/WfbQ0gjWw9zzGL - rfku6PS+skQZPfZhkTh+a7TnUwoHb3K1sY5l - tM8Cph4mXhHJbiqxdAiQqjlSj7k= ) -*._udp.example.com. 3600 IN SRV 0 0 0 . - 3600 RRSIG SRV 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - IG3bi+NqZUHgSG0qyASuEc56z9HVV1/TMCUM - dMTBMfsMzG3LqI3qonhRGPelb9ELDlowKnXC - joMXetqLNPpsFsc6tO97yxmkDfAskAFpWmUu - UQ5lG5crlwJ+6PiVANXtrNNZnsMp/jiDFOoV - b7FrF48gfkt/8E6Mzq1nYKFn67I= ) - 3600 NSEC a.example.com. SRV RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - mQxN2DLH/YEO2bHnvKaHqhfJYkx3HHgqD8JM - fRbcRX/YDNY0oy0b7VNfN1J+4FYdCZ8r60eb - 39dFigjiSEXNXmi3SJ6X6irqv4ZOXwoxtjtk - CzQV5GsKXnERFcQ5SsCwSbFNik2R3gb3kYuW - qqvYpqPSVA+ScJ4cdNXODvL9zag= ) + 3600 RRSIG DNSKEY 7 2 3600 20120311114036 ( + 20120210114036 12624 example.com. + PFHuIix2X5Cecl4x9dit0Q3gJ/+6XmvAb71W + z2+BOXI3pQTObtR0nXJTrpEeWeyTNcaejVu2 + DsiqUkrNfmmEptu1SwtNO/obKST0ewwmfZC0 + fT/MT5FlRcdXNMXYbzTtykqfebCaQFEvDqtu + xMnKVlMn6Gl1GhJWL/FOCbx+h4M8j/7XeYMc + LeA5AUFxGJ9u7o2heWk218Q8wDas4ohsmkE8 + h6EAo1A6qzWvtYZBJ40iUibC01w2oSfqqN46 + /GdzHB1+SDomrctfwSOaVFuF2mSC1X+iy7GG + tX2Mq/kl5wEGrz9vgms6s9Y75oozIq0JOkWN + XYD9Nx5c0SsehA15sQ== ) + 3600 RRSIG DNSKEY 7 2 3600 20120311114036 ( + 20120210114036 58574 example.com. + ULc5iLBsBLh3hvOGEF9wXbhoPWVOsMdeXx79 + 0UPi/Ro/c92so7WiF8hZpXNKkuISOZsp/7C5 + kpO2Ds3qwHukLmcb60mdm2ORja5rG2vq9L6V + 8L9zOki6+uqCiBQr0yTmxKH2snI74O5xA2NW + 8e4Lqhm+8kqlarFOXdac+yPNdmY= ) + 0 NSEC3PARAM 1 0 10 AD3302FF + 0 RRSIG NSEC3PARAM 7 2 0 20120311113926 ( + 20120210113926 13760 example.com. + G/XZq9xvzAe34fFEBEbE/rsRvD9datHP4EJ+ + V6z0a0gfFlkY9dbkIe6Qtbd6vR3cXPqKTgEW + yOYf2qNs/ZW3lfskq4JNTsCgtw/ZnY5XwiNi + Blt32YKmtu6VpReXK1cdFkQ08nFeugW4S6aG + jFfzXAe3YAYa+Bwz/4Ku/E533fE= ) + 0 RRSIG NSEC3PARAM 7 2 0 20120311114013 ( + 20120210114013 59507 example.com. + sM4Zu2O4BVU7XRF9wPm2kpLgwdZJ3lkuJsbS + aVX0ZZsee1DgBwJc9E/LiCmP0yn9XhL2Iro7 + O/yKwD2dcg21kO97mnrFxBh4FwCBtgPU6W1R + TEt3QFhqG+qmhsESgPTntnpUncMWy+wo9pma + Q8Q01AOO41RjOcC4uee76V81Ajg= ) + 0 RRSIG NSEC3PARAM 7 2 0 20120311114036 ( + 20120210114036 58574 example.com. + KhqJ0xarqvbLOikDJgjg+mJ512KRlqxAtYRD + xS5HJ4xtbpaVSdJW88ROFZClAfETXHLFdZwV + yByF/d+cSSXM9BdmZRgr0fXjPVvVIzP0PvNW + kQar8vufIEAigxSX8gDXM9WTYonE1vfRc/Dx + RqmK8Mu5dFAGDA31A/ELVOvlKRk= ) _foobar._tcp.example.com. 3600 IN SRV 0 1 9 old-slow-box.example.com. 3600 IN SRV 0 3 9 new-fast-box.example.com. 3600 IN SRV 1 0 9 server.example.com. 3600 IN SRV 1 0 9 sysadmins-box.example.com. - 3600 RRSIG SRV 8 4 3600 20110319091957 ( - 20110217091957 20058 example.com. - jIA+72DXdYMsWQ45Sv2MBg0rI3rv/7oEqoA0 - rJ9X4la9o/ozwca7CJE8HKP6l43gzns1pfZ7 - +QsYW5BJOOB8ov+cCEVBW9XY37naNa8fKUsK - Mpzo35gaQ1zi9+FnseAwZ0WAicl4+766p4iJ - MzDEZA9VXvSMq36i/v8c+VMxFP4= ) - 3600 NSEC *._udp.example.com. SRV RRSIG NSEC - 3600 RRSIG NSEC 8 4 3600 20110319091957 ( - 20110217091957 20058 example.com. - npUQV7MbigckrB6D4jshTkGpOvZY4XTulYP1 - EUjN7Ttr8i56UEon3zzVY2ZUK4McyNrkzWqg - KPoFNG8xwf4bI2+WxdJeYo45PPZsy6bDTbMu - lYc68hQ35r3ok32SPG4GMuV53iuSJBCNrM9o - Rat/FL4Qoqzy+sVk1+tnz2ShzqI= ) + 3600 RRSIG SRV 7 4 3600 20120311113926 ( + 20120210113926 13760 example.com. + lsx9zG/XlVYf+5KwWAQIrO9dyjfrRg9jNXTL + Hr9k9cSwAo08lgiLBL+O9oSIYBoCE6ACR7bv + o3IMb8uhQmx5TOcmBZLC/9lV/E074aQfC2gc + AoQsc3djYzRnoLqFZutHF8vtTQGTtaTh6o3U + 4YwOrsJNE0/mey7QZh34CJgsbc4= ) + 3600 RRSIG SRV 7 4 3600 20120311114013 ( + 20120210114013 59507 example.com. + 1MZAWcrEJFkQn9y7urePqFVEP9Pw5bJdESjA + w19FeHRlqQpSxcxM9KPoTFDopFSRbcCMnVf+ + qNzeSjyM7m4n+B9F0L/ga/vlfO6JIc+klcV1 + 4nf775cBZNFhP3yiMhvQdFnu8KGdxPG+MKWj + 2eNPnYzjixr89NMTdAYULyCRhBc= ) + 3600 RRSIG SRV 7 4 3600 20120311114036 ( + 20120210114036 58574 example.com. + chZW5V4d2FPj/vPI7+ImeIxVFZ1xrK3D9/Gm + r3ssEGhtVwd7MvUDuZyNsTjQCjwahoB0PcPh + IZanWyFf0nFRNQ0LdMxpCqgzT1zkzdo4/lf6 + PJi0OxKvB+yiSg7VAihABUJ2dFdVIuUx28Ep + q7y+0mnJG1KErKbUNk35V1ZlJsg= ) +*._tcp.example.com. 3600 IN SRV 0 0 0 . + 3600 RRSIG SRV 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + K/uSiRdsTASX/dlfEFWCsfPMimzdFWU/L5UL + c6ZZdiz5v22vhVMMlKuNEIqOnBvkjh/nGJRb + ZVW/yfPeclrdgBBw7qxGJE8B6z3qoAyyjuEW + 2Eoh5eWxuPWTyc0DWsRxyY6WAgK7vKUcdeCd + PSLFF28pOBkqsmpnCgi3xC/PvW8= ) + 3600 RRSIG SRV 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + lUIdAHJ8vHyuGJk15SWXGvbcoWRUY/Wvxj9D + QglTe/VeBVrQtQe4kPiM9NyfKxW26QABrvb9 + pU8PJPN9KLLeGoZvLvkEwbyGIdq5jI7gp9mt + WXQUSegexHlAcL9BxzrO7sXBoomyWkzesLqs + f7P2qiR1Mnta59tctQ8crfy88a0= ) + 3600 RRSIG SRV 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + aiCp2Z/Skts3Wsn82oPP1OfBO60VmtC9ydDK + TwwrL5t0jipNIST8CUgrc33fZE4xrKLze3QG + G2UjpNZUk75/vbGMaSqPdwpOg+1ZXC+eM+BI + Rhhg8PE8yqfbHXOaCgbHzEDH2c8aZeeuAHXE + xbjuRntIOCJL/aZwciu2U8pi0Pw= ) +*._udp.example.com. 3600 IN SRV 0 0 0 . + 3600 RRSIG SRV 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + XnZgnLEz7E5rAboyJWVu6/t1rDvVfDGk7Zs5 + 5zpv+Ue1PDzpAnATldNqzyg3su4knjZf9uEu + wPeQ85YzGV+++YhmkfLCVtyjQl9+od3S2IOL + KOc6plEA/wxeKtQZooYOA2BSOcY9n+pn4CMc + +N1N0K5HKVD25wFIa5JqmeGvVq8= ) + 3600 RRSIG SRV 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + qLv8BCXSeS37ZEyfkQ+Dk/LLhdatK4yLLWwR + 06Xq+yBxa2Abax1zhnvwpJeW+3gR9X90Y/pr + dgc4QIcO/EiKMUI83+993lcmEvwMHcKHddNZ + LDujo/hgO8Qy+yUu7rs1x59dFa+jua1fwjZr + XlQ7OCerB3sxpkqoNFTDANc0TpU= ) + 3600 RRSIG SRV 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + OhyGUYdZTY1tDWHF0UKqHlXPQh92JS0krNBy + uD5F6HdeZP/nGW1hIiMx7y7dvCnWb8rRdHyC + yVH3ilGtiS9kAnFI4OTCfzYYopKcC13H0mzN + /MoSxpzvXer9UDtIM0GQcJFGJnvY4sMwTMa6 + ggRagi0EqBuimuJCaxPBXCAAOUw= ) +a.example.com. 3600 IN A 10.0.0.4 + 3600 RRSIG A 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + ib2NUsqQbTKZd7Rxe+UGX3GbEzlNB+IogQg4 + Dh0fyvi8hZlMT/3JSzVyTMggjvvD5yNiXQJO + 7QepRRTS3s8a/4w67g3GtI55umVgk9P7amrn + dkgVbhbUfNvtj1UHpE8bSntWjEJdwUczH+Hd + Rps+WWdtcQer9oHijs6T7sFweiI= ) + 3600 RRSIG A 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + HuovqaRWsK22AL4UamGL3IGxuV7Su6X6pYms + oFWGYwp1EIh7zLtyFbE+K87HQ2Uuoj/edcqe + gxmyAzPvZjv8M9J5N4DgLs2wHNK/aqjCcQwK + v9QoymZVwZPOeAkIHO6FW6+ez1V1uL2g0Dyd + 4sRRctkZw9k2dW5G6ZAi9cnf7Eo= ) + 3600 RRSIG A 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + MTtOXhChyvgyFVMr9DoM+Q6CEXmcXSjBR4PO + wIUQ/vjp//8B11WJGrJoOFJo4dzuWp7LO1eP + zGyrzCIj46ALhj1R+Vt/YJLuFEWwsj+RnYTW + RTtEdgD7/sN2R21HC+UOGe3tgAWMWBxIHaC6 + elzE2yderm0aTs1o8UduCJEWNf8= ) *.a.example.com. 3600 IN A 10.0.0.5 - 3600 RRSIG A 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - iHMA40EdVEV0HIxDKbxcOe74roa7X3Vi+lpr - XGJWx0gbVVhMsGdXi8YycbWAyHvwxImiU/VT - ZcDiDExzH89XZbzmEtP5vjAOBaf9rQu7cFzC - mAekgEEccVYSt6QLJTxcdk97CDRNkbU1kd02 - J09lSSyQL8ATADXIlWFUfMC8Fx4= ) - 3600 NSEC c.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - NKYN+2bmtp/2Bfic6vBqWAC/ouTz4qEUgdw9 - a153VST6W3UpROG/xiKV/STmURt8oYIzHy42 - UDRp8DmuVRMgeP7CCCYDmFq1+hSHv7iia79k - bvrSqdEbfaAjBkHMPlJyd3VjqKz0L+Q7sOKP - pWKItsBruF9UTJMP0Y4WLCvsD1Y= ) + 3600 RRSIG A 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + ig0iVfSdt1gbjMe6NtCLNZS+GAqeAV72cPNy + KRAtd9sorH2A/sfLRHET0FRjHqgFkoN3tMlD + g7Fl8N8rd4f6pofemt9VrhNqO4v4cIS+F60q + QYn0WAvBPpnBR9HRSOfkMve+Offa2E2Z0kai + EZ/FtyueZAa2pZwcdEMK0FHyxcU= ) + 3600 RRSIG A 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + TrA7KYJuGNJzBHDdVwkgpDGWyN0gG82nU0k8 + qTgBKTNDoMXqR0z6dgaghLzbCN3N5iRDWeHN + /gXB4bfyy0Tpr7JxTSHaHqFyxztAcSZBv4xr + Qv0ij9pTJJge44+H2cHikcE/yptVQsr5iTNW + 2u0R3k+1GrmmuuDZtE7JkUu8puQ= ) + 3600 RRSIG A 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + Cpm2UdGKo6fwa7+DIj03t2qdjM497Va2dHLF + +MWgfWOnubJdZ8lO3Omr01MRAwxqtDZztkKE + xIdps9n3dhNrAoVTPKO8ITnO5ku44fhrQ0Jd + Quimk88sMgZlYaL4xs1uKFX5U7WeIdYO0CkW + ycnD1UA20BvJejStxofTkqYF4yY= ) d.example.com. 3600 IN CNAME non-existing.example.com. - 3600 RRSIG CNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - KFfbRqMSwZOtr3plXJ2E9uKvEZjop9wpmq57 - EXq4Pus6pBhdPXXgwDo9/tDsTj6woScdlWyk - BsDYRIVfcu+jBbyTdFYSg2Em2A3XwtTxHD+s - wL3cRc7uKHs/FsWDVldxvrKy/ljX/kdmkiHN - xiRCWZsPa6kxB3/KtDRjYO6pkCM= ) - 3600 NSEC e.example.com. CNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - HbB+j61LK2AzrGmeLtVFRI4Ee+9dkh01xY44 - AHWKIEqqxRA95yOxWYDwVXXC4F1cO/UN0nAs - pTZekW8qb3vGrBUytno3mYZST+RHN8KcrWwL - n0nXsidEekA+ZGxRw7eltu8ECYX71C56bqp/ - DIilbcD1+bIyGxFHlYN77l+nVUw= ) + 3600 RRSIG CNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + BHiNhy1zE1ziC5xkpamNHfTYGFqpLprApsxZ + PSwnguEVR8GeCyCsD9IA0/1/uqPVrDlLlZtd + znztcUuG7iJCxN+mUtILjx9SsDeeHzOIDAz0 + sJbV/383B6SkbbhTWgLobg2HvCyieJCqY1M6 + yQ0zePBZi7YMc3E7qBriGF1crWg= ) + 3600 RRSIG CNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + J81+CQdrbye+lOEAuACsTdUhC5POtpQ2iHxe + HswN3pVr+9E2NZHeOExPdikWH/HrS7IwfeYE + eo8TuiZnygvxljK6pEASEL8cXrYahSVgjIPh + W+68MjxtkJIaFalWisgiffRgIbpo+HlhB4wK + OFYKHlocZLzPr24VX89DfYnVgH0= ) + 3600 RRSIG CNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + PShNWIZ4zS/VYTOsIEMSLmDgufGD3wJp2QyS + 2JXxj/rv0o644QlBcR9rz0CMhJBri4pochIa + 2Hb1i+WCFCFCEHuvU6DS5R42M2T2OQ96xjbk + bvYN6+h6Qle/N/Y0N20wZPFsQQvPXbL/xNSH + VaYxS1j66Jw+Wx7CCNEXl2UBU30= ) e.example.com. 3600 IN DNAME bogus25.com. - 3600 RRSIG DNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - SKLwv2FArbnNXXjaRxHsw3YcqYBxPNL/EETi - 6rKHVHHOgLN/IwQ6wLtmXZfRSV3Avw0pYmgt - 6hVda0mnJ8M4BPRal3z2cf9+PVX/f9kJWUNM - h1A/ibKKIwrhcdh4Z9s7QXGioE6WiEViG3zP - pfkajBllmOrE0pEH0YX1rWValCE= ) - 3600 NSEC f.example.com. DNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - swVPAYAboz3U8Y2Jcil1R6jUIAHggZlrs8I8 - ky7EAQTFYDRhLBC4UeGO+6DpkHAKCGepd2E7 - yojy/wttp4VhBxcaDGidc94z59Km/wuxF9Yk - cCYv7Ip6qLpk8L4CJOJvkFAGWTpkOYkA1qDR - tQ1IMSOsc6s1xaY9pd4vxmZkS4o= ) + 3600 RRSIG DNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + dFPAkQVZNn4La6rZgfRZW5Xf5XqMol5bBHHJ + tslLotEN4OGHGKfqY0AmNJ6BbaWm/pug0Ne4 + sflPqt9YX1le04WMkQg577OI3yjXKpb7leht + YFiLzAg7hdskQ+xlq74wBWrn6WoO2yZhP/fw + 0Ik8hdc5ktbvzr+/GOu01hNH1vQ= ) + 3600 RRSIG DNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + xKtV9LuyzQYmhPETm3gbG83EBTx+SbtQPMMG + byisttKCVIzNOGrDibcn74EiL4K+pVxxv2/d + 1Bs+wPdjH/9OWddsdflwwhbSzB/hhptH0sYz + VfLewN4+XXeMNZO7ofvoI6TKPNkti1bxiJlK + 7tXprVyQRbqrT23WeHy1zHJ6Mlo= ) + 3600 RRSIG DNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + F92JDZa+GomHTzEno6YB1oYcnvFPvfRybfhk + 9CHJ5MY+elSYVVG27veVYqgEGCshqTwYzP46 + S0jJF/H3muFXa5A3at+8BNEoKj5PEZFNMe+8 + 8YVSIjOpLdecPCZFqrjQCqwNUInzrpzHuk2w + BOWgLfAfBTq/thRG6admkJ2ROnA= ) c.example.com. 3600 IN CNAME c.a.example.com. - 3600 RRSIG CNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - hlO9jq8fIGbacLj9oYvwwyz65+z6ttWGg0Dh - wel26v08PEEJ19wVcZsXwiZi5ey9xaNG0OfC - z0xeH4XCOYaFGtKjSAqpT1FLGmcFOqhbGP2+ - 4pxICNlMonG+w/p7YePr5jyDILbTbUmp62Hc - ZoV+MVNvjFpDbxgHvCpFoGZguqs= ) - 3600 NSEC d.example.com. CNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - yTCDrpHhmnrwD8HxGPwPAXCmCik9aFyfESjW - 7bqrVgo8/pH57JJxGw1FVdoP46+ba1E0XRmo - zBdKKjum19SJBV5rzTFsJ58TDxsIeXWgwZgB - +RKY/peVIEfhuBHfLhdPocWB7rrk0dCDsLmN - FbmhtNkmXs9CKLYv/ucsXnEEyYU= ) -g.example.com. 3600 IN CNAME www.bogus25.com. - 3600 RRSIG CNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - PCl2njNFV8UQjnI5C5QUOE4IPETqM3orSN/e - B0WhX8QRvYRqJgayP07tjgaslUIzpAWo4t/J - +R1bjfkj4w0Kxk+eABUgyHBq4Cd1EO82L88L - DVvrDAXxg7Uw1dkeeN8y5ZuJ0tK71AE7XJ7u - YdTpbi7cfwcJuhRY45NbZDVtLd8= ) - 3600 NSEC f.g.example.com. CNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - zVhwl4EzpNuLNvPr5y5m8hIZyjhMzHSMNPQz - gMqljABxOeeNw3r5y9NZzm+6vczJVuJstrzr - n99bHnis0CX9QHZ9JMyZM2+qDLqvFccjAqTF - TwZBRhYODrI6u61DiRPCum8J2sIiEwIOVW8a - cDosel0Kz5cckjLJmyvew+vI2Hg= ) + 3600 RRSIG CNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + MCvKWbCBNUANSmRvzR+/p/qtJ7MDwBoHeCcq + zIRwrJIeLozb8+tjwk65pR4M936Me+CNLzaI + ToNZQecxnZfK5qp68KSKtJxsJ5gCI/VXy7S0 + mNodC1ER2Pp1/RTpRWzhp3syQ7VduK3iDIT1 + xh782chcZl2JOMyIHvlqxRNXSH8= ) + 3600 RRSIG CNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + MO2QcNGMPeDtMMIK0oChbxdCkUqcgtTFPmnH + 8pjXnHm04T1n7ABIIXU+NQikyjDw6WMclPJv + E6wmPmutp/ofVwvc5sqhePCM5wxfU70zZWGh + eAf3uT2O91qA3whptN6n8ATxWU6YKUzsc8lH + wcNQCBHZApKHhe4BX041hjxcXYk= ) + 3600 RRSIG CNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + euNFkmfD0fvlwJyRZVRrjDiqNGjWDKYPEBhn + GebVKZXQuoyVzabzhTFggK5IPAkv78VwBYDK + DYJ611l2jkspYw7F7BwatMwlo/coCksSmG1Q + jrPmQ3dqDTZwbf7w1hQEaAIh2hQuacQh/H/m + W1kufmhNcVShIzrmyUw1VpFvAa4= ) f.example.com. 3600 IN CNAME e.example.com. - 3600 RRSIG CNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - QLcICtoOCD6eqtqDlawijBoRkruFxtOY2lv5 - nrkQoZa0zarM4Y8Zs05PPjMnFYd1kVgDgzNq - 4RU3jd0bMM6vdFBDfg/HV1OK98nvA9upuFOy - Mn4Ll98aSkZ9rBW2nHMK0gxClGZBRSU0983v - +vcSrrwK/Xr5MLYzJPCyMzmZjt0= ) - 3600 NSEC g.example.com. CNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - zWPwHGblevq/icAJ2PEB/Vrexdk78ZqkQ4fb - sfKxqHXoXlXvXSTgMd+8jD83rpCwS9ju3W1c - XF0qcrw7kWVDsjuZB4ynustAWXFa61+S93Tz - clXNNb0zRFFt/pfhMi/6MG8VL3lPZ3seRUAH - sNqUj9cD8J3ViCJ6S2tD0EaWdqI= ) -*.j.k.example.com. 3600 IN A 10.0.0.22 - 3600 RRSIG A 8 4 3600 20110319091957 ( - 20110217091957 20058 example.com. - AhY44yY5dbyJvWFfEjxhksL0Jr2hGy7LAwFS - nM1+xeU40Z4+xB+6NEiwu+aa52ylbHkGyp7W - seQ0+8DG9biYIFm4QiEud/jQQIDEqYk/oVVX - +aJmTYsJbZFVmffWK5oG+/ncP/xfLcnPQ7Zp - GAvKgnnxSr0B+FNsFGwFrAJpyy8= ) - 3600 NSEC h.i.j.k.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 4 3600 20110319091957 ( - 20110217091957 20058 example.com. - aS+Z3vh9yrxVIk5w2t5SfuSjY52ylTaKCFoq - QP5WiZ+Ce9K9E5kenfU3ugmKxU2Ocwl7491G - 7mYW9ZxfBRnqoA4WZtszDL5g/qGNS0UQm2q7 - 1tVkBQlMt5vXQO7e0mK0upZ2Y+6mllgvv5/x - EfICd8LbiJuD8PqrixsiTZRGzXk= ) + 3600 RRSIG CNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + AUq/kYNePn4R4w5YddqK07RaFSvCLDVdRPPv + fU5ICNb/A6pdmuhk1OHi3iG2LSMdNhmSoa90 + PazNVOakW5UPpoIdNuvpNudnG+X5792X1B+b + 3ZcvPMkqlHKc14/Nh6U0njghlbBD1jFwHiqQ + xB4pjcv+mHBuGi7kIAmIa4L4oZY= ) + 3600 RRSIG CNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + s+KE8eUyftH6PawCzIHLrd9gZo1psXlnU1Hj + s5xERhyBCexFnYnIhd6MLmNfV89nMgjpRaDt + wrBML9tOqCjURBqBdNrN8hKPtNHP85zxTdrj + dshRFhhh91RFohJsGd3e1uFZ0e3eonOSGCmm + JzRtM8B/dKzd80ebnFkSjz3yV6Q= ) + 3600 RRSIG CNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + YHCSKb3hW5OSuqKTPlravCFlwFymQqRZg9z3 + SD4Hqjny69Lv2NEL9eU+DXzT5sUZn9ipueSY + 0/+WGYJUSotgrINgzVDvIlhYuBPvRAQJE+Fa + PT8HwO6BI/nw57+zUtnxpnphB9E6OvKNSa81 + qEvtb/q9AQANp4b/YhmGf0kwOmY= ) f.g.example.com. 3600 IN A 10.0.0.20 - 3600 RRSIG A 8 4 3600 20110319091957 ( - 20110217091957 20058 example.com. - EEOBQ2O31vmGHuj86oLBL5AmFAV7nVVxPjxI - +Xvru2Evbm2HJdZalcB8YwrFEdFGMpoxLpXo - FKevq2mGL0CfwifSfN6Z+lU6/m3JZQ5ugzXz - c6PFm/KDtCJtWkNIYtHGC4flj2rpMNlJ4ERm - /U/lfDy0PwPQ0QvYXZE8imXQsjw= ) - 3600 NSEC *.j.k.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 4 3600 20110319091957 ( - 20110217091957 20058 example.com. - knCwO1mKW8GKZr+jq0zT2FwlPwoK58GgvyGt - wvJmotKlu0pyYvVXeibowOxacDRx1SZA/Zue - nkA3dF83GWygxg36WjH3lyN+yaIFkuXtKYFH - nb/F6tIT6C26gnBJfMBKxm5mh6DqncIMFIad - p7ohHb/HKjj0CbGP55T6NV6OJdY= ) -*.l.example.com. 3600 IN CNAME c.example.com. - 3600 RRSIG CNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - bj2qkiCFVKzkmLafxnS70+gzkTErQgsJK1sl - SAxObFbBfG9eLGktw64k5XNSX1gK8cswj4Q0 - d/XkITXMf//rVgyRSXFkIRdalhW9VlkqNHll - muF5PQF3bqz1ec3aVYJoQJurnjKj9YIyCzNm - Y5gjwqB69xzc08hUM57WwS5PrYc= ) - 3600 NSEC mail.example.com. CNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - W5qj7ZHUIii8CR3sHkLc6ivln+AFK4SmxpjD - tgYUCWaUd8Y/ahldOzgCjzFY+I+hrUCifd1G - YLr0WtlNe/LgF9JhbiuIFg+SViBnLJzJAPR/ - yTr9qENKWQABvhmd5CfCsUAW/r8q5d+q4/9d - P7DfCX7FosksTkOuO5qSWFHiPAg= ) + 3600 RRSIG A 7 4 3600 20120311113926 ( + 20120210113926 13760 example.com. + AieEyxCXhj81os9lt1WfH72+/cm8Ff2IKe+O + f9oGk8bNi1EqYGIw8oGjwBMovrfmgxFM7vw8 + yU2TF5yKjjjIIo4iMkxQWPi5z/COxERXrNDJ + VuIgYQB7OgoXdkENHNTVXxm5R97r5n2vBKJR + pvfIixoPPmmoWEvGQNd4DykX320= ) + 3600 RRSIG A 7 4 3600 20120311114013 ( + 20120210114013 59507 example.com. + mO/ICPyqa/8kY+9jxVVSwdezxeaUpdmQQIrv + Ppvm9Q5dyFguHVMeoRewUoYz129ZXZMUXkEm + ZghIE0uaotgkSA0/YjVIMIGAPP5fl5oITKbm + GOUE4cZq3w2k0QtZ1ASnv8FWqMd2ZTRS0BdZ + NMRFZ/0RM9OJ2mm+vUq08vmc3wc= ) + 3600 RRSIG A 7 4 3600 20120311114036 ( + 20120210114036 58574 example.com. + F3Z83j1JjMr6B6gOcDaSw3I7HEgUBi1aSpQi + 0Es2CWc7WlJ5KXB/kvBas3F9qiyC1/Lje86v + x9LU+Nk63RHRRFvFCGynrZTFGgvR33ZT2v4x + adAExnwOij0e9W4PX3hmjwuh/Fa99lmJKV2T + Shw37xX35ahEjIqvJZ1IsgMAy+k= ) +g.example.com. 3600 IN CNAME www.bogus25.com. + 3600 RRSIG CNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + Rr1o+aiADRswGkANUQcAx+GFYHlWPC9pVx+y + jv9JlvfhpO+F6B5SdBIh+BDw57l6TOBD5AqF + ZH3hqfepTHL45sQ76+g4h0cwwQ2Mv83+SopC + HkWZoTBqOm4o7dETajZctlWrWzYy15H9YWo6 + VJz6PNjUFBQN9x7qitTc28xynG4= ) + 3600 RRSIG CNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + Q4Ti66ZAJXoiFlHi6TUEH+RXb7YR7BnS6RAa + 4A/7pEia5f6TclezkKLqT40+CaoIVRKm/TSl + hglITjs2lezvg4QKPqSqEk40Wg+lIL96+nYJ + SnwB88oSJxeECBcFW9qnqbr8Hbo2/4RGXDlG + cyfz698QmuenSgFzGYgARPB/dU8= ) + 3600 RRSIG CNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + eJ6BkMvJbhwfkjn6mtToSW9CFeRHOhA4ffUK + zh5iNL5BwZVs1JsTp7Pp9g2BnA/yv3Qt3cPp + Y44NjN4+CxQvQ3iSpkwJSG98b8QO7TioMC1x + xSpYimqjIO8duuPCJUdfN/tMrbX1Hu0sZXyg + RGrNjyK/zdq1GFkq/zKZL5JNGv0= ) h.i.j.k.example.com. 3600 IN A 10.0.0.21 - 3600 RRSIG A 8 6 3600 20110319091957 ( - 20110217091957 20058 example.com. - IfqXe0py5ug/bM3n+L8vIjgyEF+DPCkWZ1xj - LmHAYjBHW8fBnByoYNwSBayXJDzpVPrlGiGB - u7FC78yTqNeeGKgH72D7JgNybpEELpHY72+A - uYKOgizlOQn+172h5pmQcSNZjfRPVtK5wR3t - /ZOsz44siyNR3+TQEuDTnZnS59A= ) - 3600 NSEC *.l.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 6 3600 20110319091957 ( - 20110217091957 20058 example.com. - nTUAjiYPw6Gj+V+uz7gW27lYidi7Jgu1rTRY - 7GGZZHZRaFtoeM7ymSxZmlOdKrJxsjIhpXOC - ltU9dR0PJo1OnXKCQPrLjK3nIkNfGVcJU5Xj - MfNcdW6T1ursO2uZ7lrTOgBhSTxNNqiXln1d - HLwy1lHgTqNGg8QvdsbT1ixR3uE= ) -*.n.example.com. 3600 IN DNAME bogus25.com. - 3600 RRSIG DNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - gcuk3osH5dCvM2GgfVEogCuSNIQgQFAc+hY1 - igrm4uTT9Q+xrwRTKVqyaIZs/TovhKUS3npB - 4noVLbGJIlguztNvIgaB9wnam61NaFnBZRdW - 1guOnkExhSe/dTBupdEKVAw0WOrAOLlt06Fu - TFAAOBNo6384KB3aZ1RrKUu4Cqs= ) - 3600 NSEC new-fast-box.example.com. DNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - wMenqM3A9lWwZSHJz+7t0hBfTsB1JGK9qV9F - kGtJRNl0SuZA28bFRL0J5vSKj9tuB8EjCRdW - 2l885yaKKGSTF3aFzDnF2YW9mV6BadNGwdkC - +mYguk/tkPNW2TMdrYJC7StXKh8dOQIpT6/K - oc+ShVBYtQJocRy89hk9M4Ex9EA= ) + 3600 RRSIG A 7 6 3600 20120311113926 ( + 20120210113926 13760 example.com. + aX1wWf9oiP1B3jM1zbQsg2rrVf0HR3MIugsE + k3CXZ848XmdLFy6tU2/ZochGwfKnS8XN9G7Z + LT+oN/eTYc3F2Mfg5TBkPF990KDwnHGtMYiQ + pg80IaPEZBmaY+U8orjUFM6Gg0U2DJOfKBLQ + fJH2jpZgqiQYyzV1ho+s1aIOJEI= ) + 3600 RRSIG A 7 6 3600 20120311114013 ( + 20120210114013 59507 example.com. + riGA8p/s7c4pX7ftA1jK+6+c43VTgWYhWq21 + sC2azv8XVQEoXvhRz/X4Qk56YlihPX+oGn5m + LlBCa7Zan+JDpJ67wfBnVlNZCbqxyE1eZOZ3 + H6o3mRT2OhTEmdyogI/sXsjOn/XXd0B6O0r2 + /VsSmnpsRX+v5HEzBJ9PeIz+GVo= ) + 3600 RRSIG A 7 6 3600 20120311114036 ( + 20120210114036 58574 example.com. + W0GiAkNUBtaQFmPFD6Vk8MRkPwuRfQ6DMw60 + 3ZWkL/acliVdPjEJkqo3RnXaJpxs+sa80KUv + vO6MUNonsRyBx1LtxNkR74MF+DjDBpN1WqND + 2RbsGMNfFvOvQYdTq5C2hXIbz51KNdykm/Xc + QcENLRQxkZYW0uwM7SWeg0EB4is= ) mail.example.com. 3600 IN A 10.0.0.3 - 3600 RRSIG A 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - ah9IQBB/moRnqRL9mug+9cEE6Pz1YbJMQkUg - yzTeh/09bh3POMn9eZqo5bBx6vlDsFgUbw6e - IclZY4rV4mUeIWz2kEW/ZHc2tADDYVHRTQAy - 4sy3g+tF3d8OxMQZ0v6J2MTN9DlpVCaxbjPp - sd0xjJ2uBmn81DKbaZ8UKA5ND1E= ) - 3600 NSEC *.n.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - oJMJsjzzNWihix6CeVihqCI/ByqU0qm+hDWX - mvgss0U8VXQ1o6oUJ2kXB9agzhRtzo+Z/5jU - 6zFYajcnzuwD62jmLbz5NAzcyZX+ejyHtt+d - /wlkYGrumY1B4qB0YGRji66Wo68BK11VZ+a4 - hjsW6qRyHsQeKus3BfdQ2DRHU2s= ) + 3600 RRSIG A 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + TJUSJxyBdrie+gGZ6r3Lay1eeowmYvz3UcII + nTpoFq9jHodDL99EXZ+sCu2pf/OMx5Ema3DU + MSznJobBsrTGzZyUcCfYbbSdGZbcBGs9izBn + KU8HJQYIWGx0WCpuvrLINsv6+1GoaWdemVZg + A4FMaGR7FaXif/dI9aJ+tqwp+8E= ) + 3600 RRSIG A 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + KgyWfvPIJ024fWUzf3z0RCodgiWRN2QKBAwN + Mm1XevQn7gp4JQ7mR+FJttvi87Xp+2OJsEIo + ueMZR1QD6aDK+sgbsM7Tajhq3Z556FE4rSab + 8WJf39LRBry9tgH9FslDuNlIWk/We1H2o6cm + eg5iXj0U7X/91lhKgoNdP1ddMsQ= ) + 3600 RRSIG A 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + pvOxt+RdNf3ua9pN1BVXxLoRHTy/kccP2xQr + kxMa+3wvrmc7vML+/gD980xhZZ0rBas8kGV8 + ze9M2u+cX78/utyxVJYtv7NG+LNOBXIu/7is + Q5SKaegZ3asLF6LbV6IbruQ0QDSy41Oqxhpz + 9ePzKj/Q9Csp2DWBfwwzxuiPokE= ) +*.j.k.example.com. 3600 IN A 10.0.0.22 + 3600 RRSIG A 7 4 3600 20120311113926 ( + 20120210113926 13760 example.com. + dLQwDNg/9Gcxo/rpskAs8dt8fEOEdy7fFx1W + VUu1ZqEPjq00YLW9YHNy/h8ej+TSRUp/HONu + 4nX/MflexL5lWuqpszE823Yn9heOymH2HWu8 + q53vzETP9T/ZCvpnn7pJ06MRLQEch3Z7NSuJ + Ny642jlGMFkiP/2ES1dOZu9qLMA= ) + 3600 RRSIG A 7 4 3600 20120311114013 ( + 20120210114013 59507 example.com. + XxFMfqTLkVu/+yk4jN1TLdiBb1GQ9Ixk7k5t + X7d/80ACVp4JuaP21JlyDoFHqb+Zi08ZV4ZC + zr4H8ljlBBaD90u40fX5UY7t8cdqCmDX55/Z + 37Z4YRr/K+qM8p70K4J693o7fvbhmz5OriFt + 5QJRTXs5eMqfL9g/0oYQbmrAfBQ= ) + 3600 RRSIG A 7 4 3600 20120311114036 ( + 20120210114036 58574 example.com. + oUjQJX27CxtHnHu2DwGtrLYB/hB9SenofrDt + unJLWuyNuwwj7zWm9LEp42stvHRriTf36kk9 + kz7zHr2WnS5z3+tskZhWQuDx/OBidCfpwzvB + 4Y0qEckGdPyT2gk3iNLhxme5A7vmtEUfiibP + HWQYtUZPzbXK+4PEAeshF/7x68I= ) +*.l.example.com. 3600 IN CNAME c.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + FE/DRNChjWQr5UQUnr5uyv78LqVC2Eu4z5x+ + 9eJbUBarGeu+zpMauBfS/Unni8kZ/1LcD4/5 + z74CyTZIDG1ZaZJ81Osl5eVxCjGbyQNzzX6Q + v3Bpk2panHieIzKJdAFoPjgyteQQUD0JmPyI + h1VVuE1mPG0Q0DXV+ED3PJbk5ys= ) + 3600 RRSIG CNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + q3dxD/z/bMhBmv0Ui0nA6ii+1yndPxrnrYP4 + DDZymcbO5DX5+ZZjOAtUbFLHS+u0ZBkE9zTI + fYVVzsqRF8DBU+AhHezsYIJexExrBImJW4v8 + +ShIm85213nnyU1ZfLfwKpfJXTQ1gPWj6qAl + 0UZyPvCq7riyXYHTMzXk2IdzuxQ= ) + 3600 RRSIG CNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + XqLkSp6x+UINFdBNqFYfqg5qAA/yj12icenM + M8VLrf7eSaD9ADssVDSZQ8Zh8TEdTJtl+V1Q + KI67+UatPVymvrkCCCZeV5Pj4+iEqHJatpCw + x75+xRyVXkWCFTeKXdyTMU+6nBMoE+oSIN8Z + D6O+nmGX3aEUU5uyrTwg+lve0gM= ) ns.example.com. 3600 IN A 10.0.0.2 - 3600 RRSIG A 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - Lx5lSuiEjsbXrLW6PVIkoojgWfRTxIxdbVDv - 8lC5bUziKm41NQ0AVduIY/c08fBshJ83ylM1 - GqsZKwfqSszMIlHu3u5pONkMsYs7lxxYBdES - NZqEsTsaEmgnMlv6BM5cvstiJKVX7+z43y9j - XohTZ3G9UOv3B0uObMzabqweSfw= ) - 3600 NSEC ns2.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - rqlsD5SHTL9sXqlqBU/ZcAxn9pkKFZoRjAiB - kgdU8vExku+wGRbBB+c0toFbmPjJv1E4z9ae - fN3dfxCmIg049UspJUP0AqWOrtbQqqN2d3dl - ycJRw5Cpf7qOpp41EGJ/ujPzeIq6t0nW/m2P - JGkE9arlL8J802tFJKWn2aUc78Y= ) + 3600 RRSIG A 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + O3VYWRVnAspmT89PkbAOtzLoVaCt0Nx2k46f + qHRf/iBgICBY0w1ugRbLWB3Zf9AFrJnk0/X+ + 7iWq80FwRcsSStXSIxB+mRGFxRTB41sHxhNS + gRUgbB0VDE+UfMXOEHqjOzKw2L5s4HPKyo11 + sUmLO9prjHS+/TlWn9QV1OhV8nI= ) + 3600 RRSIG A 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + rutrFJR2YwhpCtNiz3nkaqwYAfqJklrwT5AI + 95T9nUZoT5IAcfhT2E2imm9ovvJ3LHX8eSxi + ffLcnhfPs+iXPTK4HUnooKvGD4QOEgN0MCBd + S+5dI4tZqX6Oa09JpnyFxHQjT2bHtviNa0oY + kdDjeFhl5pfrdTfBy0IeSU7UzqA= ) + 3600 RRSIG A 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + JLBOPoGSb+/QFg08RPs8Rl3q3vSxMC0sZcMS + XRL+OhWOKdg0fHMu8zOJ0AlaFnmQAGETKEGC + cUw/wC3HjBE8KNgnDzMP9cwgYxgMauh2+7Tp + 6WUe6Z2qdYb5OIfuWjb00aHUK5a1cx/kb+pc + zigJlsSVN34EcaQHdvenBXqbwds= ) +*.n.example.com. 3600 IN DNAME bogus25.com. + 3600 RRSIG DNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + YpRP8uc0g55raFFpFkY17ZARRML0vuNJJlsn + EXUD1s48+is2eoMhZQNXWchmcGrcPOcdGP3X + 2/L+laJDLcAYcSQrEJQtcXyjLz5nqaRKm28x + 0bsDFlM1dbI5bOP6JSPS/cCHRy1PbfZlI9GR + 04kl6sCzAzcFaJKtwK2qLhIsYSo= ) + 3600 RRSIG DNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + xTzl2eq7QImosoIU4nzEp5KkBWMAeuhSJrmi + dj9/jIuXRLBuOe1eVtC0639/SOJWWAMSGD5p + 6oKj8lAYhwU04h2JglH5LubpPeV6TVbteZRp + 7+Va+7NioEdyxncWoVW7Xsn7lOGQ78++dmYJ + yS3x4SbEw0W+jgW0vowJxEohsEc= ) + 3600 RRSIG DNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + tILOJHeCI6hgEYTKzEyMYjc60FFxHfn85Nhs + QiMex8bzGcbuIwdEt5vcC1pO5nDJjcmtyDZ/ + EOJILY0eaYuZDHwNODG2TEpQo9PNKe/ufzZ4 + lZR+Z9UnjuZaxAls62FsDatO30MwucabcehV + dAiO1jxlg1EiwrhUh6S1ub+hYZE= ) o.example.com. 3600 IN CNAME a.e.example.com. - 3600 RRSIG CNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - fjrWtwXBv82jZ6BWeYlfxLqxOvaZNONWqiIF - 6p3NM4Nwv7O1BvI+Jr9MzxAkk3CkTynGIFQc - 2wFDrAlT6XnBjJmvNiGf45utlhkifEYOR2Vw - qR1O3o3x4XMc+gVrmhdMaYAabZnD6YYPEybM - 6dLzSDMg5K6GjLJglmimT0wfTcI= ) - 3600 NSEC old-slow-box.example.com. CNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - RwVHMNAd0Qdcu85znEzuhPF47UmoEZ0uBo0M - jd8ySEH07eV0lg9JOpzvdo3gUD6zyYs3xC1S - CO/RcTGIhEAfvkhV1N4/S5eQzUn3Cc5iaXUG - WQNpYuE2JKaLr3m3iGmxO2JqkE8YqTyK2WEf - rAL2SunFcKua1KHX959yNFGtou0= ) + 3600 RRSIG CNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + StHh2y6i8Wy6z6vL1Hi5ANcCCHHYBceKRFyG + lvpCrYV3JUIhPIVfes4cRMW4umhq/BrD0+Hp + gUroc/B8RKrnklo28rPu9ooj1X16d4JhrDmZ + 1Lb9jeWuKrdNbL2rvsG1MmsdjwjWl6MDbmoc + MK9k860eEqGzbFDQq/N86j51VQE= ) + 3600 RRSIG CNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + ph1n8IxZ37Uh/adaYXeUf8eoSv3sQ8fWxHBi + Px69Aqh2KSjWbmmxXjlDeqYOJLhURYGPzoe+ + cVxIqMehVIX7GqKEO5O7ax6kYuXfBW2CluYs + LOC+6MmCvEMe8hdinGiH08N1G/P/8zTdPPjL + ckWdkMrEqaqrTcpfO2JuyS61wm8= ) + 3600 RRSIG CNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + mt/kg83oCi2ONU25Vmb9wztOMTp0ql0bJ5TW + X1vXheYNcss8Aah4iXkt+ubxTLkFEfqt3W1e + +ZOWm0+WwGQMFcwUBH8l3Rqf8UdhDRi1Kru+ + mI3kuHCffygLVtUilS5GfsGgamItgz6QiE0p + y/eLr3oIoTok4+Nrme0t/UKKMoI= ) new-fast-box.example.com. 3600 IN A 172.30.79.13 - 3600 RRSIG A 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - aeEl9FNzWG3QAPjDjCTZNMpO108nKfRqB8oW - Sw/e6Hynq4XKQuBBKNCvRBujuyrPMSuJdV1Z - xc1MGKMbSD1ZGyROhW+F1pTyRho1f3V4gmyI - 318iZuKxy+IbOVimYxXggM2xgkBgROOVI7r8 - slU5+SqZ3c/DfJn3cVHuevAI+wo= ) - 3600 NSEC ns.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - KF7gy4yC2SLwJvhCr/wBiNDWO68ypNu6EyBo - SyFnP3BsoZxsZvz3PYnG+slYAfMYqxfZAnEX - p8qMUQeWuZEzZLqmDw4/yrRupzjLDFE581vp - LVjUxYANKjOvYPbn+bPsuLKG2BuCcpyjLeEb - 4GrR1PBI6tRPfIyeUo1AUjXzlW8= ) -ns2.example.com. 3600 IN A 10.0.0.6 - 3600 RRSIG A 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - EjnIln97zP0GlFiF8J9HUuGBohcqvaAnCZUf - u9RuM4YhAijthrv+1vYJj9IKLE7JGXesVXcW - 6iLsddK05EA9UWcKhyOWrSIz2NmBBo0lj8uK - 7K/0zAvJ4uiSU+/CiGJBmzXxAQzC/gH4mU8k - vdpB7AufVUaKGDkB8203wk7LeiU= ) - 3600 NSEC o.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - cOxEjb/Aje8DI82rY7qNowoJ2VIiPOZIhlfr - MJMNDEiXBfbw+x53ewEj+YpnwwAAFWPrATtj - C/pEyxGCqwxEYkUCCTaM6YjhAKR0yPVJVkjY - GM1frct0/uOUuowalGf1SppZsxBKqv5cGq8o - x8GlBRNWt02ElyO2Wyy9k2TjKR4= ) -old-slow-box.example.com. 3600 IN A 172.30.79.11 - 3600 RRSIG A 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - ON91+7dJR8dAN2SUBZclVbrhRX8BOU5HLRYx - J8Iy4kiaPMNdLEHqXF2tK5FqSLKkZV9S6k1p - 5Hl1TUGYxVFq1+OxXpYzgk+Wy6QCW/sxWNky - ZpZ2X0ZzicI733kJ2YTZS8F7GaU053tCwOmY - wmLMKa6qd+FNh/xGLpUFrG6xRmo= ) - 3600 NSEC p.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - LFwXMS6XtokUOkda4DcVgSTNpuO2dhzUMbiu - LhfiYQ+nXn3Qwx0gORJZNdcMmUn3/j8dV/MN - Mfdil66OwG12ZNfi6LvLlj8DdMsBie/vHDLR - oUJUXdeQe5sM1rU+QoHfPCBXMWv5Bp6ZV8Wo - Bw1ASybab+P0JXWzlnKkfzgBUsg= ) -ns.sub.example.com. 3600 IN A 10.1.0.1 + 3600 RRSIG A 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + eujmHzNAKlZqXN9jSh0C9d5LTACh3WezXKgP + B/IGo3d2VOxIjiHPLgRIgmyTQOyo+iMIgqai + lgws/TxTeNe+olyDo4ijmXe3JEHRvt3k3Klv + soj7moubP2nBDUOL+RPGum1pKfepsYzvyp/o + v8ngIrMiYinBETP4su9UyXce7uU= ) + 3600 RRSIG A 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + CKfoEKHS6pzYQZnB+NvTVA5ejrX7sj1GYihJ + xCIZ4ATPkuJGPGmGHDO5DnUC485rIxYh5KdX + KtUZYOO1MmUBG+mDBZg2s3ITdIyhO4eCuEWz + 8SEimWMwfkZg3+dydfNLOC54Wqb13EMIpgFv + 6qc/7Qr3uNMx4LAUMD+fur754o4= ) + 3600 RRSIG A 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + jnisCwvrzRKVkP5HGETwkHeKN6SLRLWwvCiV + r/I8L+l1+6E/emB0J2ufm9J6TmE2M2AcSeCN + 72/feKcmaKiCk2JfkV/lG8/dR/2NKx1LoIlM + /PVL1xz9Dw2j7WV2uhnj0GRhBAkW79aq6Xj8 + cY2aLX7pg0qWKkZ7E+sPX6OWfpM= ) +server.example.com. 3600 IN A 172.30.79.10 + 3600 RRSIG A 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + YLVX509yH2zq3++9qh5Oy9uZWL5+C9dIn8RW + W+lEfoFtwQLpj/y3oIM7mm4xsM0V9o7+z6YJ + MxPVV/ZFmBRdGKDQF9krH+nR6q89lCc13t01 + tN9spDH73S41jnMQw27Y19rYKIVu61MXOfGR + 7KEv5WHOVkkER98bHb+bCK5yBD4= ) + 3600 RRSIG A 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + UVSj/Uujr7B/Jts7Hh1yLOkQsjlyEzSGQyb7 + yWzRyN3U7dOpmuU8yKZ0vbPscsBS8yEgvtqT + WeWfqiJ0/SI6WAY7IveLhzj724w2Ks8JRxUm + mH4thHGLN3tbXA4iXWge1WV3TAMuTXZ+nbrN + PaIx1PlE0/ZehIAFDrw0e1ffHqA= ) + 3600 RRSIG A 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + A5Y4Wly9iZUxYf3z1Nx+ehOHpSkHm7DbkP8v + mJIUK7g3FMcXEDFqcdbJ99o3ZoAAfpXZ+7ej + KfTTiPRrVoKalf/lHVrJsnoF+6LOfOxKkv4U + Vs6ETZssT/7HjHlZ/AbT3oi94zexh/8pweut + H3pGgxFN+inHP19L88y3JYX0RhQ= ) sub.example.com. 3600 IN NS ns.sub.example.com. - 3600 NSEC sub2.example.com. NS RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - HjalhqyrN25GoPU0znzhzh58b7nM8N4mLKsE - bB+edEZOkM15enAhMeKzYWtUau9DTWwUC3Ip - DeLUT5XKEm91Ln0UnK7GKWfSPfVyTrpNOpKi - EnCUpk9yVC3OKkYt5jCTlP5HjuLRh7IJLpfd - RPtrJqJJSNmHt2vFoSdMw54Z1Xk= ) -*.sub2.example.com. 3600 IN A 10.2.0.1 +ns.sub.example.com. 3600 IN A 10.1.0.1 sub2.example.com. 3600 IN NS ns.sub2.example.com. - 3600 NSEC sub3.example.com. NS RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - NdI/fYvlY5BQsIU98z37XRUtoYL+3d6NJBMn - erxI0rDgqceMFVI52Hl2POzqanYoqK9QEyWS - 9rnt6pKzCG3vZv7XcdyqFkP/sIoMNcevZw5/ - JJ172wyrfYRepkbQ20CL9KUGOyQaPJQs61wR - 1L/78YmA8QD+zduli61hwDRjN4Y= ) -p.example.com. 3600 IN CNAME a.sub.example.com. - 3600 RRSIG CNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - DQQ5JhXp1OUOTm6+Rtsb3idf0iO9PvuASLwU - 9tzKExU9piaTE7FQN95fq48Kv40iH3W7513p - JKbojGbZui2OR4l4V0gqDzP4MU0fhMi+kmt8 - oKhEY7FlOx09Ei9jS0wWYBnPAxIm5N1NSTbP - g5tQ7MWYtBNtyyrN9mSdicAaCvw= ) - 3600 NSEC server.example.com. CNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - LcvgnVSYj2bojkEPkHopvuwg097SLoVYVzDe - N9M4GbHYkPILrdevgmmNIhDw7FS5XJI4zVo9 - xvE+bUMK056uT+DmPSCJh36q9gt2bteSxbqb - yus9zWldGoUoQzwuvtWcjHwPtSnquL/16xUJ - 3FPwtqNGKw4Vx6zw5PXdY+jRTcs= ) +*.sub2.example.com. 3600 IN A 10.2.0.1 sub3.example.com. 3600 IN NS ns.sub2.example.com. - 3600 NSEC sub4.example.com. NS RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - QKnEmC9rfdkdEkLLKxcnm0EkAyW1QI56AuTG - +Mf2CoD+JHgf9dFKm9EOinM+pHcrlT6/XmUW - H2IKnWcoqs2B9Vrh9CeC9qXCnFxaNxgMG9hu - zg4H6LCW0pSKOoq8/KPCrtGGJTn6k8ck+qhP - hoz2O63tHuIpAtO6jcFL0B5jk7k= ) sub4.example.com. 3600 IN NS ns.example.com. - 3600 NSEC sub5.example.com. NS RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - pFTM518iEalVbWIisYeXX0mfel5D3EeKL2tV - e547nz5STOOKeqhaFpwiEkBnvBvbUJLDpNJH - bTpR98BDLnLPhSuhdQy1uBhONl6vaI6o0+P1 - 2cDaDQWat7Qc0bt2FOjWfhwzEJznqUvHFW1E - 3umsEPEXcHR4fmdPNnpvCnuCYv8= ) -server.example.com. 3600 IN A 172.30.79.10 - 3600 RRSIG A 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - ptyuguf9rHSyP8q4a+ob+kNl4ns3ZNzOT2NZ - +9lZsqpbbe6D15/6AVZyEz7NjLsLbSTbmUxI - MKacxVRUbJS1vQ7pztP/Lms4W+LsmnXafH0d - Pyj1OpArqckA/zeX05RXizUfqmsWq5thTZZ8 - VMsCFImGqpi+p3wr6FFc6NkuvEE= ) - 3600 NSEC sub.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - Tv46nHdkqO+SBiFf3RtDnIbyom2qGJ8w+ftJ - EYNfIdIghrR45az4sE5Ax2OzbIDzDycJhu8i - dSaLEgWASatClQZvzysdqoVmM2ajD+MgKTpv - Djr5BRpLSQc/qfEINM5lus1Gy1UNruhYc7XV - ah4fr1LXSrPGoo3bPk5r9Sy2VKI= ) +ns2.example.com. 3600 IN A 10.0.0.6 + 3600 RRSIG A 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + RtHrh3MAsZtWfaIkPvMZZnZZzN2W1umMTkEY + 55HH2pnPPE2VATR/lm4xf0la0FeB1jLWLUQ9 + 4TLuy1GARwrlqswvQNHRy1nwcUdHD6OEaKS3 + qsoLanpQtik5nJUwM5dx0hMrrdGPRYgyApBA + iSbOJI3VNUKr81kPz0zGaiWdTTk= ) + 3600 RRSIG A 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + n0bkcmtuzcTAk2gSSq+4GGY85YpHBQwXJi2d + Iw6GaWoXyXVDfy1+AzFfOD6V5EPv7v5x9xY7 + RmMiTvl6YF+4w2DHj38Ti3JB8agfzeQf/q7E + AX1RigpCgroCcGHbonW5497MbNmnG7CLthLI + wEyDwYOLlD7Kbwcgjf9tUxzsXfU= ) + 3600 RRSIG A 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + Fu11GG7pPC5WN8oNvrRE17Roy9b281A0/WqY + XyXSr3CU3GLIV7wg4w4Miig437ShK47GpHLt + mGBTNZAaRFQmWIC/jNfuJa/VynDytMjyu+Oa + cDpKVaMdO5CFVHyCC25LPorVGZOn8cll19DQ + hRbqAld7APpG7mdTdrO/sP/eqqo= ) +p.example.com. 3600 IN CNAME a.sub.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + etVmE9Klo4wb9DW6QLgm3sJckAGpSDjIp10k + 7ITKrsiK6c0bMV0rznp2tlWEa5tQkmgTbpeI + MxNCd8XHa9/OSHlV6LdQPYtzVujWPftOwfiA + FMdhzEnDh4dl6s7kuryzVjQfNCN9NbhwjaaM + muyrjUNGFjB2rcimQU76AKJzgDM= ) + 3600 RRSIG CNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + ztWlq1uFc4gkNpkPRyNGo3FsK3weYU8J0gBU + CQpHyE1RrGcD6upk3lh6r+TEiTHlNtAPYfK+ + RoAqVt9hPgTq6bErrsY53Ux9kVRwEIqQ6vIC + S6OEsEJjQkdJZ9X+4LMRxzWNNozbpe9YnBLI + COh0bm9vCY9Wryxkrlt9FzWrSEk= ) + 3600 RRSIG CNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + jOkv1c+V1vaBTcIOQdHlubwMjR2sFYzbDaSM + IBRsmuD3WtAmhNDO0yZLVjqkfNYTnA80at6B + P3n28xhJUIyxp9k7l2TSCBgHDK9NAeIj2PTe + KMLKsj8ZKg9W3lCa1XnMqbi/sqgKBMWt7GDs + e6g5LbPj8JVp3tdH0dv6KqRT7rg= ) +www.example.com. 3600 IN CNAME ns.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + CXfi5IjLMEJi/3V2PFsXZDVw4VH4QqrJhpcW + Y4do17PP9VjKpoqQBOR8VZz+WIVU6Y7ljaoj + kzvktCi+h3ZTa6/xWicAItN3H2/ZQpNJoQOQ + hE7O5BGE+/PAvd2LlQnEcN26flcKiutyZ51j + AuJ4LPsbmOFkm+zYYnITDbEOcwQ= ) + 3600 RRSIG CNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + B/G4dvFwNMaKID9C71Ic5DKEUpvSJOBJYqiF + whpHMweLnDNTvQwVpxyZMG9tRWzPyDoy3MWs + 0+KYqgBqoou51h9/W/SCTMFypmAwVD7Ln7f5 + 4vqXcP6fzKO14uk6HO0XtMvN67vNQ6MKxSCm + 1xrB8rworij3GlZzZAfIaJqpYms= ) + 3600 RRSIG CNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + Hfb+gJ4MSnrR0ng1EMiS1G+huX/WnI+0k3zC + Akkuqfg93Svnkzl7IiYCd5q4+S8MbZJHuqdk + jO/juQxdQMTu+pr03u0vJI3swgn5bAnYwEGq + /4aWbfbADJ3qZmeNSgqMlUgOzLY0kZRd+hhy + h178rruFMiRXZtcYZ82zzAw6Nwo= ) +old-slow-box.example.com. 3600 IN A 172.30.79.11 + 3600 RRSIG A 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + JMMCGey2OfFJRAoBZIq6+4fTF5iu1KGONFnm + 9tW/KAzAxAfhJYtrpUOX5mqXPiJJPBzq2/0V + BzhuxRaAZ8zQ7xv0HjchGRonkBkD+arCQTlD + Z4XBg83SfZ11yBvDjNpdoqhuqmUKKpxAGb7K + raoS89RnzG584+MOFiSBjK0BhRg= ) + 3600 RRSIG A 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + MfXNI2pFznN5m3gFUKZIGRGTwzW0+neZnHpB + 3org3XKj7PdEnESBiLHsqPpTTAv0GPMbdDcR + y4P2/TCXQajeq0bltIJ23k4yemesEKnENLB3 + VDFrcH+U0j4Zaj9PMWhaPsPMqIgDRml3Eflw + 2mqp30YOHQJKstmT9ney/gUagNQ= ) + 3600 RRSIG A 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + S+F0ghsUivJDNdZTuEpuz23HTpifoI6PQCjQ + xc8rU8yDh1f5mIBttEF1eL6Kl8TLJiHEnp6Y + qV1eZ8MzIruokK4sZjbqGT91Qadg3CQziC6M + SGBg1dzGnubD4EkqDhUgiReKHKphGOMh6hGA + z9ZLmq284c3MhE8HCQVm/Gzbao8= ) sub5.example.com. 3600 IN CNAME sub3.example.com. - 3600 RRSIG CNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - AP1MAgDTW5UYOQGZe1kW9qJGNComeMgBtQtK - PzsIU9y2TyrcSbU4wB8JRFJ1hMZk5wlkUe5M - yhvKe55wvknSlWOR1AU0vks0kSzhoPxHPxEM - NpMBV/Dv7NCGivh7LMxr0ra7EENNr4Ojv1Bl - bUAj8VMuLir8xqv5z3LzWTEVQ/g= ) - 3600 NSEC sysadmins-box.example.com. CNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - u+ulC7UqLA754CiYgKQHXquGhHHHoF3SifcC - lVHj9OTLXomfJMDJX5UG5K3yODlokaYVWOZS - MDus3B0LdAVv0+rEEPNxVBZ+t6P5/4JufESK - JFvxL3pSIU1bIlUZ4VDzgg5h6rBnA/oFavCc - a8xgf6FDwRNWVxdWcSfH/dStCSk= ) -wwwtest.example.com. 3600 IN CNAME www.example.com. - 3600 RRSIG CNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - GNh/COVeSULHxFcEBE66wv56YHNAWsPuSF7C - Cl2rc0JXlOCDhUqKy7ZKFTbXMZi++upiHpwI - BBbYLb7mhpLr/zEaOJH8QdiHsE7+hkY7oe2e - Gz1rvDyjx4XSugVXHr97RhZI7UA4opECDrIv - 5p3nqGLutSWju/grR6+keppEfFk= ) - 3600 NSEC example.com. CNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - sRklHhLmH7i22GH8W3j5N6qMrG0rEmUb2+d9 - QJVcnQCgwyeiO38DMN2Vvy8jqVgXN+C5uRHV - XcvUhJjyJ7x7zaxVKvncwlRBQkGj5hNmVCoJ - 4gpVzD3aerZ8fwwMUf+ETqBtbkBajsfayEXq - kpITfSd4Pi5IyVbIr420IconoPc= ) + 3600 RRSIG CNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + LwmV0GyJSmiA04UvzBtEXTqxNGQoJuw1WNkC + TUHcw+RMTp3dEa94cA3HvN4J9mFAONI7Py3s + t7ebHB7mgQ0ksYbAE+kzr5FeUFR+g3Di/h5S + ZtlwfpIMNSczM0OgZP77PPqkY1LPHTRDIXa2 + 3UZ7FgU6n5k7XA/36SrYALdlN1U= ) + 3600 RRSIG CNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + UsLiqhIFddPFAIITmc0n6fJz5YAFKXYjuGAN + wNam8W+dTtmdj48FOInJecWRX1byEFIdBp6S + 5QjRB/vLMjPhIVpGD0WZYj5QxCZZ1gwTXy+P + /nN5bkvNbkMPoplSBUNKMmtxOJbbA7ZgOiiK + ZLqLSeQIYbSZ89hyxpIZmXRsOiI= ) + 3600 RRSIG CNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + p6wqmfuG7A8F5zYvYatnq59OlRnD5XS9qrVF + ygaih/fN84cOP8O5wXJr7fmuhVWejorseI6r + 3m5pHum6UekHf+2xSziyFs3cIJfFKmJQ5uh2 + JR7sEiIe+hwgSGWVx/RyirW16ol+fWYhYE9e + IzzqeswPEe6dBZMUk4OqIT5GTsY= ) sysadmins-box.example.com. 3600 IN A 172.30.79.12 - 3600 RRSIG A 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - ztrXayS9OAxxKPP2U6DxtU3VNQ+aauZXNB+l - lxhXm2j/dFo6j6eR1hnRfGx6UeauQAdeKQA3 - OKeNaar6KbH9rw/iwnZbErWQurdUNVYvxEHD - fRRBa1b6d/zkwPcbdT+pSIZVoRzt9LrWQuEd - 2Gk5cBl6RP2oKxulDeP5XWXpQN8= ) - 3600 NSEC www.example.com. A RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - D03U27J/Yoan06O1qYHavUBHZZapO/f0GR5j - OfNHxpEvsiQmekeJNtYD/pm3aQhXjn8GDh57 - yrN6TBmo4tleL9M0w5BTT4Bm7yHdg69T+DgW - cVvgqv2Vgq/zbIYJuBd21doDh2LrkHcMbTas - FSYHA6OV8p6DzkbkXL9oykq/LCo= ) -www.example.com. 3600 IN CNAME ns.example.com. - 3600 RRSIG CNAME 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - ElzpT92LMJmKZq37lHmE6tOFDjh3RBdW3wRF - M63YsLhlP0OFNsbFefBA9H6qQdlV/OlP9QYD - FRn6hWPkuoelvDjyNdVFPc6CZrns4+eU34Yg - aGPZoKVszovHu22Lr4soJnDFwRAJ/DXcHMCJ - EHMSQpTYIg7AuDaBg9j+LqCVKZs= ) - 3600 NSEC wwwtest.example.com. CNAME RRSIG NSEC - 3600 RRSIG NSEC 8 3 3600 20110319091957 ( - 20110217091957 20058 example.com. - ycFBDZT3AHzyCklFxMheOfRyehNZNZsXHJei - h6Fi9AChB05oLVsM1MZqVQj0LPfZC7bJENtJ - XNwNz/wOJIjX4OUSGQQvEBLa+bzMvBg9i3L1 - YduNOH1xHGYbYKvxUd5b84XsIu1VQdffWDoK - hkFCBPGlL+A8/5qPva1FFdk3s6Q= ) + 3600 RRSIG A 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + ItoQw3SlGTWVcpQKf2W0n8hCQzAGBvhMTYhM + p5Vq3Ks9Sf8iiBi525i4s2jjo/bh5kM7Xloq + zWcq6JTJCyfMRNVmflVqnaiespLlYMiT4GXX + FJP/ez1r7IysSRT1C8PivlByxChC5aLFl3YS + x5uyFEIlPPcPuiCvcyoiA57nk38= ) + 3600 RRSIG A 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + rOAEIcQSCNINZl8ZapXg/GH71TeivQ2tec4/ + Bf8XzyDAtCJoETdRJ/2vA/Gh9mc0/f78x5Er + uY9gnqr7l+z7veBZHbqn2NAQxEXd5xjg/QcZ + MLUNpytyCb1XltUwAoh8ZmC1xWdTcM01fU+8 + 2EAQT3cWEEULps0yfSaeb9onx3E= ) + 3600 RRSIG A 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + ChMtph8oxYQNNllIadTWvtwq7HBt8msgZ5tm + t+Wi/RriVxGOA51KKMAj3QSHo8bG98bvQoqP + 2o2naWkDrKxUkw/iApwNwnfWYQWTGVx6e7pk + FVZtv2z2NFXjoVPHQZ/gkdYBx1EqumJdnzAP + C5dmH1WnQC9ixns647lcvJUExDw= ) +0R5AV1LGTS4HLPNB8UK2DTLCSO65OBJ7.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 1DN7NM4DOV8TAMT2O42J0T9M8B91CEB9 + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + msfUzi1BkrU6AubIJlsPXUNyH8frCK6xT5BQ + thUm0ftrYIkm7mt6wWw1SsoeWNZYMXGmv9Eg + 0tayicAHodB0cAI7AUMR6p09hUC/2Lq5sC2Q + xjxpTwEsyhE50CmUW6L4Ro01IKKaKLKFYYo8 + 23upUqDBGBLaXvZxmWn00HYd4m4= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + D8hb2ltU3bDzA4qIkxOGMHnntavQZ2QXsmoT + k9rhzdRdnpjnNKkywKaP4++hJnECwhaqDZmn + blkLpWKC71MhChw9JyB+3Fm1Rc6DHKfSNrO0 + oOREh2GWNcdnzuLilM3KLR0ByEdXRpRf8bt9 + wpt3pDqU4j5gSbYCtlG1McPX+DM= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + aLq8mvv55dUsGek/v/zxmWvZfHHYKaPvwJZ5 + zKP4s/kDNj9EJ2R59/kMx5pjCDacodDwAjJu + C41TqInL2B31FggghHNFCrX7tnQBnr5fkbHo + sPPDYEfc4hKVXosfwaCTKmtLkk2pFGEVSqgc + HKFBcOT277dHShmPNpzjSe1W1UU= ) +1DN7NM4DOV8TAMT2O42J0T9M8B91CEB9.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 3LVPU5M9BF6R0F9L1UB36HDOI6SNPA1K CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + qAioq4Gv8IaKHCGcrWLqa9+aISIZYW8ivD7s + lvZJ9TgfD8wvh8s1Rq1xcUeufxpM21PLqm9d + ZQkoalelTlGix5CJi53TYKy4lBuR7OL9Y5Mv + hnGcGlBNP+0yv5f7CYx37H2hGBxzVLBslU9s + 82eclo2SveXTxIHZ19Gs7rXQ354= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + Wcpxl+9CEHpE1jWrkhPt/mMuUTHVMMjVlS3j + Ni6e5ubILs6Ff2+DFBUQiCDo71Q8JJ+ABmq1 + kl6XHtFDceOg0GWbzvsRqVhsGI5fM0TF9XZz + zySY9drMrba/ImpC5qUFUGCwCS0sSK8fzWhy + 3w6i1xO5+jJfHmBD7w/eFBhX3UQ= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + X1QSQnz9t1pebXLpbqu9/+SRrw1LX9Ser/X3 + oI/z3I2pDuUwsH/MaJkzUHQd+z19xFnJPw25 + 1RpuwbC5U/7s6em1tyqJ+O1Op+1PQV3hZbz9 + CrrCYw5tJ2Lw1P5dHb/vV4y3176/XzBjNMuk + ktyP9HEUbxP+fXohM5KILAKlBlk= ) +3LVPU5M9BF6R0F9L1UB36HDOI6SNPA1K.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 572T84KRFBMQUC5O8I2V5BNLNHA8CBQN SRV RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + P/VgOsq/A9doxdcX59USly5uimiWExYdSQzj + IQgibgt5GP0Jn7tkAWNfCHCX16xS2/eFTBiX + 7faMXf7xdG75yCuH6SHyospG4Sck/S4BymhF + ilBv3xfEj/upwjBOX4rO53OpUu/eSVDc4UeR + UMJ4oIZ+MxEd3vveb2zi9TZUVOk= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + nRVgUIw6/jJS8FV3OUd7JGBgTAbeQQshwSIt + MRqLl8bHewPGHUTYDjNpvVkPhQAzdqeN1Imo + eG5TSCcSKDS1/i9PTyCVtcEKFWRRGoqJ4pXf + TZDyPuB4tqcu2tfkmZtGOeDnrmV6a4DulKRW + 4JDz5X065H5ZI8OOK8IoFqtME6w= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + IjycBX276kZZ/qW/ix4icZ9VNiD3p5noUp1q + 4ff05DVPq6alRP84zGqbLZ3w5vMe/drNiDtu + 55xk4F/9kgvk6YM62lk9OzJGPOLJUvWwz9i8 + trp3lOCuEx7FzPKTnpi5YGvHt852vrAacczD + dZDcRJWuaLEGmj8CocwvOhNrVkA= ) +wwwtest.example.com. 3600 IN CNAME www.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + T/WgP1/hiPDfDym10VMEQ6nGdD9Tbf9G48ZC + Wz//5BEJPZ/dUQ/RGY6T5oKPUO9UEv3v9tcr + 6N1vROBkgu7/hnbi/yGkDR0eZC6XZGR6zBJ+ + X09QDYNDddvWCSO015QQ976IF3Z+p6woAP6a + HnT73bx67YGI3snBdayTq6TYhDs= ) + 3600 RRSIG CNAME 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + hzNM/Vf21K93xVBJjEVluisjz8uscyidcoXd + EeFWTcMe1y4JIm9/HUv4qCjAcwQa2WKxQy+x + C/N3IgIHNbw4qoHrOEqkBi9YE+cMnDb4fvuN + hwxLVp+TObsv0pdD2TUsb7igX/YBTinSAeWE + fd6Krlc4MfHHcL9e19SroL83JNo= ) + 3600 RRSIG CNAME 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + fHA/W3JKDua3rz25CZdY9MRD/IR+DIK/qs5Q + QjPIdvxqLGsuuF7Kxze29Hckkm4ph5P+nRZ/ + 1D5cB58DSVutrEAhegF4UMZpfJjj0vCHoYT9 + +a7c3y2JJFTzlYmLeNSiDfNgEs/W7aCEf6Mw + KEquRC0ZaJqezda2Fmceoz7y4BY= ) +6K06BSDDT661B33QPG6F6EB14TIAJ42D.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 9CGLSFKECUFG8QODUCMQPMVH0JP35440 A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + FnLE422keDCUcjy4rWNTF+KHGGbdiI+FITwc + ecyC3+meN0HFb+OhlI/Nrr8IwdUIqQTVIOTR + a3/oZZDtne0XbR6bXw1/AKl+aRXLBsFWVyAK + ESLIWQvxaVwWG5fcB9MO1wOsjWpRxG544Ev0 + 5EDnA2qcdtDW8x+kSdylKgyDcoE= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + sxzypr5kURXb4lYRjOwhNW+ryDpFxd/bggBL + 7pEW36NILvCO+1PHdr644gCVMYbqXslsWlQE + JCBXeU3VTaDtWrtyl67AxKq+ZtguZVb7hCeO + AVCUnGW2A/99N179vOO/1PVPNkIqT0LmZ7MC + ugGWTJeOsuPqfDtK++SL8+LtqDA= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + lGQ31blQWd74cSH+4djKZc+bzpz5QH5ESFvU + HIuW5NGBUS0qnrIi8lLWyjAarvR8DsiVsyfN + jWRlIfviI++o/cq03nWjWNqMqL88l8ka3EYV + 6m2yyRJHlJkpcZ8UxwXoksrcJ+9LXmCAl448 + HpGct8DIFtIojJKhDkTkXRWQg7U= ) +572T84KRFBMQUC5O8I2V5BNLNHA8CBQN.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 58KH92475K4K07K5NV8KAHO2UOHLGA5N A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + ZFhKIc1AZKczgkkSDC1KotilNcZZI8MG0E9s + DIFiEMpZopagIvo/Mt33m0Qc1zs2c8zH6sAH + BBHvFO2GpxQRdQDJ06BZ29QqUJqo4ekA9v8g + i3mPFB0UQMYIxXjEQ/u2tucgA1RbRD2Zhr4G + bUB7vXOF6z5C53CE7j2dQ0CcKEs= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + A52sfF+O7caf0soRM9e8v1LMTlguJzqFfGcj + pq5LfXHMnM/dpVGivmiTypCYhF4th+jtXzCS + DyYid6ycFsCHEI2UX/GH46zY9/PV3Qg5YpMH + bB5U3Fkm+hJZbOhElIE9VzwdDUUQg0h3lr36 + uTDrFId9s/eOdvkmg3kIOplsZNQ= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + Vz5KSak6VR2xAasrITcxaYG2cixKpF2e2zhE + 4fOKeKs8cA1iJGQPCw1+TCafKdvhcXrGmToI + w0Gx9JHq9+JDcSjAsmTwvPwGn0QybHGP/OXz + 8MkExF6d9Tt/YX9PQ8kwYgrf2kOewAo5C5la + RVoIqvgqSWuBx9Nh1tzUhdb3/Gg= ) +58KH92475K4K07K5NV8KAHO2UOHLGA5N.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 600RRJ34OTBFOQCRPSG5J4F19RM76IOE A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + Xabi8Xuq+lzefpWqbWWQfTKRyIlr9uAPKpUt + Ot4mR+80gUrth6Kk+EU03KJU7hlTeRWISvf8 + CLrmS+QCg22NjeIK4Zf9V1X5oeLR7qTli4Y7 + XzTyRQ/bZ6sl4azfAfwL7Ipkvj7T5VQ/wYmg + SLYH25fdL9dMELM/mgp0h0di4g0= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + kc0m5pUs/yHxe16FVmR2jrLw2hCPtOyumRsX + MmjO0V+hSlToKJ3YgsDADN96qC5siTG09yQY + XLrQ9aSifIgtw9igbGXj3BabINA7zGY5hnH2 + byKDackMIliitU0LXM1PMzN8nf9EW01CTezy + Ck+MK3AwF93Qq+KxJ+212hDy8cg= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + b2zUsnj7rDfmr43Qwa2XSV+2Z7elsmFHyJ4Z + 6LJUKESn/01La7Qdtl8sF489gHpZR+8unp6O + QfHO5Agyp/OFt026FhfCbV9DOYgm3lgSFH8C + EVOsBN+v03ufrIIWiVX2bMQTJNrXBU4wZZnR + ZqWD6xnzTIAzxudmRahS1Cp203w= ) +600RRJ34OTBFOQCRPSG5J4F19RM76IOE.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 6K06BSDDT661B33QPG6F6EB14TIAJ42D SRV RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + L86fCGixazBOgs5RmRerniPJNXjeE5O/LzHE + 7e6B3mfMqehojAMudK0ZHy8zTsBQ5af0a77C + x62bEbbHi56fDpKfck5r+bFrnJeburjCdJ1T + arke2yK5SJJvSAhhsPGwgYluKu2doxXfSGZJ + IqLRmX+tghnSBFPwvwckXJRtUGM= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + 1gkarvb7+atyK0MX+o25E0OS9guVXLkoptMv + 6axx9r1GTKTmXubDc+m4FzsUyCtPj766yU/G + w4SorsdRhRWBoL/50GL3W0Svjywv20WX8mNK + TcDVIvWy4ovcUq/UmZhJDF4k66n4NsrGl0m+ + 1H/NoOMfxsvQeLTSxUUusYVRdwM= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + O/1ebTLAAO89Jwq3iesQziZ5CaFeLUOUMoxL + WrHF7zGEkOmRqTp0nhUwL+1mr7aWxkgugF2j + 5BEHAtq25Kq2QxGl99voqlGG8x50koS7bpVX + g5wdVq+l0TA3NVcd1VKu7ZRUExBIF4zYxtvc + 0nHHfHLxzo0WoHfa6WQSEv0FuCg= ) +AQCNF4KN2I1N0LNG51GONIIGCH7JRLBN.example.com. 3600 IN NSEC3 1 0 10 AD3302FF BMSTOMQ8U0QNBNODBRAAEPTFKDBLGOGS CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + ICDZ/5MqmxF+9zgSIQFOX1BNjzhpAbl44LMQ + heaVXzkTfXs/x+JYuUIbhtYIlK9xw9CvR29z + D08IK2rdqdGMhf7YsmxXGkA5EwGSuDbvEo0D + FyU/T6rcadaZM8WjPSJX6WxzFryDOcpNvezx + HQmJlM1ElTwduh1K6AWp4NunWVs= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + KiCqHwkebsPsgcfR+8TF7p1HW7xW8yApXKQp + dAxuMVge7UrIpKCM9ZxjV/O2lsppN++gphdV + 8jarDyqNfGz+QLeZqJG1BHEsvHzLvL1KxxsB + j2J/mVdp3PgceLC856psxsc3cnXX3pO34I/y + Dy6+5cOxEXSHLqMYUoDyQ/KuCq8= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + T8914GSwUmxdWI9h2rK3vq94xx1ehRX973Io + LZKiO4HnSNQFohAg16LcuoOEHqdfIxoLOuRi + IddfITRjfGnJNhUZnQmRpVDlmiogxsC/uYJc + mq3kUibdBZTluN6OLw9RA3mkXhYsN/xrkuIv + xUrllJ6K83/3WHIBxfFb7KulZ1E= ) +BMSTOMQ8U0QNBNODBRAAEPTFKDBLGOGS.example.com. 3600 IN NSEC3 1 0 10 AD3302FF BUKTJEVN7M7HJ26RT7O3EEK96L94VGVV + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + GPJRQ4SXLTbIgyZpqNndW+K8K504KtHZ2Hb1 + VuEri1H4FhnCJKzRTtw10yEV4V+VS6XWsWIn + S/Xs12hsL0Gx7rnFYMtH7tFrxTt34u6pNulB + JAKpYFkrsTaaxLUOMHL6GGKXUaUq5XmYCOvC + rK2wBs+0qSEKKFwhBfUfaGefyEQ= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + tmdL9xAC78cwTimpNO/TpSafGcGyT+nIu979 + /bKF658ognw5ZHBZ2XIvAO+nVo49qacKDweA + m5F6Huo7ANEbF/7DS9m1aSu6EzJze6v4ynKV + yHyqytEQWM/2zaunvPaOR1jQPqwCUyd4E1mA + RxYUxvCzhkRCn1nLa64fPtvZgs0= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + TUPU8dQqli/nfKyZw2agkdM+ZfiLjUL5L4eg + N07XR/V47M2ERuHts7kxo10JK0k3/6EK8Oj5 + SEAkqrNxAkpOGy0S8AXX6pjo0fzfrdveVeKr + Sg9YFbMm9qLcsaiPTM3G/UTuLjfyoRtL2FQB + i+xAX1B4LWuZJFoA7vE3UaPXY/s= ) +9CGLSFKECUFG8QODUCMQPMVH0JP35440.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 9OEBI5IG2AOVVIECGRSF2P0DVT6VFJ3V A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + gmFVIEEb3J1pRZnOYUgn/wlBeQ61YfZ5P8Dj + HJlN+SgUOAKLwmA7y6JDIdhG3jTOC8qlC+74 + Yzy4czwapCMtp8U5W25Hoj32sCiS+CMNzZD4 + 3hVBdm7NQI1PaAZzqL4nAdzZHhUoei2wflb4 + AiZTVHNyJ6wOXqj3xxAPMKgZIoU= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + ozGyuT+NVqxRINgvFl6u67dl2rMyXEDWEWv+ + CFGbuMfgfx+fAkcRj/g0r1RxeJ+SG0SY3IzU + TSUtTMTavkToBq1oR8uMhZhmeeGD8VsYdbP0 + 7b+E9XaUuvQ8nyhfxuV9fO0dtK6Vamjof1mG + fP2IGH5vvBZwZFkcWf44lys7s7w= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + RU3+Zw8pEKULu2rnCK8bwn78TB24uWynOa9g + UbOOqGqLRwtENxVk0KlLLYicN/IOS+2MHou1 + tzRCrIxa7QoxTKxhJeSbv75m7K3njQT5GlQ1 + A28P+CbCU93pPzvvOwwfGMwVOcEAkbsnFJLs + 2VANXPRhlDMz0sxxtjUjfj5on1Q= ) +9OEBI5IG2AOVVIECGRSF2P0DVT6VFJ3V.example.com. 3600 IN NSEC3 1 0 10 AD3302FF AQCNF4KN2I1N0LNG51GONIIGCH7JRLBN CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + OFyGfq+fIlz7QWr3/oPOBzDexpQiSxXlxFH8 + teLqjyVT+wyAQ0m38KcGJzpBkmG516MbCFLS + TNiMcdVFqVsXOs8Y/1dGB590C2cfb9lKF6JR + n0ARolZ1sToaXYjAMtxZhqTWNa51NwkV115C + CkDKUQNqxX8fuCnEweN1el+xIKk= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + YzaeqS7VcDuSSeq63+GFgQnqCzrn6Zw5NIyM + m6qRAJozcYAb92BxHsKYv4as8uj9qV8A4J8j + w3koisCsueEhgmtDkOU7bBf+CmDVjNEwE2YR + WWME52NqHQ/tkaz1wcBrMYlkgv7SmdoikQjr + 1HG1mkPe9SCFF3r7N97rhNlrNnc= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + sCJs4XcYOWK5JRscEFfHXnV15HwkzujcCG6E + m8GPYBK+SUNEFcmaMc/12afHVZA689tfIH6k + BdyCBQBcnbS/L7q0SEF978sGdL8gcwWzVlzQ + scpXokXgY8l2WX3mv9ar+18fJwVkfcCXM8cU + uBAhCk32+GaG5tbsw98n5wbLcZE= ) +D2S5TIC04S7ORKP09MAEOFV1GN1IQORK.example.com. 3600 IN NSEC3 1 0 10 AD3302FF DV0IMRDKSGUBTBMM94HHURG2QOPJS33D CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + JZW2lYvpmO8BrYK4z9CEGdO/gbOCt8DRZERP + h+bqs2qUkP/SBawWQmshPI9gi+XtIh/+w4fH + 3IccRojiByz3m1TptDwkR5ay1Us4oRns1S5F + U/AYkBvZXwvoYZQkY0QHRwPAvE77jjJRt2BY + ffpHEMo31Zv2MB6y1H+UkcYRZ34= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + m2c/CE62AzrReXZ+PI+y4k1JkgydR95TxKQS + McC1MFhldTfSBcjh6c2bMco4P6Cx7iixw+ja + CaOfHkTqo2NvU7wtBzOZluVguqdmW3SR6l2Z + WMG0IIvhc446ybgH0WI9X+4CjFMwa7FMxB1j + 1um+Aq1DQNsCpHchLN4e2Kn+ry4= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + pLamZh+7VkIwYqVhZ94/AzVgzgjFqNyq3tSg + 2Ncxm3UYxpMPGRlZYrfldUXpD4vfUJgUEmK8 + 6I1UosgxqeeDk9ZWSBqfD5Wh9/ngCqAQgPRw + oTP3WTaxEb6N7ub8pCozHHJiVn8aZInW9Nbm + kZQ3xvoOin9mRe7ovFysaKM4ecw= ) +BUKTJEVN7M7HJ26RT7O3EEK96L94VGVV.example.com. 3600 IN NSEC3 1 0 10 AD3302FF CITG8IDONU692P92JJHS57P0ADNMB59S A NS SOA MX RRSIG DNSKEY NSEC3PARAM + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + BnP6ytht0Oic613DxIN3F4JFZu4QB7elZtiQ + VXQQ7hpNw6P/jx2KJ+FU+ksqIYAl+cadZzBW + GxRgLAKP5r8m00GKfn1WfVrHkBtwne6s9FAt + u7B1cKN7Y9J6Tvj19W8uPEAkxy++g5BUrBLF + kX5GObd5kuCGBqB4SgwYsN7+GSs= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + yi5W3IGmzvS3Eu4w4ONnywCpL2UhDzr3/9u7 + Vf2ascqFbmDAaZv6nD6lc4M5l9Crd9BuoApL + QVqhLFMbb+OVr2RIQibYf2yElkG6uotMM1vx + s1osq4qzwYOReEes1p3cqP4CDv5jrD0QJFky + 1abOXlRUj0xRCHhmQSQdqEL5qy8= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + dd4PChhqHEJ+28qWmXrAvm9oirdHD3UkMlbi + Q6way4XdItktmp836y505XETzKfjaS4QQDEl + Amf76VTH9tDCCPaEoAx2FAp3mEwR8/X51+/q + UqyI6Zs4dxQ6R+jZpa6XV2gE3dp+dtgWjy6T + cPFKgBMCViayDO30S9lWpkvWgEs= ) +DV0IMRDKSGUBTBMM94HHURG2QOPJS33D.example.com. 3600 IN NSEC3 1 0 10 AD3302FF E7P2NFQQEAFD7JGEK6TDOE99B16J6KCI SRV RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + gEi3yTE7HRiArjBVOT9i2RdNfiYo5H+52Oi2 + ic7xMQ6ZGoJYn76NQOwU/IIK6ss+9NRC+M/B + 6U3gEvFJeb9pYd1Pt5U3KrlZflbS4XVWBPWM + rMYgxmXSI+9Pv7mhzdVxqY0C2ABjtFies6je + zYFDQCM0KZ2CSzl+1MbLwgAeXKM= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + O8H2yYOYWWp10jANk1KEjxrBUdV1PyqdjWfl + MJk5LfP6Z5YkCSZapRQ+B4er8RQDslucao8N + lRd48+M+0dtLjBO7U01T95g+lwW+gCQz0vhN + 4HDoZuEYpewsj2NGdsVRQ+XlQEDK3ULRgdGz + upbpaoSo5ZiKU56emBvf+Ii/mG8= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + OfTv4bNbctSlcHF/yzFzqfPbubU8v8CUqOG7 + e11r5PlFEJbjYmpM0c+OOgIqDYhk3uUSY8vK + sKkMf17EnVPGSxHKYu3DRR3SmX+Jrgv9PbGx + P1QOc8NvIEO4tm9I/AJ7DdZD/JzsCrV+HnwG + CHjQG0uSUmtcyo8VO0YuaBj7QOk= ) +CITG8IDONU692P92JJHS57P0ADNMB59S.example.com. 3600 IN NSEC3 1 0 10 AD3302FF D2S5TIC04S7ORKP09MAEOFV1GN1IQORK A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + laygNP/hV2kb+vMhexrqbecVRLImwX5+soSq + CDo0PQBFV0ohHgJBpYElV9tbril3iicjwLOs + YEco448dUSovQjdb210Za3PAdNVw46PCXj6H + iPH4sFcLmSSSMZ47Mm8Jh8J4+ERjmwize3/d + 3UvVj4WILaEiqDjCw1yBoIB6tdE= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + Bf2RUMaj/YvIaZBEtpEIR84I2t6sWwQJY5fp + 4bju8q0fmCr8K69ycMtFDNrmzcwK+HLmDHjm + SurPdU6/p5F1H7e03Rw7UhSJHDhhF8kZvY8p + Uc6geNfrWBw0N53AGVTI6JocCVb1ptEtXyOy + Jl8+aSVqh+k3G13u0lyxeNqDAzA= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + oBGvU4Co5tEM4KdWrP96N1P/ZDHDt8yI0HTm + z8bmaBcaSy1IS92xVT6orNyl6m7rWn0EC4UV + TZVHslzk2pQCkNZnuBIUkrlShcv7clHAInLk + wVFVk4yiCd2833NRc5WcanNrCKyeg5sC2U2N + 6WBYspJUQGfqvBgoNSkE4JW37Xw= ) +EM46BUMIU4I93E5FQSDJSIO6TG9OJ35I.example.com. 3600 IN NSEC3 1 0 10 AD3302FF G8QQP950BTQH4E0JDQTK2RCT5MI6A7B8 CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + IGhCvWz93eZHWlqsMNNbTb4NjEad3g8TL15Q + yAJ1J/1Dw2fxGV5gJ0dCov6r10BH+WM8JDjH + VQAV7ncI2UXiZKJk3+zTDkL7Wg9nmESUMmgS + wXwEgObKsQ2iJGdJCEiItTaiWqUCi3EnhGA2 + 0qngKtz8C/foDNT3eLVbeCseyos= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + zRd9YpFH3JFNlImV7Yu+hpzdwZ/sR6UQ6wiW + FWf5N7ZGLva7fTjdhg3wdq5XDNba7wPc5dlG + Zq+F7hkAE2xC/VplomblmhDh+40b4QCDGQtO + im6BoWF6iE66C0AgbiLs8EfNcnuWNsEDW0qm + MIORJAiSfvihWD/jbQxwFCb8+gE= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + IMOZIwFNLDAGeHDKLMCdChQeICgHE5PF95/E + okpS42Yu8YrMJPvE3bx92igVCMBkctD5jPXu + ZEHE19ZPRDFwE6akGF2I5ffFcENuOILHtOwG + eO+aFLKDoIRd64QMeSPyyOphg44Oc/mL74BW + gFwtNK3fke+69QQmoA/gf0+BxZY= ) +EAO0AESHP4M49Q5F332G7SOK1JH53NT4.example.com. 3600 IN NSEC3 1 0 10 AD3302FF EM46BUMIU4I93E5FQSDJSIO6TG9OJ35I + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + X/QUrNWKc2lEWDRDrhOzACOmcxNYbKv3yuuX + iV5Cl7mRJwqELi38+Cp6r3Hux5utyQD/8As7 + CIfuB30FE+gkFnwQJQ6SnN/0cTmfA+DXQr0K + KmP9VgAjcdjqNg0Ii+6PouhMLV0lb1qR7eok + cdhShP3OTn3HL7V8TBI+WG4i/i4= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + 0+IhHYExtbNG79aZuYhlTMkPA0XE5cUq2Ept + G6AwlriXydcKw64MJtw0FfRBljjeLsCV6vsS + ArrNSTRBnptpy5ChXK82Z93IV+NOzXGrhFU9 + t5vBmk+JJvKeUV/tRl/CC8S9m6JXeVGidUm/ + y0WLQ3RNjtCzKPoLlPghh19VgBY= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + CngXdsTmCn9HvyyeMrblrHxWyh9Y8D3/n9Q1 + JhVzB7jwf2itfRUEqnHGd8FGAR/hhV5XboYP + p+3uUmykoTF2yp0JjikZwLHgq7R1Fm9Ctcy1 + yehmNpa1Sp/UH4x8BmJ2wa40rq7SZyWKkhL6 + F1Y93Dfqyd9EkHfzbXE8vy6a5zE= ) +E7P2NFQQEAFD7JGEK6TDOE99B16J6KCI.example.com. 3600 IN NSEC3 1 0 10 AD3302FF EAO0AESHP4M49Q5F332G7SOK1JH53NT4 NS + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + KsOrVaAXuBLHZKbWufX6ToCwS7PPjrEdrAoo + Vw5DBfCKKYRRJfEurtljqmoYoZTxXUKvnDyt + j1HX3K3PMWUCeSruJ6dnT2WgxFDOC/pMatX3 + flSHbVObEwIDQ0Eiz/ynydDFUVycy1bjDg44 + tfXqPQuzGvOHL2peey/41/wr+Yg= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + 0512KQdUDl9nLYut0pZ4b823mOo+fPe1TstY + 36ruxDUg42vrh3gffP0rTmV5405H9eM9T38j + BvGiRtcKC4P/IKLZKz0Q2OrPKaRoPFw5KaPh + BVWzrit1vs7+IWGso8Ka9i0eGLOT4HgqM1x/ + GB0StyEIepOwjbdqHCsHO7FbsMI= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + DB6n09AUERJMJIOWSa9jLXKmgd5q8jqJ4fZJ + m3FqEUZIhtBziboYDgvzICIowowCjX3o4HnE + i9LGuUgvWwQDbda95TmAVqSrJJCNc24hpUoM + zcX9fWPjCJPHWxZ2ChOjvN+3cp6eSM8lUAoJ + ahasAbf5BUO6pE1gyNo9b+TsSDo= ) +G8QQP950BTQH4E0JDQTK2RCT5MI6A7B8.example.com. 3600 IN NSEC3 1 0 10 AD3302FF GC9S3VD2NHESSRL256KS0805PL0KAI2T DNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + k+wgT3opBCjyZBY5oJduYiTjnjiNwikz3Ybv + Y+i4td/QakMa7bfzKVg8RqFlwj+8l4x8hGhQ + kAEgkyFB9i08F4x7ZXYwODSfqFSebvzmKyl8 + eqJIHSOU/V6F6lUyaBo/9RPVZycjsUzHU1Ci + +dHXkad7d2+TMi3Tr6aplQYsqlo= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + K8gxRNkW3QTJscsf1pMBv0qNcBqi4pb+ARcn + ASCH1ykdMR9Pvhpx+9G+u9qo1QjE8EzfkLmH + Skz3YxMm6Az8zZxXbsWWlscz8aeXp4B6isk+ + HcP0EQFjFcbLc2LZRfJxTABi7MOwEgyeLIcy + 2SjANfi6PxWOp3cHHBn24z06CpY= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + W22o4fdbyQ50Z/Jndnd8ffhYSpzbgw+vHsRF + 1sJLXUwYn4GraEm1XnbZyatFGVcFVxe9Q3PQ + UMsw7XlHkbGMEm1oyfGCkT3PsPLB2m/jknhr + hGi3KAG6+UonCXkK0WGaHRbJHUOdYz0Qzdzd + VKV45Zgdx9cKbHvgsaR7hEUYO60= ) +IV7VKFB1OLT6DRIGHT0U4O0L6PU6KMBC.example.com. 3600 IN NSEC3 1 0 10 AD3302FF J7A75JJN87L9PTVO6HBKH8IPI78IPUO4 A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + FMXWpl6oQPZphacag5FOYqBCUY8Y+zwHjGzM + zq8GQZrnhV9Pq4/ENE2Slxl6GBoxP7hqz7fC + k69+s7H9hlP1gp0IyzLSWqqTs2UI6VZaA9SJ + OBTeRBoGbzDT8uRgCmLuQIp6iVQjgp/xzgAP + o+O6Ra4Je6bTTp0LvnRLLWRD+cU= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + FLzncovwrynHUcZAelmmRyTyNf1LVfJFa+Bz + CtwTM6s9a/rpkBRPocWF9925KL8ovp/fav/v + hHibW1qub6BBVnnluChdUOuFYAuWStqh64+u + XuKWJjD6i8Orn3chwmYZJt5sIuEdBRYyxOIy + 3IJjfHra3AAbFy0B4f0j8ccKXZE= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + aepONihWE12b97aLYduH1C+IOhn8Ef31gXvt + zZ45L0pVsLaAsUoEa3e1x1HsBj0xBK3aYvVu + K8gmwqB83pJZ4BPtsi6jsTH86fdHuCQlYTFT + EtGPrC0NyzDu45YeUkwDoh9DsS+JtaNz/n1d + p1KMYWLGc03LVlKybDZ3z7exw5o= ) +GC9S3VD2NHESSRL256KS0805PL0KAI2T.example.com. 3600 IN NSEC3 1 0 10 AD3302FF H01743IKEGI4JJOMSNCP0VG5S6IPGPIF A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + mbK8uuWhXaxyjYT05jkLfHVgkhG7olI1yfPw + pWB5WIFgZnaJiman9+WmM4LV24wmCP0ftdmz + pO6gSKQU57J6kks5hguFfkMbPL9uvLwUDSLe + mnPKaxAtp+cA4/Zvfo305CvcQFvjmj547S1W + RO6NUTlA3/GlfH8Ip8czkcMZfvU= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + zP72CxHDH5bnIlPZNTLSp+rl3SgUW//pWdwt + vcH8Jvfm28ACA7uWxT0n5QcDt1cSC+mIvj5G + Mdop5eBQsFS6nm4i8vsAlxgLKKpF+Bq+UZ7d + Ivpvr6Rycg2wlaBptnPqqhQ0rBDZR0PfK7CC + GJctdwwWCF9tN9QnINTwS6CTq7Y= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + QEKHEQJDM9QgRzbe0D9jjttXE4XgIO8Ykpv/ + UByZYirJRPYrVYTKSPSEUAV52qxBTu+A8P0o + 6ZULZaUy3fyh+d61E1xA2+lYfa9/k4mYD/4e + jaFEKni//39awT94AlBTzFxJ0j3KpHGJ5XWB + murC5SrnLxKZZkbIwulz9G+uJ5w= ) +J7A75JJN87L9PTVO6HBKH8IPI78IPUO4.example.com. 3600 IN NSEC3 1 0 10 AD3302FF KI1L4Q2S3IFEG634FE6DN6E3FGEGV956 A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + aEl0050jrFVhHPlyE/xn0CO4kk0Zq7P/9gts + iWn4+s8qaHQYrEqfdyKtQge8YCT5eBvpZOS/ + qKE3Fp2DFZAbp/OfAJRoGEwgWICB9KpjCf6W + FVQHT+Z78xv8PJHvN/uEvL+hq3gaHSYBd2rf + mZ6y/baxU3bT+zy+LDlDW2MpQ4M= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + djuhZzKM27N7b6ZsGNvcLYX8QpkNyWcFaBdb + fyxJa5Yhn77RfgQJaehHWHX+by5fw4DdpJcq + +rTSM5AyhiXVeA8pa/VVrKcH/Im1n798TNYt + ut8wJTE88P3gvZyxAWNdXhPxCwe+O73uoNVV + nqdIqikvqeuQUopYaY8zrWfNh0s= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + Z7snzL1A+r8TsTzY76d2JPCFSKk6KYhfkTXV + tC/qEYHzAZsn4lzk9cLKcEiUMc8UJNo9KO6M + vTVef5TE9jZWXy1OhbAtgjCzFfaHpHiMG7oI + LsfzMDCiwLNhFSlDE1oybZrng15/0TzeMQ+D + M6gHODGA8r++0faiFgw3oTfIi9s= ) +H01743IKEGI4JJOMSNCP0VG5S6IPGPIF.example.com. 3600 IN NSEC3 1 0 10 AD3302FF IV7VKFB1OLT6DRIGHT0U4O0L6PU6KMBC + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + oRhWX0gctcbRADsspHmDpVzEkEGoe/7Q3D9T + L81bwvQpDKfe0Xa/ksLfHdElnj44GzK6CiDg + 6b05S4yKuKUjd5bbx3wyA8Wl/hMphhdDn679 + zCmi/+CFHYMTTXZEk/BTa5GrMF1Ra+6axytU + AXzHYRSF8u21f/8mx1M8Scn3n9E= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + RMVgjtaxet7goMfOdZlovbwoobRwOjABu1Zd + HhAsygqytWXgrvb4GSBa4OgjU6wnZdP4uFpt + LeWINpZpaEdLsrw+Ee4hsm+ws886QDEvUZOH + lvIaRro7gJe/cXHydjFpXNDvVN4r8PwV9ZP5 + PL8eshnUrhaDKYWygR/A7Ahe3Hk= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + VVHm6YcQyfozsGT/Im3xLGvRTy8tBpvhXtRP + 9qsI8U1QRURciaMa7NH3D8umdxpWAMjTv7A7 + mxr8PPMjCTZlVMIdacWlSMTW7YfYmMjnbeX/ + tRVK2RGKOgXmDP8sY+TuQrVq3w7UQbTmpWzE + Id2tmEhSb4FCAUe1hAw+jmQs/bc= ) +LMQIHH5MDDR9PTGEHOHA5ND49685RR01.example.com. 3600 IN NSEC3 1 0 10 AD3302FF MEVBVIJUVOB0D9J7BQ6AONI153T8P6EO CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + TTRWTk11fEIZt67lQ2esQ73vETMljLS7T9EJ + R9IdbaZwtCfyALht+LIw3UKAzuvEahO9m9c7 + yJA+2WalAv+2KXu3L3iqcVKF4CPRR+7Z+Nxw + +D09T5h+mEzPec73tTpTSG20hK65jpRd8QZn + t0qsAgYGKGBpYG1pYiesuWbH01g= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + XY2wBbFHrXJ5B+Kd3o4AevusyoEUvK3ZUlG8 + L7WYDcuopoGIMv2BuaIbjYON2PjTc3DH9iRx + gMoiKxhpm+fH0dCvH4NVrxh+j1xqgGSjteNq + zUOyxXSmhmNOoDBiONzxWqKzveVF8mHRCEPr + EGx+LKO4gApI9HnE1xzqOxsNjNg= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + hmqTo+lS7OX5KUG8mQGbYz1bUE4xleqVYOq1 + mJRjHAwWcLX7u7/oHDDCPlqmBWTEyLB8RwBU + p+QPPnJPuN0AQhUF8SWivdDQ4H5uzoOd3xIv + +IraKdp/S3qR1DDo8rCb9KFuLIhTd0EDkk9i + iF/ov3pQAEpEDeXgLeXMw73COqU= ) +KI1L4Q2S3IFEG634FE6DN6E3FGEGV956.example.com. 3600 IN NSEC3 1 0 10 AD3302FF LMQIHH5MDDR9PTGEHOHA5ND49685RR01 DNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + X4P4YY1MsXI7TQsjxNvVSxbPuHBOnAanBu7n + 59EYn88vehSsSfk5KnFurXxLrVF9w2friu4v + QMA97HwAezAq/JmDWRctDSAZTNO9zuLkeKfb + Ux5jAmZWN8c25FQc3DqbbN4Flp7e56aTMzCA + PzXj9E5E/T6Fn5nqWVt9QPrFTpw= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + qGLIB3Cbnq987NgFVE3mTjWQVDrrWgDVDKCT + umklyY/pwr6zooXROYhu0hazTs1iLqKvYfgS + khfNyU+ulLjsbDQ1lnzMd4z8n97mgG2QzhwY + apx3e5LUcpx3oTvXPC9H+jA0anMG1/VwPnwU + qehhhR8WZRyCnzVO8Eje1/9bonE= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + N85zcB7Q4vImuCyq2MSxd2E+iwOzHCuuJ7f/ + LUid0XIfBtG4vRFN3yfj1JDmxPvuYuYhsrOF + CAgCKWFmqtKDuRU7QZOH0RBGn3XeDzNBmFgj + Ep62rh/ppPpnRZ2KmGn3wA8R1wZ0At/NtHfU + X5VyBUZkhMg8/+DjmC+rTNsRfQY= ) +MEVBVIJUVOB0D9J7BQ6AONI153T8P6EO.example.com. 3600 IN NSEC3 1 0 10 AD3302FF OIKQOJ12077E6HOP6HHST9DHAMGPED5T + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + ngYCZ4ptY2sAOs3nNWekbB90cbhxXuQ8Kpdj + 9oUlzVnYyqD/fZ82l+wXiOAbIH+lKxdN2Q2D + NjJYaimQpv4UoOL5zTfcxTfVoAmJ8S5v7Eln + Bk0KZyGuSvU+pfXkLZM+9P82XmdI3maa9MZh + IhnDZi2xXuXIYsqXk1n3/wucf4k= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + YBVuPeXL+OY96fwlXYPYrc+KRXubunNndwpM + UE9SkaL/RhurQ0xpXjPBpeThcJo0gKGZa2dl + f55acakc5VL4i5MQJx0uGP1XFiqJkx2TVund + sljAffBm7Mgkonumg0CcM4qmx7LT9SrH3J/w + tvhqbjvF9Czqb13usaqiurU/2Lw= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + Obo0lj3v+eAEe8Xk4aSow3GYTMnK5IAtKBMo + Cc/5nlij7T3pIPt+q6EbWcFpRHDBHEJp/nm4 + Ic2WjTbmlHf2o/3w7TC/TcV2qIxeZ8wj2cmZ + +TrfxRSON7ybKqrBfAP2ZBlLcg2Ik0fbX0qe + H2L2UCR40CE40YpnCvuOdoiGZ+4= ) +OIKQOJ12077E6HOP6HHST9DHAMGPED5T.example.com. 3600 IN NSEC3 1 0 10 AD3302FF OTMDSI120AJGM768VIKPLND04FDSUQSJ CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + GvZZoTVd15j1afy/UoqeYgXsqoO7+P0agD+h + Jc/osBG+9u0FtrFvcgmWPVWVfYSiGgtcai41 + D9sJf3bikuLMdn4HYkZGehVuEM2Z7PXFRVVk + NklUUxxXquDo4GyHOAP/44/l73u1sCF3urof + VrrkQ0CS+OmEko/vwl1URkl28p0= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + HWdQqAItWDdlnydvAw9wZFrcSnzgrPRBlMIC + SkRHWe03X0VQWksprbk6lAJH/DIcQ3g9TSKV + W/v+ye6AmhRMKGmebMTabvTxeBqQ7YIQETso + SBUR+a//TleRx2wAS0XI0RQOyAflCjZ4J/Us + E4Ma9Y64AYNo9RUX+wg//d8RBzo= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + pIRWEqeSijTmMo2pM993IPbzynp/hg5Dtwqt + 0RzOslJ0k7KP7EX5ImvlB8igRjnmNkWJ+7jT + oAdQXmwxN7NZgs+R/e+/312YYm6WYWzoM8Zu + tq/PFwPggDeWRlE5dv/i880SvB6V8X+GfPd5 + Kv6fxWPuVo7HuphHEfV40thmYyA= ) +OTMDSI120AJGM768VIKPLND04FDSUQSJ.example.com. 3600 IN NSEC3 1 0 10 AD3302FF P3RBJILTM87MQELBIM9TNBJ4ETMSH0PA A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + jZfAumkz7cHAi7LCOwA5WfvxSbgYbnwvKpoJ + 5pEwKN7fjIgT6EGrrQ5PgQNqPnzGGS61cc82 + zMj2ExiYJR84Brc/l43dCkq+IikN3sf/EmNU + cwmF+qYSsbwUWV7uEXd+d8deYAhxO559Rrra + +11OeNNlPsaBjaS3cRIJRM8S+Zc= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + HRl88fXi1YI/C6e9cQZLWBDm20OSqTqyjuLC + 1zdvUES0bo+KnTnvwfrQohJbldezjNyJTihl + KZYKTdxxoZpBY76YQIn2fjIz95o1r4VuBkQX + /QEXTlSStnSDe/N1xhqvigglQb6CmVOHSJXQ + bB17NNReYLDhph23URS68YxYJcs= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + aF3kJqcbs2+3CeHCxGhYy0PNHb5reqKrI1SS + FpJWjE7z3bPq/shRoDaJhTZzryS9Z79ZsNlA + m8CJeu3gEdZPIa0iaeBtR0Vk+1LQhRhfmaJk + y4fELM/Vpm3C+6A8mHCNL4K+kK1wxdIRzL1M + 7MvZXmlLERS3pU1XrznboQGN150= ) +P3RBJILTM87MQELBIM9TNBJ4ETMSH0PA.example.com. 3600 IN NSEC3 1 0 10 AD3302FF P98NSUFJ2IPUSG2OOPH9CPGHBNC9RRR7 CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + HFoa13mfo+lRQcY6Y/9iM9k05dj0UxOgmVlk + o2p8eLh8gVZBcEX3vZYEVx6e5RRqdfxANC01 + EivLSMDAY/y3Lj7ZSoUX6TztjKiQ+SRdkEa7 + 5RPgvRBbOdfZm/R7gsOnUOXKgFne1wCPzI6+ + mEQ7JgTzZUazy5ggC6F3DPkDf6I= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + 2Crtwc7SjuABVPbfojQhXFzhV+dbHIfoxmHP + puFDUHszttyhGBSgZ3zwJ/J9+TXqq4M/jP4B + 2m4bx9eoCXQtUdkxAmPCiJkbkvyYTsE77lWI + t7z18GH6BriPYUot/6EeYlToocyZnEoeDPDT + +f9nRM4qL8Jlw8KnXXG38gSvkg4= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + DZe6ordphHAB6ReqwVAp7V0c1XYd1l3UZdkN + uXNg3JM7iYmoh1MJu9a0Dj6FSu5OyWjoTu6Y + kNx2m0XXFRvfXiEH7xk7ke6Pf/eQ+xIjynJO + uhZL4W4D0ZnBpIaXh2jVilexNJms21GyiUZ4 + Q3rODRmym/KG6wsC5SlQSm26k9M= ) +P98NSUFJ2IPUSG2OOPH9CPGHBNC9RRR7.example.com. 3600 IN NSEC3 1 0 10 AD3302FF PFRQA6T0EUQ6MUU9LPM9M3GP8GQ1CQ1G A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + a7ZImTzIoztA8Smg0vvQAZ3vC14Y/nb/60/4 + eHKKjBK1VH/nDzuVvnpsCEBLJWm1nLuvHqDg + 6C63qxZbnclOwssnfow8aIV5rbiKBk1HHoge + tzxJQYe7a2hotY7OTA5s+ncJdyUuS8w7VUIP + JIrF+tE015qUTaunILXfLydQgO8= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + 2X+O3SnOGNuLp5HXNpiuUHCspLQUCagtU5uQ + 1qxuLLrsx053wNIJ9vC/BNXssgdZggxYpXqp + 1nzpzk5dK4nIwmOYGhJO86/FNZu4zgt47yQb + HEfXI30hanTyuG16kNVGycpbPMyzqKEAJN1+ + 0Jv30Wd/CFjnBTto6Tbq7fEkBbM= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + bQ+F/eJYMogZ3b1SbvotL2/Aoh+UI5/McQIF + G9BB+1bQs6tqLszPx7P8PjvxJDxt8Q493M4l + INvgZDQQIaFNqMMEh0Eus17OAx1EqLhDK69C + klX1sXbZGhQqNbBWvTeaF74T0tFRVLMgtIFx + /Np2gCA42NGQskIsBGN4r3N0tqg= ) +PFRQA6T0EUQ6MUU9LPM9M3GP8GQ1CQ1G.example.com. 3600 IN NSEC3 1 0 10 AD3302FF PSMSPPC19D8OAICCQ64C7MQ387MTVGC1 NS + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + krM4mSHU0B3KtQQVoFCBpdAecqSj/7Oo4cyd + YQNuF1CvChDTHFGs5BjpMzKxrBlrNH7wXk6C + Z3kREpgK+uNRU/G3XPhYqG42lO/WHHIRiWBT + iEcUXhpLYLto8ro0UWopUPRRItotcjXFhSNJ + BzWcWphP5+fa23odDEPCO8ZRyR0= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + KPEs6aIATlvmzk+gl45yXM0VDYMI3fE2uHAR + GSLPehUZDXT4IYdERA1eQuiAfMkadomjWoQ2 + D4VvfBf3Ho7ilGmsms590NvE+W1UZTF51CjD + fyQW2+34UdgsNmNm1dIKv1sq6llQSHSL8kzF + Aum9ohDU3CS4jsbj8/4LTZ5+R0I= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + K41ckswo80M0l8+Cz3SVDqrFBbXfToKS8Gzx + pr1HycM3GblmriCBdIgxOAX/AuZZrDitxkzK + D1hNeKqAmW+76zPw0vxocX/tdnjYgHodi+FA + dVzOaMlbAT2gAOUp8BeQOgaE+k4ysTqYt2M3 + RxOB0zDtwXum5/e4ZYYWNmjBBcU= ) +PSMSPPC19D8OAICCQ64C7MQ387MTVGC1.example.com. 3600 IN NSEC3 1 0 10 AD3302FF RQK67K3ON1JGJ60JNO4883D1JVIOIG2D + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + VsNIjTrZUt/0Kyw+WYP0P1F2Xq0BgyZxiUBT + jwFp5etUAx/fx6thM2L1mLadUpb9m4R+JxXB + b3/fn9H3E+oqvlzr2p/LGcqASohdiqmCADdb + dzcqqYaKbqjUDsNsJuhGz2iWSccjOTepg4kn + gFdp5em/jmqYr5X5xZuv/ZsPWRE= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + Ouj1pNttVU3EPD7qDicNu5W3CyECZjojxusF + cibOFBQwLkK4a7RnsTbB3EFuW06pMpo0JJ13 + 2FIvwOusess7AgKC2ATyAgTY3lO+Ja7GgK8y + Q20oxMw/wiADKJqVNoROUPVacdSkU+CkBC8o + CvNXyPrro0g5LOzSgleeHCNSV4g= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + DY0n5eh2Y4XcNTCWQmDez4EtkbIcRLLXSDai + iPEnk+JITGaaghxMhnvdSAyl7OtQbWielh5i + L/toRRJfWA0RcmWvzzNpNZm7EP/+I86KTdCw + fUPt9hU0XTzyP32FYcw+NosauxrMD7prhE0H + lyXzYwT2m4cnsSqvrAIfZYrlFB4= ) +RQK67K3ON1JGJ60JNO4883D1JVIOIG2D.example.com. 3600 IN NSEC3 1 0 10 AD3302FF RSSD7AU1NQEBI2UF3B58G8JKBD0CDURF A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + bWfMW3+ct/fNIr14DZxhQSdC2xqTFfSTFzch + k2+zrsoXFL4JyD8VC5dUmuvE0JHMLRBQs2SD + T+H0L63SV4PZzyijo4lLSmz0PzdAEaCagktl + pwD5as8jXb3+uUx1qlrpVht2QuwHjRm9AMTi + YZmX6wYEyUTTC69L5BC4VvEkVvg= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + zyN8D+2X2PEvIo16h6sok8m3M3MCVqiT6P0O + sqSKVKoQ4+xzxpIYPOUPfRH3RWZ4D03II1n7 + 2gtMCc1kk8Y81D8I5L0r67WmAAj6QNtL7jpd + jghl4uyHcp3yKy8GDaKreugWgqZ6ew05vXVf + AbeSJSXFX4+j8TfF3z4M5xnWpwQ= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + Mdfdwoh4OlXhe61DmYTzQouDjcvfMLmAQihD + bLy2ZDMsPm6cv3GykhvrVPMVn0P19kcD9hqd + LIKPQlVcrpP+H+WCgDI4Dz7UjHtmxUM2s6KQ + +GzgkD4ttn07cjY0xSrT8lhpPbDiwK4V+RT4 + pme25SYDQFbcGog6IgQycgrWGeA= ) +RSSD7AU1NQEBI2UF3B58G8JKBD0CDURF.example.com. 3600 IN NSEC3 1 0 10 AD3302FF S4A8QO8DEA53D05JQA0RE3H3R6UC7V1G NS + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + JRrCvpMfhrk2JClELV805D/pt2a2YhBRROOt + 6dUZ18ZVQtXPOzvI5TEOuhFEFaBTPC2PrDfX + YBcM1pf7mwD5gTnFhrD7vXwsR9FUDw3sUx63 + H5Lkp/zZSqt16eBUmwYcuSHceJ3qRrvmgfi2 + GYP2c6kft5O7DHXFoXKcUBVsuMQ= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + hwNx2shB/t2gB/uc18S8Aaw3SXjkJq7txozP + az1JyD14ha9CpzhWMEv0qzENQAFezTapBA2t + T1FVUaSb3BaUC64w60N3bjmOQk5hycQ59YdU + Nuo46i9o3tWgr/1Vk1ZTMBw9nmXMY09AzLYa + qUxrgVo7IDp7HoE8UFl6IR+QqrI= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + JdX++j+SKyIpuad/KA89T1aVWR5927xQLK8M + 9WRe/JJEaoJoi7UKboTlAQ21AuGvGwu6wB8l + T66ZA49z5LVU4aq/TLI6u7OzIEdldmypbtjB + +xTvlLApJ1Z+CouMLzswIjdrOzBU8Zl2i21P + Gm2Je720L0Sgg3WCqL9rQAEErvY= ) +S4A8QO8DEA53D05JQA0RE3H3R6UC7V1G.example.com. 3600 IN NSEC3 1 0 10 AD3302FF SH86DKIJAGTUEUO2F2PPQ0RJEFJCKGKS NS + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + Tu+XjkIiVrDubGLnKLgIwiP0V1dQvKXVQySM + A/qOj0L4Eh38P90bjoVsD0Y5Xt9TEhbyShgX + bTJ1K4qhLX5iMejg8XHkgxPM1SckGy8xgDNq + /udOmIzHSjh6Ac9xHZv6ADvahqAQLNiuso2z + 8P99fqfqQVIrdBD9c2BEKs0Hdao= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + JWLrARNVKUnnwK2DX9Y0BBaDWMuVlNs5EN6c + EAnPmwVF4lXcD5WNkWSEmj8c5c3R9VQJAx6H + PhpWuw2olxwPV91CPeHOO7Mw8y5wCXcA4Zoo + sXbw/WfpjLYAPdZ4JSF26t4NEjQ7Zn7UNZXT + TCBJjHxdFTEGmc6852z1n47lDwg= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + cLPQugaP1G96bBA/u90h07bXtzgK+rnNmdOM + /g517Rb+0GwPrJFPNXKN5okoL3iJabyNk5DI + BxlkXL3rdXy6KnTBJA4yIFaoR3YAl0QtpuJi + vcpCizL6aEiQKwq8yTgIIY8CFt1DL74Oy4XS + s0lUYlhApluMNBGzE1LP6OIKuMc= ) +SH86DKIJAGTUEUO2F2PPQ0RJEFJCKGKS.example.com. 3600 IN NSEC3 1 0 10 AD3302FF UB8IU759M5EE63CQBISIRM9C0V2RU1RT CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + GacQYyh2UTMay2+CD8d9tADE4LWcflUwUc07 + 6tWksDvwyj/Rp9gR6p074kvghPhRS2h5F3Ik + HCxzNY61If8aCaOlB6lrv3YMfiuJoITFisqo + vQCNEtIriEENdFOfGEMZonw8WMKP9fnw9Zbq + LiE9/zcKCcxN89FVxSz2PlX0vEo= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + p+xzV4l5PxxSyvwiu5IykFbYxKnXgSRtHgYz + 2+bCOMBGyv7Snt/VTkZNulTqBNxEXWDZRnfP + oo+2ingu/gyInx0cWLcVxVvHGdPntjUb0gbS + Y+dlOh8NvjhkdEpahZHMMQDPPdkFS2EcOUiV + T8WlOKz61Qj8C+a4dwpW8hdJNn0= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + GHtvMmQUXC33TVgtFdqaiK5jVJCL1WX0LSW+ + WBmiAejPji/26k2uD9Bc2jysowrHD0eUOPYa + yhwcsn+SUBWN1QoTcJvyyx/vtXiM5xgqsoyo + bgZxtO33SkqoLUEG61NvKJKz9vXuJtpjZAXF + bFX2l4czAEXwmdLW+IlhtMwAbvg= ) +URIDB302IVQCE7DQSKELLE9LEFOHV0LT.example.com. 3600 IN NSEC3 1 0 10 AD3302FF V34U1QKHVIL4EOR63PIVLI0NBDMAQLL0 + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + bJWx87h9mPriMU0pNbZoM4ejR0P57hiZ4GTU + CGvFlO4TZZ/4i/iPYDN8J46rA7diCaEaOhIg + m9SeRvUrIiUw3WdI+7sWNI6atXlaNM+LY9un + OGueiKtabYt029SlZegkWdCqNyC70vACtBbe + 06d5J1HO15wTrtCFNP3N4MGAuME= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + qu6bqA2HCxnxvtQ5ECzMh3gm42tZsWGzC+66 + s8t97N+HXM3vv6qLQ8xjDwF633vtMY7Uuieg + 4XONpJoU3UxyFJ//900TuQ8WPHzzwSm3ORYM + 8BiKOn/eg9dtIxpYTelleOSzmen3979NAelQ + yjmyx+nNzvvrj8ZEBmB7OfB8oAw= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + WyR0ilIZAADX3HLXYuyvlhK9yRAbPFv3vtOs + DIlg8Dj2F5hgXUv9V6AbuK5nEz19S4og3E72 + JN/Z6QINx9MhZkCnzYFOHlS6GS+zqayPk6kp + 3BGzDZ/jYJ0KsUGrTIE9ritV4lfs9Ns5jSS0 + 0Hg89y8AK8KoMpvnTuzTXt/iIQ0= ) +UB8IU759M5EE63CQBISIRM9C0V2RU1RT.example.com. 3600 IN NSEC3 1 0 10 AD3302FF URIDB302IVQCE7DQSKELLE9LEFOHV0LT A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + BKqTnlAxyPcDJbWH7r2o2GS0wipIPD2fj40A + MWIF8hOtF/NwN5WAbdVjoyVGI31G6CTDGdD6 + TPllaiCCFi7yEKm3/vBZfoX5uZhy96ln4G/0 + SbRdD6Ooy351L6HPlfwJLmb5a7CBBkBmTYQs + ig1o3XoicFPRQG3clgX9v1UQrIc= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + qWWyZ2Rh83GyNUcw6ftZSDCGrYvsB7E4dHat + 3+reQZrNjmAY5GaIvUq+v1/Bp0EpRlbx64C+ + H1MrNDv3ZQ7L4O/Mc9YnOpWpEDs1g88ONmVK + lsZ2vBeT5PdEVsM8VwxRaTLHzZ+2ddn9/zQW + fjb7woheUAr4U5ga4h4XAcHh6qk= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + E6d/cFSl+89rhmjn5OXRaN4OcHmdtAgqaDQQ + gOk9EwrQq54XKgzYa6zT0VBzznQZlbsOW87X + jp3C/RBdWR7VOV77btuko3jWYYSVvA7UDseG + pr7TNEZSck0bJuih5Z/axsGioLNiUKW95XwB + 63n4EGBC8iIoekIDVi4b78OCK1E= ) +V34U1QKHVIL4EOR63PIVLI0NBDMAQLL0.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 0R5AV1LGTS4HLPNB8UK2DTLCSO65OBJ7 CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311113926 ( + 20120210113926 13760 example.com. + PUxRemQkIzsdDafT73oeBF6U8M8iFHdL2ACJ + h/Kw8TtZfZpulj2XxxeU83BqAICpZdkeqbZi + YGJuqIN3AattGV73O7nv5rjIhlhgDl0UgOFu + 5cIC1My6qYuqMEosQHAkokq40ZhIcWEFOy7P + S/Fd2r+ERPkLNDUGFyIbQzYEpyA= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114013 ( + 20120210114013 59507 example.com. + lNMX0meB0th1kePzZAWX3NYUAEGNJbCJmeUA + DsQmct5CmPObBaUjUQF1Y+XFLlme8BQJVUnj + GfthFJJhPmrW4AvDNMMRbXo0wo4hIWn6tlJF + xkTDcFB1BRz0w3Dz8cuXTxH2gpUbtbOq5FcG + 5ZmYDo9akGuBdw9okfRuZ7S8xm4= ) + 3600 RRSIG NSEC3 7 3 3600 20120311114036 ( + 20120210114036 58574 example.com. + YI/o1LESLnn3xIcJIBJ5ibKs2ajwjml70lMS + 53nM+EMe6lKZdCmdB9BRR26PzhKNngWLakI1 + 1XarAJD4gM6hJf6DMqSWbrOpfVpuePFTiVH7 + zkJfa12Qcjx4CFviV0cCdnQRVAsv2X7ajLcZ + 6QszvmkzIwR+HdsY9WeFBZ9yZ7I= ) diff --git a/samples/example.com.zone.signed.nsec3 b/samples/example.com.zone.signed.nsec3 new file mode 100644 index 0000000..88a28fc --- /dev/null +++ b/samples/example.com.zone.signed.nsec3 @@ -0,0 +1,690 @@ +; File written on Fri Feb 10 13:41:08 2012 +; dnssec_signzone version 9.7.3 +example.com. 3600 IN SOA ns.example.com. username.example.com. ( + 2007120713 ; serial + 10 ; refresh (10 seconds) + 30 ; retry (30 seconds) + 2419200 ; expire (4 weeks) + 3600 ; minimum (1 hour) + ) + 3600 RRSIG SOA 7 2 3600 20120311114108 ( + 20120210114108 60914 example.com. + Ez84tPNF+mHlVMRW2qXS4yLcaKHtlqAm7bmn + DR3jI17pwqUyJ+aFlZcuWLbGf8ipWfEFN/zh + +sn3lAafUlbuPseAgqOnaWt1OEMxPK/Fj4d+ + DodZfmCXru7Fm/baTXFB4GH94PeC5H5mqCPI + oD3m0/c7OLDIF2t66xs6XHb0YB4= ) + 3600 NS c.a.example.com. + 3600 NS ns.example.com. + 3600 NS ns.somewhere.com. + 3600 NS ns2.example.com. + 3600 RRSIG NS 7 2 3600 20120311114108 ( + 20120210114108 60914 example.com. + BauFYgGnXIOYPg8vx45JwlTJg/ZGrefAC/cH + uOpCgezjutVKsYAwKjTdUu2/YnliLPl7qTHV + wMEandEUUBhtMmaMcEqssw1fjp6hDTnPzjKh + WTaZMObi8oJzwTg9rrtlaqh9ruWlLvwmX90y + /WlIDQBob+YcrkhtmtRSadojRAA= ) + 3600 A 10.0.0.1 + 3600 RRSIG A 7 2 3600 20120311114108 ( + 20120210114108 60914 example.com. + uOArtqyKZB7f5iYvzRkyp4B1doREoJ4Mnh+P + dSmpRn4kklovuAB74kNJCy/eb9Jajtg1Gvf1 + ryNFdyRjsL5KYG0D3O9CljV1/9RAGpocp5HI + BWOgjOXPT+qpKkaV8+XP5c3uXsgsc8x0Xbd0 + EUqH4MF8mCh32m/TWqR0xhW2bvw= ) + 3600 MX 10 mail.example.com. + 3600 MX 20 mail2.example.com. + 3600 MX 50 mail3.example.com. + 3600 RRSIG MX 7 2 3600 20120311114108 ( + 20120210114108 60914 example.com. + B8uDHsHFw8ArmcuLU8oh7LppxtvDSGQE7hgA + VTwiOuGIv46xKoxTcZUpZhGMrqvFiXmgYS2j + Qq4DWCYjpDtXnfruZV0pXmcJY4AB1Blp5g5i + XK//ZIcX/gyHs2JA4KhQWtg3KfQmJcUJkO6q + YduW9eMycJ61lZUVCb1jwQE98+w= ) + 3600 DNSKEY 256 3 7 ( + AwEAAcKiv8JVo/nwOl7snGkyU8TXRXfRYuKx + QpA42gttcSGG00PhRTCWrhlC1amY0fmgabvO + YVdkM2aK+NRTz0KLitWbvkfM7BAn4QUUR262 + lxCeDXFX19pOPdV9G5hD/4X7EkilsusiAGwx + ni0lJkLVhmrEtvLSm4r0smcr/Te7o8nT + ) ; key id = 60914 + 3600 DNSKEY 257 3 7 ( + AwEAAdjJ0gueZiGl8beGI/a/D2B3svXKQbg9 + uh2J/Amfc/IgrjjzCWiBoajADo2D1A4MyTWS + BtOGk31LCyOumJFTNr4/vMHSMGS7dXX7wCMo + sJjBgMBDnv33uiE0D6RFgw3X3Xg9ftoucRrs + lG9MMZpKcFc6v3ajLckgGj0vHFmf/g3mHwXr + 7htSg1cRVzhVnC098bHRqLQgcckzOxDQZgUs + UVQEmNEPGXyURPjqVoMaWZPSWB34XJrd8q1S + qshANW/Cz550xhXEp3de4y2bBrRIgJdrcQnA + GqVb/hxn51i6bj0R5qRtcIY+OWydV8DCEOmA + I0E+ioifx6nEgw1iHEdFU70= + ) ; key id = 41955 + 3600 RRSIG DNSKEY 7 2 3600 20120311114108 ( + 20120210114108 41955 example.com. + rcZlhmkMpb+ZUt6xdOZq7RI/7p3zqLEJzMwu + 5Nce2Yo7fQHjQGWI18+HA2US8TKZKwR2L/MU + MJ8cMx7ElaoEmFnebjq1cnMcLt4EHkKNMSM1 + LcJAGowmC9q270R7vwAzpyCCToT2YDN+WO69 + 0G2lRSGjaGJR2RY8o2+zQYNU1jm3R8NiXlen + VKywg9jlrkdQ1Z6MnYQKuywTZjDb/mhjbMqF + ANKf5zgDdvZI9y3tb4EKkGHL8sE0xKDTf+tT + GdSiLXQi5FTD6eaCclDB7qd0WGPf3bkTAq8H + FofDcE+CRi+9DGReKiAFR3w5Ujq3LXkQ5swi + xyHTyYUlWvfGg+hZsg== ) + 3600 RRSIG DNSKEY 7 2 3600 20120311114108 ( + 20120210114108 60914 example.com. + PtLvtaPNUKfcRbrQKM53Qo60zimxVlNP8uPV + 257uSmxbDnmkOa38O6xXISdgq24SW6mRPqW+ + YZvXu0C7w4aZkbCgfYBmFeplAXE6iBVXd4Q+ + s6aOiqaukTn0o918nrCOCbEC/bXlPRcpRZJg + 65jQuQdRWdqK83yRzy1J/bSN/fA= ) + 0 NSEC3PARAM 1 0 10 AD3302FF + 0 RRSIG NSEC3PARAM 7 2 0 20120311114108 ( + 20120210114108 60914 example.com. + WuKOUKwmvXyM/sIVaz1AlzgazTkoCNKgS2jE + hxhzqKNHbNMMzvd5rH4lwg1z1NMDBcwvfhpd + 8qpt+Q2NklIEUC8Db0DoKdD9HT+zt6k/erhQ + JJXuSfoypnPhrwk4rs7n1U4X/xXbmOctTp2r + SFY7FAbXNtjQwE7WB0wMkpfoJTg= ) +_foobar._tcp.example.com. 3600 IN SRV 0 1 9 old-slow-box.example.com. + 3600 IN SRV 0 3 9 new-fast-box.example.com. + 3600 IN SRV 1 0 9 server.example.com. + 3600 IN SRV 1 0 9 sysadmins-box.example.com. + 3600 RRSIG SRV 7 4 3600 20120311114108 ( + 20120210114108 60914 example.com. + Kava/zmrJ9xXbNDSuq8qPwTrp8H8VkPWuKLz + pmY8Test9DbhbX17OVwOrRvb5npkiD5pjTMV + gPzUc7g3UpRzORTlf4LW2j2P5UWB3IfCBKJX + zJXhW+ScR+jRX8T7ZQTE1Xg8Qc2lvPsycZiJ + i+BL+1uIsyrXK2/T0oAeLhF4O30= ) +*._tcp.example.com. 3600 IN SRV 0 0 0 . + 3600 RRSIG SRV 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + jCxrJOjdRJNyCqPsuPlFYo1cYXn3xACjWcUQ + a+SY2h91wgtwOwy3hzPvx5G9UbynqtvbAplW + d1q/pJwyfeXf4k3BemKJiPVYl/S6CiWk5Otf + FSdiTsKsYgKiyG8cUNcXOLteRbYt0s9Y51nU + zhEfhBdRFXG8vy4sle1XA6wkqSE= ) +a.example.com. 3600 IN A 10.0.0.4 + 3600 RRSIG A 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + YzA/6SJLjNJmYZ1BYjS3hgiebRQLlcjvn8IV + jU4c2FCGW+H43IIejzaIwlvuWUaXv6hpYYBL + cBudB3Zw7t4IfgT4XMkbEVcCfv+Gu3TLXn8a + qAblKbMxRHbWaqPi0KYHMptYqm3xmChqRqHs + h11uOi2YbA2cD9SqXhMwupIH4g8= ) +c.example.com. 3600 IN CNAME c.a.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + qaA91r8RUIfGg7QXqviyFKQEb0P3lU552mX2 + 0tzo2PbdEWbnQBLNtACmhiG+nk57RYkFAPaY + TaexFiDwPXYViG0OGUiZUXJtVxXCg+vgW+34 + ZRH2eEhTOPbrBKc/bHJ1Mo/1O2oOYLPF23PT + 03IF9ywBmwXnhJBwqzHJPitJ0LA= ) +*.a.example.com. 3600 IN A 10.0.0.5 + 3600 RRSIG A 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + JTXlbeNQRnhkGUrBRb9kY9NNzPRIV8oymIha + ZGWwQFB4WjjSHSnrNB9bu7pXrYL5V4fwy4og + IJexjAqteTlDfiBsVCTs4m6V/5XMWBGA1tet + 7FT0bwPYnYrV5ij79KYogYVXbIje3g26yAT2 + TtHxp0VqpkUOHLIsPP/dJwOIi8Y= ) +*._udp.example.com. 3600 IN SRV 0 0 0 . + 3600 RRSIG SRV 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + GXRBT3HhPySbPhlnRIi3y+de7Ptesf4JDhNA + wTUoOkanLhnsE27u51OoineUchRI8AEKtejs + J1J8Q/iaFTn+nIEk1yVBZTz12NENRgJwX3Vd + XWQHWnANx7/3u3bXuHICv3q4NPJXO20j3a43 + 26hlFkZt2YviMJq9l4FIeVbXqfQ= ) +f.example.com. 3600 IN CNAME e.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + aLrdCDbjTkJ21rRaCn0O95ch85kIVQtcpLWq + pNwZdEkFG6nanUsgqFwAewl4n/PYxsHhqFlP + bNO/rL5v3Aq7CyyLZ3NM9ZSt3wermKBpseyp + jaBIrcekZeq7qUJXEJi/ZlffnBGGFjJtAXpL + ZyP6I00MYcV1FP9VYkPYi7wzFig= ) +e.example.com. 3600 IN DNAME bogus25.com. + 3600 RRSIG DNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + Bh6S2as2/EjwihXV5FM8hC9urhLMcXCyhXwX + l+/cRM/8Rd0hKZEcoMVN5U8f163hZQgueRA8 + J2n8kPSQ3tdEURCkaYdvgU332pJgBpaibWYu + KrkvyPhK/4YkMYkAj245ioHOln8G0wkf6oTW + 8dpM5JsAvSAckJ2tK0fBIreM07M= ) +f.g.example.com. 3600 IN A 10.0.0.20 + 3600 RRSIG A 7 4 3600 20120311114108 ( + 20120210114108 60914 example.com. + TwU34N2AwNYPmwOy4J9LlaOgGmX5Sozmk/Re + pjrkEmRTtCbxmYNJli6LobKFyAxwrF1tan5o + z8x/kX4zOR3iBr6dR2fqJkC3VmW9fYLPYshY + SHKsbD9U6903QpxYFGhmI+a5A6/0HY+pZyO6 + 4JFmQATfvRin31c2SHkPckqgatU= ) +d.example.com. 3600 IN CNAME non-existing.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + dLQ+FGitt6BvKZY1/TCEpH7soI+V31wPb2lJ + AX/MevBQsfVIk9BZW5eeqEcf6YqvHi4pBo++ + 1pD0NDnuDJ3UAwLH674CQnJEUKZNFCyM0z/A + rZNl3HIszRNf6tJG0flMtQczmWlMOejmuvqL + vcYPTl/0ON6vuDeB0HA8G5NQgmI= ) +h.i.j.k.example.com. 3600 IN A 10.0.0.21 + 3600 RRSIG A 7 6 3600 20120311114108 ( + 20120210114108 60914 example.com. + qvwrNdbdE3tyfN4OUZqNmtdMLLavwbwGc+06 + un4SM2DL3G2CWfxun3nHnJOwdgatWnlmMMEL + kllvuQhtNURgkP3WOwBhXJDzWCvaLT4E/Gvo + Ni23Znh8jO5Ef8RndKQY/cnIJOdh5JcTOl54 + z64rLoW71qfxhVAAZy0f08LHKis= ) +*.j.k.example.com. 3600 IN A 10.0.0.22 + 3600 RRSIG A 7 4 3600 20120311114108 ( + 20120210114108 60914 example.com. + sw2Hlu7zcahxgTCNiMBGdK/svV0FH1sy8a/h + ixywRiCYgtrRyDWjgxFMNP1wpw2I6d9QiiDr + uha/I10eA8Ku4J78YY1HpWz3Lus2UqLeXKrf + q7I5xa8Pu+SJYIomZ086yp63ZH5z/dVOcMhh + rKrUiISXfFL9mvACTLTzOWwo5Pk= ) +g.example.com. 3600 IN CNAME www.bogus25.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + Yc1t4U4yV0PZkfxAth2PtdqDOZKXJuYmOWuN + ni6g0REAaCNmuvCbHj+4YkOWKAq9NOEL5oqI + ALNA+XUeauaTYdibdVWoFbuL3q/oKqMFHvnU + eaTcM1xi+tCzo2lHvqxkc4Rcn7DjpZjFfR1H + H4YH4msXP9VPdoMMljFUvLsKwQI= ) +mail.example.com. 3600 IN A 10.0.0.3 + 3600 RRSIG A 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + MiSjUJWxYuMkwoQ2XGzdciruLO2jlKWCzyAK + BduPRMuIpx+l6cbhFdas59jKfcQGxQ7q/7h/ + JcZS99LijXSRABW/AQDQzHIJkHh3lnhRdxg6 + 7tkJExh1aLHsClLElteICS4cD0Ep7ESfPgkx + 6a9V/RB/DBGXJufxfKrTgaMJTuw= ) +new-fast-box.example.com. 3600 IN A 172.30.79.13 + 3600 RRSIG A 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + IbRvf4mFyUSm7gzpiDcmaAjasrJKWgJ2aohc + h9IowzJLiEn2+m3kII1qwC1NgMYuBzqyx5M8 + nf+DYX/Vv4+uc6wVHRQjB+m8YS/7XB5hO8Mk + 4Wi9D5zk2Pzm/nJqmaVv0z4b6GS8w46Q/V7W + DG13RKprePL7oN+5fX0wWi/hGZA= ) +ns.example.com. 3600 IN A 10.0.0.2 + 3600 RRSIG A 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + HB4CX3PPLe8XMSUkABN5huUyYJ61q+hk8R6x + 1OMBMK1g2c6L9OcLY36Jxi1fyk1UDbk7wbIV + PGObOU98gF3Rz6hYrRLO1R1yDSA0YpkDL9Q2 + fu8qGwoFdKjqE6JJiaYcH86bbEX/xaTPIwr2 + kWnMZSF1F/inw3NWxekU532xycg= ) +o.example.com. 3600 IN CNAME a.e.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + ti7Cw/aVjpeDKuRmEJrQwLOIYZCpt7YWFVn8 + XvChoxuv8OjEdhjtjZm6s5YWT7m6+NWpadZ4 + 2YxjWkbi1JfmPVB8NdR+cLse2cFdr6StTeFn + 3TZei5zLsjje7XHJ78Ezsm91nJsT7YANBCwV + bp6exprqVvWSZIjmwzndP/6ldKQ= ) +*.l.example.com. 3600 IN CNAME c.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + N8JgT0V4xI4q2HsOZ996VWSc+RvT9dIlH7zf + dpvVB9GVYcMo+CC/vz53rLM/WCPkjcYVZxqH + xyRlAktjY7mMGFy/3ATlgBW/5fUjvCAPe3n+ + WQf/lTO2p75SPgnz4yHzXRWFBgatTk4zxp5/ + 34GoV+sE0rrVgOPKm5IkBp8lN08= ) +old-slow-box.example.com. 3600 IN A 172.30.79.11 + 3600 RRSIG A 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + mRqdT1LUhXB1+jzeRmtlysRlZvQ/wVa3RYez + 0ED3YAUpbhWPulW3SLiYWdQNSCs2kL1gbix0 + 6z1gIrNUdwA9ndR9vIO4Ji1jeZIqfPtGLL2/ + FI7PhcbjGGUuR/X60G0RxKvboNIDV42zZ34z + pMJU0U5kx+ibGUKdoTI/ZUIIaMU= ) +*.n.example.com. 3600 IN DNAME bogus25.com. + 3600 RRSIG DNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + LYfL+QODtn6ImPCadS9DYp3hDWFyooI0Sdug + kG4ENfOrFco31LlGs98CRsWM2cuIdAbh3a0M + FOtuRFl0dgvw8SOR7QV5x4S/pI4Xj9OIL4T8 + xsw23Y6gVJ7oPOha7RBHRZFwniJgRyGsZc6L + 6ZTQzkOY4iGc2QEmV7kVwo0Fwdo= ) +r.example.com. 3600 IN CNAME a.l.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + NLSNK8cAEnGcIBX+oJm9VVVYxzUml/rQjNxH + pu9L+WROH0z4mgXiC9qaN6jiNHSY68aPxfph + xdnhfuaPQziKYezh5roXS036IBYdU/GzXyQE + KDmxBmM8Yevtp9xJs2/BrS5ny+bmoAf/2suv + kDfKD80tF16036x8JJFMPeyIKtI= ) +ns2.example.com. 3600 IN A 10.0.0.6 + 3600 RRSIG A 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + fijL4QoqM0u9E7eOA+Tjf3RIFGxCNGQp9Sp5 + YTiEcv4vHSNI+4Y6tp93C9C9yeUp8YQ7VW9d + zagyF/jHKfODDpn6Sm2tcWzCxX2KZTuXGSNz + i7o16HJj4jRyg+uqdXIrp7ArPjudCc3mzd1K + LxTv7Zb3KVwWYyt4r1YbARFvvOs= ) +*.s.example.com. 3600 IN CNAME s.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + vfGi8BkLoPlB2ZAORnwG3ZlmhtOtrs/0z3wb + pY29MTNGNVBHJROXg1L7ANHTBglkbzrKExHz + +M9c9YmFgtOKqDne00R79KWpC9XB/zsdQPhV + TRGR2Fc00KY74ZrQZ0by2/xW34MqDPpgbmur + b+EeKV7UnnwZ9y84HIC3U12wQGk= ) +s.example.com. 3600 IN A 10.1.1.1 + 3600 RRSIG A 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + kpS37lgrK97OEG606nym1tYyovXp97xkG0y6 + rteGws46zMYYrsW9L819ibzRO1DUAjOd4zkO + BI7hu9CI+Mgrk12wb4vKS/ERIDZkiZ5AadJE + nodcYYZBNwRMwE+frFgPxORS8rUtmtrkdqXR + Vjhs3llHqtJbJr1ve/nZvfgX/I8= ) +sub2.example.com. 3600 IN NS ns.sub2.example.com. +*.sub2.example.com. 3600 IN A 10.2.0.1 +sub3.example.com. 3600 IN NS ns.sub2.example.com. +sub4.example.com. 3600 IN NS ns.example.com. +p.example.com. 3600 IN CNAME a.sub.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + Cyvn5zf20vG8RHpIZ+oIvPV8nZnG9kROIIpC + pCXPx8RG0CY0+IhOpUdgGwvcfMkPSE4aMYw1 + 7Dgbykszd0MrCt0Lel9iCF6sroeZNLCuriUl + 8hiYli602XJCamDB/9INSzvGtfRtiN4QGuRV + mbeuXLHP8ecv0Ib9GOt32dMTuwk= ) +ns.sub.example.com. 3600 IN A 10.1.0.1 + 3600 RRSIG A 7 4 3600 20120311114108 ( + 20120210114108 60914 example.com. + YuQAVe8hfw48Ily9RdN8maHLcIUDWKuDgcdd + W/5T/yBsf1ezILAh2zugDtc86A1HRxjH6jro + xqBlSkJ4bWSwA4OtaU6krsMODlV19gCXUNvW + SV/2TkCp0F0qSj88A6ZelUhbnMHTKw22z0K9 + UdkdLB1ohRSw2I9xtSCek0DwLDA= ) +sysadmins-box.example.com. 3600 IN A 172.30.79.12 + 3600 RRSIG A 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + n+Pe+pQjCO8NJZq06uemhm/QuMRtbsuRYnrE + 85aJ65IGKfFdwn1bFYcW58Gc2HS/+nWE1gIy + DtvVxz/FZ5PK6acW8aQeji/sPBMvb7XfgXRl + 458lhlw1hkuxXRguqkKIDk1qL7GCBPHegNUV + 8xzGJLaxjQ0hMGVLPrPIH1udGwo= ) +www.example.com. 3600 IN CNAME ns.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + NnCpNpsZIV0U2qOsuuj7819OEubIY9XsoH6k + IY8fFCds7SRckoeGS+bM+LGRbQWJj4RRx4Xs + geWZB5xF/UXu5OCRSQSx3B2V+u7drfeqya/+ + kpQaECsIxGljej92QHn5ABgJgY6eaWDI+cDO + KhhUkCoSrsvU7aYQLNmSacf+fPM= ) +0R5AV1LGTS4HLPNB8UK2DTLCSO65OBJ7.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 1DN7NM4DOV8TAMT2O42J0T9M8B91CEB9 + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + hdoNfv4A1PpOTW8EuR5fcwzvYoLT1Q7znxkJ + +0vEJ6z6nhdCCwUua0IsE0J79vQfy2Nmyofc + Q2OpLjz2tnvalX9dPX40SYPPV0NTAARs1Lms + tCueg1uRT8MMrkIRChSAW5aGHL1ObZNVqFuD + ulvfm+W7/3sHEBXuuAJW1QYaJU0= ) +server.example.com. 3600 IN A 172.30.79.10 + 3600 RRSIG A 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + uEav81+vz3eDo/TkNMaKMf3IpMIsuVg7NV+3 + oN7akjotlRzGkeWT1LHM/tZz2XGG+Tlw3LI7 + +L3h6N0QQMlJJ4d6atOL4CShNWyYC27JNZ7t + WJLxZNLfZJaRBgmOqWP60g8ZicCerFasxR1o + +JDf5nNL6FH1KStC0ZuJfMLQVbk= ) +sub5.example.com. 3600 IN CNAME sub3.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + Z2PhwJKkA3pgLFRgZCNytK+f6gNX/5sfo/Y6 + 7SYp0VJHbWndhMwX4sxSRjY2F23QKrzo0PdK + cAHYrzBb8lVSaxdLqDKKGazhLE7sMwNZzTBe + f3rokNWjz+y+1GP0/WFcVW5WLh2REaR7yR62 + 3QemcT3e2uB5FV/IIIUPCR85zwU= ) +1DN7NM4DOV8TAMT2O42J0T9M8B91CEB9.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 3LVPU5M9BF6R0F9L1UB36HDOI6SNPA1K CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + to+Oi5Ls4ea8RiwCikG5CMLG3poJ6EOCn51p + Fe6c6hY532DNi64z2jBWithM9YxIfAwt3j3Y + e3gIftTZvsMzP23Cdh11PUnThMX0180E8Vnc + waYAgLB2rG9HBc+0zrgYjA6s7xOCEEoYbVLW + mjPFLlpE9iVVtGuPf823SBilzro= ) +wwwtest.example.com. 3600 IN CNAME www.example.com. + 3600 RRSIG CNAME 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + khglR0/LGoeaAsSYFAf+YXmUAVOzFeE/eY2M + HuI8HliMuHl1jlo27I88OahsCY7c36+3z3j1 + lIh3G5gpKbPB60KZ/5nWqR0os1ASm863L4Jk + L+Q5vfxiMeO6yZ2ywUjm7bUEPH6DXo9IoiXC + I6AedcGz25t1nzutks/gad6dNUg= ) +3LVPU5M9BF6R0F9L1UB36HDOI6SNPA1K.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 572T84KRFBMQUC5O8I2V5BNLNHA8CBQN SRV RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + leFMlSPZk2RQXikgAkH49rf51b1Bdz0PXGrD + FrIQ3BhVy6AWN36MkD0DppqDk5838a9J2Qo3 + 8MCR85WM061J3lGm8DhwR0az22+Ot2erzO0s + PL/21G1iaOF1OP3b5EN2jfoZdZ9F1T96dSjW + 5iA4PbB97IqgzAnFlrOBrWsBJf4= ) +572T84KRFBMQUC5O8I2V5BNLNHA8CBQN.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 58KH92475K4K07K5NV8KAHO2UOHLGA5N A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + Pr8qo3SOSxkKhW0VW+0Fk4Y/p/NMF/Ys1Rt5 + 2Ux60M/5jbIY6yIAZBeJvBAeWG0a0lO6G/+t + XL81AV6dX2XVJsgYxEhyBzIiz2Y4gJT2QS1L + VEW4b26+7MH5JL7dKaKNJx8AUNS6X7xb9RJY + wzstiifxrHTYNBwoCZPlCmYrFJ8= ) +58KH92475K4K07K5NV8KAHO2UOHLGA5N.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 600RRJ34OTBFOQCRPSG5J4F19RM76IOE A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + TJLCuX3rB9xIBaffuYRAzR1CFkJ6ReAp9AXu + j4QFsmoo7IfU8stwYscWB/NQUUDR3zA6rych + KetLhIwHG96GPiI4ERiQ2y1O0cND9j47rnkC + 2tAy7o9Ou8InmUJuKT6rV0NrVEiXmSaNMxuh + eLhcIcRmFulkAaCv7yfja91fsSU= ) +9CGLSFKECUFG8QODUCMQPMVH0JP35440.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 9OEBI5IG2AOVVIECGRSF2P0DVT6VFJ3V A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + KuqCuiNXU84Zv+R7/tFeoc4+n0jybD2v3jFQ + r7UyHwYkbgJjT4EjCkIywm56DnrZZ0J8Klz5 + dF4/fWaa/uha+q8j9zbNwYFnzUOmX08rAhAA + CTGyoq6Gq7vBLxh7IyaCTi6phDdGajAywODG + B08oWuYgyl+BaV6HUMXxjoC8v0E= ) +9OEBI5IG2AOVVIECGRSF2P0DVT6VFJ3V.example.com. 3600 IN NSEC3 1 0 10 AD3302FF AQCNF4KN2I1N0LNG51GONIIGCH7JRLBN CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + nt2Hz0NSjX67Wv9HrpzglnFtDwHB3SE1LiNm + xZeTx0hKk/4b8DGTB69/YglwCiVzd0h001A5 + 9N0KLQH/cFfV1N6GWcyH382t1e31UtYzVWbm + o4SXfj+xex9Zgnr6DpuefOCzMNSkrB8hVBR7 + jIVafVPz8H2a+EEnFrf3NII8HTY= ) +6K06BSDDT661B33QPG6F6EB14TIAJ42D.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 9CGLSFKECUFG8QODUCMQPMVH0JP35440 A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + lo+UMe/OHfBIQYxkbggwETXfy7FShVTIk51E + NBHD3TzNvUdjimVammEbkmbMI79Ic3wdnKrj + sk0IbF5DU4owVTF0Ze2EMikNpWndTIw4F03I + IbRd6cI38RtKGzxTUd3N+H0Dv+x1HK06TZsp + ildUHnYomQ3OMzdIuLOO70GGse0= ) +600RRJ34OTBFOQCRPSG5J4F19RM76IOE.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 6K06BSDDT661B33QPG6F6EB14TIAJ42D SRV RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + Gx41Q8P2L1LIMqEJ++6DDIwWOIarnKH9+APX + a0ydl7+BMEa3uYtpEMRN822szoWNro96N1km + ih6lQesDaVFqkksrnJ+2dnyuCqQFV2FxnLJu + D6w3KxzXs8HDh4jDUBo2Je7grdNXdiHT5FqY + xCYcHtvbXqPDUBUVoka0YQYq2DY= ) +AQCNF4KN2I1N0LNG51GONIIGCH7JRLBN.example.com. 3600 IN NSEC3 1 0 10 AD3302FF BMSTOMQ8U0QNBNODBRAAEPTFKDBLGOGS CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + pAm1NJoUtgrh1nZZOa+BOLe+sqxBYDRmy43+ + Qsn9/xK+5nFP4uMewpJ399W+lYRXTVHj551W + SFSaPQViD30s3f/GRhux2Thkc9qUYO4XfQhl + cFM6ZBo6mjMc7coEeE2i/SA31tYvx1aL402a + HqdzfPGLGtVvrv1ebZngBva6Wdg= ) +CITG8IDONU692P92JJHS57P0ADNMB59S.example.com. 3600 IN NSEC3 1 0 10 AD3302FF D2S5TIC04S7ORKP09MAEOFV1GN1IQORK A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + FK+huH4wLnBWZ7dtydX3lYj1pB9rP6WS+Nqq + 3+3y3HlrrVM3dfJ/CdN8VjhrE6J7UWNl0hrG + nmZix1zLXZUWLusY/hPE6cyKh+yGmjtZit/0 + qJfxPMr9GQLY6pa64kFejhX74Dr5Tch0rvIS + cCdqrgS1hppQkVC+NuJfXDiWSfc= ) +BMSTOMQ8U0QNBNODBRAAEPTFKDBLGOGS.example.com. 3600 IN NSEC3 1 0 10 AD3302FF BUKTJEVN7M7HJ26RT7O3EEK96L94VGVV + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + FhTgIqqS6DUxaSLZd7RO7uWMi7rJjRfzkcj2 + D0SP4iBPwBmntadfMSbJ7LQhqmF/RSlZJ9e3 + ijiAzMcLQspiFeV/WJAivlNLLG9wESYcSoNH + GiEhtVbQDmhsCTeywoLWL2Ttf2En4l3SonKr + EceztaBYd4VSZb9eQ6mRWdF+nwA= ) +BUKTJEVN7M7HJ26RT7O3EEK96L94VGVV.example.com. 3600 IN NSEC3 1 0 10 AD3302FF CITG8IDONU692P92JJHS57P0ADNMB59S A NS SOA MX RRSIG DNSKEY NSEC3PARAM + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + k7y2B2ZDxLVV/dGu52n2kaHU42UiLExA2RWe + pC8DuqezyFotFMwAxRT7jozgzLAYuWV6hnR4 + 4eZQ2IIoqKUTXpnNh7p+xidNACwEGY1ZD4Fb + SjVbhKKRc9HQzVcBoKsS91OmJnH3Wxl/Zr1v + fkyAORJESGw0TMVHKYiE38HKuZo= ) +E7P2NFQQEAFD7JGEK6TDOE99B16J6KCI.example.com. 3600 IN NSEC3 1 0 10 AD3302FF EAO0AESHP4M49Q5F332G7SOK1JH53NT4 NS + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + eeYNlR+7RF/WnR2Xfpi5BrwYmJsMKVtVGXBe + 3NzeQrZcqdDwnXwhwmpYZSYoBnQ46XrniGdx + BTIRHEqkj55uQxQ+xRCK+P/B7Q2VZWsiSsq5 + UAJSnCuErfJze6tRe3xTw7Jk27HBQD//nG8o + ZH9xoMdkzC9H9y8QiMJabDAG6Pk= ) +DV0IMRDKSGUBTBMM94HHURG2QOPJS33D.example.com. 3600 IN NSEC3 1 0 10 AD3302FF E7P2NFQQEAFD7JGEK6TDOE99B16J6KCI SRV RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + rEfdvZaXj4lmZJWz+o4ZOotWHlYbjFhoXUCk + JsRilkouAzzZkq6XDgTWW+n6KAHfB2t9mjex + UH7JK6/AQrSF9SolAzPZorVMVPFnoT1gQnQM + sklwqGHkwhHO+ZFumXGPjsKKDwsxfGSnchyh + 5X+jNJbtkEG45Pz0vcAgJVL7zDU= ) +D2S5TIC04S7ORKP09MAEOFV1GN1IQORK.example.com. 3600 IN NSEC3 1 0 10 AD3302FF DSSTL51IUQBKDPULIFJHGJP40C3NK2EA CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + SfsbWl8rpuCStr+LeCdKGL/2PDVI4XmqWbo/ + WvEMXcidKxw3S+MIPctFRMBQfMxaiidpjdF6 + MxTPJkQIIkuHxz0m0KCHxjkzQCGq4E9aSINJ + 58XBq9Lvq2891pymq18FogRpYaDnZUQDoezk + qaDLBJIQ7+j+wmD+gRxrIp9Co/I= ) +DSSTL51IUQBKDPULIFJHGJP40C3NK2EA.example.com. 3600 IN NSEC3 1 0 10 AD3302FF DV0IMRDKSGUBTBMM94HHURG2QOPJS33D CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + Ip7RkE1QMBk6TVbD7BckwtJpEM/bZR7CdCh2 + mYwDCH/VvE/4SHxu8ZaKZUxxe5jo4fdgbUml + tlwraOROKEY1pO3eD/x1xu5GI1NcB31Cq3Oh + 9anWbEglye9wYr2AqqWZ6/Dvf+P1gTYbEK9+ + V9Fj1xm9vnHubnEwsCOfKDdXZ/I= ) +G8QQP950BTQH4E0JDQTK2RCT5MI6A7B8.example.com. 3600 IN NSEC3 1 0 10 AD3302FF GC9S3VD2NHESSRL256KS0805PL0KAI2T DNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + cfmuSLlgtjXs7nlbqAXXSXa6A/yR6txfYWxS + MLx4KkI2La949SiV4GlcqypKlZ5EL32xdqk3 + 8qDMhBBpzxSSmrsQRi4XiAG8f0/lGEBVSy+D + 0PlXeZHuCOfND8DtxsIttkxHOEop7vj7GuTA + 1V7I6TKxdFDPYaOtp/iz8wrCIOQ= ) +GC9S3VD2NHESSRL256KS0805PL0KAI2T.example.com. 3600 IN NSEC3 1 0 10 AD3302FF GGR966KJ5J300229Q7154AMB4EVVLLMG A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + uMUt9rYgxn4+VutPJ2B2in3lt8QmiV+cUwE5 + TryjJsqFyWeKbhZpmh5fVbQLLZAjMAuQfQtY + CJb1gMeO7CIxlk4uLcjZSsMdDcKtwstU41T+ + 9b4rHh42mgQBo7LrRXP8NUtXOZyvqge3AHmV + FKSJdhvmQdtLKgJUXRWPJQk2kIA= ) +EM46BUMIU4I93E5FQSDJSIO6TG9OJ35I.example.com. 3600 IN NSEC3 1 0 10 AD3302FF G8QQP950BTQH4E0JDQTK2RCT5MI6A7B8 CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + B937ph6NFfdD4bBEBEK4NVup+k7C4+vDKZVF + Wy9tzJAEqjoFTWqxrrfs1pmpxsvB4LzawVXm + XIxjqBuve6tNOk/LWjjrMigtx0gdJ8m3fCiU + Uk7t7xiDy5AgS8vkzYiQSr4EXb00v3dcSlUQ + nqjabZhgTx58KhbqF3O4c/oViY8= ) +EAO0AESHP4M49Q5F332G7SOK1JH53NT4.example.com. 3600 IN NSEC3 1 0 10 AD3302FF EM46BUMIU4I93E5FQSDJSIO6TG9OJ35I + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + rN/OU0sPJ9P28hEhDUlvMvPnQSBbyRwnMN3h + YipF2VX2r7Ij3qdD0k3PKx/Emzsbl+ImbGNm + mfhDQ0O72m6sT664Q8yO32Pve8i/fxQIVKTF + HalkrM2xonf7Bg+wzI4CnQHmWD8hcq4L7Mj1 + bFI0H+PRWz75h0BB4hJYIs6sCuQ= ) +GGR966KJ5J300229Q7154AMB4EVVLLMG.example.com. 3600 IN NSEC3 1 0 10 AD3302FF GJRT9TI4T3VSP9D26OC04EQ88SOFVRON A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + Bg8bWWuR/Gw8xKCrFjEHQRBhbBPKu0AL2DGT + QChgHqSaAj7hcaMHLStaCH7NRy/EQL07ryU1 + Xh7EPFZn191xKJPrwFq2bIsgpYYoQ5Knwt1w + P3EdQEV6jANOx0k9IHsXC+9oGbMipe0iGYV1 + 4XG295g5Kk47sfEcl9leOgH9xNQ= ) +H01743IKEGI4JJOMSNCP0VG5S6IPGPIF.example.com. 3600 IN NSEC3 1 0 10 AD3302FF IV7VKFB1OLT6DRIGHT0U4O0L6PU6KMBC + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + SS6rDyoEGhD/SkKu87gA4GNlKoAxyXnfVZ7K + iEdXMSrSdAu1dkHWCNqHvGuws9VDjwdZ2VKM + R0H09jMFs9Uur2u2A8RYv9RTwk3i2VKY9TPW + V5cp35ukOK2zQWWM8hSxIjIudiMhSdp/dluU + hGGMxb/Vl6TWMBff961lBqmQe0k= ) +IV7VKFB1OLT6DRIGHT0U4O0L6PU6KMBC.example.com. 3600 IN NSEC3 1 0 10 AD3302FF J7A75JJN87L9PTVO6HBKH8IPI78IPUO4 A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + BsmFOWVyvp6T+lYJq9iI7N72LFces0lgUzgE + mi5hgj5j+/ak7Jbh5HMA9clnA4x2gVIbl4tB + n64PqfOoDeotG3KUS40aJMLtD5kLQ2lS8Jje + nj5ZGTvkkyDq03nzuCbO4WTVGs3Lv8nuKhPL + 0JchxWeMS4yya/7ZDAexOcaas5k= ) +GJRT9TI4T3VSP9D26OC04EQ88SOFVRON.example.com. 3600 IN NSEC3 1 0 10 AD3302FF H01743IKEGI4JJOMSNCP0VG5S6IPGPIF CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + atmcjXLJAop3xdnjTYTLDu1ooa/VrFPISBAl + 3yvMJmOBEtxO9I+wQUkSv59nDC59my/Pfye0 + +tEo8iUanThfoNFZehA7HAl+scL7eiizyzpV + iemaGcqA8blGZmvGegBfgnHClw/s+J0lyxPO + +R6C1Ht53+5RL5havJgeiyDhrF0= ) +J7A75JJN87L9PTVO6HBKH8IPI78IPUO4.example.com. 3600 IN NSEC3 1 0 10 AD3302FF KI1L4Q2S3IFEG634FE6DN6E3FGEGV956 A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + nejtB8Eb1URet62fXj1vdJ3FNJ+yIBFF5Kiw + 0trO8jpxEXZbop3Ls55eMRBO4uyxnXAQzOqd + iawmpOXkuhJkUC5dHg//l4bu7NnD1Delyfv0 + t7VXAFjH8sV82HNsk/g8ngn4gekexXZU3QTJ + GcpAIGxpza48oI9qYf1jU7SOGuE= ) +KI1L4Q2S3IFEG634FE6DN6E3FGEGV956.example.com. 3600 IN NSEC3 1 0 10 AD3302FF LMQIHH5MDDR9PTGEHOHA5ND49685RR01 DNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + eoSPJ3B1MdvFBppmzqQ6+VY3ojgFuJdAqLIZ + Rac7CTMKqOILvQVEwwV9rU+vX3WpkiJ+RaiZ + +TUICV13KE3PJW6sEar7VenLHJyBLb9L2gRO + CaVf8IZy/PKwS1zdrasidKW2URRFhJdVcnuu + kdwRXfEmZYA4qEafclF+PDj49v0= ) +OIKQOJ12077E6HOP6HHST9DHAMGPED5T.example.com. 3600 IN NSEC3 1 0 10 AD3302FF OTMDSI120AJGM768VIKPLND04FDSUQSJ CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + H8h+djCAspCVBuSd5QyWe1Z3rIQcRJSCYtky + XRqfUN4gkcrMFEduIM5Ic5AJD25AxM2CnTBL + yVOGlcEJdpMivzZwJF+5mavO3hJ36LFEZkay + hmqUx39zqNC60a6bHDK9QTkvouQ5EuM26nMf + 9o6HytksqjvsYxkBJCJfR7oiTok= ) +MEVBVIJUVOB0D9J7BQ6AONI153T8P6EO.example.com. 3600 IN NSEC3 1 0 10 AD3302FF OIKQOJ12077E6HOP6HHST9DHAMGPED5T + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + ZLiscKNOltWTqqwxDvjZmwTqhqAfjiDA68le + vmvY4mYzoPEHASd19gEhddNvR+KK/JVGYvEr + hB2jpgOSZCs1wsW90UpL0boenluMPppLFDUD + xLUD2jvzA9a6lBjl55jzUr6mLyyr2hHIPmk0 + CmrSFITGT6qEzEWq/CLA6TvtBsY= ) +LMQIHH5MDDR9PTGEHOHA5ND49685RR01.example.com. 3600 IN NSEC3 1 0 10 AD3302FF MEVBVIJUVOB0D9J7BQ6AONI153T8P6EO CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + da0fy8qWaZtO26BoIvbr56jBrrucndmMJ/0h + /Y5BE2ib8X65KVjkNVt5Mg5YKpTvaeOZN6CQ + Dls5bxnUkqmu0kgaUjIB/rhiMhpPqkKF7dSP + SI85zqJXIgCInMsgfTiBp5uZwrBKtse89LwH + y6BC682kK/uX7ikjG4+BapL6ivQ= ) +OTMDSI120AJGM768VIKPLND04FDSUQSJ.example.com. 3600 IN NSEC3 1 0 10 AD3302FF P3RBJILTM87MQELBIM9TNBJ4ETMSH0PA A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + jWagz+ntj/MtfWB6xUJlkfihEkwrj84g1CbX + F6yKKVk4WToETt2ApHMHd8tn4wbHYLfojavI + TbsIVBfWxyMFsCshMoBASML7T8I9X3jjEYKS + W877XhA2yxuFcMaTjh3jDm7wfLHIvEgqhanr + 6JO2qGWTKSlNWK+bYg4y89YJOOA= ) +PFRQA6T0EUQ6MUU9LPM9M3GP8GQ1CQ1G.example.com. 3600 IN NSEC3 1 0 10 AD3302FF PO8BSJPMDN4514A8JA8QNK1C79EJIF7E NS + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + qA/sA5sV/eRmtgb+HBzbENLI2jy7xEkiDd4H + d/REG2hCp3rlIlo1FK2y7q1sZDr3sZ0/5vrQ + jxOHpZx+akeHi7hT3R1KhQLFb/+veEOBXNVG + HMtB3+Uc7Ttq1bGdVQIDhrVpNVhKS44nEG6O + UwOKgK7aT2q2mnUA3c6foWI0sM8= ) +P98NSUFJ2IPUSG2OOPH9CPGHBNC9RRR7.example.com. 3600 IN NSEC3 1 0 10 AD3302FF PFRQA6T0EUQ6MUU9LPM9M3GP8GQ1CQ1G A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + VoYUgMVgFe4QXN5ggAzleOYWGKatee//AXnv + CeFRHn4lKcGKWGRxbaMaHHGkTX+UjN2DnGcD + nCU/LQo15nKk8m8EYoUYywaHYiZ+aJ5eoagB + hka9G8YRM4goHxyKr4asFtfjHcfGdW82y3kv + BJYH/MN82GAhMfsdCA9z9zp88zo= ) +PO8BSJPMDN4514A8JA8QNK1C79EJIF7E.example.com. 3600 IN NSEC3 1 0 10 AD3302FF PSMSPPC19D8OAICCQ64C7MQ387MTVGC1 A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + QtJhRcGQl3Fi9tGK6xD0Dr5s740QqsOhvaJN + ofLjQVTa4zDEoC6txlgTO4czRl7KPFWa8T48 + W+jCqEysIamuUMmUOypCj7Airg4lDdS2VBUJ + BC2npTHBKnx+J1h8p58p0KDhozYoMNtYUUFF + gBp99sWEsORnDxyiW+KFFTTW0xU= ) +P3RBJILTM87MQELBIM9TNBJ4ETMSH0PA.example.com. 3600 IN NSEC3 1 0 10 AD3302FF P98NSUFJ2IPUSG2OOPH9CPGHBNC9RRR7 CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + sBdCg4Y3vGxry/Z1zV/Xg6bdpYjKiTXTSDm8 + 9D1WZ8WAW5vbSJHxTnXq4IxwAJr2fpI4fUiT + cAS0uFqd+Ft8XpSQjaNPGuwzS08DCLn++Hrm + lbCngUeApxrgCfxo+cf4ibRPfef3UPcUxDOD + meqoGFw51+5DpB1Ygf5+yEPhAX0= ) +PSMSPPC19D8OAICCQ64C7MQ387MTVGC1.example.com. 3600 IN NSEC3 1 0 10 AD3302FF RQK67K3ON1JGJ60JNO4883D1JVIOIG2D + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + DMO3YD4aOFqjkxmw+SDajMoQ+3TylCrk6yyr + ZQiV7yrfP5SIwY40EKCVG+6d0jSNQd7LrbJz + uyXiGpGEpKRTmAJZYSrpiPyfbbfw1XrOW9BX + 7qVZCvK8iZrkaNT6yQ4W/Q4gwSIyRpUqE1j1 + 2SgEv934CIWBew/cjGfVzdIMHCo= ) +RQK67K3ON1JGJ60JNO4883D1JVIOIG2D.example.com. 3600 IN NSEC3 1 0 10 AD3302FF RSSD7AU1NQEBI2UF3B58G8JKBD0CDURF A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + fVTi0gRo2WwgEu51Fx1iH5Ke8eh8m8l94luf + yx5K6gCqywv9Sbk7YhyKmW5/94r0VwyNqgPS + 5DF6+RXBlM/t+35g+K04eBortmy89dbzFSZD + YPqfk2Q7v98jMnB0OzLoqGg5LqxTBPHftKm4 + O0tsGJ7AC8bto6+iBEOEjX3ky54= ) +SH86DKIJAGTUEUO2F2PPQ0RJEFJCKGKS.example.com. 3600 IN NSEC3 1 0 10 AD3302FF UB8IU759M5EE63CQBISIRM9C0V2RU1RT CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + ASL7wTfcNyORVN8g+BjK3CSP5NXsWoqF9imO + E93NzOn4EvgOI1K7jDZ+urgCaaaw3rqt/yUS + 4/nU7wHUDjuNsvP9B+lWm93l8I1n9nhkOy5D + J17XjWE+8AqBidwX7O5clx+yAMSCnL7X4Rp5 + luSPK6oZeRX2A5wSHbrvHeQkI78= ) +UB8IU759M5EE63CQBISIRM9C0V2RU1RT.example.com. 3600 IN NSEC3 1 0 10 AD3302FF URIDB302IVQCE7DQSKELLE9LEFOHV0LT A RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + uZPu1mukjnAj+p7IKGe5tQV4yMBEytV4ab5W + nWNZeChWwQfooNwaOK+ZBkFvWs/bxyKtwL7b + 24xAbU+4+TzD5Ier9xNYDNfLXUkJ9hKuBrvg + RDYN8W/rRN++aL4xR0o/jOwzVnkww/VtIkvK + 7FPE0F2YpEw16H/ZIWnL6htRb5w= ) +RSSD7AU1NQEBI2UF3B58G8JKBD0CDURF.example.com. 3600 IN NSEC3 1 0 10 AD3302FF S4A8QO8DEA53D05JQA0RE3H3R6UC7V1G + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + sIaGgFypdpWWLFqcWGI0PzitwaIZI6irA8uw + Y/E4etgI+l5aKbHPeum0+qzktYWc/wFxte44 + 0T3dRujlVbMOhDAhE3QJFjZWEZo8ZZH7ARxC + bn5pTkzmKjWqKjKhol2U0Y7ve74oJpi5H5o5 + D7nqiEmr1Ou8xkqbK281PGSti+s= ) +S4A8QO8DEA53D05JQA0RE3H3R6UC7V1G.example.com. 3600 IN NSEC3 1 0 10 AD3302FF SH86DKIJAGTUEUO2F2PPQ0RJEFJCKGKS NS + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + bDbE5EuKlVnpyavKronRh+FiK5wB0Ecw+ubc + HiVRrQfJvnayxRVOiE0OvUrK0n0FyQwuXk6w + /EysxVkcDK8wwX3SsXW71qEE1qG6GmFHUUOJ + gksxkjkVTMug0Xnmm+UGO9va5VhekMJLiNzF + Nl+vhTphDLLTgql8pyoA44PDARM= ) +URIDB302IVQCE7DQSKELLE9LEFOHV0LT.example.com. 3600 IN NSEC3 1 0 10 AD3302FF V34U1QKHVIL4EOR63PIVLI0NBDMAQLL0 + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + JuCoPMHnJZXXo+/2ACPorEF6zHtGylp4ybXe + eN2VC5jmj7NMj+8EFkHa2hRoy2yL4hA5+dOo + PDzaQtHJ9wO2gYgU9qz2eGNRfFM655ig4Uq+ + yfpQjUq5hAyuxTehlhH51jElOo1B9rC+qpbY + eQIfqyK318Xp7JswLblUn8IHzUE= ) +V34U1QKHVIL4EOR63PIVLI0NBDMAQLL0.example.com. 3600 IN NSEC3 1 0 10 AD3302FF 0R5AV1LGTS4HLPNB8UK2DTLCSO65OBJ7 CNAME RRSIG + 3600 RRSIG NSEC3 7 3 3600 20120311114108 ( + 20120210114108 60914 example.com. + q5cTrHk3CXT3nACoB0sexMUuit+ze5mj+PX3 + Xvv9XPMm30q9CGdVYQG9N5f4TiYiQJU6Lf99 + Pt7t+zWhB/YVfFrcCB3k5zWA/QfmwQYLrEyK + QiTxMEGvRU5QhbXwdiltAjQIpiO/fqa9wwr3 + l9/TaVniVaOM0XXV2A8xzNUHuYM= ) diff --git a/samples/knot.full.conf b/samples/knot.full.conf index 04fbe09..91d5674 100644 --- a/samples/knot.full.conf +++ b/samples/knot.full.conf @@ -20,14 +20,27 @@ system { # Version of the server (see RFC 4892). Not used yet. version "0.1"; + # Server identifier + # Use string format "text" + # Or hexstring 0x01ab00 + nsid "myserver0"; + # Working directory of the server # Used to store compiled zones and PID file storage "/tmp/knot-sample"; + # Custom pidfile path + # default: pidfile is created in 'storage'. + pidfile "/tmp/knot.pid"; + # Number of workers per interface # This option is used to force number of threads used per interface # Default: unset (auto-estimates optimal value from the number of online CPUs) workers 1; + + # User for running server + # May also specify user.group (f.e. knot.users) + user: root; } # Section 'keys' contains list of TSIG keys diff --git a/scripts/urcu-tls-compat.patch b/scripts/urcu-tls-compat.patch new file mode 100644 index 0000000..cd5ff25 --- /dev/null +++ b/scripts/urcu-tls-compat.patch @@ -0,0 +1,1495 @@ +From 998d005870782ed52ba0fe66a99589dc8b7eb20e Mon Sep 17 00:00:00 2001 +From: Marek Vavrusa <marek@vavrusa.com> +Date: Mon, 30 Jan 2012 16:40:12 +0100 +Subject: [PATCH] Compatibility for compilers without TLS support. + +If TLS is detected on configure, it is used as before. +If not, it is emulated using pthread_setspecific()/pthread_getspecific() +and set of macros. + +For usage info, see urcu/tls-compat.h +--- + .gitignore | 1 - + configure.ac | 3 + + m4/ax_tls.m4 | 76 ++++++++++++++++++++++++++++++++ + tests/test_mutex.c | 8 +++- + tests/test_perthreadlock.c | 8 +++- + tests/test_rwlock.c | 8 +++- + tests/test_urcu.c | 8 +++- + tests/test_urcu_assign.c | 8 +++- + tests/test_urcu_bp.c | 8 +++- + tests/test_urcu_defer.c | 8 +++- + tests/test_urcu_gc.c | 8 +++- + tests/test_urcu_lfq.c | 14 ++++-- + tests/test_urcu_lfs.c | 14 ++++-- + tests/test_urcu_qsbr.c | 8 +++- + tests/test_urcu_qsbr_gc.c | 8 +++- + tests/test_urcu_wfq.c | 14 ++++-- + tests/test_urcu_wfs.c | 14 ++++-- + urcu-bp.c | 10 +++-- + urcu-call-rcu-impl.h | 26 +++++++++++- + urcu-defer-impl.h | 49 +++++++++++--------- + urcu-qsbr.c | 18 ++++--- + urcu.c | 22 +++++---- + urcu/map/urcu-bp.h | 2 + + urcu/map/urcu-qsbr.h | 2 + + urcu/map/urcu.h | 4 ++ + urcu/static/urcu-bp.h | 18 +++++--- + urcu/static/urcu-qsbr.h | 22 ++++++---- + urcu/static/urcu.h | 21 ++++++--- + urcu/tls-compat.h | 104 ++++++++++++++++++++++++++++++++++++++++++++ + 29 files changed, 408 insertions(+), 106 deletions(-) + create mode 100644 m4/ax_tls.m4 + create mode 100644 urcu/tls-compat.h + +diff --git a/.gitignore b/.gitignore +index 6eeb2a1..7af5609 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -71,7 +71,6 @@ tests/*.log + .libs/ + Makefile.in + Makefile +-*.m4 + *.la + *.bz2 + *.o +diff --git a/configure.ac b/configure.ac +index 5a90008..1953a8a 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -14,6 +14,9 @@ AC_CANONICAL_HOST + AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip]) + m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) + ++AC_CONFIG_MACRO_DIR([m4]) ++m4_include([m4/ax_tls.m4]) ++ + AC_CONFIG_SRCDIR([urcu.h]) + AM_PROG_MKDIR_P + +diff --git a/m4/ax_tls.m4 b/m4/ax_tls.m4 +new file mode 100644 +index 0000000..033e3b1 +--- /dev/null ++++ b/m4/ax_tls.m4 +@@ -0,0 +1,76 @@ ++# =========================================================================== ++# http://www.gnu.org/software/autoconf-archive/ax_tls.html ++# =========================================================================== ++# ++# SYNOPSIS ++# ++# AX_TLS([action-if-found], [action-if-not-found]) ++# ++# DESCRIPTION ++# ++# Provides a test for the compiler support of thread local storage (TLS) ++# extensions. Defines TLS if it is found. Currently knows about GCC/ICC ++# and MSVC. I think SunPro uses the same as GCC, and Borland apparently ++# supports either. ++# ++# LICENSE ++# ++# Copyright (c) 2008 Alan Woodland <ajw05@aber.ac.uk> ++# Copyright (c) 2010 Diego Elio Petteno` <flameeyes@gmail.com> ++# ++# This program is free software: you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation, either version 3 of the License, or (at your ++# option) any later version. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General ++# Public License for more details. ++# ++# You should have received a copy of the GNU General Public License along ++# with this program. If not, see <http://www.gnu.org/licenses/>. ++# ++# As a special exception, the respective Autoconf Macro's copyright owner ++# gives unlimited permission to copy, distribute and modify the configure ++# scripts that are the output of Autoconf when processing the Macro. You ++# need not follow the terms of the GNU General Public License when using ++# or distributing such scripts, even though portions of the text of the ++# Macro appear in them. The GNU General Public License (GPL) does govern ++# all other use of the material that constitutes the Autoconf Macro. ++# ++# This special exception to the GPL applies to versions of the Autoconf ++# Macro released by the Autoconf Archive. When you make and distribute a ++# modified version of the Autoconf Macro, you may extend this special ++# exception to the GPL to apply to your modified version as well. ++ ++#serial 10 ++ ++AC_DEFUN([AX_TLS], [ ++ AC_MSG_CHECKING(for thread local storage (TLS) class) ++ AC_CACHE_VAL(ac_cv_tls, [ ++ ax_tls_keywords="__thread __declspec(thread) none" ++ for ax_tls_keyword in $ax_tls_keywords; do ++ AS_CASE([$ax_tls_keyword], ++ [none], [ac_cv_tls=none ; break], ++ [AC_TRY_COMPILE( ++ [#include <stdlib.h> ++ static void ++ foo(void) { ++ static ] $ax_tls_keyword [ int bar; ++ exit(1); ++ }], ++ [], ++ [ac_cv_tls=$ax_tls_keyword ; break], ++ ac_cv_tls=none ++ )]) ++ done ++ ]) ++ AC_MSG_RESULT($ac_cv_tls) ++ ++ AS_IF([test "$ac_cv_tls" != "none"], ++ AC_DEFINE_UNQUOTED([TLS], $ac_cv_tls, [If the compiler supports a TLS storage class define it to that here]) ++ m4_ifnblank([$1], [$1]), ++ m4_ifnblank([$2], [$2]) ++ ) ++]) +diff --git a/tests/test_mutex.c b/tests/test_mutex.c +index 3f84bbf..bb73f1c 100644 +--- a/tests/test_mutex.c ++++ b/tests/test_mutex.c +@@ -4,6 +4,7 @@ + * Userspace RCU library - test program + * + * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -35,6 +36,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -155,8 +157,10 @@ static int test_duration_read(void) + return !test_stop; + } + +-static unsigned long long __thread nr_writes; +-static unsigned long long __thread nr_reads; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_writes, _tls_nr_writes); ++#define nr_writes (*_nr_writes()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_reads, _tls_nr_reads); ++#define nr_reads (*_nr_reads()) + + static + unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; +diff --git a/tests/test_perthreadlock.c b/tests/test_perthreadlock.c +index fa9c89a..14362cf 100644 +--- a/tests/test_perthreadlock.c ++++ b/tests/test_perthreadlock.c +@@ -4,6 +4,7 @@ + * Userspace RCU library - test program + * + * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -35,6 +36,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -159,8 +161,10 @@ static int test_duration_read(void) + return !test_stop; + } + +-static unsigned long long __thread nr_writes; +-static unsigned long long __thread nr_reads; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_writes, _tls_nr_writes); ++#define nr_writes (*_nr_writes()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_reads, _tls_nr_reads); ++#define nr_reads (*_nr_reads()) + + static + unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; +diff --git a/tests/test_rwlock.c b/tests/test_rwlock.c +index 34d8c07..087ff58 100644 +--- a/tests/test_rwlock.c ++++ b/tests/test_rwlock.c +@@ -4,6 +4,7 @@ + * Userspace RCU library - test program + * + * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -35,6 +36,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -156,8 +158,10 @@ static int test_duration_read(void) + return !test_stop; + } + +-static unsigned long long __thread nr_writes; +-static unsigned long long __thread nr_reads; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_writes, _tls_nr_writes); ++#define nr_writes (*_nr_writes()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_reads, _tls_nr_reads); ++#define nr_reads (*_nr_reads()) + + static unsigned int nr_readers; + static unsigned int nr_writers; +diff --git a/tests/test_urcu.c b/tests/test_urcu.c +index 870f133..cf8e12e 100644 +--- a/tests/test_urcu.c ++++ b/tests/test_urcu.c +@@ -4,6 +4,7 @@ + * Userspace RCU library - test program + * + * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -35,6 +36,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -154,8 +156,10 @@ static int test_duration_read(void) + return !test_stop; + } + +-static unsigned long long __thread nr_writes; +-static unsigned long long __thread nr_reads; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_writes, _tls_nr_writes); ++#define nr_writes (*_nr_writes()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_reads, _tls_nr_reads); ++#define nr_reads (*_nr_reads()) + + static unsigned int nr_readers; + static unsigned int nr_writers; +diff --git a/tests/test_urcu_assign.c b/tests/test_urcu_assign.c +index 42d70c2..55eab0c 100644 +--- a/tests/test_urcu_assign.c ++++ b/tests/test_urcu_assign.c +@@ -4,6 +4,7 @@ + * Userspace RCU library - test program + * + * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -35,6 +36,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -154,8 +156,10 @@ static int test_duration_read(void) + return !test_stop; + } + +-static unsigned long long __thread nr_writes; +-static unsigned long long __thread nr_reads; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_writes, _tls_nr_writes); ++#define nr_writes (*_nr_writes()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_reads, _tls_nr_reads); ++#define nr_reads (*_nr_reads()) + + static unsigned int nr_readers; + static unsigned int nr_writers; +diff --git a/tests/test_urcu_bp.c b/tests/test_urcu_bp.c +index 857913f..08170b6 100644 +--- a/tests/test_urcu_bp.c ++++ b/tests/test_urcu_bp.c +@@ -4,6 +4,7 @@ + * Userspace RCU library - test program + * + * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -35,6 +36,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -154,8 +156,10 @@ static int test_duration_read(void) + return !test_stop; + } + +-static unsigned long long __thread nr_writes; +-static unsigned long long __thread nr_reads; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_writes, _tls_nr_writes); ++#define nr_writes (*_nr_writes()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_reads, _tls_nr_reads); ++#define nr_reads (*_nr_reads()) + + static unsigned int nr_readers; + static unsigned int nr_writers; +diff --git a/tests/test_urcu_defer.c b/tests/test_urcu_defer.c +index 1575e9c..c5aeeb4 100644 +--- a/tests/test_urcu_defer.c ++++ b/tests/test_urcu_defer.c +@@ -4,6 +4,7 @@ + * Userspace RCU library - test program (with automatic reclamation) + * + * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -35,6 +36,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -155,8 +157,10 @@ static int test_duration_read(void) + return !test_stop; + } + +-static unsigned long long __thread nr_writes; +-static unsigned long long __thread nr_reads; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_writes, _tls_nr_writes); ++#define nr_writes (*_nr_writes()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_reads, _tls_nr_reads); ++#define nr_reads (*_nr_reads()) + + static + unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; +diff --git a/tests/test_urcu_gc.c b/tests/test_urcu_gc.c +index 21c5d56..31d3e65 100644 +--- a/tests/test_urcu_gc.c ++++ b/tests/test_urcu_gc.c +@@ -4,6 +4,7 @@ + * Userspace RCU library - test program (with baatch reclamation) + * + * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -35,6 +36,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -163,8 +165,10 @@ static int test_duration_read(void) + return !test_stop; + } + +-static unsigned long long __thread nr_writes; +-static unsigned long long __thread nr_reads; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_writes, _tls_nr_writes); ++#define nr_writes (*_nr_writes()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_reads, _tls_nr_reads); ++#define nr_reads (*_nr_reads()) + + static + unsigned long long __attribute__((aligned(CAA_CACHE_LINE_SIZE))) *tot_nr_writes; +diff --git a/tests/test_urcu_lfq.c b/tests/test_urcu_lfq.c +index 11e7eb3..83db5d1 100644 +--- a/tests/test_urcu_lfq.c ++++ b/tests/test_urcu_lfq.c +@@ -5,6 +5,7 @@ + * + * Copyright February 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright February 2010 - Paolo Bonzini <pbonzini@redhat.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -38,6 +39,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -148,11 +150,15 @@ static int test_duration_enqueue(void) + return !test_stop; + } + +-static unsigned long long __thread nr_dequeues; +-static unsigned long long __thread nr_enqueues; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_dequeues, _tls_nr_dequeues); ++#define nr_dequeues (*_nr_dequeues()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_enqueues, _tls_nr_enqueues); ++#define nr_enqueues (*_nr_enqueues()) + +-static unsigned long long __thread nr_successful_dequeues; +-static unsigned long long __thread nr_successful_enqueues; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_successful_dequeues, _tls_nr_successful_dequeues); ++#define nr_successful_dequeues (*_nr_successful_dequeues()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_successful_enqueues, _tls_nr_successful_enqueues); ++#define nr_successful_enqueues (*_nr_successful_enqueues()) + + static unsigned int nr_enqueuers; + static unsigned int nr_dequeuers; +diff --git a/tests/test_urcu_lfs.c b/tests/test_urcu_lfs.c +index 883fd0c..79a1ceb 100644 +--- a/tests/test_urcu_lfs.c ++++ b/tests/test_urcu_lfs.c +@@ -5,6 +5,7 @@ + * + * Copyright February 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright February 2010 - Paolo Bonzini <pbonzini@redhat.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -38,6 +39,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -148,11 +150,15 @@ static int test_duration_enqueue(void) + return !test_stop; + } + +-static unsigned long long __thread nr_dequeues; +-static unsigned long long __thread nr_enqueues; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_dequeues, _tls_nr_dequeues); ++#define nr_dequeues (*_nr_dequeues()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_enqueues, _tls_nr_enqueues); ++#define nr_enqueues (*_nr_enqueues()) + +-static unsigned long long __thread nr_successful_dequeues; +-static unsigned long long __thread nr_successful_enqueues; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_successful_dequeues, _tls_nr_successful_dequeues); ++#define nr_successful_dequeues (*_nr_successful_dequeues()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_successful_enqueues, _tls_nr_successful_enqueues); ++#define nr_successful_enqueues (*_nr_successful_enqueues()) + + static unsigned int nr_enqueuers; + static unsigned int nr_dequeuers; +diff --git a/tests/test_urcu_qsbr.c b/tests/test_urcu_qsbr.c +index b986fd8..eaa4a67 100644 +--- a/tests/test_urcu_qsbr.c ++++ b/tests/test_urcu_qsbr.c +@@ -4,6 +4,7 @@ + * Userspace RCU library - test program + * + * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -35,6 +36,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -153,8 +155,10 @@ static int test_duration_read(void) + return !test_stop; + } + +-static unsigned long long __thread nr_writes; +-static unsigned long long __thread nr_reads; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_writes, _tls_nr_writes); ++#define nr_writes (*_nr_writes()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_reads, _tls_nr_reads); ++#define nr_reads (*_nr_reads()) + + static unsigned int nr_readers; + static unsigned int nr_writers; +diff --git a/tests/test_urcu_qsbr_gc.c b/tests/test_urcu_qsbr_gc.c +index 9deb0aa..e65503a 100644 +--- a/tests/test_urcu_qsbr_gc.c ++++ b/tests/test_urcu_qsbr_gc.c +@@ -4,6 +4,7 @@ + * Userspace RCU library - test program (with baatch reclamation) + * + * Copyright February 2009 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -35,6 +36,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -159,8 +161,10 @@ static int test_duration_read(void) + return !test_stop; + } + +-static unsigned long long __thread nr_writes; +-static unsigned long long __thread nr_reads; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_writes, _tls_nr_writes); ++#define nr_writes (*_nr_writes()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_reads, _tls_nr_reads); ++#define nr_reads (*_nr_reads()) + + static unsigned int nr_readers; + static unsigned int nr_writers; +diff --git a/tests/test_urcu_wfq.c b/tests/test_urcu_wfq.c +index 83ec635..32156dc 100644 +--- a/tests/test_urcu_wfq.c ++++ b/tests/test_urcu_wfq.c +@@ -5,6 +5,7 @@ + * + * Copyright February 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright February 2010 - Paolo Bonzini <pbonzini@redhat.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -38,6 +39,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -147,11 +149,15 @@ static int test_duration_enqueue(void) + return !test_stop; + } + +-static unsigned long long __thread nr_dequeues; +-static unsigned long long __thread nr_enqueues; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_dequeues, _tls_nr_dequeues); ++#define nr_dequeues (*_nr_dequeues()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_enqueues, _tls_nr_enqueues); ++#define nr_enqueues (*_nr_enqueues()) + +-static unsigned long long __thread nr_successful_dequeues; +-static unsigned long long __thread nr_successful_enqueues; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_successful_dequeues, _tls_nr_successful_dequeues); ++#define nr_successful_dequeues (*_nr_successful_dequeues()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_successful_enqueues, _tls_nr_successful_enqueues); ++#define nr_successful_enqueues (*_nr_successful_enqueues()) + + static unsigned int nr_enqueuers; + static unsigned int nr_dequeuers; +diff --git a/tests/test_urcu_wfs.c b/tests/test_urcu_wfs.c +index 7746a1d..1e78211 100644 +--- a/tests/test_urcu_wfs.c ++++ b/tests/test_urcu_wfs.c +@@ -5,6 +5,7 @@ + * + * Copyright February 2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright February 2010 - Paolo Bonzini <pbonzini@redhat.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -38,6 +39,7 @@ + #include <errno.h> + + #include <urcu/arch.h> ++#include <urcu/tls-compat.h> + + #ifdef __linux__ + #include <syscall.h> +@@ -147,11 +149,15 @@ static int test_duration_enqueue(void) + return !test_stop; + } + +-static unsigned long long __thread nr_dequeues; +-static unsigned long long __thread nr_enqueues; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_dequeues, _tls_nr_dequeues); ++#define nr_dequeues (*_nr_dequeues()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_enqueues, _tls_nr_enqueues); ++#define nr_enqueues (*_nr_enqueues()) + +-static unsigned long long __thread nr_successful_dequeues; +-static unsigned long long __thread nr_successful_enqueues; ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_successful_dequeues, _tls_nr_successful_dequeues); ++#define nr_successful_dequeues (*_nr_successful_dequeues()) ++TLS_DEFINE_SIMPLE(unsigned long long, _nr_successful_enqueues, _tls_nr_successful_enqueues); ++#define nr_successful_enqueues (*_nr_successful_enqueues()) + + static unsigned int nr_enqueuers; + static unsigned int nr_dequeuers; +diff --git a/urcu-bp.c b/urcu-bp.c +index f3249b4..1b38097 100644 +--- a/urcu-bp.c ++++ b/urcu-bp.c +@@ -5,6 +5,7 @@ + * + * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -35,6 +36,7 @@ + #include <poll.h> + #include <unistd.h> + #include <sys/mman.h> ++#include <config.h> + + #include "urcu/wfqueue.h" + #include "urcu/map/urcu-bp.h" +@@ -94,7 +96,7 @@ static pthread_mutex_t rcu_gp_lock = PTHREAD_MUTEX_INITIALIZER; + + #ifdef DEBUG_YIELD + unsigned int yield_active; +-unsigned int __thread rand_yield; ++TLS_DEFINE(unsigned int, get_rand_yield, _rand_yield); + #endif + + /* +@@ -109,7 +111,7 @@ long rcu_gp_ctr = RCU_GP_COUNT; + * Pointer to registry elements. Written to only by each individual reader. Read + * by both the reader and the writers. + */ +-struct rcu_reader __thread *rcu_reader; ++TLS_DEFINE(struct rcu_reader*, rcu_reader, _rcu_reader); + + static CDS_LIST_HEAD(registry); + +@@ -322,7 +324,7 @@ static void add_thread(void) + rcu_reader_reg->tid = pthread_self(); + assert(rcu_reader_reg->ctr == 0); + cds_list_add(&rcu_reader_reg->node, ®istry); +- rcu_reader = rcu_reader_reg; ++ *rcu_reader() = rcu_reader_reg; + } + + /* Called with signals off and mutex locked */ +@@ -363,7 +365,7 @@ void rcu_bp_register(void) + /* + * Check if a signal concurrently registered our thread since + * the check in rcu_read_lock(). */ +- if (rcu_reader) ++ if (*rcu_reader()) + goto end; + + mutex_lock(&rcu_gp_lock); +diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h +index 36e3cf4..27cb1ac 100644 +--- a/urcu-call-rcu-impl.h ++++ b/urcu-call-rcu-impl.h +@@ -4,6 +4,7 @@ + * Userspace RCU library - batch memory reclamation with kernel API + * + * Copyright (c) 2010 Paul E. McKenney <paulmck@linux.vnet.ibm.com> ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -61,8 +62,31 @@ struct call_rcu_data { + CDS_LIST_HEAD(call_rcu_data_list); + + /* Link a thread using call_rcu() to its call_rcu thread. */ +- ++#ifdef TLS + static __thread struct call_rcu_data *thread_call_rcu_data; ++#else ++static pthread_key_t tls_tcrd_key; ++static pthread_once_t tls_tcrd_once = PTHREAD_ONCE_INIT; ++static void tls_tcrd_deinit() { ++ void *p = pthread_getspecific(tls_tcrd_key); ++ free(p); ++} ++static void tls_tcrd_init() { ++ (void)pthread_key_create(&tls_tcrd_key, tls_tcrd_deinit); ++ atexit(tls_tcrd_deinit); ++} ++static struct call_rcu_data **tls_thread_call_rcu_data() { ++ (void)pthread_once(&tls_tcrd_once, tls_tcrd_init); ++ struct call_rcu_data **r = pthread_getspecific(tls_tcrd_key); ++ if (r == NULL) { ++ r = malloc(sizeof(struct call_rcu_data *)); ++ *r = NULL; ++ (void)pthread_setspecific(tls_tcrd_key, r); ++ } ++ return r; ++} ++#define thread_call_rcu_data (*tls_thread_call_rcu_data()) ++#endif + + /* Guard call_rcu thread creation. */ + +diff --git a/urcu-defer-impl.h b/urcu-defer-impl.h +index 4d1ca5e..21c337d 100644 +--- a/urcu-defer-impl.h ++++ b/urcu-defer-impl.h +@@ -11,6 +11,7 @@ + * + * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -40,6 +41,7 @@ + #include <sys/time.h> + #include <unistd.h> + #include <stdint.h> ++#include <config.h> + + #include "urcu/futex.h" + +@@ -48,6 +50,7 @@ + #include <urcu/uatomic.h> + #include <urcu/list.h> + #include <urcu/system.h> ++#include <urcu/tls-compat.h> + + /* + * Number of entries in the per-thread defer queue. Must be power of 2. +@@ -130,7 +133,9 @@ static int32_t defer_thread_stop; + * Written to only by each individual deferer. Read by both the deferer and + * the reclamation tread. + */ +-static struct defer_queue __thread defer_queue; ++TLS_DEFINE_SIMPLE(struct defer_queue, get_defer_queue, defer_queue); ++#define _defer_queue (*get_defer_queue()) ++ + static CDS_LIST_HEAD(registry_defer); + static pthread_t tid_defer; + +@@ -245,12 +250,12 @@ static void _rcu_defer_barrier_thread(void) + { + unsigned long head, num_items; + +- head = defer_queue.head; +- num_items = head - defer_queue.tail; ++ head = _defer_queue.head; ++ num_items = head - _defer_queue.tail; + if (caa_unlikely(!num_items)) + return; + synchronize_rcu(); +- rcu_defer_barrier_queue(&defer_queue, head); ++ rcu_defer_barrier_queue(&_defer_queue, head); + } + + void rcu_defer_barrier_thread(void) +@@ -311,8 +316,8 @@ void _defer_rcu(void (*fct)(void *p), void *p) + * Head is only modified by ourself. Tail can be modified by reclamation + * thread. + */ +- head = defer_queue.head; +- tail = CMM_LOAD_SHARED(defer_queue.tail); ++ head = _defer_queue.head; ++ tail = CMM_LOAD_SHARED(_defer_queue.tail); + + /* + * If queue is full, or reached threshold. Empty queue ourself. +@@ -321,7 +326,7 @@ void _defer_rcu(void (*fct)(void *p), void *p) + if (caa_unlikely(head - tail >= DEFER_QUEUE_SIZE - 2)) { + assert(head - tail <= DEFER_QUEUE_SIZE); + rcu_defer_barrier_thread(); +- assert(head - CMM_LOAD_SHARED(defer_queue.tail) == 0); ++ assert(head - CMM_LOAD_SHARED(_defer_queue.tail) == 0); + } + + /* +@@ -340,25 +345,25 @@ void _defer_rcu(void (*fct)(void *p), void *p) + * Decode: see the comments before 'struct defer_queue' + * or the code in rcu_defer_barrier_queue(). + */ +- if (caa_unlikely(defer_queue.last_fct_in != fct ++ if (caa_unlikely(_defer_queue.last_fct_in != fct + || DQ_IS_FCT_BIT(p) + || p == DQ_FCT_MARK)) { +- defer_queue.last_fct_in = fct; ++ _defer_queue.last_fct_in = fct; + if (caa_unlikely(DQ_IS_FCT_BIT(fct) || fct == DQ_FCT_MARK)) { +- _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], ++ _CMM_STORE_SHARED(_defer_queue.q[head++ & DEFER_QUEUE_MASK], + DQ_FCT_MARK); +- _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], ++ _CMM_STORE_SHARED(_defer_queue.q[head++ & DEFER_QUEUE_MASK], + fct); + } else { + DQ_SET_FCT_BIT(fct); +- _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], ++ _CMM_STORE_SHARED(_defer_queue.q[head++ & DEFER_QUEUE_MASK], + fct); + } + } +- _CMM_STORE_SHARED(defer_queue.q[head++ & DEFER_QUEUE_MASK], p); ++ _CMM_STORE_SHARED(_defer_queue.q[head++ & DEFER_QUEUE_MASK], p); + cmm_smp_wmb(); /* Publish new pointer before head */ + /* Write q[] before head. */ +- CMM_STORE_SHARED(defer_queue.head, head); ++ CMM_STORE_SHARED(_defer_queue.head, head); + cmm_smp_mb(); /* Write queue head before read futex */ + /* + * Wake-up any waiting defer thread. +@@ -422,16 +427,16 @@ int rcu_defer_register_thread(void) + { + int was_empty; + +- assert(defer_queue.last_head == 0); +- assert(defer_queue.q == NULL); +- defer_queue.q = malloc(sizeof(void *) * DEFER_QUEUE_SIZE); +- if (!defer_queue.q) ++ assert(_defer_queue.last_head == 0); ++ assert(_defer_queue.q == NULL); ++ _defer_queue.q = malloc(sizeof(void *) * DEFER_QUEUE_SIZE); ++ if (!_defer_queue.q) + return -ENOMEM; + + mutex_lock_defer(&defer_thread_mutex); + mutex_lock_defer(&rcu_defer_mutex); + was_empty = cds_list_empty(®istry_defer); +- cds_list_add(&defer_queue.list, ®istry_defer); ++ cds_list_add(&_defer_queue.list, ®istry_defer); + mutex_unlock(&rcu_defer_mutex); + + if (was_empty) +@@ -446,10 +451,10 @@ void rcu_defer_unregister_thread(void) + + mutex_lock_defer(&defer_thread_mutex); + mutex_lock_defer(&rcu_defer_mutex); +- cds_list_del(&defer_queue.list); ++ cds_list_del(&_defer_queue.list); + _rcu_defer_barrier_thread(); +- free(defer_queue.q); +- defer_queue.q = NULL; ++ free(_defer_queue.q); ++ _defer_queue.q = NULL; + is_empty = cds_list_empty(®istry_defer); + mutex_unlock(&rcu_defer_mutex); + +diff --git a/urcu-qsbr.c b/urcu-qsbr.c +index 5530295..6eeb90c 100644 +--- a/urcu-qsbr.c ++++ b/urcu-qsbr.c +@@ -5,6 +5,7 @@ + * + * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -34,6 +35,7 @@ + #include <string.h> + #include <errno.h> + #include <poll.h> ++#include <config.h> + + #include "urcu/wfqueue.h" + #include "urcu/map/urcu-qsbr.h" +@@ -66,11 +68,11 @@ unsigned long rcu_gp_ctr = RCU_GP_ONLINE; + * Written to only by each individual reader. Read by both the reader and the + * writers. + */ +-struct rcu_reader __thread rcu_reader; ++TLS_DEFINE(struct rcu_reader, rcu_reader, _rcu_reader); + + #ifdef DEBUG_YIELD + unsigned int yield_active; +-unsigned int __thread rand_yield; ++TLS_DEFINE(unsigned int, get_rand_yield, _rand_yield); + #endif + + static CDS_LIST_HEAD(registry); +@@ -206,7 +208,7 @@ void synchronize_rcu(void) + { + unsigned long was_online; + +- was_online = rcu_reader.ctr; ++ was_online = rcu_reader()->ctr; + + /* All threads should read qparity before accessing data structure + * where new ptr points to. In the "then" case, rcu_thread_offline +@@ -269,7 +271,7 @@ void synchronize_rcu(void) + { + unsigned long was_online; + +- was_online = rcu_reader.ctr; ++ was_online = rcu_reader()->ctr; + + /* + * Mark the writer thread offline to make sure we don't wait for +@@ -326,11 +328,11 @@ void rcu_thread_online(void) + + void rcu_register_thread(void) + { +- rcu_reader.tid = pthread_self(); +- assert(rcu_reader.ctr == 0); ++ rcu_reader()->tid = pthread_self(); ++ assert(rcu_reader()->ctr == 0); + + mutex_lock(&rcu_gp_lock); +- cds_list_add(&rcu_reader.node, ®istry); ++ cds_list_add(&rcu_reader()->node, ®istry); + mutex_unlock(&rcu_gp_lock); + _rcu_thread_online(); + } +@@ -343,7 +345,7 @@ void rcu_unregister_thread(void) + */ + _rcu_thread_offline(); + mutex_lock(&rcu_gp_lock); +- cds_list_del(&rcu_reader.node); ++ cds_list_del(&rcu_reader()->node); + mutex_unlock(&rcu_gp_lock); + } + +diff --git a/urcu.c b/urcu.c +index ba013d9..69a8311 100644 +--- a/urcu.c ++++ b/urcu.c +@@ -5,6 +5,7 @@ + * + * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -35,6 +36,7 @@ + #include <string.h> + #include <errno.h> + #include <poll.h> ++#include <config.h> + + #include "urcu/wfqueue.h" + #include "urcu/map/urcu.h" +@@ -94,11 +96,11 @@ unsigned long rcu_gp_ctr = RCU_GP_COUNT; + * Written to only by each individual reader. Read by both the reader and the + * writers. + */ +-struct rcu_reader __thread rcu_reader; ++TLS_DEFINE(struct rcu_reader, rcu_reader, _rcu_reader); + + #ifdef DEBUG_YIELD + unsigned int yield_active; +-unsigned int __thread rand_yield; ++TLS_DEFINE(unsigned int, get_rand_yield, _rand_yield); + #endif + + static CDS_LIST_HEAD(registry); +@@ -120,9 +122,9 @@ static void mutex_lock(pthread_mutex_t *mutex) + perror("Error in pthread mutex lock"); + exit(-1); + } +- if (CMM_LOAD_SHARED(rcu_reader.need_mb)) { ++ if (CMM_LOAD_SHARED(rcu_reader()->need_mb)) { + cmm_smp_mb(); +- _CMM_STORE_SHARED(rcu_reader.need_mb, 0); ++ _CMM_STORE_SHARED(rcu_reader()->need_mb, 0); + cmm_smp_mb(); + } + poll(NULL,0,10); +@@ -368,20 +370,20 @@ void rcu_read_unlock(void) + + void rcu_register_thread(void) + { +- rcu_reader.tid = pthread_self(); +- assert(rcu_reader.need_mb == 0); +- assert(!(rcu_reader.ctr & RCU_GP_CTR_NEST_MASK)); ++ rcu_reader()->tid = pthread_self(); ++ assert(rcu_reader()->need_mb == 0); ++ assert(!(rcu_reader()->ctr & RCU_GP_CTR_NEST_MASK)); + + mutex_lock(&rcu_gp_lock); + rcu_init(); /* In case gcc does not support constructor attribute */ +- cds_list_add(&rcu_reader.node, ®istry); ++ cds_list_add(&rcu_reader()->node, ®istry); + mutex_unlock(&rcu_gp_lock); + } + + void rcu_unregister_thread(void) + { + mutex_lock(&rcu_gp_lock); +- cds_list_del(&rcu_reader.node); ++ cds_list_del(&rcu_reader()->node); + mutex_unlock(&rcu_gp_lock); + } + +@@ -405,7 +407,7 @@ static void sigrcu_handler(int signo, siginfo_t *siginfo, void *context) + * executed on. + */ + cmm_smp_mb(); +- _CMM_STORE_SHARED(rcu_reader.need_mb, 0); ++ _CMM_STORE_SHARED(rcu_reader()->need_mb, 0); + cmm_smp_mb(); + } + +diff --git a/urcu/map/urcu-bp.h b/urcu/map/urcu-bp.h +index 4abe8dc..f269135 100644 +--- a/urcu/map/urcu-bp.h ++++ b/urcu/map/urcu-bp.h +@@ -9,6 +9,7 @@ + * + * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * LGPL-compatible code should include this header with : + * +@@ -44,6 +45,7 @@ + #define rcu_exit rcu_exit_bp + #define synchronize_rcu synchronize_rcu_bp + #define rcu_reader rcu_reader_bp ++#define _rcu_reader _rcu_reader_bp + #define rcu_gp_ctr rcu_gp_ctr_bp + + #define get_cpu_call_rcu_data get_cpu_call_rcu_data_bp +diff --git a/urcu/map/urcu-qsbr.h b/urcu/map/urcu-qsbr.h +index 0d88d83..f947791 100644 +--- a/urcu/map/urcu-qsbr.h ++++ b/urcu/map/urcu-qsbr.h +@@ -9,6 +9,7 @@ + * + * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * LGPL-compatible code should include this header with : + * +@@ -47,6 +48,7 @@ + #define rcu_exit rcu_exit_qsbr + #define synchronize_rcu synchronize_rcu_qsbr + #define rcu_reader rcu_reader_qsbr ++#define _rcu_reader _rcu_reader_qsbr + #define rcu_gp_ctr rcu_gp_ctr_qsbr + + #define get_cpu_call_rcu_data get_cpu_call_rcu_data_qsbr +diff --git a/urcu/map/urcu.h b/urcu/map/urcu.h +index 3f436a7..a6d5c37 100644 +--- a/urcu/map/urcu.h ++++ b/urcu/map/urcu.h +@@ -9,6 +9,7 @@ + * + * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * LGPL-compatible code should include this header with : + * +@@ -75,6 +76,7 @@ + #define rcu_exit rcu_exit_memb + #define synchronize_rcu synchronize_rcu_memb + #define rcu_reader rcu_reader_memb ++#define _rcu_reader _rcu_reader_memb + #define rcu_gp_ctr rcu_gp_ctr_memb + + #define get_cpu_call_rcu_data get_cpu_call_rcu_data_memb +@@ -107,6 +109,7 @@ + #define rcu_exit rcu_exit_sig + #define synchronize_rcu synchronize_rcu_sig + #define rcu_reader rcu_reader_sig ++#define _rcu_reader _rcu_reader_sig + #define rcu_gp_ctr rcu_gp_ctr_sig + + #define get_cpu_call_rcu_data get_cpu_call_rcu_data_sig +@@ -139,6 +142,7 @@ + #define rcu_exit rcu_exit_mb + #define synchronize_rcu synchronize_rcu_mb + #define rcu_reader rcu_reader_mb ++#define _rcu_reader _rcu_reader_mb + #define rcu_gp_ctr rcu_gp_ctr_mb + + #define get_cpu_call_rcu_data get_cpu_call_rcu_data_mb +diff --git a/urcu/static/urcu-bp.h b/urcu/static/urcu-bp.h +index 8d22163..42e4b6e 100644 +--- a/urcu/static/urcu-bp.h ++++ b/urcu/static/urcu-bp.h +@@ -11,6 +11,7 @@ + * + * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -38,6 +39,7 @@ + #include <urcu/system.h> + #include <urcu/uatomic.h> + #include <urcu/list.h> ++#include <urcu/tls-compat.h> + + /* + * This code section can only be included in LGPL 2.1 compatible source code. +@@ -74,7 +76,9 @@ extern "C" { + #define MAX_SLEEP 50 + + extern unsigned int yield_active; +-extern unsigned int __thread rand_yield; ++TLS_DECLARE(unsigned int, get_rand_yield, _rand_yield); ++// Safe if rand_yield is not redefined ++#define rand_yield (*get_rand_yield()) + + static inline void debug_yield_read(void) + { +@@ -144,7 +148,7 @@ struct rcu_reader { + * Adds a pointer dereference on the read-side, but won't require to unregister + * the reader thread. + */ +-extern struct rcu_reader __thread *rcu_reader; ++TLS_DECLARE(struct rcu_reader*, rcu_reader, _rcu_reader); + + static inline int rcu_old_gp_ongoing(long *value) + { +@@ -166,24 +170,24 @@ static inline void _rcu_read_lock(void) + long tmp; + + /* Check if registered */ +- if (caa_unlikely(!rcu_reader)) ++ if (caa_unlikely(!*rcu_reader())) + rcu_bp_register(); + + cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ +- tmp = rcu_reader->ctr; ++ tmp = (*rcu_reader())->ctr; + /* + * rcu_gp_ctr is + * RCU_GP_COUNT | (~RCU_GP_CTR_PHASE or RCU_GP_CTR_PHASE) + */ + if (caa_likely(!(tmp & RCU_GP_CTR_NEST_MASK))) { +- _CMM_STORE_SHARED(rcu_reader->ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); ++ _CMM_STORE_SHARED((*rcu_reader())->ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); + /* + * Set active readers count for outermost nesting level before + * accessing the pointer. + */ + cmm_smp_mb(); + } else { +- _CMM_STORE_SHARED(rcu_reader->ctr, tmp + RCU_GP_COUNT); ++ _CMM_STORE_SHARED((*rcu_reader())->ctr, tmp + RCU_GP_COUNT); + } + } + +@@ -193,7 +197,7 @@ static inline void _rcu_read_unlock(void) + * Finish using rcu before decrementing the pointer. + */ + cmm_smp_mb(); +- _CMM_STORE_SHARED(rcu_reader->ctr, rcu_reader->ctr - RCU_GP_COUNT); ++ _CMM_STORE_SHARED((*rcu_reader())->ctr, (*rcu_reader())->ctr - RCU_GP_COUNT); + cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ + } + +diff --git a/urcu/static/urcu-qsbr.h b/urcu/static/urcu-qsbr.h +index 68bfc31..fac39a1 100644 +--- a/urcu/static/urcu-qsbr.h ++++ b/urcu/static/urcu-qsbr.h +@@ -11,6 +11,7 @@ + * + * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -42,6 +43,7 @@ + #include <urcu/uatomic.h> + #include <urcu/list.h> + #include <urcu/futex.h> ++#include <urcu/tls-compat.h> + + #ifdef __cplusplus + extern "C" { +@@ -74,7 +76,9 @@ extern "C" { + #define MAX_SLEEP 50 + + extern unsigned int yield_active; +-extern unsigned int __thread rand_yield; ++TLS_DECLARE(unsigned int, get_rand_yield, _rand_yield); ++// Safe if rand_yield is not redefined ++#define rand_yield (*get_rand_yield()) + + static inline void debug_yield_read(void) + { +@@ -128,7 +132,7 @@ struct rcu_reader { + pthread_t tid; + }; + +-extern struct rcu_reader __thread rcu_reader; ++TLS_DECLARE(struct rcu_reader, rcu_reader, _rcu_reader); + + extern int32_t gp_futex; + +@@ -137,8 +141,8 @@ extern int32_t gp_futex; + */ + static inline void wake_up_gp(void) + { +- if (caa_unlikely(_CMM_LOAD_SHARED(rcu_reader.waiting))) { +- _CMM_STORE_SHARED(rcu_reader.waiting, 0); ++ if (caa_unlikely(_CMM_LOAD_SHARED(rcu_reader()->waiting))) { ++ _CMM_STORE_SHARED(rcu_reader()->waiting, 0); + cmm_smp_mb(); + if (uatomic_read(&gp_futex) != -1) + return; +@@ -158,7 +162,7 @@ static inline int rcu_gp_ongoing(unsigned long *ctr) + + static inline void _rcu_read_lock(void) + { +- rcu_assert(rcu_reader.ctr); ++ rcu_assert(rcu_reader()->ctr); + } + + static inline void _rcu_read_unlock(void) +@@ -168,7 +172,7 @@ static inline void _rcu_read_unlock(void) + static inline void _rcu_quiescent_state(void) + { + cmm_smp_mb(); +- _CMM_STORE_SHARED(rcu_reader.ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); ++ _CMM_STORE_SHARED(rcu_reader()->ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); + cmm_smp_mb(); /* write rcu_reader.ctr before read futex */ + wake_up_gp(); + cmm_smp_mb(); +@@ -177,8 +181,8 @@ static inline void _rcu_quiescent_state(void) + static inline void _rcu_thread_offline(void) + { + cmm_smp_mb(); +- CMM_STORE_SHARED(rcu_reader.ctr, 0); +- cmm_smp_mb(); /* write rcu_reader.ctr before read futex */ ++ CMM_STORE_SHARED(rcu_reader()->ctr, 0); ++ cmm_smp_mb(); /* write _rcu_reader.ctr before read futex */ + wake_up_gp(); + cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ + } +@@ -186,7 +190,7 @@ static inline void _rcu_thread_offline(void) + static inline void _rcu_thread_online(void) + { + cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ +- _CMM_STORE_SHARED(rcu_reader.ctr, CMM_LOAD_SHARED(rcu_gp_ctr)); ++ _CMM_STORE_SHARED(rcu_reader()->ctr, CMM_LOAD_SHARED(rcu_gp_ctr)); + cmm_smp_mb(); + } + +diff --git a/urcu/static/urcu.h b/urcu/static/urcu.h +index 7ae0185..302404b 100644 +--- a/urcu/static/urcu.h ++++ b/urcu/static/urcu.h +@@ -11,6 +11,7 @@ + * + * Copyright (c) 2009 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> + * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. ++ * Copyright (C) 2012 Marek Vavrusa <marek.vavrusa@nic.cz>, CZ.NIC, z.s.p.o. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -33,6 +34,7 @@ + #include <pthread.h> + #include <unistd.h> + #include <stdint.h> ++#include <config.h> + + #include <urcu/compiler.h> + #include <urcu/arch.h> +@@ -40,6 +42,7 @@ + #include <urcu/uatomic.h> + #include <urcu/list.h> + #include <urcu/futex.h> ++#include <urcu/tls-compat.h> + + #ifdef __cplusplus + extern "C" { +@@ -121,7 +124,9 @@ extern "C" { + #endif + + extern unsigned int yield_active; +-extern unsigned int __thread rand_yield; ++TLS_DECLARE(unsigned int, get_rand_yield, _rand_yield); ++// Safe shortcut if rand_yield is not redefined ++#define rand_yield (*get_rand_yield()) + + static inline void debug_yield_read(void) + { +@@ -222,7 +227,7 @@ struct rcu_reader { + pthread_t tid; + }; + +-extern struct rcu_reader __thread rcu_reader; ++TLS_DECLARE(struct rcu_reader, rcu_reader, _rcu_reader); + + extern int32_t gp_futex; + +@@ -256,20 +261,20 @@ static inline void _rcu_read_lock(void) + unsigned long tmp; + + cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ +- tmp = rcu_reader.ctr; ++ tmp = rcu_reader()->ctr; + /* + * rcu_gp_ctr is + * RCU_GP_COUNT | (~RCU_GP_CTR_PHASE or RCU_GP_CTR_PHASE) + */ + if (caa_likely(!(tmp & RCU_GP_CTR_NEST_MASK))) { +- _CMM_STORE_SHARED(rcu_reader.ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); ++ _CMM_STORE_SHARED(rcu_reader()->ctr, _CMM_LOAD_SHARED(rcu_gp_ctr)); + /* + * Set active readers count for outermost nesting level before + * accessing the pointer. See smp_mb_master(). + */ + smp_mb_slave(RCU_MB_GROUP); + } else { +- _CMM_STORE_SHARED(rcu_reader.ctr, tmp + RCU_GP_COUNT); ++ _CMM_STORE_SHARED(rcu_reader()->ctr, tmp + RCU_GP_COUNT); + } + } + +@@ -277,19 +282,19 @@ static inline void _rcu_read_unlock(void) + { + unsigned long tmp; + +- tmp = rcu_reader.ctr; ++ tmp = rcu_reader()->ctr; + /* + * Finish using rcu before decrementing the pointer. + * See smp_mb_master(). + */ + if (caa_likely((tmp & RCU_GP_CTR_NEST_MASK) == RCU_GP_COUNT)) { + smp_mb_slave(RCU_MB_GROUP); +- _CMM_STORE_SHARED(rcu_reader.ctr, rcu_reader.ctr - RCU_GP_COUNT); ++ _CMM_STORE_SHARED(rcu_reader()->ctr, rcu_reader()->ctr - RCU_GP_COUNT); + /* write rcu_reader.ctr before read futex */ + smp_mb_slave(RCU_MB_GROUP); + wake_up_gp(); + } else { +- _CMM_STORE_SHARED(rcu_reader.ctr, rcu_reader.ctr - RCU_GP_COUNT); ++ _CMM_STORE_SHARED(rcu_reader()->ctr, rcu_reader()->ctr - RCU_GP_COUNT); + } + cmm_barrier(); /* Ensure the compiler does not reorder us with mutex */ + } +diff --git a/urcu/tls-compat.h b/urcu/tls-compat.h +new file mode 100644 +index 0000000..d47e803 +--- /dev/null ++++ b/urcu/tls-compat.h +@@ -0,0 +1,104 @@ ++/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> ++ ++ This program is free software: you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation, either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++#ifndef _TLS_COMPAT_H ++#define _TLS_COMPAT_H ++#include <config.h> ++ ++/* Conditional includes. */ ++#ifndef TLS ++#include <pthread.h> ++#endif ++ ++/*! ++ * \brief TLS variable declaration (requires TLS_DEFINITION in .c file) ++ * \param T declared type. ++ * \param name output function name. ++ * \param vname internal variable name. ++ * ++ * Output: function "T* name()". ++ * ++ * Example: ++ * TLS_DECLARE(int, a, _a); ++ * TLS_DEFINE(int, a, _a); ++ * *(a()) = 1 ++ */ ++#ifdef TLS ++ #define TLS_DECLARE(T, name, vname) \ ++ extern TLS T vname; \ ++ static inline T *name() { \ ++ return &vname;\ ++ } ++#else ++ #define TLS_DECLARE(T, name, vname) \ ++ T *name() ++#endif ++ ++/*! ++ * \brief TLS variable definition. ++ * \param T declared type. ++ * \param name output function name. ++ * \param vname internal variable name. ++ * ++ * Output: function "T* name()" or TLS variable "vname". ++ * Requires TLS_DECLARE for exported API. ++ */ ++#ifdef TLS ++#define TLS_DEFINE(T, name, vname) \ ++TLS T vname ++#else ++#define TLS_DEFINE(T, name, vname) \ ++static pthread_key_t tls_ ## name ## _key; \ ++static pthread_once_t tls_ ## name ## _once = PTHREAD_ONCE_INIT; \ ++static void tls_ ## name ## _deinit() { \ ++ free((void*)pthread_getspecific(tls_ ## name ## _key)); \ ++} \ ++static void tls_ ## name ## _init() { \ ++ (void)pthread_key_create(&tls_ ## name ## _key, tls_ ## name ## _deinit); \ ++ atexit(tls_ ## name ## _deinit); \ ++} \ ++T *name() { \ ++ (void)pthread_once(&tls_ ## name ## _once, tls_ ## name ## _init); \ ++ void *p = pthread_getspecific(tls_ ## name ## _key); \ ++ if (p == NULL) { \ ++ p = malloc(sizeof(T)); \ ++ memset(p, 0, sizeof(T)); \ ++ (void)pthread_setspecific(tls_ ## name ## _key, p); \ ++ } \ ++ return p; \ ++} ++#endif ++ ++/*! ++ * \brief TLS variable declaration+definition. ++ * \param T declared type. ++ * \param name output function name. ++ * \param vname internal variable name. ++ * ++ * Output: function "T* name()" or TLS variable "vname". ++ * Requires TLS_DECLARE for exported API. ++ */ ++#ifndef TLS ++#define TLS_DEFINE_SIMPLE(T, name, vname) \ ++TLS_DEFINE(T, name, vname) ++#else ++#define TLS_DEFINE_SIMPLE(T, name, vname) \ ++TLS_DEFINE(T, name, vname); \ ++static inline T *name() { \ ++ return &vname;\ ++} ++#endif ++ ++#endif // _TLS_COMPAT_H +-- +1.7.7.1 + diff --git a/src/common/acl.h b/src/common/acl.h index 1b7e97f..7303de8 100644 --- a/src/common/acl.h +++ b/src/common/acl.h @@ -75,7 +75,7 @@ void acl_delete(acl_t **acl); /*! * \brief Create new ACL rule. * - * \todo Support address subnets. + * \todo Support address subnets (issue #1366). * * \param acl Pointer to ACL instance. * \param addr IP address. diff --git a/src/common/evqueue.c b/src/common/evqueue.c index ca3027f..7614111 100644 --- a/src/common/evqueue.c +++ b/src/common/evqueue.c @@ -17,6 +17,84 @@ #include <string.h> #include <stdlib.h> #include <unistd.h> +#include <config.h> + +/* OpenBSD compatibility. */ +#ifndef HAVE_PSELECT +/* + * Like select(2) but set the signals to block while waiting in + * select. This version is not entirely race condition safe. Only + * operating system support can make it so. + * + * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include <sys/time.h> +#include <sys/types.h> +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif +#include <unistd.h> +#include <signal.h> + +static int +pselect (int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + const struct timespec *timeout, + const sigset_t *sigmask) +{ + int result; + sigset_t saved_sigmask; + struct timeval saved_timeout; + + if (sigmask && sigprocmask(SIG_SETMASK, sigmask, &saved_sigmask) == -1) + return -1; + + if (timeout) { + saved_timeout.tv_sec = timeout->tv_sec; + saved_timeout.tv_usec = timeout->tv_nsec / 1000; + result = select(n, readfds, writefds, exceptfds, &saved_timeout); + } else { + result = select(n, readfds, writefds, exceptfds, NULL); + } + + if (sigmask && sigprocmask(SIG_SETMASK, &saved_sigmask, NULL) == -1) + return -1; + + return result; +} + +#endif #include "common/evqueue.h" diff --git a/src/common/evsched.c b/src/common/evsched.c index c4a6786..067977f 100644 --- a/src/common/evsched.c +++ b/src/common/evsched.c @@ -17,9 +17,15 @@ #include <sys/time.h> #include <stdlib.h> #include <stdio.h> +#include <config.h> #include "common/evsched.h" +/*! \todo Fix properly (issue #1581). */ +#ifndef HAVE_PSELECT +#define OPENBSD_SLAB_BROKEN +#endif + /*! * \brief Set event timer to T (now) + dt miliseconds. */ @@ -60,7 +66,9 @@ evsched_t *evsched_new() pthread_mutex_init(&s->mx, 0); pthread_cond_init(&s->notify, 0); pthread_mutex_init(&s->cache.lock, 0); +#ifndef OPENBSD_SLAB_BROKEN slab_cache_init(&s->cache.alloc, sizeof(event_t)); +#endif init_list(&s->calendar); return s; } @@ -83,8 +91,10 @@ void evsched_delete(evsched_t **s) evsched_event_free((*s), (event_t*)n); } +#ifndef OPENBSD_SLAB_BROKEN /* Free allocator. */ slab_cache_destroy(&(*s)->cache.alloc); +#endif pthread_mutex_destroy(&(*s)->cache.lock); /* Free scheduler. */ @@ -99,9 +109,16 @@ event_t *evsched_event_new(evsched_t *s, int type) } /* Allocate. */ +#ifndef OPENBSD_SLAB_BROKEN pthread_mutex_lock(&s->cache.lock); event_t *e = slab_cache_alloc(&s->cache.alloc); pthread_mutex_unlock(&s->cache.lock); +#else + event_t *e = malloc(sizeof(event_t)); +#endif + if (e == NULL) { + return NULL; + } /* Initialize. */ memset(e, 0, sizeof(event_t)); @@ -115,9 +132,13 @@ void evsched_event_free(evsched_t *s, event_t *ev) return; } +#ifndef OPENBSD_SLAB_BROKEN pthread_mutex_lock(&s->cache.lock); slab_free(ev); pthread_mutex_unlock(&s->cache.lock); +#else + free(ev); +#endif } event_t* evsched_next(evsched_t *s) diff --git a/src/common/fdset.c b/src/common/fdset.c index 8c070ad..a281473 100644 --- a/src/common/fdset.c +++ b/src/common/fdset.c @@ -21,8 +21,22 @@ #include <dlfcn.h> #include <string.h> #include <stdio.h> -#include "common/fdset.h" +#include <time.h> +#include <stdlib.h> #include <config.h> +#include "common/fdset.h" + +/* Workarounds for clock_gettime() not available on some platforms. */ +#ifdef HAVE_CLOCK_GETTIME +#define time_now(x) clock_gettime(CLOCK_MONOTONIC, (x)) +typedef struct timespec timev_t; +#elif HAVE_GETTIMEOFDAY +#include <sys/time.h> +#define time_now(x) gettimeofday((x), NULL) +typedef struct timeval timev_t; +#else +#error Neither clock_gettime() nor gettimeofday() found. At least one is required. +#endif struct fdset_backend_t _fdset_backend = { }; @@ -78,3 +92,114 @@ void __attribute__ ((constructor)) fdset_init() fprintf(stderr, "fdset: fatal error - no valid fdset backend found\n"); return; } + +/*! + * \brief Compare file descriptors. + * + * \param a File descriptor. + * \param b File descriptor. + * + * \retval -1 if a < b + * \retval 0 if a == b + * \retval 1 if a > b + */ +static int fdset_compare(void *a, void *b) +{ + if ((size_t)a < (size_t)b) return -1; + if ((size_t)a > (size_t)b) return 1; + return 0; +} + +fdset_t *fdset_new() { + fdset_t* set = _fdset_backend.fdset_new(); + fdset_base_t *base = (fdset_base_t*)set; + if (base != NULL) { + /* Create atimes list. */ + base->atimes = skip_create_list(fdset_compare); + if (base->atimes == NULL) { + fdset_destroy(set); + set = NULL; + } + } + return set; +} + +int fdset_destroy(fdset_t* fdset) { + fdset_base_t *base = (fdset_base_t*)fdset; + if (base != NULL && base->atimes != NULL) { + skip_destroy_list(&base->atimes, NULL, free); + } + return _fdset_backend.fdset_destroy(fdset); +} + +int fdset_remove(fdset_t *fdset, int fd) { + fdset_base_t *base = (fdset_base_t*)fdset; + if (base != NULL && base->atimes != NULL) { + skip_remove(base->atimes, (void*)((size_t)fd), NULL, free); + } + return _fdset_backend.fdset_remove(fdset, fd); +} + +int fdset_set_watchdog(fdset_t* fdset, int fd, int interval) +{ + fdset_base_t *base = (fdset_base_t*)fdset; + if (base == NULL || base->atimes == NULL) { + return -1; + } + + /* Lift watchdog if interval is negative. */ + if (interval < 0) { + skip_remove(base->atimes, (void*)((size_t)fd), NULL, free); + return 0; + } + + /* Find if exists. */ + timev_t *ts = NULL; + ts = (timev_t*)skip_find(base->atimes, (void*)((size_t)fd)); + if (ts == NULL) { + ts = malloc(sizeof(timev_t)); + if (ts == NULL) { + return -1; + } + skip_insert(base->atimes, (void*)((size_t)fd), (void*)ts, NULL); + } + + /* Update clock. */ + if (time_now(ts) < 0) { + return -1; + } + + ts->tv_sec += interval; /* Only seconds precision. */ + return 0; +} + +int fdset_sweep(fdset_t* fdset, void(*cb)(fdset_t*, int)) +{ + fdset_base_t *base = (fdset_base_t*)fdset; + if (base == NULL || base->atimes == NULL) { + return -1; + } + + /* Get time threshold. */ + timev_t now; + if (time_now(&now) < 0) { + return -1; + } + + /* Inspect all nodes. */ + int sweeped = 0; + const skip_node_t *n = skip_first(base->atimes); + while (n != NULL) { + const skip_node_t* pnext = skip_next(n); + + /* Evaluate */ + timev_t *ts = (timev_t*)n->value; + if (ts->tv_sec <= now.tv_sec) { + cb(fdset, (int)(((ssize_t)n->key))); + ++sweeped; + } + n = pnext; + } + + return sweeped; +} diff --git a/src/common/fdset.h b/src/common/fdset.h index 10196bf..a40cb4a 100644 --- a/src/common/fdset.h +++ b/src/common/fdset.h @@ -21,8 +21,7 @@ * \brief Wrapper for native I/O multiplexing. * * Selects best implementation according to config. - * - select() - * - poll() \todo + * - poll() * - epoll() * - kqueue() * @@ -34,8 +33,28 @@ #define _KNOTD_FDSET_H_ #include <stddef.h> +#include "skip-list.h" -/*! \brief Opaque pointer to implementation-specific fdset data. */ +/*! \brief Waiting for completion constants. */ +enum fdset_wait_t { + OS_EV_FOREVER = -1, /*!< Wait forever. */ + OS_EV_NOWAIT = 0 /*!< Return immediately. */ +}; + +/*! \brief Base for implementation-specific fdsets. */ +typedef struct fdset_base_t { + skip_list_t *atimes; +} fdset_base_t; + +/*! + * \brief Opaque pointer to implementation-specific fdset data. + * \warning Implementation MUST have fdset_base_t member on the first place. + * Example: + * struct fdset_t { + * fdset_base_t base; + * ...other members... + * } + */ typedef struct fdset_t fdset_t; /*! \brief Unified event types. */ @@ -63,7 +82,7 @@ struct fdset_backend_t int (*fdset_destroy)(fdset_t*); int (*fdset_add)(fdset_t*, int, int); int (*fdset_remove)(fdset_t*, int); - int (*fdset_wait)(fdset_t*); + int (*fdset_wait)(fdset_t*, int); int (*fdset_begin)(fdset_t*, fdset_it_t*); int (*fdset_end)(fdset_t*, fdset_it_t*); int (*fdset_next)(fdset_t*, fdset_it_t*); @@ -84,9 +103,7 @@ extern struct fdset_backend_t _fdset_backend; * \retval Pointer to initialized FDSET structure if successful. * \retval NULL on error. */ -static inline fdset_t *fdset_new() { - return _fdset_backend.fdset_new(); -} +fdset_t *fdset_new(); /*! * \brief Destroy FDSET. @@ -94,9 +111,7 @@ static inline fdset_t *fdset_new() { * \retval 0 if successful. * \retval -1 on error. */ -static inline int fdset_destroy(fdset_t * fdset) { - return _fdset_backend.fdset_destroy(fdset); -} +int fdset_destroy(fdset_t* fdset); /*! * \brief Add file descriptor to watched set. @@ -122,22 +137,19 @@ static inline int fdset_add(fdset_t *fdset, int fd, int events) { * \retval 0 if successful. * \retval -1 on errors. */ -static inline int fdset_remove(fdset_t *fdset, int fd) { - return _fdset_backend.fdset_remove(fdset, fd); -} +int fdset_remove(fdset_t *fdset, int fd); /*! * \brief Poll set for new events. * * \param fdset Target set. + * \param timeout Timeout (OS_EV_FOREVER, OS_EV_NOWAIT or value in miliseconds). * * \retval Number of events if successful. * \retval -1 on errors. - * - * \todo Timeout. */ -static inline int fdset_wait(fdset_t *fdset) { - return _fdset_backend.fdset_wait(fdset); +static inline int fdset_wait(fdset_t *fdset, int timeout) { + return _fdset_backend.fdset_wait(fdset, timeout); } /*! @@ -191,6 +203,33 @@ static inline const char* fdset_method() { return _fdset_backend.fdset_method(); } +/*! + * \brief Set file descriptor watchdog interval. + * + * Descriptors without activity in given interval + * can be disposed with fdset_sweep(). + * + * \param fdset Target set. + * \param fd File descriptor. + * \param interval Allowed interval without activity (seconds). + * <0 removes watchdog interval. + * + * \retval 0 if successful. + * \retval -1 on errors. + */ +int fdset_set_watchdog(fdset_t* fdset, int fd, int interval); + +/*! + * \brief Sweep file descriptors with exceeding inactivity period. + * + * \param fdset Target set. + * \param cb Callback for sweeped descriptors. + * + * \retval number of sweeped descriptors. + * \retval -1 on errors. + */ +int fdset_sweep(fdset_t* fdset, void(*cb)(fdset_t* set, int fd)); + #endif /* _KNOTD_FDSET_H_ */ /*! @} */ diff --git a/src/common/fdset_epoll.c b/src/common/fdset_epoll.c index cb2e3e1..dbd803f 100644 --- a/src/common/fdset_epoll.c +++ b/src/common/fdset_epoll.c @@ -24,11 +24,13 @@ #include <unistd.h> #include "fdset_epoll.h" +#include "skip-list.h" #define OS_FDS_CHUNKSIZE 8 /*!< Number of pollfd structs in a chunk. */ #define OS_FDS_KEEPCHUNKS 32 /*!< Will attempt to free memory when reached. */ struct fdset_t { + fdset_base_t _base; int epfd; struct epoll_event *events; size_t nfds; @@ -40,7 +42,7 @@ fdset_t *fdset_epoll_new() { fdset_t *set = malloc(sizeof(fdset_t)); if (!set) { - return 0; + return NULL; } /* Blank memory. */ @@ -95,7 +97,7 @@ int fdset_epoll_add(fdset_t *fdset, int fd, int events) /* Add to epoll set. */ struct epoll_event ev; memset(&ev, 0, sizeof(struct epoll_event)); - ev.events = EPOLLIN; /*! \todo MAP events. */ + ev.events = EPOLLIN; ev.data.fd = fd; if (epoll_ctl(fdset->epfd, EPOLL_CTL_ADD, fd, &ev) < 0) { return -1; @@ -121,11 +123,11 @@ int fdset_epoll_remove(fdset_t *fdset, int fd) /* Overwrite current item. */ --fdset->nfds; - /*! \todo Return memory if overallocated (nfds is far lower than reserved). */ + /*! \todo Return memory if unused (issue #1582). */ return 0; } -int fdset_epoll_wait(fdset_t *fdset) +int fdset_epoll_wait(fdset_t *fdset, int timeout) { if (!fdset || fdset->nfds < 1 || !fdset->events) { return -1; @@ -133,7 +135,7 @@ int fdset_epoll_wait(fdset_t *fdset) /* Poll new events. */ fdset->polled = 0; - int nfds = epoll_wait(fdset->epfd, fdset->events, fdset->nfds, -1); + int nfds = epoll_wait(fdset->epfd, fdset->events, fdset->nfds, timeout); /* Check. */ if (nfds < 0) { @@ -173,7 +175,7 @@ int fdset_epoll_end(fdset_t *fdset, fdset_it_t *it) size_t nid = fdset->polled - 1; it->fd = fdset->events[nid].data.fd; it->pos = nid; - it->events = 0; /*! \todo Map events. */ + it->events = 0; return -1; } @@ -191,7 +193,7 @@ int fdset_epoll_next(fdset_t *fdset, fdset_it_t *it) /* Select next. */ size_t nid = it->pos++; it->fd = fdset->events[nid].data.fd; - it->events = 0; /*! \todo Map events. */ + it->events = 0; return 0; } diff --git a/src/common/fdset_epoll.h b/src/common/fdset_epoll.h index 551394d..58f25f8 100644 --- a/src/common/fdset_epoll.h +++ b/src/common/fdset_epoll.h @@ -74,13 +74,12 @@ int fdset_epoll_remove(fdset_t *fdset, int fd); * \brief Poll set for new events. * * \param fdset Target set. + * \param timeout Timeout (OS_EV_FOREVER, OS_EV_NOWAIT or value in miliseconds). * * \retval Number of events if successful. * \retval -1 on errors. - * - * \todo Timeout. */ -int fdset_epoll_wait(fdset_t *fdset); +int fdset_epoll_wait(fdset_t *fdset, int timeout); /*! * \brief Set event iterator to the beginning of last polled events. diff --git a/src/common/fdset_kqueue.c b/src/common/fdset_kqueue.c index c7199ae..bbb35fc 100644 --- a/src/common/fdset_kqueue.c +++ b/src/common/fdset_kqueue.c @@ -24,6 +24,7 @@ #include <unistd.h> #include <sys/event.h> #include <sys/time.h> +#include <time.h> #include "fdset_kqueue.h" @@ -31,6 +32,7 @@ #define OS_FDS_KEEPCHUNKS 32 /*!< Will attempt to free memory when reached. */ struct fdset_t { + fdset_base_t _base; int kq; struct kevent *events; struct kevent *revents; @@ -75,7 +77,7 @@ int fdset_kqueue_destroy(fdset_t * fdset) return 0; } -int fdset_kqueue_realloc(void **old, size_t oldsize, size_t nsize) +int fdset_kqueue_realloc(struct kevent **old, size_t oldsize, size_t nsize) { void *nmem = malloc(nsize); if (!nmem) { @@ -101,10 +103,10 @@ int fdset_kqueue_add(fdset_t *fdset, int fd, int events) /* Realloc needed. */ if (fdset->nfds == fdset->reserved) { - const size_t chunk = OS_FDS_CHUNKSIZE; - const size_t nsize = (fdset->reserved + chunk) * + size_t chunk = OS_FDS_CHUNKSIZE; + size_t nsize = (fdset->reserved + chunk) * sizeof(struct kevent); - const size_t oldsize = fdset->nfds * sizeof(struct kevent); + size_t oldsize = fdset->nfds * sizeof(struct kevent); if (fdset_kqueue_realloc(&fdset->events, oldsize, nsize) < 0) { return -1; @@ -117,7 +119,7 @@ int fdset_kqueue_add(fdset_t *fdset, int fd, int events) } /* Add to kqueue set. */ - int evfilt = EVFILT_READ; /*! \todo Map events. */ + int evfilt = EVFILT_READ; EV_SET(&fdset->events[fdset->nfds], fd, evfilt, EV_ADD|EV_ENABLE, 0, 0, 0); @@ -155,20 +157,33 @@ int fdset_kqueue_remove(fdset_t *fdset, int fd) /* Overwrite current item. */ --fdset->nfds; - /*! \todo Return memory if overallocated (nfds is far lower than reserved). */ + /*! \todo Return memory if unused (issue #1582). */ return 0; } -int fdset_kqueue_wait(fdset_t *fdset) +int fdset_kqueue_wait(fdset_t *fdset, int timeout) { if (!fdset || fdset->nfds < 1 || !fdset->events) { return -1; } + /* Set timeout. */ + struct timespec tmval; + struct timespec *tm = NULL; + if (timeout == 0) { + tmval.tv_sec = tmval.tv_nsec = 0; + tm = &tmval; + } else if (timeout > 0) { + tmval.tv_sec = timeout / 1000; /* ms -> s */ + timeout -= tmval.tv_sec * 1000; /* Cut off */ + tmval.tv_nsec = timeout * 1000000L; /* ms -> ns */ + tm = &tmval; + } + /* Poll new events. */ fdset->polled = 0; int nfds = kevent(fdset->kq, fdset->events, fdset->nfds, - fdset->revents, fdset->nfds, 0); + fdset->revents, fdset->nfds, tm); /* Check. */ if (nfds < 0) { diff --git a/src/common/fdset_kqueue.h b/src/common/fdset_kqueue.h index f64482f..4b650a7 100644 --- a/src/common/fdset_kqueue.h +++ b/src/common/fdset_kqueue.h @@ -74,13 +74,12 @@ int fdset_kqueue_remove(fdset_t *fdset, int fd); * \brief Poll set for new events. * * \param fdset Target set. + * \param timeout Timeout (OS_EV_FOREVER, OS_EV_NOWAIT or value in miliseconds). * * \retval Number of events if successful. * \retval -1 on errors. - * - * \todo Timeout. */ -int fdset_kqueue_wait(fdset_t *fdset); +int fdset_kqueue_wait(fdset_t *fdset, int timeout); /*! * \brief Set event iterator to the beginning of last polled events. diff --git a/src/common/fdset_poll.c b/src/common/fdset_poll.c index 8682eaf..02ed8d4 100644 --- a/src/common/fdset_poll.c +++ b/src/common/fdset_poll.c @@ -29,6 +29,7 @@ #define OS_FDS_KEEPCHUNKS 32 /*!< Will attempt to free memory when reached. */ struct fdset_t { + fdset_base_t _base; struct pollfd *fds; nfds_t nfds; size_t reserved; @@ -54,8 +55,6 @@ int fdset_poll_destroy(fdset_t * fdset) return -1; } - /*! \todo No teardown required I guess. */ - /* OK if NULL. */ free(fdset->fds); free(fdset); @@ -88,7 +87,7 @@ int fdset_poll_add(fdset_t *fdset, int fd, int events) /* Append. */ int nid = fdset->nfds++; fdset->fds[nid].fd = fd; - fdset->fds[nid].events = POLLIN; /*! \todo Map events to POLL events. */ + fdset->fds[nid].events = POLLIN; return 0; } @@ -119,12 +118,11 @@ int fdset_poll_remove(fdset_t *fdset, int fd) memmove(fdset->fds + pos, fdset->fds + (pos + 1), remaining); --fdset->nfds; - /*! \todo Return memory if overallocated (nfds is far lower than reserved). */ - /*! \todo Maybe >64 free chunks is excess? */ + /*! \todo Return memory if unused (issue #1582). */ return 0; } -int fdset_poll_wait(fdset_t *fdset) +int fdset_poll_wait(fdset_t *fdset, int timeout) { if (!fdset || fdset->nfds < 1 || !fdset->fds) { return -1; @@ -135,7 +133,7 @@ int fdset_poll_wait(fdset_t *fdset) fdset->begin = 0; /* Poll for events. */ - int ret = poll(fdset->fds, fdset->nfds, -1); + int ret = poll(fdset->fds, fdset->nfds, timeout); if (ret < 0) { return -1; } @@ -197,7 +195,7 @@ int fdset_poll_next(fdset_t *fdset, fdset_it_t *it) struct pollfd* pfd = fdset->fds + it->pos; if (pfd->events & pfd->revents) { it->fd = pfd->fd; - it->events = pfd->revents; /*! \todo MAP events. */ + it->events = pfd->revents; ++it->pos; /* Next will start after current. */ return 0; } diff --git a/src/common/fdset_poll.h b/src/common/fdset_poll.h index d72b5bb..68e9e69 100644 --- a/src/common/fdset_poll.h +++ b/src/common/fdset_poll.h @@ -74,13 +74,12 @@ int fdset_poll_remove(fdset_t *fdset, int fd); * \brief Poll set for new events. * * \param fdset Target set. + * \param timeout Timeout (OS_EV_FOREVER, OS_EV_NOWAIT or value in miliseconds). * * \retval Number of events if successful. * \retval -1 on errors. - * - * \todo Timeout. */ -int fdset_poll_wait(fdset_t *fdset); +int fdset_poll_wait(fdset_t *fdset, int timeout); /*! * \brief Set event iterator to the beginning of last polled events. diff --git a/src/common/prng.c b/src/common/prng.c index ca87b0d..250a506 100644 --- a/src/common/prng.c +++ b/src/common/prng.c @@ -20,6 +20,10 @@ #include <pthread.h> #include <time.h> #include <sys/time.h> +#include <config.h> +#ifdef HAVE_MEMALIGN +#include <malloc.h> +#endif #include "prng.h" #include "dSFMT.h" @@ -79,7 +83,11 @@ double tls_rand() } /* Initialize PRNG state. */ +#ifdef HAVE_MEMALIGN + s = memalign(16, sizeof(dsfmt_t)); +#else s = malloc(sizeof(dsfmt_t)); +#endif if (s == NULL) { fprintf(stderr, "error: PRNG: not enough memory\n"); return .0; @@ -87,6 +95,7 @@ double tls_rand() dsfmt_init_gen_rand(s, seed); (void)pthread_setspecific(tls_prng_key, s); } + } return dsfmt_genrand_close_open(s); diff --git a/src/common/slab/slab.c b/src/common/slab/slab.c index ccdf7ca..df30998 100644 --- a/src/common/slab/slab.c +++ b/src/common/slab/slab.c @@ -117,7 +117,6 @@ static unsigned SLAB_LOGSIZE = 0; /*!< \brief Binary logarithm of slab size. */ * from a slab with just a few slab items by caching N slabs before returning * them to the system. * - * \todo With wider use, locking or RCU will be necessary. */ #ifdef MEM_SLAB_DEPOT static slab_depot_t _depot_g; /*! \brief Global slab depot. */ @@ -339,7 +338,7 @@ slab_t* slab_create(slab_cache_t* cache) slab_t* slab = slab_depot_alloc(cache->bufsize); - if (unlikely(slab < 0)) { + if (unlikely(slab == 0)) { dbg_mem("%s: failed to allocate aligned memory block\n", __func__); return 0; @@ -677,7 +676,6 @@ void* slab_alloc_alloc(slab_alloc_t* alloc, size_t size) #ifdef MEM_POISON // Memory barrier - /*! \todo Broken, need to store the barrier byte size. */ //int* pb = (int*)((char*)mem + size - sizeof(int)); //mprotect(pb, sizeof(int), PROT_NONE); #endif diff --git a/src/common/slab/slab.h b/src/common/slab/slab.h index d64188e..4ea7e31 100644 --- a/src/common/slab/slab.h +++ b/src/common/slab/slab.h @@ -74,7 +74,7 @@ * * \todo Allocate slab headers elsewhere and use just first sizeof(void*) bytes * in each slab as a pointer to slab header. This could improve the - * performance. + * performance (issue #1583). * * \note Slab allocation is not thread safe for performance reasons. * @@ -336,7 +336,6 @@ void* slab_alloc_alloc(slab_alloc_t* alloc, size_t size); * \retval Pointer to newly allocated memory. * \retval NULL on error. * - * \todo Realloc could be probably implement more effectively. */ void *slab_alloc_realloc(slab_alloc_t* alloc, void *ptr, size_t size); diff --git a/src/config.h.in b/src/config.h.in index 8fe63ce..4761e6b 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -21,6 +21,12 @@ /* Define to 1 if you have the <arpa/nameser.h> header file. */ #undef HAVE_ARPA_NAMESER_H +/* Define to 1 if you have the <cap-ng.h> header file. */ +#undef HAVE_CAP_NG_H + +/* Define to 1 if you have the `clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H @@ -60,6 +66,9 @@ /* Define to 1 if you have the <malloc.h> header file. */ #undef HAVE_MALLOC_H +/* Define to 1 if you have the `memalign' function. */ +#undef HAVE_MEMALIGN + /* Define to 1 if you have the `memmove' function. */ #undef HAVE_MEMMOVE @@ -84,9 +93,15 @@ /* Define to 1 if you have the <netinet/in.h> header file. */ #undef HAVE_NETINET_IN_H +/* Define to 1 if you have the <netinet/in_systm.h> header file. */ +#undef HAVE_NETINET_IN_SYSTM_H + /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL +/* Define to 1 if you have the `pselect' function. */ +#undef HAVE_PSELECT + /* Define to 1 if you have the `regcomp' function. */ #undef HAVE_REGCOMP @@ -96,6 +111,12 @@ /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT +/* Define to 1 if you have the `sendmmsg' function. */ +#undef HAVE_SENDMMSG + +/* Define to 1 if you have the `setgroups' function. */ +#undef HAVE_SETGROUPS + /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET diff --git a/src/knot.init b/src/knot.init deleted file mode 100755 index 97194cd..0000000 --- a/src/knot.init +++ /dev/null @@ -1,70 +0,0 @@ -#! /bin/sh -# -# bird Starts the KNOT DNS daemon -# -# Author: Ondrej Feela Filip, <feela@network.cz> -# -# chkconfig: - 32 75 -# description: Authoritative DNS server -# -# processname: knotd -# config: /etc/knot/knot.conf - -exec="/usr/sbin/knotd" -prog="knot" -config="/etc/knot/knot.conf" -lockfile=/var/lock/subsys/$prog - - -# Source function library. -. /etc/rc.d/init.d/functions - -[ -f /etc/sysconfig/network ] || exit 0 - -. /etc/sysconfig/network - -RETVAL=0 -[ "$EUID" != "0" ] && exit 4 - -# See how we were called. -case "$1" in - start) - [ "$NETWORKING" = "no" ] && exit 1 - [ -x $exec ] || exit 5 - if [ ! -f $config ]; then - echo $"Configuration file $config missing" 1>&2 - exit 6 - fi - echo -n "Starting KNOT DNS daemon: " - daemon $exec -d - RETVAL=$? - echo - [ $RETVAL -eq 0 ] && touch $lockfile - ;; - stop) - echo -n "Stopping KNOT DNS daemon: " - killproc knotd - RETVAL=$? - echo - [ $RETVAL -eq 0 ] && rm -f $lockfile - - ;; - status) - status knotd - RETVAL=$? - ;; - restart) - $0 stop - $0 start - RETVAL=$? - ;; - reload) - knotc reload - RETVAL=$? - ;; - *) - echo "Usage: knot.init {start|stop|status|restart|reload}" - exit 1 -esac - -exit $RETVAL diff --git a/src/knot.service b/src/knot.service new file mode 100644 index 0000000..36864d0 --- /dev/null +++ b/src/knot.service @@ -0,0 +1,13 @@ +[Unit] +Description=Knot DNS daemon +After=syslog.target network.target auditd.service + +[Service] +EnvironmentFile=/etc/sysconfig/knot +ExecReload=/usr/sbin/knotc reload +ExecStart=/usr/sbin/knotd $KNOTARGS +Restart=on-abort + +[Install] +WantedBy=multi-user.target + diff --git a/src/knot.spec b/src/knot.spec index a3c430b..5856aab 100644 --- a/src/knot.spec +++ b/src/knot.spec @@ -1,27 +1,28 @@ Summary: KNOT DNS daemon Name: knot -Version: 0.8 +Version: 0.9.1 Release: 1 License: GPL Group: Networking/Daemons -Source: http://public.nic.cz/files/knot-dns/knot-0.8.tar.gz -Source1: knot.init -Buildroot: /var/tmp/knot-root +Source: http://public.nic.cz/files/knot-dns/knot-%{version}.tar.gz +Source1: %{name}.sysconfig +Source2: %{name}.service +Patch: %{name}.diff +Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-build Url: http://www.knot-dns.cz -#Prereq: /sbin/chkconfig -BuildRequires: flex userspace-rcu-devel openssl-devel +BuildRequires: flex userspace-rcu-devel openssl-devel bison %description KNOT DNS is a high-performance authoritative DNS server implementation. %prep %setup -n %{name}-%{version} -#%patch -p1 +%patch -p1 %build ./configure --prefix=%{_prefix} --sysconfdir=%{_sysconfdir}/%{name} --localstatedir=%{_var}/lib --libexecdir=%{_libexecdir}/%{name} -make -C samples knot.sample.conf +make -C samples %{name}.sample.conf make @@ -29,27 +30,62 @@ make rm -rf %{buildroot}/* make install prefix=%{buildroot}/%{_prefix} sysconfdir=%{buildroot}/%{_sysconfdir}/%{name} localstatedir=%{buildroot}/%{_var}/lib mandir=%{buildroot}/%{_mandir} libexecdir=%{buildroot}/%{_libexecdir}/%{name} -install -d %{buildroot}/%{_sysconfdir}/init.d -install $RPM_SOURCE_DIR/%{name}.init %{buildroot}/%{_sysconfdir}/init.d/%{name} +install -d %{buildroot}/%{_sysconfdir}/sysconfig +install $RPM_SOURCE_DIR/%{name}.sysconfig %{buildroot}/%{_sysconfdir}/sysconfig/%{name} install -d %{buildroot}/%{_var}/lib/%{name} +install -d %{buildroot}/lib/systemd/system/ +install $RPM_SOURCE_DIR/%{name}.service %{buildroot}/lib/systemd/system/%{name}.service %post -/sbin/ldconfig -/sbin/chkconfig --add %{name} - +# run after an installation +if [ $1 -eq 1 ] ; then + # Initial installation + /bin/systemctl daemon-reload >/dev/null 2>&1 || : +fi + %preun -if [ $1 = 0 ] ; then - /sbin/chkconfig --del %{name} -fi +# run before a package is removed +if [ $1 -eq 0 ]; then + /bin/systemctl --no-reload disable %{name}.service >/dev/null 2>&1 || : + /bin/systemctl stop %{name}.service > /dev/null 2>&1 || : +fi + +%postun +# run after a package is removed +/bin/systemctl daemon-reload >/dev/null 2>&1 || : +if [ $1 -ge 1 ]; then + /bin/systemctl try-restart %{name}.service >/dev/null 2>&1 || : +fi + +%triggerun -- knot < 0.9 +# Save the current service runlevel info +# User must manually run systemd-sysv-convert --apply %{name} +# to migrate them to systemd targets +/usr/bin/systemd-sysv-convert --save %{name} + +/sbin/chkconfig --del %{name} >/dev/null 2>&1 || : +/bin/systemctl try-restart %{name}.service >/dev/null 2>&1 || : +/bin/systemctl daemon-reload >/dev/null 2>&1 || : + + %files %defattr(-,root,root,-) %config %attr(644,root,root) %{_sysconfdir}/%{name}/* %{_sbindir}/* %{_libexecdir}/%{name}/* -%attr(755,root,root) %{_sysconfdir}/init.d/%{name} %dir %{_var}/lib/%{name}/ %doc %{_mandir}/man8/* +%attr(0644,root,root) /lib/systemd/system/%{name}.service +%config(noreplace) %{_sysconfdir}/sysconfig/%{name} + + %changelog +* Mon Jan 16 2012 - feela@network.cz +- Support for systemd. +- Specfile cleanup + +* Thu Nov 3 2011 - feela@network.cz +- Initial version diff --git a/src/knot.sysconfig b/src/knot.sysconfig new file mode 100644 index 0000000..99daeba --- /dev/null +++ b/src/knot.sysconfig @@ -0,0 +1,4 @@ +# Settings for the KNOT DNS daemon. +# KNOTARGS= : any extra command-line startup arguments for knot dns +KNOTARGS= + diff --git a/src/knot/conf/cf-lex.l b/src/knot/conf/cf-lex.l index 97ac8f8..6683edc 100644 --- a/src/knot/conf/cf-lex.l +++ b/src/knot/conf/cf-lex.l @@ -27,6 +27,20 @@ void switch_input(const char *str, void *scanner) yy_scan_string(str, scanner); } +/* Convert hex to binary. */ +static inline char xd(char d) { + if (d >= '0' && d <= '9') return d - '0'; + if (d >= 'a' && d <= 'f') return d - 'a' + 10; + if (d >= 'A' && d <= 'F') return d - 'A' + 10; + return 0; +} +int hex2bin(const char* src, char *dst, size_t len) { + for (unsigned i = 0; i < len; ++i) { + dst[i] = (xd(src[i<<1])<<4) + xd(src[(i<<1)+1]); + } + return 0; +} + //#define YY_INPUT(buf,result,max) result = cf_read_hook(buf, max); #define YY_NO_UNPUT @@ -56,6 +70,7 @@ BLANK [ \t\n] system { lval.t = yytext; return SYSTEM; } identity { lval.t = yytext; return IDENTITY; } version { lval.t = yytext; return VERSION; } +nsid { lval.t = yytext; return NSID; } storage { lval.t = yytext; return STORAGE; } key { lval.t = yytext; return KEY; } keys { lval.t = yytext; return KEYS; } @@ -73,10 +88,13 @@ xfr-out { lval.t = yytext; return XFR_OUT; } notify-in { lval.t = yytext; return NOTIFY_IN; } notify-out { lval.t = yytext; return NOTIFY_OUT; } workers { lval.t = yytext; return WORKERS; } +user { lval.t = yytext; return USER; } +pidfile { lval.t = yytext; return PIDFILE; } interfaces { lval.t = yytext; return INTERFACES; } address { lval.t = yytext; return ADDRESS; } port { lval.t = yytext; return PORT; } +via { lval.t = yytext; return VIA; } log { lval.t = yytext; return LOG; } @@ -191,6 +209,31 @@ on|off { #endif } +[0][x]{HEXA}+ { + lval.t = NULL; + lval.l = 0; + yytext = yytext + 2; /* Cut off 0x */ + size_t dlen = strlen(yytext); + if (dlen % 2 == 1) { + cf_error(yyscanner, "Invalid hex-string length."); + } else { + dlen = dlen / 2; + lval.t = malloc((dlen) * sizeof(char)); + if (lval.t == NULL) { + cf_error(yyscanner, "Out of memory when allocating hex-string.\n"); + } else { + memset(lval.t, 0, dlen); + if (hex2bin(yytext, lval.t, dlen) < 0) { + cf_error(yyscanner, "Failed to convert hex-string to binary.\n"); + } else { + lval.l = dlen; + } + } + } + + return HEXSTR; +} + gss-tsig { lval.alg = KNOT_TSIG_ALG_GSS_TSIG; return TSIG_ALGO_NAME; } hmac-md5 { lval.alg = KNOT_TSIG_ALG_HMAC_MD5; return TSIG_ALGO_NAME; } hmac-sha1 { lval.alg = KNOT_TSIG_ALG_HMAC_SHA1; return TSIG_ALGO_NAME; } diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y index 9939540..9d68d90 100644 --- a/src/knot/conf/cf-parse.y +++ b/src/knot/conf/cf-parse.y @@ -10,6 +10,8 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <pwd.h> +#include <grp.h> #include "libknot/dname.h" #include "knot/conf/conf.h" #include "libknotd_la-cf-parse.h" /* Automake generated header. */ @@ -30,7 +32,6 @@ static void conf_start_iface(char* ifname) this_iface = malloc(sizeof(conf_iface_t)); memset(this_iface, 0, sizeof(conf_iface_t)); this_iface->name = ifname; - this_iface->address = 0; // No default address (mandatory) this_iface->port = CONFIG_DEFAULT_PORT; add_tail(&new_config->ifaces, &this_iface->n); ++new_config->ifaces_count; @@ -41,12 +42,30 @@ static void conf_start_remote(char *remote) this_remote = malloc(sizeof(conf_iface_t)); memset(this_remote, 0, sizeof(conf_iface_t)); this_remote->name = remote; - this_remote->address = 0; // No default address (mandatory) - this_remote->port = 0; // Port wildcard add_tail(&new_config->remotes, &this_remote->n); ++new_config->remotes_count; } +static void conf_remote_set_via(void *scanner, char *item) { + /* Find existing node in remotes. */ + node* r = 0; conf_iface_t* found = 0; + WALK_LIST (r, new_config->ifaces) { + if (strcmp(((conf_iface_t*)r)->name, item) == 0) { + found = (conf_iface_t*)r; + break; + } + } + + /* Check */ + if (!found) { + char buf[512]; + snprintf(buf, sizeof(buf), "remote '%s' is not defined", item); + cf_error(scanner, buf); + } else { + this_remote->via = found; + } +} + static void conf_acl_item(void *scanner, char *item) { /* Find existing node in remotes. */ @@ -148,14 +167,17 @@ static int conf_key_add(void *scanner, knot_key_t **key, char *item) %token END INVALID_TOKEN %token <tok> TEXT +%token <tok> HEXSTR %token <tok> NUM %token <tok> INTERVAL %token <tok> SIZE %token <tok> BOOL -%token <tok> SYSTEM IDENTITY VERSION STORAGE KEY KEYS +%token <tok> SYSTEM IDENTITY VERSION NSID STORAGE KEY KEYS %token <tok> TSIG_ALGO_NAME %token <tok> WORKERS +%token <tok> USER +%token <tok> PIDFILE %token <tok> REMOTES @@ -173,6 +195,7 @@ static int conf_key_add(void *scanner, knot_key_t **key, char *item) %token <tok> INTERFACES ADDRESS PORT %token <tok> IPA %token <tok> IPA6 +%token <tok> VIA %token <tok> LOG %token <tok> LOG_DEST @@ -264,7 +287,10 @@ system: SYSTEM '{' | system VERSION TEXT ';' { new_config->version = $3.t; } | system IDENTITY TEXT ';' { new_config->identity = $3.t; } + | system NSID HEXSTR ';' { new_config->nsid = $3.t; new_config->nsid_len = $3.l; } + | system NSID TEXT ';' { new_config->nsid = $3.t; new_config->nsid_len = strlen(new_config->nsid); } | system STORAGE TEXT ';' { new_config->storage = $3.t; } + | system PIDFILE TEXT ';' { new_config->pidfile = $3.t; } | system KEY TSIG_ALGO_NAME TEXT ';' { fprintf(stderr, "warning: Config option 'system.key' is deprecated " "and has no effect.\n"); @@ -277,6 +303,30 @@ system: new_config->workers = $3.i; } } + | system USER TEXT ';' { + char buf[512]; + new_config->uid = new_config->gid = -1; // Invalidate + char* dpos = strchr($3.t, '.'); // Find uid.gid format + if (dpos != NULL) { + struct group *grp = getgrnam(dpos + 1); // Skip dot + if (grp != NULL) { + new_config->gid = grp->gr_gid; + } else { + snprintf(buf, sizeof(buf), "invalid group name '%s'", dpos + 1); + cf_error(scanner, buf); + } + *dpos = '\0'; // Cut off + } + struct passwd* pwd = getpwnam($3.t); + if (pwd != NULL) { + new_config->uid = pwd->pw_uid; + } else { + snprintf(buf, sizeof(buf), "invalid user name '%s'", $3.t); + cf_error(scanner, buf); + } + + free($3.t); + } ; keys: @@ -291,7 +341,6 @@ keys: char *fqdn = $2.t; size_t fqdnl = strlen(fqdn); if (fqdn[fqdnl - 1] != '.') { - /*! \todo Oddly, it requires memory aligned to 4B */ fqdnl = ((fqdnl + 2)/4+1)*4; /* '.', '\0' */ char* tmpdn = malloc(fqdnl); if (!tmpdn) { @@ -398,6 +447,14 @@ remote: } free($3.t); } + | remote VIA TEXT ';' { + if (this_remote->key != 0) { + cf_error(scanner, "only one 'via' definition is allowed in remote section\n"); + } else { + conf_remote_set_via(scanner, $3.t); + } + free($3.t); + } ; remotes: diff --git a/src/knot/conf/conf.c b/src/knot/conf/conf.c index 636901b..a382bba 100644 --- a/src/knot/conf/conf.c +++ b/src/knot/conf/conf.c @@ -166,7 +166,7 @@ static void zone_free(conf_zone_t *zone) * * This function is called automatically after config update. * - * \todo Selective hooks. + * \todo Selective hooks (issue #1583). */ static void conf_update_hooks(conf_t *conf) { @@ -201,10 +201,19 @@ static int conf_process(conf_t *conf) struct stat st; if (stat(conf->storage, &st) != 0) { rmkdir(conf->storage, S_IRWXU); + if (conf->uid >= 0) { + if (chown(conf->storage, conf->uid, conf->gid) < 0) { + log_server_warning("Could not change ownership" + " of '%s' to uid=%d.\n", + conf->storage, conf->uid); + } + } } // Create PID file - conf->pidfile = strcdup(conf->storage, "/" PID_FILE); + if (conf->pidfile == NULL) { + conf->pidfile = strcdup(conf->storage, "/" PID_FILE); + } // Postprocess zones int ret = KNOTD_EOK; @@ -445,6 +454,8 @@ conf_t *conf_new(const char* path) c->notify_timeout = CONFIG_NOTIFY_TIMEOUT; c->dbsync_timeout = CONFIG_DBSYNC_TIMEOUT; c->ixfr_fslimit = -1; + c->uid = -1; + c->gid = -1; return c; } @@ -513,7 +524,7 @@ void conf_truncate(conf_t *conf, int unload_hooks) // Unload hooks if (unload_hooks) { WALK_LIST_DELSAFE(n, nxt, conf->hooks) { - //! \todo call hook unload. + /*! \todo Call hook unload (issue #1583) */ free((conf_hook_t*)n); } conf->hooks_count = 0; @@ -573,6 +584,10 @@ void conf_truncate(conf_t *conf, int unload_hooks) free(conf->pidfile); conf->pidfile = 0; } + if (conf->nsid) { + free(conf->nsid); + conf->nsid = 0; + } } void conf_free(conf_t *conf) @@ -624,11 +639,9 @@ int conf_open(const char* path) } /* Check if exists. */ - FILE *fp = fopen(path, "r"); - if (fp == 0) { + struct stat st; + if (stat(path, &st) != 0) { return KNOTD_ENOENT; - } else { - fclose(fp); } /* Create new config. */ diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h index ef35e41..b5c1afa 100644 --- a/src/knot/conf/conf.h +++ b/src/knot/conf/conf.h @@ -59,6 +59,7 @@ typedef struct conf_iface_t { int port; /*!< Port number for this interface */ int family; /*!< Address family. */ knot_key_t *key; /*!< TSIG key (only valid for remotes). */ + struct conf_iface_t *via; /*!< Used for remotes to specify qry endpoint.*/ } conf_iface_t; /*! @@ -79,8 +80,6 @@ typedef struct conf_remote_t { * location on the disk. It also allows to have multiple DNS servers * as a source for the zone transfer and multiple DNS servers to allow * zone transfers. Same logic applies for the NOTIFY. - * - * \todo Missing XFR type (AXFR/IXFR/IXFR-ONLY) for each server. */ typedef struct conf_zone_t { node n; @@ -154,7 +153,11 @@ typedef struct conf_t { char *version; /*!< Version for CH TXT version.{bind|server} */ char *storage; /*!< Persistent storage path for databases and such. */ char *pidfile; /*!< PID file path. */ + char *nsid; /*!< Server's NSID. */ + size_t nsid_len;/*!< Server's NSID length. */ int workers; /*!< Number of workers per interface. */ + int uid; /*!< Specified user id. */ + int gid; /*!< Specified group id. */ /* * Log diff --git a/src/knot/ctl/knotc_main.c b/src/knot/ctl/knotc_main.c index f472303..f111f25 100644 --- a/src/knot/ctl/knotc_main.c +++ b/src/knot/ctl/knotc_main.c @@ -36,6 +36,20 @@ enum knotc_constants_t { WAITPID_TIMEOUT = 10 /*!< \brief Timeout for waiting for process. */ }; +/*! \brief Controller flags. */ +enum knotc_flag_t { + F_NULL = 0 << 0, + F_FORCE = 1 << 0, + F_VERBOSE = 1 << 1, + F_WAIT = 1 << 2, + F_INTERACTIVE = 1 << 3, + F_AUTO = 1 << 4 +}; + +static inline unsigned has_flag(unsigned flags, enum knotc_flag_t f) { + return flags & f; +} + /*! \brief Print help. */ void help(int argc, char **argv) { @@ -49,6 +63,7 @@ void help(int argc, char **argv) " -V, --version Print %s server version.\n" " -w, --wait Wait for the server to finish start/stop operations.\n" " -i, --interactive Interactive mode (do not daemonize).\n" + " -a, --auto Enable automatic recompilation (start or reload)." " -h, --help Print help and usage.\n", PACKAGE_NAME); printf("Actions:\n" @@ -243,16 +258,15 @@ int zctask_add(knotc_zctask_t *tasks, int count, pid_t pid, conf_zone_t *zone) * \param force True if forced operation is required. * \param wait Wait for the operation to finish. * \param interactive Interactive mode. + * \param automatic Automatic compilation. * \param jobs Number of parallel tasks to run. * \param pidfile Specified PID file for action. * * \retval 0 on success. * \retval error return code for main on error. - * - * \todo Make enumerated flags instead of many parameters... */ -int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, - int force, int wait, int interactive, int jobs, const char *pidfile) +int execute(const char *action, char **argv, int argc, pid_t pid, + unsigned flags, unsigned jobs, const char *pidfile) { int valid_cmd = 0; int rc = 0; @@ -270,7 +284,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, fprintf(stderr, "control: Server PID found, " "already running.\n"); - if (!force) { + if (!has_flag(flags, F_FORCE)) { return 1; } else { fprintf(stderr, "control: forcing " @@ -281,6 +295,12 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, } } + // Recompile zones if needed + if (has_flag(flags, F_AUTO)) { + rc = execute("compile", argv, argc, -1, flags, + jobs, pidfile); + } + // Lock configuration conf_read_lock(); @@ -288,10 +308,10 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, const char *cfg = conf()->filename; const char *args[] = { PROJECT_EXEC, - interactive ? "" : "-d", + has_flag(flags, F_INTERACTIVE) ? "" : "-d", cfg ? "-c" : "", cfg ? cfg : "", - verbose ? "-v" : "", + has_flag(flags, F_VERBOSE) ? "-v" : "", argc > 0 ? argv[0] : "" }; @@ -299,7 +319,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, conf_read_unlock(); // Execute command - if (interactive) { + if (has_flag(flags, F_INTERACTIVE)) { printf("control: Running in interactive mode.\n"); fflush(stderr); fflush(stdout); @@ -312,8 +332,8 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, fflush(stdout); // Wait for finish - if (wait && !interactive) { - if (verbose) { + if (has_flag(flags, F_WAIT) && !has_flag(flags, F_INTERACTIVE)) { + if (has_flag(flags, F_VERBOSE)) { fprintf(stdout, "control: waiting for server " "to load.\n"); } @@ -338,7 +358,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, fprintf(stderr, "Server PID not found, " "probably not running.\n"); - if (!force) { + if (!has_flag(flags, F_FORCE)) { rc = 1; } else { fprintf(stderr, "control: forcing " @@ -355,8 +375,8 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, } // Wait for finish - if (rc == 0 && wait) { - if (verbose) { + if (rc == 0 && has_flag(flags, F_WAIT)) { + if (has_flag(flags, F_VERBOSE)) { fprintf(stdout, "control: waiting for server " "to stop.\n"); } @@ -372,8 +392,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, } if (strcmp(action, "restart") == 0) { valid_cmd = 1; - execute("stop", argv, argc, pid, verbose, force, wait, - interactive, jobs, pidfile); + execute("stop", argv, argc, pid, flags, jobs, pidfile); int i = 0; while((pid = pid_read(pidfile)) > 0) { @@ -394,8 +413,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, } printf("Restarting server.\n"); - rc = execute("start", argv, argc, -1, verbose, force, wait, - interactive, jobs, pidfile); + rc = execute("start", argv, argc, -1, flags, jobs, pidfile); } if (strcmp(action, "reload") == 0) { @@ -405,7 +423,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, fprintf(stderr, "Server PID not found, " "probably not running.\n"); - if (force) { + if (has_flag(flags, F_FORCE)) { fprintf(stderr, "control: forcing " "server stop.\n"); } else { @@ -413,6 +431,12 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, } } + // Recompile zones if needed + if (has_flag(flags, F_AUTO)) { + rc = execute("compile", argv, argc, -1, flags, + jobs, pidfile); + } + // Stop if (kill(pid, SIGHUP) < 0) { pid_remove(pidfile); @@ -470,7 +494,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, printf("Zone '%s' is up-to-date.\n", zone->name); - if (force) { + if (has_flag(flags, F_FORCE)) { fprintf(stderr, "control: forcing " "zone recompilation.\n"); } else { @@ -492,7 +516,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, const char *args[] = { ZONEPARSER_EXEC, zone->enable_checks ? "-s" : "", - verbose ? "-v" : "", + has_flag(flags, F_VERBOSE) ? "-v" : "", "-o", zone->db, zone->name, @@ -500,7 +524,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, }; // Execute command - if (verbose) { + if (has_flag(flags, F_VERBOSE)) { printf("Compiling '%s' as '%s'...\n", zone->name, zone->db); } @@ -527,7 +551,7 @@ int execute(const char *action, char **argv, int argc, pid_t pid, int verbose, } // Log - if (verbose) { + if (has_flag(flags, F_VERBOSE)) { printf("'%s' finished (return code %d)\n", action, rc); } return rc; @@ -537,11 +561,8 @@ int main(int argc, char **argv) { // Parse command line arguments int c = 0, li = 0; - int force = 0; - int verbose = 0; - int wait = 0; - int interactive = 0; - int jobs = 1; + unsigned jobs = 1; + unsigned flags = F_NULL; const char* config_fn = 0; /* Long options. */ @@ -551,30 +572,23 @@ int main(int argc, char **argv) {"config", required_argument, 0, 'c'}, {"verbose", no_argument, 0, 'v'}, {"interactive", no_argument, 0, 'i'}, + {"auto", no_argument, 0, 'a'}, {"jobs", required_argument, 0, 'c'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, 'h'}, {0, 0, 0, 0} }; - while ((c = getopt_long(argc, argv, "wfc:vij:Vh", opts, &li)) != -1) { - switch (c) - { - case 'w': - wait = 1; - break; - case 'f': - force = 1; - break; + while ((c = getopt_long(argc, argv, "wfc:viaj:Vh", opts, &li)) != -1) { + switch (c) { + case 'w': flags |= F_WAIT; break; + case 'f': flags |= F_FORCE; break; + case 'v': flags |= F_VERBOSE; break; + case 'i': flags |= F_INTERACTIVE; break; + case 'a': flags |= F_AUTO; break; case 'c': config_fn = optarg; break; - case 'v': - verbose = 1; - break; - case 'i': - interactive = 1; - break; case 'j': jobs = atoi(optarg); if (jobs < 1) { @@ -616,9 +630,15 @@ int main(int argc, char **argv) } // Open configuration - if (conf_open(config_fn) != 0) { - fprintf(stderr, "Failed to parse configuration '%s'.\n", - config_fn); + int conf_ret = conf_open(config_fn); + if (conf_ret != KNOTD_EOK) { + if (conf_ret == KNOTD_ENOENT) { + fprintf(stderr, "Couldn't open configuration file " + "'%s'.\n", config_fn); + } else { + fprintf(stderr, "Failed to parse configuration '%s'.\n", + config_fn); + } free(default_fn); return 1; } @@ -627,9 +647,9 @@ int main(int argc, char **argv) free(default_fn); // Verbose mode - if (verbose) { - int mask = LOG_MASK(LOG_INFO)|LOG_MASK(LOG_DEBUG); - log_levels_add(LOGT_STDOUT, LOG_ANY, mask); + if (has_flag(flags, F_VERBOSE)) { + log_levels_add(LOGT_STDOUT, LOG_ANY, + LOG_MASK(LOG_INFO)|LOG_MASK(LOG_DEBUG)); } // Fetch PID @@ -648,7 +668,7 @@ int main(int argc, char **argv) // Execute action int rc = execute(action, argv + optind + 1, argc - optind - 1, - pid, verbose, force, wait, interactive, jobs, pidfile); + pid, flags, jobs, pidfile); // Finish free(pidfile); diff --git a/src/knot/main.c b/src/knot/main.c index d4e10b9..d4c6bca 100644 --- a/src/knot/main.c +++ b/src/knot/main.c @@ -19,15 +19,18 @@ #include <stdlib.h> #include <unistd.h> #include <getopt.h> -#include "common.h" +#ifdef HAVE_CAP_NG_H +#include <cap-ng.h> +#endif /* HAVE_CAP_NG_H */ +#include "common.h" +#include "common/evqueue.h" #include "knot/common.h" #include "knot/other/error.h" #include "knot/server/server.h" #include "knot/ctl/process.h" #include "knot/conf/conf.h" #include "knot/conf/logconf.h" -#include "common/evqueue.h" #include "knot/server/zones.h" /*----------------------------------------------------------------------------*/ @@ -127,6 +130,7 @@ int main(int argc, char **argv) sigemptyset(&emptyset.sa_mask); emptyset.sa_flags = 0; sigaction(SIGALRM, &emptyset, NULL); // Interrupt + sigaction(SIGPIPE, &emptyset, NULL); // Mask // Setup event queue evqueue_set(evqueue_new()); @@ -149,8 +153,8 @@ int main(int argc, char **argv) // Initialize configuration conf_read_lock(); conf_add_hook(conf(), CONF_LOG, log_conf_hook, 0); - conf_add_hook(conf(), CONF_LOG, zones_ns_conf_hook, server->nameserver); - conf_add_hook(conf(), CONF_LOG, server_conf_hook, server); + conf_add_hook(conf(), CONF_ALL, server_conf_hook, server); + conf_add_hook(conf(), CONF_ALL, zones_ns_conf_hook, server->nameserver); conf_read_unlock(); // Find implicit configuration file @@ -181,13 +185,55 @@ int main(int argc, char **argv) free(cwbuf); config_fn = abs_cfg; } + + /* POSIX 1003.1e capabilities. */ +#ifdef HAVE_CAP_NG_H + + /* Drop all capabilities. */ + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) { + capng_clear(CAPNG_SELECT_BOTH); + + + /* Retain ability to set capabilities and FS access. */ + capng_type_t tp = CAPNG_EFFECTIVE|CAPNG_PERMITTED; + capng_update(CAPNG_ADD, tp, CAP_SETPCAP); + capng_update(CAPNG_ADD, tp, CAP_DAC_OVERRIDE); + capng_update(CAPNG_ADD, tp, CAP_CHOWN); /* Storage ownership. */ + + /* Allow binding to privileged ports. + * (Not inheritable) + */ + capng_update(CAPNG_ADD, tp, CAP_NET_BIND_SERVICE); + + /* Allow setuid/setgid. */ + capng_update(CAPNG_ADD, tp, CAP_SETUID); + capng_update(CAPNG_ADD, tp, CAP_SETGID); + + /* Allow priorities changing. */ + capng_update(CAPNG_ADD, tp, CAP_SYS_NICE); + + /* Apply */ + if (capng_apply(CAPNG_SELECT_BOTH) < 0) { + log_server_error("Couldn't set process capabilities - " + "%s.\n", strerror(errno)); + } + } else { + log_server_info("User uid=%d is not allowed to set " + "capabilities, skipping.\n", getuid()); + } +#endif /* HAVE_CAP_NG_H */ // Open configuration - log_server_info("Parsing configuration '%s' ...\n", config_fn); - if (conf_open(config_fn) != KNOTD_EOK) { - - log_server_error("Failed to parse configuration file '%s'.\n", - config_fn); + log_server_info("Reading configuration '%s' ...\n", config_fn); + int conf_ret = conf_open(config_fn); + if (conf_ret != KNOTD_EOK) { + if (conf_ret == KNOTD_ENOENT) { + log_server_error("Couldn't open configuration file " + "'%s'.\n", config_fn); + } else { + log_server_error("Failed to parse configuration '%s'.\n", + config_fn); + } server_destroy(&server); free(config_fn); return 1; @@ -241,6 +287,7 @@ int main(int argc, char **argv) sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGHUP, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); sa.sa_flags = 0; pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL); @@ -251,10 +298,6 @@ int main(int argc, char **argv) pthread_sigmask(SIG_BLOCK, &sa.sa_mask, NULL); /* Interrupts. */ - /*! \todo More robust way to exit evloop. - * Event loop should exit with a special - * event. - */ if (sig_req_stop) { sig_req_stop = 0; server_stop(server); diff --git a/src/knot/other/debug.h b/src/knot/other/debug.h index 8b01c85..93b52fe 100644 --- a/src/knot/other/debug.h +++ b/src/knot/other/debug.h @@ -32,12 +32,12 @@ #include "knot/other/log.h" #include "common/print.h" -/*! \todo Set these during configure as well. */ +/*! \todo Set these during configure as well (issue #1585). */ //#define KNOTD_SERVER_DEBUG //#define KNOTD_THREADS_DEBUG //#define KNOTD_JOURNAL_DEBUG //#define KNOTD_NET_DEBUG -#define KNOTD_ZONES_DEBUG +//#define KNOTD_ZONES_DEBUG //#define KNOTD_XFR_DEBUG //#define KNOTD_NOTIFY_DEBUG //#define KNOTD_ZDUMP_DEBUG diff --git a/src/knot/other/log.c b/src/knot/other/log.c index 00bcea3..488763d 100644 --- a/src/knot/other/log.c +++ b/src/knot/other/log.c @@ -96,7 +96,6 @@ int log_init() log_levels_set(LOGT_STDERR, LOG_ANY, emask); log_levels_set(LOGT_STDOUT, LOG_ANY, imask); - /// \todo May change to LOG_DAEMON. setlogmask(LOG_UPTO(LOG_DEBUG)); openlog(PACKAGE_NAME, LOG_PID, LOG_DAEMON); return ret; diff --git a/src/knot/server/dthreads.c b/src/knot/server/dthreads.c index 9d1e69d..be6fc24 100644 --- a/src/knot/server/dthreads.c +++ b/src/knot/server/dthreads.c @@ -21,6 +21,9 @@ #include <stdio.h> #include <unistd.h> #include <errno.h> +#ifdef HAVE_CAP_NG_H +#include <cap-ng.h> +#endif /* HAVE_CAP_NG_H */ #include "knot/common.h" #include "knot/server/dthreads.h" @@ -120,9 +123,20 @@ static void *thread_ep(void *data) sigaddset(&ignset, SIGINT); sigaddset(&ignset, SIGTERM); sigaddset(&ignset, SIGHUP); - pthread_sigmask(SIG_BLOCK, &ignset, 0); /*! \todo Review under BSD. */ + sigaddset(&ignset, SIGPIPE); + pthread_sigmask(SIG_BLOCK, &ignset, 0); /*! \todo Review under BSD (issue #1441). */ dbg_dt("dthreads: [%p] entered ep\n", thread); + + /* Drop capabilities except FS access. */ +#ifdef HAVE_CAP_NG_H + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) { + capng_type_t tp = CAPNG_EFFECTIVE|CAPNG_PERMITTED; + capng_clear(CAPNG_SELECT_BOTH); + capng_update(CAPNG_ADD, tp, CAP_DAC_OVERRIDE); + capng_apply(CAPNG_SELECT_BOTH); + } +#endif /* HAVE_CAP_NG_H */ // Run loop for (;;) { @@ -176,7 +190,6 @@ static void *thread_ep(void *data) // Wait for notification from unit dbg_dt("dthreads: [%p] going idle\n", thread); - /*! \todo Check return value. */ pthread_cond_wait(&unit->_notify, &unit->_notify_mx); pthread_mutex_unlock(&unit->_notify_mx); dbg_dt("dthreads: [%p] resumed from idle\n", thread); @@ -961,7 +974,7 @@ int dt_optimal_size() } /*! - * \todo Use memory barriers or asynchronous read-only access, locking + * \note Use memory barriers or asynchronous read-only access, locking * poses a thread performance decrease by 1.31%. */ diff --git a/src/knot/server/journal.c b/src/knot/server/journal.c index 438332a..cd3e342 100644 --- a/src/knot/server/journal.c +++ b/src/knot/server/journal.c @@ -221,7 +221,7 @@ int journal_create(const char *fn, uint16_t max_nodes) journal_t* journal_open(const char *fn, size_t fslimit, uint16_t bflags) { - /*! \todo Memory mapping may be faster than stdio? */ + /*! \todo Memory mapping may be faster than stdio? (issue #964) */ /* File lock. */ struct flock fl; @@ -590,7 +590,7 @@ int journal_write(journal_t *journal, uint64_t id, const char *src, size_t size) return KNOTD_ERROR; } - /*! \todo Delayed write-back? */ + /*! \todo Delayed write-back? (issue #964) */ dbg_journal_verb("journal: write of finished, nqueue=<%u, %u>\n", journal->qhead, journal->qtail); diff --git a/src/knot/server/journal.h b/src/knot/server/journal.h index 321b591..564f0fe 100644 --- a/src/knot/server/journal.h +++ b/src/knot/server/journal.h @@ -77,7 +77,7 @@ typedef struct journal_node_t * Each journal has a fixed number of nodes. * * \todo Organize nodes in an advanced structure, like - * btree or hash table to improve lookup time. + * btree or hash table to improve lookup time (issue #964). */ typedef struct journal_t { diff --git a/src/knot/server/notify.h b/src/knot/server/notify.h index c1bebb8..a9ba807 100644 --- a/src/knot/server/notify.h +++ b/src/knot/server/notify.h @@ -47,6 +47,7 @@ typedef struct notify_ev_t { int retries; /*!< Number of retries. */ int msgid; /*!< ID of pending NOTIFY. */ sockaddr_t addr; /*!< Slave server address. */ + sockaddr_t saddr; /*!< Transit interface address. */ struct event_t *timer; /*!< Event timer. */ knot_zone_t *zone; /*!< Associated zone. */ } notify_ev_t; diff --git a/src/knot/server/server.c b/src/knot/server/server.c index 6b61d61..5e7b6e0 100644 --- a/src/knot/server/server.c +++ b/src/knot/server/server.c @@ -22,6 +22,7 @@ #include <errno.h> #include <openssl/evp.h> #include <assert.h> +#include <grp.h> #include "knot/common.h" #include "knot/other/error.h" @@ -152,12 +153,15 @@ static int server_init_iface(iface_t *new_if, conf_iface_t *cfg_if) new_if->type[UDP_ID] = cfg_if->family; /* Set socket options - voluntary. */ + char ebuf[512]; if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &snd_opt, sizeof(snd_opt)) < 0) { - // log_server_warning("Failed to configure socket " - // "write buffers.\n"); + strerror_r(errno, ebuf, sizeof(ebuf)); + log_server_warning("Failed to configure socket " + "write buffers: %s.\n", ebuf); } if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) { - // log_server_warning("Failed to configure socket read buffers.\n"); + strerror_r(errno, ebuf, sizeof(ebuf)); + log_server_warning("Failed to configure socket read buffers: %s.\n", ebuf); } /* Create TCP socket. */ @@ -207,7 +211,9 @@ static int server_init_iface(iface_t *new_if, conf_iface_t *cfg_if) */ static int server_bind_sockets(server_t *server) { - /*! \todo This requires locking to disable parallel updates. */ + /*! \todo This requires locking to disable parallel updates (issue #278). + * However, this is only used when RCU is read-locked, so count with that. + */ /* Lock configuration. */ conf_read_lock(); @@ -455,7 +461,9 @@ iohandler_t *server_create_handler(server_t *server, int fd, dt_unit_t *unit) } } - /*! \todo This requires either RCU compatible ptr swap or locking. */ + /*! \todo This requires locking to disable parallel updates (issue #278). + * However, this is only used when RCU is read-locked, so count with that. + */ /* Lock RCU. */ rcu_read_lock(); @@ -479,7 +487,9 @@ int server_remove_handler(server_t *server, iohandler_t *h) /* Lock RCU. */ rcu_read_lock(); - /*! \todo This requires either RCU compatible ptr swap or locking. */ + /*! \todo This requires locking to disable parallel updates (issue #278). + * However, this is only used when RCU is read-locked, so count with that. + */ // Remove node rem_node((node*)h); @@ -687,24 +697,61 @@ int server_conf_hook(const struct conf_t *conf, void *data) if ((ret = server_bind_sockets(server)) < 0) { log_server_error("Failed to bind configured " "interfaces.\n"); - return KNOTD_ERROR; + } else { + /* Update handlers. */ + if ((ret = server_bind_handlers(server)) < 0) { + log_server_error("Failed to create handlers for " + "configured interfaces.\n"); + } + } + + /* Lock configuration. */ + conf_read_lock(); + int priv_failed = 0; + +#ifdef HAVE_SETGROUPS + /* Drop supplementary groups. */ + if (conf->gid > -1 || conf->uid > -1) { + ret = setgroups(0, NULL); + + /* Collect results. */ + if (ret < 0) { + log_server_error("Failed to set supplementary groups " + "for uid=%d %s\n", + getuid(), strerror(errno)); + priv_failed = 1; + } + } +#endif + + /* Watch uid/gid. */ + if (conf->gid > -1 && conf->gid != getgid()) { + log_server_info("Changing group id to %d.\n", conf->gid); + if (setregid(conf->gid, conf->gid) < 0) { + log_server_error("Failed to change gid to %d.\n", + conf->gid); + priv_failed = 1; + } + } + if (conf->uid > -1 && conf->uid != getuid()) { + log_server_info("Changing user id to %d.\n", conf->uid); + if (setreuid(conf->uid, conf->uid) < 0) { + log_server_error("Failed to change uid to %d.\n", + conf->uid); + priv_failed = 1; + } } - /* Update handlers. */ - if ((ret = server_bind_handlers(server)) < 0) { - log_server_error("Failed to create handlers for " - "configured interfaces.\n"); - return ret; + if (priv_failed) { + ret = KNOTD_EACCES; } /* Exit if the server is not running. */ - if (!(server->state & ServerRunning)) { + if (ret != KNOTD_EOK || !(server->state & ServerRunning)) { + conf_read_unlock(); return KNOTD_ENOTRUNNING; } - /* Lock configuration. */ - conf_read_lock(); - /* Start new handlers. */ iohandler_t *h = 0; WALK_LIST(h, server->handlers) { diff --git a/src/knot/server/server.h b/src/knot/server/server.h index 480219b..b1358cd 100644 --- a/src/knot/server/server.h +++ b/src/knot/server/server.h @@ -165,8 +165,6 @@ int server_remove_handler(server_t *server, iohandler_t *ref); * \retval KNOTD_EOK on success. * \retval KNOTD_EINVAL on invalid parameters. * - * \todo When a module for configuration is added, the filename parameter will - * be removed. */ int server_start(server_t *server); diff --git a/src/knot/server/socket.c b/src/knot/server/socket.c index 67f4a5f..4deb862 100644 --- a/src/knot/server/socket.c +++ b/src/knot/server/socket.c @@ -22,7 +22,11 @@ #include <errno.h> #include <stdio.h> #include <netdb.h> +#include <time.h> #include <sys/socket.h> +#ifdef HAVE_NETINET_IN_SYSTM_H +#include <netinet/in_systm.h> +#endif #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> diff --git a/src/knot/server/socket.h b/src/knot/server/socket.h index dff5216..2185f03 100644 --- a/src/knot/server/socket.h +++ b/src/knot/server/socket.h @@ -39,7 +39,7 @@ /*! \brief Socket-related constants. */ typedef enum { - SOCKET_MTU_SZ = 8192, /*!< \todo Determine UDP MTU size. */ + SOCKET_MTU_SZ = 65535, /*!< Maximum MTU size. */ } socket_const_t; /*! diff --git a/src/knot/server/tcp-handler.c b/src/knot/server/tcp-handler.c index 71452e9..0af85a9 100644 --- a/src/knot/server/tcp-handler.c +++ b/src/knot/server/tcp-handler.c @@ -24,6 +24,9 @@ #include <string.h> #include <stdio.h> #include <stdlib.h> +#ifdef HAVE_CAP_NG_H +#include <cap-ng.h> +#endif /* HAVE_CAP_NG_H */ #include "common/sockaddr.h" #include "common/skip-list.h" @@ -35,8 +38,21 @@ #include "knot/server/zones.h" #include "libknot/nameserver/name-server.h" #include "knot/other/error.h" +#include "libknot/util/error.h" #include "libknot/util/wire.h" +/* Workarounds for clock_gettime() not available on some platforms. */ +#ifdef HAVE_CLOCK_GETTIME +#define time_now(x) clock_gettime(CLOCK_MONOTONIC, (x)) +typedef struct timespec timev_t; +#elif HAVE_GETTIMEOFDAY +#define time_now(x) gettimeofday((x), NULL) +typedef struct timeval timev_t; +#else +#error Neither clock_gettime() nor gettimeofday() found. At least one is required. +#endif + + /* Defines */ #define TCP_BUFFER_SIZE 65535 /*! Do not change, as it is used for maximum DNS/TCP packet size. */ @@ -63,7 +79,60 @@ static inline int tcp_throttle() { static int xfr_send_cb(int session, sockaddr_t *addr, uint8_t *msg, size_t msglen) { UNUSED(addr); - return tcp_send(session, msg, msglen); + int ret = tcp_send(session, msg, msglen); + if (ret < 0) { + return KNOT_ECONN; + } + + return ret; +} + +/*! \brief Send reply. */ +static int tcp_reply(int fd, uint8_t *qbuf, size_t resp_len) +{ + dbg_net("tcp: got answer of size %zd.\n", + resp_len); + + int res = 0; + if (resp_len > 0) { + res = tcp_send(fd, qbuf, resp_len); + } + + /* Check result. */ + if (res < 0 || (size_t)res != resp_len) { + dbg_net("tcp: %s: failed: %d - %d.\n", + "socket_send()", + res, errno); + } + + return res; +} + +/*! \brief Sweep TCP connection. */ +static void tcp_sweep(fdset_t *set, int fd) { + char r_addr[SOCKADDR_STRLEN] = { '\0' }; + int r_port = 0; + struct sockaddr_storage addr; + socklen_t len = sizeof(addr); + getpeername(fd, (struct sockaddr*)&addr, &len); + + /* Translate */ + if (addr.ss_family == AF_INET) { + struct sockaddr_in *s = (struct sockaddr_in *)&addr; + r_port = ntohs(s->sin_port); + inet_ntop(AF_INET, &s->sin_addr, r_addr, sizeof(r_addr)); + } else { +#ifndef DISABLE_IPV6 + struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; + r_port = ntohs(s->sin6_port); + inet_ntop(AF_INET6, &s->sin6_addr, r_addr, sizeof(r_addr)); +#endif + } + + log_server_notice("Connection with %s:%d was terminated due to " + "inactivity.\n", r_addr, r_port); + fdset_remove(set, fd); + close(fd); } /*! @@ -74,18 +143,17 @@ static int xfr_send_cb(int session, sockaddr_t *addr, uint8_t *msg, size_t msgle * \param w Associated I/O event. * \param revents Returned events. */ -static void tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxlen) +static int tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxlen) { if (fd < 0 || !w || !w->ioh) { dbg_net("tcp: tcp_handle(%p, %d) - invalid parameters\n", w, fd); - return; + return KNOTD_EINVAL; } dbg_net("tcp: handling TCP event on fd=%d in thread %p.\n", fd, (void*)pthread_self()); knot_nameserver_t *ns = w->ioh->server->nameserver; - xfrhandler_t *xfr_h = w->ioh->server->xfr_h; /* Check address type. */ sockaddr_t addr; @@ -93,7 +161,7 @@ static void tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxle log_server_error("Socket type %d is not supported, " "IPv6 support is probably disabled.\n", w->ioh->type); - return; + return KNOTD_ECONNREFUSED; } /* Receive data. */ @@ -102,7 +170,15 @@ static void tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxle dbg_net("tcp: client on fd=%d disconnected\n", fd); fdset_remove(w->fdset, fd); close(fd); - return; + if (n == KNOTD_EAGAIN) { + char r_addr[SOCKADDR_STRLEN]; + sockaddr_tostr(&addr, r_addr, sizeof(r_addr)); + int r_port = sockaddr_portnum(&addr); + log_server_warning("Couldn't receive query from %s:%d " + "within the time limit %ds.\n", + r_addr, r_port, TCP_ACTIVITY_WD); + } + return KNOTD_ECONNREFUSED; } /* Parse query. */ @@ -117,26 +193,25 @@ static void tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxle if (packet == NULL) { uint16_t pkt_id = knot_wire_get_id(qbuf); knot_ns_error_response(ns, pkt_id, KNOT_RCODE_SERVFAIL, - qbuf, &resp_len); - return; + qbuf, &resp_len); + tcp_reply(fd, qbuf, resp_len); + return KNOTD_EOK; } int res = knot_ns_parse_packet(qbuf, n, packet, &qtype); - if (unlikely(res != KNOTD_EOK)) { - - /* Send error response on dnslib RCODE. */ - if (res > 0) { + if (unlikely(res != KNOT_EOK)) { + if (res > 0) { /* Returned RCODE */ uint16_t pkt_id = knot_wire_get_id(qbuf); knot_ns_error_response(ns, pkt_id, res, - qbuf, &resp_len); + qbuf, &resp_len); + tcp_reply(fd, qbuf, resp_len); } - -// knot_response_free(&resp); knot_packet_free(&packet); - return; + return KNOTD_EOK; } /* Handle query. */ + int xfrt = -1; knot_ns_xfr_t xfr; res = KNOTD_ERROR; switch(qtype) { @@ -146,23 +221,16 @@ static void tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxle //res = knot_ns_answer_normal(ns, packet, qbuf, &resp_len); res = zones_normal_query_answer(ns, packet, &addr, qbuf, &resp_len); break; + case KNOT_QUERY_AXFR: case KNOT_QUERY_IXFR: - res = xfr_request_init(&xfr, XFR_TYPE_IOUT, XFR_FLAG_TCP, packet); - if (res != KNOTD_EOK) { - knot_ns_error_response(ns, knot_packet_id(packet), - KNOT_RCODE_SERVFAIL, qbuf, - &resp_len); - res = KNOTD_EOK; - break; + if (qtype == KNOT_QUERY_IXFR) { + xfrt = XFR_TYPE_IOUT; + } else { + xfrt = XFR_TYPE_AOUT; } - xfr.send = xfr_send_cb; - xfr.session = fd; - memcpy(&xfr.addr, &addr, sizeof(sockaddr_t)); - xfr_request(xfr_h, &xfr); - dbg_net("tcp: enqueued IXFR query on fd=%d\n", fd); - return; - case KNOT_QUERY_AXFR: - res = xfr_request_init(&xfr, XFR_TYPE_AOUT, XFR_FLAG_TCP, packet); + + /* Prepare context. */ + res = xfr_request_init(&xfr, xfrt, XFR_FLAG_TCP, packet); if (res != KNOTD_EOK) { knot_ns_error_response(ns, knot_packet_id(packet), KNOT_RCODE_SERVFAIL, qbuf, @@ -172,12 +240,13 @@ static void tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxle } xfr.send = xfr_send_cb; xfr.session = fd; + xfr.wire = qbuf; + xfr.wire_size = qbuf_maxlen; memcpy(&xfr.addr, &addr, sizeof(sockaddr_t)); - xfr_request(xfr_h, &xfr); - dbg_net("tcp: enqueued AXFR query on fd=%d\n", fd); - return; - /*! \todo Implement query notify/update. */ + /* Answer. */ + return xfr_answer(ns, &xfr); + case KNOT_QUERY_UPDATE: knot_ns_error_response(ns, knot_packet_id(packet), KNOT_RCODE_NOTIMPL, qbuf, @@ -185,8 +254,12 @@ static void tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxle res = KNOTD_EOK; break; + case KNOT_QUERY_NOTIFY: + res = notify_process_request(ns, packet, &addr, + qbuf, &resp_len); + break; + /* Unhandled opcodes. */ - case KNOT_QUERY_NOTIFY: /*!< Only in UDP. */ case KNOT_RESPONSE_NOTIFY: /*!< Only in UDP. */ case KNOT_RESPONSE_NORMAL: /*!< TCP handler doesn't send queries. */ case KNOT_RESPONSE_AXFR: /*!< Processed in XFR handler. */ @@ -210,25 +283,13 @@ static void tcp_handle(tcp_worker_t *w, int fd, uint8_t *qbuf, size_t qbuf_maxle /* Send answer. */ if (res == KNOTD_EOK) { - - dbg_net("tcp: got answer of size %zd.\n", - resp_len); - - assert(resp_len > 0); - res = tcp_send(fd, qbuf, resp_len); - - /* Check result. */ - if (res != (int)resp_len) { - dbg_net("tcp: %s: failed: %d - %d.\n", - "socket_send()", - res, errno); - } + tcp_reply(fd, qbuf, resp_len); } else { dbg_net("tcp: failed to respond to query type=%d on fd=%d - %s\n", qtype, fd, knotd_strerror(res));; } - return; + return KNOTD_EOK; } static int tcp_accept(int fd) @@ -239,6 +300,7 @@ static int tcp_accept(int fd) /* Evaluate connection. */ if (incoming < 0) { int en = errno; + /*! \todo Better solution so it doesn't block current connections (issue #1542). */ if (en != EINTR) { log_server_error("Cannot accept connection " "(%d).\n", errno); @@ -256,6 +318,13 @@ static int tcp_accept(int fd) } } else { dbg_net("tcp: accepted connection fd=%d\n", incoming); + /* Set recv() timeout. */ +#ifdef SO_RCVTIMEO + struct timeval tv; + tv.tv_sec = TCP_ACTIVITY_WD; + tv.tv_usec = 0; + setsockopt(incoming, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); +#endif } return incoming; @@ -347,7 +416,11 @@ int tcp_recv(int fd, uint8_t *buf, size_t len, sockaddr_t *addr) unsigned short pktsize = 0; int n = recv(fd, &pktsize, sizeof(unsigned short), MSG_WAITALL); if (n < 0) { - return KNOTD_ERROR; + if (errno == EAGAIN) { + return KNOTD_EAGAIN; + } else { + return KNOTD_ERROR; + } } pktsize = ntohs(pktsize); @@ -364,16 +437,22 @@ int tcp_recv(int fd, uint8_t *buf, size_t len, sockaddr_t *addr) if (len < pktsize) { return KNOTD_ENOMEM; } - - /* Receive payload. */ - n = recv(fd, buf, pktsize, MSG_WAITALL); - + /* Get peer name. */ if (addr) { socklen_t alen = addr->len; getpeername(fd, addr->ptr, &alen); } + /* Receive payload. */ + n = recv(fd, buf, pktsize, MSG_WAITALL); + if (n < 0) { + if (errno == EAGAIN) { + return KNOTD_EAGAIN; + } else { + return KNOTD_ERROR; + } + } dbg_net("tcp: received packet size=%d on fd=%d\n", n, fd); @@ -438,6 +517,19 @@ int tcp_loop_worker(dthread_t *thread) dbg_net("tcp: failed to allocate buffers for TCP worker\n"); return KNOTD_EINVAL; } + + /* Drop all capabilities on workers. */ +#ifdef HAVE_CAP_NG_H + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) { + capng_clear(CAPNG_SELECT_BOTH); + capng_apply(CAPNG_SELECT_BOTH); + } +#endif /* HAVE_CAP_NG_H */ + + /* Next sweep time. */ + timev_t next_sweep; + time_now(&next_sweep); + next_sweep.tv_sec += TCP_SWEEP_INTERVAL; /* Accept clients. */ dbg_net_verb("tcp: worker %p started\n", w); @@ -449,8 +541,8 @@ int tcp_loop_worker(dthread_t *thread) } /* Wait for events. */ - int nfds = fdset_wait(w->fdset); - if (nfds <= 0) { + int nfds = fdset_wait(w->fdset, (TCP_SWEEP_INTERVAL * 1000)/2); + if (nfds < 0) { continue; } @@ -459,7 +551,7 @@ int tcp_loop_worker(dthread_t *thread) w, nfds); fdset_it_t it; fdset_begin(w->fdset, &it); - while(1) { + while(nfds > 0) { /* Handle incoming clients. */ if (it.fd == w->pipe[0]) { @@ -472,9 +564,22 @@ int tcp_loop_worker(dthread_t *thread) "client %d\n", w, client); fdset_add(w->fdset, client, OS_EV_READ); + fdset_set_watchdog(w->fdset, client, + TCP_HANDSHAKE_WD); + dbg_net("tcp: watchdog for fd=%d set to %ds\n", + client, TCP_HANDSHAKE_WD); } else { /* Handle other events. */ - tcp_handle(w, it.fd, qbuf, TCP_BUFFER_SIZE); + int ret = tcp_handle(w, it.fd, qbuf, + TCP_BUFFER_SIZE); + if (ret == KNOTD_EOK) { + fdset_set_watchdog(w->fdset, it.fd, + TCP_ACTIVITY_WD); + dbg_net("tcp: watchdog for fd=%d " + "set to %ds\n", + it.fd, TCP_ACTIVITY_WD); + } + } /* Check if next exists. */ @@ -483,6 +588,15 @@ int tcp_loop_worker(dthread_t *thread) } } + /* Sweep inactive. */ + timev_t now; + if (time_now(&now) == 0) { + if (now.tv_sec >= next_sweep.tv_sec) { + fdset_sweep(w->fdset, &tcp_sweep); + memcpy(&next_sweep, &now, sizeof(next_sweep)); + next_sweep.tv_sec += TCP_SWEEP_INTERVAL; + } + } } /* Stop whole unit. */ diff --git a/src/knot/server/tcp-handler.h b/src/knot/server/tcp-handler.h index f5fd17a..ab6baab 100644 --- a/src/knot/server/tcp-handler.h +++ b/src/knot/server/tcp-handler.h @@ -24,8 +24,6 @@ * the worker threads ("buckets"). Each threads processes it's own * set of sockets, and eliminates mutual exclusion problem by doing so. * - * \todo Improve documentation of TCP pool API and use proper error codes. - * * \addtogroup server * @{ */ @@ -39,6 +37,11 @@ #include "knot/server/server.h" #include "knot/server/dthreads.h" +/* Constants */ +#define TCP_HANDSHAKE_WD 10 /* [secs] for connection to make a request.*/ +#define TCP_ACTIVITY_WD 60 /* [secs] of allowed inactivity between requests */ +#define TCP_SWEEP_INTERVAL 2 /* [secs] granularity of connection sweeping */ + /*! * \brief Send TCP message. * diff --git a/src/knot/server/udp-handler.c b/src/knot/server/udp-handler.c index b202669..60b0843 100644 --- a/src/knot/server/udp-handler.c +++ b/src/knot/server/udp-handler.c @@ -31,6 +31,9 @@ #include <string.h> #include <assert.h> #include <errno.h> +#ifdef HAVE_CAP_NG_H +#include <cap-ng.h> +#endif /* HAVE_CAP_NG_H */ #include "common/sockaddr.h" #include "knot/common.h" @@ -46,8 +49,12 @@ #include "knot/server/notify.h" /* Check for sendmmsg syscall. */ -#ifdef SYS_sendmmsg -#define ENABLE_SENDMMSG 1 +#ifdef HAVE_SENDMMSG + #define ENABLE_SENDMMSG 1 +#else + #ifdef SYS_sendmmsg + #define ENABLE_SENDMMSG 1 + #endif #endif /*! \brief Pointer to selected UDP master implementation. */ @@ -62,7 +69,12 @@ static int (*_udp_master)(dthread_t *, stat_t *) = 0; int udp_handle(int fd, uint8_t *qbuf, size_t qbuflen, size_t *resp_len, sockaddr_t* addr, knot_nameserver_t *ns) { - dbg_net("udp: fd=%d received %zd bytes.\n", fd, qbuflen); +#ifdef DEBUG_ENABLE_BRIEF + char strfrom[SOCKADDR_STRLEN]; + sockaddr_tostr(addr, strfrom, sizeof(strfrom)); + dbg_net("udp: fd=%d received %zd bytes from %s:%d.\n", fd, qbuflen, + strfrom, sockaddr_portnum(addr)); +#endif knot_packet_type_t qtype = KNOT_QUERY_NORMAL; *resp_len = SOCKET_MTU_SZ; @@ -81,11 +93,10 @@ int udp_handle(int fd, uint8_t *qbuf, size_t qbuflen, size_t *resp_len, int res = knot_ns_parse_packet(qbuf, qbuflen, packet, &qtype); if (unlikely(res != KNOTD_EOK)) { dbg_net("udp: failed to parse packet on fd=%d\n", fd); - /* Send error response on dnslib RCODE. */ - if (res > 0) { + if (res > 0) { /* Returned RCODE */ uint16_t pkt_id = knot_wire_get_id(qbuf); knot_ns_error_response(ns, pkt_id, res, - qbuf, resp_len); + qbuf, resp_len); } knot_packet_free(&packet); @@ -119,29 +130,12 @@ int udp_handle(int fd, uint8_t *qbuf, size_t qbuflen, size_t *resp_len, /* RFC1034, p.28 requires reliable transfer protocol. * Bind responds with FORMERR. */ - /*! \todo Draft exists for AXFR/UDP, but has not been standardized. */ + /*! \note Draft exists for AXFR/UDP, but has not been standardized. */ knot_ns_error_response(ns, knot_packet_id(packet), KNOT_RCODE_FORMERR, qbuf, resp_len); res = KNOTD_EOK; break; - -// /* Process AXFR over UDP. */ -// res = xfr_request_init(&xfr, XFR_TYPE_AOUT, XFR_FLAG_UDP, packet); -// if (res != KNOTD_EOK) { -// knot_ns_error_response(ns, knot_packet_id(packet), -// KNOT_RCODE_SERVFAIL, qbuf, -// resp_len); -// res = KNOTD_EOK; -// break; -// } -// xfr.send = xfr_send_udp; -// xfr.session = dup(fd); -// memcpy(&xfr.addr, addr, sizeof(sockaddr_t)); -// xfr_request(srv->xfr_h, &xfr); -// dbg_net("udp: enqueued AXFR query on fd=%d\n", xfr.session); -// *resp_len = 0; -// return KNOTD_EOK; case KNOT_QUERY_IXFR: /* According to RFC1035, respond with SOA. * Draft proposes trying to fit response into one packet, @@ -154,28 +148,11 @@ int udp_handle(int fd, uint8_t *qbuf, size_t qbuflen, size_t *resp_len, // res = knot_ns_answer_normal(ns, packet, qbuf, // resp_len); break; -// /* Process IXFR over UDP. */ -// res = xfr_request_init(&xfr, XFR_TYPE_IOUT, XFR_FLAG_UDP, packet); -// if (res != KNOTD_EOK) { -// knot_ns_error_response(ns, knot_packet_id(packet), -// KNOT_RCODE_SERVFAIL, qbuf, -// resp_len); -// res = KNOTD_EOK; -// break; -// } -// xfr.send = xfr_send_udp; -// xfr.session = dup(fd); -// memcpy(&xfr.addr, addr, sizeof(sockaddr_t)); -// xfr_request(srv->xfr_h, &xfr); -// dbg_net("udp: enqueued IXFR query on fd=%d\n", xfr.session); -// *resp_len = 0; -// return KNOTD_EOK; case KNOT_QUERY_NOTIFY: res = notify_process_request(ns, packet, addr, qbuf, resp_len); break; - /*! \todo Implement query notify/update. */ case KNOT_QUERY_UPDATE: dbg_net("udp: UPDATE query on fd=%d not implemented\n", fd); knot_ns_error_response(ns, knot_packet_id(packet), @@ -227,23 +204,13 @@ static inline int udp_master_recvfrom(dthread_t *thread, stat_t *thread_stat) int sock = dup(h->fd); uint8_t qbuf[SOCKET_MTU_SZ]; - struct msghdr msg; - memset(&msg, 0, sizeof(struct msghdr)); - struct iovec iov; - memset(&iov, 0, sizeof(struct iovec)); - iov.iov_base = qbuf; - iov.iov_len = SOCKET_MTU_SZ; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_name = addr.ptr; - msg.msg_namelen = addr.len; /* Loop until all data is read. */ ssize_t n = 0; while (n >= 0) { /* Receive packet. */ - n = recvmsg(sock, &msg, 0); + n = recvfrom(sock, qbuf, SOCKET_MTU_SZ, 0, addr.ptr, &addr.len); /* Cancellation point. */ if (dt_is_cancelled(thread)) { @@ -331,11 +298,13 @@ int udp_sendto(int sock, sockaddr_t * addrs, struct mmsghdr *msgs, size_t count) #ifdef ENABLE_SENDMMSG /*! \brief sendmmsg() syscall interface. */ +#ifndef HAVE_SENDMMSG static inline int sendmmsg(int fd, struct mmsghdr *mmsg, unsigned vlen, unsigned flags) { return syscall(SYS_sendmmsg, fd, mmsg, vlen, flags, NULL); } +#endif /*! * \brief Send multiple packets. @@ -509,6 +478,15 @@ int udp_master(dthread_t *thread) stat_t *thread_stat = 0; STAT_INIT(thread_stat); //XXX new stat instance every time. stat_set_protocol(thread_stat, stat_UDP); + + /* Drop all capabilities on workers. */ +#ifdef HAVE_CAP_NG_H + if (capng_have_capability(CAPNG_EFFECTIVE, CAP_SETPCAP)) { + capng_clear(CAPNG_SELECT_BOTH); + capng_apply(CAPNG_SELECT_BOTH); + } +#endif /* HAVE_CAP_NG_H */ + /* Execute proper handler. */ dbg_net_verb("udp: thread started (worker %p).\n", thread); diff --git a/src/knot/server/xfr-handler.c b/src/knot/server/xfr-handler.c index bc55434..fe7c0ab 100644 --- a/src/knot/server/xfr-handler.c +++ b/src/knot/server/xfr-handler.c @@ -60,6 +60,14 @@ static int xfr_udp_timeout(event_t *e) if (!data) { return KNOTD_EINVAL; } + + /* Remove reference to this event. */ + if (data->zone != NULL) { + zonedata_t *zd = (zonedata_t *)knot_zone_data(data->zone); + if (zd != NULL && zd->soa_pending == e) { + zd->soa_pending = NULL; + } + } sockaddr_update(&data->addr); char r_addr[SOCKADDR_STRLEN]; @@ -100,24 +108,17 @@ static int xfr_udp_timeout(event_t *e) */ static int xfr_process_udp_query(xfrworker_t *w, int fd, knot_ns_xfr_t *data) { - /* Prepare msg header. */ - struct msghdr msg; - memset(&msg, 0, sizeof(struct msghdr)); - struct iovec iov; - memset(&iov, 0, sizeof(struct iovec)); - iov.iov_base = data->wire; - iov.iov_len = data->wire_size; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_name = data->addr.ptr; - msg.msg_namelen = data->addr.len; - /* Receive msg. */ - ssize_t n = recvmsg(data->session, &msg, 0); + ssize_t n = recvfrom(data->session, data->wire, data->wire_size, 0, data->addr.ptr, &data->addr.len); size_t resp_len = data->wire_size; if (n > 0) { udp_handle(fd, data->wire, n, &resp_len, &data->addr, w->ns); } + + if(data->type == XFR_TYPE_SOA && data->zone) { + zonedata_t * zd = (zonedata_t*)knot_zone_data(data->zone); + zd->soa_pending = NULL; + } /* Disable timeout. */ evsched_t *sched = @@ -144,7 +145,7 @@ static int xfr_process_udp_query(xfrworker_t *w, int fd, knot_ns_xfr_t *data) return KNOTD_EOK; } -/*! \todo Document me. */ +/*! \todo Document me (issue #1586) */ static void xfr_free_task(knot_ns_xfr_t *task) { if (!task) { @@ -179,12 +180,11 @@ static void xfr_free_task(knot_ns_xfr_t *task) skip_remove(h->tasks, (void*)((size_t)task->session), 0, 0); pthread_mutex_unlock(&h->tasks_mx); - /*! \todo Free data. */ close(task->session); free(task); } -/*! \todo Document me. */ +/*! \todo Document me (issue #1586) */ static knot_ns_xfr_t *xfr_register_task(xfrworker_t *w, knot_ns_xfr_t *req) { knot_ns_xfr_t *t = malloc(sizeof(knot_ns_xfr_t)); @@ -223,13 +223,18 @@ static int xfr_xfrin_cleanup(xfrworker_t *w, knot_ns_xfr_t *data) switch(data->type) { case XFR_TYPE_AIN: if (data->data) { - xfrin_constructed_zone_t *constr_zone = + if (data->flags & XFR_FLAG_AXFR_FINISHED) { + knot_zone_contents_deep_free( + (knot_zone_contents_t **)&data->data, 0); + } else { + xfrin_constructed_zone_t *constr_zone = (xfrin_constructed_zone_t *)data->data; - knot_zone_contents_deep_free( - &(constr_zone->contents), 0); - xfrin_free_orphan_rrsigs(&(constr_zone->rrsigs)); - free(data->data); - data->data = 0; + knot_zone_contents_deep_free( + &(constr_zone->contents), 0); + xfrin_free_orphan_rrsigs(&(constr_zone->rrsigs)); + free(data->data); + data->data = 0; + } } break; case XFR_TYPE_IIN: @@ -306,12 +311,12 @@ static int xfr_xfrin_finalize(xfrworker_t *w, knot_ns_xfr_t *data) } else { /* Update zone. */ ret = zones_apply_changesets(data); - if (ret != KNOTD_EOK) { + if (ret != KNOT_EOK) { log_zone_error("IXFR failed to " "apply changesets to " "zone '%s/IN' - %s\n", zorigin, - knotd_strerror(ret)); + knot_strerror(ret)); } } /* Free changesets, but not the data. */ @@ -400,10 +405,6 @@ static int xfr_check_tsig(knot_ns_xfr_t *xfr, knot_rcode_t *rcode) log_server_info("Unsupported digest algorithm " "requested, treating as " "bad key.\n"); - /*! \todo [TSIG] It is unclear from RFC if I - * should treat is as a bad key - * or some other error. - */ *rcode = KNOT_RCODE_NOTAUTH; xfr->tsig_key = NULL; xfr->tsig_rcode = KNOT_TSIG_RCODE_BADKEY; @@ -419,7 +420,7 @@ static int xfr_check_tsig(knot_ns_xfr_t *xfr, knot_rcode_t *rcode) if (key && kname && knot_dname_compare(key->name, kname) == 0) { dbg_xfr("xfr: found claimed TSIG key for comparison\n"); } else { - /*! \todo These ifs are redundant. */ + /*! \todo These ifs are redundant (issue #1586) */ *rcode = KNOT_RCODE_NOTAUTH; /* TSIG is mandatory if configured for interface. */ if (key && !kname) { @@ -517,9 +518,23 @@ static int xfr_check_tsig(knot_ns_xfr_t *xfr, knot_rcode_t *rcode) */ int xfr_process_event(xfrworker_t *w, int fd, knot_ns_xfr_t *data, uint8_t *buf, size_t buflen) { + /* Fetch associated zone. */ + const char *zname = "<unknown>"; + knot_zone_t *zone = (knot_zone_t *)data->zone; + if (zone) { + zonedata_t *zd = (zonedata_t *)knot_zone_data(zone); + if (zd) { + zname = zd->conf->name; + } + } + /* Update xfer state. */ data->wire = buf; data->wire_size = buflen; + + char r_addr[SOCKADDR_STRLEN]; + sockaddr_tostr(&data->addr, r_addr, sizeof(r_addr)); + int r_port = sockaddr_portnum(&data->addr); /* Handle SOA/NOTIFY responses. */ if (data->type == XFR_TYPE_NOTIFY || data->type == XFR_TYPE_SOA) { @@ -551,7 +566,9 @@ int xfr_process_event(xfrworker_t *w, int fd, knot_ns_xfr_t *data, uint8_t *buf, /* AXFR-style IXFR. */ if (ret == KNOT_ENOIXFR) { - log_server_notice("IXFR/IN - Fallback to AXFR/IN.\n"); + log_server_notice("IXFR of '%s/IN' with %s:%d - " + "Fallback to AXFR/IN.\n", + zname, r_addr, r_port); assert(data->type == XFR_TYPE_IIN); data->type = XFR_TYPE_AIN; ret = knot_ns_process_axfrin(w->ns, data); @@ -567,10 +584,10 @@ int xfr_process_event(xfrworker_t *w, int fd, knot_ns_xfr_t *data, uint8_t *buf, } /* IXFR refused, try again with AXFR. */ - knot_zone_t *zone = (knot_zone_t *)data->zone; if (zone && data->type == XFR_TYPE_IIN && ret == KNOT_EXFRREFUSED) { - log_server_notice("IXFR/IN failed, attempting to use " - "AXFR/IN instead.\n"); + log_server_notice("IXFR of '%s/IN' with %s:%d failed, attempting " + "to use AXFR/IN instead.\n", + zname, r_addr, r_port); size_t bufsize = buflen; data->wire_size = buflen; /* Reset maximum bufsize */ ret = xfrin_create_axfr_query(zone->name, data, @@ -589,13 +606,17 @@ int xfr_process_event(xfrworker_t *w, int fd, knot_ns_xfr_t *data, uint8_t *buf, /* Handle errors. */ if (ret == KNOT_ENOXFR) { - log_server_warning("%cXFR/IN request finished - %s\n", + log_server_warning("%cXFR request of '%s/IN' with %s:%d " + "finished - %s\n", data->type == XFR_TYPE_AIN ? 'A' : 'I', + zname, r_addr, r_port, knot_strerror(ret)); } else if (ret < 0) { - log_server_error("%cXFR/IN request failed - %s\n", - data->type == XFR_TYPE_AIN ? 'A' : 'I', - knot_strerror(ret)); + log_server_error("%cXFR/IN request of '%s/IN' with %s:%d " + "failed - %s\n", + data->type == XFR_TYPE_AIN ? 'A' : 'I', + zname, r_addr, r_port, + knot_strerror(ret)); } @@ -605,7 +626,6 @@ int xfr_process_event(xfrworker_t *w, int fd, knot_ns_xfr_t *data, uint8_t *buf, knot_zone_t *zone = (knot_zone_t *)data->zone; zonedata_t *zd = (zonedata_t *)knot_zone_data(zone); - const char *zorigin = zd->conf->name; /* Only for successful xfers. */ if (ret > 0) { @@ -613,14 +633,14 @@ int xfr_process_event(xfrworker_t *w, int fd, knot_ns_xfr_t *data, uint8_t *buf, /* AXFR bootstrap timeout. */ rcu_read_lock(); - if (ret != KNOTD_EOK && data->type == XFR_TYPE_AIN) { + if (ret != KNOTD_EOK && !knot_zone_contents(zone)) { /* Schedule request (60 - 90s random delay). */ int tmr_s = AXFR_BOOTSTRAP_RETRY; tmr_s += (30.0 * 1000) * (tls_rand()); zd->xfr_in.bootstrap_retry = tmr_s; log_zone_info("Another attempt to AXFR bootstrap " "zone '%s' in %d seconds.\n", - zorigin, tmr_s/1000); + zname, tmr_s/1000); } rcu_read_unlock(); @@ -652,7 +672,7 @@ int xfr_process_event(xfrworker_t *w, int fd, knot_ns_xfr_t *data, uint8_t *buf, return result; } -/*! \todo Document me. +/*! \todo Document me (issue #1586) */ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data) { @@ -693,7 +713,14 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data) /* Connect to remote. */ if (data->session <= 0) { int fd = socket_create(data->addr.family, SOCK_STREAM); - if (fd < 0) { + if (fd >= 0) { + /* Bind to specific address - if set. */ + sockaddr_update(&data->saddr); + if (data->saddr.len > 0) { + /* Presume port is already preset. */ + ret = bind(fd, data->saddr.ptr, data->saddr.len); + } + } else { pthread_mutex_unlock(&zd->xfr_in.lock); log_server_warning("Failed to create socket " "(type=%s, family=%s).\n", @@ -702,6 +729,7 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data) "AF_INET" : "AF_INET6"); return KNOTD_ERROR; } + ret = connect(fd, data->addr.ptr, data->addr.len); if (ret < 0) { pthread_mutex_unlock(&zd->xfr_in.lock); @@ -722,7 +750,7 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data) "another attempt in %d seconds." "\n", tmr_s / 1000); } - return KNOTD_ERROR; + return KNOTD_ECONNREFUSED; } /* Store new socket descriptor. */ @@ -740,7 +768,7 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data) rcu_read_unlock(); log_server_warning("Failed start IXFR on zone with no " "contents\n"); - return KNOTD_ERROR; + return KNOTD_EINVAL; } /* Prepare TSIG key if set. */ @@ -791,6 +819,7 @@ static int xfr_client_start(xfrworker_t *w, knot_ns_xfr_t *data) ret = data->send(data->session, &data->addr, data->wire, bufsize); if (ret != bufsize) { + pthread_mutex_unlock(&zd->xfr_in.lock); log_server_notice("Failed to send %cXFR query.", data->type == XFR_TYPE_AIN ? 'A' : 'I'); xfr_free_task(task); @@ -819,6 +848,67 @@ static int xfr_fd_compare(void *k1, void *k2) return 0; } +static inline char xfr_strtype(knot_ns_xfr_t *xfr) { + if (xfr->type == XFR_TYPE_IOUT) { + return 'I'; + } else { + return 'A'; + } +} + +static int xfr_answer_axfr(knot_nameserver_t *ns, knot_ns_xfr_t *xfr) +{ + int ret = knot_ns_answer_axfr(ns, xfr); + dbg_xfr("xfr: ns_answer_axfr() = %d.\n", ret); + return ret; +} + +static int xfr_answer_ixfr(knot_nameserver_t *ns, knot_ns_xfr_t *xfr) +{ + /* Check serial differeces. */ + int ret = KNOT_EOK; + uint32_t serial_from = 0; + uint32_t serial_to = 0; + dbg_xfr_verb("Loading serials for IXFR.\n"); + ret = ns_ixfr_load_serials(xfr, &serial_from, &serial_to); + dbg_xfr_detail("Loaded serials: from: %u, to: %u\n", + serial_from, serial_to); + if (ret != KNOT_EOK) { + return ret; + } + + /* Load changesets from journal. */ + dbg_xfr_verb("Loading changesets from journal.\n"); + int chsload = zones_xfr_load_changesets(xfr, serial_from, serial_to); + if (chsload != KNOTD_EOK) { + /* History cannot be reconstructed, fallback to AXFR. */ + if (chsload == KNOTD_ERANGE || chsload == KNOTD_ENOENT) { + log_server_info("IXFR transfer of zone '%s/OUT'" + " - failed to load data from journal: " + " Incomplete history. " + "Fallback to AXFR.\n", + xfr->zname); + xfr->type = XFR_TYPE_AOUT; + return xfr_answer_axfr(ns, xfr); + } else if (chsload == KNOTD_EMALF) { + xfr->rcode = KNOT_RCODE_FORMERR; + } else { + xfr->rcode = KNOT_RCODE_SERVFAIL; + } + + /* Mark all as generic error. */ + ret = KNOT_ERROR; + } + + /* Finally, answer. */ + if (chsload == KNOTD_EOK) { + ret = knot_ns_answer_ixfr(ns, xfr); + dbg_xfr("xfr: ns_answer_ixfr() = %d.\n", ret); + } + + return ret; +} + /* * Public APIs. */ @@ -1014,12 +1104,113 @@ int xfr_request(xfrhandler_t *handler, knot_ns_xfr_t *req) return KNOTD_EOK; } +int xfr_answer(knot_nameserver_t *ns, knot_ns_xfr_t *xfr) +{ + if (ns == NULL || xfr == NULL) { + return KNOTD_EINVAL; + } + + int ret = knot_ns_init_xfr(ns, xfr); + int xfr_failed = (ret != KNOT_EOK); + const char * errstr = knot_strerror(ret); + + /* Check requested zone. */ + if (!xfr_failed) { + ret = zones_xfr_check_zone(xfr, &xfr->rcode); + xfr_failed = (ret != KNOTD_EOK); + errstr = knotd_strerror(ret); + } + + /* Check TSIG. */ + if (!xfr_failed && xfr->tsig_key != NULL) { + ret = xfr_check_tsig(xfr, &xfr->rcode); + xfr_failed = (ret != KNOT_EOK); + errstr = knot_strerror(ret); + } + + /* Prepare place for TSIG data */ + xfr->tsig_data = malloc(KNOT_NS_TSIG_DATA_MAX_SIZE); + if (xfr->tsig_data) { + dbg_xfr("xfr: TSIG data allocated: %zu.\n", + KNOT_NS_TSIG_DATA_MAX_SIZE); + xfr->tsig_data_size = 0; + } else { + dbg_xfr("xfr: failed to allocate TSIG data " + "buffer (%zu kB)\n", + KNOT_NS_TSIG_DATA_MAX_SIZE / 1024); + } + + // use the QNAME as the zone name to get names also for + // zones that are not in the server + const knot_dname_t *qname = knot_packet_qname(xfr->query); + if (qname != NULL) { + xfr->zname = knot_dname_to_str(qname); + } else { + xfr->zname = strdup("(unknown)"); + } + + /* Finally, answer AXFR/IXFR. */ + int io_error = 0; + if (!xfr_failed) { + switch(xfr->type) { + case XFR_TYPE_AOUT: + ret = xfr_answer_axfr(ns, xfr); + break; + case XFR_TYPE_IOUT: + ret = xfr_answer_ixfr(ns, xfr); + break; + default: ret = KNOTD_ENOTSUP; break; + } + + xfr_failed = (ret != KNOT_EOK); + errstr = knot_strerror(ret); + io_error = (ret == KNOT_ECONN); + } + + /* Remote address identification. */ + char r_addr[SOCKADDR_STRLEN]; + sockaddr_tostr(&xfr->addr, r_addr, sizeof(r_addr)); + int r_port = sockaddr_portnum(&xfr->addr); + + /* Check results. */ + if (xfr_failed) { + if (!io_error) { + knot_ns_xfr_send_error(ns, xfr, xfr->rcode); + } + log_server_notice("%cXFR transfer of zone '%s/OUT' " + "%s:%d failed: %s\n", + xfr_strtype(xfr) , xfr->zname, + r_addr, r_port, + errstr); + ret = KNOTD_ERROR; + } else { + log_server_info("%cXFR transfer of zone '%s/OUT' " + "to %s:%d successful.\n", + xfr_strtype(xfr), xfr->zname, + r_addr, r_port); + ret = KNOTD_EOK; + } + + /* Free allocated data. */ + free(xfr->tsig_data); + xfr->tsig_data = NULL; + + /* Cleanup. */ + free(xfr->digest); + free(xfr->query->wireformat); /* Free wireformat. */ + knot_packet_free(&xfr->query); /* Free query. */ + knot_packet_free(&xfr->response); /* Free response. */ + knot_free_changesets((knot_changesets_t **)(&xfr->data)); + free(xfr->zname); + return ret; +} + static int xfr_process_request(xfrworker_t *w, uint8_t *buf, size_t buflen) { /* Read single request. */ knot_ns_xfr_t xfr = {}; int ret = evqueue_read(w->q, &xfr, sizeof(knot_ns_xfr_t)); - if (ret != sizeof(knot_ns_xfr_t)) { + if (ret != sizeof(knot_ns_xfr_t)) { dbg_xfr_verb("xfr: evqueue_read() returned %d.\n", ret); return KNOTD_ENOTRUNNING; } @@ -1035,247 +1226,23 @@ static int xfr_process_request(xfrworker_t *w, uint8_t *buf, size_t buflen) conf_read_lock(); /* Handle request. */ + zonedata_t *zd = NULL; + if(xfr.zone != NULL) { + zd = (zonedata_t *)knot_zone_data(xfr.zone); + } knot_ns_xfr_t *task = 0; evsched_t *sch = 0; const char *req_type = ""; - knot_rcode_t rcode = 0; - char *zname = "(unknown)"; - uint32_t serial_from = 0; - uint32_t serial_to = 0; - - /* XFR request state tracking. */ - int init_failed = 0; - const char *errstr = ""; - const knot_dname_t *qname = NULL; - - dbg_xfr_verb("Query ptr: %p\n", xfr.query); - dbg_xfr_verb("xfr: processing request type '%d'\n", xfr.type); + dbg_xfr_verb("xfr: query ptr: %p\n", xfr.query); switch(xfr.type) { - case XFR_TYPE_AOUT: - req_type = "AXFR/OUT"; - ret = knot_ns_init_xfr(w->ns, &xfr); - init_failed = (ret != KNOT_EOK); - errstr = knot_strerror(ret); - - // use the QNAME as the zone name to get names also for - // zones that are not in the server - qname = knot_packet_qname(xfr.query); - if (qname != NULL) { - zname = knot_dname_to_str(qname); - } - - /* Check requested zone. */ - if (!init_failed) { - ret = zones_xfr_check_zone(&xfr, &rcode); - init_failed = (ret != KNOTD_EOK); - errstr = knotd_strerror(ret); - } - - /* Check TSIG. */ - if (!init_failed && xfr.tsig_key != NULL) { - ret = xfr_check_tsig(&xfr, &rcode); - init_failed = (ret != KNOT_EOK); - errstr = knot_strerror(ret); - } - - /* Evaluate progress and answer if passed. */ - if (init_failed) { - knot_ns_xfr_send_error(w->ns, &xfr, rcode); - socket_close(xfr.session); - log_server_notice("AXFR transfer of zone '%s/OUT' " - "%s:%d failed: %s\n", - zname, - r_addr, r_port, - errstr); - } else { - /* Prepare place for TSIG data */ - xfr.tsig_data = malloc(KNOT_NS_TSIG_DATA_MAX_SIZE); - if (xfr.tsig_data) { - dbg_xfr("xfr: TSIG data allocated: %zu.\n", - KNOT_NS_TSIG_DATA_MAX_SIZE); - xfr.tsig_data_size = 0; - } else { - dbg_xfr("xfr: failed to allocate TSIG data " - "buffer (%zu kB)\n", - KNOT_NS_TSIG_DATA_MAX_SIZE / 1024); - } - - ret = knot_ns_answer_axfr(w->ns, &xfr); - dbg_xfr("xfr: ns_answer_axfr() = %d.\n", ret); - if (ret != KNOTD_EOK) { - socket_close(xfr.session); - } else { - log_server_info("AXFR transfer of zone '%s/OUT' " - "to %s:%d successful.\n", - zname, - r_addr, r_port); - } - - /* Free allocated data. */ - free(xfr.tsig_data); - xfr.tsig_data = NULL; - } - - if (xfr.digest) { - free(xfr.digest); - xfr.digest_max_size = 0; - xfr.digest = 0; - } - free(xfr.query->wireformat); - xfr.query->wireformat = 0; - knot_packet_free(&xfr.query); /* Free query. */ - xfr.query = NULL; - knot_packet_free(&xfr.response); /* Free response. */ - xfr.response = NULL; - - if (qname != NULL) { - free(zname); - } - - break; - case XFR_TYPE_IOUT: - req_type = "IXFR/OUT"; - ret = knot_ns_init_xfr(w->ns, &xfr); - init_failed = (ret != KNOT_EOK); - errstr = knot_strerror(ret); - - qname = knot_packet_qname(xfr.query); - if (qname != NULL) { - zname = knot_dname_to_str(qname); - } - - /* Check requested zone. */ - if (!init_failed) { - ret = zones_xfr_check_zone(&xfr, &rcode); - init_failed = (ret != KNOTD_EOK); - errstr = knotd_strerror(ret); - } - - /* Check TSIG. */ - if (!init_failed && xfr.tsig_key != NULL) { - ret = xfr_check_tsig(&xfr, &rcode); - init_failed = (ret != KNOT_EOK); - errstr = knot_strerror(ret); - } - - // Check serial differeces - if (!init_failed) { - dbg_xfr_verb("Loading serials for IXFR.\n"); - ret = ns_ixfr_load_serials(&xfr, &serial_from, - &serial_to); - dbg_xfr_detail("Loaded serials: from: %u, to: %u\n", - serial_from, serial_to); - init_failed = (ret != KNOT_EOK); - errstr = knot_strerror(ret); - } - - /* Load changesets from journal. */ - if (!init_failed) { - dbg_xfr_verb("Loading changesets from journal.\n"); - ret = zones_xfr_load_changesets(&xfr, serial_from, - serial_to); - if (ret != KNOTD_EOK) { - /* History cannot be reconstructed, fallback to AXFR. */ - if (ret == KNOTD_ERANGE || ret == KNOTD_ENOENT) { - log_server_info("IXFR transfer of zone '%s/OUT'" - " - failed to load data from journal: %s." - " Fallback to AXFR.\n", - knotd_strerror(ret), zname); - xfr.type = XFR_TYPE_AOUT; - xfr_request(w->master, &xfr); - conf_read_unlock(); - return KNOTD_EOK; - } else if (ret == KNOTD_EMALF) { - rcode = KNOT_RCODE_FORMERR; - } else { - rcode = KNOT_RCODE_SERVFAIL; - } - init_failed = (ret != KNOTD_EOK); - errstr = knotd_strerror(ret); - } - } - - /* Evaluate progress and answer if passed. */ - if (init_failed) { - knot_ns_xfr_send_error(w->ns, &xfr, rcode); - log_server_notice("IXFR transfer of zone '%s/OUT' " - "%s:%d failed: %s\n", - zname, - r_addr, r_port, - errstr); - ret = KNOTD_ERROR; - } else { - /* Prepare place for TSIG data */ - xfr.tsig_data = malloc(KNOT_NS_TSIG_DATA_MAX_SIZE); - if (xfr.tsig_data) { - dbg_xfr("xfr: TSIG data allocated: %zu.\n", - KNOT_NS_TSIG_DATA_MAX_SIZE); - xfr.tsig_data_size = 0; - } else { - dbg_xfr("xfr: failed to allocate TSIG data " - "buffer (%zu kB)\n", - KNOT_NS_TSIG_DATA_MAX_SIZE / 1024); - } - - ret = knot_ns_answer_ixfr(w->ns, &xfr); - dbg_xfr("xfr: ns_answer_ixfr() = %d.\n", ret); - if (ret != KNOT_EOK) { - errstr = knot_strerror(ret); - log_server_notice("IXFR transfer of zone '%s/OUT' " - "%s:%d failed: %s\n", - zname, - r_addr, r_port, - errstr); - socket_close(xfr.session); - } else { - log_server_info("IXFR transfer of zone '%s/OUT' " - "to %s:%d successful.\n", - zname, - r_addr, r_port); - } - - /* Free allocated data. */ - free(xfr.tsig_data); - xfr.tsig_data = NULL; - } - - /* Cleanup. */ - if (xfr.digest) { - free(xfr.digest); - xfr.digest = NULL; - xfr.digest_max_size = 0; - } - free(xfr.query->wireformat); /* Free wireformat. */ - xfr.query->wireformat = NULL; - knot_packet_free(&xfr.query); /* Free query. */ - xfr.query = NULL; - knot_packet_free(&xfr.response); /* Free response. */ - xfr.response = NULL; - - if (xfr.data != NULL) { /* Free changesets. */ - knot_free_changesets((knot_changesets_t **) - (&xfr.data)); - } - - if (zname) { - free(zname); - } - - break; case XFR_TYPE_AIN: - req_type = "AXFR/IN"; - ret = xfr_client_start(w, &xfr); - - /* Report. */ - if (ret != KNOTD_EOK && ret != KNOTD_EACCES) { - log_server_error("%s request from %s:%d failed: %s\n", - req_type, r_addr, r_port, - knotd_strerror(ret)); - } - break; case XFR_TYPE_IIN: - req_type = "IXFR/IN"; + if (xfr.type == XFR_TYPE_IIN) { + req_type = "IXFR/IN"; + } else { + req_type = "AXFR/IN"; + } ret = xfr_client_start(w, &xfr); /* Report. */ @@ -1302,13 +1269,18 @@ static int xfr_process_request(xfrworker_t *w, uint8_t *buf, size_t buflen) sch = ((server_t *)knot_ns_get_data(w->ns))->sched; task->data = evsched_schedule_cb(sch, xfr_udp_timeout, task, SOA_QRY_TIMEOUT); + if (zd && xfr.type == XFR_TYPE_SOA) { + zd->soa_pending = (event_t*)task->data; + } ret = KNOTD_EOK; break; /* Socket close event. */ case XFR_TYPE_CLOSE: xfr_free_task((knot_ns_xfr_t *)xfr.data); ret = KNOTD_EOK; + break; default: + log_server_error("Unknown XFR request type (%d).\n", xfr.type); break; } @@ -1347,7 +1319,7 @@ int xfr_worker(dthread_t *thread) } /* Poll fdset. */ - int nfds = fdset_wait(w->fdset); + int nfds = fdset_wait(w->fdset, OS_EV_FOREVER); if (nfds <= 0) { continue; } diff --git a/src/knot/server/xfr-handler.h b/src/knot/server/xfr-handler.h index 3587d93..02eb189 100644 --- a/src/knot/server/xfr-handler.h +++ b/src/knot/server/xfr-handler.h @@ -31,7 +31,7 @@ #include "libknot/nameserver/name-server.h" #include "common/evqueue.h" #include "common/fdset.h" -#include "common/skip-list.h" /*!< \todo Consider another data struct. */ +#include "common/skip-list.h" struct xfrhandler_t; @@ -146,6 +146,18 @@ int xfr_request_init(knot_ns_xfr_t *r, int type, int flags, knot_packet_t *pkt); int xfr_request(xfrhandler_t *handler, knot_ns_xfr_t *req); /*! + * \brief Answer XFR query. + * + * \param ns Nameserver instance. + * \param req XFR request. + * + * \retval KNOTD_EOK on success. + * \retval KNOTD_EINVAL on NULL handler or request. + * \retval KNOTD_ERROR on error. + */ +int xfr_answer(knot_nameserver_t *ns, knot_ns_xfr_t *req); + +/*! * \brief XFR master runnable. * * Processes incoming AXFR/IXFR requests asynchonously. diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index 8616ebd..a196462 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -46,7 +46,6 @@ static const size_t XFRIN_CHANGESET_BINARY_STEP = 100; /*! * \brief Wrapper for TCP send. - * \todo Implement generic fd pool properly with callbacks. */ #include "knot/server/tcp-handler.h" static int zones_send_cb(int fd, sockaddr_t *addr, uint8_t *msg, size_t msglen) @@ -59,6 +58,10 @@ static int zones_send_cb(int fd, sockaddr_t *addr, uint8_t *msg, size_t msglen) /*! \brief Zone data destructor function. */ static int zonedata_destroy(knot_zone_t *zone) { + if (zone == NULL) { + return KNOTD_EINVAL; + } + dbg_zones_verb("zones: zonedata_destroy(%p) called\n", zone); zonedata_t *zd = (zonedata_t *)knot_zone_data(zone); @@ -122,10 +125,14 @@ static int zonedata_destroy(knot_zone_t *zone) /*! \brief Zone data constructor function. */ static int zonedata_init(conf_zone_t *cfg, knot_zone_t *zone) { + if (cfg == NULL || zone == NULL) { + return KNOTD_EINVAL; + } zonedata_t *zd = malloc(sizeof(zonedata_t)); if (!zd) { return KNOTD_ENOMEM; } + memset(zd, 0, sizeof(zonedata_t)); /* Link to config. */ zd->conf = cfg; @@ -362,6 +369,7 @@ static int zones_refresh_ev(event_t *e) knot_ns_xfr_t xfr_req; memset(&xfr_req, 0, sizeof(knot_ns_xfr_t)); memcpy(&xfr_req.addr, &zd->xfr_in.master, sizeof(sockaddr_t)); + memcpy(&xfr_req.saddr, &zd->xfr_in.via, sizeof(sockaddr_t)); xfr_req.data = (void *)zone; xfr_req.send = zones_send_cb; @@ -410,15 +418,17 @@ static int zones_refresh_ev(event_t *e) } else { pthread_mutex_unlock(&zd->xfr_in.lock); } - - /* Create query. */ - /*! \todo API for retrieval of name. */ + + /* Invalidate pending SOA query. */ + event_t *soa_pending = zd->soa_pending; + zd->soa_pending = NULL; /*! \todo [TSIG] CHANGE!!! only for compatibility now. */ knot_ns_xfr_t xfr_req; memset(&xfr_req, 0, sizeof(knot_ns_xfr_t)); xfr_req.wire = qbuf; - + + /* Create query. */ int ret = xfrin_create_soa_query(zone->name, &xfr_req, &buflen); if (ret == KNOT_EOK) { @@ -426,6 +436,15 @@ static int zones_refresh_ev(event_t *e) /* Create socket on random port. */ int sock = socket_create(master->family, SOCK_DGRAM); + + /* Check requested source. */ + sockaddr_t *via = &zd->xfr_in.via; + if (via->len > 0) { + if (bind(sock, via->ptr, via->len) < 0) { + socket_close(sock); + sock = -1; + } + } /* Send query. */ ret = KNOTD_ERROR; @@ -456,12 +475,18 @@ static int zones_refresh_ev(event_t *e) req.type = XFR_TYPE_SOA; req.zone = zone; memcpy(&req.addr, master, sizeof(sockaddr_t)); + memcpy(&req.saddr, &zd->xfr_in.via, sizeof(sockaddr_t)); sockaddr_update(&req.addr); - xfr_request(zd->server->xfr_h, &req); + ret = xfr_request(zd->server->xfr_h, &req); } } else { ret = KNOTD_ERROR; } + + if (ret != KNOTD_EOK) { + log_server_warning("Failed to issue SOA query for zone '%s'.\n", + zd->conf->name); + } /* Schedule EXPIRE timer on first attempt. */ if (!zd->xfr_in.expire) { @@ -481,7 +506,13 @@ static int zones_refresh_ev(event_t *e) /* Unlock RCU. */ rcu_read_unlock(); - + + /* Close invalidated SOA query. */ + evsched_event_finished(e->parent); + if (soa_pending != NULL) { + /* Execute */ + evsched_schedule(e->parent, soa_pending, 0); + } return ret; } @@ -495,7 +526,7 @@ static int zones_notify_send(event_t *e) notify_ev_t *ev = (notify_ev_t *)e->data; knot_zone_t *zone = ev->zone; if (!zone) { - log_zone_error("notify: NOTIFY invalid event received\n"); + log_zone_error("NOTIFY invalid event received\n"); evsched_event_free(e->parent, e); free(ev); return KNOTD_EINVAL; @@ -544,6 +575,14 @@ static int zones_notify_send(event_t *e) /* Create socket on random port. */ int sock = socket_create(ev->addr.family, SOCK_DGRAM); + + /* Check requested source. */ + if (ev->saddr.len > 0) { + if (bind(sock, ev->saddr.ptr, ev->saddr.len) < 0) { + socket_close(sock); + sock = -1; + } + } /* Send query. */ ret = -1; @@ -558,9 +597,9 @@ static int zones_notify_send(event_t *e) sockaddr_tostr(&ev->addr, r_addr, sizeof(r_addr)); int r_port = sockaddr_portnum(&ev->addr); ev->msgid = knot_wire_get_id(qbuf); - log_server_info("Issued NOTIFY query to %s:%d, expecting " - "response ID=%d\n", - r_addr, r_port, + log_server_info("Issued '%s' NOTIFY query to %s:%d, " + "expecting response ID=%d\n", + zd->conf->name, r_addr, r_port, ev->msgid); } @@ -698,6 +737,17 @@ static int zones_load_zone(knot_zonedb_t *zonedb, const char *zone_name, const char *source, const char *filename) { knot_zone_t *zone = NULL; + size_t zlen = strlen(zone_name); + char *zname = NULL; + if (zlen > 0) { + if ((zname = strdup(zone_name)) == NULL) { + return KNOTD_ENOMEM; + } + } else { + return KNOTD_EINVAL; + } + + zname[zlen - 1] = '\0'; /* Trim last dot */ /* Check path */ if (filename) { @@ -709,24 +759,29 @@ static int zones_load_zone(knot_zonedb_t *zonedb, const char *zone_name, /* OK */ break; case KNOT_EFEWDATA: - log_server_error("Compiled zone db '%s' not exists.\n", - filename); + log_server_error("Couldn't find compiled zone. " + "Please recompile '%s'.\n", zname); + free(zname); return KNOTD_EZONEINVAL; case KNOT_ECRC: - log_server_error("Compiled zone db CRC mismatches, " - "db is corrupted or .crc file is " - "deleted.\n"); + log_server_error("Compiled zone db CRC mismatch, " + "db is corrupted or .crc file is " + "deleted. Please recompile '%s'.\n", + zname); + free(zname); return KNOTD_EZONEINVAL; case KNOT_EMALF: - log_server_error("Compiled db '%s' is too old, " - " please recompile.\n", - filename); + log_server_error("Compiled db '%s' is too old. " + "Please recompile '%s'.\n", + filename, zname); + free(zname); return KNOTD_EZONEINVAL; case KNOT_ERROR: case KNOT_ENOMEM: default: - log_server_error("Failed to read zone db file '%s'.\n", - filename); + log_server_error("Failed to load compiled zone file " + "'%s'.\n", filename); + free(zname); return KNOTD_EZONEINVAL; } @@ -735,7 +790,7 @@ static int zones_load_zone(knot_zonedb_t *zonedb, const char *zone_name, if (src_changed || knot_zload_needs_update(zl)) { log_server_warning("Database for zone '%s' is not " "up-to-date. Please recompile.\n", - zone_name); + zname); } zone = knot_zload_load(zl); @@ -743,8 +798,7 @@ static int zones_load_zone(knot_zonedb_t *zonedb, const char *zone_name, /* Check loaded name. */ const knot_dname_t *dname = knot_zone_name(zone); knot_dname_t *dname_req = 0; - dname_req = knot_dname_new_from_str(zone_name, - strlen(zone_name), 0); + dname_req = knot_dname_new_from_str(zone_name, zlen, 0); if (knot_dname_compare(dname, dname_req) != 0) { log_server_warning("Origin of the zone db file is " "different than '%s'\n", @@ -756,7 +810,9 @@ static int zones_load_zone(knot_zonedb_t *zonedb, const char *zone_name, knot_dname_free(&dname_req); /* CLEANUP */ - //knot_zone_contents_dump(zone->contents, 1); +// knot_zone_contents_dump(zone->contents, 1); +// int errs = knot_zone_contents_integrity_check(zone->contents); +// fprintf(stderr, "INTEGRITY CHECK OF ZONE. ERRORS: %d\n", errs); if (zone) { /* save the timestamp from the zone db file */ @@ -780,16 +836,20 @@ static int zones_load_zone(knot_zonedb_t *zonedb, const char *zone_name, if (!zone) { log_server_error("Failed to load " "db '%s' for zone '%s'.\n", - filename, zone_name); + filename, zname); + free(zname); return KNOTD_EZONEINVAL; } } else { /* db is null. */ + log_server_error("No file name for zone '%s'.\n", zname); + free(zname); return KNOTD_EINVAL; } /* CLEANUP */ // knot_zone_dump(zone, 1); + free(zname); return KNOTD_EOK; } @@ -1113,7 +1173,7 @@ static int zones_journal_apply(knot_zone_t *zone) log_server_info("Applying '%zu' changesets from journal " "to zone '%s'.\n", chsets->count, zd->conf->name); - int apply_ret = xfrin_apply_changesets_to_zone(zone, chsets); + int apply_ret = xfrin_apply_changesets(zone, chsets); if (apply_ret != KNOT_EOK) { log_server_error("Failed to apply changesets to " "'%s' - %s\n", @@ -1237,15 +1297,10 @@ static int zones_insert_zones(knot_nameserver_t *ns, z->name, z->db); ret = zones_load_zone(db_new, z->name, - z->file, z->db); + z->file, z->db); if (ret == KNOTD_EOK) { log_server_info("Loaded zone '%s'\n", z->name); - } else { - log_server_error("Failed to load zone " - "'%s' - %s\n", - z->name, - knotd_strerror(ret)); } } @@ -1302,6 +1357,7 @@ static int zones_insert_zones(knot_nameserver_t *ns, /* Update master server address. */ memset(&zd->xfr_in.tsig_key, 0, sizeof(knot_key_t)); sockaddr_init(&zd->xfr_in.master, -1); + sockaddr_init(&zd->xfr_in.via, -1); if (!EMPTY_LIST(z->acl.xfr_in)) { conf_remote_t *r = HEAD(z->acl.xfr_in); conf_iface_t *cfg_if = r->remote; @@ -1309,6 +1365,12 @@ static int zones_insert_zones(knot_nameserver_t *ns, cfg_if->family, cfg_if->address, cfg_if->port); + if (cfg_if->via) { + sockaddr_set(&zd->xfr_in.via, + cfg_if->via->family, + cfg_if->via->address, + 0); + } if (cfg_if->key) { memcpy(&zd->xfr_in.tsig_key, @@ -1510,7 +1572,7 @@ static int zones_check_tsig_query(const knot_zone_t *zone, assert(rcode != NULL); assert(tsig_key_zone != NULL); - knot_rrset_t *tsig = NULL; + const knot_rrset_t *tsig = NULL; if (knot_packet_additional_rrset_count(query) > 0) { /*! \todo warning */ @@ -1811,17 +1873,24 @@ int zones_normal_query_answer(knot_nameserver_t *nameserver, rcode = KNOT_RCODE_REFUSED; } - assert(resp != NULL); - if (rcode != KNOT_RCODE_NOERROR) { dbg_zones_verb("Failed preparing response structure: %s.\n", knot_strerror(rcode)); - knot_ns_error_response(nameserver, knot_packet_id(query), - rcode, resp_wire, rsize); + if (resp == NULL) { + knot_ns_error_response(nameserver, knot_packet_id(query), + rcode, resp_wire, rsize); + rcu_read_unlock(); + return KNOT_EOK; + } + knot_ns_error_response_full(nameserver, resp, rcode, resp_wire, + rsize); +// knot_ns_error_response(nameserver, knot_packet_id(query), +// rcode, resp_wire, rsize); } else { /* * Now we have zone. Verify TSIG if it is in the packet. */ + assert(resp != NULL); assert(rcode == KNOT_RCODE_NOERROR); uint16_t tsig_rcode = 0; knot_key_t *tsig_key_zone = NULL; @@ -1996,6 +2065,9 @@ int zones_process_response(knot_nameserver_t *nameserver, response_wire == NULL) { return KNOTD_EINVAL; } + + /* Declare no response. */ + *rsize = 0; /* Handle SOA query response, cancel EXPIRE timer * and start AXFR transfer if needed. @@ -2008,9 +2080,6 @@ int zones_process_response(knot_nameserver_t *nameserver, return KNOTD_ERROR; } - /* No response. */ - *rsize = 0; - /* Find matching zone and ID. */ const knot_dname_t *zone_name = knot_packet_qname(packet); /*! \todo Change the access to the zone db. */ @@ -2041,6 +2110,7 @@ int zones_process_response(knot_nameserver_t *nameserver, dbg_zones_verb("xfrin_transfer_needed() returned %d\n", ret); if (ret < 0) { /* RETRY/EXPIRE timers running, do not interfere. */ + rcu_read_unlock(); return KNOTD_ERROR; } @@ -2074,7 +2144,8 @@ int zones_process_response(knot_nameserver_t *nameserver, /* Prepare XFR client transfer. */ knot_ns_xfr_t xfr_req; memset(&xfr_req, 0, sizeof(knot_ns_xfr_t)); - memcpy(&xfr_req.addr, from, sizeof(sockaddr_t)); + memcpy(&xfr_req.addr, &zd->xfr_in.master, sizeof(sockaddr_t)); + memcpy(&xfr_req.saddr, &zd->xfr_in.via, sizeof(sockaddr_t)); xfr_req.zone = (void *)zone; xfr_req.send = zones_send_cb; @@ -2094,7 +2165,6 @@ int zones_process_response(knot_nameserver_t *nameserver, nameserver))->xfr_h, &xfr_req); } - return KNOTD_EOK; } @@ -2194,6 +2264,7 @@ static int zones_dump_xfr_zone_text(knot_zone_contents_t *zone, * until the zone_dump_text is called. Needs to be opened in * this function for writing. * Use open() for exclusive open and fcntl() for locking. + * (issue #1587) */ char *new_zonefile = zones_find_free_filename(zonefile); @@ -2213,13 +2284,13 @@ static int zones_dump_xfr_zone_text(knot_zone_contents_t *zone, return KNOTD_ERROR; } - /*! \todo this would also need locking as well. */ + /*! \todo this would also need locking as well (issue #1587) */ remove(zonefile); /* Don't care, as the rename will trigger the error. */ if (rename(new_zonefile, zonefile) != 0) { log_zone_warning("Failed to replace old zone file '%s'' with a new" " zone file '%s'.\n", zonefile, new_zonefile); /*! \todo with proper locking, this shouldn't happen, - * revise it later on. + * revise it later on (issue #1587) */ zone_dump_text(zone, zonefile); free(new_zonefile); @@ -2243,6 +2314,7 @@ static int ns_dump_xfr_zone_binary(knot_zone_contents_t *zone, * until the zone_dump_text is called. Needs to be opened in * this function for writing. * Use open() for exclusive open and fcntl() for locking. + * (issue #1587) */ char *new_zonedb = zones_find_free_filename(zonedb); @@ -2253,7 +2325,7 @@ static int ns_dump_xfr_zone_binary(knot_zone_contents_t *zone, return KNOTD_ERROR; /*! \todo New error code? */ } - /*! \todo this would also need locking as well. */ + /*! \todo this would also need locking as well (issue #1587) */ int rc = knot_zdump_dump_and_swap(zone, new_zonedb, zonedb, zonefile); free(new_zonedb); @@ -2306,6 +2378,9 @@ int zones_ns_conf_hook(const struct conf_t *conf, void *data) { knot_nameserver_t *ns = (knot_nameserver_t *)data; dbg_zones_verb("zones: reconfiguring name server.\n"); + + /* Set NSID. */ + knot_ns_set_nsid(ns, conf->nsid, conf->nsid_len); knot_zonedb_t *old_db = 0; @@ -2477,8 +2552,6 @@ int zones_store_changesets(knot_ns_xfr_t *xfr) knot_zone_t *zone = xfr->zone; knot_changesets_t *src = (knot_changesets_t *)xfr->data; - /*! \todo Convert to binary format. */ - int ret = zones_changesets_to_binary(src); if (ret != KNOTD_EOK) { return ret; @@ -2606,11 +2679,11 @@ int zones_xfr_load_changesets(knot_ns_xfr_t *xfr, uint32_t serial_from, int zones_apply_changesets(knot_ns_xfr_t *xfr) { if (xfr == NULL || xfr->zone == NULL || xfr->data == NULL) { - return KNOTD_EINVAL; + return KNOT_EBADARG; } - return xfrin_apply_changesets_to_zone(xfr->zone, - (knot_changesets_t *)xfr->data); + return xfrin_apply_changesets(xfr->zone, + (knot_changesets_t *)xfr->data); } /*----------------------------------------------------------------------------*/ @@ -2665,7 +2738,7 @@ int zones_timers_update(knot_zone_t *zone, conf_zone_t *cfzone, evsched_t *sch) } /* Schedule IXFR database syncing. */ - /*! \todo Sync timer should not be reset after each xfr. */ + /*! \todo Sync timer should not be reset after each xfr (issue #1348) */ int sync_timeout = cfzone->dbsync_timeout * 1000; /* Convert to ms. */ if (zd->ixfr_dbsync) { evsched_cancel(sch, zd->ixfr_dbsync); @@ -2702,9 +2775,15 @@ int zones_timers_update(knot_zone_t *zone, conf_zone_t *cfzone, evsched_t *sch) } /* Parse server address. */ + sockaddr_init(&ev->saddr, -1); int ret = sockaddr_set(&ev->addr, cfg_if->family, cfg_if->address, cfg_if->port); + conf_iface_t *via = cfg_if->via; + if (ret > 0 && via != NULL) { + ret = sockaddr_set(&ev->saddr, via->family, + via->address, 0); + } if (ret < 1) { free(ev); dbg_zones("notify: NOTIFY slave %s has invalid " @@ -2726,7 +2805,8 @@ int zones_timers_update(knot_zone_t *zone, conf_zone_t *cfzone, evsched_t *sch) add_tail(&zd->notify_pending, &ev->n); pthread_mutex_unlock(&zd->lock); - log_server_info("Scheduled NOTIFY query after %d s to %s:%d\n", + log_server_info("Scheduled '%s' NOTIFY query " + "after %d s to %s:%d\n", zd->conf->name, tmr_s, cfg_if->address, cfg_if->port); } diff --git a/src/knot/server/zones.h b/src/knot/server/zones.h index 9fcab7d..53c5290 100644 --- a/src/knot/server/zones.h +++ b/src/knot/server/zones.h @@ -69,6 +69,7 @@ typedef struct zonedata_t struct { acl_t *acl; /*!< ACL for xfr-in.*/ sockaddr_t master; /*!< Master server for xfr-in.*/ + sockaddr_t via; /*!< Master server transit interface.*/ knot_key_t tsig_key; /*!< Master TSIG key. */ struct event_t *timer; /*!< Timer for REFRESH/RETRY. */ struct event_t *expire; /*!< Timer for REFRESH. */ @@ -80,6 +81,9 @@ typedef struct zonedata_t /*! \brief List of pending NOTIFY events. */ list notify_pending; + + /*! \brief List of pending SOA queries. */ + struct event_t* soa_pending; /*! \brief Zone IXFR history. */ journal_t *ixfr_db; diff --git a/src/knot/stat/stat.h b/src/knot/stat/stat.h index a82f130..0cf1454 100644 --- a/src/knot/stat/stat.h +++ b/src/knot/stat/stat.h @@ -71,7 +71,7 @@ typedef struct stat_stat stat_t; #ifdef STAT_COMPILE stat_t *stat_new(); #else -inline stat_t *stat_new() +static inline inline stat_t *stat_new() { return NULL; } diff --git a/src/knot/zone/semantic-check.c b/src/knot/zone/semantic-check.c index 3ca38a2..f511f35 100644 --- a/src/knot/zone/semantic-check.c +++ b/src/knot/zone/semantic-check.c @@ -3,6 +3,7 @@ #include <arpa/inet.h> #include "knot/common.h" +#include "knot/zone/zone-dump.h" #include "knot/other/error.h" #include "libknot/libknot.h" #include "common/base32hex.h" @@ -10,6 +11,90 @@ #include "semantic-check.h" +static char *error_messages[(-ZC_ERR_ALLOC) + 1] = { + [-ZC_ERR_ALLOC] = "Memory allocation error!\n", + + [-ZC_ERR_MISSING_SOA] = "SOA record missing in zone!\n", + + [-ZC_ERR_RRSIG_RDATA_TYPE_COVERED] = + "RRSIG: Type covered rdata field is wrong!\n", + [-ZC_ERR_RRSIG_RDATA_TTL] = + "RRSIG: TTL rdata field is wrong!\n", + [-ZC_ERR_RRSIG_RDATA_LABELS] = + "RRSIG: Labels rdata field is wrong!\n", + [-ZC_ERR_RRSIG_RDATA_DNSKEY_OWNER] = + "RRSIG: Signer name is different than in DNSKEY!\n", + [-ZC_ERR_RRSIG_RDATA_SIGNED_WRONG] = + "RRSIG: Key error!\n", + [-ZC_ERR_RRSIG_NO_RRSIG] = + "RRSIG: No RRSIG!\n", + [-ZC_ERR_RRSIG_SIGNED] = + "RRSIG: Signed RRSIG!\n", + [-ZC_ERR_RRSIG_OWNER] = + "RRSIG: Owner name rdata field is wrong!\n", + [-ZC_ERR_RRSIG_CLASS] = + "RRSIG: Class is wrong!\n", + [-ZC_ERR_RRSIG_TTL] = + "RRSIG: TTL is wrong!\n", + [-ZC_ERR_RRSIG_NOT_ALL] = + "RRSIG: Not all RRs are signed!\n", + + [-ZC_ERR_NO_NSEC] = + "NSEC: Missing NSEC record\n", + [-ZC_ERR_NSEC_RDATA_BITMAP] = + "NSEC: Wrong NSEC bitmap!\n", + [-ZC_ERR_NSEC_RDATA_MULTIPLE] = + "NSEC: Multiple NSEC records!\n", + [-ZC_ERR_NSEC_RDATA_CHAIN] = + "NSEC: NSEC chain is not coherent!\n", + [-ZC_ERR_NSEC_RDATA_CHAIN_NOT_CYCLIC] = + "NSEC: NSEC chain is not cyclic!\n", + + [-ZC_ERR_NSEC3_UNSECURED_DELEGATION] = + "NSEC3: Zone contains unsecured delegation!\n", + [-ZC_ERR_NSEC3_NOT_FOUND] = + "NSEC3: Could not find previous NSEC3 record in the zone!\n", + [-ZC_ERR_NSEC3_UNSECURED_DELEGATION_OPT] = + "NSEC3: Unsecured delegation is not part " + "of the Opt-Out span!\n", + [-ZC_ERR_NSEC3_RDATA_TTL] = + "NSEC3: Original TTL rdata field is wrong!\n", + [-ZC_ERR_NSEC3_RDATA_CHAIN] = + "NSEC3: NSEC3 chain is not coherent!\n", + [-ZC_ERR_NSEC3_RDATA_BITMAP] = + "NSEC3: NSEC3 bitmap error!\n", + + [-ZC_ERR_CNAME_CYCLE] = + "CNAME: CNAME cycle!\n", + [-ZC_ERR_DNAME_CYCLE] = + "CNAME: DNAME cycle!\n", + [-ZC_ERR_CNAME_EXTRA_RECORDS] = + "CNAME: Node with CNAME record has other records!\n", + [-ZC_ERR_DNAME_CHILDREN] = + "DNAME: Node with DNAME record has children!\n", + [-ZC_ERR_CNAME_EXTRA_RECORDS_DNSSEC] = + "CNAME: Node with CNAME record has other " + "records than RRSIG and NSEC/NSEC3!\n", + [-ZC_ERR_CNAME_MULTIPLE] = "CNAME: Multiple CNAME records!\n", + [-ZC_ERR_DNAME_MULTIPLE] = "DNAME: Multiple DNAME records!\n", + [-ZC_ERR_CNAME_WILDCARD_SELF] = "CNAME wildcard " + "pointing to itself!\n", + [-ZC_ERR_DNAME_WILDCARD_SELF] = "DNAME wildcard " + "pointing to itself!\n", + + /* ^ + | Important errors (to be logged on first occurence and counted) */ + + + /* Below are errors of lesser importance, to be counted unless + specified otherwise */ + + [-ZC_ERR_GLUE_NODE] = + "GLUE: Node with Glue record missing!\n", + [-ZC_ERR_GLUE_RECORD] = + "GLUE: Record with Glue address missing\n", +}; + static const uint MAX_CNAME_CYCLE_DEPTH = 15; err_handler_t *handler_new(char log_cname, char log_glue, @@ -21,7 +106,8 @@ err_handler_t *handler_new(char log_cname, char log_glue, /* It should be initialized, but to be safe */ memset(handler->errors, 0, sizeof(uint) * (-ZC_ERR_ALLOC + 1)); - + + handler->error_count = 0; handler->options.log_cname = log_cname; handler->options.log_glue = log_glue; handler->options.log_rrsigs = log_rrsigs; @@ -42,9 +128,15 @@ err_handler_t *handler_new(char log_cname, char log_glue, */ static void log_error_from_node(err_handler_t *handler, const knot_node_t *node, - uint error) + int error) { + if (error > (int)ZC_ERR_GLUE_RECORD) { + fprintf(stderr, "Unknown error.\n"); + return; + } + if (node != NULL) { + handler->error_count++; char *name = knot_dname_to_str(knot_node_owner(node)); fprintf(stderr, "Semantic warning in node: %s: ", name); @@ -59,7 +151,7 @@ static void log_error_from_node(err_handler_t *handler, int err_handler_handle_error(err_handler_t *handler, const knot_node_t *node, - uint error) + int error) { assert(handler && node); if ((error != 0) && @@ -67,9 +159,10 @@ int err_handler_handle_error(err_handler_t *handler, return ZC_ERR_UNKNOWN; } - if (error == ZC_ERR_ALLOC) { - ERR_ALLOC_FAILED; - return ZC_ERR_ALLOC; + /*!< \todo this is so wrong! This should not even return anything. */ + if (error == ZC_ERR_ALLOC || error == KNOT_ERROR + || error == KNOT_EBADARG) { + return KNOT_EBADARG; } /* missing SOA can only occur once, so there @@ -145,8 +238,14 @@ void err_handler_log_all(err_handler_t *handler) * \retval ZC_ERR_CNAME_CYCLE when cycle is present. */ static int check_cname_cycles_in_zone(knot_zone_contents_t *zone, - const knot_rrset_t *rrset) + const knot_rrset_t *rrset, + char *fatal_error) { + if (rrset->type != KNOT_RRTYPE_CNAME && + rrset->type != KNOT_RRTYPE_DNAME) { + return KNOT_EBADARG; + } + const knot_rrset_t *next_rrset = rrset; assert(rrset); const knot_rdata_t *tmp_rdata = knot_rrset_rdata(next_rrset); @@ -158,19 +257,151 @@ static int check_cname_cycles_in_zone(knot_zone_contents_t *zone, const knot_dname_t *next_dname = knot_rdata_cname_name(tmp_rdata); + /* (cname_name == dname_target) */ assert(next_dname); - + + /* Check wildcard pointing to itself. */ + if (knot_dname_is_wildcard(knot_rrset_owner(rrset))) { + /* We need to chop the wildcard. */ + + knot_dname_t *chopped_wc = + knot_dname_left_chop(knot_rrset_owner(rrset)); + if (!chopped_wc) { + /* Definitely not a cycle. */ + return KNOT_EOK; + } + + /* + * And check that no sub-dname up to zone apex is present + * in its rdata. + */ + + knot_dname_t *next_dname_copy = + knot_dname_deep_copy(next_dname); + if (!next_dname_copy) { + knot_dname_free(&chopped_wc); + return KNOT_ERROR; + } + + const knot_dname_t *zone_origin = + knot_node_owner(knot_zone_contents_apex(zone)); + if (!zone_origin) { + knot_dname_free(&chopped_wc); + knot_dname_free(&next_dname_copy); + return KNOT_ERROR; + } + + char error_found = 0; + char cut_offs = 1; + + while (knot_dname_compare(next_dname_copy, + zone_origin) != 0 && + !error_found) { + /* Compare chopped owner with current next dname. */ + error_found = + knot_dname_compare(next_dname_copy, + chopped_wc) == 0; + if (error_found && cut_offs == 1) { + /* WC without * == link. */ + knot_dname_free(&next_dname_copy); + knot_dname_free(&chopped_wc); + return KNOT_EOK; + } + + knot_dname_t *tmp_chopped = + knot_dname_left_chop(next_dname_copy); + knot_dname_free(&next_dname_copy); + if (!tmp_chopped) { + knot_dname_free(&chopped_wc); + knot_dname_free(&next_dname_copy); + return KNOT_ERROR; + } + + cut_offs++; + + next_dname_copy = tmp_chopped; + } + + if (error_found) { + knot_dname_free(&next_dname_copy); + knot_dname_free(&chopped_wc); + assert(cut_offs > 1); + *fatal_error = 1; + return ZC_ERR_CNAME_WILDCARD_SELF; + } + + knot_dname_free(&next_dname_copy); + knot_dname_free(&chopped_wc); + + /* + * Test for transitive wildcard loops. + * Basically the same as below, only we look for wildcards and + * strip them in the same fashion as above. + */ + + } + while (i < MAX_CNAME_CYCLE_DEPTH && next_dname != NULL) { next_node = knot_zone_contents_get_node(zone, next_dname); if (next_node == NULL) { next_node = - knot_zone_contents_get_nsec3_node(zone, next_dname); + knot_zone_contents_get_nsec3_node(zone, + next_dname); + } + +/*!< \todo this might replace some of the code above. */ +// /* Still NULL, try wildcards. */ +// if (next_node == NULL && knot_dname_is_wildcard(next_dname)) { +// /* We can only use the wildcard so many times. */ + +// /* Create chopped copy of wc. */ +// knot_dname_t *chopped_wc = +// knot_dname_left_chop(next_dname); +// if (chopped_wc == NULL) { +// /* If name with this wc is in the zone, +// we have a problem (eg. cycle continues). */ +// next_node = +// knot_zone_contents_get_node(zone, +// chopped_wc); +// /* (No need to consider NSEC3 nodes.) */ +// knot_dname_free(&chopped_wc); +// } +// } + + /* Just a guess. */ + knot_dname_t *chopped_next = + knot_dname_left_chop(next_dname); + if (chopped_next == NULL) { + /*!< \todo check. */ + return KNOT_ERROR; + } + while (next_node == NULL && chopped_next != NULL) { + /* Cat '*' .*/ + knot_dname_t *wc = + knot_dname_new_from_str("*", strlen("*"), + NULL); + if (wc == NULL) { + return KNOT_ENOMEM; + } + + if (knot_dname_cat(wc, chopped_next) == NULL) { + return KNOT_ERROR; + } + + next_node = + knot_zone_contents_get_node(zone, wc); + knot_dname_free(&wc); + knot_dname_t *tmp = chopped_next; + chopped_next = knot_dname_left_chop(chopped_next); + knot_dname_free(&tmp); } + + knot_dname_free(&chopped_next); if (next_node != NULL) { next_rrset = knot_node_rrset(next_node, - KNOT_RRTYPE_CNAME); + rrset->type); if (next_rrset != NULL) { next_dname = knot_rdata_cname_name(next_rrset->rdata); @@ -186,6 +417,7 @@ static int check_cname_cycles_in_zone(knot_zone_contents_t *zone, /* even if the length is 0, i will be 1 */ if (i >= MAX_CNAME_CYCLE_DEPTH) { + *fatal_error = 1; return ZC_ERR_CNAME_CYCLE; } @@ -626,7 +858,7 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone, knot_node_t *nod err_handler_t *handler) { assert(handler); - const knot_node_t *nsec3_node = knot_node_nsec3_node(node, 0); + const knot_node_t *nsec3_node = knot_node_nsec3_node(node); if (nsec3_node == NULL) { /* I know it's probably not what RFCs say, but it will have to @@ -643,7 +875,7 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone, knot_node_t *nod if (knot_zone_contents_find_nsec3_for_name(zone, knot_node_owner(node), &nsec3_node, - &nsec3_previous, 0) != 0) { + &nsec3_previous) != 0) { err_handler_handle_error(handler, node, ZC_ERR_NSEC3_NOT_FOUND); } @@ -713,17 +945,17 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone, knot_node_t *nod } /* This is why we allocate maximum length of decoded string + 1 */ - memmove(next_dname_decoded + 1, next_dname_decoded, real_size); - next_dname_decoded[0] = real_size; - +// memmove(next_dname_decoded + 1, next_dname_decoded, real_size); +// next_dname_decoded[0] = real_size; + /* Local allocation, will be discarded. */ knot_dname_t *next_dname = - knot_dname_new_from_wire(next_dname_decoded, - real_size + 1, NULL); + knot_dname_new_from_str((char *)next_dname_decoded, + real_size, NULL); CHECK_ALLOC_LOG(next_dname, KNOT_ENOMEM); free(next_dname_decoded); - + if (knot_dname_cat(next_dname, knot_node_owner(knot_zone_contents_apex(zone))) == NULL) { fprintf(stderr, "Could not concatenate dnames!\n"); @@ -764,7 +996,6 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone, knot_node_t *nod type) == NULL) { err_handler_handle_error(handler, node, ZC_ERR_NSEC3_RDATA_BITMAP); - break; /* char *name = knot_dname_to_str( log_zone_error("Node %s does " @@ -796,21 +1027,25 @@ static int check_nsec3_node_in_zone(knot_zone_contents_t *zone, knot_node_t *nod static int semantic_checks_plain(knot_zone_contents_t *zone, knot_node_t *node, char do_checks, - err_handler_t *handler) + err_handler_t *handler, + int only_mandatory, + char *fatal_error) { assert(handler); const knot_rrset_t *cname_rrset = knot_node_rrset(node, KNOT_RRTYPE_CNAME); if (cname_rrset != NULL) { - if (check_cname_cycles_in_zone(zone, cname_rrset) != - KNOT_EOK) { + int ret = check_cname_cycles_in_zone(zone, cname_rrset, + fatal_error); + if (ret != KNOT_EOK) { err_handler_handle_error(handler, node, - ZC_ERR_CNAME_CYCLE); + ret); } /* No DNSSEC and yet there is more than one rrset in node */ if (do_checks == 1 && knot_node_rrset_count(node) != 1) { + *fatal_error = 1; err_handler_handle_error(handler, node, ZC_ERR_CNAME_EXTRA_RECORDS); } else if (knot_node_rrset_count(node) != 1) { @@ -818,6 +1053,7 @@ static int semantic_checks_plain(knot_zone_contents_t *zone, if (!(knot_node_rrset(node, KNOT_RRTYPE_RRSIG) || knot_node_rrset(node, KNOT_RRTYPE_NSEC)) || knot_node_rrset_count(node) > 3) { + *fatal_error = 1; err_handler_handle_error(handler, node, ZC_ERR_CNAME_EXTRA_RECORDS_DNSSEC); } @@ -825,6 +1061,7 @@ static int semantic_checks_plain(knot_zone_contents_t *zone, if (knot_rrset_rdata(cname_rrset)->next != knot_rrset_rdata(cname_rrset)) { + *fatal_error = 1; err_handler_handle_error(handler, node, ZC_ERR_CNAME_MULTIPLE); } @@ -833,23 +1070,35 @@ static int semantic_checks_plain(knot_zone_contents_t *zone, const knot_rrset_t *dname_rrset = knot_node_rrset(node, KNOT_RRTYPE_DNAME); if (dname_rrset != NULL) { - if (check_cname_cycles_in_zone(zone, dname_rrset) != - KNOT_EOK) { + int ret = check_cname_cycles_in_zone(zone, dname_rrset, + fatal_error); + if (ret == ZC_ERR_CNAME_CYCLE) { + *fatal_error = 1; err_handler_handle_error(handler, node, ZC_ERR_DNAME_CYCLE); + } else if (ret == ZC_ERR_CNAME_WILDCARD_SELF) { + *fatal_error = 1; + err_handler_handle_error(handler, node, + ZC_ERR_DNAME_WILDCARD_SELF); } if (knot_node_rrset(node, KNOT_RRTYPE_CNAME)) { + *fatal_error = 1; err_handler_handle_error(handler, node, - ZC_ERR_DNAME_EXTRA_RECORDS); + ZC_ERR_CNAME_EXTRA_RECORDS); } - - if (knot_rrset_rdata(dname_rrset)->next != - knot_rrset_rdata(dname_rrset)) { + + if (node->children != 0) { + *fatal_error = 1; err_handler_handle_error(handler, node, - ZC_ERR_DNAME_MULTIPLE); + ZC_ERR_DNAME_CHILDREN); } } + + if (only_mandatory) { + return KNOT_EOK; + } + /* check for glue records at zone cuts */ if (knot_node_is_deleg_point(node)) { @@ -1086,23 +1335,27 @@ static void do_checks_in_tree(knot_node_t *node, void *data) assert(zone); - -/* for (int i = 0; i < count; ++i) { - assert(rrsets[i] != NULL); - knot_zone_save_enclosers_rrset(rrsets[i], - zone, - (skip_list_t *)args->arg2); - } */ - knot_node_t *first_node = (knot_node_t *)args->arg4; knot_node_t **last_node = (knot_node_t **)args->arg5; err_handler_t *handler = (err_handler_t *)args->arg6; - + char do_checks = *((char *)(args->arg3)); if (do_checks) { - semantic_checks_plain(zone, node, do_checks, handler); + semantic_checks_plain(zone, node, do_checks, handler, 0, + (char *)args->arg7); + } else { + assert(handler); + /* All CNAME/DNAME checks are mandatory. */ + handler->options.log_cname = 1; + int check_level = 1 + (zone_is_secure(zone) ? 1 : 0); + semantic_checks_plain(zone, node, check_level, handler, 1, + (char *)args->arg7); + + free(rrsets); + assert(do_checks == 0); + return; } if (do_checks > 1) { @@ -1113,24 +1366,31 @@ static void do_checks_in_tree(knot_node_t *node, void *data) free(rrsets); } -void zone_do_sem_checks(knot_zone_contents_t *zone, char do_checks, +int zone_do_sem_checks(knot_zone_contents_t *zone, char do_checks, err_handler_t *handler, knot_node_t **last_node) { - if (!do_checks) { - return; + if (!handler) { + return KNOT_EBADARG; } - arg_t arguments; arguments.arg1 = zone; arguments.arg3 = &do_checks; arguments.arg4 = NULL; arguments.arg5 = last_node; arguments.arg6 = handler; + char fatal_error = 0; + arguments.arg7 = (void *)&fatal_error; knot_zone_contents_tree_apply_inorder(zone, do_checks_in_tree, (void *)&arguments); + + if (fatal_error) { + return KNOT_ERROR; + } + + return KNOT_EOK; } void log_cyclic_errors_in_zone(err_handler_t *handler, @@ -1167,14 +1427,10 @@ void log_cyclic_errors_in_zone(err_handler_t *handler, return; } - /* This is why allocate maximum length of decoded string + 1 */ - memmove(next_dname_decoded + 1, next_dname_decoded, real_size); - next_dname_decoded[0] = real_size; - /* Local allocation, will be discarded. */ knot_dname_t *next_dname = - knot_dname_new_from_wire(next_dname_decoded, - real_size + 1, NULL); + knot_dname_new_from_str((char *)next_dname_decoded, + real_size, NULL); if (next_dname == NULL) { fprintf(stderr, "Could not allocate dname!\n"); err_handler_handle_error(handler, last_nsec3_node, @@ -1196,15 +1452,18 @@ void log_cyclic_errors_in_zone(err_handler_t *handler, /* Check it points somewhere first. */ if (knot_zone_contents_find_nsec3_node(zone, next_dname) == NULL) { + assert(knot_zone_contents_find_node(zone, + next_dname) == + NULL); err_handler_handle_error(handler, last_nsec3_node, ZC_ERR_NSEC3_RDATA_CHAIN); - } - - /* Compare with the actual first NSEC3 node. */ - if (knot_dname_compare(first_nsec3_node->owner, - next_dname) != 0) { - err_handler_handle_error(handler, last_nsec3_node, - ZC_ERR_NSEC3_RDATA_CHAIN); + } else { + /* Compare with the actual first NSEC3 node. */ + if (knot_dname_compare(first_nsec3_node->owner, + next_dname) != 0) { + err_handler_handle_error(handler, last_nsec3_node, + ZC_ERR_NSEC3_RDATA_CHAIN); + } } /* Directly discard. */ diff --git a/src/knot/zone/semantic-check.h b/src/knot/zone/semantic-check.h index 88d828a..08396c8 100644 --- a/src/knot/zone/semantic-check.h +++ b/src/knot/zone/semantic-check.h @@ -32,7 +32,7 @@ * so that code does not have to change if new errors are added. */ enum zonechecks_errors { - ZC_ERR_ALLOC = -40, + ZC_ERR_ALLOC = -50, ZC_ERR_UNKNOWN, ZC_ERR_MISSING_SOA, @@ -73,10 +73,12 @@ enum zonechecks_errors { ZC_ERR_CNAME_CYCLE, ZC_ERR_DNAME_CYCLE, ZC_ERR_CNAME_EXTRA_RECORDS, - ZC_ERR_DNAME_EXTRA_RECORDS, + ZC_ERR_DNAME_CHILDREN, ZC_ERR_CNAME_EXTRA_RECORDS_DNSSEC, ZC_ERR_CNAME_MULTIPLE, ZC_ERR_DNAME_MULTIPLE, + ZC_ERR_CNAME_WILDCARD_SELF, + ZC_ERR_DNAME_WILDCARD_SELF, ZC_ERR_CNAME_GENERAL_ERROR, @@ -86,86 +88,6 @@ enum zonechecks_errors { ZC_ERR_GLUE_GENERAL_ERROR, }; -static char *error_messages[(-ZC_ERR_ALLOC) + 1] = { - [-ZC_ERR_ALLOC] = "Memory allocation error!\n", - - [-ZC_ERR_MISSING_SOA] = "SOA record missing in zone!\n", - - [-ZC_ERR_RRSIG_RDATA_TYPE_COVERED] = - "RRSIG: Type covered rdata field is wrong!\n", - [-ZC_ERR_RRSIG_RDATA_TTL] = - "RRSIG: TTL rdata field is wrong!\n", - [-ZC_ERR_RRSIG_RDATA_LABELS] = - "RRSIG: Labels rdata field is wrong!\n", - [-ZC_ERR_RRSIG_RDATA_DNSKEY_OWNER] = - "RRSIG: Signer name is different than in DNSKEY!\n", - [-ZC_ERR_RRSIG_RDATA_SIGNED_WRONG] = - "RRSIG: Key error!\n", - [-ZC_ERR_RRSIG_NO_RRSIG] = - "RRSIG: No RRSIG!\n", - [-ZC_ERR_RRSIG_SIGNED] = - "RRSIG: Signed RRSIG!\n", - [-ZC_ERR_RRSIG_OWNER] = - "RRSIG: Owner name rdata field is wrong!\n", - [-ZC_ERR_RRSIG_CLASS] = - "RRSIG: Class is wrong!\n", - [-ZC_ERR_RRSIG_TTL] = - "RRSIG: TTL is wrong!\n", - [-ZC_ERR_RRSIG_NOT_ALL] = - "RRSIG: Not all RRs are signed!\n", - - [-ZC_ERR_NO_NSEC] = - "NSEC: Missing NSEC record\n", - [-ZC_ERR_NSEC_RDATA_BITMAP] = - "NSEC: Wrong NSEC bitmap!\n", - [-ZC_ERR_NSEC_RDATA_MULTIPLE] = - "NSEC: Multiple NSEC records!\n", - [-ZC_ERR_NSEC_RDATA_CHAIN] = - "NSEC: NSEC chain is not coherent!\n", - [-ZC_ERR_NSEC_RDATA_CHAIN_NOT_CYCLIC] = - "NSEC: NSEC chain is not cyclic!\n", - - [-ZC_ERR_NSEC3_UNSECURED_DELEGATION] = - "NSEC3: Zone contains unsecured delegation!\n", - [-ZC_ERR_NSEC3_NOT_FOUND] = - "NSEC3: Could not find previous NSEC3 record in the zone!\n", - [-ZC_ERR_NSEC3_UNSECURED_DELEGATION_OPT] = - "NSEC3: Unsecured delegation is not part " - "of the Opt-Out span!\n", - [-ZC_ERR_NSEC3_RDATA_TTL] = - "NSEC3: Original TTL rdata field is wrong!\n", - [-ZC_ERR_NSEC3_RDATA_CHAIN] = - "NSEC3: NSEC3 chain is not coherent!\n", - [-ZC_ERR_NSEC3_RDATA_BITMAP] = - "NSEC3: NSEC3 bitmap error!\n", - - [-ZC_ERR_CNAME_CYCLE] = - "CNAME: CNAME cycle!\n", - [-ZC_ERR_DNAME_CYCLE] = - "CNAME: DNAME cycle!\n", - [-ZC_ERR_CNAME_EXTRA_RECORDS] = - "CNAME: Node with CNAME record has other records!\n", - [-ZC_ERR_DNAME_EXTRA_RECORDS] = - "DNAME: Node with DNAME record has other records!\n", - [-ZC_ERR_CNAME_EXTRA_RECORDS_DNSSEC] = - "CNAME: Node with CNAME record has other " - "records than RRSIG and NSEC/NSEC3!\n", - [-ZC_ERR_CNAME_MULTIPLE] = "CNAME: Multiple CNAME records!\n", - [-ZC_ERR_DNAME_MULTIPLE] = "DNAME: Multiple DNAME records!\n", - - /* ^ - | Important errors (to be logged on first occurence and counted) */ - - - /* Below are errors of lesser importance, to be counted unless - specified otherwise */ - - [-ZC_ERR_GLUE_NODE] = - "GLUE: Node with Glue record missing!\n", - [-ZC_ERR_GLUE_RECORD] = - "GLUE: Record with Glue address missing\n", -}; - /*! * \brief Arguments to be used with tree traversal functions. Uses void pointers * to be more versatile. @@ -201,6 +123,7 @@ struct err_handler { /* Consider moving error messages here */ struct handler_options options; /*!< Handler options. */ uint errors[(-ZC_ERR_ALLOC) + 1]; /*!< Array with error messages */ + uint error_count; /*!< Total error count */ }; typedef struct err_handler err_handler_t; @@ -234,7 +157,7 @@ err_handler_t *handler_new(char log_cname, char log_glue, */ int err_handler_handle_error(err_handler_t *handler, const knot_node_t *node, - uint error); + int error); /*! * \brief Checks if last node in NSEC/NSEC3 chain points to first node in the @@ -269,7 +192,7 @@ void err_handler_log_all(err_handler_t *handler); * \param handler Semantic error handler. * \param last_node Last checked node, which is part of NSEC(3) chain. */ -void zone_do_sem_checks(knot_zone_contents_t *zone, char do_checks, +int zone_do_sem_checks(knot_zone_contents_t *zone, char do_checks, err_handler_t *handler, knot_node_t **last_node); diff --git a/src/knot/zone/zone-dump-text.c b/src/knot/zone/zone-dump-text.c index 8ce0441..dcb9add 100644 --- a/src/knot/zone/zone-dump-text.c +++ b/src/knot/zone/zone-dump-text.c @@ -316,6 +316,11 @@ char *rdata_binary_dname_to_string(knot_rdata_item_t item) if (item.raw_data == NULL) { return NULL; } + + if (item.raw_data[0] == 0) { + return NULL; + } + /* Create new dname frow raw data - probably the easiest way. */ knot_dname_t *dname = knot_dname_new_from_wire((uint8_t *)(item.raw_data + 1), item.raw_data[0], NULL); diff --git a/src/knot/zone/zone-dump.c b/src/knot/zone/zone-dump.c index de4a5a1..0be1ac7 100644 --- a/src/knot/zone/zone-dump.c +++ b/src/knot/zone/zone-dump.c @@ -406,9 +406,9 @@ static void knot_node_dump_binary(knot_node_t *node, void *data, fwrite_wrapper(&owner_id, sizeof(owner_id), 1, f, stream, stream_size, crc); - if (knot_node_parent(node, 0) != NULL) { + if (knot_node_parent(node) != NULL) { uint32_t parent_id = knot_dname_id( - knot_node_owner(knot_node_parent(node, 0))); + knot_node_owner(knot_node_parent(node))); fwrite_wrapper(&parent_id, sizeof(parent_id), 1, f, stream, stream_size, crc); } else { @@ -422,13 +422,13 @@ static void knot_node_dump_binary(knot_node_t *node, void *data, dbg_zdump("Written flags: %u\n", node->flags); - if (knot_node_nsec3_node(node, 0) != NULL) { + if (knot_node_nsec3_node(node) != NULL) { uint32_t nsec3_id = - knot_node_owner(knot_node_nsec3_node(node, 0))->id; + knot_node_owner(knot_node_nsec3_node(node))->id; fwrite_wrapper(&nsec3_id, sizeof(nsec3_id), 1, f, stream, stream_size, crc); dbg_zdump("Written nsec3 node id: %u\n", - knot_node_owner(knot_node_nsec3_node(node, 0))->id); + knot_node_owner(knot_node_nsec3_node(node))->id); } else { uint32_t nsec3_id = 0; fwrite_wrapper(&nsec3_id, sizeof(nsec3_id), 1, f, @@ -472,16 +472,7 @@ static void knot_node_dump_binary(knot_node_t *node, void *data, dbg_zdump("Function ends with: %ld\n\n", ftell(f)); } -/*! - * \brief Checks if zone uses DNSSEC and/or NSEC3 - * - * \param zone Zone to be checked. - * - * \retval 0 if zone is not secured. - * \retval 2 if zone uses NSEC3 - * \retval 1 if zone uses NSEC - */ -static int zone_is_secure(knot_zone_contents_t *zone) +int zone_is_secure(knot_zone_contents_t *zone) { if (knot_node_rrset(knot_zone_contents_apex(zone), KNOT_RRTYPE_DNSKEY) == NULL) { @@ -562,6 +553,21 @@ static void dump_node_to_file(knot_node_t *node, void *data) knot_node_dump_binary(node, data, NULL, NULL, (crc_t *)arg->arg7); } +static char *knot_zdump_crc_file(const char* filename) +{ + char *crc_path = + malloc(sizeof(char) * (strlen(filename) + + strlen(".crc") + 1)); + CHECK_ALLOC_LOG(crc_path, NULL); + memset(crc_path, 0, + sizeof(char) * (strlen(filename) + + strlen(".crc") + 1)); + memcpy(crc_path, filename, + sizeof(char) * strlen(filename)); + crc_path = strcat(crc_path, ".crc"); + return crc_path; +} + int knot_zdump_binary(knot_zone_contents_t *zone, const char *filename, int do_checks, const char *sfilename) { @@ -572,6 +578,9 @@ int knot_zdump_binary(knot_zone_contents_t *zone, const char *filename, mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; int fd = open(new_path, O_WRONLY | O_CREAT | O_TRUNC, mode); if (fd == -1) { + close(fd); + remove(new_path); + remove(knot_zdump_crc_file(filename)); return KNOT_EBADARG; } @@ -606,31 +615,37 @@ int knot_zdump_binary(knot_zone_contents_t *zone, const char *filename, if (do_checks && zone_is_secure(zone)) { do_checks += zone_is_secure(zone); } - - err_handler_t *handler = NULL; - - if (do_checks) { - handler = handler_new(1, 0, 1, 1, 1); - if (handler == NULL) { - /* disable checks and we can continue */ - do_checks = 0; - } else { /* Do check for SOA right now */ - if (knot_node_rrset(knot_zone_contents_apex(zone), - KNOT_RRTYPE_SOA) == NULL) { - err_handler_handle_error(handler, - knot_zone_contents_apex(zone), - ZC_ERR_MISSING_SOA); - } + + err_handler_t *handler = handler_new(1, 1, 1, 1, 1); + if (handler == NULL) { + return KNOT_ENOMEM; + } else { /* Do check for SOA right now */ + if (knot_node_rrset(knot_zone_contents_apex(zone), + KNOT_RRTYPE_SOA) == NULL) { + err_handler_handle_error(handler, + knot_zone_contents_apex(zone), + ZC_ERR_MISSING_SOA); } - - knot_node_t *last_node = NULL; - - zone_do_sem_checks(zone, do_checks, handler, &last_node); - log_cyclic_errors_in_zone(handler, zone, last_node, - first_nsec3_node, last_nsec3_node, - do_checks); - err_handler_log_all(handler); - free(handler); + } + + knot_node_t *last_node = NULL; + int ret = zone_do_sem_checks(zone, + do_checks, handler, &last_node); + log_cyclic_errors_in_zone(handler, zone, last_node, + first_nsec3_node, last_nsec3_node, + do_checks); + err_handler_log_all(handler); + free(handler); + + if (ret != KNOT_EOK) { + fprintf(stderr, "Zone will not be dumped because of " + "fatal semantic errors.\n"); + fclose(f); + close(fd); + /* If remove fails, there is nothing we can do. */ + remove(new_path); + remove(knot_zdump_crc_file(filename)); + return KNOT_ERROR; } crc_t crc = crc_init(); @@ -671,6 +686,11 @@ int knot_zdump_binary(knot_zone_contents_t *zone, const char *filename, /* Write dname table. */ if (knot_dump_dname_table(zone->dname_table, f, &crc) != KNOT_EOK) { + fclose(f); + close(fd); + /* If remove fails, there is nothing we can do. */ + remove(new_path); + remove(knot_zdump_crc_file(filename)); return KNOT_ERROR; } @@ -693,6 +713,10 @@ int knot_zdump_binary(knot_zone_contents_t *zone, const char *filename, malloc(sizeof(char) * (strlen(filename) + strlen(".crc") + 1)); if (unlikely(!crc_path)) { close(fd); + /* If remove fails, there is nothing we can do. */ + remove(new_path); + remove(knot_zdump_crc_file(filename)); + free(crc_path); return KNOT_ENOMEM; } memset(crc_path, 0, @@ -705,6 +729,9 @@ int knot_zdump_binary(knot_zone_contents_t *zone, const char *filename, dbg_zload("knot_zload_open: failed to open '%s'\n", crc_path); close(fd); + /* If remove fails, there is nothing we can do. */ + remove(new_path); + remove(knot_zdump_crc_file(filename)); free(crc_path); return ENOENT; } @@ -720,6 +747,10 @@ int knot_zdump_binary(knot_zone_contents_t *zone, const char *filename, fprintf(stderr, "%s\n", strerror(errno)); fprintf(stderr, "Could not open destination file! Use '%s' " "file instead.\n", new_path); + close(fd); + /* If remove fails, there is nothing we can do. */ + remove(new_path); + remove(knot_zdump_crc_file(filename)); return KNOT_ERROR; } @@ -728,6 +759,9 @@ int knot_zdump_binary(knot_zone_contents_t *zone, const char *filename, fprintf(stderr, "Could not lock destination file for write! " "Use '%s' file instead.\n", new_path); close(fd); + /* If remove fails, there is nothing we can do. */ + remove(new_path); + remove(knot_zdump_crc_file(filename)); return KNOT_ERROR; } @@ -736,12 +770,19 @@ int knot_zdump_binary(knot_zone_contents_t *zone, const char *filename, fprintf(stderr, "Could not move to originally given file! " "Use '%s' file instead.\n", new_path); close(fd); + /* If remove fails, there is nothing we can do. */ + remove(new_path); + remove(knot_zdump_crc_file(filename)); return KNOT_ERROR; } /* Release the lock. */ if (fcntl(fd, F_SETLK, knot_file_lock(F_UNLCK, SEEK_SET)) == -1) { fprintf(stderr, "Could not unlock destination file!\n"); + close(fd); + /* If remove fails, there is nothing we can do. */ + remove(new_path); + remove(knot_zdump_crc_file(filename)); return KNOT_ERROR; } @@ -767,21 +808,6 @@ int knot_zdump_rrset_serialize(const knot_rrset_t *rrset, uint8_t **stream, return KNOT_EOK; } -static char *knot_zdump_crc_file(const char* filename) -{ - char *crc_path = - malloc(sizeof(char) * (strlen(filename) + - strlen(".crc") + 1)); - CHECK_ALLOC_LOG(crc_path, NULL); - memset(crc_path, 0, - sizeof(char) * (strlen(filename) + - strlen(".crc") + 1)); - memcpy(crc_path, filename, - sizeof(char) * strlen(filename)); - crc_path = strcat(crc_path, ".crc"); - return crc_path; -} - int knot_zdump_dump_and_swap(knot_zone_contents_t *zone, const char *temp_zonedb, const char *destination_zonedb, diff --git a/src/knot/zone/zone-dump.h b/src/knot/zone/zone-dump.h index daf6c18..97f1318 100644 --- a/src/knot/zone/zone-dump.h +++ b/src/knot/zone/zone-dump.h @@ -38,7 +38,7 @@ enum { }; /*! \brief Magic identifier: { "knot", maj_ver, min_ver, revision } */ -#define MAGIC_BYTES {'k', 'n', 'o', 't', '0', '8', '0'} +#define MAGIC_BYTES {'k', 'n', 'o', 't', '1', 'r', 'c'} /*! * \brief Dumps given zone to binary file. @@ -84,6 +84,17 @@ int knot_zdump_rrset_serialize(const knot_rrset_t *rrset, uint8_t **stream, int knot_zdump_rrset_serialize(const knot_rrset_t *rrset, uint8_t **stream, size_t *size); +/*! + * \brief Checks if zone uses DNSSEC and/or NSEC3 + * + * \param zone Zone to be checked. + * + * \retval 0 if zone is not secured. + * \retval 2 if zone uses NSEC3 + * \retval 1 if zone uses NSEC + */ +int zone_is_secure(knot_zone_contents_t *zone); + int knot_zdump_dump_and_swap(knot_zone_contents_t *zone, const char *temp_zonedb, const char *destination_zonedb, diff --git a/src/knot/zone/zone-load.c b/src/knot/zone/zone-load.c index 9ab0e8d..5710fe9 100644 --- a/src/knot/zone/zone-load.c +++ b/src/knot/zone/zone-load.c @@ -310,7 +310,7 @@ static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f, } else if (use_ids && !in_the_zone) { /* destroy the node */ if (id_array[dname_id]->node != NULL) { knot_node_free(&id_array[dname_id]-> - node, 0, 0); + node, 0); } /* Also sets node to NULL! */ } @@ -571,7 +571,7 @@ static knot_node_t *knot_load_node(FILE *f, knot_dname_t **id_array) if (parent_id != 0) { knot_node_set_parent(node, id_array[parent_id]->node); - assert(knot_node_parent(node, 0) != NULL); + assert(knot_node_parent(node) != NULL); } else { knot_node_set_parent(node, NULL); } @@ -580,7 +580,7 @@ static knot_node_t *knot_load_node(FILE *f, knot_dname_t **id_array) for (int i = 0; i < rrset_count; i++) { if ((tmp_rrset = knot_load_rrset(f, id_array, 1)) == NULL) { - knot_node_free(&node, 1, 0); + knot_node_free(&node, 0); //TODO what else to free? fprintf(stderr, "zone: Could not load rrset.\n"); return NULL; @@ -611,7 +611,6 @@ static void find_and_set_wildcard_child(knot_zone_contents_t *zone, knot_node_t *node, int nsec3) { knot_dname_t *chopped = knot_dname_left_chop(node->owner); - assert(chopped); knot_node_t *wildcard_parent; if (!nsec3) { wildcard_parent = @@ -1065,8 +1064,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader) } } - assert(knot_node_previous(knot_zone_contents_apex(contents), 0) - == NULL); + assert(knot_node_previous(knot_zone_contents_apex(contents)) == NULL); knot_node_set_previous(knot_zone_contents_get_apex(contents), last_node); @@ -1120,7 +1118,7 @@ knot_zone_t *knot_zload_load(zloader_t *loader) } if (nsec3_node_count) { - assert(knot_node_previous(nsec3_first, 0) == NULL); + assert(knot_node_previous(nsec3_first) == NULL); knot_node_set_previous(nsec3_first, last_node); /* CLEANUP */ // nsec3_first->prev = last_node; @@ -1134,6 +1132,13 @@ knot_zone_t *knot_zload_load(zloader_t *loader) free(id_array); dbg_zload("zone loaded, returning: %p\n", zone); + +// knot_zone_contents_integrity_check(zone->contents); + + //knot_dname_table_dump(zone->contents->dname_table); + + //knot_zone_contents_dump(zone->contents); + return zone; } diff --git a/src/libknot/dname.c b/src/libknot/dname.c index 869b342..e4b7d5f 100644 --- a/src/libknot/dname.c +++ b/src/libknot/dname.c @@ -408,8 +408,8 @@ knot_dname_t *knot_dname_new_from_str(const char *name, uint size, dbg_dname("\n"); if (dname->size <= 0) { - fprintf(stderr, "Could not parse domain name " - "from string: '%.*s'\n", size, name); + dbg_dname("Could not parse domain name " + "from string: '%.*s'\n", size, name); } assert(dname->name != NULL); @@ -491,6 +491,10 @@ knot_dname_t *knot_dname_parse_from_wire(const uint8_t *wire, int pointer_used = 0; while (p < size && wire[p] != 0) { + /* Check maximum number of labels (may overflow). */ + if (l == KNOT_MAX_DNAME_LABELS) { + return NULL; + } labels[l] = i; dbg_dname("Next label (%d.) position: %zu\n", l, i); @@ -508,7 +512,15 @@ knot_dname_t *knot_dname_parse_from_wire(const uint8_t *wire, } else { // label; first byte is label length uint8_t length = *(wire + p); -// printf("Label, length: %u.\n", length); + /* Check label length (maximum 63 bytes allowed). */ + if (length > 63) { + return NULL; + } + /* Check if there's enough space. */ + if (i + length + 2 > KNOT_MAX_DNAME_LENGTH) { + return NULL; + } + //printf("Label %d (max %d), length: %u.\n", l, KNOT_MAX_DNAME_LABELS, length); memcpy(name + i, wire + p, length + 1); p += length + 1; i += length + 1; @@ -693,27 +705,20 @@ uint8_t knot_dname_size_part(const knot_dname_t *dname, int labels) /*----------------------------------------------------------------------------*/ -const struct knot_node *knot_dname_node(const knot_dname_t *dname, - int check_version) +const struct knot_node *knot_dname_node(const knot_dname_t *dname) { - if (check_version) { - return knot_node_current(dname->node); - } else { - return dname->node; - } + return knot_dname_get_node(dname); } /*----------------------------------------------------------------------------*/ -struct knot_node *knot_dname_get_node(knot_dname_t *dname, - int check_version) +struct knot_node *knot_dname_get_node(const knot_dname_t *dname) { - if (check_version) { - return knot_node_get_current(dname->node); - } else { - return dname->node; + if (dname == NULL) { + return NULL; } + return dname->node; } /*----------------------------------------------------------------------------*/ @@ -741,10 +746,42 @@ int knot_dname_is_fqdn(const knot_dname_t *dname) knot_dname_t *knot_dname_left_chop(const knot_dname_t *dname) { + if (dname == NULL || + /* Root domain. */ + ((knot_dname_label_count(dname) == 0) && + (knot_dname_is_fqdn(dname)))) { + return NULL; + } + knot_dname_t *parent = knot_dname_new(); if (parent == NULL) { return NULL; } + + // last label, the result should be root domain + if (dname->label_count == 1) { + dbg_dname_verb("Chopping last label.\n"); + parent->label_count = 0; + + parent->name = (uint8_t *)malloc(1); + if (parent->name == NULL) { + ERR_ALLOC_FAILED; + knot_dname_free(&parent); + return NULL; + } + + *parent->name = 0; + + parent->size = 1; + + return parent; + } + +// if (dname->label_count <= 1) { +// /* Nothing to chop. */ +// return NULL; +// } + parent->size = dname->size - dname->name[0] - 1; parent->name = (uint8_t *)malloc(parent->size); @@ -763,6 +800,7 @@ knot_dname_t *knot_dname_left_chop(const knot_dname_t *dname) } memcpy(parent->name, &dname->name[dname->name[0] + 1], parent->size); + short first_label_length = dname->labels[1]; diff --git a/src/libknot/dname.h b/src/libknot/dname.h index 9efcffe..bb5e2db 100644 --- a/src/libknot/dname.h +++ b/src/libknot/dname.h @@ -215,11 +215,9 @@ uint8_t knot_dname_size_part(const knot_dname_t *dname, int labels); * * \return Zone node the domain name belongs to or NULL if none. */ -const struct knot_node *knot_dname_node(const knot_dname_t *dname, - int check_version); +const struct knot_node *knot_dname_node(const knot_dname_t *dname); -struct knot_node *knot_dname_get_node(knot_dname_t *dname, - int check_version); +struct knot_node *knot_dname_get_node(const knot_dname_t *dname); void knot_dname_set_node(knot_dname_t *dname, struct knot_node *node); diff --git a/src/libknot/edns.c b/src/libknot/edns.c index 05ebd7b..435e27c 100644 --- a/src/libknot/edns.c +++ b/src/libknot/edns.c @@ -32,9 +32,6 @@ enum knot_edns_consts { KNOT_EDNS_OPTION_STEP = 1 }; -/*! \brief Minimum size of EDNS OPT RR in wire format. */ -static const short KNOT_EDNS_MIN_SIZE = 11; - /*----------------------------------------------------------------------------*/ knot_opt_rr_t *knot_edns_new() @@ -42,6 +39,7 @@ knot_opt_rr_t *knot_edns_new() knot_opt_rr_t *opt_rr = (knot_opt_rr_t *)malloc( sizeof(knot_opt_rr_t)); CHECK_ALLOC_LOG(opt_rr, NULL); + memset(opt_rr, 0, sizeof(knot_opt_rr_t)); opt_rr->size = KNOT_EDNS_MIN_SIZE; opt_rr->option_count = 0; opt_rr->options_max = 0; @@ -174,15 +172,16 @@ int knot_edns_new_from_rr(knot_opt_rr_t *opt_rr, // i.e. preceded by their length if (rdata != NULL) { assert(knot_rdata_item_count(rdata) == 1); + uint16_t size = knot_rdata_item(rdata, 0)->raw_data[0]; const uint8_t *raw = (const uint8_t *) knot_rdata_item(rdata, 0)->raw_data; - uint16_t size = knot_wire_read_u16(raw); int pos = 2; assert(size > 0); while (pos - 2 < size) { // ensure there is enough data to parse the OPTION CODE // and OPTION LENGTH if (size - pos + 2 < 4) { + dbg_edns("Not enough data to parse.\n"); return KNOT_EMALF; } uint16_t opt_code = knot_wire_read_u16(raw + pos); @@ -191,16 +190,23 @@ int knot_edns_new_from_rr(knot_opt_rr_t *opt_rr, // there should be enough data for parsing the OPTION // data if (size - pos - 2 < opt_size) { + dbg_edns("Not enough data to parse options: " + "size - pos - 2=%d, opt_size=%d\n", + size - pos - 2, opt_size); return KNOT_EMALF; } rc = knot_edns_add_option(opt_rr, opt_code, opt_size, raw + pos + 4); if (rc != KNOT_EOK) { + dbg_edns("Could not add option.\n"); return rc; } pos += 4 + opt_size; } } + + + dbg_edns("EDNS created.\n"); return KNOT_EOK; } @@ -302,8 +308,11 @@ int knot_edns_add_option(knot_opt_rr_t *opt_rr, uint16_t code, sizeof(knot_opt_option_t)); CHECK_ALLOC_LOG(options_new, KNOT_ENOMEM); memcpy(options_new, opt_rr->options, opt_rr->option_count); + + knot_opt_option_t *old_options = opt_rr->options; opt_rr->options = options_new; opt_rr->options_max += KNOT_EDNS_OPTION_STEP; + free(old_options); } dbg_edns("Adding option.\n"); @@ -359,6 +368,11 @@ short knot_edns_to_wire(const knot_opt_rr_t *opt_rr, uint8_t *wire, } uint8_t *pos = wire; + + dbg_edns_detail("Putting OPT RR to the wire format. Size: %zu, " + "position: %zu\n", + opt_rr->size, (size_t)(pos - wire)); + *(pos++) = 0; knot_wire_write_u16(pos, KNOT_RRTYPE_OPT); pos += 2; @@ -369,12 +383,17 @@ short knot_edns_to_wire(const knot_opt_rr_t *opt_rr, uint8_t *wire, knot_wire_write_u16(pos, opt_rr->flags); pos += 2; + dbg_edns_detail("Leaving space for RDLENGTH at pos %zu\n", + (size_t)(pos - wire)); + uint8_t *rdlen = pos; uint16_t len = 0; pos += 2; // OPTIONs for (int i = 0; i < opt_rr->option_count; ++i) { + dbg_edns_detail("Inserting option #%d at pos %zu\n", + i, (size_t)(pos - wire)); knot_wire_write_u16(pos, opt_rr->options[i].code); pos += 2; knot_wire_write_u16(pos, opt_rr->options[i].length); @@ -384,6 +403,8 @@ short knot_edns_to_wire(const knot_opt_rr_t *opt_rr, uint8_t *wire, len += 4 + opt_rr->options[i].length; } + dbg_edns_detail("Final pos %zu\n", (size_t)(pos - wire)); + knot_wire_write_u16(rdlen, len); return opt_rr->size; @@ -402,15 +423,30 @@ short knot_edns_size(knot_opt_rr_t *opt_rr) /*----------------------------------------------------------------------------*/ +void knot_edns_free_options(knot_opt_rr_t *opt_rr) +{ + if (opt_rr->option_count > 0) { + /* Free the option data, if any. */ + for (int i = 0; i < opt_rr->option_count; i++) { + struct knot_opt_option option = opt_rr->options[i]; + if (option.data != NULL) { + free(option.data); + } + } + free(opt_rr->options); + } +} + +/*----------------------------------------------------------------------------*/ + void knot_edns_free(knot_opt_rr_t **opt_rr) { if (opt_rr == NULL || *opt_rr == NULL) { return; } - if ((*opt_rr)->option_count > 0) { - free((*opt_rr)->options); - } + knot_edns_free_options(*opt_rr); + free(*opt_rr); *opt_rr = NULL; } diff --git a/src/libknot/edns.h b/src/libknot/edns.h index 010d155..022ac36 100644 --- a/src/libknot/edns.h +++ b/src/libknot/edns.h @@ -81,6 +81,9 @@ enum knot_edns_option_codes { EDNS_OPTION_NSID = (uint16_t)3 /*!< NSID option code. */ }; +/*! \brief Minimum size of EDNS OPT RR in wire format. */ +static const short KNOT_EDNS_MIN_SIZE = 11; + /*----------------------------------------------------------------------------*/ /*! * \brief Creates new empty OPT RR structure for holding EDNS parameters. @@ -261,6 +264,8 @@ short knot_edns_to_wire(const knot_opt_rr_t *opt_rr, uint8_t *wire, */ short knot_edns_size(knot_opt_rr_t *opt_rr); +void knot_edns_free_options(knot_opt_rr_t *opt_rr); + /*! * \brief Properly destroys the OPT RR structure. * diff --git a/src/libknot/hash/cuckoo-hash-table.c b/src/libknot/hash/cuckoo-hash-table.c index c5d1c4f..6688a40 100644 --- a/src/libknot/hash/cuckoo-hash-table.c +++ b/src/libknot/hash/cuckoo-hash-table.c @@ -379,6 +379,8 @@ static uint ck_check_used_twice(da_array_t *used, uint32_t hash) static inline uint ck_items_match(const ck_hash_table_item_t *item, const char *key, size_t length) { + assert(item != NULL); + return (length == item->key_length && (strncmp(item->key, key, length) == 0)); } @@ -414,7 +416,13 @@ static ck_hash_table_item_t **ck_find_in_stash(const ck_hash_table_t *table, "with searched item (key %.*s (size %u)).\n", (int)item->item->key_length, item->item->key, item->item->key_length, (int)length, key, length); - if (ck_items_match(item->item, key, length)) { + /*! \todo Can the item be NULL? + * Sometimes it crashed on assert in ck_items_match(), + * But I'm not sure if this may happen or if the + * semantics of the stash are that all items must be + * non-NULL. + */ + if (item->item && ck_items_match(item->item, key, length)) { return &item->item; } item = item->next; @@ -1137,7 +1145,7 @@ int ck_shallow_copy(const ck_hash_table_t *from, ck_hash_table_t **to) // copy the ck_hash_table_item_t within them. ck_stash_item_t *si = from->stash; ck_stash_item_t **pos = &(*to)->stash; - dbg_ck_verb(stderr, "Copying hash table stash.\n"); + dbg_ck_verb("Copying hash table stash.\n"); while (si != NULL) { ck_stash_item_t *si_new = (ck_stash_item_t *) malloc(sizeof(ck_stash_item_t)); @@ -1202,7 +1210,182 @@ int ck_shallow_copy(const ck_hash_table_t *from, ck_hash_table_t **to) /*----------------------------------------------------------------------------*/ -int ck_apply(ck_hash_table_t *table, +static int ck_copy_items(ck_hash_table_item_t **from, + ck_hash_table_item_t **to, uint32_t count) +{ + assert(from != NULL); + assert(to != NULL); + + for (int i = 0; i < count; ++i) { + if (from[i] != NULL) { + to[i] = (ck_hash_table_item_t *) + malloc(sizeof(ck_hash_table_item_t)); + + if (to[i] == NULL) { + return -2; + } + + memcpy(to[i], from[i], sizeof(ck_hash_table_item_t)); + } else { + to[i] = NULL; + } + } + + return 0; +} + +/*----------------------------------------------------------------------------*/ + +void ck_deep_copy_cleanup(ck_hash_table_t *table, int table_count) +{ + // free tables with their items + for (int t = 0; t < table_count; ++t) { + for (int i = 0; i < hashsize(table->table_size_exp); ++i) { + free(table->tables[t][i]); + } + free(table->tables[t]); + } + + // free stash items with hash table items in them + ck_stash_item_t *si = table->stash; + ck_stash_item_t *to_free; + while (si != NULL) { + to_free = si; + si = si->next; + free(to_free->item); + free(to_free); + } + + free(table); +} + +/*----------------------------------------------------------------------------*/ + +int ck_deep_copy(ck_hash_table_t *from, ck_hash_table_t **to) +{ + if (from == NULL || to == NULL) { + return -1; + } + + dbg_ck("Allocating new table...\n"); + *to = (ck_hash_table_t *)malloc(sizeof(ck_hash_table_t)); + + if (*to == NULL) { + ERR_ALLOC_FAILED; + return -2; + } + memset(*to, 0, sizeof(ck_hash_table_t)); + + // copy table count and table size exponent + (*to)->table_size_exp = from->table_size_exp; + (*to)->table_count = from->table_count; + assert((*to)->table_size_exp <= 32); + + dbg_ck("Creating hash table for %u items.\n", from->table_count); + dbg_ck("Exponent: %u, number of tables: %u\n ", + (*to)->table_size_exp, (*to)->table_count); + dbg_ck("Table size: %u items, each %zu bytes, total %zu bytes\n", + hashsize((*to)->table_size_exp), + sizeof(ck_hash_table_item_t *), + hashsize((*to)->table_size_exp) + * sizeof(ck_hash_table_item_t *)); + + // create tables + for (uint t = 0; t < (*to)->table_count; ++t) { + dbg_ck("Creating table %u...\n", t); + (*to)->tables[t] = (ck_hash_table_item_t **)malloc( + hashsize((*to)->table_size_exp) + * sizeof(ck_hash_table_item_t *)); + if ((*to)->tables[t] == NULL) { + ERR_ALLOC_FAILED; + for (uint i = 0; i < t; ++i) { + free((*to)->tables[i]); + } + free(*to); + return -2; + } + + // copy the table with all hash table items + dbg_ck("Copying table %u...\n", t); + int ret = ck_copy_items(from->tables[t], (*to)->tables[t], + hashsize((*to)->table_size_exp)); + if (ret != 0) { + dbg_ck("Failed!\n"); + // free all tables created until now + ck_deep_copy_cleanup(*to, t); + return ret; + } + } + + // copy the stash - we must explicitly copy each stash item, + // together with the hash table item stored in it + ck_stash_item_t *si = from->stash; + ck_stash_item_t **pos = &(*to)->stash; + dbg_ck_verb("Copying hash table stash.\n"); + while (si != NULL) { + ck_stash_item_t *si_new = (ck_stash_item_t *) + malloc(sizeof(ck_stash_item_t)); + if (si_new == NULL) { + ERR_ALLOC_FAILED; + ck_deep_copy_cleanup(*to, (*to)->table_count); + return -2; + } + + dbg_ck("Copying stash item: %p with item %p, ", si, si->item); + dbg_ck("key: %.*s\n", (int)si->item->key_length, si->item->key); + + si_new->item = (ck_hash_table_item_t *) + malloc(sizeof(ck_hash_table_item_t)); + + if (si_new->item == NULL) { + ERR_ALLOC_FAILED; + ck_deep_copy_cleanup(*to, (*to)->table_count); + return -2; + } + + memcpy(si_new->item, si->item, sizeof(ck_hash_table_item_t)); + + *pos = si_new; + pos = &si_new->next; + si = si->next; + + + dbg_ck("Old stash item: %p with item %p, ", si, + ((si == NULL) ? NULL : si->item)); + if (si != NULL) { + dbg_ck("key: %.*s\n", (int)si->item->key_length, si->item->key); + } else { + dbg_ck("\n"); + } + dbg_ck("New stash item: %p with item %p, ", si_new, + si_new->item); + dbg_ck("key: %.*s\n", (int)si_new->item->key_length, + si_new->item->key); + } + + *pos = NULL; + + // there should be no item being hashed right now + /*! \todo This operation should not be done while inserting / rehashing. + */ + assert(from->hashed == NULL); + (*to)->hashed = NULL; + + // initialize rehash/insert mutex + pthread_mutex_init(&(*to)->mtx_table, NULL); + + // copy the generation + (*to)->generation = from->generation; + + // copy the hash functions + memcpy(&(*to)->hash_system, &from->hash_system, sizeof(us_system_t)); + + return 0; +} + +/*----------------------------------------------------------------------------*/ + +int ck_apply(ck_hash_table_t *table, void (*function)(ck_hash_table_item_t *item, void *data), void *data) { diff --git a/src/libknot/hash/cuckoo-hash-table.h b/src/libknot/hash/cuckoo-hash-table.h index dd78294..eaa6a89 100644 --- a/src/libknot/hash/cuckoo-hash-table.h +++ b/src/libknot/hash/cuckoo-hash-table.h @@ -309,6 +309,8 @@ ck_hash_table_item_t *ck_remove_item(ck_hash_table_t *table, const char *key, */ int ck_shallow_copy(const ck_hash_table_t *from, ck_hash_table_t **to); +int ck_deep_copy(ck_hash_table_t *from, ck_hash_table_t **to); + int ck_apply(ck_hash_table_t *table, void (*function)(ck_hash_table_item_t *item, void *data), void *data); diff --git a/src/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c index a4e4ae7..547a629 100644 --- a/src/libknot/nameserver/name-server.c +++ b/src/libknot/nameserver/name-server.c @@ -98,6 +98,11 @@ static const knot_zone_t *ns_get_zone_for_qname(knot_zonedb_t *zdb, zone = knot_zonedb_find_zone_for_name(zdb, name); /* Directly discard. */ knot_dname_free(&name); + /* If zone does not exist, search for its parent zone, + this will later result to NODATA answer. */ + if (zone == NULL) { + zone = knot_zonedb_find_zone_for_name(zdb, qname); + } } else { zone = knot_zonedb_find_zone_for_name(zdb, qname); } @@ -148,7 +153,7 @@ static knot_rrset_t *ns_synth_from_wildcard( // but there is no way to distinguish it when deleting // temporary RRSets knot_rdata_t *rdata_copy = knot_rdata_deep_copy(rdata, - knot_rrset_type(synth_rrset)); + knot_rrset_type(synth_rrset), 0); if (rdata_copy == NULL) { knot_rrset_deep_free(&synth_rrset, 1, 1, 0); return NULL; @@ -312,7 +317,7 @@ dbg_ns_exec( knot_rrset_rdata(cname_rrset)); dbg_ns("CNAME name from RDATA: %p\n", cname); // change the node to the node of that name - *node = knot_dname_node(cname, 1); + *node = knot_dname_node(cname); dbg_ns("This name's node: %p\n", *node); // // it is not an old node and if yes, skip it // if (knot_node_is_old(*node)) { @@ -470,24 +475,22 @@ static void ns_put_additional_for_rrset(knot_packet_t *resp, while (rdata != NULL) { dbg_ns("Getting name from RDATA, type %s..\n", knot_rrtype_to_string(knot_rrset_type(rrset))); - dname = knot_rdata_get_name(rdata, - knot_rrset_type(rrset)); + dname = knot_rdata_get_name(rdata, knot_rrset_type(rrset)); assert(dname != NULL); - node = knot_dname_node(dname, 1); -// // check if the node is not old and if yes, take the new one -// if (knot_node_is_old(node)) { -// node = knot_node_new_node(node); -// } + node = knot_dname_node(dname); - dbg_ns_detail("Node saved in RDATA dname: %p\n", node); +// dbg_ns_detail("Node saved in RDATA dname: %p\n", node); +// char *name = knot_dname_to_str(dname); +// dbg_ns_detail("Owner of the node: %p, dname: %p (%s)\n", +// node->owner, dname, name); +// free(name); +// knot_node_dump((knot_node_t *)node, (void *)1); if (node != NULL && node->owner != dname) { // the stored node should be the closest encloser assert(knot_dname_is_subdomain(dname, node->owner)); // try the wildcard child, if any - node = knot_node_wildcard_child(node, 1); -// // this should not be old node!! -// assert(!knot_node_is_old(node)); + node = knot_node_wildcard_child(node); } knot_rrset_t *rrset_add; @@ -731,10 +734,10 @@ static int ns_put_covering_nsec3(const knot_zone_contents_t *zone, const knot_node_t *prev, *node; /*! \todo Check version. */ int match = knot_zone_contents_find_nsec3_for_name(zone, name, - &node, &prev, 1); + &node, &prev); assert(match >= 0); - node = knot_node_current(node); - prev = knot_node_current(prev); +// node = knot_node_current(node); +// prev = knot_node_current(prev); if (match == KNOT_ZONE_NAME_FOUND){ // run-time collision => SERVFAIL @@ -811,10 +814,10 @@ dbg_ns_exec( */ const knot_node_t *nsec3_node = NULL; const knot_dname_t *next_closer = NULL; - while ((nsec3_node = knot_node_nsec3_node((*closest_encloser), 1)) + while ((nsec3_node = knot_node_nsec3_node((*closest_encloser))) == NULL) { next_closer = knot_node_owner((*closest_encloser)); - *closest_encloser = knot_node_parent(*closest_encloser, 1); + *closest_encloser = knot_node_parent(*closest_encloser); if (*closest_encloser == NULL) { // there are no NSEC3s to add return KNOT_EOK; @@ -957,7 +960,7 @@ static void ns_put_nsec_nsec3_nodata(const knot_node_t *node, return; } - knot_node_t *nsec3_node = knot_node_get_nsec3_node(node, 1); + knot_node_t *nsec3_node = knot_node_get_nsec3_node(node); knot_rrset_t *rrset = NULL; if ((rrset = knot_node_get_rrset(node, KNOT_RRTYPE_NSEC)) != NULL || (nsec3_node != NULL && (rrset = @@ -1001,13 +1004,11 @@ static int ns_put_nsec_nxdomain(const knot_dname_t *qname, if (previous == NULL) { /*! \todo Check version. */ previous = knot_zone_contents_find_previous(zone, qname); + assert(previous != NULL); while (!knot_node_is_auth(previous)) { - previous = knot_node_previous(previous, 1); + previous = knot_node_previous(previous); } - - previous = knot_node_current(previous); - assert(previous != NULL); } char *name = knot_dname_to_str(previous->owner); @@ -1044,16 +1045,22 @@ static int ns_put_nsec_nxdomain(const knot_dname_t *qname, while (knot_dname_compare(knot_node_owner(prev_new), wildcard) > 0) { - dbg_ns("Previous node: %s\n", - knot_dname_to_str(knot_node_owner(prev_new))); +dbg_ns_exec( + char *name = knot_dname_to_str(knot_node_owner(prev_new)); + dbg_ns("Previous node: %s\n", name); + free(name); +); assert(prev_new != knot_zone_contents_apex(zone)); - prev_new = knot_node_previous(prev_new, 1); + prev_new = knot_node_previous(prev_new); } assert(knot_dname_compare(knot_node_owner(prev_new), wildcard) < 0); - dbg_ns("Previous node: %s\n", - knot_dname_to_str(knot_node_owner(prev_new))); +dbg_ns_exec( + char *name = knot_dname_to_str(knot_node_owner(prev_new)); + dbg_ns("Previous node: %s\n", name); + free(name); +); /* Directly discard dname. */ knot_dname_free(&wildcard); @@ -1226,13 +1233,11 @@ static void ns_put_nsec_wildcard(const knot_zone_contents_t *zone, // check if we have previous; if not, find one using the tree if (previous == NULL) { previous = knot_zone_contents_find_previous(zone, qname); + assert(previous != NULL); while (!knot_node_is_auth(previous)) { - previous = knot_node_previous(previous, 1); + previous = knot_node_previous(previous); } - - previous = knot_node_current(previous); - assert(previous != NULL); } knot_rrset_t *rrset = @@ -1280,7 +1285,7 @@ static int ns_put_nsec_nsec3_wildcard_nodata(const knot_node_t *node, const knot_node_t *nsec3_node; if (ret == KNOT_EOK - && (nsec3_node = knot_node_nsec3_node(node, 1)) + && (nsec3_node = knot_node_nsec3_node(node)) != NULL) { ns_put_nsec3_from_node(nsec3_node, resp); } @@ -1350,21 +1355,59 @@ static int ns_put_nsec_nsec3_wildcard_answer(const knot_node_t *node, static inline int ns_referral(const knot_node_t *node, const knot_zone_contents_t *zone, const knot_dname_t *qname, - knot_packet_t *resp) + knot_packet_t *resp, + uint16_t qtype) { dbg_ns("Referral response.\n"); while (!knot_node_is_deleg_point(node)) { - assert(knot_node_parent(node, 1) != NULL); - node = knot_node_parent(node, 1); + assert(knot_node_parent(node) != NULL); + node = knot_node_parent(node); } + // Special handling of DS queries + if (qtype == KNOT_RRTYPE_DS) { + knot_rrset_t *ds_rrset = knot_node_get_rrset(node, + KNOT_RRTYPE_DS); + int ret = KNOT_EOK; + + if (ds_rrset) { + knot_response_add_rrset_answer(resp, ds_rrset, 1, 0, + 0, 1); + if (DNSSEC_ENABLED + && knot_query_dnssec_requested( + knot_packet_query(resp))) { + ns_add_rrsigs(ds_rrset, resp, node->owner, + knot_response_add_rrset_authority, + 1); + } + } else { + // normal NODATA response + /*! \todo Handle in some generic way. */ + + dbg_ns("Adding NSEC/NSEC3 for NODATA.\n"); + ns_put_nsec_nsec3_nodata(node, resp); + + // wildcard delegations not supported! +// if (knot_dname_is_wildcard(node->owner)) { +// dbg_ns("Putting NSEC/NSEC3 for wildcard" +// " NODATA\n"); +// ret = ns_put_nsec_nsec3_wildcard_nodata(node, +// closest_encloser, previous, zone, qname, +// resp); +// } + ns_put_authority_soa(zone, resp); + } + + return ret; + } + knot_rrset_t *rrset = knot_node_get_rrset(node, KNOT_RRTYPE_NS); assert(rrset != NULL); // TODO: wildcards?? //ns_check_wildcard(name, resp, &rrset); - + knot_response_add_rrset_authority(resp, rrset, 1, 0, 0, 1); ns_add_rrsigs(rrset, resp, node->owner, knot_response_add_rrset_authority, 1); @@ -1387,7 +1430,7 @@ static inline int ns_referral(const knot_node_t *node, // if NSEC3 enabled, search for NSEC3 if (knot_zone_contents_nsec3_enabled(zone)) { const knot_node_t *nsec3_node = - knot_node_nsec3_node(node, 1); + knot_node_nsec3_node(node); dbg_ns("There is no DS, putting NSEC3s...\n"); if (nsec3_node != NULL) { dbg_ns("Putting NSEC3s from the node.\n"); @@ -1406,7 +1449,7 @@ static inline int ns_referral(const knot_node_t *node, /*! \todo Check return value? */ knot_response_add_rrset_authority( resp, nsec, 1, 1, 0, 1); - if ((nsec = knot_rrset_rrsigs(nsec)) != NULL) { + if ((nsec = knot_rrset_get_rrsigs(nsec)) != NULL) { knot_response_add_rrset_authority( resp, nsec, 1, 1, 0, 1); } @@ -1465,7 +1508,7 @@ static int ns_answer_from_node(const knot_node_t *node, //assert(knot_node_rrset_count(closest_encloser) > 0); dbg_ns("Adding NSEC/NSEC3 for NXDOMAIN.\n"); ret = ns_put_nsec_nsec3_nxdomain(zone, - knot_node_previous(node, 1), closest_encloser, + knot_node_previous(node), closest_encloser, qname, resp); } else { dbg_ns("Adding NSEC/NSEC3 for NODATA.\n"); @@ -1725,7 +1768,7 @@ have_node: if (knot_node_is_deleg_point(closest_encloser) || knot_node_is_non_auth(closest_encloser)) { - ret = ns_referral(closest_encloser, zone, qname, resp); + ret = ns_referral(closest_encloser, zone, qname, resp, qtype); goto finalize; } @@ -1741,7 +1784,7 @@ have_node: } // else check for a wildcard child const knot_node_t *wildcard_node = - knot_node_wildcard_child(closest_encloser, 1); + knot_node_wildcard_child(closest_encloser); if (wildcard_node == NULL) { dbg_ns("No wildcard node. (cname: %d)\n", @@ -1769,7 +1812,7 @@ have_node: // now we have the node for answering if (knot_node_is_deleg_point(node) || knot_node_is_non_auth(node)) { - ret = ns_referral(node, zone, qname, resp); + ret = ns_referral(node, zone, qname, resp, qtype); goto finalize; } @@ -1974,7 +2017,15 @@ static int ns_error_response_to_wire(knot_packet_t *resp, uint8_t *wire, /*! \todo Why is this copied?? Why we cannot use resp->wireformat?? */ memcpy(wire, rwire, rsize); - *wire_size = rsize; + if (resp->opt_rr.version != EDNS_NOT_SUPPORTED) { + short edns_size = knot_edns_to_wire(&resp->opt_rr, wire + rsize, + *wire_size - rsize); + if (edns_size > 0) { + *wire_size = rsize + edns_size; + } + } else { + *wire_size = rsize; + } return KNOT_EOK; } @@ -2465,7 +2516,9 @@ static int ns_ixfr(knot_ns_xfr_t *xfr) dbg_ns("IXFR query does not contain authority record.\n"); knot_response_set_rcode(xfr->response, KNOT_RCODE_FORMERR); /*! \todo Probably rename the function. */ - ns_xfr_send_and_clear(xfr, 1); + if (ns_xfr_send_and_clear(xfr, 1) == KNOT_ECONN) { + return KNOT_ECONN; + } //socket_close(xfr->session); return KNOT_EMALF; } @@ -2481,7 +2534,9 @@ static int ns_ixfr(knot_ns_xfr_t *xfr) dbg_ns("IXFR query is malformed.\n"); knot_response_set_rcode(xfr->response, KNOT_RCODE_FORMERR); /*! \todo Probably rename the function. */ - ns_xfr_send_and_clear(xfr, 1); + if (ns_xfr_send_and_clear(xfr, 1) == KNOT_ECONN) { + return KNOT_ECONN; + } //socket_close(xfr->session); /*! \todo Remove for UDP. */ return KNOT_EMALF; } @@ -2635,6 +2690,30 @@ knot_nameserver_t *knot_ns_create() /*----------------------------------------------------------------------------*/ +void knot_ns_set_nsid(knot_nameserver_t *nameserver, const char *nsid, size_t len) +{ + if (nameserver == NULL) { + dbg_ns("NS: set_nsid: nameserver=NULL.\n"); + return; + } + + if (nsid == NULL) { + /* This is fine. */ + return; + } + + int ret = knot_edns_add_option(nameserver->opt_rr, EDNS_OPTION_NSID, + len, (const uint8_t *)nsid); + if (ret != KNOT_EOK) { + dbg_ns("NS: set_nsid: could not add EDNS option.\n"); + return; + } + + dbg_ns("NS: set_nsid: added successfully.\n"); +} + +/*----------------------------------------------------------------------------*/ + int knot_ns_parse_packet(const uint8_t *query_wire, size_t qsize, knot_packet_t *packet, knot_packet_type_t *type) { @@ -2820,7 +2899,8 @@ int knot_ns_prep_normal_response(knot_nameserver_t *nameserver, // set the OPT RR to the response if (knot_query_edns_supported(query)) { - ret = knot_response_add_opt(*resp, nameserver->opt_rr, 1); + ret = knot_response_add_opt(*resp, nameserver->opt_rr, 1, + knot_query_nsid_requested(query)); if (ret != KNOT_EOK) { dbg_ns("Failed to set OPT RR to the response" ": %s\n", knot_strerror(ret)); @@ -3097,7 +3177,7 @@ int knot_ns_answer_axfr(knot_nameserver_t *nameserver, knot_ns_xfr_t *xfr) xfr->wire_size); rcu_read_unlock(); knot_packet_free(&xfr->response); - return KNOT_EOK; + return ret; } /*! @@ -3119,7 +3199,7 @@ int knot_ns_answer_axfr(knot_nameserver_t *nameserver, knot_ns_xfr_t *xfr) * and when it does not. E.g. if there was problem in sending * packet, it will probably fail when sending the SERVFAIL also. */ - if (ret < 0) { + if (ret < 0 && ret != KNOT_ECONN) { dbg_ns("AXFR failed, sending SERVFAIL.\n"); // now only one type of error (SERVFAIL), later maybe more /*! \todo xfr->wire is not NULL, will fail on assert! */ @@ -3137,7 +3217,7 @@ int knot_ns_answer_axfr(knot_nameserver_t *nameserver, knot_ns_xfr_t *xfr) knot_packet_free(&xfr->response); - return KNOT_EOK; + return ret; } /*----------------------------------------------------------------------------*/ @@ -3226,24 +3306,44 @@ int knot_ns_process_axfrin(knot_nameserver_t *nameserver, knot_ns_xfr_t *xfr) knot_zone_contents_t *zone = constr_zone->contents; assert(zone != NULL); - dbg_ns("ns_process_axfrin: adjusting zone.\n"); - knot_zone_contents_adjust(zone, 0); - /* Create and fill hash table */ dbg_ns("ns_process_axfrin: filling hash table.\n"); int rc = knot_zone_contents_create_and_fill_hash_table(zone); if (rc != KNOT_EOK) { return KNOT_ERROR; // TODO: change error code } + + dbg_ns("ns_process_axfrin: adjusting zone.\n"); + rc = knot_zone_contents_adjust(zone); + if (rc != KNOT_EOK) { + return rc; + } + + dbg_ns("ns_process_axfrin: checking loops.\n"); + rc = knot_zone_contents_check_loops(zone); + if (rc != KNOT_EOK) { + return rc; + } // save the zone contents to the xfr->data xfr->data = zone; + xfr->flags |= XFR_FLAG_AXFR_FINISHED; + + assert(zone->nsec3_nodes != NULL); // free the structure used for processing XFR assert(constr_zone->rrsigs == NULL); free(constr_zone); //knot_zone_contents_dump(zone, 0); + + // check zone integrity +#ifdef KNOT_XFRIN_DEBUG +#ifdef DEBUG_ENABLE_BRIEF + int errs = knot_zone_contents_integrity_check(zone); + dbg_ns("Zone integrity check: %d errors.\n", errs); +#endif +#endif } /*! diff --git a/src/libknot/nameserver/name-server.h b/src/libknot/nameserver/name-server.h index 928d79c..3bf9552 100644 --- a/src/libknot/nameserver/name-server.h +++ b/src/libknot/nameserver/name-server.h @@ -81,9 +81,10 @@ typedef int (*xfr_callback_t)(int session, sockaddr_t *addr, typedef struct knot_ns_xfr { int type; int flags; - sockaddr_t addr; + sockaddr_t addr, saddr; knot_packet_t *query; knot_packet_t *response; + knot_rcode_t rcode; xfr_callback_t send; int session; @@ -100,6 +101,7 @@ typedef struct knot_ns_xfr { size_t wire_size; void *data; knot_zone_t *zone; + char* zname; void *owner; /*! \note [TSIG] TSIG fields */ @@ -148,7 +150,8 @@ static const size_t KNOT_NS_TSIG_DATA_MAX_SIZE = 100 * 64 * 1024; */ enum knot_ns_xfr_flag_t { XFR_FLAG_TCP = 1 << 0, /*!< XFR request is on TCP. */ - XFR_FLAG_UDP = 1 << 1 /*!< XFR request is on UDP. */ + XFR_FLAG_UDP = 1 << 1, /*!< XFR request is on UDP. */ + XFR_FLAG_AXFR_FINISHED = 1 << 2 }; /*! @@ -175,6 +178,10 @@ typedef enum knot_ns_xfr_type_t { */ knot_nameserver_t *knot_ns_create(); +/*! \todo Document me. */ +void knot_ns_set_nsid(knot_nameserver_t *nameserver, const char *nsid, + size_t nsid_length); + /*! * \brief Parses the given query into the response structure and recognizes * type of the query. diff --git a/src/libknot/packet/packet.c b/src/libknot/packet/packet.c index 59c1a0d..6fc97b8 100644 --- a/src/libknot/packet/packet.c +++ b/src/libknot/packet/packet.c @@ -110,6 +110,7 @@ static void knot_packet_init_pointers_response(knot_packet_t *pkt) dbg_packet("Compression offsets: %p\n", pkt->compression.offsets); pkt->compression.max = DEFAULT_DOMAINS_IN_RESPONSE; + pkt->compression.default_count = DEFAULT_DOMAINS_IN_RESPONSE; pkt->tmp_rrsets = (const knot_rrset_t **)pos; pos += DEFAULT_TMP_RRSETS * sizeof(const knot_rrset_t *); @@ -633,7 +634,7 @@ static void knot_packet_free_allocated_space(knot_packet_t *pkt) free(pkt->additional); } - if (pkt->compression.max > DEFAULT_DOMAINS_IN_RESPONSE) { + if (pkt->compression.max > pkt->compression.default_count) { free(pkt->compression.dnames); free(pkt->compression.offsets); } @@ -1470,6 +1471,9 @@ void knot_packet_free(knot_packet_t **packet) free((*packet)->wireformat); } + // free EDNS options + knot_edns_free_options(&(*packet)->opt_rr); + dbg_packet("Freeing packet structure\n"); free(*packet); *packet = NULL; diff --git a/src/libknot/packet/packet.h b/src/libknot/packet/packet.h index 81b1812..8f76ae2 100644 --- a/src/libknot/packet/packet.h +++ b/src/libknot/packet/packet.h @@ -48,6 +48,7 @@ struct knot_compressed_dnames { size_t *offsets; /*!< Offsets of domain names in the packet. */ short count; /*!< Count of items in the previous arrays. */ short max; /*!< Capacity of the structure (allocated). */ + short default_count; }; typedef struct knot_compressed_dnames knot_compressed_dnames_t; diff --git a/src/libknot/packet/query.c b/src/libknot/packet/query.c index 63e902a..b76059b 100644 --- a/src/libknot/packet/query.c +++ b/src/libknot/packet/query.c @@ -207,6 +207,7 @@ int knot_query_add_rrset_authority(knot_packet_t *query, assert(endp - startp > query->opt_rr.size + query->tsig_size); // reserve space for OPT RR + /*! \todo Why here??? */ endp -= query->opt_rr.size; /*! \note [TSIG] reserve space for TSIG RR */ endp -= query->tsig_size; diff --git a/src/libknot/packet/response.c b/src/libknot/packet/response.c index ed16e2f..c9f2ba7 100644 --- a/src/libknot/packet/response.c +++ b/src/libknot/packet/response.c @@ -23,6 +23,7 @@ #include "util/error.h" #include "util/debug.h" #include "packet/packet.h" +#include "edns.h" /*----------------------------------------------------------------------------*/ /*! @@ -75,7 +76,7 @@ static const size_t KNOT_RESPONSE_MAX_PTR = 16383; */ static int knot_response_realloc_compr(knot_compressed_dnames_t *table) { - int free_old = table->max != DEFAULT_DOMAINS_IN_RESPONSE; + int free_old = table->max != table->default_count; size_t *old_offsets = table->offsets; const knot_dname_t **old_dnames = table->dnames; @@ -233,10 +234,10 @@ dbg_response_exec( // If case-sensitive search is in place, we should not save the // node's parent's positions. - to_save = !compr_cs && (knot_dname_node(to_save, 1) != NULL - && knot_node_parent(knot_dname_node(to_save, 1), 1) + to_save = !compr_cs && (knot_dname_node(to_save) != NULL + && knot_node_parent(knot_dname_node(to_save)) != NULL) ? knot_node_owner(knot_node_parent( - knot_dname_node(to_save, 1), 1)) + knot_dname_node(to_save))) : NULL; dbg_response("i: %d\n", i); @@ -391,31 +392,31 @@ dbg_response_exec( } #else // if case-sensitive comparation, we cannot just take the parent - if (compr_cs || knot_dname_node(to_find, 1) == NULL - || knot_node_owner(knot_dname_node(to_find, 1)) != to_find - || knot_node_parent(knot_dname_node(to_find, 1), 1) + if (compr_cs || knot_dname_node(to_find) == NULL + || knot_node_owner(knot_dname_node(to_find)) != to_find + || knot_node_parent(knot_dname_node(to_find)) == NULL) { dbg_response("compr_cs: %d\n", compr_cs); dbg_response("knot_dname_node(to_find, 1) == %p" - "\n", knot_dname_node(to_find, 1)); + "\n", knot_dname_node(to_find)); - if (knot_dname_node(to_find, 1) != NULL) { + if (knot_dname_node(to_find) != NULL) { dbg_response("knot_node_owner(knot_dname_node(" "to_find, 1)) = %p, to_find = %p\n", - knot_node_owner(knot_dname_node(to_find, 1)), + knot_node_owner(knot_dname_node(to_find)), to_find); dbg_response("knot_node_parent(knot_dname_node(" "to_find, 1), 1) = %p\n", - knot_node_parent(knot_dname_node(to_find, 1), 1)); + knot_node_parent(knot_dname_node(to_find))); } break; } else { - assert(knot_dname_node(to_find, 1) != - knot_node_parent(knot_dname_node(to_find, 1), 1)); + assert(knot_dname_node(to_find) != + knot_node_parent(knot_dname_node(to_find))); assert(to_find != knot_node_owner( - knot_node_parent(knot_dname_node(to_find, 1), 1))); + knot_node_parent(knot_dname_node(to_find)))); to_find = knot_node_owner( - knot_node_parent(knot_dname_node(to_find, 1), 1)); + knot_node_parent(knot_dname_node(to_find))); dbg_response("New to_find: %p\n", to_find); } #endif @@ -456,7 +457,7 @@ dbg_response_exec( assert(compr->wire_pos >= 0); if (knot_response_store_dname_pos(compr->table, dname, not_matched, - compr->wire_pos, offset, compr_cs) + compr->wire_pos, offset, compr_cs) != 0) { dbg_response("Compression info could not be stored." "\n"); @@ -952,25 +953,79 @@ void knot_response_clear(knot_packet_t *resp, int clear_question) /*----------------------------------------------------------------------------*/ int knot_response_add_opt(knot_packet_t *resp, - const knot_opt_rr_t *opt_rr, - int override_max_size) + const knot_opt_rr_t *opt_rr, + int override_max_size, + int add_nsid) { if (resp == NULL || opt_rr == NULL) { return KNOT_EBADARG; } // copy the OPT RR + + /*! \todo Change the way OPT RR is handled in response. + * Pointer to nameserver->opt_rr should be enough. + */ + resp->opt_rr.version = opt_rr->version; resp->opt_rr.ext_rcode = opt_rr->ext_rcode; resp->opt_rr.payload = opt_rr->payload; - resp->opt_rr.size = opt_rr->size; + + /* + * Add options only if NSID is requested. + * + * This is a bit hack and should be resolved in other way before some + * other options are supported. + */ + + if (add_nsid) { + resp->opt_rr.option_count = opt_rr->option_count; + assert(resp->opt_rr.options == NULL); + resp->opt_rr.options = (knot_opt_option_t *)malloc( + resp->opt_rr.option_count * sizeof(knot_opt_option_t)); + CHECK_ALLOC_LOG(resp->opt_rr.options, KNOT_ENOMEM); + + memcpy(resp->opt_rr.options, opt_rr->options, + resp->opt_rr.option_count * sizeof(knot_opt_option_t)); + + // copy all data + for (int i = 0; i < opt_rr->option_count; i++) { + resp->opt_rr.options[i].data = (uint8_t *)malloc( + resp->opt_rr.options[i].length); + CHECK_ALLOC_LOG(resp->opt_rr.options[i].data, KNOT_ENOMEM); + + memcpy(resp->opt_rr.options[i].data, + opt_rr->options[i].data, + resp->opt_rr.options[i].length); + +// struct knot_opt_option option; +// option = opt_rr->options[i]; + +// /* Do not add NSID unless specified. */ +// if ((option.code != EDNS_OPTION_NSID) || (add_nsid)) { +// int ret = +// knot_edns_add_option(&resp->opt_rr, +// option.code, +// option.length, +// option.data); +// if (ret != KNOT_EOK) { +// dbg_response("Could not " +// "copy option to EDNS!\n"); +// } +// } + } + resp->opt_rr.size = opt_rr->size; + } else { + resp->opt_rr.size = KNOT_EDNS_MIN_SIZE; + } // if max size is set, it means there is some reason to be that way, // so we can't just set it to higher value if (override_max_size && resp->max_size > 0 && resp->max_size < opt_rr->payload) { - return KNOT_EPAYLOAD; +// return KNOT_EPAYLOAD; + return KNOT_EOK; } // set max size (less is OK) diff --git a/src/libknot/packet/response.h b/src/libknot/packet/response.h index d76c10c..d522f82 100644 --- a/src/libknot/packet/response.h +++ b/src/libknot/packet/response.h @@ -96,7 +96,8 @@ void knot_response_clear(knot_packet_t *resp, int clear_question); */ int knot_response_add_opt(knot_packet_t *resp, const knot_opt_rr_t *opt_rr, - int override_max_size); + int override_max_size, + int add_nsid); /*! * \brief Adds a RRSet to the Answer section of the response. diff --git a/src/libknot/rdata.c b/src/libknot/rdata.c index 27fa6ec..51a1a70 100644 --- a/src/libknot/rdata.c +++ b/src/libknot/rdata.c @@ -268,20 +268,38 @@ int knot_rdata_from_wire(knot_rdata_t *rdata, const uint8_t *wire, break; case 3: pos2 = *pos; - fprintf(stderr, "reading dname from pos: %zu\n", pos2); - dname = - knot_dname_parse_from_wire( + //fprintf(stderr, "reading dname from pos: %zu\n", pos2); + dname = knot_dname_parse_from_wire( wire, &pos2, total_size, NULL); if (dname == NULL) { return KNOT_ERROR; } - items[i].dname = dname; + + items[i].raw_data = (uint16_t *)malloc( + knot_dname_size(dname) + 2); + if (items[i].raw_data == NULL) { + /*! \todo This will leak. */ + free(items); + return KNOT_ENOMEM; + } + + items[i].raw_data[0] = knot_dname_size(dname); + memcpy((uint8_t *)(items[i].raw_data + 1), + knot_dname_name(dname), + knot_dname_size(dname)); + +// items[i].dname = dname; //*pos += dname->size; parsed += pos2 - *pos; - fprintf(stderr, "read %zu bytes.\n", parsed); + //fprintf(stderr, "read %zu bytes.\n", parsed); *pos = pos2; - dname = 0; + knot_dname_free(&dname); + + // continue with next item + ++i; + continue; + break; default: assert(0); @@ -295,6 +313,7 @@ int knot_rdata_from_wire(knot_rdata_t *rdata, const uint8_t *wire, if (item_size != 0) { if (parsed + item_size > rdlength) { + /*! \todo This will leak a lot. */ free(items); return KNOT_EFEWDATA; } @@ -302,15 +321,16 @@ int knot_rdata_from_wire(knot_rdata_t *rdata, const uint8_t *wire, items[i].raw_data = (uint16_t *)malloc(item_size + 2); if (items[i].raw_data == NULL) { free(items); + /*! \todo This will also leak a lot. */ return KNOT_ENOMEM; } memcpy(items[i].raw_data, &item_size, 2); memcpy(items[i].raw_data + 1, wire + *pos, item_size); *pos += item_size; parsed += item_size; - } else if (item_type == KNOT_RDATA_WF_BINARY - || item_type == KNOT_RDATA_WF_IPSECGATEWAY) { - fprintf(stderr, "item_size was 0, creating empty rdata item.\n"); + } else if (item_type == KNOT_RDATA_WF_BINARY/* + || item_type == KNOT_RDATA_WF_IPSECGATEWAY*/) { +// fprintf(stderr, "item_size was 0, creating empty rdata item.\n"); // in this case we are at the end of the RDATA // and should create an empty RDATA item items[i].raw_data = (uint16_t *)malloc(2); @@ -322,8 +342,8 @@ int knot_rdata_from_wire(knot_rdata_t *rdata, const uint8_t *wire, } else if (item_type != KNOT_RDATA_WF_COMPRESSED_DNAME && item_type != KNOT_RDATA_WF_UNCOMPRESSED_DNAME && item_type != KNOT_RDATA_WF_LITERAL_DNAME) { - fprintf(stderr, "RDATA item not set (i: %d), type: %u" - " RDATA item type: %d\n", i, desc->type ,item_type); +// fprintf(stderr, "RDATA item not set (i: %d), type: %u" +// " RDATA item type: %d\n", i, desc->type ,item_type); assert(0); } @@ -634,7 +654,7 @@ void knot_rdata_deep_free(knot_rdata_t **rdata, uint type, /*----------------------------------------------------------------------------*/ knot_rdata_t *knot_rdata_deep_copy(const knot_rdata_t *rdata, - uint16_t type) + uint16_t type, int copy_dnames) { knot_rdata_t *copy = knot_rdata_new(); CHECK_ALLOC_LOG(copy, NULL); @@ -658,8 +678,13 @@ knot_rdata_t *knot_rdata_deep_copy(const knot_rdata_t *rdata, if (d->wireformat[i] == KNOT_RDATA_WF_COMPRESSED_DNAME || d->wireformat[i] == KNOT_RDATA_WF_UNCOMPRESSED_DNAME || d->wireformat[i] == KNOT_RDATA_WF_LITERAL_DNAME) { - copy->items[i].dname = - knot_dname_deep_copy(rdata->items[i].dname); + if (copy_dnames) { + copy->items[i].dname = + knot_dname_deep_copy(rdata->items[i].dname); + } else { + copy->items[i].dname = rdata->items[i].dname; + knot_dname_retain(rdata->items[i].dname); + } } else { copy->items[i].raw_data = (uint16_t *)malloc( rdata->items[i].raw_data[0] + 2); diff --git a/src/libknot/rdata.h b/src/libknot/rdata.h index 6d9907d..bb45f50 100644 --- a/src/libknot/rdata.h +++ b/src/libknot/rdata.h @@ -229,7 +229,7 @@ int knot_rdata_item_set_raw_data(knot_rdata_t *rdata, unsigned int pos, * \return Copy of \a rdata. */ knot_rdata_t *knot_rdata_deep_copy(const knot_rdata_t *rdata, - uint16_t type); + uint16_t type, int copy_dnames); /*! * \brief Destroys the RDATA structure without deleting RDATA items. diff --git a/src/libknot/rrset.c b/src/libknot/rrset.c index 44282fd..d968378 100644 --- a/src/libknot/rrset.c +++ b/src/libknot/rrset.c @@ -55,6 +55,8 @@ static void knot_rrset_disconnect_rdata(knot_rrset_t *rrset, rrset->rdata = rdata->next; } } + + rdata->next = NULL; } /*----------------------------------------------------------------------------*/ @@ -128,7 +130,7 @@ knot_rdata_t *knot_rrset_remove_rdata(knot_rrset_t *rrset, } while (rr != NULL) { - /*! \todo maybe the dnames should be compared case-insensitive*/ + /*! \todo dnames are compared case-insensitive. is it OK?*/ if (knot_rdata_compare(rr, rdata, desc->wireformat) == 0) { knot_rrset_disconnect_rdata(rrset, prev, rr); return rr; @@ -457,8 +459,7 @@ static int knot_rrset_rr_to_wire(const knot_rrset_t *rrset, // save whole domain name memcpy(*pos, knot_dname_name(dname), knot_dname_size(dname)); - dbg_rrset_detail(stderr, - "Uncompressed dname size: %d\n", + dbg_rrset_detail("Uncompressed dname size: %d\n", knot_dname_size(dname)); *pos += knot_dname_size(dname); rdlength += knot_dname_size(dname); @@ -579,7 +580,9 @@ int knot_rrset_deep_copy(const knot_rrset_t *from, knot_rrset_t **to) *to = (knot_rrset_t *)calloc(1, sizeof(knot_rrset_t)); CHECK_ALLOC_LOG(*to, KNOT_ENOMEM); - (*to)->owner = knot_dname_deep_copy(from->owner); + //(*to)->owner = knot_dname_deep_copy(from->owner); + (*to)->owner = from->owner; + knot_dname_retain((*to)->owner); (*to)->rclass = from->rclass; (*to)->ttl = from->ttl; (*to)->type = from->type; @@ -597,7 +600,7 @@ int knot_rrset_deep_copy(const knot_rrset_t *from, knot_rrset_t **to) /*! \note Order of RDATA will be reversed. */ while (rdata != NULL) { ret = knot_rrset_add_rdata(*to, knot_rdata_deep_copy(rdata, - knot_rrset_type(from))); + knot_rrset_type(from), 1)); if (ret != KNOT_EOK) { knot_rrset_deep_free(to, 1, 1, 1); return ret; @@ -654,6 +657,12 @@ void knot_rrset_deep_free(knot_rrset_t **rrset, int free_owner, return; } +// char *name = knot_dname_to_str(knot_rrset_owner(*rrset)); +// char *type = knot_rrtype_to_string(knot_rrset_type(*rrset)); +// fprintf(stderr, "Deleting RRSet (%p) %s, type %s, rdata: %p\n", +// *rrset, name, type, (*rrset)->rdata); +// free(name); + if (free_rdata) { knot_rdata_t *tmp_rdata; knot_rdata_t *next_rdata; @@ -668,6 +677,7 @@ void knot_rrset_deep_free(knot_rrset_t **rrset, int free_owner, tmp_rdata = next_rdata; } +// printf("test: %p\n", tmp_rdata->next->next); assert(tmp_rdata == NULL || tmp_rdata->next == (*rrset)->rdata); diff --git a/src/libknot/tsig-op.c b/src/libknot/tsig-op.c index edc68d8..bdaf083 100644 --- a/src/libknot/tsig-op.c +++ b/src/libknot/tsig-op.c @@ -540,11 +540,11 @@ int knot_tsig_sign(uint8_t *msg, size_t *msg_len, tsig_rdata_set_time_signed(tmp_tsig, request_time_signed); /* Store current time into Other data. */ - uint8_t time_signed[3]; + uint8_t time_signed[6]; time_t curr_time = time(NULL); - /*! \todo bleeding eyes. */ - knot_wire_write_u48(time_signed, (uint64_t)curr_time); + uint64_t time64 = curr_time; + knot_wire_write_u48(time_signed, time64); tsig_rdata_set_other_data(tmp_tsig, 6, time_signed); } else { diff --git a/src/libknot/updates/xfr-in.c b/src/libknot/updates/xfr-in.c index 4a7e9ba..c1ea13d 100644 --- a/src/libknot/updates/xfr-in.c +++ b/src/libknot/updates/xfr-in.c @@ -248,23 +248,33 @@ int xfrin_create_ixfr_query(const knot_zone_contents_t *zone, /*----------------------------------------------------------------------------*/ -static int xfrin_add_orphan_rrsig(xfrin_orphan_rrsig_t *rrsigs, +static int xfrin_add_orphan_rrsig(xfrin_orphan_rrsig_t **rrsigs, knot_rrset_t *rr) { // try to find similar RRSIGs (check owner and type covered) in the list assert(knot_rrset_type(rr) == KNOT_RRTYPE_RRSIG); + if (*rrsigs == NULL) { + /* First item, nothing to iterate. */ + *rrsigs = malloc(sizeof(xfrin_orphan_rrsig_t)); + CHECK_ALLOC_LOG(*rrsigs, KNOT_ENOMEM); + (*rrsigs)->rrsig = rr; + (*rrsigs)->next = NULL; + return KNOT_EOK; + } + int ret = 0; - xfrin_orphan_rrsig_t **last = &rrsigs; - while (*last != NULL) { + xfrin_orphan_rrsig_t *last = *rrsigs; + assert(last); + while (last != NULL) { // check if the RRSIG is not similar to the one we want to add - assert((*last)->rrsig != NULL); - if (knot_rrset_compare((*last)->rrsig, rr, + assert(last->rrsig != NULL); + if (knot_rrset_compare(last->rrsig, rr, KNOT_RRSET_COMPARE_HEADER) == 1 && knot_rdata_rrsig_type_covered(knot_rrset_rdata( - (*last)->rrsig)) + last->rrsig)) == knot_rdata_rrsig_type_covered(knot_rrset_rdata(rr))) { - ret = knot_rrset_merge((void **)&(*last)->rrsig, + ret = knot_rrset_merge((void **)&last->rrsig, (void **)&rr); if (ret != KNOT_EOK) { return ret; @@ -272,16 +282,19 @@ static int xfrin_add_orphan_rrsig(xfrin_orphan_rrsig_t *rrsigs, return 1; } } - last = &((*last)->next); + last = last->next; } + + assert(last == NULL); + assert(&last != rrsigs); - assert(*last == NULL); - // we did not find the right RRSIGs, add to the end - *last = (xfrin_orphan_rrsig_t *)malloc(sizeof(xfrin_orphan_rrsig_t)); - CHECK_ALLOC_LOG(*last, KNOT_ENOMEM); + // the RRSIG is not in the list, add to the front + xfrin_orphan_rrsig_t *new_item = malloc(sizeof(xfrin_orphan_rrsig_t)); + CHECK_ALLOC_LOG(new_item, KNOT_ENOMEM); + new_item->rrsig = rr; + new_item->next = *rrsigs; - (*last)->rrsig = rr; - (*last)->next = NULL; + *rrsigs = new_item; return KNOT_EOK; } @@ -506,7 +519,7 @@ int xfrin_process_axfr_packet(/*const uint8_t *pkt, size_t size, dbg_xfrin("No zone created, but the first RR in " "Answer is not a SOA RR.\n"); knot_packet_free(&packet); - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); knot_rrset_deep_free(&rr, 1, 1, 1); /*! \todo Cleanup. */ return KNOT_EMALF; @@ -528,7 +541,7 @@ dbg_xfrin_exec( ); /*! \todo Cleanup. */ knot_packet_free(&packet); - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); knot_rrset_deep_free(&rr, 1, 1, 1); return KNOT_EMALF; } @@ -549,7 +562,7 @@ dbg_xfrin_exec( if (*constr == NULL) { dbg_xfrin("Failed to create new constr. zone.\n"); knot_packet_free(&packet); - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); knot_rrset_deep_free(&rr, 1, 1, 1); return KNOT_ENOMEM; } @@ -561,7 +574,7 @@ dbg_xfrin_exec( if ((*constr)->contents== NULL) { dbg_xfrin("Failed to create new zone.\n"); knot_packet_free(&packet); - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); knot_rrset_deep_free(&rr, 1, 1, 1); /*! \todo Cleanup. */ return KNOT_ENOMEM; @@ -580,7 +593,7 @@ dbg_xfrin_exec( dbg_xfrin("Failed to add RRSet to zone node: %s.\n", knot_strerror(ret)); knot_packet_free(&packet); - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); knot_rrset_deep_free(&rr, 1, 1, 1); /*! \todo Cleanup. */ return KNOT_ERROR; @@ -687,8 +700,14 @@ dbg_xfrin_exec( if (ret == KNOT_ENONODE || ret == KNOT_ENORRSET) { dbg_xfrin("No node or RRSet for RRSIGs\n"); dbg_xfrin("Saving for later insertion.\n"); - ret = xfrin_add_orphan_rrsig((*constr)->rrsigs, + + if (ret == KNOT_ENORRSET) { + in_zone = 1; + } + + ret = xfrin_add_orphan_rrsig(&(*constr)->rrsigs, rr); + if (ret > 0) { dbg_xfrin("Merged RRSIGs.\n"); knot_rrset_free(&rr); @@ -696,7 +715,7 @@ dbg_xfrin_exec( dbg_xfrin("Failed to save orphan" " RRSIGs.\n"); knot_packet_free(&packet); - knot_node_free(&node, 1, 0); // ??? + knot_node_free(&node, 0); // ??? knot_rrset_deep_free(&rr, 1, 1, 1); return ret; } @@ -704,7 +723,7 @@ dbg_xfrin_exec( dbg_xfrin("Failed to add RRSIGs (%s).\n", knot_strerror(ret)); knot_packet_free(&packet); - knot_node_free(&node, 1, 0); // ??? + knot_node_free(&node, 0); // ??? knot_rrset_deep_free(&rr, 1, 1, 1); return KNOT_ERROR; /*! \todo Other error code. */ } else if (ret == 1) { @@ -712,7 +731,7 @@ dbg_xfrin_exec( dbg_xfrin_exec( char *name = knot_dname_to_str(node->owner); dbg_xfrin("Found node for the record in " - "zone: %s.\n", name); + "zone: %s. Merged.\n", name); free(name); ); in_zone = 1; @@ -744,7 +763,7 @@ dbg_xfrin_exec( // not allowed here dbg_xfrin(" in Answer section.\n"); knot_packet_free(&packet); - knot_node_free(&node, 1, 0); // ??? + knot_node_free(&node, 0); // ??? knot_rrset_deep_free(&rr, 1, 1, 1); return KNOT_EMALF; } @@ -787,7 +806,7 @@ dbg_xfrin_exec( dbg_xfrin("Failed to add RRSet to node (%s" ")\n", knot_strerror(ret)); knot_packet_free(&packet); - knot_node_free(&node, 1, 0); // ??? + knot_node_free(&node, 0); // ??? knot_rrset_deep_free(&rr, 1, 1, 1); return KNOT_ERROR; } else if (ret > 0) { @@ -803,7 +822,7 @@ dbg_xfrin_exec( dbg_xfrin("Failed to add node to zone (%s)" ".\n", knot_strerror(ret)); knot_packet_free(&packet); - knot_node_free(&node, 1, 0); // ??? + knot_node_free(&node, 0); // ??? knot_rrset_deep_free(&rr, 1, 1, 1); return KNOT_ERROR; } @@ -839,7 +858,7 @@ dbg_xfrin_exec( dbg_xfrin("Could not parse next RR: %s.\n", knot_strerror(ret)); knot_packet_free(&packet); - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); knot_rrset_deep_free(&rr, 1, 1, 1); /*! \todo Cleanup. */ return KNOT_EMALF; @@ -856,7 +875,7 @@ dbg_xfrin_exec( dbg_xfrin("Failed to add last node into zone (%s)" ".\n", knot_strerror(ret)); knot_packet_free(&packet); - knot_node_free(&node, 1, 0); + knot_node_free(&node, 0); return KNOT_ERROR; /*! \todo Other error */ } } @@ -1009,6 +1028,7 @@ int xfrin_process_ixfr_packet(knot_ns_xfr_t *xfr) return XFRIN_RES_SOA_ONLY; } else if (knot_rrset_type(rr) != KNOT_RRTYPE_SOA) { knot_rrset_deep_free(&rr, 1, 1, 1); + knot_packet_free(&packet); dbg_xfrin("Fallback to AXFR.\n"); ret = XFRIN_RES_FALLBACK; return ret; @@ -1260,39 +1280,27 @@ typedef struct { int new_rrsets_allocated; /*! - * Deleted (without contents) after successful update. + * Deleted after failed update. */ + knot_rdata_t **new_rdata; + uint *new_rdata_types; + int new_rdata_count; + int new_rdata_allocated; + +// /*! +// * Deleted (without contents) after successful update. +// */ knot_node_t **old_nodes; int old_nodes_count; int old_nodes_allocated; - /*! - * Deleted (without contents) after failed update. - */ - knot_node_t **new_nodes; - int new_nodes_count; - int new_nodes_allocated; - - ck_hash_table_item_t **old_hash_items; - int old_hash_items_count; - int old_hash_items_allocated; + knot_node_t **old_nsec3; + int old_nsec3_count; + int old_nsec3_allocated; } xfrin_changes_t; /*----------------------------------------------------------------------------*/ -static void xfrin_changes_free(xfrin_changes_t **changes) -{ - free((*changes)->old_nodes); - free((*changes)->old_rrsets); - free((*changes)->old_rdata); - free((*changes)->old_rdata_types); - free((*changes)->new_rrsets); - free((*changes)->new_nodes); - free((*changes)->old_hash_items); -} - -/*----------------------------------------------------------------------------*/ - static int xfrin_changes_check_rrsets(knot_rrset_t ***rrsets, int *count, int *allocated, int to_add) { @@ -1397,51 +1405,20 @@ static int xfrin_changes_check_rdata(knot_rdata_t ***rdatas, uint **types, /*----------------------------------------------------------------------------*/ -static int xfrin_changes_check_hash_items(ck_hash_table_item_t ***items, - int *count, int *allocated) -{ - /* Prevent infinite loop in case of allocated = 0. */ - int new_count = 0; - if (*allocated == 0) { - new_count = *count + 1; - } else { - if (*count == *allocated) { - new_count = *allocated * 2; - } - } - - const size_t item_len = sizeof(ck_hash_table_item_t *); - ck_hash_table_item_t **items_new = malloc(new_count * item_len); - if (items_new == NULL) { - return KNOT_ENOMEM; - } - - memset(items_new, 0, new_count * item_len); - memcpy(items_new, *items, (*count) * item_len); - free(*items); - *items = items_new; - *allocated = new_count; - - return KNOT_EOK; -} - -/*----------------------------------------------------------------------------*/ - static void xfrin_zone_contents_free(knot_zone_contents_t **contents) { /*! \todo This should be all in some API!! */ if ((*contents)->table != NULL) { -// ck_destroy_table(&(*contents)->table, NULL, 0); - ck_table_free(&(*contents)->table); + ck_destroy_table(&(*contents)->table, NULL, 0); +// ck_table_free(&(*contents)->table); } - // free the zone tree, but only the structure - // (nodes are already destroyed) + // free the zone tree with nodes dbg_zone("Destroying zone tree.\n"); - knot_zone_tree_free(&(*contents)->nodes); + knot_zone_tree_deep_free(&(*contents)->nodes); dbg_zone("Destroying NSEC3 zone tree.\n"); - knot_zone_tree_free(&(*contents)->nsec3_nodes); + knot_zone_tree_deep_free(&(*contents)->nsec3_nodes); knot_nsec3_params_free(&(*contents)->nsec3_params); @@ -1453,39 +1430,6 @@ static void xfrin_zone_contents_free(knot_zone_contents_t **contents) /*----------------------------------------------------------------------------*/ -static void xfrin_rollback_update(knot_zone_contents_t *contents, - xfrin_changes_t *changes) -{ - /* - * This function is called only when no references were actually set to - * the new nodes, just the new nodes reference other. - * We thus do not need to fix any references, just from the old nodes - * to the new ones. - */ - - // discard new nodes, but do not remove RRSets from them - for (int i = 0; i < changes->new_nodes_count; ++i) { - knot_node_free(&changes->new_nodes[i], 0, 0); - } - - // set references from old nodes to new nodes to NULL and remove the - // old flag - for (int i = 0; i < changes->old_nodes_count; ++i) { - knot_node_set_new_node(changes->old_nodes[i], NULL); - knot_node_clear_old(changes->old_nodes[i]); - } - - // discard new RRSets - for (int i = 0; i < changes->new_rrsets_count; ++i) { - knot_rrset_deep_free(&changes->new_rrsets[i], 0, 1, 0); - } - - // destroy the shallow copy of zone - xfrin_zone_contents_free(&contents); -} - -/*----------------------------------------------------------------------------*/ - static knot_rdata_t *xfrin_remove_rdata(knot_rrset_t *from, const knot_rrset_t *what) { @@ -1495,6 +1439,8 @@ static knot_rdata_t *xfrin_remove_rdata(knot_rrset_t *from, const knot_rdata_t *rdata = knot_rrset_rdata(what); while (rdata != NULL) { + // rdata - the RDATA to be removed + // old_actual - removed RDATA old_actual = knot_rrset_remove_rdata(from, rdata); if (old_actual != NULL) { old_actual->next = old; @@ -1503,105 +1449,97 @@ static knot_rdata_t *xfrin_remove_rdata(knot_rrset_t *from, rdata = knot_rrset_rdata_next(what, rdata); } + // returning chain of removed RDATA (terminated with NULL) return old; } /*----------------------------------------------------------------------------*/ -static int xfrin_get_node_copy(knot_node_t **node, xfrin_changes_t *changes) -{ - knot_node_t *new_node = - knot_node_get_new_node(*node); - if (new_node == NULL) { - dbg_xfrin("Creating copy of node.\n"); - int ret = knot_node_shallow_copy(*node, &new_node); - if (ret != KNOT_EOK) { - dbg_xfrin("Failed to create node copy.\n"); - return KNOT_ENOMEM; - } - - dbg_xfrin_detail("Created copy of old node %p to new node %p\n", - *node, new_node); - - assert(changes); - -// changes->new_nodes_allocated = 0; - - // save the copy of the node - ret = xfrin_changes_check_nodes( - &changes->new_nodes, - &changes->new_nodes_count, - &changes->new_nodes_allocated); - if (ret != KNOT_EOK) { - dbg_xfrin("Failed to add new node to list.\n"); - knot_node_free(&new_node, 0, 0); - return ret; - } - -// changes->old_nodes_allocated = 0; - - // save the old node to list of old nodes - ret = xfrin_changes_check_nodes( - &changes->old_nodes, - &changes->old_nodes_count, - &changes->old_nodes_allocated); - if (ret != KNOT_EOK) { - dbg_xfrin("Failed to add old node to list.\n"); - knot_node_free(&new_node, 0, 0); - return ret; - } - - assert(changes->new_nodes); - assert(changes->old_nodes); - - changes->new_nodes[changes->new_nodes_count++] = new_node; - changes->old_nodes[changes->old_nodes_count++] = *node; - - // mark the old node as old - knot_node_set_old(*node); - - knot_node_set_new(new_node); - knot_node_set_new_node(*node, new_node); - } - - *node = new_node; - return KNOT_EOK; -} - -/*----------------------------------------------------------------------------*/ - static int xfrin_copy_old_rrset(knot_rrset_t *old, knot_rrset_t **copy, xfrin_changes_t *changes) { // create new RRSet by copying the old one - int ret = knot_rrset_shallow_copy(old, copy); +// int ret = knot_rrset_shallow_copy(old, copy); + int ret = knot_rrset_deep_copy(old, copy); if (ret != KNOT_EOK) { dbg_xfrin("Failed to create RRSet copy.\n"); return KNOT_ENOMEM; } // add the RRSet to the list of new RRSets + // create place also for RRSIGs ret = xfrin_changes_check_rrsets(&changes->new_rrsets, &changes->new_rrsets_count, - &changes->new_rrsets_allocated, 1); + &changes->new_rrsets_allocated, 2); if (ret != KNOT_EOK) { dbg_xfrin("Failed to add new RRSet to list.\n"); - knot_rrset_free(copy); + knot_rrset_deep_free(copy, 1, 1, 1); + return ret; + } + + // add the copied RDATA to the list of new RDATA + ret = xfrin_changes_check_rdata(&changes->new_rdata, + &changes->new_rdata_types, + changes->new_rdata_count, + &changes->new_rdata_allocated, 2); + if (ret != KNOT_EOK) { + dbg_xfrin("Failed to add new RRSet to list.\n"); + knot_rrset_deep_free(copy, 1, 1, 1); return ret; } changes->new_rrsets[changes->new_rrsets_count++] = *copy; + changes->new_rdata[changes->new_rdata_count] = + knot_rrset_get_rdata(*copy); + changes->new_rdata_types[changes->new_rdata_count] = + knot_rrset_type(*copy); + ++changes->new_rdata_count; + + if ((*copy)->rrsigs != NULL) { + assert(old->rrsigs != NULL); + changes->new_rrsets[changes->new_rrsets_count++] = + (*copy)->rrsigs; + changes->new_rdata[changes->new_rdata_count] = + knot_rrset_get_rdata((*copy)->rrsigs); + changes->new_rdata_types[changes->new_rdata_count] = + KNOT_RRTYPE_RRSIG; + ++changes->new_rdata_count; + } // add the old RRSet to the list of old RRSets ret = xfrin_changes_check_rrsets(&changes->old_rrsets, &changes->old_rrsets_count, - &changes->old_rrsets_allocated, 1); + &changes->old_rrsets_allocated, 2); + if (ret != KNOT_EOK) { + dbg_xfrin("Failed to add old RRSet to list.\n"); + return ret; + } + + // and old RDATA to the list of old RDATA + ret = xfrin_changes_check_rdata(&changes->old_rdata, + &changes->old_rdata_types, + changes->old_rdata_count, + &changes->old_rdata_allocated, 2); if (ret != KNOT_EOK) { dbg_xfrin("Failed to add old RRSet to list.\n"); return ret; } changes->old_rrsets[changes->old_rrsets_count++] = old; + changes->old_rdata[changes->old_rdata_count] = old->rdata; + changes->old_rdata_types[changes->old_rdata_count] = + knot_rrset_type(old); + ++changes->old_rdata_count; + + if ((*copy)->rrsigs != NULL) { + assert(old->rrsigs != NULL); + changes->old_rrsets[changes->old_rrsets_count++] = old->rrsigs; + changes->old_rdata[changes->old_rdata_count] = + old->rrsigs->rdata; + changes->old_rdata_types[changes->old_rdata_count] = + KNOT_RRTYPE_RRSIG; + ++changes->old_rdata_count; + } return KNOT_EOK; } @@ -1623,8 +1561,7 @@ static int xfrin_copy_rrset(knot_node_t *node, knot_rr_type_t type, return ret; } - dbg_xfrin_detail("Copied old rrset %p to new %p.\n", - old, *rrset); + dbg_xfrin_detail("Copied old rrset %p to new %p.\n", old, *rrset); // replace the RRSet in the node copy by the new one ret = knot_node_add_rrset(node, *rrset, 0); @@ -1655,6 +1592,8 @@ static int xfrin_apply_remove_rrsigs(xfrin_changes_t *changes, int ret; + int copied = 0; + if (!*rrset || knot_dname_compare(knot_rrset_owner(*rrset), knot_node_owner(node)) != 0 @@ -1670,6 +1609,7 @@ static int xfrin_apply_remove_rrsigs(xfrin_changes_t *changes, dbg_xfrin("Failed to copy rrset from changeset.\n"); return ret; } + copied = 1; } else { // we should have the right RRSIG RRSet in *rrset assert(knot_rrset_type(*rrset) @@ -1677,6 +1617,7 @@ static int xfrin_apply_remove_rrsigs(xfrin_changes_t *changes, knot_rrset_rdata(remove))); // this RRSet should be the already copied RRSet so we may // update it right away + /*! \todo Does this case even occur? */ } // get the old rrsigs @@ -1686,11 +1627,14 @@ static int xfrin_apply_remove_rrsigs(xfrin_changes_t *changes, } // copy the RRSIGs - /*! \todo This may be done unnecessarily more times. */ - knot_rrset_t *rrsigs; - ret = xfrin_copy_old_rrset(old, &rrsigs, changes); - if (ret != KNOT_EOK) { - return ret; + knot_rrset_t *rrsigs = NULL; + if (!copied) { + ret = xfrin_copy_old_rrset(old, &rrsigs, changes); + if (ret != KNOT_EOK) { + return ret; + } + } else { + rrsigs = old; } // set the RRSIGs to the new RRSet copy @@ -1698,8 +1642,6 @@ static int xfrin_apply_remove_rrsigs(xfrin_changes_t *changes, dbg_xfrin("Failed to set rrsigs.\n"); return KNOT_ERROR; } - - // now in '*rrset' we have a copy of the RRSet which holds the RRSIGs // and in 'rrsigs' we have the copy of the RRSIGs @@ -1710,6 +1652,20 @@ static int xfrin_apply_remove_rrsigs(xfrin_changes_t *changes, knot_strerror(ret)); return 1; } + + // connect the RDATA to the list of old RDATA + ret = xfrin_changes_check_rdata(&changes->old_rdata, + &changes->old_rdata_types, + changes->old_rdata_count, + &changes->old_rdata_allocated, 1); + if (ret != KNOT_EOK) { + return ret; + } + + changes->old_rdata[changes->old_rdata_count] = rdata; + changes->old_rdata_types[changes->old_rdata_count] = + knot_rrset_type(remove); + ++changes->old_rdata_count; // if the RRSet is empty, remove from node and add to old RRSets // check if there is no RRSIGs; if there are, leave the RRSet @@ -1718,6 +1674,7 @@ static int xfrin_apply_remove_rrsigs(xfrin_changes_t *changes, // remove the RRSIGs from the RRSet knot_rrset_set_rrsigs(*rrset, NULL); + // add RRSet to the list of old RRSets ret = xfrin_changes_check_rrsets(&changes->old_rrsets, &changes->old_rrsets_count, &changes->old_rrsets_allocated, @@ -1731,6 +1688,8 @@ static int xfrin_apply_remove_rrsigs(xfrin_changes_t *changes, } changes->old_rrsets[changes->old_rrsets_count++] = rrsigs; + + // saving old RDATA is not necessary as there is none // now check if the RRSet is not totally empty if (knot_rrset_rdata(*rrset) == NULL) { @@ -1758,20 +1717,6 @@ static int xfrin_apply_remove_rrsigs(xfrin_changes_t *changes, } } - // connect the RDATA to the list of old RDATA - ret = xfrin_changes_check_rdata(&changes->old_rdata, - &changes->old_rdata_types, - changes->old_rdata_count, - &changes->old_rdata_allocated, 1); - if (ret != KNOT_EOK) { - return ret; - } - - changes->old_rdata[changes->old_rdata_count] = rdata; - changes->old_rdata_types[changes->old_rdata_count] = - knot_rrset_type(remove); - ++changes->old_rdata_count; - return KNOT_EOK; } @@ -1797,8 +1742,7 @@ static int xfrin_apply_remove_normal(xfrin_changes_t *changes, if (!*rrset || knot_dname_compare(knot_rrset_owner(*rrset), knot_node_owner(node)) != 0 - || knot_rrset_type(*rrset) - != knot_rrset_type(remove)) { + || knot_rrset_type(*rrset) != knot_rrset_type(remove)) { /*! * \todo This may happen also with already * copied RRSet. In that case it would be @@ -1812,7 +1756,7 @@ static int xfrin_apply_remove_normal(xfrin_changes_t *changes, if (ret != KNOT_EOK) { return ret; } - } + } /*! \todo Does some other case even occur? */ if (*rrset == NULL) { dbg_xfrin("RRSet not found for RR to be removed.\n"); @@ -1830,8 +1774,8 @@ dbg_xfrin_exec( // sets) knot_rdata_t *rdata = xfrin_remove_rdata(*rrset, remove); if (rdata == NULL) { - dbg_xfrin("Failed to remove RDATA from RRSet: %s.\n", - knot_strerror(ret)); + dbg_xfrin("Failed to remove RDATA from RRSet\n"); + // In this case, the RDATA was not found in the RRSet return 1; } @@ -1846,6 +1790,20 @@ dbg_xfrin_exec_detail( } while (r != NULL && r != rdata); } ); + + // connect the RDATA to the list of old RDATA + ret = xfrin_changes_check_rdata(&changes->old_rdata, + &changes->old_rdata_types, + changes->old_rdata_count, + &changes->old_rdata_allocated, 1); + if (ret != KNOT_EOK) { + return ret; + } + + changes->old_rdata[changes->old_rdata_count] = rdata; + changes->old_rdata_types[changes->old_rdata_count] = + knot_rrset_type(remove); + ++changes->old_rdata_count; // if the RRSet is empty, remove from node and add to old RRSets // check if there is no RRSIGs; if there are, leave the RRSet @@ -1875,20 +1833,6 @@ dbg_xfrin_exec_detail( changes->old_rrsets[changes->old_rrsets_count++] = *rrset; } - // connect the RDATA to the list of old RDATA - ret = xfrin_changes_check_rdata(&changes->old_rdata, - &changes->old_rdata_types, - changes->old_rdata_count, - &changes->old_rdata_allocated, 1); - if (ret != KNOT_EOK) { - return ret; - } - - changes->old_rdata[changes->old_rdata_count] = rdata; - changes->old_rdata_types[changes->old_rdata_count] = - knot_rrset_type(remove); - ++changes->old_rdata_count; - return KNOT_EOK; } @@ -1897,7 +1841,6 @@ dbg_xfrin_exec_detail( static int xfrin_apply_remove_all_rrsets(xfrin_changes_t *changes, knot_node_t *node, uint16_t type) { - /*! \todo Implement. */ int ret; if (type == KNOT_RRTYPE_ANY) { @@ -1915,7 +1858,8 @@ static int xfrin_apply_remove_all_rrsets(xfrin_changes_t *changes, knot_rrset_t **place = changes->old_rrsets + changes->old_rrsets_count; /*! \todo Test this!!! */ - memcpy(place, rrsets, knot_node_rrset_count(node) * sizeof(knot_rrset_t *)); + memcpy(place, rrsets, knot_node_rrset_count(node) + * sizeof(knot_rrset_t *)); // remove all RRSets from the node knot_node_remove_all_rrsets(node); @@ -1938,83 +1882,11 @@ static int xfrin_apply_remove_all_rrsets(xfrin_changes_t *changes, /*----------------------------------------------------------------------------*/ -static int xfrin_apply_remove(knot_zone_contents_t *contents, - knot_changeset_t *chset, - xfrin_changes_t *changes) -{ - /* - * Iterate over removed RRSets, copy appropriate nodes and remove - * the rrsets from them. By default, the RRSet should be copied so that - * RDATA may be removed from it. - */ - int ret = 0; - knot_node_t *node = NULL; - knot_rrset_t *rrset = NULL; - - for (int i = 0; i < chset->remove_count; ++i) { - // check if the old node is not the one we should use - if (!node || knot_rrset_owner(chset->remove[i]) - != knot_node_owner(node)) { - node = knot_zone_contents_get_node(contents, - knot_rrset_owner(chset->remove[i])); - if (node == NULL) { - dbg_xfrin("Node not found for RR to be removed" - "!\n"); - continue; - } - } - - // create a copy of the node if not already created - if (!knot_node_is_new(node)) { - ret = xfrin_get_node_copy(&node, changes); - if (ret != KNOT_EOK) { - return ret; - } - } - - assert(node != NULL); - assert(knot_node_is_new(node)); - - // first check if all RRSets should be removed - if (knot_rrset_class(chset->remove[i]) == KNOT_CLASS_ANY) { - ret = xfrin_apply_remove_all_rrsets( - changes, node, - knot_rrset_type(chset->remove[i])); - } else if (knot_rrset_type(chset->remove[i]) - == KNOT_RRTYPE_RRSIG) { - // this should work also for UPDATE - ret = xfrin_apply_remove_rrsigs(changes, - chset->remove[i], - node, &rrset); - } else { - // this should work also for UPDATE - ret = xfrin_apply_remove_normal(changes, - chset->remove[i], - node, &rrset); - } - - dbg_xfrin("xfrin_apply_remove() ret = %d\n", ret); - - if (ret > 0) { - continue; - } else if (ret != KNOT_EOK) { - return ret; - } - } - - return KNOT_EOK; -} - -/*----------------------------------------------------------------------------*/ - static knot_node_t *xfrin_add_new_node(knot_zone_contents_t *contents, - knot_rrset_t *rrset) + knot_rrset_t *rrset, int is_nsec3) { - /*! \todo Why is the function disabled? */ - //return NULL; - knot_node_t *node = knot_node_new(knot_rrset_get_owner(rrset), - NULL, KNOT_NODE_FLAGS_NEW); + NULL, 0); if (node == NULL) { dbg_xfrin("Failed to create a new node.\n"); return NULL; @@ -2027,36 +1899,22 @@ static knot_node_t *xfrin_add_new_node(knot_zone_contents_t *contents, // dbg_xfrin("Adding new node to zone. From owner: %s type %s\n", // knot_dname_to_str(node->owner), // knot_rrtype_to_string(rrset->type)); - if (knot_rrset_type(rrset) == KNOT_RRTYPE_NSEC3) { + if (is_nsec3) { ret = knot_zone_contents_add_nsec3_node(contents, node, 1, 0, 1); } else { - ret = knot_zone_contents_add_node(contents, node, 1, - KNOT_NODE_FLAGS_NEW, 1); + ret = knot_zone_contents_add_node(contents, node, 1, 0, 1); } if (ret != KNOT_EOK) { dbg_xfrin("Failed to add new node to zone contents.\n"); return NULL; } - // find previous node and connect the new one to it - knot_node_t *prev = NULL; - if (knot_rrset_type(rrset) == KNOT_RRTYPE_NSEC3) { - prev = knot_zone_contents_get_previous_nsec3(contents, - knot_rrset_owner(rrset)); - } else { - prev = knot_zone_contents_get_previous(contents, - knot_rrset_owner(rrset)); - } - - // fix prev and next pointers - if (prev != NULL) { - knot_node_set_previous(node, prev); - } + /*! + * \note It is not needed to set the previous node, we will do this + * in adjusting after the transfer. + */ -// printf("contents owned by: %s (%p)\n", -// knot_dname_to_str(contents->apex->owner), -// contents); assert(contents->zone != NULL); knot_node_set_zone(node, contents->zone); @@ -2068,12 +1926,14 @@ static knot_node_t *xfrin_add_new_node(knot_zone_contents_t *contents, static int xfrin_apply_add_normal(xfrin_changes_t *changes, knot_rrset_t *add, knot_node_t *node, - knot_rrset_t **rrset) + knot_rrset_t **rrset, + knot_zone_contents_t *contents) { assert(changes != NULL); assert(add != NULL); assert(node != NULL); assert(rrset != NULL); + assert(contents != NULL); int ret; @@ -2104,15 +1964,22 @@ dbg_xfrin_exec_verb( /*! \todo What about domain names?? Shouldn't we use the * zone-contents' version of this function?? */ - ret = knot_node_add_rrset(node, add, 0); -// ret = knot_zone_contents_add_rrset(node->zone->contents, -// rrset, node, -// KNOT_RRSET_DUPL_MERGE, -// 1); - if (ret != KNOT_EOK) { + /*! + * \note The new zone must be adjusted nevertheless, so it + * doesn't matter whether there are some extra dnames to + * be added to the table or not. + */ +// ret = knot_node_add_rrset(node, add, 0); + ret = knot_zone_contents_add_rrset(contents, add, &node, + KNOT_RRSET_DUPL_SKIP, 1); + + if (ret < 0) { dbg_xfrin("Failed to add RRSet to node.\n"); return KNOT_ERROR; } + + assert(ret == 0); + return 1; // return 1 to indicate the add RRSet was used } @@ -2124,7 +1991,7 @@ dbg_xfrin_exec( knot_rrtype_to_string(knot_rrset_type(*rrset))); free(name); ); - knot_rrset_dump(*rrset, 1); +// knot_rrset_dump(*rrset, 1); ret = xfrin_copy_old_rrset(old, rrset, changes); if (ret != KNOT_EOK) { assert(0); @@ -2149,7 +2016,7 @@ dbg_xfrin_exec( dbg_xfrin("Merging RRSets with owners: %s %s types: %d %d\n", (*rrset)->owner->name, add->owner->name, (*rrset)->type, add->type); - dbg_xfrin_detail("RDATA in RRSet1: %p, RDATA in RRSet2: %p\n", + dbg_xfrin_detail("RDATA in RRSet1: %p, RDATA in RRSet2: %p\n", (*rrset)->rdata, add->rdata); ret = knot_rrset_merge((void **)rrset, (void **)&add); if (ret != KNOT_EOK) { @@ -2172,19 +2039,31 @@ dbg_xfrin_exec( static int xfrin_apply_add_rrsig(xfrin_changes_t *changes, knot_rrset_t *add, knot_node_t *node, - knot_rrset_t **rrset) + knot_rrset_t **rrset, + knot_zone_contents_t *contents) { assert(changes != NULL); assert(add != NULL); assert(node != NULL); assert(rrset != NULL); assert(knot_rrset_type(add) == KNOT_RRTYPE_RRSIG); + assert(contents != NULL); int ret; knot_rr_type_t type = knot_rdata_rrsig_type_covered( knot_rrset_rdata(add)); +dbg_xfrin_exec( + char *name = knot_dname_to_str(knot_rrset_owner(add)); + const char *typestr = knot_rrtype_to_string(type); + dbg_xfrin("Adding RRSIG: Owner %s, type covered %s.\n", + name, typestr); + free(name); +); + + int copied = 0; + if (!*rrset || knot_dname_compare(knot_rrset_owner(*rrset), knot_node_owner(node)) != 0 @@ -2194,7 +2073,10 @@ static int xfrin_apply_add_rrsig(xfrin_changes_t *changes, ret = xfrin_copy_rrset(node, type, rrset, changes); if (ret < 0) { return ret; + } else if (ret != KNOT_EOK) { + *rrset = NULL; } + copied = 1; } else { // we should have the right RRSIG RRSet in *rrset assert(knot_rrset_type(*rrset) == type); @@ -2205,6 +2087,7 @@ static int xfrin_apply_add_rrsig(xfrin_changes_t *changes, if (*rrset == NULL) { dbg_xfrin("RRSet to be added not found in zone.\n"); + dbg_xfrin("Creating new RRSet for RRSIG.\n"); // create a new RRSet to add the RRSIGs into *rrset = knot_rrset_new(knot_node_get_owner(node), type, knot_rrset_class(add), @@ -2213,13 +2096,30 @@ static int xfrin_apply_add_rrsig(xfrin_changes_t *changes, dbg_xfrin("Failed to create new RRSet for RRSIGs.\n"); return KNOT_ENOMEM; } - - // add the RRSet from the changeset to the node + + // add the RRset to the list of new RRsets + ret = xfrin_changes_check_rrsets( + &changes->new_rrsets, + &changes->new_rrsets_count, + &changes->new_rrsets_allocated, 1); + if (ret != KNOT_EOK) { + dbg_xfrin("Failed to add old RRSet to " + "list.\n"); + knot_rrset_free(rrset); + return ret; + } + + // add the new RRSet to the node + // not needed to insert it through the zone_contents() function, + // as the owner is already in the dname table ret = knot_node_add_rrset(node, *rrset, 0); if (ret != KNOT_EOK) { dbg_xfrin("Failed to add RRSet to node.\n"); + knot_rrset_free(rrset); return KNOT_ERROR; } + + changes->new_rrsets[changes->new_rrsets_count++] = *rrset; } dbg_xfrin_exec( @@ -2230,11 +2130,18 @@ dbg_xfrin_exec( ); if (knot_rrset_rrsigs(*rrset) == NULL) { - ret = knot_rrset_set_rrsigs(*rrset, add); - if (ret != KNOT_EOK) { + + dbg_xfrin("Adding new RRSIGs to RRSet.\n"); + ret = knot_zone_contents_add_rrsigs(contents, add, rrset, &node, + KNOT_RRSET_DUPL_SKIP, 1); + +// ret = knot_rrset_set_rrsigs(*rrset, add); + if (ret < 0) { dbg_xfrin("Failed to add RRSIGs to the RRSet.\n"); return KNOT_ERROR; } + + assert(ret == 0); return 1; } else { @@ -2242,21 +2149,24 @@ dbg_xfrin_exec( assert(old != NULL); knot_rrset_t *rrsig; - ret = xfrin_copy_old_rrset(old, &rrsig, changes); - if (ret != KNOT_EOK) { - return ret; + if (!copied) { + ret = xfrin_copy_old_rrset(old, &rrsig, changes); + if (ret != KNOT_EOK) { + return ret; + } + } else { + rrsig = old; } // replace the old RRSIGs with the new ones knot_rrset_set_rrsigs(*rrset, rrsig); // merge the changeset RRSet to the copy - /*! \todo What if the update fails? - * - */ + dbg_xfrin("Merging RRSIG to the one in the RRSet.\n"); ret = knot_rrset_merge((void **)&rrsig, (void **)&add); if (ret != KNOT_EOK) { - dbg_xfrin("Failed to merge changeset RRSet to copy.\n"); + dbg_xfrin("Failed to merge changeset RRSIG to copy: %s" + ".\n", knot_strerror(ret)); return KNOT_ERROR; } @@ -2268,83 +2178,416 @@ dbg_xfrin_exec( /*----------------------------------------------------------------------------*/ -static int xfrin_apply_add(knot_zone_contents_t *contents, - knot_changeset_t *chset, - xfrin_changes_t *changes) +static void xfrin_cleanup_update(xfrin_changes_t *changes) +{ + + for (int i = 0; i < changes->old_rrsets_count; ++i) { + dbg_xfrin_detail("Deleting old RRSet: %p\n", + changes->old_rrsets[i]); + knot_rrset_dump(changes->old_rrsets[i], 0); + knot_rrset_free(&changes->old_rrsets[i]); + } + + // delete old RDATA + for (int i = 0; i < changes->old_rdata_count; ++i) { + dbg_xfrin_detail("Deleting old RDATA: %p, type: %s\n", + changes->old_rdata[i], + knot_rrtype_to_string(changes->old_rdata_types[i])); + knot_rdata_dump(changes->old_rdata[i], + changes->old_rdata_types[i], 0); + knot_rdata_t *rdata = changes->old_rdata[i]; + if (rdata != NULL) { + do { + knot_rdata_t *tmp = rdata->next; + knot_rdata_deep_free(&rdata, + changes->old_rdata_types[i], 1); + rdata = tmp; + } while (rdata != NULL + && rdata != changes->old_rdata[i]); + } + + } + + // free allocated arrays of nodes and rrsets + free(changes->new_rrsets); + free(changes->new_rdata); + free(changes->new_rdata_types); + free(changes->old_nodes); + free(changes->old_nsec3); + free(changes->old_rrsets); + free(changes->old_rdata); + free(changes->old_rdata_types); +} + +/*----------------------------------------------------------------------------*/ +/* New changeset applying */ +/*----------------------------------------------------------------------------*/ + +static void xfrin_switch_nodes_in_node(knot_node_t *node, void *data) +{ + assert(node != NULL); + UNUSED(data); + + assert(knot_node_new_node(node) == NULL); + + knot_node_update_refs(node); +} + +/*----------------------------------------------------------------------------*/ + +static void xfrin_switch_node_in_hash_table(ck_hash_table_item_t *item, + void *data) +{ + UNUSED(data); + + if (item == NULL) { + return; + } + + knot_node_t *node = (knot_node_t *)item->value; + knot_node_t *new_node = knot_node_get_new_node(node); + + assert(new_node != NULL); + + if (new_node != NULL) { + item->value = new_node; + } +} + +/*----------------------------------------------------------------------------*/ + +static void xfrin_switch_node_in_dname_table(knot_dname_t *dname, void *data) +{ + UNUSED(data); + + if (knot_dname_node(dname) == NULL) { + return; + } + + assert(knot_node_new_node(knot_dname_node(dname)) != NULL); + knot_dname_set_node(dname, knot_node_get_new_node( + knot_dname_get_node(dname))); +} + +/*----------------------------------------------------------------------------*/ + +static int xfrin_switch_nodes(knot_zone_contents_t *contents_copy) +{ + assert(contents_copy != NULL); + + // Traverse the trees and for each node check every reference + // stored in that node. The node itself should be new. + knot_zone_contents_tree_apply_inorder(contents_copy, + xfrin_switch_nodes_in_node, NULL); + + knot_zone_contents_nsec3_apply_inorder(contents_copy, + xfrin_switch_nodes_in_node, NULL); + + // Then traverse the hash table and change each pointer in hash table + // item from old node to new node. + int ret = ck_apply(knot_zone_contents_get_hash_table(contents_copy), + xfrin_switch_node_in_hash_table, NULL); + assert(ret == 0); + + // Traverse also the dname table and change the node pointers in dnames + knot_zone_contents_dname_table_apply(contents_copy, + xfrin_switch_node_in_dname_table, + NULL); + + return KNOT_EOK; +} + +/*----------------------------------------------------------------------------*/ + +static void xfrin_zone_contents_free2(knot_zone_contents_t **contents) { - // iterate over removed RRSets, copy appropriate nodes and remove - // the rrsets from them + /*! \todo This should be all in some API!! */ + + if ((*contents)->table != NULL) { + ck_destroy_table(&(*contents)->table, NULL, 0); +// ck_table_free(&(*contents)->table); + } + + // free the zone tree, but only the structure + // (nodes are already destroyed) + dbg_zone("Destroying zone tree.\n"); + knot_zone_tree_deep_free(&(*contents)->nodes); + dbg_zone("Destroying NSEC3 zone tree.\n"); + knot_zone_tree_deep_free(&(*contents)->nsec3_nodes); + + knot_nsec3_params_free(&(*contents)->nsec3_params); + + knot_dname_table_deep_free(&(*contents)->dname_table); + + free(*contents); + *contents = NULL; +} + +/*----------------------------------------------------------------------------*/ + +static void xfrin_cleanup_old_nodes(knot_node_t *node, void *data) +{ + UNUSED(data); + assert(node != NULL); + + knot_node_set_new_node(node, NULL); + knot_dname_set_node(knot_node_get_owner(node), node); +} + +/*----------------------------------------------------------------------------*/ + +static void xfrin_rollback_update2(knot_zone_contents_t *old_contents, + knot_zone_contents_t *new_contents, + xfrin_changes_t *changes) +{ + // discard new RRSets + for (int i = 0; i < changes->new_rrsets_count; ++i) { + //knot_rrset_deep_free(&changes->new_rrsets[i], 0, 1, 1); + knot_rrset_free(&changes->new_rrsets[i]); + } + + for (int i = 0; i < changes->new_rdata_count; ++i) { + // discard the whole chain of RDATA + knot_rdata_t *rdata = changes->new_rdata[i]; + knot_rdata_t *rdata_next = NULL; + + while (rdata != NULL && rdata->next != changes->new_rdata[i]) { + rdata_next = rdata->next; + knot_rdata_deep_free(&rdata, + changes->new_rdata_types[i], 1); + rdata = rdata_next; + } + + assert(rdata == NULL || rdata->next == changes->new_rdata[i]); + + knot_rdata_deep_free(&rdata, changes->new_rdata_types[i], 1); + + changes->new_rdata[i] = NULL; + } + + // free allocated arrays of nodes and rrsets + free(changes->new_rrsets); + free(changes->new_rdata); + free(changes->new_rdata_types); + free(changes->old_nodes); + free(changes->old_nsec3); + free(changes->old_rrsets); + free(changes->old_rdata); + free(changes->old_rdata_types); + + // destroy the shallow copy of zone + xfrin_zone_contents_free2(&new_contents); + + // cleanup old zone tree - reset pointers to new node to NULL + // also set pointers from dnames to old nodes + knot_zone_contents_tree_apply_inorder(old_contents, + xfrin_cleanup_old_nodes, NULL); + + knot_zone_contents_nsec3_apply_inorder(old_contents, + xfrin_cleanup_old_nodes, NULL); +} + +/*----------------------------------------------------------------------------*/ + +static int xfrin_apply_remove2(knot_zone_contents_t *contents, + knot_changeset_t *chset, + xfrin_changes_t *changes) +{ + /* + * Iterate over removed RRSets, and remove them from the new nodes + * in 'contents'. By default, the RRSet should be copied so that + * RDATA may be removed from it. + */ int ret = 0; knot_node_t *node = NULL; knot_rrset_t *rrset = NULL; + int is_nsec3 = 0; + + for (int i = 0; i < chset->remove_count; ++i) { + + is_nsec3 = 0; + + // check if the RRSet belongs to the NSEC3 tree + if ((knot_rrset_type(chset->remove[i]) == KNOT_RRTYPE_NSEC3) + || (knot_rrset_type(chset->remove[i]) == KNOT_RRTYPE_RRSIG + && knot_rdata_rrsig_type_covered( + knot_rrset_rdata(chset->remove[i])) + == KNOT_RRTYPE_NSEC3)) + { + is_nsec3 = 1; + } + + // check if the old node is not the one we should use + if (!node || knot_rrset_owner(chset->remove[i]) + != knot_node_owner(node)) { + if (is_nsec3) { + node = knot_zone_contents_get_nsec3_node( + contents, + knot_rrset_owner(chset->remove[i])); + } else { + node = knot_zone_contents_get_node(contents, + knot_rrset_owner(chset->remove[i])); + } + if (node == NULL) { + dbg_xfrin("Node not found for RR to be removed" + "!\n"); + continue; + } + } + + assert(node != NULL); + + // first check if all RRSets should be removed + if (knot_rrset_class(chset->remove[i]) == KNOT_CLASS_ANY) { + ret = xfrin_apply_remove_all_rrsets( + changes, node, + knot_rrset_type(chset->remove[i])); + } else if (knot_rrset_type(chset->remove[i]) + == KNOT_RRTYPE_RRSIG) { + // this should work also for UPDATE + ret = xfrin_apply_remove_rrsigs(changes, + chset->remove[i], + node, &rrset); + } else { + // this should work also for UPDATE + ret = xfrin_apply_remove_normal(changes, + chset->remove[i], + node, &rrset); + } + + dbg_xfrin("xfrin_apply_remove() ret = %d\n", ret); + + if (ret > 0) { + continue; + } else if (ret != KNOT_EOK) { + return ret; + } + } + + return KNOT_EOK; +} + +/*----------------------------------------------------------------------------*/ + +static int xfrin_apply_add2(knot_zone_contents_t *contents, + knot_changeset_t *chset, + xfrin_changes_t *changes) +{ + int ret = 0; + knot_node_t *node = NULL; + knot_rrset_t *rrset = NULL; + + int is_nsec3 = 0; + for (int i = 0; i < chset->add_count; ++i) { dbg_xfrin_detail("Adding RRSet:\n"); knot_rrset_dump(chset->add[i], 0); + + is_nsec3 = 0; + + // check if the RRSet belongs to the NSEC3 tree + if ((knot_rrset_type(chset->add[i]) == KNOT_RRTYPE_NSEC3) + || (knot_rrset_type(chset->add[i]) == KNOT_RRTYPE_RRSIG + && knot_rdata_rrsig_type_covered( + knot_rrset_rdata(chset->add[i])) + == KNOT_RRTYPE_NSEC3)) + { + dbg_xfrin_verb("This is NSEC3-related RRSet.\n"); + is_nsec3 = 1; + } + // check if the old node is not the one we should use if (!node || knot_rrset_owner(chset->add[i]) != knot_node_owner(node)) { - node = knot_zone_contents_get_node(contents, - knot_rrset_owner(chset->add[i])); + dbg_xfrin_verb("Searching for node...\n"); + if (is_nsec3) { + node = knot_zone_contents_get_nsec3_node( + contents, + knot_rrset_owner(chset->add[i])); + } else { + node = knot_zone_contents_get_node(contents, + knot_rrset_owner(chset->add[i])); + } if (node == NULL) { // create new node, connect it properly to the // zone nodes - dbg_xfrin("Creating new node from.\n"); + dbg_xfrin("Node not found. Creating new.\n"); node = xfrin_add_new_node(contents, - chset->add[i]); + chset->add[i], + is_nsec3); if (node == NULL) { dbg_xfrin("Failed to create new node " "in zone.\n"); return KNOT_ERROR; } -// continue; // continue with another RRSet } } - // create a copy of the node if not already created - if (!knot_node_is_new(node)) { - xfrin_get_node_copy(&node, changes); - } - assert(node != NULL); - assert(knot_node_is_new(node)); - + if (knot_rrset_type(chset->add[i]) == KNOT_RRTYPE_RRSIG) { ret = xfrin_apply_add_rrsig(changes, chset->add[i], - node, &rrset); + node, &rrset, contents); } else { ret = xfrin_apply_add_normal(changes, chset->add[i], - node, &rrset); + node, &rrset, contents); } - + + assert(ret != KNOT_EOK); + dbg_xfrin("xfrin_apply_..() returned %d, rrset: %p\n", ret, rrset); - - if (ret == 1) { - // the ADD RRSet was used, i.e. it should be removed - // from the changeset and saved in the list of new - // RRSets - ret = xfrin_changes_check_rrsets( - &changes->new_rrsets, - &changes->new_rrsets_count, - &changes->new_rrsets_allocated, 1); - if (ret != KNOT_EOK) { - dbg_xfrin("Failed to add old RRSet to list.\n"); - return ret; + + if (ret > 0) { + // store the new RDATA + // in both cases it must be deleted if the transfer + // fails + + // connect the RDATA to the list of old RDATA + int res = xfrin_changes_check_rdata(&changes->new_rdata, + &changes->new_rdata_types, + changes->new_rdata_count, + &changes->new_rdata_allocated, 1); + if (res != KNOT_EOK) { + return res; } - changes->new_rrsets[changes->new_rrsets_count++] = - chset->add[i]; + changes->new_rdata[changes->new_rdata_count] = + knot_rrset_get_rdata(chset->add[i]); + changes->new_rdata_types[changes->new_rdata_count] = + knot_rrset_type(chset->add[i]); + ++changes->new_rdata_count; + + if (ret == 1) { + // the ADD RRSet was used, i.e. it should be + // removed from the changeset and saved in the + // list of new RRSets + ret = xfrin_changes_check_rrsets( + &changes->new_rrsets, + &changes->new_rrsets_count, + &changes->new_rrsets_allocated, 1); + if (ret != KNOT_EOK) { + dbg_xfrin("Failed to add old RRSet to " + "list.\n"); + return ret; + } + + changes->new_rrsets[changes->new_rrsets_count++] + = chset->add[i]; + + chset->add[i] = NULL; + } else if (ret == 2) { + // the copy of the RRSet was used, but it was + // already stored in the new RRSets list + // just delete the add RRSet, but without RDATA + // as these were merged to the copied RRSet + knot_rrset_free(&chset->add[i]); + } else { + assert(0); + } - chset->add[i] = NULL; - } else if (ret == 2) { - // the copy of the RRSet was used, but it was already - // stored in the new RRSets list - // just delete the add RRSet, but without RDATA - // as these were merged to the copied RRSet - knot_rrset_free(&chset->add[i]); } else if (ret != KNOT_EOK) { - return ret; } } @@ -2353,51 +2596,18 @@ static int xfrin_apply_add(knot_zone_contents_t *contents, } /*----------------------------------------------------------------------------*/ -/*! - * \todo This must be tested!! Simulate failure somehow. - */ -static void xfrin_clean_changes_after_fail(xfrin_changes_t *changes) -{ - /* 1) Delete copies of RRSets created because they were updated. - * Do not delete their RDATA or owners. - */ - for (int i = 0; i < changes->new_rrsets_count; ++i) { - knot_rrset_free(&changes->new_rrsets[i]); - } - - /* 2) Delete copies of nodes created because they were updated. - * Do not delete their RRSets. - */ - for (int i = 0; i < changes->new_nodes_count; ++i) { - knot_node_free(&changes->new_nodes[i], 0, 1); - } - - // changesets will be deleted elsewhere - // so just delete the changes structure - xfrin_changes_free(&changes); -} - -/*----------------------------------------------------------------------------*/ -static int xfrin_apply_replace_soa(knot_zone_contents_t *contents, - xfrin_changes_t *changes, - knot_changeset_t *chset) +static int xfrin_apply_replace_soa2(knot_zone_contents_t *contents, + xfrin_changes_t *changes, + knot_changeset_t *chset) { knot_node_t *node = knot_zone_contents_get_apex(contents); assert(node != NULL); int ret = 0; - // create a copy of the node if not already created - if (!knot_node_is_new(node)) { - ret = xfrin_get_node_copy(&node, changes); - if (ret != KNOT_EOK) { - return ret; - } - } + assert(node != NULL); - assert(knot_node_is_new(node)); - // set the node copy as the apex of the contents contents->apex = node; @@ -2431,7 +2641,17 @@ static int xfrin_apply_replace_soa(knot_zone_contents_t *contents, &changes->new_rrsets_count, &changes->new_rrsets_allocated, 1); if (ret != KNOT_EOK) { - dbg_xfrin("Failed to add old RRSet to list.\n"); + dbg_xfrin("Failed to add new RRSet to list.\n"); + return ret; + } + + // save the new SOA RDATA + ret = xfrin_changes_check_rdata(&changes->new_rdata, + &changes->new_rdata_types, + changes->new_rdata_count, + &changes->new_rdata_allocated, 1); + if (ret != KNOT_EOK) { + dbg_xfrin("Failed to add new RDATA to list.\n"); return ret; } @@ -2442,15 +2662,27 @@ static int xfrin_apply_replace_soa(knot_zone_contents_t *contents, changes->old_rdata_types[changes->old_rdata_count] = KNOT_RRTYPE_SOA; ++changes->old_rdata_count; + // store RRSIGs from the old SOA to the new SOA + knot_rrset_set_rrsigs(chset->soa_to, knot_rrset_get_rrsigs(rrset)); + // insert the new SOA RRSet to the node dbg_xfrin_verb("Adding SOA.\n"); - ret = knot_node_add_rrset(node, chset->soa_to, 0); - if (ret != KNOT_EOK) { + //ret = knot_node_add_rrset(node, chset->soa_to, 0); + ret = knot_zone_contents_add_rrset(contents, chset->soa_to, &node, + KNOT_RRSET_DUPL_SKIP, 1); + + if (ret < 0) { dbg_xfrin("Failed to add RRSet to node.\n"); return KNOT_ERROR; } + assert(ret == 0); changes->new_rrsets[changes->new_rrsets_count++] = chset->soa_to; + changes->new_rdata[changes->new_rdata_count] = + knot_rrset_get_rdata(chset->soa_to); + changes->new_rdata_types[changes->new_rdata_count] = + knot_rrset_type(chset->soa_to); + ++changes->new_rdata_count; // remove the SOA from the changeset, so it will not be deleted after // successful apply @@ -2461,9 +2693,9 @@ static int xfrin_apply_replace_soa(knot_zone_contents_t *contents, /*----------------------------------------------------------------------------*/ -static int xfrin_apply_changeset(knot_zone_contents_t *contents, - xfrin_changes_t *changes, - knot_changeset_t *chset) +static int xfrin_apply_changeset2(knot_zone_contents_t *contents, + xfrin_changes_t *changes, + knot_changeset_t *chset) { /* * Applies one changeset to the zone. Checks if the changeset may be @@ -2481,383 +2713,293 @@ static int xfrin_apply_changeset(knot_zone_contents_t *contents, return KNOT_ERROR; } - int ret = xfrin_apply_remove(contents, chset, changes); + int ret = xfrin_apply_remove2(contents, chset, changes); if (ret != KNOT_EOK) { - xfrin_clean_changes_after_fail(changes); +// xfrin_clean_changes_after_fail2(changes); return ret; } - ret = xfrin_apply_add(contents, chset, changes); + ret = xfrin_apply_add2(contents, chset, changes); if (ret != KNOT_EOK) { - xfrin_clean_changes_after_fail(changes); +// xfrin_clean_changes_after_fail(changes); return ret; } - /*! \todo Only if SOA is present? */ - return xfrin_apply_replace_soa(contents, changes, chset); + return xfrin_apply_replace_soa2(contents, changes, chset); } /*----------------------------------------------------------------------------*/ -static void xfrin_check_node_in_tree(knot_zone_tree_node_t *tnode, void *data) +static void xfrin_mark_empty(knot_node_t *node, void *data) { - assert(tnode != NULL); + assert(node != NULL); assert(data != NULL); - assert(tnode->node != NULL); - - xfrin_changes_t *changes = (xfrin_changes_t *)data; - - knot_node_t *node = knot_node_get_new_node(tnode->node); - - if (node == NULL) { - // no RRSets were removed from this node, thus it cannot be - // empty - return; - } - dbg_xfrin("xfrin_check_node_in_tree: children of old node: %u, " - "children of new node: %u.\n", - knot_node_children(node), - knot_node_children(tnode->node)); + xfrin_changes_t *changes = (xfrin_changes_t *)data; - - // check if the node is empty and has no children - // to be sure, check also the count of children of the old node if (knot_node_rrset_count(node) == 0 - && knot_node_children(node) == 0 - && knot_node_children(tnode->node) == 0) { - // in this case the new node copy should be removed - // but it cannot be deleted because if a rollback happens, - // the node must be in the new nodes list - // just add it to the old nodes list so that it is deleted - // after successful update - - // set the new node of the old node to NULL - knot_node_set_new_node(tnode->node, NULL); - - // if the parent has a new copy, decrease the number of - // children of that copy - if (knot_node_new_node(knot_node_parent(node, 0))) { - /*! \todo Replace by some API. */ - --node->parent->new_node->children; - } - - // put the new node to te list of old nodes - if (xfrin_changes_check_nodes(&changes->old_nodes, - &changes->old_nodes_count, - &changes->old_nodes_allocated) - != KNOT_EOK) { - /*! \todo Notify about the error!!! */ + && knot_node_children(node) == 0) { + int ret = xfrin_changes_check_nodes(&changes->old_nodes, + &changes->old_nodes_count, + &changes->old_nodes_allocated); + if (ret != KNOT_EOK) { + /*! \todo Stop on error? */ return; } - + changes->old_nodes[changes->old_nodes_count++] = node; - - // leave the old node in the old node list, we will delete - // it later + + if (node->parent != NULL) { + assert(node->parent->children > 0); + --node->parent->children; + if (node->parent->wildcard_child == node) { + node->parent->wildcard_child = NULL; + } + node->parent = NULL; + } } } /*----------------------------------------------------------------------------*/ -static int xfrin_finalize_remove_nodes(knot_zone_contents_t *contents, - xfrin_changes_t *changes) +static void xfrin_mark_empty_nsec3(knot_node_t *node, void *data) { - assert(contents != NULL); - assert(changes != NULL); - - knot_node_t *node; - knot_zone_tree_node_t *removed; - ck_hash_table_item_t *rem_hash; - int ret; - - for (int i = 0; i < changes->old_nodes_count; ++i) { - node = changes->old_nodes[i]; + assert(node != NULL); + assert(data != NULL); - // if the node is marked as old and has no new node copy - // remove it from the zone structure but do not delete it - // that may be done only after the grace period - if (knot_node_is_old(node) - && knot_node_new_node(node) == NULL) { - - if (knot_node_rrset(node, KNOT_RRTYPE_NSEC3) - != NULL) { - ret = knot_zone_contents_remove_nsec3_node( - contents, node, &removed); - } else { - ret = knot_zone_contents_remove_node( - contents, node, &removed, &rem_hash); - } - if (ret != KNOT_EOK) { - dbg_xfrin("Failed to remove node from zone" - "!\n"); - return KNOT_ENONODE; - } - - assert(removed != NULL); - assert(removed->node == node); - // delete the tree node (not needed) - free(removed); - - if (rem_hash != NULL) { - // save the removed hash table item - ret = xfrin_changes_check_hash_items( - &changes->old_hash_items, - &changes->old_hash_items_count, - &changes->old_hash_items_allocated); - if (ret != KNOT_EOK) { - dbg_xfrin("Failed to save the hash" - " table item to list of " - "old items.\n"); - return ret; - } - changes->old_hash_items[ - changes->old_hash_items_count++] - = rem_hash; + xfrin_changes_t *changes = (xfrin_changes_t *)data; + + if (knot_node_rrset_count(node) == 0 + && knot_node_children(node) == 0) { + int ret = xfrin_changes_check_nodes(&changes->old_nsec3, + &changes->old_nsec3_count, + &changes->old_nsec3_allocated); + if (ret != KNOT_EOK) { + /*! \todo Stop on error? */ + return; + } + + changes->old_nsec3[changes->old_nsec3_count++] = node; + + if (node->parent != NULL) { + assert(node->parent->children > 0); + --node->parent->children; + if (node->parent->wildcard_child == node) { + node->parent->wildcard_child = NULL; } + node->parent = NULL; } } - return KNOT_EOK; } /*----------------------------------------------------------------------------*/ -static int xfrin_finalize_contents(knot_zone_contents_t *contents, - xfrin_changes_t *changes) +static int xfrin_remove_empty_nodes(knot_zone_contents_t *contents, + xfrin_changes_t *changes) { - // don't know what should have been done here, except for one thing: - // walk through the zone and remove empty nodes (save them in the - // old nodes list). But only those having no children!!! - - /* - * Walk through the zone and remove empty nodes. - * We must walk backwards, so that children are processed before - * their parents. This will allow to remove chain of parent-children - * nodes. - * We cannot remove the nodes right away as it would modify the very - * structure used for walking through the zone. Just put the nodes - * to the list of old nodes to be removed. - * We must also decrease the node's parent's children count now - * and not when deleting the node, so that the chain of parent-child - * nodes may be removed. - */ - knot_zone_tree_t *t = knot_zone_contents_get_nodes(contents); - assert(t != NULL); - + int ret; + + dbg_xfrin("OLD NODES COUNT: %d\n", changes->old_nodes_count); + dbg_xfrin("OLD NSEC3 NODES COUNT: %d\n", changes->old_nsec3_count); + // walk through the zone and select nodes to be removed - knot_zone_tree_reverse_apply_postorder(t, xfrin_check_node_in_tree, - (void *)changes); - + ret = knot_zone_contents_tree_apply_inorder_reverse(contents, + xfrin_mark_empty, + (void *)changes); + assert(ret == KNOT_EOK); + // Do the same with NSEC3 nodes. - t = knot_zone_contents_get_nsec3_nodes(contents); - assert(t != NULL); - - knot_zone_tree_reverse_apply_postorder(t, xfrin_check_node_in_tree, - (void *)changes); - - // remove the nodes one by one - return xfrin_finalize_remove_nodes(contents, changes); -} + ret = knot_zone_contents_nsec3_apply_inorder_reverse(contents, + xfrin_mark_empty_nsec3, + (void *)changes); + assert(ret == KNOT_EOK); -/*----------------------------------------------------------------------------*/ + dbg_xfrin("OLD NODES COUNT: %d\n", changes->old_nodes_count); + dbg_xfrin("OLD NSEC3 NODES COUNT: %d\n", changes->old_nsec3_count); -static void xfrin_fix_refs_in_node(knot_zone_tree_node_t *tnode, void *data) -{ - /*! \todo Passed data is always seto to NULL. */ - assert(tnode != NULL); - //assert(data != NULL); + // remove these nodes from both hash table and the tree + ck_hash_table_item_t *hash_item = NULL; + knot_zone_tree_node_t *zone_node = NULL; - //xfrin_changes_t *changes = (xfrin_changes_t *)data; + for (int i = 0; i < changes->old_nodes_count; ++i) { + zone_node = NULL; + hash_item = NULL; - // 1) Fix the reference to the node to the new one if there is some - knot_node_t *node = tnode->node; + char *name = knot_dname_to_str(knot_node_owner( + changes->old_nodes[i])); + dbg_xfrin_detail("Old node #%d: %p, %s\n", i, + changes->old_nodes[i], name); + free(name); - knot_node_t *new_node = knot_node_get_new_node(node); - if (new_node != NULL) { - //assert(knot_node_rrset_count(new_node) > 0); - node = new_node; - tnode->node = new_node; - } + ret = knot_zone_contents_remove_node( + contents, changes->old_nodes[i], &zone_node, + &hash_item); - // 2) fix references from the node remaining in the zone - knot_node_update_refs(node); -} + if (ret != KNOT_EOK) { + dbg_xfrin("Failed to remove node from zone!\n"); + return KNOT_ENONODE; + } -/*----------------------------------------------------------------------------*/ + free(hash_item); + free(zone_node); + knot_node_free(&changes->old_nodes[i], 0); + } + changes->old_nodes_count = 0; -static void xfrin_fix_gen_in_node(knot_zone_tree_node_t *tnode, void *data) -{ - /*! \todo Passed data is always seto to NULL. */ - assert(tnode != NULL); - - knot_node_t *node = tnode->node; + // remove NSEC3 nodes + for (int i = 0; i < changes->old_nsec3_count; ++i) { + zone_node = NULL; - knot_node_set_old(node); -} + char *name = knot_dname_to_str(knot_node_owner( + changes->old_nsec3[i])); + dbg_xfrin_detail("Old NSEC3 node #%d: %p, %s\n", i, + changes->old_nsec3[i], name); + free(name); -/*----------------------------------------------------------------------------*/ + ret = knot_zone_contents_remove_nsec3_node( + contents, changes->old_nsec3[i], &zone_node); -static void xfrin_fix_hash_refs(ck_hash_table_item_t *item, void *data) -{ - if (item == NULL) { - return; - } - - knot_node_t *new_node = knot_node_get_new_node( - (knot_node_t *)item->value); - if (new_node != NULL) { - assert(item->key_length - == knot_dname_size(knot_node_owner(new_node))); - assert(strncmp(item->key, (const char *)knot_dname_name( - knot_node_owner(new_node)), item->key_length) == 0); - item->value = (void *)new_node; - item->key = (const char *)knot_dname_name( - knot_node_owner(new_node)); + if (ret != KNOT_EOK) { + dbg_xfrin("Failed to remove NSEC3 node from zone!\n"); + return KNOT_ENONODE; + } + + free(zone_node); + knot_node_free(&changes->old_nsec3[i], 0); } + changes->old_nsec3_count = 0; + + return KNOT_EOK; } /*----------------------------------------------------------------------------*/ -static void xfrin_fix_dname_refs(knot_dname_t *dname, void *data) -{ - UNUSED(data); - knot_dname_update_node(dname); -} +//static int xfrin_adjust_contents(knot_zone_contents_t *contents, +// xfrin_changes_t *changes) +//{ +// // first, load the NSEC3PARAM record, if there is one +// const knot_node_t *apex = knot_zone_contents_apex(contents); +// assert(apex != NULL); +// const knot_rrset_t *rrset = knot_node_rrset(apex, +// KNOT_RRTYPE_NSEC3PARAM); + +// if (rrset != NULL) { +// knot_nsec3_params_from_wire(&contents->nsec3_params, rrset); +// } else { +// memset(&contents->nsec3_params, 0, sizeof(knot_nsec3_params_t)); +// } + +// // ^ OK + +// xfrin_adjust_data_t data; +//// data.changes = changes; +// data.contents = contents; +// data.err = KNOT_EOK; + +// /* +// * Select and delete empty nodes. +// * +// * TODO: do separately +// */ +// int ret = xfrin_remove_empty_nodes(contents, changes); +// if (ret != KNOT_EOK) { +// dbg_xfrin("Failed to remove empty nodes: %s\n", +// knot_strerror(ret)); +// return ret; +// } + +// /* +// * Walk through the nodes in the zone and do the following: +// * 1) Check node flags (authoritative / non-authoritative / deleg. pt.). +// * 2) For each node without NSEC3 node, try to find the NSEC3 node. +// * 3) Insert all dnames to dname table. +// * +// * We must also set previous nodes, as this cannot be done during +// * node insertion - in that time we do not know, if the node is +// * authoritative or no. +// */ + +// knot_zone_contents_tree_apply_inorder(contents, +// xfrin_adjust_node_in_tree, +// (void *)&data); + +// if (data.err != KNOT_EOK) { +// dbg_xfrin("Failed to adjust nodes after IXFR: %s\n", +// knot_strerror(data.err)); +// return data.err; +// } + +// /* +// * In second walkthrough check CNAME loops, including wildcards. +// */ +// knot_zone_contents_tree_apply_inorder(contents, +// xfrin_check_loops_in_tree, +// (void *)&data); + +// return data.err; +//} /*----------------------------------------------------------------------------*/ -static int xfrin_fix_references(knot_zone_contents_t *contents) +static void xfrin_check_contents_copy_node(knot_node_t *node, void *data) { - /*! \todo This function must not fail!! */ + assert(node != NULL); + assert(data != NULL); - /* - * Now the contents are already switched, and we should update all - * references not updated yet, so that the old contents may be removed. - * - * Walk through the zone tree, so that each node will be checked - * and updated. - */ - // fix references in normal nodes - knot_zone_tree_t *tree = knot_zone_contents_get_nodes(contents); - knot_zone_tree_forward_apply_inorder(tree, xfrin_fix_refs_in_node, - NULL); + int *err = (int *)data; - // fix refereces in NSEC3 nodes - tree = knot_zone_contents_get_nsec3_nodes(contents); - knot_zone_tree_forward_apply_inorder(tree, xfrin_fix_refs_in_node, - NULL); + if (*err != KNOT_EOK) { + return; + } - // fix references in hash table - ck_hash_table_t *table = knot_zone_contents_get_hash_table(contents); - ck_apply(table, xfrin_fix_hash_refs, NULL); - - // fix references dname table - int ret = knot_zone_contents_dname_table_apply(contents, - xfrin_fix_dname_refs, NULL); - assert(ret == KNOT_EOK); - - return KNOT_EOK; + if (knot_node_new_node(node) == NULL) { + *err = KNOT_ENONODE; + } } /*----------------------------------------------------------------------------*/ -static int xfrin_fix_generation(knot_zone_contents_t *contents) +static int xfrin_check_contents_copy(knot_zone_contents_t *old_contents) { - assert(contents != NULL); - - knot_zone_tree_t *tree = knot_zone_contents_get_nodes(contents); - knot_zone_tree_forward_apply_inorder(tree, xfrin_fix_gen_in_node, - NULL); - - tree = knot_zone_contents_get_nsec3_nodes(contents); - knot_zone_tree_forward_apply_inorder(tree, xfrin_fix_gen_in_node, - NULL); - - return KNOT_EOK; -} + int err = KNOT_EOK; -/*----------------------------------------------------------------------------*/ + int ret = knot_zone_contents_tree_apply_inorder(old_contents, + xfrin_check_contents_copy_node, + &err); -static void xfrin_cleanup_update(xfrin_changes_t *changes) -{ - // free old nodes but do not destroy their RRSets - // remove owners also, because of reference counting - for (int i = 0; i < changes->old_nodes_count; ++i) { - dbg_xfrin_detail("Deleting old node: %p\n", changes->old_nodes[i]); - knot_node_dump(changes->old_nodes[i], 0); - knot_node_free(&changes->old_nodes[i], 1, 0); - } - - // free old RRSets, and destroy also domain names in them - // because of reference counting - - // check if there are not some duplicate RRSets -// for (int i = 0; i < changes->old_rrsets_count; ++i) { -// for (int j = i + 1; j < changes->old_rrsets_count; ++j) { -// if (changes->old_rrsets[i] == changes->old_rrsets[j]) { -// assert(0); -// } -// if (changes->old_rrsets[i]->rdata != NULL -// && changes->old_rrsets[i]->rdata -// == changes->old_rrsets[j]->rdata) { -// assert(0); -// } -// } -// } + assert(ret == KNOT_EOK); - for (int i = 0; i < changes->old_rrsets_count; ++i) { -// knot_rrset_deep_free(&changes->old_rrsets[i], 1, 1, 1); - dbg_xfrin_detail("Deleting old RRSet: %p\n", changes->old_rrsets[i]); - knot_rrset_dump(changes->old_rrsets[i], 0); - knot_rrset_free(&changes->old_rrsets[i]); + if (err == KNOT_EOK) { + ret = knot_zone_contents_nsec3_apply_inorder(old_contents, + xfrin_check_contents_copy_node, + &err); } - // delete old RDATA - for (int i = 0; i < changes->old_rdata_count; ++i) { - dbg_xfrin_detail("Deleting old RDATA: %p, type: %s\n", - changes->old_rdata[i], - knot_rrtype_to_string(changes->old_rdata_types[i])); - knot_rdata_dump(changes->old_rdata[i], changes->old_rdata_types[i], 0); - knot_rdata_t *rdata = changes->old_rdata[i]; - assert(rdata != NULL); - do { - knot_rdata_t *tmp = rdata->next; - knot_rdata_deep_free(&rdata, - changes->old_rdata_types[i], 1); - rdata = tmp; - } while (rdata != NULL && rdata != changes->old_rdata[i]); - changes->old_rdata[i] = NULL; - } - - // free old hash table items, but do not touch their contents - for (int i = 0; i < changes->old_hash_items_count; ++i) { - free(changes->old_hash_items[i]); + assert(ret == KNOT_EOK); + + if (knot_node_new_node(knot_zone_contents_apex(old_contents)) == NULL) { + return KNOT_ENONODE; } - free(changes->old_hash_items); - // free allocated arrays of nodes and rrsets - free(changes->new_nodes); - free(changes->old_nodes); - free(changes->new_rrsets); - free(changes->old_rrsets); - free(changes->old_rdata); - free(changes->old_rdata_types); + return err; } /*----------------------------------------------------------------------------*/ -int xfrin_apply_changesets_to_zone(knot_zone_t *zone, - knot_changesets_t *chsets) +int xfrin_apply_changesets(knot_zone_t *zone, + knot_changesets_t *chsets) { if (zone == NULL || chsets == NULL || chsets->count == 0) { return KNOT_EBADARG; } - + knot_zone_contents_t *old_contents = knot_zone_get_contents(zone); if (!old_contents) { return KNOT_EBADARG; } - + + dbg_xfrin("Applying changesets to zone...\n"); + // dbg_xfrin("\nOLD ZONE CONTENTS:\n\n"); // knot_zone_contents_dump(old_contents, 1); @@ -2877,137 +3019,116 @@ int xfrin_apply_changesets_to_zone(knot_zone_t *zone, * updated. * * This will create new zone contents structures (normal nodes' tree, - * NSEC3 tree, hash table, domain name table), but fill them with the - * data from the old contents. + * NSEC3 tree, hash table, domain name table), and copy all nodes. + * The data in the nodes (RRSets) remain the same though. */ knot_zone_contents_t *contents_copy = NULL; - int ret = knot_zone_contents_shallow_copy(old_contents, - &contents_copy); + dbg_xfrin("Copying zone contents.\n"); + int ret = knot_zone_contents_shallow_copy2(old_contents, + &contents_copy); if (ret != KNOT_EOK) { dbg_xfrin("Failed to create shallow copy of zone: %s\n", knot_strerror(ret)); return ret; } - /* - * Now, apply one changeset after another until all are applied. - * Changesets may be either from IXFR or from a dynamic update. - * Dynamic updates use special TYPE and CLASS values to distinguish - * requests, such as "remove all RRSets from a node", "remove all RRs - * with the specified type from a node", etc. - * - * When updating anything within some node (removing RR, adding RR), - * the node structure is copied, but the RRSets within are not. - * - * 1) When removing RRs from node, The affected RRSet is copied. This - * it also a 'shallow copy', i.e. the RDATA remain the exact same. - * The specified RRs (i.e. RDATA) are then removed from the copied - * RRSet. - * 2) When adding RRs to node, there are two cases: - * a) If there is a RRSet that should contain these RRs - * this RRSet is copied (shallow copy) and the RRs are added to - * it (rrset_merge()). - * b) If there is not such a RRSet, the whole RRSet from the - * changeset is added to the new node (thus this RRSet must not - * be deleted afterwards). - * - * A special case are RRSIG RRs. These functions assume that they - * are grouped together in knot_rrset_t structures according to - * their header (owner, type, class) AND their 'type covered', i.e. - * there may be more RRSIG RRSets in one changeset (while there - * should not be more RRSets of any other type). - * 3) When removing RRSIG RRs from node, the appropriate RRSet holding - * them must be found (according to the 'type covered' field). This - * RRSet is then copied (shallow copy), Its RRSIGs are also copied - * and the RRSIG RRs are added to the RRSIG copy. - * 4) When adding RRSIG RRs to node, the same process is done - the - * proper RRSet holding them is found, copied, its RRSIGs are - * copied (if there are some) and the RRs are added to the copy. - * - * When a node is copied, reference to the copy is stored within the - * old node (node_t.old_node). This is important, because when the - * zone contents are switched to the new ones, references from old nodes - * that should point to new nodes are not yet set (it would influence - * replying from the old zone contents). While all these references - * (such as node_t.prev, node_t.next, node_t.parent, etc.) are properly - * modified, the search functions use old or new nodes accordingly - * (old nodes while old contents are used, new nodes when new contents - * are used). The 'check_version' parameter turns on this behaviour in - * search functions. - * - * In case of error, we must remove all data created by the update, i.e. - * - new nodes, - * - new RRSets, - * and remove the references to the new nodes from old nodes. - * - * In case of success, the RRSet structures from the changeset - * structures must not be deleted, as they are either already used by - * the server (stored within the new zone contents) or deleted when - * cleaning up the temporary 'changes' structure. - */ xfrin_changes_t changes; memset(&changes, 0, sizeof(xfrin_changes_t)); + /*! + * \todo Check if all nodes have their copy. + */ + ret = xfrin_check_contents_copy(old_contents); + if (ret != KNOT_EOK) { + dbg_xfrin("Contents copy check failed!\n"); + xfrin_rollback_update2(old_contents, contents_copy, &changes); + return ret; + } + + assert(knot_zone_contents_apex(contents_copy) != NULL); + + /* + * Fix references to new nodes. Some references in new nodes may point + * to old nodes. Hash table contains only old nodes. + */ + dbg_xfrin("Switching ptrs pointing to old nodes to the new nodes.\n"); + ret = xfrin_switch_nodes(contents_copy); + assert(knot_zone_contents_apex(contents_copy) != NULL); + + /* + * Apply the changesets. + */ + dbg_xfrin("Applying changesets.\n"); + dbg_xfrin_verb("Old contents apex: %p, new apex: %p\n", + old_contents->apex, contents_copy->apex); for (int i = 0; i < chsets->count; ++i) { - if ((ret = xfrin_apply_changeset(contents_copy, &changes, - &chsets->sets[i])) != KNOT_EOK) { - xfrin_rollback_update(contents_copy, &changes); + if ((ret = xfrin_apply_changeset2(contents_copy, &changes, + &chsets->sets[i])) + != KNOT_EOK) { + xfrin_rollback_update2(old_contents, + contents_copy, &changes); dbg_xfrin("Failed to apply changesets to zone: " "%s\n", knot_strerror(ret)); return ret; } } + assert(knot_zone_contents_apex(contents_copy) != NULL); + + /*! + * \todo Test failure of IXFR. + */ /* - * When all changesets are applied, set generation 1 to the copy of - * the zone so that new nodes are used instead of old ones. + * Finalize the new zone contents: + * - delete empty nodes + * - parse NSEC3PARAM + * - do adjusting of nodes and RDATA + * - ??? */ -// knot_zone_contents_switch_generation(contents_copy); - //contents_copy->generation = 1; - knot_zone_contents_set_gen_new(contents_copy); /* - * Finalize the zone contents. + * Select and delete empty nodes. */ - ret = xfrin_finalize_contents(contents_copy, &changes); + ret = xfrin_remove_empty_nodes(contents_copy, &changes); if (ret != KNOT_EOK) { - xfrin_rollback_update(contents_copy, &changes); - dbg_xfrin("Failed to finalize new zone contents: %s\n", + dbg_xfrin("Failed to remove empty nodes: %s\n", knot_strerror(ret)); + xfrin_rollback_update2(old_contents, contents_copy, &changes); return ret; } - /* - * Switch the zone contents - */ + + dbg_xfrin("Adjusting zone contents.\n"); + dbg_xfrin_verb("Old contents apex: %p, new apex: %p\n", + old_contents->apex, contents_copy->apex); +// ret = xfrin_adjust_contents(contents_copy, &changes); + ret = knot_zone_contents_adjust(contents_copy); + if (ret != KNOT_EOK) { + dbg_xfrin("Failed to finalize zone contents: %s\n", + knot_strerror(ret)); + xfrin_rollback_update2(old_contents, contents_copy, &changes); + return ret; + } + assert(knot_zone_contents_apex(contents_copy) != NULL); + + dbg_xfrin("Checking zone for CNAME loops.\n"); + ret = knot_zone_contents_check_loops(contents_copy); + if (ret != KNOT_EOK) { + dbg_xfrin("CNAME loop check failed: %s\n", knot_strerror(ret)); + xfrin_rollback_update2(old_contents, contents_copy, &changes); + return ret; + } + + dbg_xfrin("Switching zone contents.\n"); + dbg_xfrin_verb("Old contents apex: %p, new apex: %p\n", + old_contents->apex, contents_copy->apex); knot_zone_contents_t *old = knot_zone_switch_contents(zone, contents_copy); assert(old == old_contents); - /* - * From now on, the new contents of the zone are being used. - * References to nodes may be updated in the meantime. However, we must - * traverse the zone and fix all references that were not. - */ - /*! \todo This operation must not fail!!! .*/ - ret = xfrin_fix_references(contents_copy); - assert(ret == KNOT_EOK); - - // set generation to finished - knot_zone_contents_set_gen_new_finished(contents_copy); - - // set generation of all nodes to the old one - // now it is safe (no old nodes should be referenced) - ret = xfrin_fix_generation(contents_copy); - assert(ret == KNOT_EOK); - - /* - * Now we may also set the generation back to 0 so that another - * update is possible. - */ - knot_zone_contents_set_gen_old(contents_copy); - + dbg_xfrin_verb("Old contents apex: %p, new apex: %p\n", + old_contents->apex, contents_copy->apex); /* * Wait until all readers finish reading */ @@ -3016,6 +3137,7 @@ int xfrin_apply_changesets_to_zone(knot_zone_t *zone, /* * Delete all old and unused data. */ + dbg_xfrin("Cleaning up.\n"); xfrin_zone_contents_free(&old_contents); xfrin_cleanup_update(&changes); diff --git a/src/libknot/updates/xfr-in.h b/src/libknot/updates/xfr-in.h index bb1b98b..233527b 100644 --- a/src/libknot/updates/xfr-in.h +++ b/src/libknot/updates/xfr-in.h @@ -181,6 +181,9 @@ int xfrin_process_ixfr_packet(knot_ns_xfr_t *xfr/*const uint8_t *pkt, size_t siz int xfrin_apply_changesets_to_zone(knot_zone_t *zone, knot_changesets_t *chsets); +int xfrin_apply_changesets(knot_zone_t *zone, + knot_changesets_t *chsets); + #endif /* _KNOTXFR_IN_H_ */ /*! @} */ diff --git a/src/libknot/util/debug.c b/src/libknot/util/debug.c index 0ca67c9..78cd4a4 100644 --- a/src/libknot/util/debug.c +++ b/src/libknot/util/debug.c @@ -47,8 +47,8 @@ void knot_rdata_dump(knot_rdata_t *rdata, uint32_t type, char loaded_zone) desc->wireformat[i] == KNOT_RDATA_WF_LITERAL_DNAME ) { assert(rdata->items[i].dname != NULL); name = knot_dname_to_str(rdata->items[i].dname); - fprintf(stderr, " DNAME: %d: %s\n", - i, name); + fprintf(stderr, " DNAME: %d: %s (%p)\n", + i, name, rdata->items[i].dname); free(name); if (loaded_zone) { if (rdata->items[i].dname->node) { diff --git a/src/libknot/util/debug.h b/src/libknot/util/debug.h index 2c03c9c..a7eb86a 100644 --- a/src/libknot/util/debug.h +++ b/src/libknot/util/debug.h @@ -57,10 +57,10 @@ //#define KNOT_NSEC3_DEBUG //#define CUCKOO_DEBUG //#define CUCKOO_DEBUG_HASH -#define KNOT_NS_DEBUG +//#define KNOT_NS_DEBUG //#define KNOT_XFRIN_DEBUG //#define KNOT_DDNS_DEBUG -#define KNOT_TSIG_DEBUG +//#define KNOT_TSIG_DEBUG /*! * \brief Dumps RDATA of the given type. diff --git a/src/libknot/util/error.h b/src/libknot/util/error.h index 2f34a28..317c681 100644 --- a/src/libknot/util/error.h +++ b/src/libknot/util/error.h @@ -65,7 +65,8 @@ enum knot_error { KNOT_EXFRREFUSED, /*!< Zone transfer refused by the server. */ KNOT_ECONN, /*!< Connection reset. */ KNOT_EIXFRSPACE, /*!< IXFR reply did not fit in. */ - KNOT_ERROR_COUNT = 31 + KNOT_ECNAME, /*!< CNAME loop found in zone. */ + KNOT_ERROR_COUNT = 32 }; /*! \brief Table linking error messages to error codes. */ diff --git a/src/libknot/util/libknot_error.c b/src/libknot/util/libknot_error.c index 5795a23..d922afb 100644 --- a/src/libknot/util/libknot_error.c +++ b/src/libknot/util/libknot_error.c @@ -50,5 +50,6 @@ const error_table_t knot_error_msgs[KNOT_ERROR_COUNT] = { {KNOT_TSIG_EBADTIME, "TSIG signing time out of range." }, {KNOT_ECONN, "Connection reset."}, {KNOT_EIXFRSPACE, "IXFR reply did not fit in."}, + {KNOT_ECNAME, "CNAME loop found in zone."}, {KNOT_ERROR, 0} }; diff --git a/src/libknot/util/utils.h b/src/libknot/util/utils.h index f43b8f0..ba7a6d2 100644 --- a/src/libknot/util/utils.h +++ b/src/libknot/util/utils.h @@ -89,6 +89,8 @@ size_t knot_strlcpy(char *dst, const char *src, size_t size); * * \param pos Data to read the 2 bytes from. * + * \todo Wrong assumption of endianness (issue #1558). + * * \return The 2 bytes read, in inverse endian. */ static inline uint16_t knot_wire_read_u16(const uint8_t *pos) @@ -101,6 +103,8 @@ static inline uint16_t knot_wire_read_u16(const uint8_t *pos) * * \param pos Data to read the 4 bytes from. * + * \todo Wrong assumption of endianness (issue #1558). + * * \return The 4 bytes read, in inverse endian. */ static inline uint32_t knot_wire_read_u32(const uint8_t *pos) @@ -113,6 +117,8 @@ static inline uint32_t knot_wire_read_u32(const uint8_t *pos) * * \param pos Data to read the 6 bytes from. * + * \todo Wrong assumption of endianness (issue #1558). + * * \return The 6 bytes read, in inverse endian. */ static inline uint64_t knot_wire_read_u48(const uint8_t *pos) @@ -126,13 +132,15 @@ static inline uint64_t knot_wire_read_u48(const uint8_t *pos) * * The endian of the data is inverted. * + * \todo Wrong assumption of endianness (issue #1558). + * * \param pos Position where to put the 2 bytes. * \param data Data to put. */ static inline void knot_wire_write_u16(uint8_t *pos, uint16_t data) { - pos[0] = (uint8_t)((data >> 8) & 0xff); - pos[1] = (uint8_t)(data & 0xff); + *(pos++) = (uint8_t)((data >> 8) & 0xff); + *pos = (uint8_t)(data & 0xff); } /*! @@ -140,15 +148,17 @@ static inline void knot_wire_write_u16(uint8_t *pos, uint16_t data) * * The endian of the data is inverted. * + * \todo Wrong assumption of endianness (issue #1558). + * * \param pos Position where to put the 4 bytes. * \param data Data to put. */ static inline void knot_wire_write_u32(uint8_t *pos, uint32_t data) { - pos[0] = (uint8_t)((data >> 24) & 0xff); - pos[1] = (uint8_t)((data >> 16) & 0xff); - pos[2] = (uint8_t)((data >> 8) & 0xff); - pos[3] = (uint8_t)(data & 0xff); + *(pos++) = (uint8_t)((data >> 24) & 0xff); + *(pos++) = (uint8_t)((data >> 16) & 0xff); + *(pos++) = (uint8_t)((data >> 8) & 0xff); + *pos = (uint8_t)(data & 0xff); } /*! @@ -156,17 +166,19 @@ static inline void knot_wire_write_u32(uint8_t *pos, uint32_t data) * * The endian of the data is inverted. * + * \todo Wrong assumption of endianness (issue #1558). + * * \param pos Position where to put the 4 bytes. * \param data Data to put. */ static inline void knot_wire_write_u48(uint8_t *pos, uint64_t data) { - pos[0] = (uint8_t)((data >> 40) & 0xff); - pos[1] = (uint8_t)((data >> 32) & 0xff); - pos[2] = (uint8_t)((data >> 24) & 0xff); - pos[3] = (uint8_t)((data >> 16) & 0xff); - pos[4] = (uint8_t)((data >> 8) & 0xff); - pos[5] = (uint8_t)(data & 0xff); + *(pos++) = (uint8_t)((data >> 40) & 0xff); + *(pos++) = (uint8_t)((data >> 32) & 0xff); + *(pos++) = (uint8_t)((data >> 24) & 0xff); + *(pos++) = (uint8_t)((data >> 16) & 0xff); + *(pos++) = (uint8_t)((data >> 8) & 0xff); + *pos = (uint8_t)(data & 0xff); } /*! diff --git a/src/libknot/zone/dname-table.c b/src/libknot/zone/dname-table.c index c41b4bd..d2d97c2 100644 --- a/src/libknot/zone/dname-table.c +++ b/src/libknot/zone/dname-table.c @@ -217,7 +217,6 @@ int knot_dname_table_add_dname_check(knot_dname_table_t *table, return 1; /*! \todo Error code? */ } else { - /* If the dname is already in the table, there is already * a reference to it. */ @@ -308,3 +307,19 @@ void knot_dname_table_tree_inorder_apply(const knot_dname_table_t *table, knot_dname_table_apply, &d); } +static void knot_dump_node_of_table(knot_dname_t *dname, void *data) +{ + UNUSED(data); + char *name = knot_dname_to_str(dname); + fprintf(stderr, "%s (%p)\n", name, dname); + free(name); +} + +void knot_dname_table_dump(const knot_dname_table_t *table) +{ + fprintf(stderr, "-------DNAME TABLE-------\n"); + knot_dname_table_tree_inorder_apply(table, knot_dump_node_of_table, + NULL); + fprintf(stderr, "-----END DNAME TABLE-----\n"); +} + diff --git a/src/libknot/zone/dname-table.h b/src/libknot/zone/dname-table.h index dd86eaf..945b6de 100644 --- a/src/libknot/zone/dname-table.h +++ b/src/libknot/zone/dname-table.h @@ -162,6 +162,14 @@ void knot_dname_table_tree_inorder_apply(const knot_dname_table_t *table, void *data); +/*! + * \brief Dumps dname table to stderr. + * + * \param table Table to be dumped. + */ +void knot_dname_table_dump(const knot_dname_table_t *table); + + #endif // _KNOT_DNAME_TABLE_H_ /*! @} */ diff --git a/src/libknot/zone/node.c b/src/libknot/zone/node.c index 61ef3e4..27eb7f2 100644 --- a/src/libknot/zone/node.c +++ b/src/libknot/zone/node.c @@ -81,67 +81,67 @@ static inline void knot_node_flags_set_nonauth(uint8_t *flags) *flags |= KNOT_NODE_FLAGS_NONAUTH; } -/*----------------------------------------------------------------------------*/ -/*! - * \brief Returns the old node flag - * - * \param flags Flags to retrieve the flag from. - * - * \return A byte with only the old node flag set if it was set in \a flags. - */ -static inline uint8_t knot_node_flags_get_old(uint8_t flags) -{ - return flags & KNOT_NODE_FLAGS_OLD; -} - -/*----------------------------------------------------------------------------*/ -/*! - * \brief Sets the old node flag. - * - * \param flags Flags to set the flag in. - */ -static inline void knot_node_flags_set_new(uint8_t *flags) -{ - *flags |= KNOT_NODE_FLAGS_NEW; -} - -/*----------------------------------------------------------------------------*/ -/*! - * \brief Returns the new node flag - * - * \param flags Flags to retrieve the flag from. - * - * \return A byte with only the new node flag set if it was set in \a flags. - */ -static inline uint8_t knot_node_flags_get_new(uint8_t flags) -{ - return flags & KNOT_NODE_FLAGS_NEW; -} - -/*----------------------------------------------------------------------------*/ -/*! - * \brief Sets the new node flag. - * - * \param flags Flags to set the flag in. - */ -static inline void knot_node_flags_set_old(uint8_t *flags) -{ - *flags |= KNOT_NODE_FLAGS_OLD; -} - -/*----------------------------------------------------------------------------*/ - -static inline void knot_node_flags_clear_new(uint8_t *flags) -{ - *flags &= ~KNOT_NODE_FLAGS_NEW; -} - -/*----------------------------------------------------------------------------*/ - -static inline void knot_node_flags_clear_old(uint8_t *flags) -{ - *flags &= ~KNOT_NODE_FLAGS_OLD; -} +///*----------------------------------------------------------------------------*/ +///*! +// * \brief Returns the old node flag +// * +// * \param flags Flags to retrieve the flag from. +// * +// * \return A byte with only the old node flag set if it was set in \a flags. +// */ +//static inline uint8_t knot_node_flags_get_old(uint8_t flags) +//{ +// return flags & KNOT_NODE_FLAGS_OLD; +//} + +///*----------------------------------------------------------------------------*/ +///*! +// * \brief Sets the old node flag. +// * +// * \param flags Flags to set the flag in. +// */ +//static inline void knot_node_flags_set_new(uint8_t *flags) +//{ +// *flags |= KNOT_NODE_FLAGS_NEW; +//} + +///*----------------------------------------------------------------------------*/ +///*! +// * \brief Returns the new node flag +// * +// * \param flags Flags to retrieve the flag from. +// * +// * \return A byte with only the new node flag set if it was set in \a flags. +// */ +//static inline uint8_t knot_node_flags_get_new(uint8_t flags) +//{ +// return flags & KNOT_NODE_FLAGS_NEW; +//} + +///*----------------------------------------------------------------------------*/ +///*! +// * \brief Sets the new node flag. +// * +// * \param flags Flags to set the flag in. +// */ +//static inline void knot_node_flags_set_old(uint8_t *flags) +//{ +// *flags |= KNOT_NODE_FLAGS_OLD; +//} + +///*----------------------------------------------------------------------------*/ + +//static inline void knot_node_flags_clear_new(uint8_t *flags) +//{ +// *flags &= ~KNOT_NODE_FLAGS_NEW; +//} + +///*----------------------------------------------------------------------------*/ + +//static inline void knot_node_flags_clear_old(uint8_t *flags) +//{ +// *flags &= ~KNOT_NODE_FLAGS_OLD; +//} /*----------------------------------------------------------------------------*/ /*! @@ -167,30 +167,30 @@ static int compare_rrset_types(void *rr1, void *rr2) /*----------------------------------------------------------------------------*/ -static int knot_node_zone_gen_is_new(const knot_node_t *node) -{ - assert(node->zone != NULL); - knot_zone_contents_t *cont = rcu_dereference(node->zone->contents); - assert(cont != NULL); - return knot_zone_contents_gen_is_new(cont); -} +//static int knot_node_zone_gen_is_new(const knot_node_t *node) +//{ +// assert(node->zone != NULL); +// knot_zone_contents_t *cont = rcu_dereference(node->zone->contents); +// assert(cont != NULL); +// return knot_zone_contents_gen_is_new(cont); +//} -/*----------------------------------------------------------------------------*/ +///*----------------------------------------------------------------------------*/ -static int knot_node_zone_gen_is_old(const knot_node_t *node) -{ - assert(node->zone != NULL); - knot_zone_contents_t *cont = rcu_dereference(node->zone->contents); - assert(cont != NULL); - return knot_zone_contents_gen_is_old(cont); -} +//static int knot_node_zone_gen_is_old(const knot_node_t *node) +//{ +// assert(node->zone != NULL); +// knot_zone_contents_t *cont = rcu_dereference(node->zone->contents); +// assert(cont != NULL); +// return knot_zone_contents_gen_is_old(cont); +//} /*----------------------------------------------------------------------------*/ /* API functions */ /*----------------------------------------------------------------------------*/ knot_node_t *knot_node_new(knot_dname_t *owner, knot_node_t *parent, - uint8_t flags) + uint8_t flags) { knot_node_t *ret = (knot_node_t *)calloc(1, sizeof(knot_node_t)); if (ret == NULL) { @@ -289,13 +289,20 @@ short knot_node_rrset_count(const knot_node_t *node) struct knot_node_save_rrset_arg { knot_rrset_t **array; size_t count; + size_t max_count; }; static void save_rrset_to_array(void *node, void *data) { - knot_rrset_t *rrset = (knot_rrset_t *)node; struct knot_node_save_rrset_arg *args = (struct knot_node_save_rrset_arg *)data; + knot_rrset_t *rrset = (knot_rrset_t *)node; + + if (args->count > args->max_count) { + ++args->count; + return; + } + args->array[args->count++] = rrset; } @@ -311,9 +318,9 @@ knot_rrset_t **knot_node_get_rrsets(const knot_node_t *node) struct knot_node_save_rrset_arg args; args.array = rrsets; args.count = 0; + args.max_count = node->rrset_count; - gen_tree_apply_inorder(node->rrset_tree, save_rrset_to_array, - &args); + gen_tree_apply_inorder(node->rrset_tree, save_rrset_to_array, &args); assert(args.count == node->rrset_count); @@ -329,41 +336,54 @@ const knot_rrset_t **knot_node_rrsets(const knot_node_t *node) /*----------------------------------------------------------------------------*/ -const knot_node_t *knot_node_parent(const knot_node_t *node, - int check_version) +static void count_rrsets(void *node, void *data) { -// assert(!check_version -// || (node->zone != NULL && node->zone->contents != NULL)); - - knot_node_t *parent = node->parent; - - if (check_version && node->zone != NULL) { - int new_gen = knot_node_zone_gen_is_new(node); -// short ver = knot_node_zone_generation(node); - - /*! \todo Remove, this will not be true during the reference - * fixing. - */ -// assert(new_gen || parent == NULL -// || !knot_node_is_new(parent)); - - if (new_gen && parent != NULL) { - // we want the new node - assert(node->parent->new_node != NULL); - parent = parent->new_node; - } + assert(node != NULL); + assert(data != NULL); + + int *count = (int *)data; + ++(*count); +} + +/*----------------------------------------------------------------------------*/ + +int knot_node_count_rrsets(const knot_node_t *node) +{ + int count = 0; + gen_tree_apply_inorder(node->rrset_tree, count_rrsets, (void *)&count); + + return count; +} + +/*----------------------------------------------------------------------------*/ + +const knot_node_t *knot_node_parent(const knot_node_t *node) +{ + return knot_node_get_parent(node); +} + +/*----------------------------------------------------------------------------*/ + +knot_node_t *knot_node_get_parent(const knot_node_t *node) +{ + if (node == NULL) { + return NULL; } - - return parent; + + return node->parent; } /*----------------------------------------------------------------------------*/ void knot_node_set_parent(knot_node_t *node, knot_node_t *parent) { + if (node->parent == parent) { + return; + } + // decrease number of children of previous parent if (node->parent != NULL) { - --parent->children; + --node->parent->children; } // set the parent node->parent = parent; @@ -383,45 +403,27 @@ unsigned int knot_node_children(const knot_node_t *node) /*----------------------------------------------------------------------------*/ -const knot_node_t *knot_node_previous(const knot_node_t *node, - int check_version) +const knot_node_t *knot_node_previous(const knot_node_t *node) { - return knot_node_get_previous(node, check_version); + return knot_node_get_previous(node); } /*----------------------------------------------------------------------------*/ -knot_node_t *knot_node_get_previous(const knot_node_t *node, - int check_version) +knot_node_t *knot_node_get_previous(const knot_node_t *node) { - assert(!check_version - || (node->zone != NULL && node->zone->contents != NULL)); - - knot_node_t *prev = node->prev; - - if (check_version && prev != NULL) { - int new_gen = knot_node_zone_gen_is_new(node); - int old_gen = knot_node_zone_gen_is_old(node); -// short ver = knot_node_zone_generation(node); - - if (old_gen) { // we want old node - while (knot_node_is_new(prev)) { - prev = prev->prev; - } - assert(!knot_node_is_new(prev)); - } else if (new_gen) { // we want new node - while (knot_node_is_old(prev)) { - if (prev->new_node) { - prev = prev->new_node; - } else { - prev = prev; - } - } - assert(knot_node_is_new(prev)); - } + if (node == NULL) { + return NULL; } - return prev; + return node->prev; +} + +/*----------------------------------------------------------------------------*/ + +const knot_node_t *knot_node_next(const knot_node_t *node) +{ + return node->next; } /*----------------------------------------------------------------------------*/ @@ -429,48 +431,24 @@ knot_node_t *knot_node_get_previous(const knot_node_t *node, void knot_node_set_previous(knot_node_t *node, knot_node_t *prev) { node->prev = prev; - if (prev != NULL) { - // set the prev pointer of the next node to the given node - if (prev->next != NULL) { - assert(prev->next->prev == prev); - prev->next->prev = node; - } - node->next = prev->next; - prev->next = node; - } } /*----------------------------------------------------------------------------*/ -knot_node_t *knot_node_get_nsec3_node(const knot_node_t *node, - int check_version) +knot_node_t *knot_node_get_nsec3_node(const knot_node_t *node) { - knot_node_t *nsec3_node = node->nsec3_node; - if (nsec3_node == NULL) { + if (node == NULL) { return NULL; } - if (check_version) { - int new_gen = knot_node_zone_gen_is_new(node); - int old_gen = knot_node_zone_gen_is_old(node); -// short ver = knot_node_zone_generation(node); - assert(new_gen || !knot_node_is_new(nsec3_node)); - if (old_gen && knot_node_is_new(nsec3_node)) { - return NULL; - } else if (new_gen && knot_node_is_old(nsec3_node)) { - nsec3_node = nsec3_node->new_node; - } - } - - return nsec3_node; + return node->nsec3_node; } /*----------------------------------------------------------------------------*/ -const knot_node_t *knot_node_nsec3_node(const knot_node_t *node, - int check_version) +const knot_node_t *knot_node_nsec3_node(const knot_node_t *node) { - return knot_node_get_nsec3_node(node, check_version); + return knot_node_get_nsec3_node(node); } /*----------------------------------------------------------------------------*/ @@ -511,31 +489,19 @@ void knot_node_set_owner(knot_node_t *node, knot_dname_t* owner) /*----------------------------------------------------------------------------*/ -const knot_node_t *knot_node_wildcard_child(const knot_node_t *node, - int check_version) +knot_node_t *knot_node_get_wildcard_child(const knot_node_t *node) { - knot_node_t *w = node->wildcard_child; - - if (check_version && w != 0) { - int new_gen = knot_node_zone_gen_is_new(node); - int old_gen = knot_node_zone_gen_is_old(node); -// short ver = knot_node_zone_generation(node); - - if (old_gen && knot_node_is_new(w)) { - return NULL; - } else if (new_gen && knot_node_is_old(w)) { - assert(w->new_node != NULL); - w = w->new_node; - } + if (node == NULL) { + return NULL; } - - return w; + + return node->wildcard_child; } /*----------------------------------------------------------------------------*/ void knot_node_set_wildcard_child(knot_node_t *node, - knot_node_t *wildcard_child) + knot_node_t *wildcard_child) { node->wildcard_child = wildcard_child; // assert(wildcard_child->parent == node); @@ -543,52 +509,59 @@ void knot_node_set_wildcard_child(knot_node_t *node, /*----------------------------------------------------------------------------*/ -const knot_node_t *knot_node_current(const knot_node_t *node) +const knot_node_t *knot_node_wildcard_child(const knot_node_t *node) { - if (node == NULL || node->zone == NULL - || knot_zone_contents(node->zone) == NULL) { - return node; - } + return knot_node_get_wildcard_child(node); +} - int new_gen = knot_node_zone_gen_is_new(node); - int old_gen = knot_node_zone_gen_is_old(node); -// short ver = knot_node_zone_generation(node); +/*----------------------------------------------------------------------------*/ - if (old_gen && knot_node_is_new(node)) { - return NULL; - } else if (new_gen && knot_node_is_old(node)) { - assert(node->new_node != NULL); - return node->new_node; - } - return node; -} +//const knot_node_t *knot_node_current(const knot_node_t *node) +//{ +// if (node == NULL || node->zone == NULL +// || knot_zone_contents(node->zone) == NULL) { +// return node; +// } + +// int new_gen = knot_node_zone_gen_is_new(node); +// int old_gen = knot_node_zone_gen_is_old(node); +//// short ver = knot_node_zone_generation(node); + +// if (old_gen && knot_node_is_new(node)) { +// return NULL; +// } else if (new_gen && knot_node_is_old(node)) { +// assert(node->new_node != NULL); +// return node->new_node; +// } +// return node; +//} /*----------------------------------------------------------------------------*/ -knot_node_t *knot_node_get_current(knot_node_t *node) -{ - if (node == NULL || node->zone == NULL - || knot_zone_contents(node->zone) == NULL) { - return node; - } +//knot_node_t *knot_node_get_current(knot_node_t *node) +//{ +// if (node == NULL || node->zone == NULL +// || knot_zone_contents(node->zone) == NULL) { +// return node; +// } - int new_gen = knot_node_zone_gen_is_new(node); - int old_gen = knot_node_zone_gen_is_old(node); -// short ver = knot_node_zone_generation(node); +// int new_gen = knot_node_zone_gen_is_new(node); +// int old_gen = knot_node_zone_gen_is_old(node); +//// short ver = knot_node_zone_generation(node); - if (old_gen && knot_node_is_new(node)) { - return NULL; - } else if (new_gen && knot_node_is_old(node)) { - assert(node->new_node != NULL); - return node->new_node; - } +// if (old_gen && knot_node_is_new(node)) { +// return NULL; +// } else if (new_gen && knot_node_is_old(node)) { +// assert(node->new_node != NULL); +// return node->new_node; +// } - assert((old_gen && knot_node_is_old(node)) - || (new_gen && knot_node_is_new(node)) - || (!old_gen && !new_gen)); +// assert((old_gen && knot_node_is_old(node)) +// || (new_gen && knot_node_is_new(node)) +// || (!old_gen && !new_gen)); - return node; -} +// return node; +//} /*----------------------------------------------------------------------------*/ @@ -623,7 +596,10 @@ void knot_node_set_zone(knot_node_t *node, knot_zone_t *zone) void knot_node_update_ref(knot_node_t **ref) { - if (*ref != NULL && knot_node_is_old(*ref)) { +// if (*ref != NULL && knot_node_is_old(*ref)) { +// *ref = (*ref)->new_node; +// } + if (*ref != NULL && (*ref)->new_node != NULL) { *ref = (*ref)->new_node; } } @@ -632,52 +608,18 @@ void knot_node_update_ref(knot_node_t **ref) void knot_node_update_refs(knot_node_t *node) { - /* CLEANUP */ - /* OMG! */ // reference to previous node knot_node_update_ref(&node->prev); -// if (node->prev && knot_node_is_old(node->prev)) { -// assert(node->prev->new_node != NULL); -// node->prev = node->prev->new_node; -// } - // reference to next node knot_node_update_ref(&node->next); -// if (node->next && knot_node_is_old(node->next)) { -// assert(node->next->new_node != NULL); -// node->next = node->next->new_node; -// } - // reference to parent -// if (node->parent && knot_node_is_old(node->parent)) { -// assert(node->parent->new_node != NULL); -// // do not use the API function to set parent, so that children count -// // is not changed -// //knot_node_set_parent(node, node->parent->new_node); -// node->parent = node->parent->new_node; -// } knot_node_update_ref(&node->parent); - // reference to wildcard child knot_node_update_ref(&node->wildcard_child); -// if (node->wildcard_child && knot_node_is_old(node->wildcard_child)) { -// assert(node->wildcard_child->new_node != NULL); -// node->wildcard_child = node->wildcard_child->new_node; -// } - // reference to NSEC3 node knot_node_update_ref(&node->nsec3_node); -// if (node->nsec3_node && knot_node_is_old(node->nsec3_node)) { -// assert(node->nsec3_node->new_node != NULL); -// node->nsec3_node = node->nsec3_node->new_node; -// } - // reference to NSEC3 referrer knot_node_update_ref(&node->nsec3_referer); -// if (node->nsec3_referer && knot_node_is_old(node->nsec3_referer)) { -// assert(node->nsec3_referer->new_node != NULL); -// node->nsec3_referer = node->nsec3_referer->new_node; -// } } /*----------------------------------------------------------------------------*/ @@ -715,47 +657,47 @@ int knot_node_is_auth(const knot_node_t *node) return (node->flags == 0); } -/*----------------------------------------------------------------------------*/ +///*----------------------------------------------------------------------------*/ -int knot_node_is_new(const knot_node_t *node) -{ - return knot_node_flags_get_new(node->flags); -} +//int knot_node_is_new(const knot_node_t *node) +//{ +// return knot_node_flags_get_new(node->flags); +//} -/*----------------------------------------------------------------------------*/ +///*----------------------------------------------------------------------------*/ -int knot_node_is_old(const knot_node_t *node) -{ - return knot_node_flags_get_old(node->flags); -} +//int knot_node_is_old(const knot_node_t *node) +//{ +// return knot_node_flags_get_old(node->flags); +//} -/*----------------------------------------------------------------------------*/ +///*----------------------------------------------------------------------------*/ -void knot_node_set_new(knot_node_t *node) -{ - knot_node_flags_set_new(&node->flags); -} +//void knot_node_set_new(knot_node_t *node) +//{ +// knot_node_flags_set_new(&node->flags); +//} -/*----------------------------------------------------------------------------*/ +///*----------------------------------------------------------------------------*/ -void knot_node_set_old(knot_node_t *node) -{ - knot_node_flags_set_old(&node->flags); -} +//void knot_node_set_old(knot_node_t *node) +//{ +// knot_node_flags_set_old(&node->flags); +//} -/*----------------------------------------------------------------------------*/ +///*----------------------------------------------------------------------------*/ -void knot_node_clear_new(knot_node_t *node) -{ - knot_node_flags_clear_new(&node->flags); -} +//void knot_node_clear_new(knot_node_t *node) +//{ +// knot_node_flags_clear_new(&node->flags); +//} -/*----------------------------------------------------------------------------*/ +///*----------------------------------------------------------------------------*/ -void knot_node_clear_old(knot_node_t *node) -{ - knot_node_flags_clear_old(&node->flags); -} +//void knot_node_clear_old(knot_node_t *node) +//{ +// knot_node_flags_clear_old(&node->flags); +//} /*----------------------------------------------------------------------------*/ @@ -790,23 +732,28 @@ void knot_node_free_rrsets(knot_node_t *node, int free_rdata_dnames) /*----------------------------------------------------------------------------*/ -void knot_node_free(knot_node_t **node, int free_owner, int fix_refs) +void knot_node_free(knot_node_t **node, int fix_refs) { if (node == NULL || *node == NULL) { return; } - dbg_node("Freeing node.\n"); + dbg_node("Freeing node: %p\n", *node); + if ((*node)->rrset_tree != NULL) { dbg_node("Freeing RRSets.\n"); gen_tree_destroy(&(*node)->rrset_tree, NULL, NULL); } - /*! \todo Always release owner? */ - //if (free_owner) { - dbg_node("Releasing owner.\n"); - knot_dname_release((*node)->owner); - //} + // set owner's node pointer to NULL, but only if the 'node' does + // not point to the owner's node + if (node != &(*node)->owner->node + && knot_dname_node(knot_node_owner(*node)) == *node) { + knot_dname_set_node((*node)->owner, NULL); + } + + dbg_node("Releasing owner.\n"); + knot_dname_release((*node)->owner); // check nodes referencing this node and fix the references @@ -866,11 +813,14 @@ int knot_node_compare(knot_node_t *node1, knot_node_t *node2) int knot_node_shallow_copy(const knot_node_t *from, knot_node_t **to) { // create new node - *to = knot_node_new(from->owner, from->parent, from->flags); + *to = knot_node_new(from->owner, NULL, from->flags); if (*to == NULL) { return KNOT_ENOMEM; } + // set the parent by hand, so that the children count is not affected + (*to)->parent = from->parent; + /* Free old rrset_tree, as it will be replaced by shallow copy. */ gen_tree_destroy(&(*to)->rrset_tree, 0, 0); @@ -880,11 +830,8 @@ int knot_node_shallow_copy(const knot_node_t *from, knot_node_t **to) memcpy(*to, from, sizeof(knot_node_t)); // copy RRSets - // copy the skip list with the old references - /* CLEANUP */ (*to)->rrset_tree = gen_tree_shallow_copy(from->rrset_tree); -// assert((*to)->rrset_tree != from->rrset_tree); -// (*to)->rrsets = skip_copy_list(from->rrsets); + if ((*to)->rrset_tree == NULL) { free(*to); *to = NULL; diff --git a/src/libknot/zone/node.h b/src/libknot/zone/node.h index eb0d242..583f248 100644 --- a/src/libknot/zone/node.h +++ b/src/libknot/zone/node.h @@ -204,6 +204,8 @@ knot_rrset_t **knot_node_get_rrsets(const knot_node_t *node); */ const knot_rrset_t **knot_node_rrsets(const knot_node_t *node); +int knot_node_count_rrsets(const knot_node_t *node); + /*! * \brief Returns the parent of the node. * @@ -212,8 +214,9 @@ const knot_rrset_t **knot_node_rrsets(const knot_node_t *node); * \return Parent node of the given node or NULL if no parent has been set (e.g. * node in a zone apex has no parent). */ -const knot_node_t *knot_node_parent(const knot_node_t *node, - int check_version); +const knot_node_t *knot_node_parent(const knot_node_t *node); + +knot_node_t *knot_node_get_parent(const knot_node_t *node); /*! * \brief Sets the parent of the node. @@ -235,8 +238,7 @@ unsigned int knot_node_children(const knot_node_t *node); * the first node in zone if \a node is the last node in zone. * \retval NULL if previous node is not set. */ -const knot_node_t *knot_node_previous(const knot_node_t *node, - int check_version); +const knot_node_t *knot_node_previous(const knot_node_t *node); /*! * \brief Returns the previous authoritative node or delegation point in @@ -251,8 +253,9 @@ const knot_node_t *knot_node_previous(const knot_node_t *node, * the first node in zone if \a node is the last node in zone. * \retval NULL if previous node is not set. */ -knot_node_t *knot_node_get_previous(const knot_node_t *node, - int check_version); +knot_node_t *knot_node_get_previous(const knot_node_t *node); + +const knot_node_t *knot_node_next(const knot_node_t *node); /*! * \brief Sets the previous node of the given node. @@ -272,8 +275,7 @@ void knot_node_set_previous(knot_node_t *node, knot_node_t *prev); * and the name of the zone \a node belongs to). * \retval NULL if the NSEC3 node is not set. */ -knot_node_t *knot_node_get_nsec3_node(const knot_node_t *node, - int check_version); +knot_node_t *knot_node_get_nsec3_node(const knot_node_t *node); /*! * \brief Returns the NSEC3 node corresponding to the given node. @@ -285,8 +287,7 @@ knot_node_t *knot_node_get_nsec3_node(const knot_node_t *node, * and the name of the zone \a node belongs to). * \retval NULL if the NSEC3 node is not set. */ -const knot_node_t *knot_node_nsec3_node(const knot_node_t *node, - int check_version); +const knot_node_t *knot_node_nsec3_node(const knot_node_t *node); /*! * \brief Sets the corresponding NSEC3 node of the given node. @@ -327,8 +328,7 @@ void knot_node_set_owner(knot_node_t *node, knot_dname_t* owner); * * \return Wildcard child of the given node or NULL if it has none. */ -const knot_node_t *knot_node_wildcard_child(const knot_node_t *node, - int check_version); +const knot_node_t *knot_node_wildcard_child(const knot_node_t *node); /*! * \brief Sets the wildcard child of the node. @@ -337,18 +337,19 @@ const knot_node_t *knot_node_wildcard_child(const knot_node_t *node, * \param wildcard_child Wildcard child of the node. */ void knot_node_set_wildcard_child(knot_node_t *node, - knot_node_t *wildcard_child); + knot_node_t *wildcard_child); + +knot_node_t *knot_node_get_wildcard_child(const knot_node_t *node); -const knot_node_t *knot_node_current(const knot_node_t *node); +//const knot_node_t *knot_node_current(const knot_node_t *node); -knot_node_t *knot_node_get_current(knot_node_t *node); +//knot_node_t *knot_node_get_current(knot_node_t *node); const knot_node_t *knot_node_new_node(const knot_node_t *node); knot_node_t *knot_node_get_new_node(const knot_node_t *node); -void knot_node_set_new_node(knot_node_t *node, - knot_node_t *new_node); +void knot_node_set_new_node(knot_node_t *node, knot_node_t *new_node); void knot_node_set_zone(knot_node_t *node, struct knot_zone *zone); @@ -427,7 +428,7 @@ void knot_node_free_rrsets(knot_node_t *node, int free_rdata_dnames); * * \todo Document missing parameters. */ -void knot_node_free(knot_node_t **node, int free_owner, int fix_refs); +void knot_node_free(knot_node_t **node, int fix_refs); /*! * \brief Compares two nodes according to their owner. diff --git a/src/libknot/zone/zone-contents.c b/src/libknot/zone/zone-contents.c index feec8e5..8a74e23 100644 --- a/src/libknot/zone/zone-contents.c +++ b/src/libknot/zone/zone-contents.c @@ -35,7 +35,7 @@ typedef struct { knot_node_t *first_node; knot_zone_contents_t *zone; knot_node_t *previous_node; - int check_ver; + int err; } knot_zone_adjust_arg_t; /*----------------------------------------------------------------------------*/ @@ -52,7 +52,6 @@ static void knot_zone_tree_apply(knot_zone_tree_node_t *node, } /*----------------------------------------------------------------------------*/ - /*! * \brief Checks if the given node can be inserted into the given zone. * @@ -129,9 +128,133 @@ static void knot_zone_contents_destroy_node_owner_from_tree( UNUSED(data); /*!< \todo change completely! */ - knot_node_free(&tnode->node, 0, 0); + knot_node_free(&tnode->node, 0); +} + +/*----------------------------------------------------------------------------*/ + +static int knot_zone_contents_dnames_from_rdata_to_table( + knot_dname_table_t *table, knot_rdata_t *rdata, + knot_rrtype_descriptor_t *d) +{ + unsigned int count = knot_rdata_item_count(rdata); + int rc = 0; + if (d->fixed_items) { + assert(count <= d->length); + } + // for each RDATA item + for (unsigned int j = 0; j < count; ++j) { + if (d->wireformat[j] + == KNOT_RDATA_WF_COMPRESSED_DNAME + || d->wireformat[j] + == KNOT_RDATA_WF_UNCOMPRESSED_DNAME + || d->wireformat[j] + == KNOT_RDATA_WF_LITERAL_DNAME) { +// printf("Saving dname from rdata to dname table: " +// "%p.\n", knot_rdata_get_item(rdata, j)->dname); + rc = knot_dname_table_add_dname_check(table, + &knot_rdata_get_item(rdata, j)->dname); +// printf("Returned: %d\n", rc); + if (rc < 0) { + dbg_zone("Error: %s\n", knot_strerror(rc)); + return rc; + } + } + } + + dbg_zone("RDATA OK.\n"); + return KNOT_EOK; +} + +/*----------------------------------------------------------------------------*/ + +static int knot_zone_contents_dnames_from_rrset_to_table( + knot_dname_table_t *table, knot_rrset_t *rrset, int replace_owner, + knot_dname_t *owner) +{ + assert(table != NULL && rrset != NULL && owner != NULL); + + if (replace_owner) { + // discard the old owner and replace it with the new + knot_rrset_set_owner(rrset, owner); + } + dbg_zone("RRSet owner: %p\n", rrset->owner); + + knot_rrtype_descriptor_t *desc = knot_rrtype_descriptor_by_type( + knot_rrset_type(rrset)); + if (desc == NULL) { + // not recognized RR type, ignore + dbg_zone("RRSet type not recognized.\n"); + return KNOT_EOK; + } + // for each RDATA in RRSet +// char *name = knot_dname_to_str(rrset->owner); +// char *type = knot_rrtype_to_string(rrset->type); +// printf("Storing dnames from RDATA from RRSet %s, %s\n", name, type); +// free(name); + knot_rdata_t *rdata = knot_rrset_get_rdata(rrset); + while (rdata != NULL) { + int rc = knot_zone_contents_dnames_from_rdata_to_table(table, + rdata, desc); + if (rc != KNOT_EOK) { + return rc; + } + + rdata = knot_rrset_rdata_get_next(rrset, rdata); + } + + dbg_zone("RRSet OK.\n"); + return KNOT_EOK; +} + +/*----------------------------------------------------------------------------*/ + +static int knot_zone_contents_dnames_from_node_to_table( + knot_dname_table_t *table, knot_node_t *node) +{ + /* + * Assuming that all the RRSets have the same owner as the node. + */ + + // insert owner + char *name = knot_dname_to_str(node->owner); + dbg_zone("Node owner before inserting to dname table: %p.\n", + node->owner); + dbg_zone("Node owner before inserting to dname table: %s.\n", + name); + free(name); + //knot_dname_t *old_owner = node->owner; + int rc = knot_dname_table_add_dname_check(table, &node->owner); + if (rc < 0) { + dbg_zone("Failed to add dname to dname table.\n"); + return rc; + } + int replace_owner = (rc > 0); + dbg_zone("Node owner after inserting to dname table: %p.\n", + node->owner); + name = knot_dname_to_str(node->owner); + dbg_zone("Node owner after inserting to dname table: %s.\n", + name); + free(name); + + knot_rrset_t **rrsets = knot_node_get_rrsets(node); + // for each RRSet + for (int i = 0; i < knot_node_rrset_count(node); ++i) { + dbg_zone("Inserting RRSets from node to table.\n"); + rc = knot_zone_contents_dnames_from_rrset_to_table(table, + rrsets[i], replace_owner, node->owner); + if (rc != KNOT_EOK) { + return rc; + } + } + + free(rrsets); + + dbg_zone("Node OK\n"); + return KNOT_EOK; } +/*----------------------------------------------------------------------------*/ /*! * \brief Finds and sets wildcard child for given node's owner. * @@ -340,10 +463,14 @@ static void knot_zone_contents_adjust_rrsets(knot_node_t *node, * * \param node Zone node to adjust. * \param zone Zone the node belongs to. + * + * \todo Consider whether this function should replace RRSet owners with + * node owner + store this owner to the dname table. This is now done + * in the inserting function, though that may not be always used (e.g. + * old changeset processing). */ static void knot_zone_contents_adjust_node(knot_node_t *node, - knot_zone_contents_t *zone, - int check_ver) + knot_zone_contents_t *zone) { dbg_zone_exec( @@ -356,15 +483,15 @@ dbg_zone_exec( knot_zone_contents_adjust_rrsets(node, zone); dbg_zone_exec( - if (knot_node_parent(node, 1)) { + if (knot_node_parent(node)) { char *name = knot_dname_to_str(knot_node_owner( - knot_node_parent(node, check_ver))); + knot_node_parent(node))); dbg_zone("Parent: %s\n", name); dbg_zone("Parent is delegation point: %s\n", - knot_node_is_deleg_point(knot_node_parent(node, check_ver)) + knot_node_is_deleg_point(knot_node_parent(node)) ? "yes" : "no"); dbg_zone("Parent is non-authoritative: %s\n", - knot_node_is_non_auth(knot_node_parent(node, check_ver)) + knot_node_is_non_auth(knot_node_parent(node)) ? "yes" : "no"); free(name); } else { @@ -372,32 +499,32 @@ dbg_zone_exec( } ); // delegation point / non-authoritative node - if (knot_node_parent(node, check_ver) - && (knot_node_is_deleg_point(knot_node_parent(node, check_ver)) - || knot_node_is_non_auth(knot_node_parent(node, check_ver)))) { + if (knot_node_parent(node) + && (knot_node_is_deleg_point(knot_node_parent(node)) + || knot_node_is_non_auth(knot_node_parent(node)))) { knot_node_set_non_auth(node); } else if (knot_node_rrset(node, KNOT_RRTYPE_NS) != NULL && node != zone->apex) { knot_node_set_deleg_point(node); } - // authorative node? -// if (!knot_node_is_non_auth(node)) { - zone->node_count++; -// } - // assure that owner has proper node - if (knot_dname_node(knot_node_owner(node), 0) == NULL) { - knot_dname_set_node(knot_node_get_owner(node), node); + if (knot_dname_node(knot_node_owner(node)) == NULL) { knot_dname_set_node(knot_node_get_owner(node), node); } + // check if this node is not a wildcard child of its parent + if (knot_dname_is_wildcard(knot_node_owner(node))) { + assert(knot_node_parent(node) != NULL); + knot_node_set_wildcard_child(knot_node_get_parent(node), node); + } + // NSEC3 node (only if NSEC3 tree is not empty) const knot_node_t *prev; const knot_node_t *nsec3; int match = knot_zone_contents_find_nsec3_for_name(zone, - knot_node_owner(node), - &nsec3, &prev, check_ver); + knot_node_owner(node), + &nsec3, &prev); if (match != KNOT_ZONE_NAME_FOUND) { nsec3 = NULL; } @@ -430,14 +557,52 @@ static void knot_zone_contents_adjust_node_in_tree( knot_zone_adjust_arg_t *args = (knot_zone_adjust_arg_t *)data; knot_node_t *node = tnode->node; + + if (args->err != KNOT_EOK) { + dbg_xfrin_detail("Error during adjusting: %s, skipping node.\n", + knot_strerror(args->err)); + return; + } + + /* + * 1) Set previous node pointer. + */ knot_node_set_previous(node, args->previous_node); - args->previous_node = node; + if (args->first_node == NULL) { args->first_node = node; } knot_zone_contents_t *zone = args->zone; - knot_zone_contents_adjust_node(node, zone, args->check_ver); + /* + * 2) Store domain names to dname table. + * + * TODO: make optional! + */ + assert(zone->dname_table != NULL); + + int ret = knot_zone_contents_dnames_from_node_to_table( + zone->dname_table, node); + if (ret != KNOT_EOK) { + dbg_xfrin("Failed to add dnames from adjusted node to " + "table: %s\n", knot_strerror(ret)); + args->err = ret; + return; + } + + /* + * 3) Do other adjusting (flags, closest enclosers, wildcard children, + * etc.). + */ + knot_zone_contents_adjust_node(node, zone); + + /* + * 4) Store previous node depending on the type of this node. + */ + if (!knot_node_is_non_auth(node) + && knot_node_rrset_count(node) > 0) { + args->previous_node = node; + } } /*----------------------------------------------------------------------------*/ @@ -459,15 +624,36 @@ static void knot_zone_contents_adjust_nsec3_node_in_tree( knot_zone_adjust_arg_t *args = (knot_zone_adjust_arg_t *)data; knot_node_t *node = tnode->node; + + // set previous node knot_node_set_previous(node, args->previous_node); + + // assure that owner has proper node + if (knot_dname_node(knot_node_owner(node)) == NULL) { + knot_dname_set_node(knot_node_get_owner(node), node); + } + + /* + * Store domain names to dname table. + */ + knot_zone_contents_t *zone = args->zone; + assert(zone != NULL); + + int ret = knot_zone_contents_dnames_from_node_to_table( + zone->dname_table, node); + if (ret != KNOT_EOK) { + dbg_xfrin("Failed to add dnames from adjusted node to " + "table: %s\n", knot_strerror(ret)); + args->err = ret; + return; + } + + // here is nothing to consider, all nodes are the same args->previous_node = node; + if (args->first_node == NULL) { args->first_node = node; } - - /* Not needed anymore. */ -// knot_zone_contents_t *zone = args->zone; -// knot_zone_contents_adjust_nsec3_node(node, zone, 1); } /*----------------------------------------------------------------------------*/ @@ -595,9 +781,9 @@ dbg_zone_exec( * node. \a previous is set properly. */ static int knot_zone_contents_find_in_tree(knot_zone_tree_t *tree, - const knot_dname_t *name, - knot_node_t **node, - knot_node_t **previous) + const knot_dname_t *name, + knot_node_t **node, + knot_node_t **previous) { assert(tree != NULL); assert(name != NULL); @@ -607,8 +793,8 @@ static int knot_zone_contents_find_in_tree(knot_zone_tree_t *tree, knot_node_t *found = NULL, *prev = NULL; // knot_node_t *found2 = NULL, *prev2 = NULL; - int exact_match = knot_zone_tree_get_less_or_equal( - tree, name, &found, &prev, 1); + int exact_match = knot_zone_tree_get_less_or_equal(tree, name, &found, + &prev); // assert(prev != NULL); assert(exact_match >= 0); @@ -652,11 +838,6 @@ static void knot_zone_contents_node_to_hash(knot_zone_tree_node_t *tnode, */ #ifdef USE_HASH_TABLE -//dbg_zone_exec( -// char *name = knot_dname_to_str(node->owner); -// dbg_zone("Adding node with owner %s to hash table.\n", name); -// free(name); -//); //assert(zone->table != NULL); // add the node also to the hash table if authoritative, or deleg. point if (zone->table != NULL @@ -669,123 +850,164 @@ static void knot_zone_contents_node_to_hash(knot_zone_tree_node_t *tnode, } /*----------------------------------------------------------------------------*/ +/* CNAME chain checking */ +/*----------------------------------------------------------------------------*/ -static int knot_zone_contents_dnames_from_rdata_to_table( - knot_dname_table_t *table, knot_rdata_t *rdata, - knot_rrtype_descriptor_t *d) +typedef struct cname_chain { + const knot_node_t *node; + struct cname_chain *next; +} cname_chain_t; + +/*----------------------------------------------------------------------------*/ + +static int cname_chain_add(cname_chain_t **last, const knot_node_t *node) { - unsigned int count = knot_rdata_item_count(rdata); - int rc = 0; - if (d->fixed_items) { - assert(count <= d->length); - } - // for each RDATA item - for (unsigned int j = 0; j < count; ++j) { - if (d->wireformat[j] - == KNOT_RDATA_WF_COMPRESSED_DNAME - || d->wireformat[j] - == KNOT_RDATA_WF_UNCOMPRESSED_DNAME - || d->wireformat[j] - == KNOT_RDATA_WF_LITERAL_DNAME) { - dbg_zone("Saving dname from " - "rdata to dname table" - ".\n"); - rc = knot_dname_table_add_dname_check(table, - &knot_rdata_get_item(rdata, j)->dname); - if (rc < 0) { - dbg_zone("Error: %s\n", - knot_strerror(rc)); - return rc; - } - } + assert(last != NULL); + + cname_chain_t *new_cname = + (cname_chain_t *)malloc(sizeof(cname_chain_t)); + CHECK_ALLOC_LOG(new_cname, KNOT_ENOMEM); + + new_cname->node = node; + new_cname->next = NULL; + + if (*last != NULL) { + (*last)->next = new_cname; + } else { + *last = new_cname; } - dbg_zone("RDATA OK.\n"); return KNOT_EOK; } /*----------------------------------------------------------------------------*/ -static int knot_zone_contents_dnames_from_rrset_to_table( - knot_dname_table_t *table, knot_rrset_t *rrset, int replace_owner, - knot_dname_t *owner) +static int cname_chain_contains(cname_chain_t *chain, const knot_node_t *node) { - assert(table != NULL && rrset != NULL && owner != NULL); - - if (replace_owner) { - // discard the old owner and replace it with the new - knot_rrset_set_owner(rrset, owner); + cname_chain_t *act = chain; + while (act != NULL) { + if (act->node == node) { + return 1; + } + act = act->next; } - dbg_zone("RRSet owner: %p\n", rrset->owner); - knot_rrtype_descriptor_t *desc = knot_rrtype_descriptor_by_type( - knot_rrset_type(rrset)); - if (desc == NULL) { - // not recognized RR type, ignore - dbg_zone("RRSet type not recognized.\n"); - return KNOT_EOK; - } - // for each RDATA in RRSet - knot_rdata_t *rdata = knot_rrset_get_rdata(rrset); - while (rdata != NULL) { - int rc = knot_zone_contents_dnames_from_rdata_to_table(table, - rdata, desc); - if (rc != KNOT_EOK) { - return rc; - } + return 0; +} - rdata = knot_rrset_rdata_get_next(rrset, rdata); - } +/*----------------------------------------------------------------------------*/ - dbg_zone("RRSet OK.\n"); - return KNOT_EOK; +static void cname_chain_free(cname_chain_t *chain) +{ + cname_chain_t *act = chain; + + while (act != NULL) { + chain = chain->next; + free(act); + act = chain; + } } /*----------------------------------------------------------------------------*/ -static int knot_zone_contents_dnames_from_node_to_table( - knot_dname_table_t *table, knot_node_t *node) +typedef struct loop_check_data { + knot_zone_contents_t *zone; + int err; +} loop_check_data_t; + +/*----------------------------------------------------------------------------*/ + +static void knot_zone_contents_check_loops_in_tree(knot_zone_tree_node_t *tnode, + void *data) { - /* - * Assuming that all the RRSets have the same owner as the node. - */ + assert(tnode != NULL); + assert(tnode->node != NULL); + assert(data != NULL); - // insert owner - char *name = knot_dname_to_str(node->owner); - dbg_zone("Node owner before inserting to dname table: %p.\n", - node->owner); - dbg_zone("Node owner before inserting to dname table: %s.\n", - name); - free(name); - //knot_dname_t *old_owner = node->owner; - int rc = knot_dname_table_add_dname_check(table, &node->owner); - if (rc < 0) { - dbg_zone("Failed to add dname to dname table.\n"); - return rc; + loop_check_data_t *args = (loop_check_data_t *)data; + const knot_node_t *node = tnode->node; + + assert(args->zone != NULL); + + if (args->err != KNOT_EOK) { + dbg_xfrin_detail("Error during CNAME loop checking, skipping " + "node.\n"); + return; } - int replace_owner = (rc > 0); - dbg_zone("Node owner after inserting to dname table: %p.\n", - node->owner); - name = knot_dname_to_str(node->owner); - dbg_zone("Node owner after inserting to dname table: %s.\n", - name); - free(name); - knot_rrset_t **rrsets = knot_node_get_rrsets(node); - // for each RRSet - for (int i = 0; i < knot_node_rrset_count(node); ++i) { - dbg_zone("Inserting RRSets from node to table.\n"); - rc = knot_zone_contents_dnames_from_rrset_to_table(table, - rrsets[i], replace_owner, node->owner); - if (rc != KNOT_EOK) { - return rc; + // if there is CNAME in the node + const knot_rrset_t *cname = knot_node_rrset(node, KNOT_RRTYPE_CNAME); + cname_chain_t *chain = NULL; + cname_chain_t **act_cname = &chain; + int ret = 0; + + while (cname != NULL && !cname_chain_contains(chain, node)) { + ret = cname_chain_add(act_cname, node); + if (ret != KNOT_EOK) { + cname_chain_free(chain); + args->err = ret; + return; + } + act_cname = &(*act_cname)->next; + + // follow the CNAME chain, including wildcards and + // remember the nodes passed through + const knot_dname_t *next_name = knot_rdata_cname_name( + knot_rrset_rdata(cname)); + assert(next_name != NULL); + const knot_node_t *next_node = knot_dname_node(next_name); + if (next_node == NULL) { + // try to find the name in the zone + const knot_node_t *ce = NULL; + ret = knot_zone_contents_find_dname_hash( + args->zone, next_name, + &next_node, &ce); + +// char *name1 = knot_dname_to_str(next_name); +// char *name2 = (next_node != NULL) +// ? knot_dname_to_str(knot_node_owner(next_node)) +// : "none"; +// char *name3 = (ce != NULL) +// ? knot_dname_to_str(knot_node_owner(ce)) +// : "none"; +// printf("Searched: %s, found: %p (%s), %p (%s); ret: %d" +// ".\n", name1, next_node, name2, ce, name3, ret); +// free(name1); +// if (next_node != NULL) { +// free(name2); +// } +// if (ce != NULL) { +// free(name3); +// } + + if (ret != KNOT_ZONE_NAME_FOUND + && ce != NULL) { + // try to find wildcard child + assert(knot_dname_is_subdomain(next_name, + knot_node_owner(ce))); + next_node = knot_node_wildcard_child(ce); + } + + assert(next_node == NULL || knot_dname_compare( + knot_node_owner(next_node), next_name) == 0 + || knot_dname_is_wildcard(knot_node_owner(next_node))); + } + + if (next_node == NULL) { + // no CNAME node to follow + cname = NULL; + } else { + node = next_node; + cname = knot_node_rrset(node, KNOT_RRTYPE_CNAME); } } - free(rrsets); + if (cname != NULL) { + // this means the node is in the chain already + args->err = KNOT_ECNAME; + } - dbg_zone("Node OK\n"); - return KNOT_EOK; + cname_chain_free(chain); } /*----------------------------------------------------------------------------*/ @@ -793,10 +1015,11 @@ static int knot_zone_contents_dnames_from_node_to_table( /*----------------------------------------------------------------------------*/ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, - uint node_count, - int use_domain_table, - struct knot_zone *zone) + uint node_count, + int use_domain_table, + struct knot_zone *zone) { + dbg_zone("Creating contents for %u nodes.\n", node_count); knot_zone_contents_t *contents = (knot_zone_contents_t *) calloc(1, sizeof(knot_zone_contents_t)); if (contents == NULL) { @@ -810,6 +1033,7 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, contents->apex = apex; contents->zone = zone; knot_node_set_zone(apex, zone); + contents->node_count = 1; dbg_zone("Creating tree for normal nodes.\n"); contents->nodes = malloc(sizeof(knot_zone_tree_t)); @@ -836,7 +1060,7 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, contents->dname_table = NULL; } - contents->node_count = node_count; + //contents->node_count = node_count; /* Initialize NSEC3 params */ dbg_zone("Initializing NSEC3 parameters.\n"); @@ -859,9 +1083,9 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, } #ifdef USE_HASH_TABLE - if (contents->node_count > 0) { + if (node_count > 0) { dbg_zone("Creating hash table.\n"); - contents->table = ck_create_table(contents->node_count); + contents->table = ck_create_table(node_count); if (contents->table == NULL) { goto cleanup; } @@ -984,6 +1208,7 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, int ret = 0; if ((ret = knot_zone_contents_check_node(zone, node)) != 0) { + dbg_zone("Node check failed.\n"); return ret; } @@ -993,10 +1218,20 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, return ret; } + if (use_domain_table) { + ret = knot_zone_contents_dnames_from_node_to_table( + zone->dname_table, node); + if (ret != KNOT_EOK) { + /*! \todo Remove node from the tree and hash table.*/ + dbg_zone("Failed to add dnames into table.\n"); + return ret; + } + } + #ifdef USE_HASH_TABLE - char *name = knot_dname_to_str(node->owner); +// char *name = knot_dname_to_str(node->owner); // dbg_zone("Adding node with owner %s to hash table.\n", name); - free(name); +// free(name); //assert(zone->table != NULL); // add the node also to the hash table if authoritative, or deleg. point if (zone->table != NULL @@ -1010,18 +1245,10 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, #endif assert(knot_zone_contents_find_node(zone, node->owner)); - if (use_domain_table) { - ret = knot_zone_contents_dnames_from_node_to_table( - zone->dname_table, node); - if (ret != KNOT_EOK) { - /*! \todo Remove node from the tree and hash table.*/ - dbg_zone("Failed to add dnames into table.\n"); - return ret; - } - } - knot_node_set_zone(node, zone->zone); + ++zone->node_count; + if (!create_parents) { return KNOT_EOK; } @@ -1030,21 +1257,38 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, knot_dname_t *chopped = knot_dname_left_chop(knot_node_owner(node)); + if(chopped == NULL) { + /* Root domain and root domain only. */ + assert(node->owner && node->owner->labels && + node->owner->labels[0] == 0); + return KNOT_EOK; + } + if (knot_dname_compare(knot_node_owner(zone->apex), chopped) == 0) { dbg_zone("Zone apex is the parent.\n"); knot_node_set_parent(node, zone->apex); + + // check if the node is not wildcard child of the parent + if (knot_dname_is_wildcard( + knot_node_owner(node))) { + knot_node_set_wildcard_child(zone->apex, node); + } } else { knot_node_t *next_node; while ((next_node - = knot_zone_contents_get_node(zone, chopped)) == NULL) { + = knot_zone_contents_get_node(zone, chopped)) == NULL && + chopped != NULL) { /* Adding new dname to zone + add to table. */ dbg_zone("Creating new node.\n"); + + assert(chopped); next_node = knot_node_new(chopped, NULL, flags); if (next_node == NULL) { /* Directly discard. */ knot_dname_free(&chopped); return KNOT_ENOMEM; } + if (use_domain_table) { ret = knot_zone_contents_dnames_from_node_to_table( @@ -1058,6 +1302,8 @@ int knot_zone_contents_add_node(knot_zone_contents_t *zone, if (next_node->owner != chopped) { /* Node owner was in RDATA */ + knot_dname_release(chopped); + knot_dname_retain(next_node->owner); chopped = next_node->owner; } @@ -1101,7 +1347,7 @@ dbg_zone_exec( knot_dname_release(chopped); return KNOT_EHASH; } - +#endif // set parent knot_node_set_parent(node, next_node); @@ -1113,7 +1359,9 @@ dbg_zone_exec( knot_node_owner(node))) { knot_node_set_wildcard_child(next_node, node); } -#endif + + ++zone->node_count; + dbg_zone("Next parent.\n"); node = next_node; knot_dname_t *chopped_last = chopped; @@ -1127,7 +1375,7 @@ dbg_zone_exec( } // set the found parent (in the zone) as the parent of the last // inserted node - assert(knot_node_parent(node, 0) == NULL); + assert(knot_node_parent(node) == NULL); knot_node_set_parent(node, next_node); dbg_zone("Created all parents.\n"); @@ -1450,6 +1698,12 @@ int knot_zone_contents_remove_node(knot_zone_contents_t *contents, const knot_dname_t *owner = knot_node_owner(node); +dbg_zone_exec_verb( + char *name = knot_dname_to_str(owner); + dbg_zone_verb("Removing zone node: %s\n", name); + free(name); +); + // 1) remove the node from hash table *removed_hash = NULL; *removed_hash = ck_remove_item(contents->table, @@ -1677,7 +1931,7 @@ dbg_zone_exec( while (matched_labels < knot_dname_label_count( knot_node_owner((*closest_encloser)))) { (*closest_encloser) = - knot_node_parent((*closest_encloser), 1); + knot_node_parent((*closest_encloser)); assert(*closest_encloser); } } @@ -1799,6 +2053,7 @@ dbg_zone_exec( return KNOT_ERROR; } + assert(zone->table != NULL); const ck_hash_table_item_t *item = ck_find_item(zone->table, name_tmp, name_size); @@ -1865,8 +2120,7 @@ const knot_node_t *knot_zone_contents_find_nsec3_node( int knot_zone_contents_find_nsec3_for_name(const knot_zone_contents_t *zone, const knot_dname_t *name, const knot_node_t **nsec3_node, - const knot_node_t **nsec3_previous, - int check_ver) + const knot_node_t **nsec3_previous) { if (zone == NULL || name == NULL || nsec3_node == NULL || nsec3_previous == NULL) { @@ -1890,7 +2144,7 @@ dbg_zone_exec( // create dummy node to use for lookup int exact_match = knot_zone_tree_find_less_or_equal( - zone->nsec3_nodes, nsec3_name, &found, &prev, check_ver); + zone->nsec3_nodes, nsec3_name, &found, &prev); assert(exact_match >= 0); knot_dname_release(nsec3_name); @@ -1921,7 +2175,7 @@ dbg_zone_exec( // set the previous node of the found node assert(exact_match); assert(*nsec3_node != NULL); - *nsec3_previous = knot_node_previous(*nsec3_node, check_ver); + *nsec3_previous = knot_node_previous(*nsec3_node); } else { *nsec3_previous = prev; } @@ -1958,18 +2212,97 @@ knot_node_t *knot_zone_contents_get_apex(const knot_zone_contents_t *zone) /*----------------------------------------------------------------------------*/ -//knot_dname_t *knot_zone_contents_name(const knot_zone_contents_t *zone) -//{ -// if (zone == NULL) { -// return NULL; -// } +int knot_zone_contents_adjust(knot_zone_contents_t *zone) +{ + if (zone == NULL) { + return KNOT_EBADARG; + } -// return zone->name; -//} + // load NSEC3PARAM (needed on adjusting function) + knot_zone_contents_load_nsec3param(zone); + + knot_zone_adjust_arg_t adjust_arg; + adjust_arg.zone = zone; + adjust_arg.first_node = NULL; + adjust_arg.previous_node = NULL; + adjust_arg.err = KNOT_EOK; +// adjust_arg.check_ver = check_ver; + + dbg_zone("Adjusting normal nodes.\n"); + int ret = knot_zone_tree_forward_apply_inorder(zone->nodes, + knot_zone_contents_adjust_node_in_tree, + &adjust_arg); + assert(ret == KNOT_EOK); + + if (adjust_arg.err != KNOT_EOK) { + dbg_zone("Failed to adjust normal nodes: %s\n", + knot_strerror(adjust_arg.err)); + return adjust_arg.err; + } + + assert(zone->apex == adjust_arg.first_node); + knot_node_set_previous(zone->apex, adjust_arg.previous_node); + + dbg_zone("Done.\n"); + + adjust_arg.first_node = NULL; + adjust_arg.previous_node = NULL; + + dbg_zone("Adjusting NSEC3 nodes.\n"); + ret = knot_zone_tree_forward_apply_inorder( + zone->nsec3_nodes, + knot_zone_contents_adjust_nsec3_node_in_tree, + &adjust_arg); + assert(ret == KNOT_EOK); + + if (adjust_arg.err != KNOT_EOK) { + dbg_zone("Failed to adjust NSEC3 nodes: %s\n", + knot_strerror(adjust_arg.err)); + return adjust_arg.err; + } + + dbg_zone("Done.\n"); + // set the last node as previous of the first node + if (adjust_arg.first_node) { + knot_node_set_previous(adjust_arg.first_node, + adjust_arg.previous_node); + } + + return ret; +} /*----------------------------------------------------------------------------*/ -int knot_zone_contents_adjust(knot_zone_contents_t *zone, int check_ver) +int knot_zone_contents_check_loops(knot_zone_contents_t *zone) +{ + if (zone == NULL) { + return KNOT_EBADARG; + } + + dbg_zone("Checking CNAME and wildcard loops.\n"); + + loop_check_data_t data; + data.err = KNOT_EOK; + data.zone = zone; + + assert(zone->nodes != NULL); + knot_zone_tree_forward_apply_inorder(zone->nodes, + knot_zone_contents_check_loops_in_tree, + (void *)&data); + + if (data.err != KNOT_EOK) { + dbg_zone("Found CNAME loop in data. Aborting transfer.\n"); + return data.err; + } + + dbg_zone("Done\n"); + + return KNOT_EOK; +} + +/*----------------------------------------------------------------------------*/ + +int knot_zone_contents_adjust_old(knot_zone_contents_t *zone) { if (zone == NULL) { return KNOT_EBADARG; @@ -1982,7 +2315,8 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone, int check_ver) adjust_arg.zone = zone; adjust_arg.first_node = NULL; adjust_arg.previous_node = NULL; - adjust_arg.check_ver = check_ver; +// adjust_arg.check_ver = check_ver; + adjust_arg.err = KNOT_EOK; dbg_zone("Adjusting normal nodes.\n"); int ret = knot_zone_tree_forward_apply_inorder(zone->nodes, @@ -1991,6 +2325,12 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone, int check_ver) if (ret != KNOT_EOK) { return ret; } + if (adjust_arg.err != KNOT_EOK) { + dbg_zone("Failed node adjusting: %s\n", + knot_strerror(adjust_arg.err)); + return adjust_arg.err; + } + dbg_zone("Done.\n"); assert(zone->apex == adjust_arg.first_node); @@ -2000,10 +2340,8 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone, int check_ver) adjust_arg.previous_node = NULL; dbg_zone("Adjusting NSEC3 nodes.\n"); - ret = knot_zone_tree_forward_apply_inorder( - zone->nsec3_nodes, - knot_zone_contents_adjust_nsec3_node_in_tree, - &adjust_arg); + ret = knot_zone_tree_forward_apply_inorder(zone->nsec3_nodes, + knot_zone_contents_adjust_nsec3_node_in_tree, &adjust_arg); dbg_zone("Done.\n"); if (adjust_arg.first_node) { @@ -2023,7 +2361,7 @@ int knot_zone_contents_load_nsec3param(knot_zone_contents_t *zone) } const knot_rrset_t *rrset = knot_node_rrset(zone->apex, - KNOT_RRTYPE_NSEC3PARAM); + KNOT_RRTYPE_NSEC3PARAM); if (rrset != NULL) { knot_nsec3_params_from_wire(&zone->nsec3_params, rrset); @@ -2214,7 +2552,7 @@ int knot_zone_contents_dname_table_apply(knot_zone_contents_t *contents, /*----------------------------------------------------------------------------*/ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from, - knot_zone_contents_t **to) + knot_zone_contents_t **to) { if (from == NULL || to == NULL) { return KNOT_EBADARG; @@ -2310,6 +2648,102 @@ cleanup: /*----------------------------------------------------------------------------*/ +int knot_zone_contents_shallow_copy2(const knot_zone_contents_t *from, + knot_zone_contents_t **to) +{ + if (from == NULL || to == NULL) { + return KNOT_EBADARG; + } + + /* Copy to same destination as source. */ + if (from == *to) { + return KNOT_EBADARG; + } + + int ret = KNOT_EOK; + + knot_zone_contents_t *contents = (knot_zone_contents_t *)calloc( + 1, sizeof(knot_zone_contents_t)); + if (contents == NULL) { + ERR_ALLOC_FAILED; + return KNOT_ENOMEM; + } + + //contents->apex = from->apex; + + contents->nodes = malloc(sizeof(knot_zone_tree_t)); + if (contents->nodes == NULL) { + ERR_ALLOC_FAILED; + ret = KNOT_ENOMEM; + goto cleanup; + } + + contents->nsec3_nodes = malloc(sizeof(knot_zone_tree_t)); + if (contents->nsec3_nodes == NULL) { + ERR_ALLOC_FAILED; + ret = KNOT_ENOMEM; + goto cleanup; + } + + if (from->dname_table != NULL) { + contents->dname_table = knot_dname_table_new(); + if (contents->dname_table == NULL) { + ERR_ALLOC_FAILED; + ret = KNOT_ENOMEM; + goto cleanup; + } + if ((ret = knot_dname_table_shallow_copy(from->dname_table, + contents->dname_table)) != KNOT_EOK) { + goto cleanup; + } + } else { + contents->dname_table = NULL; + } + + contents->node_count = from->node_count; + contents->generation = from->generation; + + contents->zone = from->zone; + +// /* Initialize NSEC3 params */ +// memcpy(&contents->nsec3_params, &from->nsec3_params, +// sizeof(knot_nsec3_params_t)); + + if ((ret = knot_zone_tree_deep_copy(from->nodes, + contents->nodes)) != KNOT_EOK + || (ret = knot_zone_tree_deep_copy(from->nsec3_nodes, + contents->nsec3_nodes)) != KNOT_EOK) { + goto cleanup; + } + +#ifdef USE_HASH_TABLE + if (from->table != NULL) { + ret = ck_deep_copy(from->table, &contents->table); + if (ret != 0) { + dbg_zone("knot_zone_contents_shallow_copy: " + "hash table copied\n"); + ret = KNOT_ERROR; + goto cleanup; + } + } +#endif + contents->apex = knot_node_get_new_node(from->apex); + + dbg_zone("knot_zone_contents_shallow_copy: finished OK\n"); + + *to = contents; + return KNOT_EOK; + +cleanup: + knot_zone_tree_free(&contents->nodes); + knot_zone_tree_free(&contents->nsec3_nodes); + free(contents->dname_table); + free(contents); + return ret; +} + +/*----------------------------------------------------------------------------*/ + void knot_zone_contents_free(knot_zone_contents_t **contents) { if (contents == NULL || *contents == NULL) { @@ -2396,3 +2830,635 @@ void knot_zone_contents_deep_free(knot_zone_contents_t **contents, *contents = NULL; } +/*----------------------------------------------------------------------------*/ +/* Integrity check */ +/*----------------------------------------------------------------------------*/ + +typedef struct check_data { + const knot_zone_contents_t *contents; + const knot_node_t *previous; + const knot_node_t *deleg_point; + const knot_node_t *parent; + int children; + int errors; +} check_data_t; + +/*----------------------------------------------------------------------------*/ + +static void knot_zc_integrity_check_previous(const knot_node_t *node, + check_data_t *check_data, + const char *name) +{ + // first, check if the previous and next pointers are set properly + if (check_data->previous != NULL) { + char *name_prev = knot_dname_to_str( + knot_node_owner(check_data->previous)); + + if (knot_node_previous(node) != check_data->previous) { + char *name2 = knot_dname_to_str(knot_node_owner( + knot_node_previous(node))); + fprintf(stderr, "Wrong previous node: node: %s, " + "previous: %s. Should be: %s.\n", name, name2, + name_prev); + free(name2); + + ++check_data->errors; + } + +// if (knot_node_next(check_data->previous) != node) { +// char *name2 = knot_dname_to_str(knot_node_owner( +// knot_node_next(check_data->previous))); +// fprintf(stderr, "Wrong next node: node %s, next %s. " +// "Should be %s.\n", name_prev, name2 ,name); +// free(name2); + +// ++check_data->errors; +// } + + free(name_prev); + } +} + +/*----------------------------------------------------------------------------*/ + +static void knot_zc_integrity_check_flags(const knot_node_t *node, + check_data_t *check_data, + char *name) +{ + if (node == knot_zone_contents_apex(check_data->contents)) { + if (!knot_node_is_auth(node)) { + fprintf(stderr, "Wrong flags: node %s, flags: %u. " + "Should be non-authoritative.\n", name, + node->flags); + ++check_data->errors; + } + return; + } + + // check the flags + if (check_data->deleg_point != NULL + && knot_dname_is_subdomain(knot_node_owner(node), + knot_node_owner(check_data->deleg_point))) { + // this is a non-authoritative node + if (!knot_node_is_non_auth(node)) { + fprintf(stderr, "Wrong flags: node %s, flags: %u. " + "Should be non-authoritative.\n", name, + node->flags); + ++check_data->errors; + } + } else { + if (knot_node_rrset(node, KNOT_RRTYPE_NS) != NULL) { + // this is a delegation point + if (!knot_node_is_deleg_point(node)) { + fprintf(stderr, "Wrong flags: node %s, flags: " + "%u. Should be deleg. point.\n", name, + node->flags); + ++check_data->errors; + } + check_data->deleg_point = node; + } else { + // this is an authoritative node + if (!knot_node_is_auth(node)) { + fprintf(stderr, "Wrong flags: node %s, flags: " + "%u. Should be authoritative.\n", name, + node->flags); + ++check_data->errors; + } + check_data->deleg_point = NULL; + } + + // in this case (authoritative or deleg-point), the node should + // be a previous of some next node only if it has some data + if (knot_node_rrset_count(node) > 0) { + check_data->previous = node; + } + } +} + +/*----------------------------------------------------------------------------*/ + +static void knot_zc_integrity_check_parent(const knot_node_t *node, + check_data_t *check_data, + char *name) +{ + if (check_data->parent == NULL) { + // this is only possible for apex + assert(node == knot_zone_contents_apex(check_data->contents)); + check_data->parent = node; + return; + } + + const knot_dname_t *node_owner = knot_node_owner(node); + const knot_dname_t *parent_owner = knot_node_owner(check_data->parent); + char *pname = knot_dname_to_str(parent_owner); + + // if direct child + if (knot_dname_is_subdomain(node_owner, parent_owner) + && knot_dname_matched_labels(node_owner, parent_owner) + == knot_dname_label_count(parent_owner)) { + +// // increase the parent's children count +// fprintf(stderr, "Parent: %s, node: %s. Increasing children count.\n", +// pname, name); +// ++check_data->children; + + // check the parent pointer + const knot_node_t *parent = knot_node_parent(node); + if (parent != check_data->parent) { + char *name2 = (parent != NULL) + ? knot_dname_to_str( + knot_node_owner(parent)) + : "none"; + fprintf(stderr, "Wrong parent: node %s, parent %s. " + " Should be %s\n", name, name2, pname); + if (parent != NULL) { + free(name2); + } + + ++check_data->errors; + } else { + // if parent is OK, check if the node is not a + // wildcard child of it; in such case it should be set + // as the wildcard child of its parent + if (knot_dname_is_wildcard(node_owner) + && knot_node_wildcard_child(check_data->parent) + != node) { + char *wc = (knot_node_wildcard_child( + check_data->parent) == NULL) + ? "none" + : knot_dname_to_str(knot_node_owner( + knot_node_wildcard_child( + check_data->parent))); + fprintf(stderr, "Wrong wildcard child: node %s," + " wildcard child: %s. Should be %s\n", + pname, wc, name); + if (knot_node_wildcard_child( + check_data->parent) != NULL) { + free(wc); + } + + ++check_data->errors; + } + } + } else { + // not a direct child, check children count +// if (check_data->parent +// && knot_node_children(check_data->parent) +// != check_data->children) { +// fprintf(stderr, "Wrong children count: node %s, count: " +// "%u. Should be: %u\n", pname, +// knot_node_children(check_data->parent), +// check_data->children); + +// ++check_data->errors; +// } + + // reset the children count + //check_data->parent = node; +// check_data->children = 0; + } + + free(pname); + check_data->parent = node; +} + +/*----------------------------------------------------------------------------*/ + +static void knot_zc_integrity_check_rrset_count(const knot_node_t *node, + check_data_t *check_data, + const char *name) +{ + // count RRSets + int real_count = knot_node_count_rrsets(node); + int count = knot_node_rrset_count(node); + + if (count != real_count) { + fprintf(stderr, "Wrong RRSet count: node %s, count %d. " + "Should be %d\n", name, count, real_count); + + ++check_data->errors; + } +} + +/*----------------------------------------------------------------------------*/ + +typedef struct find_dname_data { + const knot_dname_t *to_find; + const knot_dname_t *found; +} find_dname_data_t; + +/*----------------------------------------------------------------------------*/ + +void find_in_dname_table(knot_dname_t *dname, void *data) +{ + assert(dname != NULL); + assert(data != NULL); + + find_dname_data_t *fdata = (find_dname_data_t *)data; + + if (fdata->found != NULL) { + return; + } + + if (knot_dname_compare(dname, fdata->to_find) == 0) { + fdata->found = dname; + } +} + +/*----------------------------------------------------------------------------*/ + +static int knot_zc_integrity_check_find_dname(const knot_zone_contents_t *zone, + const knot_dname_t *to_find, + const char *node_name) +{ + int ret = 0; + +// find_dname_data_t data_find; +// data_find.found = NULL; +// data_find.to_find = to_find; + +// int res = knot_zone_contents_dname_table_apply( +// (knot_zone_contents_t *)zone, +// find_in_dname_table, (void *)&data_find); +// assert(res == KNOT_EOK); + + knot_dname_t *found = knot_dname_table_find_dname(zone->dname_table, + (knot_dname_t *)to_find); + + char *to_find_name = knot_dname_to_str(to_find); + + if (!found || found != to_find) { + fprintf(stderr, "Dname not stored in dname table: " + "node %s, name %s, found some dname: %s\n", node_name, + to_find_name, (found != NULL) ? "yes" : "no"); + fprintf(stderr, "Dname to find: %p, found dname: %p\n", + found, to_find); + ret = 1; + } + + free(to_find_name); + + knot_dname_release(found); + + return ret; +} + +/*----------------------------------------------------------------------------*/ + +static void knot_zc_integrity_check_owner(const knot_node_t *node, + check_data_t *check_data, + const char *name) +{ + // check node stored in owner + const knot_node_t *owner_node = + knot_dname_node(knot_node_owner(node)); + if (owner_node != node) { + char *name2 = (owner_node != NULL) + ? knot_dname_to_str(knot_node_owner(owner_node)) + : "none"; + fprintf(stderr, "Wrong owner's node: node %s, owner's node %s" + "\n", name, name2); + if (owner_node != NULL) { + free(name2); + } + + ++check_data->errors; + } + + // check if the owner is stored in dname table + check_data->errors += knot_zc_integrity_check_find_dname( + check_data->contents, knot_node_owner(node), name); +} + +/*----------------------------------------------------------------------------*/ + +static void knot_zc_integrity_check_dnames_in_rrset(const knot_rrset_t *rrset, + check_data_t *check_data, + const char *name) +{ + // check owner of the RRSet + check_data->errors += knot_zc_integrity_check_find_dname( + check_data->contents, + knot_rrset_owner(rrset), name); + + knot_rrtype_descriptor_t *desc = knot_rrtype_descriptor_by_type( + knot_rrset_type(rrset)); + + assert(desc != NULL); + + const knot_rdata_t *rdata = knot_rrset_rdata(rrset); + while (rdata != NULL) { + for (int i = 0; i < knot_rdata_item_count(rdata); ++i) { + if (desc->wireformat[i] + == KNOT_RDATA_WF_COMPRESSED_DNAME + || desc->wireformat[i] + == KNOT_RDATA_WF_UNCOMPRESSED_DNAME + || desc->wireformat[i] + == KNOT_RDATA_WF_LITERAL_DNAME) { + knot_rdata_item_t *item = knot_rdata_get_item( + rdata, i); + check_data->errors += + knot_zc_integrity_check_find_dname( + check_data->contents, item->dname, name); + } + } + rdata = knot_rrset_rdata_next(rrset, rdata); + } +} + +/*----------------------------------------------------------------------------*/ + +static void knot_zc_integrity_check_dnames(const knot_node_t *node, + check_data_t *check_data, + const char *name) +{ + // check all dnames in all RRSets - both owners and in RDATA + const knot_rrset_t **rrsets = knot_node_rrsets(node); + if (rrsets != NULL) { + for (int i = 0; i < knot_node_rrset_count(node); ++i) { + knot_zc_integrity_check_dnames_in_rrset(rrsets[i], + check_data, name); + } + } + free(rrsets); +} + +/*----------------------------------------------------------------------------*/ + +static void knot_zc_integrity_check_node(knot_node_t *node, void *data) +{ + assert(node != NULL); + assert(data != NULL); + + const knot_dname_t *node_owner = knot_node_owner(node); + char *name = knot_dname_to_str(node_owner); + + check_data_t *check_data = (check_data_t *)data; + + // check previous-next chain + knot_zc_integrity_check_previous(node, check_data, name); + + // check node flags + knot_zc_integrity_check_flags(node, check_data, name); + + // check if the node is child of the saved parent & children count + // & wildcard child + knot_zc_integrity_check_parent(node, check_data, name); + + // check RRSet count + knot_zc_integrity_check_rrset_count(node, check_data, name); + + // check owner + knot_zc_integrity_check_owner(node, check_data, name); + + // check dnames + knot_zc_integrity_check_dnames(node, check_data, name); + + /*! \todo Check NSEC3 node. */ + + free(name); +} + +/*----------------------------------------------------------------------------*/ + +static void knot_zc_integrity_check_nsec3(knot_node_t *node, void *data) +{ + assert(node != NULL); + assert(data != NULL); + + const knot_dname_t *node_owner = knot_node_owner(node); + char *name = knot_dname_to_str(node_owner); + + check_data_t *check_data = (check_data_t *)data; + + // check previous-next chain + knot_zc_integrity_check_previous(node, check_data, name); + // store the node as new previous + check_data->previous = node; + + // check if the node is child of the zone apex + if (node->parent != check_data->parent) { + fprintf(stderr, "NSEC3 node's parent is not apex. Node: %s.\n", + name); + ++check_data->errors; + } + + // check RRSet count + knot_zc_integrity_check_rrset_count(node, check_data, name); + + // check owner + knot_zc_integrity_check_owner(node, check_data, name); + + // check dnames + knot_zc_integrity_check_dnames(node, check_data, name); + + free(name); +} + +/*----------------------------------------------------------------------------*/ + +void reset_child_count(knot_zone_tree_node_t *tree_node, void *data) +{ + assert(tree_node != NULL); + assert(data != NULL); + + knot_node_t **apex_copy = (knot_node_t **)data; + if (*apex_copy == NULL) { + *apex_copy = tree_node->node; + } + + if (tree_node->node != NULL) { + tree_node->node->children = 0; + } +} + +/*----------------------------------------------------------------------------*/ + +void count_children(knot_zone_tree_node_t *tree_node, void *data) +{ + UNUSED(data); + if (tree_node->node != NULL && tree_node->node->parent != NULL) { + assert(tree_node->node->parent->new_node != NULL); + // fix parent pointer + tree_node->node->parent = tree_node->node->parent->new_node; + ++tree_node->node->parent->children; + } +} + +/*----------------------------------------------------------------------------*/ + +void check_child_count(knot_zone_tree_node_t *tree_node, void *data) +{ + assert(tree_node != NULL); + assert(data != NULL); + + check_data_t *check_data = (check_data_t *)data; + knot_node_t *node = tree_node->node; + + // find corresponding node in the given contents + const knot_node_t *found = NULL; + found = knot_zone_contents_find_node(check_data->contents, + knot_node_owner(node)); + assert(found != NULL); + + if (knot_node_children(node) != knot_node_children(found)) { + char *name = knot_dname_to_str(knot_node_owner(node)); + fprintf(stderr, "Wrong children count: node (%p) %s, count %u. " + "Should be %u (%p)\n", found, name, + knot_node_children(found), + knot_node_children(node), node); + free(name); + + ++check_data->errors; + } +} + +/*----------------------------------------------------------------------------*/ + +static void reset_new_nodes(knot_zone_tree_node_t *tree_node, void *data) +{ + assert(tree_node != NULL); + UNUSED(data); + + knot_node_t *node = tree_node->node; + knot_node_set_new_node(node, NULL); +} + +/*----------------------------------------------------------------------------*/ + +/*!< \todo remove debug code. */ +//static void print_child_count(knot_node_t *node, void *data) +//{ +// UNUSED(data); +// assert(node != NULL); + +// char *name = knot_dname_to_str(knot_node_owner(node)); +// fprintf(stderr, "Node: %s, children count: %d\n", name, +// knot_node_children(node)); +// free(name); +//} + +/*----------------------------------------------------------------------------*/ + +static void count_nsec3_nodes(knot_zone_tree_node_t *tree_node, void *data) +{ + assert(tree_node != NULL); + assert(tree_node->node != NULL); + assert(data != NULL); + +// int *count = (int *)data; + knot_node_t *apex = (knot_node_t *)data; + assert(apex != NULL); + + apex->children += 1; +} + +/*----------------------------------------------------------------------------*/ + +int knot_zc_integrity_check_child_count(check_data_t *data) +{ + int errors = 0; + + // do shallow copy of the node tree + knot_zone_tree_t *nodes_copy = (knot_zone_tree_t *) + malloc(sizeof(knot_zone_tree_t)); + if (nodes_copy == NULL) { + return 1; + } + + knot_zone_tree_init(nodes_copy); + +// int ret = knot_zone_contents_tree_apply_inorder(data->contents, +// print_child_count, +// NULL); + + int ret = knot_zone_tree_deep_copy(data->contents->nodes, nodes_copy); + assert(ret == KNOT_EOK); + + + // set children count of all nodes to 0 + // in the same walkthrough find the apex + knot_node_t *apex_copy = NULL; + knot_zone_tree_forward_apply_inorder(nodes_copy, reset_child_count, + (void *)&apex_copy); + assert(apex_copy != NULL); + + // now count children of all nodes, presuming the parent pointers are ok + knot_zone_tree_forward_apply_inorder(nodes_copy, count_children, NULL); + + // add count of NSEC3 nodes to the apex' children count +// int nsec3_nodes = 0; + dbg_zone(stderr, "Children count of new apex before NSEC3: %d\n", + data->contents->apex->new_node->children); + knot_zone_tree_forward_apply_inorder(data->contents->nsec3_nodes, + count_nsec3_nodes, + (void *)apex_copy); + + + // now compare the children counts + // iterate over the old zone and search for nodes in the copy +// data->children = nsec3_nodes; + knot_zone_tree_forward_apply_inorder(nodes_copy, check_child_count, + (void *)data); + + // cleanup old zone tree - reset pointers to new node to NULL + knot_zone_tree_forward_apply_inorder(data->contents->nodes, + reset_new_nodes, NULL); + + // destroy the shallow copy + knot_zone_tree_deep_free(&nodes_copy); + + return errors; +} + +/*----------------------------------------------------------------------------*/ + +int knot_zone_contents_integrity_check(const knot_zone_contents_t *contents) +{ + /* + * 1) Check flags of nodes. + * - Those containing NS RRSets should have the 'delegation point' + * flag set. + * - Their descendants should be marked as non-authoritative. + * - Other nodes should be marked as authoritative. + * + * In the same walkthrough check: + * - if nodes are properly connected by 'previous' and 'next' pointers. + * Only authoritative nodes and delegation points should be. + * - parents - each node (except for the apex) should have a parent set + * and it should be a node with owner one label shorter. + * - RRSet counts. + * - etc... + */ + + check_data_t data; + data.errors = 0; + data.previous = NULL; + data.deleg_point = NULL; + data.parent = NULL; + data.children = 0; + data.contents = contents; + + int ret = knot_zone_contents_tree_apply_inorder( + (knot_zone_contents_t *)contents, + knot_zc_integrity_check_node, (void *)&data); + assert(ret == KNOT_EOK); + + // if OK, we can continue with checking children count + // (we need the parent pointers to be set well) + if (data.errors == 0) { + data.contents = contents; + knot_zc_integrity_check_child_count(&data); + } + + data.previous = NULL; + data.children = 0; + data.parent = contents->apex; + ret = knot_zone_contents_nsec3_apply_inorder( + (knot_zone_contents_t *)contents, + knot_zc_integrity_check_nsec3, (void *)&data); + assert(ret == KNOT_EOK); + + return data.errors; +} + diff --git a/src/libknot/zone/zone-contents.h b/src/libknot/zone/zone-contents.h index 2856f76..24fbcac 100644 --- a/src/libknot/zone/zone-contents.h +++ b/src/libknot/zone/zone-contents.h @@ -338,8 +338,7 @@ int knot_zone_contents_find_nsec3_for_name( const knot_zone_contents_t *contents, const knot_dname_t *name, const knot_node_t **nsec3_node, - const knot_node_t **nsec3_previous, - int check_ver); + const knot_node_t **nsec3_previous); /*! * \brief Returns the apex node of the zone. * @@ -362,7 +361,9 @@ knot_node_t *knot_zone_contents_get_apex( * * \param zone Zone to adjust domain names in. */ -int knot_zone_contents_adjust(knot_zone_contents_t *contents, int check_ver); +int knot_zone_contents_adjust(knot_zone_contents_t *contents); + +int knot_zone_contents_check_loops(knot_zone_contents_t *zone); /*! * \brief Parses the NSEC3PARAM record stored in the zone. @@ -544,13 +545,24 @@ int knot_zone_contents_dname_table_apply(knot_zone_contents_t *contents, * \retval KNOT_ENOMEM */ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from, - knot_zone_contents_t **to); + knot_zone_contents_t **to); + +int knot_zone_contents_shallow_copy2(const knot_zone_contents_t *from, + knot_zone_contents_t **to); + +//int knot_zone_contents_dnames_from_node_to_table( +// knot_dname_table_t *table, knot_node_t *node); + +//void knot_zone_contents_adjust_node(knot_node_t *node, +// knot_zone_contents_t *zone, int check_ver); void knot_zone_contents_free(knot_zone_contents_t **contents); void knot_zone_contents_deep_free(knot_zone_contents_t **contents, int destroy_dname_table); +int knot_zone_contents_integrity_check(const knot_zone_contents_t *contents); + #endif /*! @} */ diff --git a/src/libknot/zone/zone-tree.c b/src/libknot/zone/zone-tree.c index cdf128e..de5df18 100644 --- a/src/libknot/zone/zone-tree.c +++ b/src/libknot/zone/zone-tree.c @@ -21,6 +21,7 @@ #include "zone-tree.h" #include "zone/node.h" #include "util/error.h" +#include "util/debug.h" /*----------------------------------------------------------------------------*/ /* Non-API functions */ @@ -87,6 +88,8 @@ static int knot_zone_tree_copy_node(knot_zone_tree_node_t *from, if (ret != KNOT_EOK) { knot_zone_tree_delete_subtree((*to)->avl.avl_left); (*to)->avl.avl_left = NULL; + free(*to); + *to = NULL; return ret; } @@ -96,24 +99,74 @@ static int knot_zone_tree_copy_node(knot_zone_tree_node_t *from, /*----------------------------------------------------------------------------*/ static void knot_zone_tree_free_node(knot_zone_tree_node_t *node, - int free_data, int free_owner) + int free_data) { if (node == NULL) { return; } - knot_zone_tree_free_node(node->avl.avl_left, free_data, free_owner); + knot_zone_tree_free_node(node->avl.avl_left, free_data); - knot_zone_tree_free_node(node->avl.avl_right, free_data, free_owner); + knot_zone_tree_free_node(node->avl.avl_right, free_data); if (free_data) { - knot_node_free(&node->node, free_owner, 0); + knot_node_free(&node->node, 0); } free(node); } /*----------------------------------------------------------------------------*/ + +static int knot_zone_tree_deep_copy_node(knot_zone_tree_node_t *from, + knot_zone_tree_node_t **to) +{ + if (from == NULL) { + *to = NULL; + return KNOT_EOK; + } + + *to = (knot_zone_tree_node_t *)malloc(sizeof(knot_zone_tree_node_t)); + if (*to == NULL) { + return KNOT_ENOMEM; + } + + int ret = knot_node_shallow_copy(from->node, &(*to)->node); +// printf("Copied node: %p to node %p. New node1: %p, new node 2: %p\n", +// from->node, (*to)->node, from->node->new_node, (*to)->node->new_node); + if (ret != KNOT_EOK) { + dbg_zone_verb("Failed to do shallow copy of node.\n"); + free(*to); + return ret; + } + + (*to)->avl.avl_height = from->avl.avl_height; + + ret = knot_zone_tree_deep_copy_node(from->avl.avl_left, + &(*to)->avl.avl_left); + if (ret != KNOT_EOK) { + dbg_zone_verb("Failed to do shallow copy of left subtree.\n"); + return ret; + } + + ret = knot_zone_tree_deep_copy_node(from->avl.avl_right, + &(*to)->avl.avl_right); + if (ret != KNOT_EOK) { + dbg_zone_verb("Failed to do shallow copy of right subtree.\n"); + knot_zone_tree_free_node((*to)->avl.avl_left, 1); + (*to)->avl.avl_left = NULL; + knot_node_free(&(*to)->node, 0); + free(*to); + *to = NULL; + return ret; + } + + knot_node_set_new_node(from->node, (*to)->node); + + return KNOT_EOK; +} + +/*----------------------------------------------------------------------------*/ /* API functions */ /*----------------------------------------------------------------------------*/ @@ -197,7 +250,7 @@ int knot_zone_tree_get(knot_zone_tree_t *tree, const knot_dname_t *owner, knot_zone_tree_node_t *n = TREE_FIND(tree, knot_zone_tree_node, avl, tmp); - knot_node_free(&tmp_data, 0, 0); + knot_node_free(&tmp_data, 0); free(tmp); if (n != NULL) { @@ -212,15 +265,14 @@ int knot_zone_tree_get(knot_zone_tree_t *tree, const knot_dname_t *owner, int knot_zone_tree_find_less_or_equal(knot_zone_tree_t *tree, const knot_dname_t *owner, const knot_node_t **found, - const knot_node_t **previous, - int check_version) + const knot_node_t **previous) { if (tree == NULL || owner == NULL || found == NULL || previous == NULL) { return KNOT_EBADARG; } knot_node_t *f, *p; - int ret = knot_zone_tree_get_less_or_equal(tree, owner, &f, &p, check_version); + int ret = knot_zone_tree_get_less_or_equal(tree, owner, &f, &p); *found = f; *previous = p; @@ -233,8 +285,7 @@ int knot_zone_tree_find_less_or_equal(knot_zone_tree_t *tree, int knot_zone_tree_get_less_or_equal(knot_zone_tree_t *tree, const knot_dname_t *owner, knot_node_t **found, - knot_node_t **previous, - int check_version) + knot_node_t **previous) { if (tree == NULL || owner == NULL || found == NULL || previous == NULL) { @@ -262,7 +313,7 @@ int knot_zone_tree_get_less_or_equal(knot_zone_tree_t *tree, int exact_match = TREE_FIND_LESS_EQUAL( tree, knot_zone_tree_node, avl, tmp, &f, &prev); - knot_node_free(&tmp_data, 0, 0); + knot_node_free(&tmp_data, 0); free(tmp); *found = (exact_match > 0) ? f->node : NULL; @@ -271,7 +322,7 @@ int knot_zone_tree_get_less_or_equal(knot_zone_tree_t *tree, // previous is not really previous but should be the leftmost // node in the tree; take it's previous assert(prev != NULL); - *previous = knot_node_get_previous(prev->node, check_version); + *previous = knot_node_get_previous(prev->node); exact_match = 0; } else if (prev == NULL) { if (!exact_match) { @@ -292,7 +343,7 @@ int knot_zone_tree_get_less_or_equal(knot_zone_tree_t *tree, // node assert(exact_match > 0); assert(f != NULL); - *previous = knot_node_get_previous(f->node, check_version); + *previous = knot_node_get_previous(f->node); } else { // otherwise check if the previous node is not an empty // non-terminal @@ -300,7 +351,7 @@ int knot_zone_tree_get_less_or_equal(knot_zone_tree_t *tree, * to an empty non-terminal. */ *previous = (knot_node_rrset_count(prev->node) == 0) - ? knot_node_get_previous(prev->node, check_version) + ? knot_node_get_previous(prev->node) : prev->node; } @@ -342,7 +393,7 @@ int knot_zone_tree_remove(knot_zone_tree_t *tree, /*! \todo How to know if this was successful? */ TREE_REMOVE(tree, knot_zone_tree_node, avl, tmp); - knot_node_free(&tmp_data, 0, 0); + knot_node_free(&tmp_data, 0); free(tmp); // *removed = (n) ? n->node : NULL; @@ -445,24 +496,43 @@ int knot_zone_tree_shallow_copy(knot_zone_tree_t *from, /*----------------------------------------------------------------------------*/ +int knot_zone_tree_deep_copy(knot_zone_tree_t *from, + knot_zone_tree_t *to) +{ + if (to == NULL || from == NULL) { + return KNOT_EBADARG; + } + /* + * This function will copy the tree by hand, so that the nodes + * do not have to be inserted the normal way. It should be substantially + * faster. + */ + + to->th_cmp = from->th_cmp; + + return knot_zone_tree_deep_copy_node(from->th_root, &to->th_root); +} + +/*----------------------------------------------------------------------------*/ + void knot_zone_tree_free(knot_zone_tree_t **tree) { if (tree == NULL || *tree == NULL) { return; } - knot_zone_tree_free_node((*tree)->th_root, 0, 0); + knot_zone_tree_free_node((*tree)->th_root, 0); free(*tree); *tree = NULL; } /*----------------------------------------------------------------------------*/ -void knot_zone_tree_deep_free(knot_zone_tree_t **tree, int free_owners) +void knot_zone_tree_deep_free(knot_zone_tree_t **tree) { if (tree == NULL || *tree == NULL) { return; } - knot_zone_tree_free_node((*tree)->th_root, 1, free_owners); + knot_zone_tree_free_node((*tree)->th_root, 1); free(*tree); *tree = NULL; } diff --git a/src/libknot/zone/zone-tree.h b/src/libknot/zone/zone-tree.h index 0971749..ca65fe6 100644 --- a/src/libknot/zone/zone-tree.h +++ b/src/libknot/zone/zone-tree.h @@ -125,8 +125,7 @@ int knot_zone_tree_get(knot_zone_tree_t *tree, int knot_zone_tree_find_less_or_equal(knot_zone_tree_t *tree, const knot_dname_t *owner, const knot_node_t **found, - const knot_node_t **previous, - int check_version); + const knot_node_t **previous); /*! * \brief Tries to find the given domain name in the zone tree and returns the @@ -153,8 +152,7 @@ int knot_zone_tree_find_less_or_equal(knot_zone_tree_t *tree, int knot_zone_tree_get_less_or_equal(knot_zone_tree_t *tree, const knot_dname_t *owner, knot_node_t **found, - knot_node_t **previous, - int check_version); + knot_node_t **previous); /*! * \brief Removes node with the given owner from the zone tree and returns it. @@ -276,6 +274,9 @@ int knot_zone_tree_reverse_apply_postorder(knot_zone_tree_t *tree, int knot_zone_tree_shallow_copy(knot_zone_tree_t *from, knot_zone_tree_t *to); +int knot_zone_tree_deep_copy(knot_zone_tree_t *from, + knot_zone_tree_t *to); + /*! * \brief Destroys the zone tree, not touching the saved data. * @@ -290,7 +291,7 @@ void knot_zone_tree_free(knot_zone_tree_t **tree); * \param free_owners Set to <> 0 if owners of the nodes should be destroyed * as well. Set to 0 otherwise. */ -void knot_zone_tree_deep_free(knot_zone_tree_t **tree, int free_owners); +void knot_zone_tree_deep_free(knot_zone_tree_t **tree); /*----------------------------------------------------------------------------*/ diff --git a/src/libknot/zone/zonedb.c b/src/libknot/zone/zonedb.c index 8f07d45..7b445dd 100644 --- a/src/libknot/zone/zonedb.c +++ b/src/libknot/zone/zonedb.c @@ -227,15 +227,21 @@ const knot_zone_t *knot_zonedb_find_zone_for_name(knot_zonedb_t *db, } knot_zone_t dummy_zone; - dummy_zone.name = (knot_dname_t *)dname; + dummy_zone.name = knot_dname_deep_copy(dname); void *found = NULL; - int exact_match = gen_tree_find_less_or_equal(db->zone_tree, - &dummy_zone, - &found); - UNUSED(exact_match); + +// int exact_match = gen_tree_find_less_or_equal(db->zone_tree, +// &dummy_zone, +// &found); +// UNUSED(exact_match); + found = gen_tree_find(db->zone_tree, &dummy_zone); + while (found == NULL && knot_dname_label_count(dummy_zone.name) > 0) { + knot_dname_left_chop_no_copy(dummy_zone.name); + found = gen_tree_find(db->zone_tree, &dummy_zone); + } knot_zone_t *zone = (found) ? (knot_zone_t *)found : NULL; - + dbg_zonedb_exec( char *name = knot_dname_to_str(dname); dbg_zonedb("Found zone for name %s: %p\n", name, zone); @@ -247,6 +253,8 @@ dbg_zonedb_exec( zone = NULL; } + knot_dname_free(&dummy_zone.name); + return zone; } diff --git a/src/tests/common/acl_tests.c b/src/tests/common/acl_tests.c index e9af20c..a7613e7 100644 --- a/src/tests/common/acl_tests.c +++ b/src/tests/common/acl_tests.c @@ -14,6 +14,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <sys/types.h> #include <sys/socket.h> #include "tests/common/acl_tests.h" diff --git a/src/tests/common/fdset_tests.c b/src/tests/common/fdset_tests.c index 7dd95a1..08e0577 100644 --- a/src/tests/common/fdset_tests.c +++ b/src/tests/common/fdset_tests.c @@ -120,7 +120,7 @@ static int fdset_tests_run(int argc, char *argv[]) pthread_create(&t, 0, thr_action, &fds[1]); /* 4. Watch fdset. */ - ret = fdset_wait(set); + ret = fdset_wait(set, OS_EV_FOREVER); gettimeofday(&te, 0); size_t diff = timeval_diff(&ts, &te); @@ -151,7 +151,7 @@ static int fdset_tests_run(int argc, char *argv[]) close(tmpfds[1]); /* 9. Poll empty fdset. */ - ret = fdset_wait(set); + ret = fdset_wait(set, OS_EV_FOREVER); ok(ret <= 0, "fdset: polling empty fdset returns -1 (ret=%d)", ret); /* 10. Crash test. */ @@ -159,7 +159,7 @@ static int fdset_tests_run(int argc, char *argv[]) fdset_destroy(0); fdset_add(0, -1, 0); fdset_remove(0, -1); - fdset_wait(0); + fdset_wait(0, OS_EV_NOWAIT); fdset_begin(0, 0); fdset_end(0, 0); fdset_next(0, 0); diff --git a/src/tests/libknot/libknot/dname_tests.c b/src/tests/libknot/libknot/dname_tests.c index 9730756..22f6fbc 100644 --- a/src/tests/libknot/libknot/dname_tests.c +++ b/src/tests/libknot/libknot/dname_tests.c @@ -101,7 +101,7 @@ static int test_dname_create() if (dname == NULL || knot_dname_name(dname) != NULL || knot_dname_size(dname) != 0 - || knot_dname_node(dname, 0) != NULL) { + || knot_dname_node(dname) != NULL) { diag("New domain name not initialized properly!"); return 0; } @@ -161,10 +161,10 @@ static int check_domain_name(const knot_dname_t *dname, } if (check_node) { - if (knot_dname_node(dname, 0) != NODE_ADDRESS) { + if (knot_dname_node(dname) != NODE_ADDRESS) { diag("Node pointer in the created domain name is wrong:" "%p (should be %p)", - knot_dname_node(dname, 0), NODE_ADDRESS); + knot_dname_node(dname), NODE_ADDRESS); ++errors; } } @@ -719,7 +719,7 @@ static int test_dname_node(knot_dname_t **dnames_fqdn, for (int i = 0; i < TEST_DOMAINS_OK; i++) { const knot_node_t *tmp_node; - if ((tmp_node = knot_dname_node(dnames_fqdn[i], 0)) != + if ((tmp_node = knot_dname_node(dnames_fqdn[i])) != NODE_ADDRESS) { diag("Got bad node value from structure: " "%p, should be: %p", @@ -730,7 +730,7 @@ static int test_dname_node(knot_dname_t **dnames_fqdn, for (int i = 0; i < TEST_DOMAINS_NON_FQDN; i++) { const knot_node_t *tmp_node; - if ((tmp_node = knot_dname_node(dnames_non_fqdn[i], 0)) != + if ((tmp_node = knot_dname_node(dnames_non_fqdn[i])) != NODE_ADDRESS) { diag("Got bad node value from structure: " "%s, should be: %s", diff --git a/src/tests/libknot/libknot/node_tests.c b/src/tests/libknot/libknot/node_tests.c index f04a202..d6b1e48 100644 --- a/src/tests/libknot/libknot/node_tests.c +++ b/src/tests/libknot/libknot/node_tests.c @@ -76,7 +76,7 @@ static int test_node_create() errors++; diag("Failed to create node structure"); } - knot_node_free(&tmp, 0, 0); + knot_node_free(&tmp, 0); } return (errors == 0); } @@ -134,7 +134,7 @@ static int test_node_add_rrset() diag("Values in found rrset are wrong"); } - knot_node_free(&tmp, 0, 0); + knot_node_free(&tmp, 0); } return (errors == 0); @@ -166,7 +166,7 @@ static int test_node_get_rrset() diag("Failed to get proper rrset from node"); } } - knot_node_free(&nodes[i], 0, 0); + knot_node_free(&nodes[i], 0); } return (errors == 0); @@ -190,11 +190,11 @@ static int test_node_get_parent() for (int i = 0; i < TEST_NODES && !errors; i++) { rrset = &rrsets[i]; - if (knot_node_parent(nodes[i], 0) != test_nodes[i].parent) { + if (knot_node_parent(nodes[i]) != test_nodes[i].parent) { errors++; diag("Failed to get proper parent from node"); } - knot_node_free(&nodes[i], 0, 0); + knot_node_free(&nodes[i], 0); } return (errors == 0); } @@ -230,7 +230,7 @@ static int test_node_sorting() // last = *((uint16_t *)node->key); // } - knot_node_free(&tmp, 0, 0); + knot_node_free(&tmp, 0); return (errors == 0); } @@ -244,7 +244,7 @@ static int test_node_delete() tmp_node = knot_node_new(&test_nodes[i].owner, test_nodes[i].parent, 0); - knot_node_free(&tmp_node, 0, 0); + knot_node_free(&tmp_node, 0); errors += (tmp_node != NULL); } @@ -269,9 +269,9 @@ static int test_node_set_parent() diag("Parent node is wrongly set."); errors++; } - knot_node_free(&tmp_node, 0, 0); + knot_node_free(&tmp_node, 0); } - knot_node_free(&tmp_parent, 0, 0); + knot_node_free(&tmp_parent, 0); return (errors == 0); } @@ -289,7 +289,7 @@ static int test_node_free_rrsets() // errors += (tmp_node->rrsets != NULL); - knot_node_free(&tmp_node, 0, 0); + knot_node_free(&tmp_node, 0); } return (errors == 0); } diff --git a/src/tests/libknot/libknot/response_tests.c b/src/tests/libknot/libknot/response_tests.c index 93cf2df..f40bb76 100644 --- a/src/tests/libknot/libknot/response_tests.c +++ b/src/tests/libknot/libknot/response_tests.c @@ -234,7 +234,7 @@ static int test_response_add_opt() opt.size = 25; // does it matter? lives_ok({ - if (knot_response_add_opt(NULL, NULL, 0) != KNOT_EBADARG) { + if (knot_response_add_opt(NULL, NULL, 0, 0) != KNOT_EBADARG) { diag("Calling response add opt with NULL arguments " "did not result to KNOT_EBADARG"); errors++; @@ -245,7 +245,7 @@ static int test_response_add_opt() assert(response); lived = 0; if (knot_response_add_opt(response, - NULL, 0) != KNOT_EBADARG) { + NULL, 0, 0) != KNOT_EBADARG) { diag("Calling response add opt with NULL OPT RR " "did not result to KNOT_EBADARG"); errors++; @@ -254,7 +254,7 @@ static int test_response_add_opt() lived = 0; if (knot_response_add_opt(NULL, - &opt, 0) != KNOT_EBADARG) { + &opt, 0, 0) != KNOT_EBADARG) { diag("Calling response add opt with NULL response " "did not result to KNOT_EBADARG"); errors++; @@ -270,21 +270,21 @@ static int test_response_add_opt() knot_packet_set_max_size(response, KNOT_PACKET_PREALLOC_RESPONSE * 100); assert(knot_response_init(response) == KNOT_EOK);; - if (knot_response_add_opt(response, &opt, 0) != KNOT_EOK) { + if (knot_response_add_opt(response, &opt, 0, 0) != KNOT_EOK) { diag("Adding valid OPT RR to response " "did not return KNOT_EOK"); errors++; } opt.payload = response->max_size + 1; - if (knot_response_add_opt(response, &opt, 1) != KNOT_EPAYLOAD) { + if (knot_response_add_opt(response, &opt, 1, 0) != KNOT_EPAYLOAD) { diag("If OPT RR payload is bigger than response max size " "response_add_opt does not return KNOT_EPAYLOAD!"); errors++; } opt.payload = 0; - if (knot_response_add_opt(response, &opt, 1) != KNOT_EBADARG) { + if (knot_response_add_opt(response, &opt, 1, 0) != KNOT_EBADARG) { diag("Calling response_add_opt with OPT RR payload set to 0 " "did not return KNOT_EBADARG"); } @@ -294,14 +294,14 @@ static int test_response_add_opt() } static int test_response_add_generic(int (*func)(knot_packet_t *, - const knot_rrset_t *, - int, int, int)) + knot_rrset_t *, + int, int, int, int)) { int errors = 0; int lived = 0; lives_ok({ - if (func(NULL, NULL, 0, 0, 0) != KNOT_EBADARG) { + if (func(NULL, NULL, 0, 0, 0, 0) != KNOT_EBADARG) { diag("Calling response add rrset with NULL " "arguments did not return KNOT_EBADARG!"); errors++; @@ -311,7 +311,7 @@ static int test_response_add_generic(int (*func)(knot_packet_t *, knot_packet_new(KNOT_PACKET_PREALLOC_RESPONSE); assert(response); lived = 0; - if (func(response, NULL, 0, 0, 0) != KNOT_EBADARG) { + if (func(response, NULL, 0, 0, 0, 0) != KNOT_EBADARG) { diag("Calling response add rrset with NULL rrset " "did not return KNOT_EBADARG!"); errors++; @@ -327,7 +327,7 @@ static int test_response_add_generic(int (*func)(knot_packet_t *, KNOT_CLASS_IN, 3600); assert(rrset); lived = 0; - if (func(NULL, rrset, 0, 0, 0) != KNOT_EBADARG) { + if (func(NULL, rrset, 0, 0, 0, 0) != KNOT_EBADARG) { diag("Calling response add rrset with NULL response " "did not return KNOT_EBADARG!"); errors++; @@ -354,7 +354,7 @@ static int test_response_add_generic(int (*func)(knot_packet_t *, knot_rrset_new(owner, KNOT_RRTYPE_NS, KNOT_CLASS_IN, 3600); assert(rrset); - if (func(response, rrset, 0, 0, 0) != KNOT_EOK) { + if (func(response, rrset, 0, 0, 0, 0) != KNOT_EOK) { diag("Adding valid RRSet to response did not result to " "KNOT_EOK"); errors++; diff --git a/src/tests/libknot/libknot/tsig_tests.c b/src/tests/libknot/libknot/tsig_tests.c index e8cab14..31720ec 100644 --- a/src/tests/libknot/libknot/tsig_tests.c +++ b/src/tests/libknot/libknot/tsig_tests.c @@ -23,6 +23,7 @@ #include "libknot/util/error.h" #include "libknot/util/wire.h" #include "libknot/tsig-op.h" +#include "common/print.h" #include "tsig_tests.h" @@ -239,8 +240,8 @@ static int test_knot_tsig_sign() knot_wire_set_arcount(msg, 0); /* Wire now should be identical. Compare with its pre-signing copy. */ if (strncmp((char *)msg, (char *)msg_copy, msg_len) != 0) { - hex_print(msg, msg_len); - hex_print(msg_copy, msg_len); + hex_print((const char*)msg, msg_len); + hex_print((const char*)msg_copy, msg_len); diag("knot_tsig_sign has changed the signed wire!"); errors++; } @@ -267,8 +268,8 @@ static int test_knot_tsig_sign() knot_wire_set_arcount(msg, 0); /* Wire now should be identical. Compare with its pre-signing copy. */ if (strncmp((char *)msg, (char *)msg_copy, msg_len) != 0) { - hex_print(msg, msg_len); - hex_print(msg_copy, msg_len); + hex_print((const char*)msg, msg_len); + hex_print((const char*)msg_copy, msg_len); diag("knot_tsig_sign has changed the signed wire!"); errors++; } diff --git a/src/tests/libknot/libknot/zone_tests.c b/src/tests/libknot/libknot/zone_tests.c index 2fdd61a..192996c 100644 --- a/src/tests/libknot/libknot/zone_tests.c +++ b/src/tests/libknot/libknot/zone_tests.c @@ -95,13 +95,13 @@ static int test_zone_create(knot_zone_contents_t **zone) if ((*zone) == NULL) { diag("zone: Failed to create zone."); - knot_node_free(&node, 1, 0); + knot_node_free(&node, 0); return 0; } if ((*zone)->apex != node) { diag("zone: Zone apex not set right."); - knot_node_free(&node, 1, 0); + knot_node_free(&node, 0); return 0; } @@ -133,7 +133,7 @@ static int test_zone_add_node(knot_zone_contents_t *zone, int nsec3) : knot_zone_contents_add_node(zone, node, 0, 0, 0))) != 0) { diag("zone: Failed to insert node into zone (returned" " %d).", res); - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); ++errors; } /* TODO check values in the node as well */ @@ -157,7 +157,7 @@ static int test_zone_add_node(knot_zone_contents_t *zone, int nsec3) KNOT_EBADZONE); ++errors; } - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); } //note("NULL zone"); @@ -179,7 +179,7 @@ static int test_zone_add_node(knot_zone_contents_t *zone, int nsec3) ++errors; } - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); //note("NULL node"); note("Inserting NULL node...\n"); @@ -211,7 +211,7 @@ static int test_zone_add_node(knot_zone_contents_t *zone, int nsec3) ++errors; } - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); } // check if all nodes are inserted diff --git a/src/tests/libknot/libknot/zone_tree_tests.c b/src/tests/libknot/libknot/zone_tree_tests.c index c26746e..207afea 100644 --- a/src/tests/libknot/libknot/zone_tree_tests.c +++ b/src/tests/libknot/libknot/zone_tree_tests.c @@ -238,14 +238,14 @@ static int test_tree_finding_less_or_equal() if (knot_zone_tree_find_less_or_equal(NULL, NULL, NULL, - NULL, 0) != + NULL) != KNOT_EBADARG) { errors++; } lived = 1; lived = 0; if (knot_zone_tree_find_less_or_equal(tree, NULL, - NULL, NULL, 0) != + NULL, NULL) != KNOT_EBADARG) { errors++; } @@ -254,7 +254,7 @@ static int test_tree_finding_less_or_equal() if (knot_zone_tree_find_less_or_equal(tree, node->owner, NULL, - NULL, 0) != + NULL) != KNOT_EBADARG) { errors++; } @@ -262,7 +262,7 @@ static int test_tree_finding_less_or_equal() const knot_node_t *found_node = NULL; lived = 0; if (knot_zone_tree_find_less_or_equal(NULL, node->owner, - &found_node, NULL, 0) != + &found_node, NULL) != KNOT_EBADARG) { errors++; } @@ -271,7 +271,7 @@ static int test_tree_finding_less_or_equal() lived = 0; if (knot_zone_tree_find_less_or_equal(tree, NULL, &found_node, - &previous_node, 0) != + &previous_node) != KNOT_EBADARG) { errors++; } @@ -296,7 +296,7 @@ static int test_tree_finding_less_or_equal() if (knot_zone_tree_find_less_or_equal(tree, node->owner, &found_node, - &previous_node, 0) <= 0) { + &previous_node) <= 0) { diag("Calling zone tree find less with valid arguments did " "not return KNOT_EOK"); errors++; @@ -309,8 +309,8 @@ static int test_tree_finding_less_or_equal() if (knot_zone_tree_get_less_or_equal(tree, node->owner, (knot_node_t **)&found_node, - (knot_node_t **)&previous_node, 0) <= - 0) { + (knot_node_t **)&previous_node) + <= 0) { diag("Calling zone tree get less with valid arguments did " "not return KNOT_EOK"); errors++; @@ -331,7 +331,7 @@ static int test_tree_finding_less_or_equal() if (knot_zone_tree_find_less_or_equal(tree, less_dname, &found_node, - &previous_node, 0) <= 0) { + &previous_node) <= 0) { diag("Calling zone tree find less or equal " "with valid arguments did " "not return > 0"); @@ -345,8 +345,8 @@ static int test_tree_finding_less_or_equal() if (knot_zone_tree_get_less_or_equal(tree, less_dname, (knot_node_t **)&found_node, - (knot_node_t **)&previous_node, 0) <= - 0) { + (knot_node_t **)&previous_node) + <= 0) { diag("Calling zone tree less or equal with valid arguments did " "not return > 0"); errors++; @@ -365,7 +365,7 @@ static int test_tree_finding_less_or_equal() if (knot_zone_tree_find_less_or_equal(tree, alien_dname, &found_node, - &previous_node, 0) != + &previous_node) != 0) { diag("Calling zone tree find less with valid arguments did " "not return 0"); @@ -375,8 +375,8 @@ static int test_tree_finding_less_or_equal() if (knot_zone_tree_get_less_or_equal(tree, alien_dname, (knot_node_t **)&found_node, - (knot_node_t **)&previous_node, 0) != - 0) { + (knot_node_t **)&previous_node) + != 0) { diag("Calling zone tree get with valid arguments did " "not return 0"); errors++; @@ -392,7 +392,7 @@ static int test_tree_finding_less_or_equal() if (knot_zone_tree_find_less_or_equal(tree, node->owner, &found_node, - &previous_node, 0) <= + &previous_node) <= 0) { diag("Calling zone tree find with valid arguments did " "not return > 0"); @@ -407,8 +407,8 @@ static int test_tree_finding_less_or_equal() if (knot_zone_tree_get_less_or_equal(tree, node->owner, (knot_node_t **)&found_node, - (knot_node_t **)&previous_node, 0) <= - 0) { + (knot_node_t **)&previous_node) + <= 0) { diag("Calling zone tree get with valid arguments did " "not return > 0"); errors++; diff --git a/src/tests/libknot/realdata/libknot/node_tests_realdata.c b/src/tests/libknot/realdata/libknot/node_tests_realdata.c index 3218c8e..b9415ef 100644 --- a/src/tests/libknot/realdata/libknot/node_tests_realdata.c +++ b/src/tests/libknot/realdata/libknot/node_tests_realdata.c @@ -94,7 +94,7 @@ static int test_node_create(const list *node_list) errors++; diag("Failed to create node structure"); } - knot_node_free(&tmp, 0, 0); + knot_node_free(&tmp, 0); } return (errors == 0); @@ -168,7 +168,7 @@ static int test_node_add_rrset(list *rrset_list) diag("Values in found rrset are wrong"); } - knot_node_free(&tmp, 1, 0); + knot_node_free(&tmp, 0); } return (errors == 0); diff --git a/src/tests/libknot/realdata/libknot/response_tests_realdata.c b/src/tests/libknot/realdata/libknot/response_tests_realdata.c index 5bbda36..7dac341 100644 --- a/src/tests/libknot/realdata/libknot/response_tests_realdata.c +++ b/src/tests/libknot/realdata/libknot/response_tests_realdata.c @@ -105,8 +105,8 @@ static int test_response_init_from_query(list query_list) extern knot_rrset_t *rrset_from_test_rrset(test_rrset_t *test_rrset); static int test_response_add_generic(int (*func)(knot_packet_t *, - const knot_rrset_t *, - int, int, int), + knot_rrset_t *, + int, int, int, int), list rrset_list) { /*!< \todo Now adding only one RRSet at the time, try more, use nodes */ @@ -125,7 +125,7 @@ static int test_response_add_generic(int (*func)(knot_packet_t *, assert(rrset); int ret = 0; - if ((ret = func(response, rrset, 0, 1, 0)) != KNOT_EOK) { + if ((ret = func(response, rrset, 0, 1, 0, 0)) != KNOT_EOK) { diag("Could not add RRSet to response! Returned: %d", ret); diag("(owner: %s type %s)", diff --git a/src/tests/libknot/realdata/libknot/zone_tests_realdata.c b/src/tests/libknot/realdata/libknot/zone_tests_realdata.c index 445997f..2738dab 100644 --- a/src/tests/libknot/realdata/libknot/zone_tests_realdata.c +++ b/src/tests/libknot/realdata/libknot/zone_tests_realdata.c @@ -77,7 +77,7 @@ static int test_zone_create(list node_list) errors++; } knot_node_free_rrsets(node, 1); - knot_node_free(&node, 0, 0); + knot_node_free(&node, 0); } return (errors == 0); diff --git a/src/tests/xfr_tests.c b/src/tests/xfr_tests.c index 8a0b703..9ea19fe 100644 --- a/src/tests/xfr_tests.c +++ b/src/tests/xfr_tests.c @@ -21,7 +21,6 @@ * - signal handler now handles one more signal * SIGCONT is used to signal this * binary that an integrity check should be done - * - once the integrity check is completed, the server signal the script */ #include <time.h> @@ -46,10 +45,8 @@ static volatile short sig_req_stop = 0; static volatile short sig_req_reload = 0; static volatile short sig_stopping = 0; +static volatile short sig_integrity_check = 0; -/* Global PID of invoking script. */ -static pid_t script_pid; -static const char *zone; // SIGINT signal handler void interrupt_handle(int s) @@ -73,12 +70,8 @@ void interrupt_handle(int s) // Start zone integrity check if (s == SIGCONT) { - /*!< \todo Insert actual integrity check! */ - if (1) { - kill(script_pid, SIGCONT); - } else { - kill(script_pid, SIGHUP); - } + sig_integrity_check = 1; + return; } } @@ -88,6 +81,7 @@ void help(int argc, char **argv) PACKAGE_NAME); printf("Parameters:\n" " -c, --config [file] Select configuration file.\n" + " -z, --zone [origin] Inspected zone origin.\n" " -d, --daemonize Run server as a daemon.\n" " -v, --verbose Verbose mode - additional runtime information.\n" " -V, --version Print version of the server.\n" @@ -97,15 +91,17 @@ void help(int argc, char **argv) int main(int argc, char **argv) { // Parse command line arguments + int check_iteration = 0; int c = 0, li = 0; int verbose = 0; int daemonize = 0; - char* config_fn = 0; + char* config_fn = NULL; + char *zone = NULL; /* Long options. */ struct option opts[] = { {"config", required_argument, 0, 'c'}, - {"script_pid",required_argument, 0, 'p'}, + {"zone", required_argument, 0, 'z'}, {"daemonize", no_argument, 0, 'd'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, @@ -113,7 +109,7 @@ int main(int argc, char **argv) {0, 0, 0, 0} }; - while ((c = getopt_long(argc, argv, "c:p:dvVh", opts, &li)) != -1) { + while ((c = getopt_long(argc, argv, "c:z:dvVh", opts, &li)) != -1) { switch (c) { case 'c': @@ -128,9 +124,6 @@ int main(int argc, char **argv) case 'V': printf("%s, version %s\n", "Knot DNS", PACKAGE_VERSION); return 0; - case 'p': - script_pid = atoi(optarg); - break; case 'z': zone = strdup(optarg); break; @@ -144,7 +137,9 @@ int main(int argc, char **argv) // Now check if we want to daemonize if (daemonize) { - if (daemon(1, 0) != 0) { + if (daemon(1, 0) != 0) { + free(zone); + free(config_fn); fprintf(stderr, "Daemonization failed, " "shutting down...\n"); return 1; @@ -214,11 +209,16 @@ int main(int argc, char **argv) } // Open configuration - log_server_info("Parsing configuration '%s' ...\n", config_fn); - if (conf_open(config_fn) != KNOTD_EOK) { - - log_server_error("Failed to parse configuration file '%s'.\n", - config_fn); + log_server_info("Reading configuration '%s' ...\n", config_fn); + int conf_ret = conf_open(config_fn); + if (conf_ret != KNOTD_EOK) { + if (conf_ret == KNOTD_ENOENT) { + log_server_error("Couldn't open configuration file " + "'%s'.\n", config_fn); + } else { + log_server_error("Failed to parse configuration '%s'.\n", + config_fn); + } server_destroy(&server); free(config_fn); return 1; @@ -313,6 +313,17 @@ int main(int argc, char **argv) break; } } + if (zone == NULL) sig_integrity_check = 0; + if (sig_integrity_check) { + log_server_info("Starting integrity check of zone: %s\n", zone); + knot_dname_t* zdn = knot_dname_new_from_str(zone, strlen(zone), NULL); + knot_zone_t *z = knot_zonedb_find_zone(server->nameserver->zone_db, zdn); + int ic_ret = knot_zone_contents_integrity_check(z->contents); + log_server_info("Integrity check: %d errors discovered.\n", ic_ret); + knot_dname_free(&zdn); + log_server_info("Integrity check %d finished.\n", check_iteration); + ++check_iteration; + } /* Events. */ if (ret > 0) { @@ -357,6 +368,7 @@ int main(int argc, char **argv) evqueue_free(&q); // Free default config filename if exists + free(zone); free(config_fn); if (!daemonize) { diff --git a/src/zcompile/zcompile.c b/src/zcompile/zcompile.c index 7038cd4..f02fdcf 100644 --- a/src/zcompile/zcompile.c +++ b/src/zcompile/zcompile.c @@ -527,7 +527,7 @@ int zone_read(const char *name, const char *zonefile, const char *outfile, //assert(origin_node->next == NULL); - assert(knot_node_parent(origin_node, 0) == NULL); + assert(knot_node_parent(origin_node) == NULL); if (origin_node == NULL) { knot_dname_release(dname); return KNOTDZCOMPILE_ENOMEM; @@ -609,7 +609,8 @@ int zone_read(const char *name, const char *zonefile, const char *outfile, parser->errors++; } - knot_zone_contents_adjust(contents, 0); + /*! \todo Check return value. */ + knot_zone_contents_adjust(contents); dbg_zp("rdata adjusted\n"); |