diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 19:05:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 19:05:44 +0000 |
commit | b045529c40c83601909dca7b76a53498e9a70f33 (patch) | |
tree | 88371572105933fd950676c07b3a12163a0c9de0 /tests | |
parent | Initial commit. (diff) | |
download | knot-b045529c40c83601909dca7b76a53498e9a70f33.tar.xz knot-b045529c40c83601909dca7b76a53498e9a70f33.zip |
Adding upstream version 3.3.4.upstream/3.3.4
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests')
341 files changed, 35290 insertions, 0 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..eb6f1aa --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,247 @@ +AM_CPPFLAGS = \ + -include $(top_builddir)/src/config.h \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/libdnssec \ + -I$(top_srcdir)/src/libdnssec/shared \ + $(gnutls_CFLAGS) \ + $(libkqueue_CFLAGS) \ + $(lmdb_CFLAGS) + +LDADD = \ + libtap.la + +if HAVE_DAEMON +LDADD += \ + $(top_builddir)/src/libknotd.la \ + $(liburcu_LIBS) \ + $(systemd_LIBS) +endif HAVE_DAEMON + +LDADD += \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la \ + $(gnutls_LIBS) \ + $(lmdb_LIBS) + +EXTRA_DIST = \ + tap/libtap.sh \ + libdnssec/sample_keys.h \ + knot/semantic_check_data \ + knot/test_semantic_check.in \ + libzscanner/data \ + libzscanner/test_zscanner.in \ + libzscanner/TESTS + +check_LTLIBRARIES = libtap.la + +libtap_la_SOURCES = \ + tap/basic.c \ + tap/basic.h \ + tap/files.c \ + tap/files.h \ + tap/float.c \ + tap/float.h \ + tap/macros.h + +EXTRA_PROGRAMS = tap/runtests + +check_PROGRAMS = \ + contrib/test_base32hex \ + contrib/test_base64 \ + contrib/test_base64url \ + contrib/test_heap \ + contrib/test_inet_ntop \ + contrib/test_net \ + contrib/test_net_shortwrite \ + contrib/test_qp-trie \ + contrib/test_qp-cow \ + contrib/test_siphash \ + contrib/test_sockaddr \ + contrib/test_spinlock \ + contrib/test_string \ + contrib/test_strtonum \ + contrib/test_time \ + contrib/test_toeplitz \ + contrib/test_wire_ctx + +check_PROGRAMS += \ + libdnssec/test_binary \ + libdnssec/test_crypto \ + libdnssec/test_key \ + libdnssec/test_key_algorithm \ + libdnssec/test_key_ds \ + libdnssec/test_keyid \ + libdnssec/test_keystore_pkcs11 \ + libdnssec/test_keystore_pkcs8 \ + libdnssec/test_keytag \ + libdnssec/test_nsec_bitmap \ + libdnssec/test_nsec_hash \ + libdnssec/test_random \ + libdnssec/test_sign \ + libdnssec/test_sign_der \ + libdnssec/test_shared_bignum \ + libdnssec/test_shared_dname \ + libdnssec/test_tsig + +if HAVE_DAEMON +check_PROGRAMS += \ + knot/test_acl \ + knot/test_changeset \ + knot/test_conf \ + knot/test_conf_tools \ + knot/test_confdb \ + knot/test_confio \ + knot/test_digest \ + knot/test_dthreads \ + knot/test_fdset \ + knot/test_journal \ + knot/test_kasp_db \ + knot/test_node \ + knot/test_process_query \ + knot/test_query_module \ + knot/test_requestor \ + knot/test_server \ + knot/test_unreachable \ + knot/test_worker_pool \ + knot/test_worker_queue \ + knot/test_zone-tree \ + knot/test_zone-update \ + knot/test_zone_events \ + knot/test_zone_serial \ + knot/test_zone_timers \ + knot/test_zonedb + +knot_test_acl_SOURCES = \ + knot/test_acl.c \ + knot/test_conf.h + +knot_test_conf_SOURCES = \ + knot/test_conf.c \ + knot/test_conf.h + +knot_test_confdb_SOURCES = \ + knot/test_confdb.c \ + knot/test_conf.h + +knot_test_confio_SOURCES = \ + knot/test_confio.c \ + knot/test_conf.h + +knot_test_process_query_SOURCES = \ + knot/test_process_query.c \ + knot/test_server.h \ + knot/test_conf.h +endif HAVE_DAEMON + +check_PROGRAMS += \ + libknot/test_control \ + libknot/test_cookies \ + libknot/test_db \ + libknot/test_descriptor \ + libknot/test_dname \ + libknot/test_dynarray \ + libknot/test_edns \ + libknot/test_edns_ecs \ + libknot/test_endian \ + libknot/test_lookup \ + libknot/test_pkt \ + libknot/test_probe \ + libknot/test_rdata \ + libknot/test_rdataset \ + libknot/test_rrset \ + libknot/test_rrset-wire \ + libknot/test_tsig \ + libknot/test_yparser \ + libknot/test_ypschema \ + libknot/test_yptrafo \ + libknot/test_wire + +if ENABLE_XDP +AM_CPPFLAGS += $(libbpf_CFLAGS) +check_PROGRAMS += \ + libknot/test_xdp_tcp +endif ENABLE_XDP + +if HAVE_LIBUTILS +check_PROGRAMS += \ + utils/test_lookup +endif HAVE_LIBUTILS + +if HAVE_DAEMON +if STATIC_MODULE_onlinesign +check_PROGRAMS += \ + modules/test_onlinesign +else +if SHARED_MODULE_onlinesign +check_PROGRAMS += \ + modules/test_onlinesign +endif +endif + +if STATIC_MODULE_rrl +check_PROGRAMS += \ + modules/test_rrl +else +if SHARED_MODULE_rrl +check_PROGRAMS += \ + modules/test_rrl +endif +endif +endif HAVE_DAEMON + +libdnssec_test_keystore_pkcs11_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -DLIBDIR='"$(libdir)"' + +if HAVE_LIBUTILS +utils_test_lookup_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(libedit_CFLAGS) + +utils_test_lookup_LDADD = \ + $(top_builddir)/src/libknotus.la \ + $(libedit_LIBS) \ + $(LDADD) +endif HAVE_LIBUTILS + +EXTRA_PROGRAMS += libzscanner/zscanner-tool + +libzscanner_zscanner_tool_SOURCES = \ + libzscanner/zscanner-tool.c \ + libzscanner/processing.h \ + libzscanner/processing.c + +check_SCRIPTS = \ + libzscanner/test_zscanner + +edit = $(SED) \ + -e 's|@top_srcdir[@]|$(abs_top_srcdir)|g' \ + -e 's|@top_builddir[@]|$(abs_top_builddir)|g' + +if HAVE_LIBUTILS +check_SCRIPTS += \ + knot/test_semantic_check + +knot/test_semantic_check: + @$(edit) < $(top_srcdir)/tests/$@.in > $(top_builddir)/tests/$@ + @chmod +x $(top_builddir)/tests/$@ +endif HAVE_LIBUTILS + +libzscanner/test_zscanner: libzscanner/zscanner-tool + @$(edit) < $(top_srcdir)/tests/$@.in > $(top_builddir)/tests/$@ + @chmod +x $(top_builddir)/tests/$@ + +CLEANFILES = $(check_SCRIPTS) $(EXTRA_PROGRAMS) runtests.log + +check-compile: $(check_LTLIBRARIES) $(EXTRA_PROGRAMS) $(check_PROGRAMS) $(check_SCRIPTS) + +AM_V_RUNTESTS = $(am__v_RUNTESTS_@AM_V@) +am__v_RUNTESTS_ = $(am__v_RUNTESTS_@AM_DEFAULT_V@) +am__v_RUNTESTS_0 = +am__v_RUNTESTS_1 = RET=$$?; if [ "$$RET" != "0" ]; then cat "$(builddir)/runtests.log"; exit $$RET; fi +check-local: $(check_LTLIBRARIES) $(EXTRA_PROGRAMS) $(check_PROGRAMS) $(check_SCRIPTS) + @$(top_builddir)/tests/tap/runtests -s $(srcdir) -b $(builddir) \ + -L $(builddir)/runtests.log $(check_PROGRAMS) $(check_SCRIPTS); \ + $(AM_V_RUNTESTS) diff --git a/tests/Makefile.in b/tests/Makefile.in new file mode 100644 index 0000000..b02c209 --- /dev/null +++ b/tests/Makefile.in @@ -0,0 +1,2769 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@HAVE_DAEMON_TRUE@am__append_1 = \ +@HAVE_DAEMON_TRUE@ $(top_builddir)/src/libknotd.la \ +@HAVE_DAEMON_TRUE@ $(liburcu_LIBS) \ +@HAVE_DAEMON_TRUE@ $(systemd_LIBS) + +EXTRA_PROGRAMS = tap/runtests$(EXEEXT) \ + libzscanner/zscanner-tool$(EXEEXT) +check_PROGRAMS = contrib/test_base32hex$(EXEEXT) \ + contrib/test_base64$(EXEEXT) contrib/test_base64url$(EXEEXT) \ + contrib/test_heap$(EXEEXT) contrib/test_inet_ntop$(EXEEXT) \ + contrib/test_net$(EXEEXT) contrib/test_net_shortwrite$(EXEEXT) \ + contrib/test_qp-trie$(EXEEXT) contrib/test_qp-cow$(EXEEXT) \ + contrib/test_siphash$(EXEEXT) contrib/test_sockaddr$(EXEEXT) \ + contrib/test_spinlock$(EXEEXT) contrib/test_string$(EXEEXT) \ + contrib/test_strtonum$(EXEEXT) contrib/test_time$(EXEEXT) \ + contrib/test_toeplitz$(EXEEXT) contrib/test_wire_ctx$(EXEEXT) \ + libdnssec/test_binary$(EXEEXT) libdnssec/test_crypto$(EXEEXT) \ + libdnssec/test_key$(EXEEXT) \ + libdnssec/test_key_algorithm$(EXEEXT) \ + libdnssec/test_key_ds$(EXEEXT) libdnssec/test_keyid$(EXEEXT) \ + libdnssec/test_keystore_pkcs11$(EXEEXT) \ + libdnssec/test_keystore_pkcs8$(EXEEXT) \ + libdnssec/test_keytag$(EXEEXT) \ + libdnssec/test_nsec_bitmap$(EXEEXT) \ + libdnssec/test_nsec_hash$(EXEEXT) \ + libdnssec/test_random$(EXEEXT) libdnssec/test_sign$(EXEEXT) \ + libdnssec/test_sign_der$(EXEEXT) \ + libdnssec/test_shared_bignum$(EXEEXT) \ + libdnssec/test_shared_dname$(EXEEXT) \ + libdnssec/test_tsig$(EXEEXT) $(am__EXEEXT_1) \ + libknot/test_control$(EXEEXT) libknot/test_cookies$(EXEEXT) \ + libknot/test_db$(EXEEXT) libknot/test_descriptor$(EXEEXT) \ + libknot/test_dname$(EXEEXT) libknot/test_dynarray$(EXEEXT) \ + libknot/test_edns$(EXEEXT) libknot/test_edns_ecs$(EXEEXT) \ + libknot/test_endian$(EXEEXT) libknot/test_lookup$(EXEEXT) \ + libknot/test_pkt$(EXEEXT) libknot/test_probe$(EXEEXT) \ + libknot/test_rdata$(EXEEXT) libknot/test_rdataset$(EXEEXT) \ + libknot/test_rrset$(EXEEXT) libknot/test_rrset-wire$(EXEEXT) \ + libknot/test_tsig$(EXEEXT) libknot/test_yparser$(EXEEXT) \ + libknot/test_ypschema$(EXEEXT) libknot/test_yptrafo$(EXEEXT) \ + libknot/test_wire$(EXEEXT) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \ + $(am__EXEEXT_7) +@HAVE_DAEMON_TRUE@am__append_2 = \ +@HAVE_DAEMON_TRUE@ knot/test_acl \ +@HAVE_DAEMON_TRUE@ knot/test_changeset \ +@HAVE_DAEMON_TRUE@ knot/test_conf \ +@HAVE_DAEMON_TRUE@ knot/test_conf_tools \ +@HAVE_DAEMON_TRUE@ knot/test_confdb \ +@HAVE_DAEMON_TRUE@ knot/test_confio \ +@HAVE_DAEMON_TRUE@ knot/test_digest \ +@HAVE_DAEMON_TRUE@ knot/test_dthreads \ +@HAVE_DAEMON_TRUE@ knot/test_fdset \ +@HAVE_DAEMON_TRUE@ knot/test_journal \ +@HAVE_DAEMON_TRUE@ knot/test_kasp_db \ +@HAVE_DAEMON_TRUE@ knot/test_node \ +@HAVE_DAEMON_TRUE@ knot/test_process_query \ +@HAVE_DAEMON_TRUE@ knot/test_query_module \ +@HAVE_DAEMON_TRUE@ knot/test_requestor \ +@HAVE_DAEMON_TRUE@ knot/test_server \ +@HAVE_DAEMON_TRUE@ knot/test_unreachable \ +@HAVE_DAEMON_TRUE@ knot/test_worker_pool \ +@HAVE_DAEMON_TRUE@ knot/test_worker_queue \ +@HAVE_DAEMON_TRUE@ knot/test_zone-tree \ +@HAVE_DAEMON_TRUE@ knot/test_zone-update \ +@HAVE_DAEMON_TRUE@ knot/test_zone_events \ +@HAVE_DAEMON_TRUE@ knot/test_zone_serial \ +@HAVE_DAEMON_TRUE@ knot/test_zone_timers \ +@HAVE_DAEMON_TRUE@ knot/test_zonedb + +@ENABLE_XDP_TRUE@am__append_3 = $(libbpf_CFLAGS) +@ENABLE_XDP_TRUE@am__append_4 = \ +@ENABLE_XDP_TRUE@ libknot/test_xdp_tcp + +@HAVE_LIBUTILS_TRUE@am__append_5 = \ +@HAVE_LIBUTILS_TRUE@ utils/test_lookup + +@HAVE_DAEMON_TRUE@@STATIC_MODULE_onlinesign_TRUE@am__append_6 = \ +@HAVE_DAEMON_TRUE@@STATIC_MODULE_onlinesign_TRUE@ modules/test_onlinesign + +@HAVE_DAEMON_TRUE@@SHARED_MODULE_onlinesign_TRUE@@STATIC_MODULE_onlinesign_FALSE@am__append_7 = \ +@HAVE_DAEMON_TRUE@@SHARED_MODULE_onlinesign_TRUE@@STATIC_MODULE_onlinesign_FALSE@ modules/test_onlinesign + +@HAVE_DAEMON_TRUE@@STATIC_MODULE_rrl_TRUE@am__append_8 = \ +@HAVE_DAEMON_TRUE@@STATIC_MODULE_rrl_TRUE@ modules/test_rrl + +@HAVE_DAEMON_TRUE@@SHARED_MODULE_rrl_TRUE@@STATIC_MODULE_rrl_FALSE@am__append_9 = \ +@HAVE_DAEMON_TRUE@@SHARED_MODULE_rrl_TRUE@@STATIC_MODULE_rrl_FALSE@ modules/test_rrl + +@HAVE_LIBUTILS_TRUE@am__append_10 = \ +@HAVE_LIBUTILS_TRUE@ knot/test_semantic_check + +subdir = tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4/ax_check_link_flag.m4 \ + $(top_srcdir)/m4/code-coverage.m4 \ + $(top_srcdir)/m4/knot-lib-version.m4 \ + $(top_srcdir)/m4/knot-module.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/sanitizer.m4 $(top_srcdir)/m4/visibility.m4 \ + $(top_srcdir)/m4/knot-version.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@HAVE_DAEMON_TRUE@am__EXEEXT_1 = knot/test_acl$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_changeset$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_conf$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_conf_tools$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_confdb$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_confio$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_digest$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_dthreads$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_fdset$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_journal$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_kasp_db$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_node$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_process_query$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_query_module$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_requestor$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_server$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_unreachable$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_worker_pool$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_worker_queue$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zone-tree$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zone-update$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zone_events$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zone_serial$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zone_timers$(EXEEXT) \ +@HAVE_DAEMON_TRUE@ knot/test_zonedb$(EXEEXT) +@ENABLE_XDP_TRUE@am__EXEEXT_2 = libknot/test_xdp_tcp$(EXEEXT) +@HAVE_LIBUTILS_TRUE@am__EXEEXT_3 = utils/test_lookup$(EXEEXT) +@HAVE_DAEMON_TRUE@@STATIC_MODULE_onlinesign_TRUE@am__EXEEXT_4 = modules/test_onlinesign$(EXEEXT) +@HAVE_DAEMON_TRUE@@SHARED_MODULE_onlinesign_TRUE@@STATIC_MODULE_onlinesign_FALSE@am__EXEEXT_5 = modules/test_onlinesign$(EXEEXT) +@HAVE_DAEMON_TRUE@@STATIC_MODULE_rrl_TRUE@am__EXEEXT_6 = modules/test_rrl$(EXEEXT) +@HAVE_DAEMON_TRUE@@SHARED_MODULE_rrl_TRUE@@STATIC_MODULE_rrl_FALSE@am__EXEEXT_7 = modules/test_rrl$(EXEEXT) +libtap_la_LIBADD = +am__dirstamp = $(am__leading_dot)dirstamp +am_libtap_la_OBJECTS = tap/basic.lo tap/files.lo tap/float.lo +libtap_la_OBJECTS = $(am_libtap_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +contrib_test_base32hex_SOURCES = contrib/test_base32hex.c +contrib_test_base32hex_OBJECTS = contrib/test_base32hex.$(OBJEXT) +contrib_test_base32hex_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +@HAVE_DAEMON_TRUE@am__DEPENDENCIES_2 = \ +@HAVE_DAEMON_TRUE@ $(top_builddir)/src/libknotd.la \ +@HAVE_DAEMON_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +contrib_test_base32hex_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_base64_SOURCES = contrib/test_base64.c +contrib_test_base64_OBJECTS = contrib/test_base64.$(OBJEXT) +contrib_test_base64_LDADD = $(LDADD) +contrib_test_base64_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_base64url_SOURCES = contrib/test_base64url.c +contrib_test_base64url_OBJECTS = contrib/test_base64url.$(OBJEXT) +contrib_test_base64url_LDADD = $(LDADD) +contrib_test_base64url_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_heap_SOURCES = contrib/test_heap.c +contrib_test_heap_OBJECTS = contrib/test_heap.$(OBJEXT) +contrib_test_heap_LDADD = $(LDADD) +contrib_test_heap_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_inet_ntop_SOURCES = contrib/test_inet_ntop.c +contrib_test_inet_ntop_OBJECTS = contrib/test_inet_ntop.$(OBJEXT) +contrib_test_inet_ntop_LDADD = $(LDADD) +contrib_test_inet_ntop_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_net_SOURCES = contrib/test_net.c +contrib_test_net_OBJECTS = contrib/test_net.$(OBJEXT) +contrib_test_net_LDADD = $(LDADD) +contrib_test_net_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_net_shortwrite_SOURCES = contrib/test_net_shortwrite.c +contrib_test_net_shortwrite_OBJECTS = \ + contrib/test_net_shortwrite.$(OBJEXT) +contrib_test_net_shortwrite_LDADD = $(LDADD) +contrib_test_net_shortwrite_DEPENDENCIES = libtap.la \ + $(am__DEPENDENCIES_2) $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_qp_cow_SOURCES = contrib/test_qp-cow.c +contrib_test_qp_cow_OBJECTS = contrib/test_qp-cow.$(OBJEXT) +contrib_test_qp_cow_LDADD = $(LDADD) +contrib_test_qp_cow_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_qp_trie_SOURCES = contrib/test_qp-trie.c +contrib_test_qp_trie_OBJECTS = contrib/test_qp-trie.$(OBJEXT) +contrib_test_qp_trie_LDADD = $(LDADD) +contrib_test_qp_trie_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_siphash_SOURCES = contrib/test_siphash.c +contrib_test_siphash_OBJECTS = contrib/test_siphash.$(OBJEXT) +contrib_test_siphash_LDADD = $(LDADD) +contrib_test_siphash_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_sockaddr_SOURCES = contrib/test_sockaddr.c +contrib_test_sockaddr_OBJECTS = contrib/test_sockaddr.$(OBJEXT) +contrib_test_sockaddr_LDADD = $(LDADD) +contrib_test_sockaddr_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_spinlock_SOURCES = contrib/test_spinlock.c +contrib_test_spinlock_OBJECTS = contrib/test_spinlock.$(OBJEXT) +contrib_test_spinlock_LDADD = $(LDADD) +contrib_test_spinlock_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_string_SOURCES = contrib/test_string.c +contrib_test_string_OBJECTS = contrib/test_string.$(OBJEXT) +contrib_test_string_LDADD = $(LDADD) +contrib_test_string_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_strtonum_SOURCES = contrib/test_strtonum.c +contrib_test_strtonum_OBJECTS = contrib/test_strtonum.$(OBJEXT) +contrib_test_strtonum_LDADD = $(LDADD) +contrib_test_strtonum_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_time_SOURCES = contrib/test_time.c +contrib_test_time_OBJECTS = contrib/test_time.$(OBJEXT) +contrib_test_time_LDADD = $(LDADD) +contrib_test_time_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_toeplitz_SOURCES = contrib/test_toeplitz.c +contrib_test_toeplitz_OBJECTS = contrib/test_toeplitz.$(OBJEXT) +contrib_test_toeplitz_LDADD = $(LDADD) +contrib_test_toeplitz_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +contrib_test_wire_ctx_SOURCES = contrib/test_wire_ctx.c +contrib_test_wire_ctx_OBJECTS = contrib/test_wire_ctx.$(OBJEXT) +contrib_test_wire_ctx_LDADD = $(LDADD) +contrib_test_wire_ctx_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__knot_test_acl_SOURCES_DIST = knot/test_acl.c knot/test_conf.h +@HAVE_DAEMON_TRUE@am_knot_test_acl_OBJECTS = knot/test_acl.$(OBJEXT) +knot_test_acl_OBJECTS = $(am_knot_test_acl_OBJECTS) +knot_test_acl_LDADD = $(LDADD) +knot_test_acl_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_changeset_SOURCES = knot/test_changeset.c +knot_test_changeset_OBJECTS = knot/test_changeset.$(OBJEXT) +knot_test_changeset_LDADD = $(LDADD) +knot_test_changeset_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__knot_test_conf_SOURCES_DIST = knot/test_conf.c knot/test_conf.h +@HAVE_DAEMON_TRUE@am_knot_test_conf_OBJECTS = \ +@HAVE_DAEMON_TRUE@ knot/test_conf.$(OBJEXT) +knot_test_conf_OBJECTS = $(am_knot_test_conf_OBJECTS) +knot_test_conf_LDADD = $(LDADD) +knot_test_conf_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_conf_tools_SOURCES = knot/test_conf_tools.c +knot_test_conf_tools_OBJECTS = knot/test_conf_tools.$(OBJEXT) +knot_test_conf_tools_LDADD = $(LDADD) +knot_test_conf_tools_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__knot_test_confdb_SOURCES_DIST = knot/test_confdb.c \ + knot/test_conf.h +@HAVE_DAEMON_TRUE@am_knot_test_confdb_OBJECTS = \ +@HAVE_DAEMON_TRUE@ knot/test_confdb.$(OBJEXT) +knot_test_confdb_OBJECTS = $(am_knot_test_confdb_OBJECTS) +knot_test_confdb_LDADD = $(LDADD) +knot_test_confdb_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__knot_test_confio_SOURCES_DIST = knot/test_confio.c \ + knot/test_conf.h +@HAVE_DAEMON_TRUE@am_knot_test_confio_OBJECTS = \ +@HAVE_DAEMON_TRUE@ knot/test_confio.$(OBJEXT) +knot_test_confio_OBJECTS = $(am_knot_test_confio_OBJECTS) +knot_test_confio_LDADD = $(LDADD) +knot_test_confio_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_digest_SOURCES = knot/test_digest.c +knot_test_digest_OBJECTS = knot/test_digest.$(OBJEXT) +knot_test_digest_LDADD = $(LDADD) +knot_test_digest_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_dthreads_SOURCES = knot/test_dthreads.c +knot_test_dthreads_OBJECTS = knot/test_dthreads.$(OBJEXT) +knot_test_dthreads_LDADD = $(LDADD) +knot_test_dthreads_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_fdset_SOURCES = knot/test_fdset.c +knot_test_fdset_OBJECTS = knot/test_fdset.$(OBJEXT) +knot_test_fdset_LDADD = $(LDADD) +knot_test_fdset_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_journal_SOURCES = knot/test_journal.c +knot_test_journal_OBJECTS = knot/test_journal.$(OBJEXT) +knot_test_journal_LDADD = $(LDADD) +knot_test_journal_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_kasp_db_SOURCES = knot/test_kasp_db.c +knot_test_kasp_db_OBJECTS = knot/test_kasp_db.$(OBJEXT) +knot_test_kasp_db_LDADD = $(LDADD) +knot_test_kasp_db_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_node_SOURCES = knot/test_node.c +knot_test_node_OBJECTS = knot/test_node.$(OBJEXT) +knot_test_node_LDADD = $(LDADD) +knot_test_node_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__knot_test_process_query_SOURCES_DIST = knot/test_process_query.c \ + knot/test_server.h knot/test_conf.h +@HAVE_DAEMON_TRUE@am_knot_test_process_query_OBJECTS = \ +@HAVE_DAEMON_TRUE@ knot/test_process_query.$(OBJEXT) +knot_test_process_query_OBJECTS = \ + $(am_knot_test_process_query_OBJECTS) +knot_test_process_query_LDADD = $(LDADD) +knot_test_process_query_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_query_module_SOURCES = knot/test_query_module.c +knot_test_query_module_OBJECTS = knot/test_query_module.$(OBJEXT) +knot_test_query_module_LDADD = $(LDADD) +knot_test_query_module_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_requestor_SOURCES = knot/test_requestor.c +knot_test_requestor_OBJECTS = knot/test_requestor.$(OBJEXT) +knot_test_requestor_LDADD = $(LDADD) +knot_test_requestor_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_server_SOURCES = knot/test_server.c +knot_test_server_OBJECTS = knot/test_server.$(OBJEXT) +knot_test_server_LDADD = $(LDADD) +knot_test_server_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_unreachable_SOURCES = knot/test_unreachable.c +knot_test_unreachable_OBJECTS = knot/test_unreachable.$(OBJEXT) +knot_test_unreachable_LDADD = $(LDADD) +knot_test_unreachable_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_worker_pool_SOURCES = knot/test_worker_pool.c +knot_test_worker_pool_OBJECTS = knot/test_worker_pool.$(OBJEXT) +knot_test_worker_pool_LDADD = $(LDADD) +knot_test_worker_pool_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_worker_queue_SOURCES = knot/test_worker_queue.c +knot_test_worker_queue_OBJECTS = knot/test_worker_queue.$(OBJEXT) +knot_test_worker_queue_LDADD = $(LDADD) +knot_test_worker_queue_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_zone_tree_SOURCES = knot/test_zone-tree.c +knot_test_zone_tree_OBJECTS = knot/test_zone-tree.$(OBJEXT) +knot_test_zone_tree_LDADD = $(LDADD) +knot_test_zone_tree_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_zone_update_SOURCES = knot/test_zone-update.c +knot_test_zone_update_OBJECTS = knot/test_zone-update.$(OBJEXT) +knot_test_zone_update_LDADD = $(LDADD) +knot_test_zone_update_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_zone_events_SOURCES = knot/test_zone_events.c +knot_test_zone_events_OBJECTS = knot/test_zone_events.$(OBJEXT) +knot_test_zone_events_LDADD = $(LDADD) +knot_test_zone_events_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_zone_serial_SOURCES = knot/test_zone_serial.c +knot_test_zone_serial_OBJECTS = knot/test_zone_serial.$(OBJEXT) +knot_test_zone_serial_LDADD = $(LDADD) +knot_test_zone_serial_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_zone_timers_SOURCES = knot/test_zone_timers.c +knot_test_zone_timers_OBJECTS = knot/test_zone_timers.$(OBJEXT) +knot_test_zone_timers_LDADD = $(LDADD) +knot_test_zone_timers_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +knot_test_zonedb_SOURCES = knot/test_zonedb.c +knot_test_zonedb_OBJECTS = knot/test_zonedb.$(OBJEXT) +knot_test_zonedb_LDADD = $(LDADD) +knot_test_zonedb_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_binary_SOURCES = libdnssec/test_binary.c +libdnssec_test_binary_OBJECTS = libdnssec/test_binary.$(OBJEXT) +libdnssec_test_binary_LDADD = $(LDADD) +libdnssec_test_binary_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_crypto_SOURCES = libdnssec/test_crypto.c +libdnssec_test_crypto_OBJECTS = libdnssec/test_crypto.$(OBJEXT) +libdnssec_test_crypto_LDADD = $(LDADD) +libdnssec_test_crypto_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_key_SOURCES = libdnssec/test_key.c +libdnssec_test_key_OBJECTS = libdnssec/test_key.$(OBJEXT) +libdnssec_test_key_LDADD = $(LDADD) +libdnssec_test_key_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_key_algorithm_SOURCES = libdnssec/test_key_algorithm.c +libdnssec_test_key_algorithm_OBJECTS = \ + libdnssec/test_key_algorithm.$(OBJEXT) +libdnssec_test_key_algorithm_LDADD = $(LDADD) +libdnssec_test_key_algorithm_DEPENDENCIES = libtap.la \ + $(am__DEPENDENCIES_2) $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_key_ds_SOURCES = libdnssec/test_key_ds.c +libdnssec_test_key_ds_OBJECTS = libdnssec/test_key_ds.$(OBJEXT) +libdnssec_test_key_ds_LDADD = $(LDADD) +libdnssec_test_key_ds_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_keyid_SOURCES = libdnssec/test_keyid.c +libdnssec_test_keyid_OBJECTS = libdnssec/test_keyid.$(OBJEXT) +libdnssec_test_keyid_LDADD = $(LDADD) +libdnssec_test_keyid_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_keystore_pkcs11_SOURCES = \ + libdnssec/test_keystore_pkcs11.c +libdnssec_test_keystore_pkcs11_OBJECTS = \ + libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.$(OBJEXT) +libdnssec_test_keystore_pkcs11_LDADD = $(LDADD) +libdnssec_test_keystore_pkcs11_DEPENDENCIES = libtap.la \ + $(am__DEPENDENCIES_2) $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_keystore_pkcs8_SOURCES = \ + libdnssec/test_keystore_pkcs8.c +libdnssec_test_keystore_pkcs8_OBJECTS = \ + libdnssec/test_keystore_pkcs8.$(OBJEXT) +libdnssec_test_keystore_pkcs8_LDADD = $(LDADD) +libdnssec_test_keystore_pkcs8_DEPENDENCIES = libtap.la \ + $(am__DEPENDENCIES_2) $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_keytag_SOURCES = libdnssec/test_keytag.c +libdnssec_test_keytag_OBJECTS = libdnssec/test_keytag.$(OBJEXT) +libdnssec_test_keytag_LDADD = $(LDADD) +libdnssec_test_keytag_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_nsec_bitmap_SOURCES = libdnssec/test_nsec_bitmap.c +libdnssec_test_nsec_bitmap_OBJECTS = \ + libdnssec/test_nsec_bitmap.$(OBJEXT) +libdnssec_test_nsec_bitmap_LDADD = $(LDADD) +libdnssec_test_nsec_bitmap_DEPENDENCIES = libtap.la \ + $(am__DEPENDENCIES_2) $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_nsec_hash_SOURCES = libdnssec/test_nsec_hash.c +libdnssec_test_nsec_hash_OBJECTS = libdnssec/test_nsec_hash.$(OBJEXT) +libdnssec_test_nsec_hash_LDADD = $(LDADD) +libdnssec_test_nsec_hash_DEPENDENCIES = libtap.la \ + $(am__DEPENDENCIES_2) $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_random_SOURCES = libdnssec/test_random.c +libdnssec_test_random_OBJECTS = libdnssec/test_random.$(OBJEXT) +libdnssec_test_random_LDADD = $(LDADD) +libdnssec_test_random_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_shared_bignum_SOURCES = libdnssec/test_shared_bignum.c +libdnssec_test_shared_bignum_OBJECTS = \ + libdnssec/test_shared_bignum.$(OBJEXT) +libdnssec_test_shared_bignum_LDADD = $(LDADD) +libdnssec_test_shared_bignum_DEPENDENCIES = libtap.la \ + $(am__DEPENDENCIES_2) $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_shared_dname_SOURCES = libdnssec/test_shared_dname.c +libdnssec_test_shared_dname_OBJECTS = \ + libdnssec/test_shared_dname.$(OBJEXT) +libdnssec_test_shared_dname_LDADD = $(LDADD) +libdnssec_test_shared_dname_DEPENDENCIES = libtap.la \ + $(am__DEPENDENCIES_2) $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_sign_SOURCES = libdnssec/test_sign.c +libdnssec_test_sign_OBJECTS = libdnssec/test_sign.$(OBJEXT) +libdnssec_test_sign_LDADD = $(LDADD) +libdnssec_test_sign_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_sign_der_SOURCES = libdnssec/test_sign_der.c +libdnssec_test_sign_der_OBJECTS = libdnssec/test_sign_der.$(OBJEXT) +libdnssec_test_sign_der_LDADD = $(LDADD) +libdnssec_test_sign_der_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libdnssec_test_tsig_SOURCES = libdnssec/test_tsig.c +libdnssec_test_tsig_OBJECTS = libdnssec/test_tsig.$(OBJEXT) +libdnssec_test_tsig_LDADD = $(LDADD) +libdnssec_test_tsig_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_control_SOURCES = libknot/test_control.c +libknot_test_control_OBJECTS = libknot/test_control.$(OBJEXT) +libknot_test_control_LDADD = $(LDADD) +libknot_test_control_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_cookies_SOURCES = libknot/test_cookies.c +libknot_test_cookies_OBJECTS = libknot/test_cookies.$(OBJEXT) +libknot_test_cookies_LDADD = $(LDADD) +libknot_test_cookies_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_db_SOURCES = libknot/test_db.c +libknot_test_db_OBJECTS = libknot/test_db.$(OBJEXT) +libknot_test_db_LDADD = $(LDADD) +libknot_test_db_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_descriptor_SOURCES = libknot/test_descriptor.c +libknot_test_descriptor_OBJECTS = libknot/test_descriptor.$(OBJEXT) +libknot_test_descriptor_LDADD = $(LDADD) +libknot_test_descriptor_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_dname_SOURCES = libknot/test_dname.c +libknot_test_dname_OBJECTS = libknot/test_dname.$(OBJEXT) +libknot_test_dname_LDADD = $(LDADD) +libknot_test_dname_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_dynarray_SOURCES = libknot/test_dynarray.c +libknot_test_dynarray_OBJECTS = libknot/test_dynarray.$(OBJEXT) +libknot_test_dynarray_LDADD = $(LDADD) +libknot_test_dynarray_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_edns_SOURCES = libknot/test_edns.c +libknot_test_edns_OBJECTS = libknot/test_edns.$(OBJEXT) +libknot_test_edns_LDADD = $(LDADD) +libknot_test_edns_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_edns_ecs_SOURCES = libknot/test_edns_ecs.c +libknot_test_edns_ecs_OBJECTS = libknot/test_edns_ecs.$(OBJEXT) +libknot_test_edns_ecs_LDADD = $(LDADD) +libknot_test_edns_ecs_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_endian_SOURCES = libknot/test_endian.c +libknot_test_endian_OBJECTS = libknot/test_endian.$(OBJEXT) +libknot_test_endian_LDADD = $(LDADD) +libknot_test_endian_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_lookup_SOURCES = libknot/test_lookup.c +libknot_test_lookup_OBJECTS = libknot/test_lookup.$(OBJEXT) +libknot_test_lookup_LDADD = $(LDADD) +libknot_test_lookup_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_pkt_SOURCES = libknot/test_pkt.c +libknot_test_pkt_OBJECTS = libknot/test_pkt.$(OBJEXT) +libknot_test_pkt_LDADD = $(LDADD) +libknot_test_pkt_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_probe_SOURCES = libknot/test_probe.c +libknot_test_probe_OBJECTS = libknot/test_probe.$(OBJEXT) +libknot_test_probe_LDADD = $(LDADD) +libknot_test_probe_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_rdata_SOURCES = libknot/test_rdata.c +libknot_test_rdata_OBJECTS = libknot/test_rdata.$(OBJEXT) +libknot_test_rdata_LDADD = $(LDADD) +libknot_test_rdata_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_rdataset_SOURCES = libknot/test_rdataset.c +libknot_test_rdataset_OBJECTS = libknot/test_rdataset.$(OBJEXT) +libknot_test_rdataset_LDADD = $(LDADD) +libknot_test_rdataset_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_rrset_SOURCES = libknot/test_rrset.c +libknot_test_rrset_OBJECTS = libknot/test_rrset.$(OBJEXT) +libknot_test_rrset_LDADD = $(LDADD) +libknot_test_rrset_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_rrset_wire_SOURCES = libknot/test_rrset-wire.c +libknot_test_rrset_wire_OBJECTS = libknot/test_rrset-wire.$(OBJEXT) +libknot_test_rrset_wire_LDADD = $(LDADD) +libknot_test_rrset_wire_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_tsig_SOURCES = libknot/test_tsig.c +libknot_test_tsig_OBJECTS = libknot/test_tsig.$(OBJEXT) +libknot_test_tsig_LDADD = $(LDADD) +libknot_test_tsig_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_wire_SOURCES = libknot/test_wire.c +libknot_test_wire_OBJECTS = libknot/test_wire.$(OBJEXT) +libknot_test_wire_LDADD = $(LDADD) +libknot_test_wire_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_xdp_tcp_SOURCES = libknot/test_xdp_tcp.c +libknot_test_xdp_tcp_OBJECTS = libknot/test_xdp_tcp.$(OBJEXT) +libknot_test_xdp_tcp_LDADD = $(LDADD) +libknot_test_xdp_tcp_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_yparser_SOURCES = libknot/test_yparser.c +libknot_test_yparser_OBJECTS = libknot/test_yparser.$(OBJEXT) +libknot_test_yparser_LDADD = $(LDADD) +libknot_test_yparser_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_ypschema_SOURCES = libknot/test_ypschema.c +libknot_test_ypschema_OBJECTS = libknot/test_ypschema.$(OBJEXT) +libknot_test_ypschema_LDADD = $(LDADD) +libknot_test_ypschema_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +libknot_test_yptrafo_SOURCES = libknot/test_yptrafo.c +libknot_test_yptrafo_OBJECTS = libknot/test_yptrafo.$(OBJEXT) +libknot_test_yptrafo_LDADD = $(LDADD) +libknot_test_yptrafo_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_libzscanner_zscanner_tool_OBJECTS = \ + libzscanner/zscanner-tool.$(OBJEXT) \ + libzscanner/processing.$(OBJEXT) +libzscanner_zscanner_tool_OBJECTS = \ + $(am_libzscanner_zscanner_tool_OBJECTS) +libzscanner_zscanner_tool_LDADD = $(LDADD) +libzscanner_zscanner_tool_DEPENDENCIES = libtap.la \ + $(am__DEPENDENCIES_2) $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +modules_test_onlinesign_SOURCES = modules/test_onlinesign.c +modules_test_onlinesign_OBJECTS = modules/test_onlinesign.$(OBJEXT) +modules_test_onlinesign_LDADD = $(LDADD) +modules_test_onlinesign_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +modules_test_rrl_SOURCES = modules/test_rrl.c +modules_test_rrl_OBJECTS = modules/test_rrl.$(OBJEXT) +modules_test_rrl_LDADD = $(LDADD) +modules_test_rrl_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +tap_runtests_SOURCES = tap/runtests.c +tap_runtests_OBJECTS = tap/runtests.$(OBJEXT) +tap_runtests_LDADD = $(LDADD) +tap_runtests_DEPENDENCIES = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +utils_test_lookup_SOURCES = utils/test_lookup.c +utils_test_lookup_OBJECTS = \ + utils/utils_test_lookup-test_lookup.$(OBJEXT) +am__DEPENDENCIES_3 = libtap.la $(am__DEPENDENCIES_2) \ + $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +@HAVE_LIBUTILS_TRUE@utils_test_lookup_DEPENDENCIES = \ +@HAVE_LIBUTILS_TRUE@ $(top_builddir)/src/libknotus.la \ +@HAVE_LIBUTILS_TRUE@ $(am__DEPENDENCIES_1) \ +@HAVE_LIBUTILS_TRUE@ $(am__DEPENDENCIES_3) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = contrib/$(DEPDIR)/test_base32hex.Po \ + contrib/$(DEPDIR)/test_base64.Po \ + contrib/$(DEPDIR)/test_base64url.Po \ + contrib/$(DEPDIR)/test_heap.Po \ + contrib/$(DEPDIR)/test_inet_ntop.Po \ + contrib/$(DEPDIR)/test_net.Po \ + contrib/$(DEPDIR)/test_net_shortwrite.Po \ + contrib/$(DEPDIR)/test_qp-cow.Po \ + contrib/$(DEPDIR)/test_qp-trie.Po \ + contrib/$(DEPDIR)/test_siphash.Po \ + contrib/$(DEPDIR)/test_sockaddr.Po \ + contrib/$(DEPDIR)/test_spinlock.Po \ + contrib/$(DEPDIR)/test_string.Po \ + contrib/$(DEPDIR)/test_strtonum.Po \ + contrib/$(DEPDIR)/test_time.Po \ + contrib/$(DEPDIR)/test_toeplitz.Po \ + contrib/$(DEPDIR)/test_wire_ctx.Po knot/$(DEPDIR)/test_acl.Po \ + knot/$(DEPDIR)/test_changeset.Po knot/$(DEPDIR)/test_conf.Po \ + knot/$(DEPDIR)/test_conf_tools.Po \ + knot/$(DEPDIR)/test_confdb.Po knot/$(DEPDIR)/test_confio.Po \ + knot/$(DEPDIR)/test_digest.Po knot/$(DEPDIR)/test_dthreads.Po \ + knot/$(DEPDIR)/test_fdset.Po knot/$(DEPDIR)/test_journal.Po \ + knot/$(DEPDIR)/test_kasp_db.Po knot/$(DEPDIR)/test_node.Po \ + knot/$(DEPDIR)/test_process_query.Po \ + knot/$(DEPDIR)/test_query_module.Po \ + knot/$(DEPDIR)/test_requestor.Po knot/$(DEPDIR)/test_server.Po \ + knot/$(DEPDIR)/test_unreachable.Po \ + knot/$(DEPDIR)/test_worker_pool.Po \ + knot/$(DEPDIR)/test_worker_queue.Po \ + knot/$(DEPDIR)/test_zone-tree.Po \ + knot/$(DEPDIR)/test_zone-update.Po \ + knot/$(DEPDIR)/test_zone_events.Po \ + knot/$(DEPDIR)/test_zone_serial.Po \ + knot/$(DEPDIR)/test_zone_timers.Po \ + knot/$(DEPDIR)/test_zonedb.Po \ + libdnssec/$(DEPDIR)/test_binary.Po \ + libdnssec/$(DEPDIR)/test_crypto.Po \ + libdnssec/$(DEPDIR)/test_key.Po \ + libdnssec/$(DEPDIR)/test_key_algorithm.Po \ + libdnssec/$(DEPDIR)/test_key_ds.Po \ + libdnssec/$(DEPDIR)/test_keyid.Po \ + libdnssec/$(DEPDIR)/test_keystore_pkcs11-test_keystore_pkcs11.Po \ + libdnssec/$(DEPDIR)/test_keystore_pkcs8.Po \ + libdnssec/$(DEPDIR)/test_keytag.Po \ + libdnssec/$(DEPDIR)/test_nsec_bitmap.Po \ + libdnssec/$(DEPDIR)/test_nsec_hash.Po \ + libdnssec/$(DEPDIR)/test_random.Po \ + libdnssec/$(DEPDIR)/test_shared_bignum.Po \ + libdnssec/$(DEPDIR)/test_shared_dname.Po \ + libdnssec/$(DEPDIR)/test_sign.Po \ + libdnssec/$(DEPDIR)/test_sign_der.Po \ + libdnssec/$(DEPDIR)/test_tsig.Po \ + libknot/$(DEPDIR)/test_control.Po \ + libknot/$(DEPDIR)/test_cookies.Po libknot/$(DEPDIR)/test_db.Po \ + libknot/$(DEPDIR)/test_descriptor.Po \ + libknot/$(DEPDIR)/test_dname.Po \ + libknot/$(DEPDIR)/test_dynarray.Po \ + libknot/$(DEPDIR)/test_edns.Po \ + libknot/$(DEPDIR)/test_edns_ecs.Po \ + libknot/$(DEPDIR)/test_endian.Po \ + libknot/$(DEPDIR)/test_lookup.Po libknot/$(DEPDIR)/test_pkt.Po \ + libknot/$(DEPDIR)/test_probe.Po \ + libknot/$(DEPDIR)/test_rdata.Po \ + libknot/$(DEPDIR)/test_rdataset.Po \ + libknot/$(DEPDIR)/test_rrset-wire.Po \ + libknot/$(DEPDIR)/test_rrset.Po libknot/$(DEPDIR)/test_tsig.Po \ + libknot/$(DEPDIR)/test_wire.Po \ + libknot/$(DEPDIR)/test_xdp_tcp.Po \ + libknot/$(DEPDIR)/test_yparser.Po \ + libknot/$(DEPDIR)/test_ypschema.Po \ + libknot/$(DEPDIR)/test_yptrafo.Po \ + libzscanner/$(DEPDIR)/processing.Po \ + libzscanner/$(DEPDIR)/zscanner-tool.Po \ + modules/$(DEPDIR)/test_onlinesign.Po \ + modules/$(DEPDIR)/test_rrl.Po tap/$(DEPDIR)/basic.Plo \ + tap/$(DEPDIR)/files.Plo tap/$(DEPDIR)/float.Plo \ + tap/$(DEPDIR)/runtests.Po \ + utils/$(DEPDIR)/utils_test_lookup-test_lookup.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libtap_la_SOURCES) contrib/test_base32hex.c \ + contrib/test_base64.c contrib/test_base64url.c \ + contrib/test_heap.c contrib/test_inet_ntop.c \ + contrib/test_net.c contrib/test_net_shortwrite.c \ + contrib/test_qp-cow.c contrib/test_qp-trie.c \ + contrib/test_siphash.c contrib/test_sockaddr.c \ + contrib/test_spinlock.c contrib/test_string.c \ + contrib/test_strtonum.c contrib/test_time.c \ + contrib/test_toeplitz.c contrib/test_wire_ctx.c \ + $(knot_test_acl_SOURCES) knot/test_changeset.c \ + $(knot_test_conf_SOURCES) knot/test_conf_tools.c \ + $(knot_test_confdb_SOURCES) $(knot_test_confio_SOURCES) \ + knot/test_digest.c knot/test_dthreads.c knot/test_fdset.c \ + knot/test_journal.c knot/test_kasp_db.c knot/test_node.c \ + $(knot_test_process_query_SOURCES) knot/test_query_module.c \ + knot/test_requestor.c knot/test_server.c \ + knot/test_unreachable.c knot/test_worker_pool.c \ + knot/test_worker_queue.c knot/test_zone-tree.c \ + knot/test_zone-update.c knot/test_zone_events.c \ + knot/test_zone_serial.c knot/test_zone_timers.c \ + knot/test_zonedb.c libdnssec/test_binary.c \ + libdnssec/test_crypto.c libdnssec/test_key.c \ + libdnssec/test_key_algorithm.c libdnssec/test_key_ds.c \ + libdnssec/test_keyid.c libdnssec/test_keystore_pkcs11.c \ + libdnssec/test_keystore_pkcs8.c libdnssec/test_keytag.c \ + libdnssec/test_nsec_bitmap.c libdnssec/test_nsec_hash.c \ + libdnssec/test_random.c libdnssec/test_shared_bignum.c \ + libdnssec/test_shared_dname.c libdnssec/test_sign.c \ + libdnssec/test_sign_der.c libdnssec/test_tsig.c \ + libknot/test_control.c libknot/test_cookies.c \ + libknot/test_db.c libknot/test_descriptor.c \ + libknot/test_dname.c libknot/test_dynarray.c \ + libknot/test_edns.c libknot/test_edns_ecs.c \ + libknot/test_endian.c libknot/test_lookup.c libknot/test_pkt.c \ + libknot/test_probe.c libknot/test_rdata.c \ + libknot/test_rdataset.c libknot/test_rrset.c \ + libknot/test_rrset-wire.c libknot/test_tsig.c \ + libknot/test_wire.c libknot/test_xdp_tcp.c \ + libknot/test_yparser.c libknot/test_ypschema.c \ + libknot/test_yptrafo.c $(libzscanner_zscanner_tool_SOURCES) \ + modules/test_onlinesign.c modules/test_rrl.c tap/runtests.c \ + utils/test_lookup.c +DIST_SOURCES = $(libtap_la_SOURCES) contrib/test_base32hex.c \ + contrib/test_base64.c contrib/test_base64url.c \ + contrib/test_heap.c contrib/test_inet_ntop.c \ + contrib/test_net.c contrib/test_net_shortwrite.c \ + contrib/test_qp-cow.c contrib/test_qp-trie.c \ + contrib/test_siphash.c contrib/test_sockaddr.c \ + contrib/test_spinlock.c contrib/test_string.c \ + contrib/test_strtonum.c contrib/test_time.c \ + contrib/test_toeplitz.c contrib/test_wire_ctx.c \ + $(am__knot_test_acl_SOURCES_DIST) knot/test_changeset.c \ + $(am__knot_test_conf_SOURCES_DIST) knot/test_conf_tools.c \ + $(am__knot_test_confdb_SOURCES_DIST) \ + $(am__knot_test_confio_SOURCES_DIST) knot/test_digest.c \ + knot/test_dthreads.c knot/test_fdset.c knot/test_journal.c \ + knot/test_kasp_db.c knot/test_node.c \ + $(am__knot_test_process_query_SOURCES_DIST) \ + knot/test_query_module.c knot/test_requestor.c \ + knot/test_server.c knot/test_unreachable.c \ + knot/test_worker_pool.c knot/test_worker_queue.c \ + knot/test_zone-tree.c knot/test_zone-update.c \ + knot/test_zone_events.c knot/test_zone_serial.c \ + knot/test_zone_timers.c knot/test_zonedb.c \ + libdnssec/test_binary.c libdnssec/test_crypto.c \ + libdnssec/test_key.c libdnssec/test_key_algorithm.c \ + libdnssec/test_key_ds.c libdnssec/test_keyid.c \ + libdnssec/test_keystore_pkcs11.c \ + libdnssec/test_keystore_pkcs8.c libdnssec/test_keytag.c \ + libdnssec/test_nsec_bitmap.c libdnssec/test_nsec_hash.c \ + libdnssec/test_random.c libdnssec/test_shared_bignum.c \ + libdnssec/test_shared_dname.c libdnssec/test_sign.c \ + libdnssec/test_sign_der.c libdnssec/test_tsig.c \ + libknot/test_control.c libknot/test_cookies.c \ + libknot/test_db.c libknot/test_descriptor.c \ + libknot/test_dname.c libknot/test_dynarray.c \ + libknot/test_edns.c libknot/test_edns_ecs.c \ + libknot/test_endian.c libknot/test_lookup.c libknot/test_pkt.c \ + libknot/test_probe.c libknot/test_rdata.c \ + libknot/test_rdataset.c libknot/test_rrset.c \ + libknot/test_rrset-wire.c libknot/test_tsig.c \ + libknot/test_wire.c libknot/test_xdp_tcp.c \ + libknot/test_yparser.c libknot/test_ypschema.c \ + libknot/test_yptrafo.c $(libzscanner_zscanner_tool_SOURCES) \ + modules/test_onlinesign.c modules/test_rrl.c tap/runtests.c \ + utils/test_lookup.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_VISIBILITY = @CFLAG_VISIBILITY@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DNSTAP_CFLAGS = @DNSTAP_CFLAGS@ +DNSTAP_LIBS = @DNSTAP_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +GENHTML = @GENHTML@ +GREP = @GREP@ +HAVE_VISIBILITY = @HAVE_VISIBILITY@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KNOT_VERSION_MAJOR = @KNOT_VERSION_MAJOR@ +KNOT_VERSION_MINOR = @KNOT_VERSION_MINOR@ +KNOT_VERSION_PATCH = @KNOT_VERSION_PATCH@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LDFLAG_EXCLUDE_LIBS = @LDFLAG_EXCLUDE_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_NO_UNDEFINED = @LT_NO_UNDEFINED@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PROTOC_C = @PROTOC_C@ +RANLIB = @RANLIB@ +RELEASE_DATE = @RELEASE_DATE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINXBUILD = @SPHINXBUILD@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +cap_ng_CFLAGS = @cap_ng_CFLAGS@ +cap_ng_LIBS = @cap_ng_LIBS@ +conf_mapsize = @conf_mapsize@ +config_dir = @config_dir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dlopen_LIBS = @dlopen_LIBS@ +docdir = @docdir@ +dvidir = @dvidir@ +embedded_libngtcp2_CFLAGS = @embedded_libngtcp2_CFLAGS@ +embedded_libngtcp2_LIBS = @embedded_libngtcp2_LIBS@ +exec_prefix = @exec_prefix@ +fuzzer_CFLAGS = @fuzzer_CFLAGS@ +fuzzer_LDFLAGS = @fuzzer_LDFLAGS@ +gnutls_CFLAGS = @gnutls_CFLAGS@ +gnutls_LIBS = @gnutls_LIBS@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libbpf_CFLAGS = @libbpf_CFLAGS@ +libbpf_LIBS = @libbpf_LIBS@ +libdir = @libdir@ +libdnssec_SONAME = @libdnssec_SONAME@ +libdnssec_SOVERSION = @libdnssec_SOVERSION@ +libdnssec_VERSION_INFO = @libdnssec_VERSION_INFO@ +libedit_CFLAGS = @libedit_CFLAGS@ +libedit_LIBS = @libedit_LIBS@ +libexecdir = @libexecdir@ +libfstrm_CFLAGS = @libfstrm_CFLAGS@ +libfstrm_LIBS = @libfstrm_LIBS@ +libidn2_CFLAGS = @libidn2_CFLAGS@ +libidn2_LIBS = @libidn2_LIBS@ +libidn_CFLAGS = @libidn_CFLAGS@ +libidn_LIBS = @libidn_LIBS@ +libknot_SONAME = @libknot_SONAME@ +libknot_SOVERSION = @libknot_SOVERSION@ +libknot_VERSION_INFO = @libknot_VERSION_INFO@ +libkqueue_CFLAGS = @libkqueue_CFLAGS@ +libkqueue_LIBS = @libkqueue_LIBS@ +libmaxminddb_CFLAGS = @libmaxminddb_CFLAGS@ +libmaxminddb_LIBS = @libmaxminddb_LIBS@ +libmnl_CFLAGS = @libmnl_CFLAGS@ +libmnl_LIBS = @libmnl_LIBS@ +libnghttp2_CFLAGS = @libnghttp2_CFLAGS@ +libnghttp2_LIBS = @libnghttp2_LIBS@ +libngtcp2_CFLAGS = @libngtcp2_CFLAGS@ +libngtcp2_LIBS = @libngtcp2_LIBS@ +libprotobuf_c_CFLAGS = @libprotobuf_c_CFLAGS@ +libprotobuf_c_LIBS = @libprotobuf_c_LIBS@ +liburcu_CFLAGS = @liburcu_CFLAGS@ +liburcu_LIBS = @liburcu_LIBS@ +liburcu_PKGCONFIG = @liburcu_PKGCONFIG@ +libxdp_CFLAGS = @libxdp_CFLAGS@ +libxdp_LIBS = @libxdp_LIBS@ +libzscanner_SONAME = @libzscanner_SONAME@ +libzscanner_SOVERSION = @libzscanner_SOVERSION@ +libzscanner_VERSION_INFO = @libzscanner_VERSION_INFO@ +lmdb_CFLAGS = @lmdb_CFLAGS@ +lmdb_LIBS = @lmdb_LIBS@ +localedir = @localedir@ +localstatedir = @localstatedir@ +malloc_LIBS = @malloc_LIBS@ +mandir = @mandir@ +math_LIBS = @math_LIBS@ +mkdir_p = @mkdir_p@ +module_dir = @module_dir@ +module_instdir = @module_instdir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgconfigdir = @pkgconfigdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pthread_LIBS = @pthread_LIBS@ +run_dir = @run_dir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +storage_dir = @storage_dir@ +sysconfdir = @sysconfdir@ +systemd_CFLAGS = @systemd_CFLAGS@ +systemd_LIBS = @systemd_LIBS@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -include $(top_builddir)/src/config.h \ + -I$(top_srcdir)/src -I$(top_srcdir)/src/libdnssec \ + -I$(top_srcdir)/src/libdnssec/shared $(gnutls_CFLAGS) \ + $(libkqueue_CFLAGS) $(lmdb_CFLAGS) $(am__append_3) +LDADD = libtap.la $(am__append_1) $(top_builddir)/src/libknot.la \ + $(top_builddir)/src/libdnssec.la \ + $(top_builddir)/src/libcontrib.la \ + $(top_builddir)/src/libzscanner.la $(gnutls_LIBS) $(lmdb_LIBS) +EXTRA_DIST = \ + tap/libtap.sh \ + libdnssec/sample_keys.h \ + knot/semantic_check_data \ + knot/test_semantic_check.in \ + libzscanner/data \ + libzscanner/test_zscanner.in \ + libzscanner/TESTS + +check_LTLIBRARIES = libtap.la +libtap_la_SOURCES = \ + tap/basic.c \ + tap/basic.h \ + tap/files.c \ + tap/files.h \ + tap/float.c \ + tap/float.h \ + tap/macros.h + +@HAVE_DAEMON_TRUE@knot_test_acl_SOURCES = \ +@HAVE_DAEMON_TRUE@ knot/test_acl.c \ +@HAVE_DAEMON_TRUE@ knot/test_conf.h + +@HAVE_DAEMON_TRUE@knot_test_conf_SOURCES = \ +@HAVE_DAEMON_TRUE@ knot/test_conf.c \ +@HAVE_DAEMON_TRUE@ knot/test_conf.h + +@HAVE_DAEMON_TRUE@knot_test_confdb_SOURCES = \ +@HAVE_DAEMON_TRUE@ knot/test_confdb.c \ +@HAVE_DAEMON_TRUE@ knot/test_conf.h + +@HAVE_DAEMON_TRUE@knot_test_confio_SOURCES = \ +@HAVE_DAEMON_TRUE@ knot/test_confio.c \ +@HAVE_DAEMON_TRUE@ knot/test_conf.h + +@HAVE_DAEMON_TRUE@knot_test_process_query_SOURCES = \ +@HAVE_DAEMON_TRUE@ knot/test_process_query.c \ +@HAVE_DAEMON_TRUE@ knot/test_server.h \ +@HAVE_DAEMON_TRUE@ knot/test_conf.h + +libdnssec_test_keystore_pkcs11_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -DLIBDIR='"$(libdir)"' + +@HAVE_LIBUTILS_TRUE@utils_test_lookup_CPPFLAGS = \ +@HAVE_LIBUTILS_TRUE@ $(AM_CPPFLAGS) \ +@HAVE_LIBUTILS_TRUE@ $(libedit_CFLAGS) + +@HAVE_LIBUTILS_TRUE@utils_test_lookup_LDADD = \ +@HAVE_LIBUTILS_TRUE@ $(top_builddir)/src/libknotus.la \ +@HAVE_LIBUTILS_TRUE@ $(libedit_LIBS) \ +@HAVE_LIBUTILS_TRUE@ $(LDADD) + +libzscanner_zscanner_tool_SOURCES = \ + libzscanner/zscanner-tool.c \ + libzscanner/processing.h \ + libzscanner/processing.c + +check_SCRIPTS = libzscanner/test_zscanner $(am__append_10) +edit = $(SED) \ + -e 's|@top_srcdir[@]|$(abs_top_srcdir)|g' \ + -e 's|@top_builddir[@]|$(abs_top_builddir)|g' + +CLEANFILES = $(check_SCRIPTS) $(EXTRA_PROGRAMS) runtests.log +AM_V_RUNTESTS = $(am__v_RUNTESTS_@AM_V@) +am__v_RUNTESTS_ = $(am__v_RUNTESTS_@AM_DEFAULT_V@) +am__v_RUNTESTS_0 = +am__v_RUNTESTS_1 = RET=$$?; if [ "$$RET" != "0" ]; then cat "$(builddir)/runtests.log"; exit $$RET; fi +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tests/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +clean-checkLTLIBRARIES: + -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) + @list='$(check_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +tap/$(am__dirstamp): + @$(MKDIR_P) tap + @: > tap/$(am__dirstamp) +tap/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) tap/$(DEPDIR) + @: > tap/$(DEPDIR)/$(am__dirstamp) +tap/basic.lo: tap/$(am__dirstamp) tap/$(DEPDIR)/$(am__dirstamp) +tap/files.lo: tap/$(am__dirstamp) tap/$(DEPDIR)/$(am__dirstamp) +tap/float.lo: tap/$(am__dirstamp) tap/$(DEPDIR)/$(am__dirstamp) + +libtap.la: $(libtap_la_OBJECTS) $(libtap_la_DEPENDENCIES) $(EXTRA_libtap_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libtap_la_OBJECTS) $(libtap_la_LIBADD) $(LIBS) +contrib/$(am__dirstamp): + @$(MKDIR_P) contrib + @: > contrib/$(am__dirstamp) +contrib/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) contrib/$(DEPDIR) + @: > contrib/$(DEPDIR)/$(am__dirstamp) +contrib/test_base32hex.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_base32hex$(EXEEXT): $(contrib_test_base32hex_OBJECTS) $(contrib_test_base32hex_DEPENDENCIES) $(EXTRA_contrib_test_base32hex_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_base32hex$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_base32hex_OBJECTS) $(contrib_test_base32hex_LDADD) $(LIBS) +contrib/test_base64.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_base64$(EXEEXT): $(contrib_test_base64_OBJECTS) $(contrib_test_base64_DEPENDENCIES) $(EXTRA_contrib_test_base64_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_base64$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_base64_OBJECTS) $(contrib_test_base64_LDADD) $(LIBS) +contrib/test_base64url.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_base64url$(EXEEXT): $(contrib_test_base64url_OBJECTS) $(contrib_test_base64url_DEPENDENCIES) $(EXTRA_contrib_test_base64url_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_base64url$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_base64url_OBJECTS) $(contrib_test_base64url_LDADD) $(LIBS) +contrib/test_heap.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_heap$(EXEEXT): $(contrib_test_heap_OBJECTS) $(contrib_test_heap_DEPENDENCIES) $(EXTRA_contrib_test_heap_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_heap$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_heap_OBJECTS) $(contrib_test_heap_LDADD) $(LIBS) +contrib/test_inet_ntop.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_inet_ntop$(EXEEXT): $(contrib_test_inet_ntop_OBJECTS) $(contrib_test_inet_ntop_DEPENDENCIES) $(EXTRA_contrib_test_inet_ntop_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_inet_ntop$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_inet_ntop_OBJECTS) $(contrib_test_inet_ntop_LDADD) $(LIBS) +contrib/test_net.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_net$(EXEEXT): $(contrib_test_net_OBJECTS) $(contrib_test_net_DEPENDENCIES) $(EXTRA_contrib_test_net_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_net$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_net_OBJECTS) $(contrib_test_net_LDADD) $(LIBS) +contrib/test_net_shortwrite.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_net_shortwrite$(EXEEXT): $(contrib_test_net_shortwrite_OBJECTS) $(contrib_test_net_shortwrite_DEPENDENCIES) $(EXTRA_contrib_test_net_shortwrite_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_net_shortwrite$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_net_shortwrite_OBJECTS) $(contrib_test_net_shortwrite_LDADD) $(LIBS) +contrib/test_qp-cow.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_qp-cow$(EXEEXT): $(contrib_test_qp_cow_OBJECTS) $(contrib_test_qp_cow_DEPENDENCIES) $(EXTRA_contrib_test_qp_cow_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_qp-cow$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_qp_cow_OBJECTS) $(contrib_test_qp_cow_LDADD) $(LIBS) +contrib/test_qp-trie.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_qp-trie$(EXEEXT): $(contrib_test_qp_trie_OBJECTS) $(contrib_test_qp_trie_DEPENDENCIES) $(EXTRA_contrib_test_qp_trie_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_qp-trie$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_qp_trie_OBJECTS) $(contrib_test_qp_trie_LDADD) $(LIBS) +contrib/test_siphash.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_siphash$(EXEEXT): $(contrib_test_siphash_OBJECTS) $(contrib_test_siphash_DEPENDENCIES) $(EXTRA_contrib_test_siphash_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_siphash$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_siphash_OBJECTS) $(contrib_test_siphash_LDADD) $(LIBS) +contrib/test_sockaddr.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_sockaddr$(EXEEXT): $(contrib_test_sockaddr_OBJECTS) $(contrib_test_sockaddr_DEPENDENCIES) $(EXTRA_contrib_test_sockaddr_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_sockaddr$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_sockaddr_OBJECTS) $(contrib_test_sockaddr_LDADD) $(LIBS) +contrib/test_spinlock.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_spinlock$(EXEEXT): $(contrib_test_spinlock_OBJECTS) $(contrib_test_spinlock_DEPENDENCIES) $(EXTRA_contrib_test_spinlock_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_spinlock$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_spinlock_OBJECTS) $(contrib_test_spinlock_LDADD) $(LIBS) +contrib/test_string.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_string$(EXEEXT): $(contrib_test_string_OBJECTS) $(contrib_test_string_DEPENDENCIES) $(EXTRA_contrib_test_string_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_string$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_string_OBJECTS) $(contrib_test_string_LDADD) $(LIBS) +contrib/test_strtonum.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_strtonum$(EXEEXT): $(contrib_test_strtonum_OBJECTS) $(contrib_test_strtonum_DEPENDENCIES) $(EXTRA_contrib_test_strtonum_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_strtonum$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_strtonum_OBJECTS) $(contrib_test_strtonum_LDADD) $(LIBS) +contrib/test_time.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_time$(EXEEXT): $(contrib_test_time_OBJECTS) $(contrib_test_time_DEPENDENCIES) $(EXTRA_contrib_test_time_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_time$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_time_OBJECTS) $(contrib_test_time_LDADD) $(LIBS) +contrib/test_toeplitz.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_toeplitz$(EXEEXT): $(contrib_test_toeplitz_OBJECTS) $(contrib_test_toeplitz_DEPENDENCIES) $(EXTRA_contrib_test_toeplitz_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_toeplitz$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_toeplitz_OBJECTS) $(contrib_test_toeplitz_LDADD) $(LIBS) +contrib/test_wire_ctx.$(OBJEXT): contrib/$(am__dirstamp) \ + contrib/$(DEPDIR)/$(am__dirstamp) + +contrib/test_wire_ctx$(EXEEXT): $(contrib_test_wire_ctx_OBJECTS) $(contrib_test_wire_ctx_DEPENDENCIES) $(EXTRA_contrib_test_wire_ctx_DEPENDENCIES) contrib/$(am__dirstamp) + @rm -f contrib/test_wire_ctx$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(contrib_test_wire_ctx_OBJECTS) $(contrib_test_wire_ctx_LDADD) $(LIBS) +knot/$(am__dirstamp): + @$(MKDIR_P) knot + @: > knot/$(am__dirstamp) +knot/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) knot/$(DEPDIR) + @: > knot/$(DEPDIR)/$(am__dirstamp) +knot/test_acl.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_acl$(EXEEXT): $(knot_test_acl_OBJECTS) $(knot_test_acl_DEPENDENCIES) $(EXTRA_knot_test_acl_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_acl$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_acl_OBJECTS) $(knot_test_acl_LDADD) $(LIBS) +knot/test_changeset.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_changeset$(EXEEXT): $(knot_test_changeset_OBJECTS) $(knot_test_changeset_DEPENDENCIES) $(EXTRA_knot_test_changeset_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_changeset$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_changeset_OBJECTS) $(knot_test_changeset_LDADD) $(LIBS) +knot/test_conf.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_conf$(EXEEXT): $(knot_test_conf_OBJECTS) $(knot_test_conf_DEPENDENCIES) $(EXTRA_knot_test_conf_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_conf$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_conf_OBJECTS) $(knot_test_conf_LDADD) $(LIBS) +knot/test_conf_tools.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_conf_tools$(EXEEXT): $(knot_test_conf_tools_OBJECTS) $(knot_test_conf_tools_DEPENDENCIES) $(EXTRA_knot_test_conf_tools_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_conf_tools$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_conf_tools_OBJECTS) $(knot_test_conf_tools_LDADD) $(LIBS) +knot/test_confdb.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_confdb$(EXEEXT): $(knot_test_confdb_OBJECTS) $(knot_test_confdb_DEPENDENCIES) $(EXTRA_knot_test_confdb_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_confdb$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_confdb_OBJECTS) $(knot_test_confdb_LDADD) $(LIBS) +knot/test_confio.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_confio$(EXEEXT): $(knot_test_confio_OBJECTS) $(knot_test_confio_DEPENDENCIES) $(EXTRA_knot_test_confio_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_confio$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_confio_OBJECTS) $(knot_test_confio_LDADD) $(LIBS) +knot/test_digest.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_digest$(EXEEXT): $(knot_test_digest_OBJECTS) $(knot_test_digest_DEPENDENCIES) $(EXTRA_knot_test_digest_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_digest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_digest_OBJECTS) $(knot_test_digest_LDADD) $(LIBS) +knot/test_dthreads.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_dthreads$(EXEEXT): $(knot_test_dthreads_OBJECTS) $(knot_test_dthreads_DEPENDENCIES) $(EXTRA_knot_test_dthreads_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_dthreads$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_dthreads_OBJECTS) $(knot_test_dthreads_LDADD) $(LIBS) +knot/test_fdset.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_fdset$(EXEEXT): $(knot_test_fdset_OBJECTS) $(knot_test_fdset_DEPENDENCIES) $(EXTRA_knot_test_fdset_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_fdset$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_fdset_OBJECTS) $(knot_test_fdset_LDADD) $(LIBS) +knot/test_journal.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_journal$(EXEEXT): $(knot_test_journal_OBJECTS) $(knot_test_journal_DEPENDENCIES) $(EXTRA_knot_test_journal_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_journal$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_journal_OBJECTS) $(knot_test_journal_LDADD) $(LIBS) +knot/test_kasp_db.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_kasp_db$(EXEEXT): $(knot_test_kasp_db_OBJECTS) $(knot_test_kasp_db_DEPENDENCIES) $(EXTRA_knot_test_kasp_db_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_kasp_db$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_kasp_db_OBJECTS) $(knot_test_kasp_db_LDADD) $(LIBS) +knot/test_node.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_node$(EXEEXT): $(knot_test_node_OBJECTS) $(knot_test_node_DEPENDENCIES) $(EXTRA_knot_test_node_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_node$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_node_OBJECTS) $(knot_test_node_LDADD) $(LIBS) +knot/test_process_query.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_process_query$(EXEEXT): $(knot_test_process_query_OBJECTS) $(knot_test_process_query_DEPENDENCIES) $(EXTRA_knot_test_process_query_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_process_query$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_process_query_OBJECTS) $(knot_test_process_query_LDADD) $(LIBS) +knot/test_query_module.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_query_module$(EXEEXT): $(knot_test_query_module_OBJECTS) $(knot_test_query_module_DEPENDENCIES) $(EXTRA_knot_test_query_module_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_query_module$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_query_module_OBJECTS) $(knot_test_query_module_LDADD) $(LIBS) +knot/test_requestor.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_requestor$(EXEEXT): $(knot_test_requestor_OBJECTS) $(knot_test_requestor_DEPENDENCIES) $(EXTRA_knot_test_requestor_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_requestor$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_requestor_OBJECTS) $(knot_test_requestor_LDADD) $(LIBS) +knot/test_server.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_server$(EXEEXT): $(knot_test_server_OBJECTS) $(knot_test_server_DEPENDENCIES) $(EXTRA_knot_test_server_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_server$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_server_OBJECTS) $(knot_test_server_LDADD) $(LIBS) +knot/test_unreachable.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_unreachable$(EXEEXT): $(knot_test_unreachable_OBJECTS) $(knot_test_unreachable_DEPENDENCIES) $(EXTRA_knot_test_unreachable_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_unreachable$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_unreachable_OBJECTS) $(knot_test_unreachable_LDADD) $(LIBS) +knot/test_worker_pool.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_worker_pool$(EXEEXT): $(knot_test_worker_pool_OBJECTS) $(knot_test_worker_pool_DEPENDENCIES) $(EXTRA_knot_test_worker_pool_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_worker_pool$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_worker_pool_OBJECTS) $(knot_test_worker_pool_LDADD) $(LIBS) +knot/test_worker_queue.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_worker_queue$(EXEEXT): $(knot_test_worker_queue_OBJECTS) $(knot_test_worker_queue_DEPENDENCIES) $(EXTRA_knot_test_worker_queue_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_worker_queue$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_worker_queue_OBJECTS) $(knot_test_worker_queue_LDADD) $(LIBS) +knot/test_zone-tree.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zone-tree$(EXEEXT): $(knot_test_zone_tree_OBJECTS) $(knot_test_zone_tree_DEPENDENCIES) $(EXTRA_knot_test_zone_tree_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zone-tree$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zone_tree_OBJECTS) $(knot_test_zone_tree_LDADD) $(LIBS) +knot/test_zone-update.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zone-update$(EXEEXT): $(knot_test_zone_update_OBJECTS) $(knot_test_zone_update_DEPENDENCIES) $(EXTRA_knot_test_zone_update_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zone-update$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zone_update_OBJECTS) $(knot_test_zone_update_LDADD) $(LIBS) +knot/test_zone_events.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zone_events$(EXEEXT): $(knot_test_zone_events_OBJECTS) $(knot_test_zone_events_DEPENDENCIES) $(EXTRA_knot_test_zone_events_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zone_events$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zone_events_OBJECTS) $(knot_test_zone_events_LDADD) $(LIBS) +knot/test_zone_serial.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zone_serial$(EXEEXT): $(knot_test_zone_serial_OBJECTS) $(knot_test_zone_serial_DEPENDENCIES) $(EXTRA_knot_test_zone_serial_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zone_serial$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zone_serial_OBJECTS) $(knot_test_zone_serial_LDADD) $(LIBS) +knot/test_zone_timers.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zone_timers$(EXEEXT): $(knot_test_zone_timers_OBJECTS) $(knot_test_zone_timers_DEPENDENCIES) $(EXTRA_knot_test_zone_timers_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zone_timers$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zone_timers_OBJECTS) $(knot_test_zone_timers_LDADD) $(LIBS) +knot/test_zonedb.$(OBJEXT): knot/$(am__dirstamp) \ + knot/$(DEPDIR)/$(am__dirstamp) + +knot/test_zonedb$(EXEEXT): $(knot_test_zonedb_OBJECTS) $(knot_test_zonedb_DEPENDENCIES) $(EXTRA_knot_test_zonedb_DEPENDENCIES) knot/$(am__dirstamp) + @rm -f knot/test_zonedb$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(knot_test_zonedb_OBJECTS) $(knot_test_zonedb_LDADD) $(LIBS) +libdnssec/$(am__dirstamp): + @$(MKDIR_P) libdnssec + @: > libdnssec/$(am__dirstamp) +libdnssec/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) libdnssec/$(DEPDIR) + @: > libdnssec/$(DEPDIR)/$(am__dirstamp) +libdnssec/test_binary.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_binary$(EXEEXT): $(libdnssec_test_binary_OBJECTS) $(libdnssec_test_binary_DEPENDENCIES) $(EXTRA_libdnssec_test_binary_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_binary$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_binary_OBJECTS) $(libdnssec_test_binary_LDADD) $(LIBS) +libdnssec/test_crypto.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_crypto$(EXEEXT): $(libdnssec_test_crypto_OBJECTS) $(libdnssec_test_crypto_DEPENDENCIES) $(EXTRA_libdnssec_test_crypto_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_crypto$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_crypto_OBJECTS) $(libdnssec_test_crypto_LDADD) $(LIBS) +libdnssec/test_key.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_key$(EXEEXT): $(libdnssec_test_key_OBJECTS) $(libdnssec_test_key_DEPENDENCIES) $(EXTRA_libdnssec_test_key_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_key$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_key_OBJECTS) $(libdnssec_test_key_LDADD) $(LIBS) +libdnssec/test_key_algorithm.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_key_algorithm$(EXEEXT): $(libdnssec_test_key_algorithm_OBJECTS) $(libdnssec_test_key_algorithm_DEPENDENCIES) $(EXTRA_libdnssec_test_key_algorithm_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_key_algorithm$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_key_algorithm_OBJECTS) $(libdnssec_test_key_algorithm_LDADD) $(LIBS) +libdnssec/test_key_ds.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_key_ds$(EXEEXT): $(libdnssec_test_key_ds_OBJECTS) $(libdnssec_test_key_ds_DEPENDENCIES) $(EXTRA_libdnssec_test_key_ds_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_key_ds$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_key_ds_OBJECTS) $(libdnssec_test_key_ds_LDADD) $(LIBS) +libdnssec/test_keyid.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_keyid$(EXEEXT): $(libdnssec_test_keyid_OBJECTS) $(libdnssec_test_keyid_DEPENDENCIES) $(EXTRA_libdnssec_test_keyid_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_keyid$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_keyid_OBJECTS) $(libdnssec_test_keyid_LDADD) $(LIBS) +libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.$(OBJEXT): \ + libdnssec/$(am__dirstamp) libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_keystore_pkcs11$(EXEEXT): $(libdnssec_test_keystore_pkcs11_OBJECTS) $(libdnssec_test_keystore_pkcs11_DEPENDENCIES) $(EXTRA_libdnssec_test_keystore_pkcs11_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_keystore_pkcs11$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_keystore_pkcs11_OBJECTS) $(libdnssec_test_keystore_pkcs11_LDADD) $(LIBS) +libdnssec/test_keystore_pkcs8.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_keystore_pkcs8$(EXEEXT): $(libdnssec_test_keystore_pkcs8_OBJECTS) $(libdnssec_test_keystore_pkcs8_DEPENDENCIES) $(EXTRA_libdnssec_test_keystore_pkcs8_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_keystore_pkcs8$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_keystore_pkcs8_OBJECTS) $(libdnssec_test_keystore_pkcs8_LDADD) $(LIBS) +libdnssec/test_keytag.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_keytag$(EXEEXT): $(libdnssec_test_keytag_OBJECTS) $(libdnssec_test_keytag_DEPENDENCIES) $(EXTRA_libdnssec_test_keytag_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_keytag$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_keytag_OBJECTS) $(libdnssec_test_keytag_LDADD) $(LIBS) +libdnssec/test_nsec_bitmap.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_nsec_bitmap$(EXEEXT): $(libdnssec_test_nsec_bitmap_OBJECTS) $(libdnssec_test_nsec_bitmap_DEPENDENCIES) $(EXTRA_libdnssec_test_nsec_bitmap_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_nsec_bitmap$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_nsec_bitmap_OBJECTS) $(libdnssec_test_nsec_bitmap_LDADD) $(LIBS) +libdnssec/test_nsec_hash.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_nsec_hash$(EXEEXT): $(libdnssec_test_nsec_hash_OBJECTS) $(libdnssec_test_nsec_hash_DEPENDENCIES) $(EXTRA_libdnssec_test_nsec_hash_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_nsec_hash$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_nsec_hash_OBJECTS) $(libdnssec_test_nsec_hash_LDADD) $(LIBS) +libdnssec/test_random.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_random$(EXEEXT): $(libdnssec_test_random_OBJECTS) $(libdnssec_test_random_DEPENDENCIES) $(EXTRA_libdnssec_test_random_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_random$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_random_OBJECTS) $(libdnssec_test_random_LDADD) $(LIBS) +libdnssec/test_shared_bignum.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_shared_bignum$(EXEEXT): $(libdnssec_test_shared_bignum_OBJECTS) $(libdnssec_test_shared_bignum_DEPENDENCIES) $(EXTRA_libdnssec_test_shared_bignum_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_shared_bignum$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_shared_bignum_OBJECTS) $(libdnssec_test_shared_bignum_LDADD) $(LIBS) +libdnssec/test_shared_dname.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_shared_dname$(EXEEXT): $(libdnssec_test_shared_dname_OBJECTS) $(libdnssec_test_shared_dname_DEPENDENCIES) $(EXTRA_libdnssec_test_shared_dname_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_shared_dname$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_shared_dname_OBJECTS) $(libdnssec_test_shared_dname_LDADD) $(LIBS) +libdnssec/test_sign.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_sign$(EXEEXT): $(libdnssec_test_sign_OBJECTS) $(libdnssec_test_sign_DEPENDENCIES) $(EXTRA_libdnssec_test_sign_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_sign$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_sign_OBJECTS) $(libdnssec_test_sign_LDADD) $(LIBS) +libdnssec/test_sign_der.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_sign_der$(EXEEXT): $(libdnssec_test_sign_der_OBJECTS) $(libdnssec_test_sign_der_DEPENDENCIES) $(EXTRA_libdnssec_test_sign_der_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_sign_der$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_sign_der_OBJECTS) $(libdnssec_test_sign_der_LDADD) $(LIBS) +libdnssec/test_tsig.$(OBJEXT): libdnssec/$(am__dirstamp) \ + libdnssec/$(DEPDIR)/$(am__dirstamp) + +libdnssec/test_tsig$(EXEEXT): $(libdnssec_test_tsig_OBJECTS) $(libdnssec_test_tsig_DEPENDENCIES) $(EXTRA_libdnssec_test_tsig_DEPENDENCIES) libdnssec/$(am__dirstamp) + @rm -f libdnssec/test_tsig$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libdnssec_test_tsig_OBJECTS) $(libdnssec_test_tsig_LDADD) $(LIBS) +libknot/$(am__dirstamp): + @$(MKDIR_P) libknot + @: > libknot/$(am__dirstamp) +libknot/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) libknot/$(DEPDIR) + @: > libknot/$(DEPDIR)/$(am__dirstamp) +libknot/test_control.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_control$(EXEEXT): $(libknot_test_control_OBJECTS) $(libknot_test_control_DEPENDENCIES) $(EXTRA_libknot_test_control_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_control$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_control_OBJECTS) $(libknot_test_control_LDADD) $(LIBS) +libknot/test_cookies.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_cookies$(EXEEXT): $(libknot_test_cookies_OBJECTS) $(libknot_test_cookies_DEPENDENCIES) $(EXTRA_libknot_test_cookies_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_cookies$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_cookies_OBJECTS) $(libknot_test_cookies_LDADD) $(LIBS) +libknot/test_db.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_db$(EXEEXT): $(libknot_test_db_OBJECTS) $(libknot_test_db_DEPENDENCIES) $(EXTRA_libknot_test_db_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_db$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_db_OBJECTS) $(libknot_test_db_LDADD) $(LIBS) +libknot/test_descriptor.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_descriptor$(EXEEXT): $(libknot_test_descriptor_OBJECTS) $(libknot_test_descriptor_DEPENDENCIES) $(EXTRA_libknot_test_descriptor_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_descriptor$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_descriptor_OBJECTS) $(libknot_test_descriptor_LDADD) $(LIBS) +libknot/test_dname.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_dname$(EXEEXT): $(libknot_test_dname_OBJECTS) $(libknot_test_dname_DEPENDENCIES) $(EXTRA_libknot_test_dname_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_dname$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_dname_OBJECTS) $(libknot_test_dname_LDADD) $(LIBS) +libknot/test_dynarray.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_dynarray$(EXEEXT): $(libknot_test_dynarray_OBJECTS) $(libknot_test_dynarray_DEPENDENCIES) $(EXTRA_libknot_test_dynarray_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_dynarray$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_dynarray_OBJECTS) $(libknot_test_dynarray_LDADD) $(LIBS) +libknot/test_edns.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_edns$(EXEEXT): $(libknot_test_edns_OBJECTS) $(libknot_test_edns_DEPENDENCIES) $(EXTRA_libknot_test_edns_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_edns$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_edns_OBJECTS) $(libknot_test_edns_LDADD) $(LIBS) +libknot/test_edns_ecs.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_edns_ecs$(EXEEXT): $(libknot_test_edns_ecs_OBJECTS) $(libknot_test_edns_ecs_DEPENDENCIES) $(EXTRA_libknot_test_edns_ecs_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_edns_ecs$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_edns_ecs_OBJECTS) $(libknot_test_edns_ecs_LDADD) $(LIBS) +libknot/test_endian.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_endian$(EXEEXT): $(libknot_test_endian_OBJECTS) $(libknot_test_endian_DEPENDENCIES) $(EXTRA_libknot_test_endian_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_endian$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_endian_OBJECTS) $(libknot_test_endian_LDADD) $(LIBS) +libknot/test_lookup.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_lookup$(EXEEXT): $(libknot_test_lookup_OBJECTS) $(libknot_test_lookup_DEPENDENCIES) $(EXTRA_libknot_test_lookup_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_lookup_OBJECTS) $(libknot_test_lookup_LDADD) $(LIBS) +libknot/test_pkt.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_pkt$(EXEEXT): $(libknot_test_pkt_OBJECTS) $(libknot_test_pkt_DEPENDENCIES) $(EXTRA_libknot_test_pkt_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_pkt$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_pkt_OBJECTS) $(libknot_test_pkt_LDADD) $(LIBS) +libknot/test_probe.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_probe$(EXEEXT): $(libknot_test_probe_OBJECTS) $(libknot_test_probe_DEPENDENCIES) $(EXTRA_libknot_test_probe_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_probe$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_probe_OBJECTS) $(libknot_test_probe_LDADD) $(LIBS) +libknot/test_rdata.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_rdata$(EXEEXT): $(libknot_test_rdata_OBJECTS) $(libknot_test_rdata_DEPENDENCIES) $(EXTRA_libknot_test_rdata_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_rdata$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_rdata_OBJECTS) $(libknot_test_rdata_LDADD) $(LIBS) +libknot/test_rdataset.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_rdataset$(EXEEXT): $(libknot_test_rdataset_OBJECTS) $(libknot_test_rdataset_DEPENDENCIES) $(EXTRA_libknot_test_rdataset_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_rdataset$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_rdataset_OBJECTS) $(libknot_test_rdataset_LDADD) $(LIBS) +libknot/test_rrset.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_rrset$(EXEEXT): $(libknot_test_rrset_OBJECTS) $(libknot_test_rrset_DEPENDENCIES) $(EXTRA_libknot_test_rrset_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_rrset$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_rrset_OBJECTS) $(libknot_test_rrset_LDADD) $(LIBS) +libknot/test_rrset-wire.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_rrset-wire$(EXEEXT): $(libknot_test_rrset_wire_OBJECTS) $(libknot_test_rrset_wire_DEPENDENCIES) $(EXTRA_libknot_test_rrset_wire_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_rrset-wire$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_rrset_wire_OBJECTS) $(libknot_test_rrset_wire_LDADD) $(LIBS) +libknot/test_tsig.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_tsig$(EXEEXT): $(libknot_test_tsig_OBJECTS) $(libknot_test_tsig_DEPENDENCIES) $(EXTRA_libknot_test_tsig_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_tsig$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_tsig_OBJECTS) $(libknot_test_tsig_LDADD) $(LIBS) +libknot/test_wire.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_wire$(EXEEXT): $(libknot_test_wire_OBJECTS) $(libknot_test_wire_DEPENDENCIES) $(EXTRA_libknot_test_wire_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_wire$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_wire_OBJECTS) $(libknot_test_wire_LDADD) $(LIBS) +libknot/test_xdp_tcp.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_xdp_tcp$(EXEEXT): $(libknot_test_xdp_tcp_OBJECTS) $(libknot_test_xdp_tcp_DEPENDENCIES) $(EXTRA_libknot_test_xdp_tcp_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_xdp_tcp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_xdp_tcp_OBJECTS) $(libknot_test_xdp_tcp_LDADD) $(LIBS) +libknot/test_yparser.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_yparser$(EXEEXT): $(libknot_test_yparser_OBJECTS) $(libknot_test_yparser_DEPENDENCIES) $(EXTRA_libknot_test_yparser_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_yparser$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_yparser_OBJECTS) $(libknot_test_yparser_LDADD) $(LIBS) +libknot/test_ypschema.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_ypschema$(EXEEXT): $(libknot_test_ypschema_OBJECTS) $(libknot_test_ypschema_DEPENDENCIES) $(EXTRA_libknot_test_ypschema_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_ypschema$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_ypschema_OBJECTS) $(libknot_test_ypschema_LDADD) $(LIBS) +libknot/test_yptrafo.$(OBJEXT): libknot/$(am__dirstamp) \ + libknot/$(DEPDIR)/$(am__dirstamp) + +libknot/test_yptrafo$(EXEEXT): $(libknot_test_yptrafo_OBJECTS) $(libknot_test_yptrafo_DEPENDENCIES) $(EXTRA_libknot_test_yptrafo_DEPENDENCIES) libknot/$(am__dirstamp) + @rm -f libknot/test_yptrafo$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libknot_test_yptrafo_OBJECTS) $(libknot_test_yptrafo_LDADD) $(LIBS) +libzscanner/$(am__dirstamp): + @$(MKDIR_P) libzscanner + @: > libzscanner/$(am__dirstamp) +libzscanner/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) libzscanner/$(DEPDIR) + @: > libzscanner/$(DEPDIR)/$(am__dirstamp) +libzscanner/zscanner-tool.$(OBJEXT): libzscanner/$(am__dirstamp) \ + libzscanner/$(DEPDIR)/$(am__dirstamp) +libzscanner/processing.$(OBJEXT): libzscanner/$(am__dirstamp) \ + libzscanner/$(DEPDIR)/$(am__dirstamp) + +libzscanner/zscanner-tool$(EXEEXT): $(libzscanner_zscanner_tool_OBJECTS) $(libzscanner_zscanner_tool_DEPENDENCIES) $(EXTRA_libzscanner_zscanner_tool_DEPENDENCIES) libzscanner/$(am__dirstamp) + @rm -f libzscanner/zscanner-tool$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(libzscanner_zscanner_tool_OBJECTS) $(libzscanner_zscanner_tool_LDADD) $(LIBS) +modules/$(am__dirstamp): + @$(MKDIR_P) modules + @: > modules/$(am__dirstamp) +modules/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) modules/$(DEPDIR) + @: > modules/$(DEPDIR)/$(am__dirstamp) +modules/test_onlinesign.$(OBJEXT): modules/$(am__dirstamp) \ + modules/$(DEPDIR)/$(am__dirstamp) + +modules/test_onlinesign$(EXEEXT): $(modules_test_onlinesign_OBJECTS) $(modules_test_onlinesign_DEPENDENCIES) $(EXTRA_modules_test_onlinesign_DEPENDENCIES) modules/$(am__dirstamp) + @rm -f modules/test_onlinesign$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(modules_test_onlinesign_OBJECTS) $(modules_test_onlinesign_LDADD) $(LIBS) +modules/test_rrl.$(OBJEXT): modules/$(am__dirstamp) \ + modules/$(DEPDIR)/$(am__dirstamp) + +modules/test_rrl$(EXEEXT): $(modules_test_rrl_OBJECTS) $(modules_test_rrl_DEPENDENCIES) $(EXTRA_modules_test_rrl_DEPENDENCIES) modules/$(am__dirstamp) + @rm -f modules/test_rrl$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(modules_test_rrl_OBJECTS) $(modules_test_rrl_LDADD) $(LIBS) +tap/runtests.$(OBJEXT): tap/$(am__dirstamp) \ + tap/$(DEPDIR)/$(am__dirstamp) + +tap/runtests$(EXEEXT): $(tap_runtests_OBJECTS) $(tap_runtests_DEPENDENCIES) $(EXTRA_tap_runtests_DEPENDENCIES) tap/$(am__dirstamp) + @rm -f tap/runtests$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(tap_runtests_OBJECTS) $(tap_runtests_LDADD) $(LIBS) +utils/$(am__dirstamp): + @$(MKDIR_P) utils + @: > utils/$(am__dirstamp) +utils/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) utils/$(DEPDIR) + @: > utils/$(DEPDIR)/$(am__dirstamp) +utils/utils_test_lookup-test_lookup.$(OBJEXT): utils/$(am__dirstamp) \ + utils/$(DEPDIR)/$(am__dirstamp) + +utils/test_lookup$(EXEEXT): $(utils_test_lookup_OBJECTS) $(utils_test_lookup_DEPENDENCIES) $(EXTRA_utils_test_lookup_DEPENDENCIES) utils/$(am__dirstamp) + @rm -f utils/test_lookup$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(utils_test_lookup_OBJECTS) $(utils_test_lookup_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f contrib/*.$(OBJEXT) + -rm -f knot/*.$(OBJEXT) + -rm -f libdnssec/*.$(OBJEXT) + -rm -f libknot/*.$(OBJEXT) + -rm -f libzscanner/*.$(OBJEXT) + -rm -f modules/*.$(OBJEXT) + -rm -f tap/*.$(OBJEXT) + -rm -f tap/*.lo + -rm -f utils/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_base32hex.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_base64.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_base64url.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_heap.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_inet_ntop.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_net.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_net_shortwrite.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_qp-cow.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_qp-trie.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_siphash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_sockaddr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_spinlock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_string.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_strtonum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_time.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_toeplitz.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@contrib/$(DEPDIR)/test_wire_ctx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_acl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_changeset.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_conf.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_conf_tools.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_confdb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_confio.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_digest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_dthreads.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_fdset.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_journal.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_kasp_db.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_node.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_process_query.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_query_module.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_requestor.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_server.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_unreachable.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_worker_pool.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_worker_queue.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zone-tree.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zone-update.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zone_events.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zone_serial.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zone_timers.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@knot/$(DEPDIR)/test_zonedb.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_binary.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_crypto.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_key.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_key_algorithm.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_key_ds.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_keyid.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_keystore_pkcs11-test_keystore_pkcs11.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_keystore_pkcs8.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_keytag.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_nsec_bitmap.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_nsec_hash.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_random.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_shared_bignum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_shared_dname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_sign.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_sign_der.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libdnssec/$(DEPDIR)/test_tsig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_control.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_cookies.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_db.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_descriptor.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_dname.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_dynarray.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_edns.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_edns_ecs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_endian.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_lookup.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_pkt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_probe.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_rdata.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_rdataset.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_rrset-wire.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_rrset.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_tsig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_wire.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_xdp_tcp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_yparser.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_ypschema.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libknot/$(DEPDIR)/test_yptrafo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libzscanner/$(DEPDIR)/processing.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@libzscanner/$(DEPDIR)/zscanner-tool.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@modules/$(DEPDIR)/test_onlinesign.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@modules/$(DEPDIR)/test_rrl.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tap/$(DEPDIR)/basic.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tap/$(DEPDIR)/files.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tap/$(DEPDIR)/float.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@tap/$(DEPDIR)/runtests.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/utils_test_lookup-test_lookup.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.o: libdnssec/test_keystore_pkcs11.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdnssec_test_keystore_pkcs11_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.o -MD -MP -MF libdnssec/$(DEPDIR)/test_keystore_pkcs11-test_keystore_pkcs11.Tpo -c -o libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.o `test -f 'libdnssec/test_keystore_pkcs11.c' || echo '$(srcdir)/'`libdnssec/test_keystore_pkcs11.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libdnssec/$(DEPDIR)/test_keystore_pkcs11-test_keystore_pkcs11.Tpo libdnssec/$(DEPDIR)/test_keystore_pkcs11-test_keystore_pkcs11.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libdnssec/test_keystore_pkcs11.c' object='libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdnssec_test_keystore_pkcs11_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.o `test -f 'libdnssec/test_keystore_pkcs11.c' || echo '$(srcdir)/'`libdnssec/test_keystore_pkcs11.c + +libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.obj: libdnssec/test_keystore_pkcs11.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdnssec_test_keystore_pkcs11_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.obj -MD -MP -MF libdnssec/$(DEPDIR)/test_keystore_pkcs11-test_keystore_pkcs11.Tpo -c -o libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.obj `if test -f 'libdnssec/test_keystore_pkcs11.c'; then $(CYGPATH_W) 'libdnssec/test_keystore_pkcs11.c'; else $(CYGPATH_W) '$(srcdir)/libdnssec/test_keystore_pkcs11.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) libdnssec/$(DEPDIR)/test_keystore_pkcs11-test_keystore_pkcs11.Tpo libdnssec/$(DEPDIR)/test_keystore_pkcs11-test_keystore_pkcs11.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libdnssec/test_keystore_pkcs11.c' object='libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdnssec_test_keystore_pkcs11_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdnssec/test_keystore_pkcs11-test_keystore_pkcs11.obj `if test -f 'libdnssec/test_keystore_pkcs11.c'; then $(CYGPATH_W) 'libdnssec/test_keystore_pkcs11.c'; else $(CYGPATH_W) '$(srcdir)/libdnssec/test_keystore_pkcs11.c'; fi` + +utils/utils_test_lookup-test_lookup.o: utils/test_lookup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_lookup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utils/utils_test_lookup-test_lookup.o -MD -MP -MF utils/$(DEPDIR)/utils_test_lookup-test_lookup.Tpo -c -o utils/utils_test_lookup-test_lookup.o `test -f 'utils/test_lookup.c' || echo '$(srcdir)/'`utils/test_lookup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) utils/$(DEPDIR)/utils_test_lookup-test_lookup.Tpo utils/$(DEPDIR)/utils_test_lookup-test_lookup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/test_lookup.c' object='utils/utils_test_lookup-test_lookup.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_lookup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utils/utils_test_lookup-test_lookup.o `test -f 'utils/test_lookup.c' || echo '$(srcdir)/'`utils/test_lookup.c + +utils/utils_test_lookup-test_lookup.obj: utils/test_lookup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_lookup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utils/utils_test_lookup-test_lookup.obj -MD -MP -MF utils/$(DEPDIR)/utils_test_lookup-test_lookup.Tpo -c -o utils/utils_test_lookup-test_lookup.obj `if test -f 'utils/test_lookup.c'; then $(CYGPATH_W) 'utils/test_lookup.c'; else $(CYGPATH_W) '$(srcdir)/utils/test_lookup.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) utils/$(DEPDIR)/utils_test_lookup-test_lookup.Tpo utils/$(DEPDIR)/utils_test_lookup-test_lookup.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='utils/test_lookup.c' object='utils/utils_test_lookup-test_lookup.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(utils_test_lookup_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utils/utils_test_lookup-test_lookup.obj `if test -f 'utils/test_lookup.c'; then $(CYGPATH_W) 'utils/test_lookup.c'; else $(CYGPATH_W) '$(srcdir)/utils/test_lookup.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf contrib/.libs contrib/_libs + -rm -rf knot/.libs knot/_libs + -rm -rf libdnssec/.libs libdnssec/_libs + -rm -rf libknot/.libs libknot/_libs + -rm -rf libzscanner/.libs libzscanner/_libs + -rm -rf modules/.libs modules/_libs + -rm -rf tap/.libs tap/_libs + -rm -rf utils/.libs utils/_libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(check_LTLIBRARIES) \ + $(check_SCRIPTS) + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f contrib/$(DEPDIR)/$(am__dirstamp) + -rm -f contrib/$(am__dirstamp) + -rm -f knot/$(DEPDIR)/$(am__dirstamp) + -rm -f knot/$(am__dirstamp) + -rm -f libdnssec/$(DEPDIR)/$(am__dirstamp) + -rm -f libdnssec/$(am__dirstamp) + -rm -f libknot/$(DEPDIR)/$(am__dirstamp) + -rm -f libknot/$(am__dirstamp) + -rm -f libzscanner/$(DEPDIR)/$(am__dirstamp) + -rm -f libzscanner/$(am__dirstamp) + -rm -f modules/$(DEPDIR)/$(am__dirstamp) + -rm -f modules/$(am__dirstamp) + -rm -f tap/$(DEPDIR)/$(am__dirstamp) + -rm -f tap/$(am__dirstamp) + -rm -f utils/$(DEPDIR)/$(am__dirstamp) + -rm -f utils/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ + clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f contrib/$(DEPDIR)/test_base32hex.Po + -rm -f contrib/$(DEPDIR)/test_base64.Po + -rm -f contrib/$(DEPDIR)/test_base64url.Po + -rm -f contrib/$(DEPDIR)/test_heap.Po + -rm -f contrib/$(DEPDIR)/test_inet_ntop.Po + -rm -f contrib/$(DEPDIR)/test_net.Po + -rm -f contrib/$(DEPDIR)/test_net_shortwrite.Po + -rm -f contrib/$(DEPDIR)/test_qp-cow.Po + -rm -f contrib/$(DEPDIR)/test_qp-trie.Po + -rm -f contrib/$(DEPDIR)/test_siphash.Po + -rm -f contrib/$(DEPDIR)/test_sockaddr.Po + -rm -f contrib/$(DEPDIR)/test_spinlock.Po + -rm -f contrib/$(DEPDIR)/test_string.Po + -rm -f contrib/$(DEPDIR)/test_strtonum.Po + -rm -f contrib/$(DEPDIR)/test_time.Po + -rm -f contrib/$(DEPDIR)/test_toeplitz.Po + -rm -f contrib/$(DEPDIR)/test_wire_ctx.Po + -rm -f knot/$(DEPDIR)/test_acl.Po + -rm -f knot/$(DEPDIR)/test_changeset.Po + -rm -f knot/$(DEPDIR)/test_conf.Po + -rm -f knot/$(DEPDIR)/test_conf_tools.Po + -rm -f knot/$(DEPDIR)/test_confdb.Po + -rm -f knot/$(DEPDIR)/test_confio.Po + -rm -f knot/$(DEPDIR)/test_digest.Po + -rm -f knot/$(DEPDIR)/test_dthreads.Po + -rm -f knot/$(DEPDIR)/test_fdset.Po + -rm -f knot/$(DEPDIR)/test_journal.Po + -rm -f knot/$(DEPDIR)/test_kasp_db.Po + -rm -f knot/$(DEPDIR)/test_node.Po + -rm -f knot/$(DEPDIR)/test_process_query.Po + -rm -f knot/$(DEPDIR)/test_query_module.Po + -rm -f knot/$(DEPDIR)/test_requestor.Po + -rm -f knot/$(DEPDIR)/test_server.Po + -rm -f knot/$(DEPDIR)/test_unreachable.Po + -rm -f knot/$(DEPDIR)/test_worker_pool.Po + -rm -f knot/$(DEPDIR)/test_worker_queue.Po + -rm -f knot/$(DEPDIR)/test_zone-tree.Po + -rm -f knot/$(DEPDIR)/test_zone-update.Po + -rm -f knot/$(DEPDIR)/test_zone_events.Po + -rm -f knot/$(DEPDIR)/test_zone_serial.Po + -rm -f knot/$(DEPDIR)/test_zone_timers.Po + -rm -f knot/$(DEPDIR)/test_zonedb.Po + -rm -f libdnssec/$(DEPDIR)/test_binary.Po + -rm -f libdnssec/$(DEPDIR)/test_crypto.Po + -rm -f libdnssec/$(DEPDIR)/test_key.Po + -rm -f libdnssec/$(DEPDIR)/test_key_algorithm.Po + -rm -f libdnssec/$(DEPDIR)/test_key_ds.Po + -rm -f libdnssec/$(DEPDIR)/test_keyid.Po + -rm -f libdnssec/$(DEPDIR)/test_keystore_pkcs11-test_keystore_pkcs11.Po + -rm -f libdnssec/$(DEPDIR)/test_keystore_pkcs8.Po + -rm -f libdnssec/$(DEPDIR)/test_keytag.Po + -rm -f libdnssec/$(DEPDIR)/test_nsec_bitmap.Po + -rm -f libdnssec/$(DEPDIR)/test_nsec_hash.Po + -rm -f libdnssec/$(DEPDIR)/test_random.Po + -rm -f libdnssec/$(DEPDIR)/test_shared_bignum.Po + -rm -f libdnssec/$(DEPDIR)/test_shared_dname.Po + -rm -f libdnssec/$(DEPDIR)/test_sign.Po + -rm -f libdnssec/$(DEPDIR)/test_sign_der.Po + -rm -f libdnssec/$(DEPDIR)/test_tsig.Po + -rm -f libknot/$(DEPDIR)/test_control.Po + -rm -f libknot/$(DEPDIR)/test_cookies.Po + -rm -f libknot/$(DEPDIR)/test_db.Po + -rm -f libknot/$(DEPDIR)/test_descriptor.Po + -rm -f libknot/$(DEPDIR)/test_dname.Po + -rm -f libknot/$(DEPDIR)/test_dynarray.Po + -rm -f libknot/$(DEPDIR)/test_edns.Po + -rm -f libknot/$(DEPDIR)/test_edns_ecs.Po + -rm -f libknot/$(DEPDIR)/test_endian.Po + -rm -f libknot/$(DEPDIR)/test_lookup.Po + -rm -f libknot/$(DEPDIR)/test_pkt.Po + -rm -f libknot/$(DEPDIR)/test_probe.Po + -rm -f libknot/$(DEPDIR)/test_rdata.Po + -rm -f libknot/$(DEPDIR)/test_rdataset.Po + -rm -f libknot/$(DEPDIR)/test_rrset-wire.Po + -rm -f libknot/$(DEPDIR)/test_rrset.Po + -rm -f libknot/$(DEPDIR)/test_tsig.Po + -rm -f libknot/$(DEPDIR)/test_wire.Po + -rm -f libknot/$(DEPDIR)/test_xdp_tcp.Po + -rm -f libknot/$(DEPDIR)/test_yparser.Po + -rm -f libknot/$(DEPDIR)/test_ypschema.Po + -rm -f libknot/$(DEPDIR)/test_yptrafo.Po + -rm -f libzscanner/$(DEPDIR)/processing.Po + -rm -f libzscanner/$(DEPDIR)/zscanner-tool.Po + -rm -f modules/$(DEPDIR)/test_onlinesign.Po + -rm -f modules/$(DEPDIR)/test_rrl.Po + -rm -f tap/$(DEPDIR)/basic.Plo + -rm -f tap/$(DEPDIR)/files.Plo + -rm -f tap/$(DEPDIR)/float.Plo + -rm -f tap/$(DEPDIR)/runtests.Po + -rm -f utils/$(DEPDIR)/utils_test_lookup-test_lookup.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f contrib/$(DEPDIR)/test_base32hex.Po + -rm -f contrib/$(DEPDIR)/test_base64.Po + -rm -f contrib/$(DEPDIR)/test_base64url.Po + -rm -f contrib/$(DEPDIR)/test_heap.Po + -rm -f contrib/$(DEPDIR)/test_inet_ntop.Po + -rm -f contrib/$(DEPDIR)/test_net.Po + -rm -f contrib/$(DEPDIR)/test_net_shortwrite.Po + -rm -f contrib/$(DEPDIR)/test_qp-cow.Po + -rm -f contrib/$(DEPDIR)/test_qp-trie.Po + -rm -f contrib/$(DEPDIR)/test_siphash.Po + -rm -f contrib/$(DEPDIR)/test_sockaddr.Po + -rm -f contrib/$(DEPDIR)/test_spinlock.Po + -rm -f contrib/$(DEPDIR)/test_string.Po + -rm -f contrib/$(DEPDIR)/test_strtonum.Po + -rm -f contrib/$(DEPDIR)/test_time.Po + -rm -f contrib/$(DEPDIR)/test_toeplitz.Po + -rm -f contrib/$(DEPDIR)/test_wire_ctx.Po + -rm -f knot/$(DEPDIR)/test_acl.Po + -rm -f knot/$(DEPDIR)/test_changeset.Po + -rm -f knot/$(DEPDIR)/test_conf.Po + -rm -f knot/$(DEPDIR)/test_conf_tools.Po + -rm -f knot/$(DEPDIR)/test_confdb.Po + -rm -f knot/$(DEPDIR)/test_confio.Po + -rm -f knot/$(DEPDIR)/test_digest.Po + -rm -f knot/$(DEPDIR)/test_dthreads.Po + -rm -f knot/$(DEPDIR)/test_fdset.Po + -rm -f knot/$(DEPDIR)/test_journal.Po + -rm -f knot/$(DEPDIR)/test_kasp_db.Po + -rm -f knot/$(DEPDIR)/test_node.Po + -rm -f knot/$(DEPDIR)/test_process_query.Po + -rm -f knot/$(DEPDIR)/test_query_module.Po + -rm -f knot/$(DEPDIR)/test_requestor.Po + -rm -f knot/$(DEPDIR)/test_server.Po + -rm -f knot/$(DEPDIR)/test_unreachable.Po + -rm -f knot/$(DEPDIR)/test_worker_pool.Po + -rm -f knot/$(DEPDIR)/test_worker_queue.Po + -rm -f knot/$(DEPDIR)/test_zone-tree.Po + -rm -f knot/$(DEPDIR)/test_zone-update.Po + -rm -f knot/$(DEPDIR)/test_zone_events.Po + -rm -f knot/$(DEPDIR)/test_zone_serial.Po + -rm -f knot/$(DEPDIR)/test_zone_timers.Po + -rm -f knot/$(DEPDIR)/test_zonedb.Po + -rm -f libdnssec/$(DEPDIR)/test_binary.Po + -rm -f libdnssec/$(DEPDIR)/test_crypto.Po + -rm -f libdnssec/$(DEPDIR)/test_key.Po + -rm -f libdnssec/$(DEPDIR)/test_key_algorithm.Po + -rm -f libdnssec/$(DEPDIR)/test_key_ds.Po + -rm -f libdnssec/$(DEPDIR)/test_keyid.Po + -rm -f libdnssec/$(DEPDIR)/test_keystore_pkcs11-test_keystore_pkcs11.Po + -rm -f libdnssec/$(DEPDIR)/test_keystore_pkcs8.Po + -rm -f libdnssec/$(DEPDIR)/test_keytag.Po + -rm -f libdnssec/$(DEPDIR)/test_nsec_bitmap.Po + -rm -f libdnssec/$(DEPDIR)/test_nsec_hash.Po + -rm -f libdnssec/$(DEPDIR)/test_random.Po + -rm -f libdnssec/$(DEPDIR)/test_shared_bignum.Po + -rm -f libdnssec/$(DEPDIR)/test_shared_dname.Po + -rm -f libdnssec/$(DEPDIR)/test_sign.Po + -rm -f libdnssec/$(DEPDIR)/test_sign_der.Po + -rm -f libdnssec/$(DEPDIR)/test_tsig.Po + -rm -f libknot/$(DEPDIR)/test_control.Po + -rm -f libknot/$(DEPDIR)/test_cookies.Po + -rm -f libknot/$(DEPDIR)/test_db.Po + -rm -f libknot/$(DEPDIR)/test_descriptor.Po + -rm -f libknot/$(DEPDIR)/test_dname.Po + -rm -f libknot/$(DEPDIR)/test_dynarray.Po + -rm -f libknot/$(DEPDIR)/test_edns.Po + -rm -f libknot/$(DEPDIR)/test_edns_ecs.Po + -rm -f libknot/$(DEPDIR)/test_endian.Po + -rm -f libknot/$(DEPDIR)/test_lookup.Po + -rm -f libknot/$(DEPDIR)/test_pkt.Po + -rm -f libknot/$(DEPDIR)/test_probe.Po + -rm -f libknot/$(DEPDIR)/test_rdata.Po + -rm -f libknot/$(DEPDIR)/test_rdataset.Po + -rm -f libknot/$(DEPDIR)/test_rrset-wire.Po + -rm -f libknot/$(DEPDIR)/test_rrset.Po + -rm -f libknot/$(DEPDIR)/test_tsig.Po + -rm -f libknot/$(DEPDIR)/test_wire.Po + -rm -f libknot/$(DEPDIR)/test_xdp_tcp.Po + -rm -f libknot/$(DEPDIR)/test_yparser.Po + -rm -f libknot/$(DEPDIR)/test_ypschema.Po + -rm -f libknot/$(DEPDIR)/test_yptrafo.Po + -rm -f libzscanner/$(DEPDIR)/processing.Po + -rm -f libzscanner/$(DEPDIR)/zscanner-tool.Po + -rm -f modules/$(DEPDIR)/test_onlinesign.Po + -rm -f modules/$(DEPDIR)/test_rrl.Po + -rm -f tap/$(DEPDIR)/basic.Plo + -rm -f tap/$(DEPDIR)/files.Plo + -rm -f tap/$(DEPDIR)/float.Plo + -rm -f tap/$(DEPDIR)/runtests.Po + -rm -f utils/$(DEPDIR)/utils_test_lookup-test_lookup.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am \ + check-local clean clean-checkLTLIBRARIES clean-checkPROGRAMS \ + clean-generic clean-libtool cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +@HAVE_LIBUTILS_TRUE@knot/test_semantic_check: +@HAVE_LIBUTILS_TRUE@ @$(edit) < $(top_srcdir)/tests/$@.in > $(top_builddir)/tests/$@ +@HAVE_LIBUTILS_TRUE@ @chmod +x $(top_builddir)/tests/$@ + +libzscanner/test_zscanner: libzscanner/zscanner-tool + @$(edit) < $(top_srcdir)/tests/$@.in > $(top_builddir)/tests/$@ + @chmod +x $(top_builddir)/tests/$@ + +check-compile: $(check_LTLIBRARIES) $(EXTRA_PROGRAMS) $(check_PROGRAMS) $(check_SCRIPTS) +check-local: $(check_LTLIBRARIES) $(EXTRA_PROGRAMS) $(check_PROGRAMS) $(check_SCRIPTS) + @$(top_builddir)/tests/tap/runtests -s $(srcdir) -b $(builddir) \ + -L $(builddir)/runtests.log $(check_PROGRAMS) $(check_SCRIPTS); \ + $(AM_V_RUNTESTS) + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tests/contrib/test_base32hex.c b/tests/contrib/test_base32hex.c new file mode 100644 index 0000000..541667c --- /dev/null +++ b/tests/contrib/test_base32hex.c @@ -0,0 +1,267 @@ +/* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/libknot.h" +#include "contrib/base32hex.h" +#include "contrib/openbsd/strlcpy.h" + +#define BUF_LEN 256 +#define MAX_BIN_DATA_LEN ((INT32_MAX / 8) * 5) + +int main(int argc, char *argv[]) +{ + plan(67); + + int32_t ret; + uint8_t in[BUF_LEN], ref[BUF_LEN], out[BUF_LEN], out2[BUF_LEN], *out3; + uint32_t in_len, ref_len; + + // 0. test invalid input + ret = knot_base32hex_encode(NULL, 0, out, BUF_LEN); + is_int(KNOT_EINVAL, ret, "knot_base32hex_encode: NULL input buffer"); + ret = knot_base32hex_encode(in, BUF_LEN, NULL, 0); + is_int(KNOT_EINVAL, ret, "knot_base32hex_encode: NULL output buffer"); + ret = knot_base32hex_encode(in, MAX_BIN_DATA_LEN + 1, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "knot_base32hex_encode: input buffer too large"); + ret = knot_base32hex_encode(in, BUF_LEN, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "knot_base32hex_encode: output buffer too small"); + + ret = knot_base32hex_encode_alloc(NULL, 0, &out3); + is_int(KNOT_EINVAL, ret, "knot_base32hex_encode_alloc: NULL input buffer"); + ret = knot_base32hex_encode_alloc(in, MAX_BIN_DATA_LEN + 1, &out3); + is_int(KNOT_ERANGE, ret, "knot_base32hex_encode_alloc: input buffer too large"); + ret = knot_base32hex_encode_alloc(in, BUF_LEN, NULL); + is_int(KNOT_EINVAL, ret, "knot_base32hex_encode_alloc: NULL output buffer"); + + ret = knot_base32hex_decode(NULL, 0, out, BUF_LEN); + is_int(KNOT_EINVAL, ret, "knot_base32hex_decode: NULL input buffer"); + ret = knot_base32hex_decode(in, BUF_LEN, NULL, 0); + is_int(KNOT_EINVAL, ret, "knot_base32hex_decode: NULL output buffer"); + ret = knot_base32hex_decode(in, UINT32_MAX, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "knot_base32hex_decode: input buffer too large"); + ret = knot_base32hex_decode(in, BUF_LEN, out, 0); + is_int(KNOT_ERANGE, ret, "knot_base32hex_decode: output buffer too small"); + + ret = knot_base32hex_decode_alloc(NULL, 0, &out3); + is_int(KNOT_EINVAL, ret, "knot_base32hex_decode_alloc: NULL input buffer"); + ret = knot_base32hex_decode_alloc(in, UINT32_MAX, &out3); + is_int(KNOT_ERANGE, ret, "knot_base32hex_decode_aloc: input buffer too large"); + ret = knot_base32hex_decode_alloc(in, BUF_LEN, NULL); + is_int(KNOT_EINVAL, ret, "knot_base32hex_decode_alloc: NULL output buffer"); + + // 1. test vector -> ENC -> DEC + strlcpy((char *)in, "", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "1. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "1. test vector - ENC output content"); + } + ret = knot_base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "1. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "1. test vector - DEC output content"); + } + + // 2. test vector -> ENC -> DEC + strlcpy((char *)in, "f", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "co======", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "2. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "2. test vector - ENC output content"); + } + ret = knot_base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "2. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "2. test vector - DEC output content"); + } + + // 3. test vector -> ENC -> DEC + strlcpy((char *)in, "fo", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "cpng====", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "3. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "3. test vector - ENC output content"); + } + ret = knot_base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "3. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "3. test vector - DEC output content"); + } + + // 4. test vector -> ENC -> DEC + strlcpy((char *)in, "foo", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "cpnmu===", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "4. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "4. test vector - ENC output content"); + } + ret = knot_base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "4. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "4. test vector - DEC output content"); + } + + // 5. test vector -> ENC -> DEC + strlcpy((char *)in, "foob", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "cpnmuog=", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "5. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "5. test vector - ENC output content"); + } + ret = knot_base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "5. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "5. test vector - DEC output content"); + } + + // 6. test vector -> ENC -> DEC + strlcpy((char *)in, "fooba", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "cpnmuoj1", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "6. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "6. test vector - ENC output content"); + } + ret = knot_base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "6. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "6. test vector - DEC output content"); + } + + // 7. test vector -> ENC -> DEC + strlcpy((char *)in, "foobar", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "cpnmuoj1e8======", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base32hex_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "7. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "7. test vector - ENC output content"); + } + ret = knot_base32hex_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "7. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "7. test vector - DEC output content"); + } + + // Bad paddings + ret = knot_base32hex_decode((uint8_t *)"AAAAAA==", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding length 2"); + ret = knot_base32hex_decode((uint8_t *)"AAA=====", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding length 5"); + ret = knot_base32hex_decode((uint8_t *)"A=======", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding length 7"); + ret = knot_base32hex_decode((uint8_t *)"========", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding length 8"); + ret = knot_base32hex_decode((uint8_t *)"AAAAA=A=", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding character on position 2"); + ret = knot_base32hex_decode((uint8_t *)"AA=A====", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding character on position 5"); + ret = knot_base32hex_decode((uint8_t *)"=A======", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad padding character on position 7"); + ret = knot_base32hex_decode((uint8_t *)"CO======CO======", 16, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Two octects with padding"); + + // Bad data length + ret = knot_base32hex_decode((uint8_t *)"A", 1, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 1"); + ret = knot_base32hex_decode((uint8_t *)"AA", 2, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 2"); + ret = knot_base32hex_decode((uint8_t *)"AAA", 3, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 3"); + ret = knot_base32hex_decode((uint8_t *)"AAAA", 4, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 4"); + ret = knot_base32hex_decode((uint8_t *)"AAAAA", 5, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 5"); + ret = knot_base32hex_decode((uint8_t *)"AAAAAA", 6, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 6"); + ret = knot_base32hex_decode((uint8_t *)"AAAAAAA", 7, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 7"); + ret = knot_base32hex_decode((uint8_t *)"AAAAAAAAA", 9, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ESIZE, "Bad data length 9"); + + // Bad data character + ret = knot_base32hex_decode((uint8_t *)"AAAAAAA$", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar"); + ret = knot_base32hex_decode((uint8_t *)"AAAAAAA ", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character space"); + ret = knot_base32hex_decode((uint8_t *)"AAAAAA$A", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 7"); + ret = knot_base32hex_decode((uint8_t *)"AAAAA$AA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 6"); + ret = knot_base32hex_decode((uint8_t *)"AAAA$AAA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 5"); + ret = knot_base32hex_decode((uint8_t *)"AAA$AAAA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 4"); + ret = knot_base32hex_decode((uint8_t *)"AA$AAAAA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 3"); + ret = knot_base32hex_decode((uint8_t *)"A$AAAAAA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 2"); + ret = knot_base32hex_decode((uint8_t *)"$AAAAAAA", 8, out, BUF_LEN); + ok(ret == KNOT_BASE32HEX_ECHAR, "Bad data character dollar on position 1"); + + return 0; +} diff --git a/tests/contrib/test_base64.c b/tests/contrib/test_base64.c new file mode 100644 index 0000000..82eee7d --- /dev/null +++ b/tests/contrib/test_base64.c @@ -0,0 +1,237 @@ +/* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/libknot.h" +#include "contrib/base64.h" +#include "contrib/openbsd/strlcpy.h" + +#define BUF_LEN 256 +#define MAX_BIN_DATA_LEN ((INT32_MAX / 4) * 3) + +int main(int argc, char *argv[]) +{ + plan(52); + + int32_t ret; + uint8_t in[BUF_LEN], ref[BUF_LEN], out[BUF_LEN], out2[BUF_LEN], *out3; + uint32_t in_len, ref_len; + + // 0. test invalid input + ret = knot_base64_encode(NULL, 0, out, BUF_LEN); + is_int(KNOT_EINVAL, ret, "knot_base64_encode: NULL input buffer"); + ret = knot_base64_encode(in, BUF_LEN, NULL, 0); + is_int(KNOT_EINVAL, ret, "knot_base64_encode: NULL output buffer"); + ret = knot_base64_encode(in, MAX_BIN_DATA_LEN + 1, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "knot_base64_encode: input buffer too large"); + ret = knot_base64_encode(in, BUF_LEN, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "knot_base64_encode: output buffer too small"); + + ret = knot_base64_encode_alloc(NULL, 0, &out3); + is_int(KNOT_EINVAL, ret, "knot_base64_encode_alloc: NULL input buffer"); + ret = knot_base64_encode_alloc(in, MAX_BIN_DATA_LEN + 1, &out3); + is_int(KNOT_ERANGE, ret, "knot_base64_encode_alloc: input buffer too large"); + ret = knot_base64_encode_alloc(in, BUF_LEN, NULL); + is_int(KNOT_EINVAL, ret, "knot_base64_encode_alloc: NULL output buffer"); + + ret = knot_base64_decode(NULL, 0, out, BUF_LEN); + is_int(KNOT_EINVAL, ret, "knot_base64_decode: NULL input buffer"); + ret = knot_base64_decode(in, BUF_LEN, NULL, 0); + is_int(KNOT_EINVAL, ret, "knot_base64_decode: NULL output buffer"); + ret = knot_base64_decode(in, UINT32_MAX, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "knot_base64_decode: input buffer too large"); + ret = knot_base64_decode(in, BUF_LEN, out, 0); + is_int(KNOT_ERANGE, ret, "knot_base64_decode: output buffer too small"); + + ret = knot_base64_decode_alloc(NULL, 0, &out3); + is_int(KNOT_EINVAL, ret, "knot_base64_decode_alloc: NULL input buffer"); + ret = knot_base64_decode_alloc(in, UINT32_MAX, &out3); + is_int(KNOT_ERANGE, ret, "knot_base64_decode_aloc: input buffer too large"); + ret = knot_base64_decode_alloc(in, BUF_LEN, NULL); + is_int(KNOT_EINVAL, ret, "knot_base64_decode_alloc: NULL output buffer"); + + // 1. test vector -> ENC -> DEC + strlcpy((char *)in, "", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "1. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "1. test vector - ENC output content"); + } + ret = knot_base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "1. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "1. test vector - DEC output content"); + } + + // 2. test vector -> ENC -> DEC + strlcpy((char *)in, "f", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zg==", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "2. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "2. test vector - ENC output content"); + } + ret = knot_base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "2. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "2. test vector - DEC output content"); + } + + // 3. test vector -> ENC -> DEC + strlcpy((char *)in, "fo", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm8=", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "3. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "3. test vector - ENC output content"); + } + ret = knot_base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "3. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "3. test vector - DEC output content"); + } + + // 4. test vector -> ENC -> DEC + strlcpy((char *)in, "foo", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9v", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "4. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "4. test vector - ENC output content"); + } + ret = knot_base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "4. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "4. test vector - DEC output content"); + } + + // 5. test vector -> ENC -> DEC + strlcpy((char *)in, "foob", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9vYg==", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "5. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "5. test vector - ENC output content"); + } + ret = knot_base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "5. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "5. test vector - DEC output content"); + } + + // 6. test vector -> ENC -> DEC + strlcpy((char *)in, "fooba", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9vYmE=", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "6. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "6. test vector - ENC output content"); + } + ret = knot_base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "6. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "6. test vector - DEC output content"); + } + + // 7. test vector -> ENC -> DEC + strlcpy((char *)in, "foobar", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9vYmFy", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "7. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "7. test vector - ENC output content"); + } + ret = knot_base64_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "7. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "7. test vector - DEC output content"); + } + + // Bad paddings + ret = knot_base64_decode((uint8_t *)"A===", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad padding length 3"); + ret = knot_base64_decode((uint8_t *)"====", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad padding length 4"); + ret = knot_base64_decode((uint8_t *)"AA=A", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad padding character on position 2"); + ret = knot_base64_decode((uint8_t *)"Zg==Zg==", 8, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Two quartets with padding"); + + // Bad data length + ret = knot_base64_decode((uint8_t *)"A", 1, out, BUF_LEN); + ok(ret == KNOT_BASE64_ESIZE, "Bad data length 1"); + ret = knot_base64_decode((uint8_t *)"AA", 2, out, BUF_LEN); + ok(ret == KNOT_BASE64_ESIZE, "Bad data length 2"); + ret = knot_base64_decode((uint8_t *)"AAA", 3, out, BUF_LEN); + ok(ret == KNOT_BASE64_ESIZE, "Bad data length 3"); + ret = knot_base64_decode((uint8_t *)"AAAAA", 5, out, BUF_LEN); + ok(ret == KNOT_BASE64_ESIZE, "Bad data length 5"); + + // Bad data character + ret = knot_base64_decode((uint8_t *)"AAA$", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad data character dollar"); + ret = knot_base64_decode((uint8_t *)"AAA ", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad data character space"); + + return 0; +} diff --git a/tests/contrib/test_base64url.c b/tests/contrib/test_base64url.c new file mode 100644 index 0000000..710aa29 --- /dev/null +++ b/tests/contrib/test_base64url.c @@ -0,0 +1,252 @@ +/* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/libknot.h" +#include "contrib/base64url.h" +#include "contrib/openbsd/strlcpy.h" + +#define BUF_LEN 256 +#define MAX_BIN_DATA_LEN ((INT32_MAX / 4) * 3) + +int main(int argc, char *argv[]) +{ + plan(50); + + int32_t ret; + uint8_t in[BUF_LEN], ref[BUF_LEN], out[BUF_LEN], out2[BUF_LEN], *out3; + uint32_t in_len, ref_len; + + // 0. test invalid input + ret = knot_base64url_encode(NULL, 0, out, BUF_LEN); + is_int(KNOT_EINVAL, ret, "knot_base64ulr_encode: NULL input buffer"); + ret = knot_base64url_encode(in, BUF_LEN, NULL, 0); + is_int(KNOT_EINVAL, ret, "knot_base64ulr_encode: NULL output buffer"); + ret = knot_base64url_encode(in, MAX_BIN_DATA_LEN + 1, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "knot_base64ulr_encode: input buffer too large"); + ret = knot_base64url_encode(in, BUF_LEN, out, BUF_LEN); + is_int(KNOT_ERANGE, ret, "knot_base64ulr_encode: output buffer too small"); + + ret = knot_base64url_encode_alloc(NULL, 0, &out3); + is_int(KNOT_EINVAL, ret, "knot_base64ulr_encode_alloc: NULL input buffer"); + ret = knot_base64url_encode_alloc(in, MAX_BIN_DATA_LEN + 1, &out3); + is_int(KNOT_ERANGE, ret, "knot_base64ulr_encode_alloc: input buffer too large"); + ret = knot_base64url_encode_alloc(in, BUF_LEN, NULL); + is_int(KNOT_EINVAL, ret, "knot_base64ulr_encode_alloc: NULL output buffer"); + + ret = knot_base64url_decode(NULL, 0, out, BUF_LEN); + is_int(KNOT_EINVAL, ret, "knot_base64ulr_decode: NULL input buffer"); + ret = knot_base64url_decode(in, BUF_LEN, NULL, 0); + is_int(KNOT_EINVAL, ret, "knot_base64ulr_decode: NULL output buffer"); + ret = knot_base64url_decode(in, BUF_LEN, out, 0); + is_int(KNOT_ERANGE, ret, "knot_base64ulr_decode: output buffer too small"); + + ret = knot_base64url_decode_alloc(NULL, 0, &out3); + is_int(KNOT_EINVAL, ret, "knot_base64ulr_decode_alloc: NULL input buffer"); + ret = knot_base64url_decode_alloc(in, BUF_LEN, NULL); + is_int(KNOT_EINVAL, ret, "knot_base64ulr_decode_alloc: NULL output buffer"); + + // 1. test vector -> ENC -> DEC + strlcpy((char *)in, "", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64url_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "1. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "1. test vector - ENC output content"); + } + ret = knot_base64url_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "1. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "1. test vector - DEC output content"); + } + + // 2. test vector -> ENC -> DEC + strlcpy((char *)in, "f", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zg", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64url_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "2. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "2. test vector - ENC output content"); + } + ret = knot_base64url_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "2. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "2. test vector - DEC output content"); + } + + // 3. test vector -> ENC -> DEC + strlcpy((char *)in, "fo", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm8", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64url_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "3. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "3. test vector - ENC output content"); + } + ret = knot_base64url_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "3. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "3. test vector - DEC output content"); + } + + // 4. test vector -> ENC -> DEC + strlcpy((char *)in, "foo", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9v", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64url_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "4. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "4. test vector - ENC output content"); + } + ret = knot_base64url_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "4. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "4. test vector - DEC output content"); + } + + // 5. test vector -> ENC -> DEC + strlcpy((char *)in, "foob", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9vYg", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64url_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "5. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "5. test vector - ENC output content"); + } + ret = knot_base64url_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "5. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "5. test vector - DEC output content"); + } + + // 6. test vector -> ENC -> DEC + strlcpy((char *)in, "fooba", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9vYmE", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64url_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "6. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "6. test vector - ENC output content"); + } + ret = knot_base64url_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "6. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "6. test vector - DEC output content"); + } + + // 7. test vector -> ENC -> DEC + strlcpy((char *)in, "foobar", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "Zm9vYmFy", BUF_LEN); + ref_len = strlen((char *)ref); + ret = knot_base64url_encode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "7. test vector - ENC output length"); + if (ret < 0) { + skip("Encode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "7. test vector - ENC output content"); + } + ret = knot_base64url_decode(out, ret, out2, BUF_LEN); + ok(ret == in_len, "7. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out2, in, ret) == 0, "7. test vector - DEC output content"); + } + + // 8. ENC (percent-encoded padding) -> DEC + strlcpy((char *)in, "Zm9vYmE%3D", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "fooba", BUF_LEN); + ref_len = strlen((char *)ref); + + ret = knot_base64url_decode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "8. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "8. test vector - DEC output content"); + } + + strlcpy((char *)in, "Zm9vYmFyCg%3d%3d", BUF_LEN); + in_len = strlen((char *)in); + strlcpy((char *)ref, "foobar\n", BUF_LEN); + ref_len = strlen((char *)ref); + + ret = knot_base64url_decode(in, in_len, out, BUF_LEN); + ok(ret == ref_len, "9. test vector - DEC output length"); + if (ret < 0) { + skip("Decode err"); + } else { + ok(memcmp(out, ref, ret) == 0, "9. test vector - DEC output content"); + } + + // Bad paddings + ret = knot_base64url_decode((uint8_t *)"A", 1, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad padding length 3"); + ret = knot_base64url_decode((uint8_t *)"%3D", 3, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad padding length 4"); + + // Paddings not at the end + ret = knot_base64url_decode((uint8_t *)"AB%3DCDEFG", 10, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad padding 1"); + ret = knot_base64url_decode((uint8_t *)"AB\0CDEFG", 8, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad padding 2"); + + // Bad data character + ret = knot_base64url_decode((uint8_t *)"AAA$", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad data character dollar"); + ret = knot_base64url_decode((uint8_t *)"AAA ", 4, out, BUF_LEN); + ok(ret == KNOT_BASE64_ECHAR, "Bad data character space"); + + return 0; +} diff --git a/tests/contrib/test_heap.c b/tests/contrib/test_heap.c new file mode 100644 index 0000000..7dc5975 --- /dev/null +++ b/tests/contrib/test_heap.c @@ -0,0 +1,166 @@ +/* Copyright (C) 2016 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "contrib/ucw/heap.h" + +static void seed_random(void) +{ + unsigned short int seed[3] = { 0 }; + + FILE *f = fopen("/dev/urandom", "r"); + if (f) { + if (fread(seed, sizeof(seed), 1, f) != 1) { + diag("failed to seed random source"); + } + fclose(f); + } + + diag("seed %hu %hu %hu", seed[0], seed[1], seed[2]); + seed48(seed); +} + +struct value { + heap_val_t _heap; + int data; +}; + +static int value_cmp(void *_a, void *_b) +{ + const struct value *a = _a; + const struct value *b = _b; + return (a->data - b->data); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + seed_random(); + + static const int VALUE_COUNT = 1000; + static const int VALUE_RANGE = 950; + static const int VALUE_REPLACE = 300; + static const int VALUE_DELETE = 100; + + struct heap heap; + heap_init(&heap, value_cmp, 0); + + ok(EMPTY_HEAP(&heap), "heap is empty"); + + // fill the heap with random values (with duplicates) + + struct value *values = calloc(VALUE_COUNT, sizeof(struct value)); + assert(values); + assert(VALUE_RANGE < VALUE_COUNT); + + bool valid = true; + for (int i = 0; i < VALUE_COUNT; i++) { + values[i].data = lrand48() % VALUE_RANGE; + if (heap_insert(&heap, &values[i]._heap) == 0) { + valid = false; + } + } + ok(valid, "heap_insert"); + ok(!EMPTY_HEAP(&heap), "heap is non-empty"); + + // exercise heap_insert + + valid = true; + for (int i = 0; i < VALUE_COUNT; i++) { + int pos = heap_find(&heap, &values[i]._heap); + if (*HELEMENT(&heap, pos) != &values[i]._heap) { + valid = false; + } + } + ok(valid, "heap_find"); + + // exercise heap_replace + + assert(VALUE_REPLACE <= VALUE_COUNT); + struct value *replaced = calloc(VALUE_REPLACE, sizeof(struct value)); + assert(replaced); + + valid = true; + for (int i = 0; i < VALUE_REPLACE; i++) { + replaced[i].data = lrand48() % VALUE_RANGE; + int pos = heap_find(&heap, &values[i]._heap); + if (pos < 1) { + valid = false; + continue; + } + + heap_replace(&heap, pos, &replaced[i]._heap); + int newpos = heap_find(&heap, &replaced[i]._heap); + if (newpos < 1) { + valid = false; + } + } + ok(valid, "heap_replace"); + + // exercise heap_delete + + assert(VALUE_REPLACE + VALUE_DELETE < VALUE_COUNT); + + valid = true; + for (int i = 0; i < VALUE_DELETE; i++) { + heap_val_t *value = &values[i + VALUE_REPLACE]._heap; + int pos = heap_find(&heap, value); + if (pos < 1) { + valid = false; + continue; + + } + heap_delete(&heap, pos); + pos = heap_find(&heap, value); + if (pos != 0) { + valid = false; + } + } + ok(valid, "heap_delete"); + + // exercise item retrieval + + assert(VALUE_COUNT > VALUE_DELETE); + + valid = true; + int current = -1; + for (int i = 0; i < VALUE_COUNT - VALUE_DELETE; i++) { + struct value *val = (struct value *)*HHEAD(&heap); + heap_delmin(&heap); + if (current <= val->data) { + current = val->data; + } else { + valid = false; + } + } + + ok(valid, "heap ordering"); + ok(EMPTY_HEAP(&heap), "heap_delmin"); + + free(replaced); + free(values); + heap_deinit(&heap); + + return 0; +} diff --git a/tests/contrib/test_inet_ntop.c b/tests/contrib/test_inet_ntop.c new file mode 100644 index 0000000..33e7b7e --- /dev/null +++ b/tests/contrib/test_inet_ntop.c @@ -0,0 +1,85 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <string.h> + +#include "contrib/musl/inet_ntop.h" + +uint8_t bin[sizeof(struct in6_addr)]; +const socklen_t len = INET6_ADDRSTRLEN; +char buf[INET6_ADDRSTRLEN]; +const char *txt; + +#define CHECK4(addr) \ + ok(inet_pton(AF_INET, addr, bin) == 1, "inet_pton(%s)", addr); \ + ok((txt = knot_inet_ntop(AF_INET, bin, buf, len)) != NULL, "knot_inet_ntop(%s)", addr); \ + ok(strcmp(txt, addr) == 0, "match %s", addr); + +#define CHECK6(addr, ref) \ + ok(inet_pton(AF_INET6, addr, bin) == 1, "inet_pton(%s)", addr); \ + ok((txt = knot_inet_ntop(AF_INET6, bin, buf, len)) != NULL, "knot_inet_ntop(%s)", addr); \ + ok(strcmp(txt, ref) == 0, "match %s %s", txt, ref); + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("IPv4 addresses"); + CHECK4("0.0.0.0"); + CHECK4("1.2.3.4"); + CHECK4("11.12.13.14"); + CHECK4("255.255.255.255"); + + diag("IPv6 addresses"); + CHECK6("::0", "::"); + CHECK6("::00", "::"); + CHECK6("::000", "::"); + CHECK6("::0000", "::"); + + CHECK6("::1", "::1"); + CHECK6("::01", "::1"); + CHECK6("::001", "::1"); + CHECK6("::0001", "::1"); + + CHECK6("::10", "::10"); + CHECK6("::100", "::100"); + CHECK6("::1000", "::1000"); + + CHECK6("::1:0", "::1:0"); + CHECK6("::1:0:0", "::1:0:0"); + CHECK6("::1:0:0:0", "::1:0:0:0"); + CHECK6("::1:0:0:0:0", "0:0:0:1::"); + CHECK6("::1:0:0:0:0:0", "0:0:1::"); + CHECK6("::1:0:0:0:0:0:0", "0:1::"); + CHECK6("1:0:0:0:0:0:0:0", "1::"); + + // IPv4-Compatible IPv6 Addresses (not supported). + CHECK6("::0:1:1", "::1:1"); + CHECK6("::0:1.2.3.4", "::102:304"); + + // IPv4-Mapped IPv6 Addresses. + CHECK6("::ffff:1:1", "::ffff:0.1.0.1"); + CHECK6("::ffff:1.2.3.4", "::ffff:1.2.3.4"); + + CHECK6("1::1", "1::1"); + CHECK6("1000::1", "1000::1"); + CHECK6("1:20:300:4000:0005:006:07:8", "1:20:300:4000:5:6:7:8"); + + return 0; +} diff --git a/tests/contrib/test_net.c b/tests/contrib/test_net.c new file mode 100644 index 0000000..c0061cd --- /dev/null +++ b/tests/contrib/test_net.c @@ -0,0 +1,718 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <assert.h> +#include <fcntl.h> +#include <poll.h> +#include <pthread.h> +#include <signal.h> +#include <stdbool.h> +#include <string.h> +#include <unistd.h> + +#include "libknot/errcode.h" +#include "contrib/net.h" +#include "contrib/sockaddr.h" + +const int TIMEOUT = 5000; +const int TIMEOUT_SHORT = 500; + +/*! + * \brief Get loopback socket address with unset port. + */ +static struct sockaddr_storage addr_local(void) +{ + struct sockaddr_storage addr = { 0 }; + + struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr; + addr4->sin_family = AF_INET; + addr4->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + return addr; +} + +/*! + * \brief Get address of a socket. + */ +static struct sockaddr_storage addr_from_socket(int sock) +{ + struct sockaddr_storage addr = { 0 }; + socklen_t len = sizeof(addr); + int ret = getsockname(sock, (struct sockaddr *)&addr, &len); + is_int(0, ret, "check getsockname return"); + + return addr; +} + +static const char *socktype_name(int type) +{ + switch (type) { + case SOCK_STREAM: return "TCP"; + case SOCK_DGRAM: return "UDP"; + default: return "unknown"; + } +} + +static bool socktype_is_stream(int type) +{ + return type == SOCK_STREAM; +} + +/* -- mock server ---------------------------------------------------------- */ + +#define LISTEN_BACKLOG 5 + +struct server_ctx; +typedef struct server_ctx server_ctx_t; + +typedef void (*server_cb)(int sock, void *data); + +/*! + * \brief Server context. + */ +struct server_ctx { + int sock; + int type; + bool terminate; + server_cb handler; + void *handler_data; + + pthread_t thr; + pthread_mutex_t mx; +}; + +static int poll_read(int sock) +{ + struct pollfd pfd = { .fd = sock, .events = POLLIN }; + return poll(&pfd, 1, TIMEOUT); +} + +static void server_handle(server_ctx_t *ctx) +{ + int remote = ctx->sock; + + assert(ctx->type == SOCK_STREAM || ctx->type == SOCK_DGRAM); + + if (socktype_is_stream(ctx->type)) { + remote = accept(ctx->sock, 0, 0); + if (remote < 0) { + return; + } + } + + pthread_mutex_lock(&ctx->mx); + server_cb handler = ctx->handler; + pthread_mutex_unlock(&ctx->mx); + handler(remote, ctx->handler_data); + + if (socktype_is_stream(ctx->type)) { + close(remote); + } +} + +/*! + * \brief Simple server. + * + * Terminated when a one-byte message is delivered. + */ +static void *server_main(void *_ctx) +{ + server_ctx_t *ctx = _ctx; + + for (;;) { + pthread_mutex_lock(&ctx->mx); + bool terminate = ctx->terminate; + pthread_mutex_unlock(&ctx->mx); + if (terminate) { + break; + } + + int r = poll_read(ctx->sock); + if (r == -1) { + if (errno == EINTR) { + continue; + } else { + break; + } + } else if (r == 0) { + continue; + } + + assert(r == 1); + server_handle(ctx); + } + + return NULL; +} + +static bool server_start(server_ctx_t *ctx, int sock, int type, + server_cb handler, void *handler_data) +{ + memset(ctx, 0, sizeof(*ctx)); + + ctx->sock = sock; + ctx->type = type; + ctx->handler = handler; + ctx->handler_data = handler_data; + + ctx->terminate = false; + + pthread_mutex_init(&ctx->mx, NULL); + return (pthread_create(&ctx->thr, NULL, server_main, ctx) == 0); +} + +static void server_stop(server_ctx_t *ctx) +{ + pthread_mutex_lock(&ctx->mx); + ctx->terminate = true; + pthread_mutex_unlock(&ctx->mx); + + pthread_kill(ctx->thr, SIGUSR1); + pthread_join(ctx->thr, NULL); +} + +/* -- tests ---------------------------------------------------------------- */ + +static void handler_echo(int sock, void *_server) +{ + server_ctx_t *server = _server; + uint8_t buffer[16] = { 0 }; + + struct sockaddr_storage remote = { 0 }; + struct sockaddr_storage *addr = NULL; + if (!socktype_is_stream(server->type)) { + addr = &remote; + } + + int in = net_base_recv(sock, buffer, sizeof(buffer), addr, TIMEOUT); + if (in <= 0) { + return; + } + + net_base_send(sock, buffer, in, addr, TIMEOUT); +} + +static void test_connected_one(const struct sockaddr_storage *server_addr, + const struct sockaddr_storage *source_addr, + int type, const char *name, const char *addr_name) +{ + int r; + + int client = net_connected_socket(type, server_addr, source_addr, false); + ok(client >= 0, "%s, %s: client, create connected socket", name, addr_name); + + const uint8_t out[] = "test message"; + const size_t out_len = sizeof(out); + if (socktype_is_stream(type)) { + r = net_stream_send(client, out, out_len, TIMEOUT); + } else { + r = net_dgram_send(client, out, out_len, NULL); + } + is_int(out_len, r, "%s, %s: client, send message", name, addr_name); + + r = net_is_connected(client); + ok(r, "%s, %s: client, is connected", name, addr_name); + + uint8_t in[128] = { 0 }; + if (socktype_is_stream(type)) { + r = net_stream_recv(client, in, sizeof(in), TIMEOUT); + } else { + r = net_dgram_recv(client, in, sizeof(in), TIMEOUT); + } + is_int(out_len, r, "%s, %s: client, receive message length", name, addr_name); + ok(memcmp(out, in, out_len) == 0, "%s, %s: client, receive message", name, addr_name); + + close(client); +} + +static void test_connected(int type) +{ + const char *name = socktype_name(type); + const struct sockaddr_storage empty_addr = { 0 }; + const struct sockaddr_storage local_addr = addr_local(); + + int r; + + // setup server + + int server = net_bound_socket(type, &local_addr, 0, 0); + ok(server >= 0, "%s: server, create bound socket", name); + + if (socktype_is_stream(type)) { + r = listen(server, LISTEN_BACKLOG); + is_int(0, r, "%s: server, start listening", name); + } + + server_ctx_t server_ctx = { 0 }; + r = server_start(&server_ctx, server, type, handler_echo, &server_ctx); + ok(r, "%s: server, start", name); + + const struct sockaddr_storage server_addr = addr_from_socket(server); + + // connected socket, send and receive + + test_connected_one(&server_addr, NULL, type, name, "NULL source"); + test_connected_one(&server_addr, &empty_addr, type, name, "zero source"); + test_connected_one(&server_addr, &local_addr, type, name, "valid source"); + + // cleanup + + server_stop(&server_ctx); + close(server); +} + +static void handler_noop(int sock, void *data) +{ +} + +static void test_unconnected(void) +{ + int r = 0; + int sock = -1; + const struct sockaddr_storage local = addr_local(); + + uint8_t buffer[] = { 'k', 'n', 'o', 't' }; + ssize_t buffer_len = sizeof(buffer); + + // server + + int server = net_bound_socket(SOCK_DGRAM, &local, 0, 0); + ok(server >= 0, "UDP, create server socket"); + + server_ctx_t server_ctx = { 0 }; + r = server_start(&server_ctx, server, SOCK_DGRAM, handler_noop, NULL); + ok(r, "UDP, start server"); + + // UDP + + sock = net_unbound_socket(SOCK_DGRAM, &local); + ok(sock >= 0, "UDP, create unbound socket"); + + ok(!net_is_connected(sock), "UDP, is not connected"); + + r = net_dgram_send(sock, buffer, buffer_len, NULL); + is_int(KNOT_ECONN, r, "UDP, send failure on unconnected socket"); + + r = net_dgram_recv(sock, buffer, buffer_len, TIMEOUT_SHORT); + is_int(KNOT_ETIMEOUT, r, "UDP, receive timeout on unconnected socket"); + + struct sockaddr_storage server_addr = addr_from_socket(server); + r = net_dgram_send(sock, buffer, buffer_len, &server_addr); + is_int(buffer_len, r, "UDP, send on defined address"); + + close(sock); + + // TCP + + sock = net_unbound_socket(SOCK_STREAM, &local); + ok(sock >= 0, "TCP, create unbound socket"); + + ok(!net_is_connected(sock), "TCP, is not connected"); + +#ifdef __linux__ + const int expected = KNOT_ECONN; + const char *expected_msg = "failure"; + const int expected_timeout = TIMEOUT; +#else + const int expected = KNOT_ETIMEOUT; + const char *expected_msg = "timeout"; + const int expected_timeout = TIMEOUT_SHORT; +#endif + + r = net_stream_send(sock, buffer, buffer_len, expected_timeout); + is_int(expected, r, "TCP, send %s on unconnected socket", expected_msg); + + r = net_stream_recv(sock, buffer, sizeof(buffer), expected_timeout); + is_int(expected, r, "TCP, receive %s on unconnected socket", expected_msg); + + close(sock); + + // server termination + + server_stop(&server_ctx); + close(server); +} + +static void test_refused(void) +{ + int r = -1; + + struct sockaddr_storage addr = { 0 }; + uint8_t buffer[1] = { 0 }; + int server, client; + + // listening, not accepting + + addr = addr_local(); + server = net_bound_socket(SOCK_STREAM, &addr, 0, 0); + ok(server >= 0, "server, create server"); + addr = addr_from_socket(server); + + r = listen(server, LISTEN_BACKLOG); + is_int(0, r, "server, start listening"); + + client = net_connected_socket(SOCK_STREAM, &addr, NULL, false); + ok(client >= 0, "client, connect"); + + r = net_stream_send(client, (uint8_t *)"", 1, TIMEOUT); + is_int(1, r, "client, successful write"); + + r = net_stream_recv(client, buffer, sizeof(buffer), TIMEOUT_SHORT); + is_int(KNOT_ETIMEOUT, r, "client, timeout on read"); + + close(client); + + // listening, closed immediately + + client = net_connected_socket(SOCK_STREAM, &addr, NULL, false); + ok(client >= 0, "client, connect"); + + r = close(server); + is_int(0, r, "server, close socket"); + usleep(50000); + + r = net_stream_send(client, (uint8_t *)"", 1, TIMEOUT); + is_int(KNOT_ECONN, r, "client, refused on write"); + + close(client); +} + +struct dns_handler_ctx { + const uint8_t *expected; + int len; + bool raw; + bool success; +}; + +static bool _sync(int remote, int send) +{ + uint8_t buf[1] = { 0 }; + int r; + if (send) { + r = net_stream_send(remote, buf, sizeof(buf), TIMEOUT); + } else { + r = net_stream_recv(remote, buf, sizeof(buf), TIMEOUT); + + } + return r == sizeof(buf); +} + +static bool sync_signal(int remote) +{ + return _sync(remote, true); +} + +static bool sync_wait(int remote) +{ + return _sync(remote, false); +} + +static void handler_dns(int sock, void *_ctx) +{ + struct dns_handler_ctx *ctx = _ctx; + + uint8_t in[16] = { 0 }; + int in_len = 0; + + sync_signal(sock); + + if (ctx->raw) { + in_len = net_stream_recv(sock, in, sizeof(in), TIMEOUT); + } else { + in_len = net_dns_tcp_recv(sock, in, sizeof(in), TIMEOUT); + } + + ctx->success = in_len == ctx->len && + (ctx->len < 0 || memcmp(in, ctx->expected, in_len) == 0); +} + +static void dns_send_hello(int sock) +{ + net_dns_tcp_send(sock, (uint8_t *)"wimbgunts", 9, TIMEOUT, NULL); +} + +static void dns_send_fragmented(int sock) +{ + struct fragment { const uint8_t *data; size_t len; }; + + const struct fragment fragments[] = { + { (uint8_t *)"\x00", 1 }, + { (uint8_t *)"\x08""qu", 3 }, + { (uint8_t *)"oopisk", 6 }, + { NULL } + }; + + for (const struct fragment *f = fragments; f->len > 0; f++) { + net_stream_send(sock, f->data, f->len, TIMEOUT); + } +} + +static void dns_send_incomplete(int sock) +{ + net_stream_send(sock, (uint8_t *)"\x00\x08""korm", 6, TIMEOUT); +} + +static void dns_send_trailing(int sock) +{ + net_stream_send(sock, (uint8_t *)"\x00\x05""bloitxx", 9, TIMEOUT); +} + +static void test_dns_tcp(void) +{ + struct testcase { + const char *name; + const uint8_t *expected; + size_t expected_len; + bool expected_raw; + void (*send_callback)(int sock); + }; + + const struct testcase testcases[] = { + { "single DNS", (uint8_t *)"wimbgunts", 9, false, dns_send_hello }, + { "single RAW", (uint8_t *)"\x00\x09""wimbgunts", 11, true, dns_send_hello }, + { "fragmented", (uint8_t *)"quoopisk", 8, false, dns_send_fragmented }, + { "incomplete", NULL, KNOT_ECONN, false, dns_send_incomplete }, + { "trailing garbage", (uint8_t *)"bloit", 5, false, dns_send_trailing }, + { NULL } + }; + + for (const struct testcase *t = testcases; t->name != NULL; t++) { + struct dns_handler_ctx handler_ctx = { + .expected = t->expected, + .len = t->expected_len, + .raw = t->expected_raw, + .success = false + }; + + struct sockaddr_storage addr = addr_local(); + int server = net_bound_socket(SOCK_STREAM, &addr, 0, 0); + ok(server >= 0, "%s, server, create socket", t->name); + + int r = listen(server, LISTEN_BACKLOG); + is_int(0, r, "%s, server, start listening", t->name); + + server_ctx_t server_ctx = { 0 }; + r = server_start(&server_ctx, server, SOCK_STREAM, handler_dns, &handler_ctx); + ok(r, "%s, server, start handler", t->name); + + addr = addr_from_socket(server); + int client = net_connected_socket(SOCK_STREAM, &addr, NULL, false); + ok(client >= 0, "%s, client, create connected socket", t->name); + + r = sync_wait(client); + ok(r, "%s, client, wait for stream read", t->name); + t->send_callback(client); + + close(client); + server_stop(&server_ctx); + close(server); + + ok(handler_ctx.success, "%s, expected result", t->name); + } +} + +static bool socket_is_blocking(int sock) +{ + return fcntl(sock, F_GETFL, O_NONBLOCK) == 0; +} + +static void test_nonblocking_mode(int type) +{ + const char *name = socktype_name(type); + const struct sockaddr_storage addr = addr_local(); + + int client = net_unbound_socket(type, &addr); + ok(client >= 0, "%s: unbound, create", name); + ok(!socket_is_blocking(client), "%s: unbound, nonblocking mode", name); + close(client); + + int server = net_bound_socket(type, &addr, 0, 0); + ok(server >= 0, "%s: bound, create", name); + ok(!socket_is_blocking(server), "%s: bound, nonblocking mode", name); + + if (socktype_is_stream(type)) { + int r = listen(server, LISTEN_BACKLOG); + is_int(0, r, "%s: bound, start listening", name); + } + + struct sockaddr_storage server_addr = addr_from_socket(server); + client = net_connected_socket(type, &server_addr, NULL, false); + ok(client >= 0, "%s: connected, create", name); + ok(!socket_is_blocking(client), "%s: connected, nonblocking mode", name); + + close(client); + close(server); +} + +static void test_nonblocking_accept(void) +{ + int r; + + // create server + + struct sockaddr_storage addr_server = addr_local(); + + int server = net_bound_socket(SOCK_STREAM, &addr_server, 0, 0); + ok(server >= 0, "server, create socket"); + + r = listen(server, LISTEN_BACKLOG); + is_int(0, r, "server, start listening"); + + addr_server = addr_from_socket(server); + + // create client + + int client = net_connected_socket(SOCK_STREAM, &addr_server, NULL, false); + ok(client >= 0, "client, create connected socket"); + + struct sockaddr_storage addr_client = addr_from_socket(client); + + // accept connection + + r = poll_read(server); + is_int(1, r, "server, pending connection"); + + struct sockaddr_storage addr_accepted = { 0 }; + int accepted = net_accept(server, &addr_accepted); + ok(accepted >= 0, "server, accept connection"); + + ok(!socket_is_blocking(accepted), "accepted, nonblocking mode"); + + ok(sockaddr_cmp(&addr_client, &addr_accepted, false) == 0, + "accepted, correct address"); + + close(client); + + // client reconnect + + close(client); + client = net_connected_socket(SOCK_STREAM, &addr_server, NULL, false); + ok(client >= 0, "client, reconnect"); + + r = poll_read(server); + is_int(1, r, "server, pending connection"); + + accepted = net_accept(server, NULL); + ok(accepted >= 0, "server, accept connection (no remote address)"); + + ok(!socket_is_blocking(accepted), "accepted, nonblocking mode"); + + // cleanup + + close(client); + close(server); +} + +static void test_socket_types(void) +{ + struct sockaddr_storage addr = addr_local(); + + struct testcase { + const char *name; + int type; + bool is_stream; + }; + + const struct testcase testcases[] = { + { "UDP", SOCK_DGRAM, false }, + { "TCP", SOCK_STREAM, true }, + { NULL } + }; + + for (const struct testcase *t = testcases; t->name != NULL; t++) { + int sock = net_unbound_socket(t->type, &addr); + ok(sock >= 0, "%s, create socket", t->name); + + is_int(t->type, net_socktype(sock), "%s, socket type", t->name); + + ok(net_is_stream(sock) == t->is_stream, "%s, is stream", t->name); + + close(sock); + } + + is_int(AF_UNSPEC, net_socktype(-1), "invalid, socket type"); + ok(!net_is_stream(-1), "invalid, is stream"); +} + +static void test_bind_multiple(void) +{ + const struct sockaddr_storage addr = addr_local(); + + // bind first socket + + int sock_one = net_bound_socket(SOCK_DGRAM, &addr, NET_BIND_MULTIPLE, 0); + if (sock_one == KNOT_ENOTSUP) { + skip("not supported on this system"); + return; + } + ok(sock_one >= 0, "bind first socket"); + + // bind second socket to the same address + + const struct sockaddr_storage addr_one = addr_from_socket(sock_one); + int sock_two = net_bound_socket(SOCK_DGRAM, &addr_one, NET_BIND_MULTIPLE, 0); + ok(sock_two >= 0, "bind second socket"); + + // compare sockets + + ok(sock_one != sock_two, "descriptors are different"); + + const struct sockaddr_storage addr_two = addr_from_socket(sock_two); + ok(sockaddr_cmp(&addr_one, &addr_two, false) == 0, + "addresses are the same"); + + close(sock_one); + close(sock_two); +} + +static void signal_noop(int sig) +{ +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + signal(SIGUSR1, signal_noop); + + diag("nonblocking mode"); + test_nonblocking_mode(SOCK_DGRAM); + test_nonblocking_mode(SOCK_STREAM); + test_nonblocking_accept(); + + diag("socket types"); + test_socket_types(); + + diag("connected sockets"); + test_connected(SOCK_DGRAM); + test_connected(SOCK_STREAM); + + diag("unconnected sockets"); + test_unconnected(); + + diag("refused connections"); + test_refused(); + + diag("DNS messages over TCP"); + test_dns_tcp(); + + diag("flag NET_BIND_MULTIPLE"); + test_bind_multiple(); + + return 0; +} diff --git a/tests/contrib/test_net_shortwrite.c b/tests/contrib/test_net_shortwrite.c new file mode 100644 index 0000000..f3d4c6e --- /dev/null +++ b/tests/contrib/test_net_shortwrite.c @@ -0,0 +1,151 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <fcntl.h> +#include <stdint.h> +#include <string.h> +#include <pthread.h> +#include <poll.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> + +#include "libknot/errcode.h" +#include "contrib/net.h" +#include "contrib/sockaddr.h" + +const int TIMEOUT = 2000; + +static struct sockaddr_storage localhost(void) +{ + struct sockaddr_storage addr = { 0 }; + + struct addrinfo *res = NULL; + if (getaddrinfo(NULL, "0", NULL, &res) == 0) { + memcpy(&addr, res->ai_addr, res->ai_addrlen); + freeaddrinfo(res); + } + + return addr; +} + +struct data { + int server_fd; + uint8_t *buffer; + size_t size; + int result; +}; + +static void *thr_receive(void *data) +{ + struct data *d = data; + + struct pollfd pfd = { .fd = d->server_fd, .events = POLLIN }; + int r = poll(&pfd, 1, TIMEOUT); + if (r != 1) { + d->result = KNOT_ETIMEOUT; + return NULL; + } + + int client = accept(d->server_fd, NULL, NULL); + if (client < 0) { + d->result = KNOT_ECONN; + return NULL; + } + + d->result = net_dns_tcp_recv(client, d->buffer, d->size, TIMEOUT); + + close(client); + + return NULL; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + int r; + + // create TCP server + + struct sockaddr_storage addr = localhost(); + int server = net_bound_socket(SOCK_STREAM, &addr, 0, 0); + ok(server >= 0, "server: bind socket"); + + r = listen(server, 1); + ok(r == 0, "server: start listening"); + + struct sockaddr *sa = (struct sockaddr *)&addr; + socklen_t salen = sockaddr_len(&addr); + r = getsockname(server, sa, &salen); + ok(r == 0, "server: get bound address"); + + // create TCP client + + int client = net_connected_socket(SOCK_STREAM, &addr, NULL, false); + ok(client >= 0, "client: connect to server"); + + int optval = 8192; + socklen_t optlen = sizeof(optval); + r = setsockopt(client, SOL_SOCKET, SO_SNDBUF, &optval, optlen); + ok(r == 0, "client: configure small send buffer"); + + // accept TCP connection on the background + + uint8_t recvbuf[UINT16_MAX] = { 0 }; + struct data recv_data = { + .server_fd = server, + .buffer = recvbuf, + .size = sizeof(recvbuf) + }; + + pthread_t thr; + r = pthread_create(&thr, NULL, thr_receive, &recv_data); + ok(r == 0, "server: start receiver thread"); + + // send message (should handle partial-write correctly) + + uint8_t sndbuf[UINT16_MAX]; + for (size_t i = 0; i < sizeof(sndbuf); i++) { + sndbuf[i] = i; + } + r = net_dns_tcp_send(client, sndbuf, sizeof(sndbuf), TIMEOUT, NULL); + ok(r == sizeof(sndbuf), "client: net_dns_tcp_send() with short-write"); + + // receive message + + r = pthread_join(thr, NULL); + ok(r == 0, "server: wait for receiver thread to terminate"); + + ok(recv_data.result == sizeof(recvbuf) && + memcmp(sndbuf, recvbuf, sizeof(recvbuf)) == 0, + "server: net_dns_tcp_recv() complete and valid data"); + + // clean up + + if (server >= 0) { + close(server); + } + + if (client >= 0) { + close(client); + } + + return 0; +} diff --git a/tests/contrib/test_qp-cow.c b/tests/contrib/test_qp-cow.c new file mode 100644 index 0000000..4cd8c6c --- /dev/null +++ b/tests/contrib/test_qp-cow.c @@ -0,0 +1,282 @@ +/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> + Copyright (C) 2018 Tony Finch <dot@dotat.at> + + 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <err.h> +#include <unistd.h> + +#include "contrib/qp-trie/trie.h" +#include "contrib/string.h" +#include "libknot/attribute.h" +#include "libknot/errcode.h" +#include "tap/basic.h" + +/* Constants. */ +#define MAX_KEYLEN 64 +#define MAX_LEAVES 12345 +#define MAX_MUTATIONS 123 +#define MAX_TRANSACTIONS 1234 + +enum cowstate { + cow_absent, // not in trie + cow_unmarked, + cow_shared, + cow_old, // deleted from new trie + cow_new, // added to new trie + deadbeef, +}; + +struct cowleaf { + char *key; + size_t len; + int cowstate; +}; + +static inline size_t +prng(size_t max) { + /* good enough these days */ + return (size_t)rand() % max; +} + +static struct cowleaf * +grow_leaves(size_t maxlen, size_t leaves) +{ + struct cowleaf *leaf = bcalloc(leaves, sizeof(*leaf)); + + trie_t *trie = trie_create(NULL); + if (!trie) sysbail("trie_create"); + + for (size_t i = 0; i < leaves; i++) { + trie_val_t *valp; + char *str = NULL; + size_t len = 0; + do { + free(str); + len = prng(maxlen); + str = bmalloc(len + 1); + for (size_t j = 0; j < len; j++) + str[j] = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + [prng(62)]; + str[len] = '\0'; + valp = trie_get_ins(trie, (uint8_t *)str, (uint32_t)len); + if (!valp) bail("trie_get_ins"); + } while (*valp != NULL); + *valp = &leaf[i]; + leaf[i].key = str; + leaf[i].len = len; + leaf[i].cowstate = cow_absent; + } + trie_free(trie); + + return (leaf); +} + +static void +dead_leaves(struct cowleaf *leaf, size_t leaves) +{ + for (size_t i = 0; i < leaves; i++) + free(leaf[i].key); + free(leaf); +} + +static void +mark_cb(trie_val_t val, const uint8_t *key, size_t len, void *d) +{ + struct cowleaf *leaf = val; + assert(leaf->cowstate == cow_unmarked && + "leaf should go from unmarked to shared exactly once"); + leaf->cowstate = cow_shared; + (void)key; + (void)len; + (void)d; +} + +static void +commit_rollback(trie_val_t val, const uint8_t *key, size_t len, void *d) +{ + struct cowleaf *leaf = val; + int *commit = d; + if (*commit) + assert((leaf->cowstate == cow_shared || + leaf->cowstate == cow_old) && + "committing deletes from old trie"); + else + assert((leaf->cowstate == cow_shared || + leaf->cowstate == cow_new) && + "roll back deletes from new trie"); + if (leaf->cowstate != cow_shared) + leaf->cowstate = deadbeef; + (void)key; + (void)len; +} + +static void +del_cow(trie_cow_t *x, struct cowleaf *leaf) +{ + _unused_ trie_val_t val; + assert(KNOT_EOK == trie_del_cow(x, + (uint8_t *)leaf->key, + (uint32_t)leaf->len, + &val)); + assert(val == leaf); +} + +static void +usage(void) { + fprintf(stderr, + "usage: test_qp-cow [-k N] [-l N] [-t N]\n" + " -k N maximum key length (default %d)\n" + " -l N number of leaves (default %d)\n" + " -m N mutations per transaction (default %d)\n" + " -t N number of transactions (default %d)\n", + MAX_KEYLEN, + MAX_LEAVES, + MAX_MUTATIONS, + MAX_TRANSACTIONS); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + size_t keylen = MAX_KEYLEN; + size_t leaves = MAX_LEAVES; + int mutations = MAX_MUTATIONS; + int transactions = MAX_TRANSACTIONS; + + int opt; + while ((opt = getopt(argc, argv, "k:l:m:t:h")) != -1) + switch (opt) { + case('k'): + keylen = (unsigned)atoi(optarg); + continue; + case('l'): + leaves = (unsigned)atoi(optarg); + continue; + case('m'): + mutations = atoi(optarg); + continue; + case('t'): + transactions = atoi(optarg); + continue; + default: + usage(); + } + + if (argc != optind) + usage(); + + plan(transactions); + + struct cowleaf *leaf = grow_leaves(keylen, leaves); + trie_t *t = trie_create(NULL); + + for (int round = 0; round < transactions; round++) { + trie_cow_t *x = trie_cow(t, mark_cb, NULL); + if (!x) sysbail("trie_cow"); + + int hits = prng(mutations); + for (int hit = 0; hit < hits; hit++) { + size_t i = prng(leaves); + switch (leaf[i].cowstate) { + case(cow_absent): { + trie_val_t *val = + trie_get_cow(x, + (uint8_t *)leaf[i].key, + (uint32_t)leaf[i].len); + if (!val) sysbail("trie_get_cow"); + assert(*val == NULL && "new leaf"); + *val = &leaf[i]; + leaf[i].cowstate = cow_new; + } break; + case(cow_unmarked): { + del_cow(x, &leaf[i]); + assert(leaf[i].cowstate == cow_shared && + "state changed unmarked -> shared"); + leaf[i].cowstate = cow_old; + } break; + case(cow_shared): { + del_cow(x, &leaf[i]); + assert(leaf[i].cowstate == cow_shared && + "state remained shared"); + leaf[i].cowstate = cow_old; + } break; + case(cow_new): { + del_cow(x, &leaf[i]); + assert(leaf[i].cowstate == cow_new && + "state remained new"); + leaf[i].cowstate = cow_absent; + } break; + case(cow_old): { + // don't want to mess with old tree + } break; + case(deadbeef): { + assert(!"deadbeef should not be possible"); + } break; + default: + assert(!"bug - unhandled state"); + } + } + + int commit = !prng(2); + if (commit) + t = trie_cow_commit(x, commit_rollback, &commit); + else + t = trie_cow_rollback(x, commit_rollback, &commit); + + trie_it_t *it = trie_it_begin(t); + while (!trie_it_finished(it)) { + trie_val_t *val = trie_it_val(it); + assert(val != NULL); + struct cowleaf *l = *val; + if (commit) + assert((l->cowstate == cow_unmarked || + l->cowstate == cow_shared || + l->cowstate == cow_new) && + "committing expected state"); + else + assert((l->cowstate == cow_unmarked || + l->cowstate == cow_shared || + l->cowstate == cow_old) && + "roll back expected state"); + l->cowstate = cow_unmarked; + trie_it_next(it); + } + trie_it_free(it); + + for (size_t i = 0; i < leaves; i++) { + assert((leaf[i].cowstate == cow_unmarked || + leaf[i].cowstate == cow_absent || + leaf[i].cowstate == deadbeef) && + "cleanup leaves either unmarked or dead"); + if (leaf[i].cowstate == deadbeef) + leaf[i].cowstate = cow_absent; + } + ok(1, "transaction done"); + } + + trie_free(t); + dead_leaves(leaf, leaves); + + return 0; +} diff --git a/tests/contrib/test_qp-trie.c b/tests/contrib/test_qp-trie.c new file mode 100644 index 0000000..a50661f --- /dev/null +++ b/tests/contrib/test_qp-trie.c @@ -0,0 +1,284 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <tap/basic.h> + +#include "contrib/qp-trie/trie.h" +#include "contrib/macros.h" +#include "contrib/string.h" +#include "libknot/dname.h" +#include "libknot/errcode.h" + +/* UCW array sorting defines. */ +#define ASORT_PREFIX(X) str_key_##X +#define ASORT_KEY_TYPE char* +#define ASORT_LT(x, y) (strcmp((x), (y)) < 0) +#include "contrib/ucw/array-sort.h" + +/* Constants. */ +#define KEY_MAXLEN 64 + +/* Generate random key. */ +static const char *alphabet = "abcdefghijklmn0123456789"; +static char *str_key_rand(size_t len) +{ + char *s = malloc(len); + memset(s, 0, len); + for (unsigned i = 0; i < len - 1; ++i) { + s[i] = alphabet[rand() % strlen(alphabet)]; + } + return s; +} + +/* Check lesser or equal result. */ +static bool str_key_get_leq(trie_t *trie, char **keys, size_t i, size_t size) +{ + static char key_buf[KEY_MAXLEN]; + + int ret = 0; + trie_val_t *val = NULL; + const char *key = keys[i]; + size_t key_len = strlen(key) + 1; + memcpy(key_buf, key, key_len); + + /* Count equal first keys. */ + size_t first_key_count = 1; + for (size_t k = 1; k < size; ++k) { + if (strcmp(keys[0], keys[k]) == 0) { + first_key_count += 1; + } else { + break; + } + } + + /* Before current key. */ + key_buf[key_len - 2] -= 1; + if (i < first_key_count) { + ret = trie_get_leq(trie, (uint8_t *)key_buf, key_len, &val); + if (ret != KNOT_ENOENT) { + diag("%s: leq for key BEFORE %zu/'%s' ret = %d", __func__, i, keys[i], ret); + return false; /* No key before first. */ + } + } else { + ret = trie_get_leq(trie, (uint8_t *)key_buf, key_len, &val); + if (ret < KNOT_EOK || strcmp(*val, key_buf) > 0) { + diag("%s: '%s' is not before the key %zu/'%s'", __func__, (char*)*val, i, keys[i]); + return false; /* Found key must be LEQ than searched. */ + } + } + + /* Current key. */ + key_buf[key_len - 2] += 1; + ret = trie_get_leq(trie, (uint8_t *)key_buf, key_len, &val); + if (! (ret == KNOT_EOK && val && strcmp(*val, key_buf) == 0)) { + diag("%s: leq for key %zu/'%s' ret = %d", __func__, i, keys[i], ret); + return false; /* Must find equal match. */ + } + + /* After the current key. */ + key_buf[key_len - 2] += 1; + ret = trie_get_leq(trie, (uint8_t *)key_buf, key_len, &val); + if (! (ret >= KNOT_EOK && strcmp(*val, key_buf) <= 0)) { + diag("%s: leq for key AFTER %zu/'%s' ret = %d %s", __func__, i, keys[i], ret, (char*)*val); + return false; /* Every key must have its LEQ match. */ + } + + return true; + +} + +static void test_wildcards(void) +{ + /* Test zone. */ + const char *names[] = { + "*", + "example.cz", + "*.example.cz", + "+.example.cz", + + "*.exampld.cz", + "www.exampld.cz", + }; + /* Query-answer pairs for wildcard search. */ + const char *qa_pairs[][2] = { + { ".", NULL }, + { "*", "*" }, + { "bar", "*" }, + { "foo.test.", "*" }, + { "example.cz", "example.cz" }, + { "*.example.cz", "*.example.cz" }, + { "a.example.cz", "*.example.cz" }, + { "ab.cd.example.cz", "*.example.cz" }, + { "a+.example.cz", "*.example.cz" }, + { "+.example.cz", "+.example.cz" }, + { "exampld.cz", NULL }, + { ":.exampld.cz", "*.exampld.cz" }, + { "ww.exampld.cz", "*.exampld.cz" }, + }; + + trie_t *trie = trie_create(NULL); + if (!trie) ok(false, "trie: create"); + + /* Insert the whole zone. */ + for (int i = 0; i < sizeof(names) / sizeof(names[0]); ++i) { + knot_dname_storage_t dname_st, lf_st; + const knot_dname_t + *dname = knot_dname_from_str(dname_st, names[i], sizeof(dname_st)), + *lf = knot_dname_lf(dname, lf_st); + if (!dname || !lf) { + ok(false, "trie: converting '%s'", names[i]); + return; + } + + trie_val_t *val = trie_get_ins(trie, lf + 1 , lf[0]); + if (!val || *val != NULL) { + ok(false, "trie: inserting '%s' (as dname_lf)", names[i]); + return; + } + *val = (void *)names[i]; + } + + /* Perform each test query. */ + for (int i = 0; i < sizeof(qa_pairs) / sizeof(qa_pairs[0]); ++i) { + knot_dname_storage_t q_dname_st, q_lf_st; + const knot_dname_t *q_dname = + knot_dname_from_str(q_dname_st, qa_pairs[i][0], sizeof(q_dname_st)); + const knot_dname_t *q_lf = knot_dname_lf(q_dname, q_lf_st); + if (!q_dname || !q_lf) { + ok(false, "trie: converting '%s'", qa_pairs[i][0]); + return; + } + + const char **ans = (const char **)trie_get_try_wildcard(trie, q_lf + 1, q_lf[0]); + bool is_ok = !!ans == !!qa_pairs[i][1] && (!ans || !strcmp(*ans, qa_pairs[i][1])); + if (!is_ok) { + ok(false, "trie: wildcard test for '%s' -> '%s'", + qa_pairs[i][0], ans ? *ans : "<null>"); + return; + } + } + + trie_free(trie); + ok(true, "trie: wildcard searches"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Random keys. */ + srand(time(NULL)); + unsigned key_count = 100000; + char **keys = malloc(sizeof(char*) * key_count); + /* key must have at least one char and a nul terminator + so that the before/after checks have a char to modify */ + for (unsigned i = 0; i < key_count; ++i) { + keys[i] = str_key_rand(rand() % (KEY_MAXLEN - 2) + 2); + } + + /* Sort random keys. */ + str_key_sort(keys, key_count); + + /* Create trie */ + trie_val_t *val = NULL; + trie_t *trie = trie_create(NULL); + ok(trie != NULL, "trie: create"); + + /* Insert keys */ + bool passed = true; + size_t inserted = 0; + for (unsigned i = 0; i < key_count; ++i) { + val = trie_get_ins(trie, (uint8_t *)keys[i], strlen(keys[i]) + 1); + if (!val) { + passed = false; + break; + } + if (*val == NULL) { + *val = keys[i]; + ++inserted; + } + } + ok(passed, "trie: insert"); + + /* Check total insertions against trie weight. */ + is_int(trie_weight(trie), inserted, "trie: trie weight matches insertions"); + + /* Lookup all keys */ + passed = true; + for (unsigned i = 0; i < key_count; ++i) { + val = trie_get_try(trie, (uint8_t *)keys[i], strlen(keys[i]) + 1); + if (val && (*val == keys[i] || strcmp(*val, keys[i]) == 0)) { + continue; + } else { + diag("trie: mismatch on element '%u'", i); + passed = false; + break; + } + } + ok(passed, "trie: lookup all keys"); + + /* Lesser or equal lookup. */ + passed = true; + for (unsigned i = 0; i < key_count; ++i) { + if (!str_key_get_leq(trie, keys, i, key_count)) { + passed = false; + for (int off = -10; off < 10; ++off) { + int k = (int)i + off; + if (k < 0 || k >= key_count) { + continue; + } + diag("[%u/%d]: %s%s", i, off, off == 0?">":"",keys[k]); + } + break; + } + } + ok(passed, "trie: find lesser or equal for all keys"); + + /* Sorted iteration. */ + char key_buf[KEY_MAXLEN] = {'\0'}; + size_t iterated = 0; + trie_it_t *it = trie_it_begin(trie); + while (!trie_it_finished(it)) { + size_t cur_key_len = 0; + const char *cur_key = (const char *)trie_it_key(it, &cur_key_len); + if (iterated > 0) { /* Only if previous exists. */ + if (strcmp(key_buf, cur_key) > 0) { + diag("'%s' <= '%s' FAIL\n", key_buf, cur_key); + break; + } + } + ++iterated; + memcpy(key_buf, cur_key, cur_key_len); + trie_it_next(it); + } + is_int(inserted, iterated, "trie: sorted iteration"); + trie_it_free(it); + + /* Cleanup */ + for (unsigned i = 0; i < key_count; ++i) { + free(keys[i]); + } + free(keys); + trie_free(trie); + + /* Test trie_get_try_wildcard(). */ + test_wildcards(); + + return 0; +} diff --git a/tests/contrib/test_siphash.c b/tests/contrib/test_siphash.c new file mode 100644 index 0000000..1ca019b --- /dev/null +++ b/tests/contrib/test_siphash.c @@ -0,0 +1,135 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <tap/basic.h> + +// Prevent possible linking with a system SiphHash (OpenBSD). +#include "contrib/openbsd/siphash.c" + +// https://github.com/veorq/SipHash +const uint8_t vectors24[64][8] = { + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72 }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74 }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85 }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18 }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93 }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4 }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75 }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14 }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7 }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1 }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69 }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0 }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93 }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8 }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8 }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17 }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6 }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32 }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71 }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7 }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12 }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15 }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31 }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02 }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18 }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4 }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9 }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9 }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0 }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6 }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7 }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1 }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81 }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24 }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7 }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60 }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66 }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5 }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95 }, +}; + +static void block_test(SIPHASH_KEY *key, uint8_t *data, int data_len, int block_len) +{ + int count = data_len / block_len; + int rest = data_len % block_len; + + SIPHASH_CTX ctx; + SipHash24_Init(&ctx, key); + + for (int i = 0; i < count; i++) { + SipHash24_Update(&ctx, data + i * block_len, block_len); + } + SipHash24_Update(&ctx, data + count * block_len, rest); + + uint64_t hash = SipHash24_End(&ctx); + ok(memcmp(&hash, vectors24[data_len], sizeof(uint64_t)) == 0, + "siphash24: %i-byte block updates", block_len); +} + +int main(void) +{ + plan_lazy(); + + SIPHASH_KEY key; + memcpy(&key.k0, "\x00\x01\x02\x03\x04\x05\x06\x07", sizeof(uint64_t)); + memcpy(&key.k1, "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", sizeof(uint64_t)); + + uint8_t data[64]; + for (int i = 0; i < sizeof(data); i++) { + data[i] = i; + } + + for (int data_len = 0; data_len < sizeof(data); data_len++) { + diag("data length %i", data_len); + + uint64_t hash = SipHash24(&key, data, data_len); + ok(memcmp(&hash, vectors24[data_len], sizeof(uint64_t)) == 0, + "siphash24: 1-block update"); + + for (int block_len = 1; block_len <= 8; block_len++) { + block_test(&key, data, data_len, block_len); + } + } + + return 0; +} diff --git a/tests/contrib/test_sockaddr.c b/tests/contrib/test_sockaddr.c new file mode 100644 index 0000000..7a5cf54 --- /dev/null +++ b/tests/contrib/test_sockaddr.c @@ -0,0 +1,256 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "contrib/sockaddr.h" +#include "libknot/errcode.h" + +static void test_sockaddr_is_any(void) +{ + struct sockaddr_storage invalid = { 0 }; + ok(!sockaddr_is_any(&invalid), "sockaddr_is_any: invalid"); + + struct sockaddr_storage path = { 0 }; + path.ss_family = AF_UNIX; + ok(!sockaddr_is_any(&path), "sockaddr_is_any: unix"); + + struct sockaddr_storage ipv4_local = { 0 }; + sockaddr_set(&ipv4_local, AF_INET, "127.0.0.1", 0); + ok(!sockaddr_is_any(&ipv4_local), "sockaddr_is_any: IPv4 local"); + + struct sockaddr_storage ipv4_any = { 0 }; + sockaddr_set(&ipv4_any, AF_INET, "0.0.0.0", 0); + ok(sockaddr_is_any(&ipv4_any), "sockaddr_is_any: IPv4 any"); + + struct sockaddr_storage ipv6_local = { 0 }; + sockaddr_set(&ipv6_local, AF_INET6, "::1", 0); + ok(!sockaddr_is_any(&ipv6_local), "sockaddr_is_any: IPv6 local"); + + struct sockaddr_storage ipv6_any = { 0 }; + sockaddr_set(&ipv6_any, AF_INET6, "::", 0); + ok(sockaddr_is_any(&ipv6_any), "sockaddr_is_any: IPv6 any"); +} + +static void check_sockaddr_set(struct sockaddr_storage *ss, int family, + const char *straddr, int port) +{ + int ret = sockaddr_set(ss, family, straddr, port); + is_int(KNOT_EOK, ret, "set address '%s'", straddr); +} + +static void test_net_match(void) +{ + int ret; + struct sockaddr_storage t = { 0 }; + + // 127 dec ~ 01111111 bin + // 170 dec ~ 10101010 bin + struct sockaddr_storage ref4 = { 0 }; + check_sockaddr_set(&ref4, AF_INET, "127.170.170.127", 0); + + // 7F hex ~ 01111111 bin + // AA hex ~ 10101010 bin + struct sockaddr_storage ref6 = { 0 }; + check_sockaddr_set(&ref6, AF_INET6, "7FAA::AA7F", 0); + + ret = sockaddr_net_match(&ref4, &ref6, 32); + ok(ret == false, "match: family mismatch"); + + ret = sockaddr_net_match(NULL, &ref4, 32); + ok(ret == false, "match: NULL first parameter"); + ret = sockaddr_net_match(&ref4, NULL, 32); + ok(ret == false, "match: NULL second parameter"); + + ret = sockaddr_net_match(&ref4, &ref4, -1); + ok(ret == true, "match: ipv4 - identity, auto full prefix"); + ret = sockaddr_net_match(&ref4, &ref4, 31); + ok(ret == true, "match: ipv4 - identity, subnet"); + ret = sockaddr_net_match(&ref4, &ref4, 32); + ok(ret == true, "match: ipv4 - identity, full prefix"); + ret = sockaddr_net_match(&ref4, &ref4, 33); + ok(ret == true, "match: ipv4 - identity, prefix overflow"); + + ret = sockaddr_net_match(&ref6, &ref6, -1); + ok(ret == true, "match: ipv6 - identity, auto full prefix"); + ret = sockaddr_net_match(&ref6, &ref6, 127); + ok(ret == true, "match: ipv6 - identity, subnet"); + ret = sockaddr_net_match(&ref6, &ref6, 128); + ok(ret == true, "match: ipv6 - identity, full prefix"); + ret = sockaddr_net_match(&ref6, &ref6, 129); + ok(ret == true, "match: ipv6 - identity, prefix overflow"); + + // 124 dec ~ 01111100 bin + check_sockaddr_set(&t, AF_INET, "124.0.0.0", 0); + ret = sockaddr_net_match(&t, &ref4, 5); + ok(ret == true, "match: ipv4 - first byte, shorter prefix"); + ret = sockaddr_net_match(&t, &ref4, 6); + ok(ret == true, "match: ipv4 - first byte, precise prefix"); + ret = sockaddr_net_match(&t, &ref4, 7); + ok(ret == false, "match: ipv4 - first byte, not match"); + + check_sockaddr_set(&t, AF_INET, "127.170.170.124", 0); + ret = sockaddr_net_match(&t, &ref4, 29); + ok(ret == true, "match: ipv4 - last byte, shorter prefix"); + ret = sockaddr_net_match(&t, &ref4, 30); + ok(ret == true, "match: ipv4 - last byte, precise prefix"); + ret = sockaddr_net_match(&t, &ref4, 31); + ok(ret == false, "match: ipv4 - last byte, not match"); + + // 7C hex ~ 01111100 bin + check_sockaddr_set(&t, AF_INET6, "7CAA::", 0); + ret = sockaddr_net_match(&t, &ref6, 5); + ok(ret == true, "match: ipv6 - first byte, shorter prefix"); + ret = sockaddr_net_match(&t, &ref6, 6); + ok(ret == true, "match: ipv6 - first byte, precise prefix"); + ret = sockaddr_net_match(&t, &ref6, 7); + ok(ret == false, "match: ipv6 - first byte, not match"); + + check_sockaddr_set(&t, AF_INET6, "7FAA::AA7C", 0); + ret = sockaddr_net_match(&t, &ref6, 125); + ok(ret == true, "match: ipv6 - last byte, shorter prefix"); + ret = sockaddr_net_match(&t, &ref6, 126); + ok(ret == true, "match: ipv6 - last byte, precise prefix"); + ret = sockaddr_net_match(&t, &ref6, 127); + ok(ret == false, "match: ipv6 - last byte, not match"); + + // UNIX socket path tests + + struct sockaddr_storage ref_un = { 0 }; + check_sockaddr_set(&ref_un, AF_UNIX, "/tmp/knot.listen", 0); + + check_sockaddr_set(&t, AF_UNIX, "/tmp/knot.listen", 0); + ret = sockaddr_net_match(&t, &ref_un, 0); + ok(ret == true, "match: UNIX, match"); + + check_sockaddr_set(&t, AF_UNIX, "/tmp/knot.liste", 0); + ret = sockaddr_net_match(&t, &ref_un, 0); + ok(ret == false, "match: UNIX, shorter, not match"); + + check_sockaddr_set(&t, AF_UNIX, "/tmp/knot.listen.", 0); + ret = sockaddr_net_match(&t, &ref_un, 0); + ok(ret == false, "match: UNIX, longer, not match"); + + check_sockaddr_set(&t, AF_UNIX, "1234567890123456789012345678901234567890", 0); + ret = sockaddr_net_match(&t, &ref_un, 0); + ok(ret == false, "match: UNIX, longer than max for sockaddr_t, not match"); +} + +static void test_range_match(void) +{ + bool ret; + struct sockaddr_storage t = { 0 }; + struct sockaddr_storage min = { 0 }; + struct sockaddr_storage max = { 0 }; + + // IPv4 tests. + + check_sockaddr_set(&min, AF_INET, "0.0.0.0", 0); + check_sockaddr_set(&max, AF_INET, "255.255.255.255", 0); + + check_sockaddr_set(&t, AF_INET, "0.0.0.0", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == true, "match: ipv4 max range - minimum"); + check_sockaddr_set(&t, AF_INET, "255.255.255.255", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == true, "match: ipv4 max range - maximum"); + + check_sockaddr_set(&min, AF_INET, "1.13.113.213", 0); + check_sockaddr_set(&max, AF_INET, "2.24.124.224", 0); + + check_sockaddr_set(&t, AF_INET, "1.12.113.213", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == false, "match: ipv4 middle range - negative far min"); + check_sockaddr_set(&t, AF_INET, "1.13.113.212", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == false, "match: ipv4 middle range - negative close min"); + check_sockaddr_set(&t, AF_INET, "1.13.113.213", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == true, "match: ipv4 middle range - minimum"); + check_sockaddr_set(&t, AF_INET, "1.13.213.213", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == true, "match: ipv4 middle range - middle"); + check_sockaddr_set(&t, AF_INET, "2.24.124.224", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == true, "match: ipv4 middle range - max"); + check_sockaddr_set(&t, AF_INET, "2.24.124.225", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == false, "match: ipv4 middle range - negative close max"); + check_sockaddr_set(&t, AF_INET, "2.25.124.225", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == false, "match: ipv4 middle range - negative far max"); + + // IPv6 tests. + + check_sockaddr_set(&min, AF_INET6, "::0", 0); + check_sockaddr_set(&max, AF_INET6, + "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", 0); + + check_sockaddr_set(&t, AF_INET6, "::0", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == true, "match: ipv6 max range - minimum"); + check_sockaddr_set(&t, AF_INET6, + "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == true, "match: ipv6 max range - maximum"); + + check_sockaddr_set(&min, AF_INET6, "1:13::ABCD:200B", 0); + check_sockaddr_set(&max, AF_INET6, "2:A24::124:224", 0); + + check_sockaddr_set(&t, AF_INET6, "1:12::BCD:2000", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == false, "match: ipv6 middle range - negative far min"); + check_sockaddr_set(&t, AF_INET6, "1:13::ABCD:200A", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == false, "match: ipv6 middle range - negative close min"); + check_sockaddr_set(&t, AF_INET6, "1:13::ABCD:200B", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == true, "match: ipv6 middle range - minimum"); + check_sockaddr_set(&t, AF_INET6, "1:13:0:12:34:0:ABCD:200B", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == true, "match: ipv6 middle range - middle"); + check_sockaddr_set(&t, AF_INET6, "2:A24::124:224", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == true, "match: ipv6 middle range - max"); + check_sockaddr_set(&t, AF_INET6, "2:A24::124:225", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == false, "match: ipv6 middle range - negative close max"); + check_sockaddr_set(&t, AF_INET6, "2:FA24::4:24", 0); + ret = sockaddr_range_match(&t, &min, &max); + ok(ret == false, "match: ipv6 middle range - negative far max"); + + // UNIX socket path tests + + check_sockaddr_set(&t, AF_UNIX, "/tmp/knot.listen", 0); + ret = sockaddr_range_match(&t, &t, &t); + ok(ret == false, "match: range not supported for UNIX"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("sockaddr_is_any"); + test_sockaddr_is_any(); + + diag("sockaddr_net_match"); + test_net_match(); + + diag("sockaddr_range_match"); + test_range_match(); + + return 0; +} diff --git a/tests/contrib/test_spinlock.c b/tests/contrib/test_spinlock.c new file mode 100644 index 0000000..0d5122b --- /dev/null +++ b/tests/contrib/test_spinlock.c @@ -0,0 +1,78 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <signal.h> +#include <tap/basic.h> + +#include "knot/server/dthreads.h" +#include "contrib/spinlock.h" + +#define THREADS 8 +#define CYCLES 100000 + +static volatile int counter = 0; +static volatile int tens_counter = 0; +static knot_spin_t spinlock; + +static int thread(struct dthread *thread) +{ + volatile int i, j, k; + + for (i = 0; i < CYCLES; i++) { + knot_spin_lock(&spinlock); + j = counter; + k = tens_counter; + if (++j % 10 == 0) { + k++; + } + tens_counter = k; + counter = j; + knot_spin_unlock(&spinlock); + } + + return 0; +} + +// Signal handler +static void interrupt_handle(int s) +{ +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // Register service and signal handler + struct sigaction sa; + sa.sa_handler = interrupt_handle; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGALRM, &sa, NULL); // Interrupt + + knot_spin_init(&spinlock); + + dt_unit_t *unit = dt_create(THREADS, thread, NULL, NULL); + dt_start(unit); + dt_join(unit); + dt_delete(&unit); + + knot_spin_destroy(&spinlock); + + is_int(THREADS * CYCLES, counter, "spinlock: protected counter one"); + is_int(THREADS * CYCLES / 10, tens_counter, "spinlock: protected counter two"); + + return 0; +} diff --git a/tests/contrib/test_string.c b/tests/contrib/test_string.c new file mode 100644 index 0000000..681dd61 --- /dev/null +++ b/tests/contrib/test_string.c @@ -0,0 +1,59 @@ +/* Copyright (C) 2015 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <stdlib.h> + +#include "contrib/string.h" + +static void test_strstrip(void) +{ + char *c = NULL; + + c = strstrip("hello"); + is_string("hello", c, "strstrip: no whitespace"); + free(c); + + c = strstrip("world \n"); + is_string("world", c, "strstrip: trailing whitespace"); + free(c); + + c = strstrip(" \n banana"); + is_string("banana", c, "strstrip: leading whitespace"); + free(c); + + c = strstrip(" \t hello world \n"); + is_string("hello world", c, "strstrip: leading and trailing"); + free(c); + + c = strstrip(""); + is_string("", c, "strstrip: empty string"); + free(c); + + c = strstrip(" "); + is_string("", c, "strstrip: just whitespaces"); + free(c); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_strstrip(); + + return 0; +} diff --git a/tests/contrib/test_strtonum.c b/tests/contrib/test_strtonum.c new file mode 100644 index 0000000..e883575 --- /dev/null +++ b/tests/contrib/test_strtonum.c @@ -0,0 +1,156 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <tap/basic.h> + +#include "contrib/strtonum.h" +#include "libdnssec/error.h" +#include "libknot/attribute.h" + +static void test_u8(const char *in, uint8_t expected, int errcode) +{ + uint8_t out = 0x11; + assert(expected != out); + + ok(str_to_u8(in, &out) == errcode && + (errcode != KNOT_EOK || out == expected), + "str_to_u8 %s on \"%s\"", + (errcode == KNOT_EOK ? "succeeds" : "fails"), in); +} + +static void test_u16(const char *in, uint16_t expected, int errcode) +{ + uint16_t out = 0x0101; + assert(expected != out); + + ok(str_to_u16(in, &out) == errcode && + (errcode != KNOT_EOK || out == expected), + "str_to_u16 %s on \"%s\"", + (errcode == KNOT_EOK ? "succeeds" : "fails"), in); +} + +static void test_u32(const char *in, uint32_t expected, int errcode) +{ + uint32_t out = 0x010101; + assert(expected != out); + + ok(str_to_u32(in, &out) == errcode && + (errcode != KNOT_EOK || out == expected), + "str_to_u32 %s on \"%s\"", + (errcode == KNOT_EOK ? "succeeds" : "fails"), in); +} + +static void test_int(const char *in, int expected, int errcode) +{ + int out = 12345; + assert(expected != out); + + ok(str_to_int(in, &out, INT_MIN, INT_MAX) == errcode && + (errcode != KNOT_EOK || out == expected), + "str_to_int %s on \"%s\"", + (errcode == KNOT_EOK ? "succeeds" : "fails"), in); +} + +static void test_size(const char *in, size_t expected, size_t min, size_t max, + int errcode) +{ + size_t out = 12345; + assert(expected != out); + + ok(str_to_size(in, &out, min, max) == errcode && + (errcode != KNOT_EOK || out == expected), + "str_to_int %s on \"%s\"", + (errcode == KNOT_EOK ? "succeeds" : "fails"), in); +} + +#define asprintf(args, ...) do { \ + _unused_ int r = (asprintf)(args, ##__VA_ARGS__); assert(r >= 0); \ +} while (0); + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_u8("-1", 0, KNOT_EINVAL); + test_u8("256", 0, KNOT_ERANGE); + test_u8("0x1", 0, KNOT_EINVAL); + test_u8(" 1", 0, KNOT_EINVAL); + test_u8("1 ", 0, KNOT_EINVAL); + test_u8("0", 0, KNOT_EOK); + test_u8("42", 42, KNOT_EOK); + test_u8("+84", 84, KNOT_EOK); + test_u8("255", UINT8_MAX, KNOT_EOK); + + test_u16("-1", 0, KNOT_EINVAL); + test_u16("65536", 0, KNOT_ERANGE); + test_u16("0x1", 0, KNOT_EINVAL); + test_u16(" 1", 0, KNOT_EINVAL); + test_u16("1 ", 0, KNOT_EINVAL); + test_u16("0", 0, KNOT_EOK); + test_u16("65280", 65280, KNOT_EOK); + test_u16("+256", 256, KNOT_EOK); + test_u16("65535", UINT16_MAX, KNOT_EOK); + + test_u32("-1", 0, KNOT_EINVAL); + test_u32("4294967296", 0, KNOT_ERANGE); + test_u32("0x1", 0, KNOT_EINVAL); + test_u32(" 1", 0, KNOT_EINVAL); + test_u32("1 ", 0, KNOT_EINVAL); + test_u32("0", 0, KNOT_EOK); + test_u32("65280", 65280, KNOT_EOK); + test_u32("+256", 256, KNOT_EOK); + test_u32("4294967295", UINT32_MAX, KNOT_EOK); + + test_size("-1", 0, 0, 1, KNOT_EINVAL); + test_size("4294967296", 0, 0, 1, KNOT_ERANGE); + test_size("0", 0, 1, 2, KNOT_ERANGE); + test_size("0x1", 0, 0, 1, KNOT_EINVAL); + test_size(" 1", 0, 0, 1, KNOT_EINVAL); + test_size("1 ", 0, 0, 1, KNOT_EINVAL); + test_size("0", 0, 0, 1, KNOT_EOK); + test_size("65280", 65280, 0, 65280, KNOT_EOK); + test_size("+256", 256, 0, 65280, KNOT_EOK); + + char *int_under = NULL; + asprintf(&int_under, "%lld", (long long)INT_MIN - 1); + char *int_min = NULL; + asprintf(&int_min, "%lld", (long long)INT_MIN); + char *int_max = NULL; + asprintf(&int_max, "%lld", (long long)INT_MAX); + char *int_over = NULL; + asprintf(&int_over, "%lld", (long long)INT_MAX + 1); + + test_int(int_under, 0, KNOT_ERANGE); + test_int(int_over, 0, KNOT_ERANGE); + test_int("0x1", 0, KNOT_EINVAL); + test_int(" 1", 0, KNOT_EINVAL); + test_int("1 ", 0, KNOT_EINVAL); + test_int(int_min, INT_MIN, KNOT_EOK); + test_int("0", 0, KNOT_EOK); + test_int("268435459", 268435459, KNOT_EOK); + test_int("+1073741827", 1073741827, KNOT_EOK); + test_int(int_max, INT_MAX, KNOT_EOK); + + free(int_under); + free(int_min); + free(int_max); + free(int_over); + + return 0; +} diff --git a/tests/contrib/test_time.c b/tests/contrib/test_time.c new file mode 100644 index 0000000..84518f2 --- /dev/null +++ b/tests/contrib/test_time.c @@ -0,0 +1,203 @@ +/* Copyright (C) 2017 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <string.h> + +#include "contrib/time.h" + +static void test_now(void) +{ + struct timespec t = time_now(); + ok(t.tv_sec != 0, "time_now() returns something"); +} + +static void test_diff(void) +{ + struct timespec t1 = { 10, 1000 }; + struct timespec t2 = { 50, 1500 }; + struct timespec t3 = { 70, 500 }; + + struct timespec res; + + res = time_diff(&t1, &t2); + ok(res.tv_sec == 40 && res.tv_nsec == 500, "time_diff()"); + + res = time_diff(&t2, &t3); + ok(res.tv_sec == 19 && res.tv_nsec == 999999000, "time_diff() ns overflow"); + + res = time_diff(&t3, &t1); + ok(res.tv_sec == -60 && res.tv_nsec == 500, "time_diff() negative"); + + res = time_diff(&t2, &t1); + ok(res.tv_sec == -41 && res.tv_nsec == 999999500, "time_diff() negative"); +} + +static void test_diff_ms(void) +{ + struct timespec t1 = { 10, 1000 }; + struct timespec t2 = { 50, 500 }; + + float ms = 0.0; + + ms = time_diff_ms(&t1, &t2); + ok(39990.0 < ms && ms < 40010.0, "time_diff_ms()"); + + ms = time_diff_ms(&t2, &t1); + ok(-40010.0 < ms && ms < -39990.0, "time_diff_ms() negative"); +} + +static void test_knot_time(void) +{ + knot_time_t a = knot_time(); + knot_time_t inf = 0; + knot_time_t c; + knot_timediff_t d; + int ret; + + ok(a != 0, "knot time not zero"); + + ret = knot_time_cmp(a, a); + ok(ret == 0, "compare same times"); + + ret = knot_time_cmp(a - 1, a + 1); + ok(ret == -1, "compare smaller time"); + + ret = knot_time_cmp(a + 10, a - 10); + ok(ret == 1, "compare bigger time"); + + ret = knot_time_cmp(inf, inf); + ok(ret == 0, "compare two infinities"); + + ret = knot_time_cmp(a, inf); + ok(ret == -1, "compare time and infinity"); + + ret = knot_time_cmp(inf, a); + ok(ret == 1, "compare infinity and time"); + + c = knot_time_min(a, a); + ok(c == a, "take same time"); + + c = knot_time_min(a, a + 1); + ok(c == a, "take first smaller"); + + c = knot_time_min(a + 1, a); + ok(c == a, "take second smaller"); + + c = knot_time_min(inf, inf); + ok(c == inf, "take same infinity"); + + c = knot_time_min(a, inf); + ok(c == a, "take first finite"); + + c = knot_time_min(inf, a); + ok(c == a, "take second finite"); + + d = knot_time_diff(a + 1, a); + ok(d == 1, "positive diff"); + + d = knot_time_diff(a, a + 1); + ok(d == -1, "negative diff"); + + d = knot_time_diff(inf, inf); + ok(d == KNOT_TIMEDIFF_MAX, "positive double infinity diff"); + + d = knot_time_diff(inf, a); + ok(d == KNOT_TIMEDIFF_MAX, "positive infinity diff"); + + d = knot_time_diff(a, inf); + ok(d == KNOT_TIMEDIFF_MIN, "negative infinity diff"); +} + +static void test_time_parse_expect(int ret, knot_time_t res, + knot_time_t expected, const char *msg) +{ + ok(ret == 0, "time_parse %s ok", msg); + ok(res == expected, "time_parse %s result", msg); +} + +static void test_time_parse(void) +{ + knot_time_t res; + int ret; + + ret = knot_time_parse("", "", &res); + test_time_parse_expect(ret, res, 0, "nihilist"); + + ret = knot_time_parse("#", "12345", &res); + test_time_parse_expect(ret, res, 12345, "unix"); + + ret = knot_time_parse("+-#U", "-1h", &res); + test_time_parse_expect(ret, res, knot_time() - 3600, "hour"); + + ret = knot_time_parse("+-#u'nths'|+-#u'nutes'", "+1minutes", &res); + test_time_parse_expect(ret, res, knot_time() + 60, "minute"); +} + +static void test_time_print_expect(int ret, const char *res, int res_len, + const char *expected, const char *msg) +{ + ok(ret == 0, "time_print %s ok", msg); + ok(strncmp(res, expected, res_len) == 0, "time_print %s result", msg); +} + +static void test_time_print(void) +{ + char buff[100]; + int bufl = sizeof(buff); + int ret; + knot_time_t t = 44000, t2, big; + + ret = knot_time_print(TIME_PRINT_UNIX, t, buff, bufl); + test_time_print_expect(ret, buff, bufl, "44000", "unix"); + + t2 = knot_time_add(knot_time(), -10000); + ret = knot_time_print(TIME_PRINT_RELSEC, t2, buff, bufl); + test_time_print_expect(ret, buff, bufl, "-10000", "relsec"); + + ret = knot_time_print(TIME_PRINT_ISO8601, t, buff, bufl); + buff[11] = '0', buff[12] = '0'; // zeroing 'hours' field to avoid locality issues + test_time_print_expect(ret, buff, bufl, "1970-01-01T00:13:20Z", "iso"); + + t2 = knot_time_add(knot_time(), -10000); + ret = knot_time_print(TIME_PRINT_HUMAN_MIXED, t2, buff, bufl); + test_time_print_expect(ret, buff, bufl, "-2h46m40s", "negative human mixed"); + big = knot_time_add(knot_time(), 2 * 365 * 24 * 3600 + 1); + ret = knot_time_print(TIME_PRINT_HUMAN_MIXED, big, buff, bufl); + test_time_print_expect(ret, buff, bufl, "+2Y1s", "big human mixed"); + + t2 = knot_time_add(knot_time(), -10000); + ret = knot_time_print(TIME_PRINT_HUMAN_LOWER, t2, buff, bufl); + test_time_print_expect(ret, buff, bufl, "-2h46mi40s", "negative human lower"); + big = knot_time_add(knot_time(), 2 * 365 * 24 * 3600 + 1); + ret = knot_time_print(TIME_PRINT_HUMAN_LOWER, big, buff, bufl); + test_time_print_expect(ret, buff, bufl, "+2y1s", "big human lower"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_now(); + test_diff(); + test_diff_ms(); + test_knot_time(); + test_time_parse(); + test_time_print(); + + return 0; +} diff --git a/tests/contrib/test_toeplitz.c b/tests/contrib/test_toeplitz.c new file mode 100644 index 0000000..244137c --- /dev/null +++ b/tests/contrib/test_toeplitz.c @@ -0,0 +1,93 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <tap/basic.h> + +#include "contrib/toeplitz.h" +#include "contrib/wire_ctx.h" + +// Test vectors come from Intel Ethernet Controller X710/XXV710/XL710 Series Datasheet +const uint8_t key[] = { + 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, + 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, + 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, + 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, + 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +void toeplitz_check(int family, const char *src_ip, const char *dst_ip, + uint16_t src_port, uint16_t dst_port, uint32_t expected) +{ + uint8_t data[2 * sizeof(struct in6_addr) + 2 * sizeof(uint16_t)]; + + wire_ctx_t ctx = wire_ctx_init(data, sizeof(data)); + + struct in_addr src_addr4, dst_addr4; + struct in6_addr src_addr6, dst_addr6; + + if (family == AF_INET && + inet_pton(AF_INET, src_ip, &src_addr4) == 1 && + inet_pton(AF_INET, dst_ip, &dst_addr4) == 1) { + wire_ctx_write(&ctx, (uint8_t *)&(src_addr4.s_addr), sizeof(struct in_addr)); + wire_ctx_write(&ctx, (uint8_t *)&(dst_addr4.s_addr), sizeof(struct in_addr)); + } else if (family == AF_INET6 && + inet_pton(AF_INET6, src_ip, &src_addr6) == 1 && + inet_pton(AF_INET6, dst_ip, &dst_addr6) == 1) { + wire_ctx_write(&ctx, (uint8_t *)&(src_addr6.s6_addr), sizeof(struct in6_addr)); + wire_ctx_write(&ctx, (uint8_t *)&(dst_addr6.s6_addr), sizeof(struct in6_addr)); + } else { + assert(0); + } + + wire_ctx_write_u16(&ctx, src_port); + wire_ctx_write_u16(&ctx, dst_port); + + if (ctx.error != KNOT_EOK) { + assert(0); + } + + uint32_t value = toeplitz_hash(key, sizeof(key), data, wire_ctx_offset(&ctx)); + is_int(expected, value, "toeplitz_hash: %u", expected); + + toeplitz_ctx_t toepl; + for (int i = 0; i <= wire_ctx_offset(&ctx); i++) { + toeplitz_init(&toepl, i, key, sizeof(key), data, wire_ctx_offset(&ctx)); + value = toeplitz_finish(&toepl); + is_int(expected, value, "toeplitz_init to %i: %u", i, expected); + } +} + +int main(void) +{ + plan_lazy(); + + toeplitz_check(AF_INET, "66.9.149.187", "161.142.100.80", 2794, 1766, 0x51ccc178); + toeplitz_check(AF_INET, "199.92.111.2", "65.69.140.83", 14230, 4739, 0xc626b0ea); + toeplitz_check(AF_INET, "24.19.198.95", "12.22.207.184", 12898, 38024, 0x5c2b394a); + toeplitz_check(AF_INET, "38.27.205.30", "209.142.163.6", 48228, 2217, 0xafc7327f); + toeplitz_check(AF_INET, "153.39.163.191", "202.188.127.2", 44251, 1303, 0x10e828a2); + + toeplitz_check(AF_INET6, "3ffe:2501:200:1fff::7", "3ffe:2501:200:3::1", 2794, 1766, 0x40207d3d); + toeplitz_check(AF_INET6, "3ffe:501:8::260:97ff:fe40:efab", "ff02::1", 14230, 4739, 0xdde51bbf); + toeplitz_check(AF_INET6, "3ffe:1900:4545:3:200:f8ff:fe21:67cf", "fe80::200:f8ff:fe21:67cf", 44251, 38024, 0x02d1feef); + + return 0; +} diff --git a/tests/contrib/test_wire_ctx.c b/tests/contrib/test_wire_ctx.c new file mode 100644 index 0000000..81386c9 --- /dev/null +++ b/tests/contrib/test_wire_ctx.c @@ -0,0 +1,287 @@ +/* Copyright (C) 2015 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <netinet/in.h> +#include <stdio.h> + +#include "libknot/errcode.h" +#include "contrib/wire_ctx.h" + +#define OK(wire) { \ + is_int(KNOT_EOK, (wire)->error, "check for no error"); \ +} + +#define NOK(wire, code) { \ + is_int(code, (wire)->error, "check for error"); \ +} + +void ok_offset(wire_ctx_t *wire, size_t max, size_t i) +{ + wire_ctx_set_offset(wire, i); + OK(wire); + is_int(max - i, wire_ctx_available(wire), "get available %zu", max - i); + OK(wire); + is_int(i, wire_ctx_offset(wire), "get start position %zu", i); + OK(wire); +} + +void nok_offset(wire_ctx_t *wire, size_t max) +{ + wire_ctx_set_offset(wire, max); + OK(wire); + wire_ctx_set_offset(wire, max + 1); + NOK(wire, KNOT_ERANGE); + is_int(0, wire_ctx_available(wire), "get available %i", 0); + NOK(wire, KNOT_ERANGE); + is_int(max, wire_ctx_offset(wire), "get last start position %zu", max); + NOK(wire, KNOT_ERANGE); +} + +void offset_test(void) +{ + diag("offset operation"); + + const size_t LEN = 3; + uint8_t data[LEN]; + + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); + + // First free byte. + ok_offset(&wire, LEN, 0); + // Last free byte. + ok_offset(&wire, LEN, 2); + // First non-free byte. + ok_offset(&wire, LEN, 3); + // Invalid offset. + nok_offset(&wire, LEN); +} + +void skip_test(void) +{ + diag("skip operation"); + + uint8_t data[3]; + + // Forward skips. + + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); + + wire_ctx_skip(&wire, 2); + OK(&wire); + is_int(2, wire_ctx_offset(&wire), "skip by offset %i", 2); + + wire_ctx_skip(&wire, 1); + OK(&wire); + is_int(3, wire_ctx_offset(&wire), "skip by offset %i", 1); + + // Out-of-bounds skip. + wire_ctx_skip(&wire, 1); + NOK(&wire, KNOT_ERANGE); + is_int(3, wire_ctx_offset(&wire), "out-of-bounds skip by %i", 1); + + // Backward skips. + + wire = wire_ctx_init(data, sizeof(data)); + + wire_ctx_set_offset(&wire, 3); + OK(&wire); + + wire_ctx_skip(&wire, -2); + OK(&wire); + is_int(1, wire_ctx_offset(&wire), "skip by offset %i", -2); + + wire_ctx_skip(&wire, -1); + OK(&wire); + is_int(0, wire_ctx_offset(&wire), "skip by offset %i", -1); + + // Out-of-bounds skip. + wire_ctx_skip(&wire, -1); + NOK(&wire, KNOT_ERANGE); + is_int(0, wire_ctx_offset(&wire), "out-of-bounds skip by %i", -1); +} + +void clear_test(void) +{ + diag("clear operation"); + + uint8_t data[] = { 1, 2, 3 }; + + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); + + wire_ctx_clear(&wire, 10); + NOK(&wire, KNOT_ESPACE); + is_int(1, data[0], "no attempt to clear"); + + wire = wire_ctx_init(data, sizeof(data)); + wire_ctx_clear(&wire, 3); + OK(&wire); + is_int(0, wire_ctx_available(&wire), "no space available"); + for (int i = 0; i < sizeof(data); i++) { + is_int(0, data[i], "wire position %i is zero", i); + } +} + +#define check_rw(size, value, ...) { \ + const uint8_t expect[] = { __VA_ARGS__ }; \ + uint8_t data[sizeof(expect)] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); \ + \ + wire_ctx_write_u ## size(&wire, value); \ + OK(&wire); \ + ok(memcmp(data, expect, sizeof(expect)) == 0, "write %i value", size); \ + is_int(size/8, wire_ctx_offset(&wire), "write %i offset", size); \ + \ + wire_ctx_set_offset(&wire, 0); \ + OK(&wire); \ + \ + uint64_t num = wire_ctx_read_u ## size(&wire); \ + OK(&wire); \ + is_int(value, num, "read %i value", size); \ + is_int(size/8, wire_ctx_offset(&wire), "read %i offset", size); \ +} + +#define check_general_rw(...) { \ + const uint8_t expect[] = { __VA_ARGS__ }; \ + uint8_t data[sizeof(expect)] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); \ + \ + wire_ctx_write(&wire, expect, sizeof(expect)); \ + OK(&wire); \ + ok(memcmp(data, expect, sizeof(expect)) == 0, "write value"); \ + is_int(sizeof(expect), wire_ctx_offset(&wire), "write offset"); \ + \ + wire_ctx_set_offset(&wire, 0); \ + OK(&wire); \ + \ + uint8_t d[sizeof(expect)] = { 0 }; \ + wire_ctx_read(&wire, d, sizeof(expect)); \ + OK(&wire); \ + ok(memcmp(d, expect, sizeof(expect)) == 0, "read value"); \ + is_int(sizeof(expect), wire_ctx_offset(&wire), "read offset"); \ +} + +void read_write_test(void) +{ + diag("read and write operation"); + + check_rw( 8, 0x11, 0x11); + check_rw(16, 0x1122, 0x11, 0x22); + check_rw(32, 0x11223344, 0x11, 0x22, 0x33, 0x44); + check_rw(48, 0x112233445566, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66); + check_rw(64, 0x1122334455667788, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88); + + check_general_rw(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x10); +} + +#define check_rw_over(size) { \ + uint8_t data[1] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); \ + wire_ctx_set_offset(&wire, 1); \ + OK(&wire); \ + \ + wire_ctx_write_u ## size(&wire, 0); \ + NOK(&wire, KNOT_ESPACE); \ + is_int(1, wire_ctx_offset(&wire), "err write %i offset", size); \ + \ + wire = wire_ctx_init(data, sizeof(data)); \ + wire_ctx_set_offset(&wire, 1); \ + OK(&wire); \ + \ + uint64_t num = wire_ctx_read_u ## size(&wire); \ + NOK(&wire, KNOT_EFEWDATA); \ + is_int(0, num, "err read %i value", size); \ + is_int(1, wire_ctx_offset(&wire), "err read %i offset", size); \ +} + +#define check_general_rw_over(void) { \ + uint8_t data[1] = { 0 }; \ + uint8_t d[2] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init(data, sizeof(data)); \ + wire_ctx_write(&wire, d, sizeof(d)); \ + NOK(&wire, KNOT_ESPACE); \ + is_int(0, wire_ctx_offset(&wire), "err write offset"); \ + \ + wire = wire_ctx_init(data, sizeof(data)); \ + wire_ctx_read(&wire, d, sizeof(d)); \ + NOK(&wire, KNOT_EFEWDATA); \ + is_int(0, wire_ctx_offset(&wire), "err read offset"); \ +} + +void read_write_overflow_test(void) +{ + diag("overflow read and write operation"); + + check_rw_over(8); + check_rw_over(16); + check_rw_over(32); + check_rw_over(48); + check_rw_over(64); + + check_general_rw_over(); +} + +#define check_ro(size) { \ + uint8_t data[8] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init_const(data, sizeof(data)); \ + \ + wire_ctx_write_u ## size(&wire, 0); \ + NOK(&wire, KNOT_EACCES); \ + is_int(0, wire_ctx_offset(&wire), "err write %i offset", size); \ +} + +#define check_general_ro(void) { \ + uint8_t data[8] = { 0 }; \ + uint8_t d[2] = { 0 }; \ + \ + wire_ctx_t wire = wire_ctx_init_const(data, sizeof(data)); \ + \ + wire_ctx_write(&wire, d, sizeof(d)); \ + NOK(&wire, KNOT_EACCES); \ + is_int(0, wire_ctx_offset(&wire), "err write offset"); \ +} + +void write_readonly_test(void) +{ + diag("readonly write operation"); + + check_ro(8); + check_ro(16); + check_ro(32); + check_ro(48); + check_ro(64); + + check_general_ro(); +} + +int main(void) +{ + plan_lazy(); + + offset_test(); + skip_test(); + clear_test(); + read_write_test(); + read_write_overflow_test(); + write_readonly_test(); + + return 0; +} diff --git a/tests/knot/semantic_check_data/cdnskey.cds b/tests/knot/semantic_check_data/cdnskey.cds new file mode 100644 index 0000000..6ce5610 --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.cds @@ -0,0 +1,123 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144147 25752 example.com. + dEDk41MHSAAoc2eboWOXxGQHYFj1gXuD/gfX + Qz6HEq44narP0IHuOWt4ni9HUhYDBuanPp7S + j/8nYnZc6gdpMg== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144147 25752 example.com. + 1HFpOHudUJp7hvrsTmdX6qt+X0I4K9RYo/Uy + gpWbJBNhNsPVENVrw8AabhnPaETJGbreS/4T + slgbxM1Ks/erzA== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144147 25752 example.com. + EA9rtC9Ub4LPDwS6Q8wE4g9nGddbVrg9ivHN + oHQzUjTFlxtn8gFPaJkUfHwqwg3PsSVGagyx + Bjsool21k/TG7A== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDS CDNSKEY + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144147 25752 example.com. + YLQPkC55O9bpQI/Hg/Ih91UkieeM3wtQvJMT + ro3QJ2eDImSyeoIbWsF+ghtoQ+6IUulXLu3k + PtDViOe2tfaL/Q== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + 1J1lDp/FQFgAGv7EFeDTAru7rUIcUCc7bkYj + 8OlczfdQjo9IfS5MFg6MqIrE/KPC18CDX1Ki + DzaCFaMGDlavjQ== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 25752 + 3600 DNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + hRcbHnvrTqCb215+XsIn96tvHacV5d15lcnS + h91pg8Htes3H0vOoG98C5oWXoj7RM4V/tDoH + /0ahiLyRzRnvBA== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 20197 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144147 20197 example.com. + JLKC5uLW1+JPkOyVcc8D6B6lCC/0FOlak/Qd + Na6Nb33hi9io1HMFI1eYiG7u7lxWmXsKnBo9 + ONROz+WYGds++Q== ) + 3600 CDS 53851 8 2 ( + 6F8129D687EC387C948E6F4B0AC9AA01481C + CEBF7570AFEC582897E7725122D6 ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144147 20197 example.com. + pgi1+O/TWU6WCmLLYEibCYj+RzbcOuodnF1i + wlBQxDZLTcGYG+1KEC0spZTN1nQncEfdeEKc + jnYQUa0izPQRnA== ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144147 25752 example.com. + MaFyQcB908WIXS+RiLeLXiKdjOo/R6tl9AM/ + 6xokhcvRqQzuyQeoH4snUvcht0m5ghz09Km7 + MPN0uzJcXIGg0Q== ) + 3600 CDNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144147 20197 example.com. + Vdo7aYGIByxiC85dyqLKrrNAYYDFBnKXm8uE + rYSXBMWiQoFHwzvlavyqhUWlEABfvYD0pUrX + PZ27Hz8rPFCSLQ== ) + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144147 25752 example.com. + 9Llt7e4nm8uMLqliT2NZJINmAmLmKDYqjloj + Q3/wNI4K+J0RUmWpg3f6xODVkKjjuVnwpxkK + eWV9zqY4jUTAGg== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144147 25752 example.com. + lZSHyLdXGFvoL9fhk26y70ifFwui2A5bpdir + Su7VhfsnNdLgNuCceRXbYwxQaUyODCl7dcJ9 + UkRzq2eDs0evKQ== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144147 25752 example.com. + dDE1XApt4lZ9u20Z/vXwhJxE27AZJQzKwLkk + jpwEDVJo6/SdV2smB7s7+qmGnSKhIehVpUFX + wv3/3YaFxSTifQ== ) diff --git a/tests/knot/semantic_check_data/cdnskey.delete.both b/tests/knot/semantic_check_data/cdnskey.delete.both new file mode 100644 index 0000000..b3b840b --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.delete.both @@ -0,0 +1,113 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144234 36859 example.com. + uHjgn9WEMdw/d//q2ZhGF1GAQItK9UPyByET + VDuZgER/JBHuFd1/MMEkkFmCRneXuVudSnki + aXiza0GLV0ujfw== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144234 36859 example.com. + 39YAhtx1qe9sbJ/6N1fS7F4QLS9iqagdbQN4 + w6VRyMRrseRY16G2n3Th9yw1+R9aXOazb6iP + BL6azQJiUCZJ5g== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144234 36859 example.com. + EXv3vV7Njpz59INdubRpDsGANROKfEhqBzQ8 + zSL1vujpUOdaZWqmS3uoKusxHCghJacCFeUA + KQNrWNuZHT2S8g== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDS CDNSKEY + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144234 36859 example.com. + LgXpsIgBZBO03iU6D2nqsbmal6AK51ev21Cj + PQFfFBLQ+ARqyE3k7mlTK4A+/UfIpWgpkKnz + St4SbtL3r6GK+g== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + l/Uak3BSxeoEO8n42GtZkS1aTdEV590rAuwS + Jvt8Gzyj1S5Aqx5Tytm+nb93ZtO3eSL2OpJg + p7tdmPjtHKxYpg== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 36859 + 3600 DNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + jNkK9sXUo8jTJ2snaD+3Mao2q0m5UjyZ7ykD + 6yQqTJ2xgldvTCyuu/YlSCoR9gli8pOGz+KT + 3YA9HjG46ob8ug== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 65430 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144234 65430 example.com. + id6EVGBrg2vZm6vIIGNhSukuI2Uv6/MzZiJk + C1N9k5P3zAP6Es9aLp9m4cR8qGIdUu3DZ3AU + ngKndEZvk5YUUg== ) + 3600 CDS 0 0 0 ( + 00 ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144234 36859 example.com. + mDmiCviPRxQ1BiinR2+/lQ/KabHgIu/LSKZ2 + yZFsgiF8YF4IT8mJc/qiKVtaCWLK4Sszxk/F + P8kMTmTKORT40Q== ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144234 65430 example.com. + O1KH8u+VPLnd5TwGPRbv7VpMss+Mjwr+nIOE + UxSS7unksPUldU0e9qXby0fydlN5LTf/L0sD + daMwGOA2fuD/dA== ) + 3600 CDNSKEY 0 3 0 ( + AA== + ) ; ZSK; alg = 0 ; key id = 768 + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144234 36859 example.com. + Hj8WJNT51BdqA6szAI7sn8gZftHY6/1/Y7qQ + DRsunh1J1cNRuqHtLBnRKpVdteZ4znNKnavb + uoC6kzSzbRiJzQ== ) + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144234 65430 example.com. + 7YGVqSgaiHXwY+GdMkUJXZyqkGvkfA8LliB6 + 6Nn4AvuETs4lX080MNq3dWmjI/tHSg5ptQz7 + Hukvd6cYWNgtBQ== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144234 36859 example.com. + SVatJA8FhwAotw625XttyhgD8Rcp4ukcidii + By06YX9e5rCgOHOvjsHwA57kBBzcZg0ZXAbF + SOhDdUQibKaRSg== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144234 36859 example.com. + D+r82Tvm8eGuYrJKVCUMw1Gz+tevXwE2IGoG + 7pXErKbDv13p/eFAPsRdUKtdmsOq4mHSxQuZ + GVGAULfJjcs3pQ== ) diff --git a/tests/knot/semantic_check_data/cdnskey.delete.invalid.cdnskey b/tests/knot/semantic_check_data/cdnskey.delete.invalid.cdnskey new file mode 100644 index 0000000..366edaf --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.delete.invalid.cdnskey @@ -0,0 +1,113 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144623 39533 example.com. + wXvCukXPMbON0oD2nKINzyauQRgeYE/kIYKZ + pYaMwV5Z6yZ9SKSSy7oRBn7t1+rOmGI69NSx + 3WHXaRiLjcH1Sg== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144623 39533 example.com. + XNdl4tiEhUPOpEgwGO2njssc8QMB8IeP5QDM + 9/LZJUPZ0hZ76F7fX9C3X3edgysEoDFR1HAE + JdTxkJ5Oqv7Xig== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144623 39533 example.com. + Or2a9ZLl2FnBmNM1KbUcgAjgLKRS6O9H4XmK + VAGM3QxutaTZuF1sjsz+kNh6yrT38eLm5B8M + PLCxUmkTSUmgeA== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDS CDNSKEY + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144623 39533 example.com. + 5SBXb1HpSfhPinO3hadK7E0lhRHwyUAsjZpy + /7jTO7/uUNXD6asY9V6kvOJmRgMpSeXFJKFw + +Vsyx0jifistyg== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + TQSEqjdF8egQ1YjZPdVXrX+pngPHTdCgwJFR + AefWVHOLsMADS3/LL5G+pZTSldB3j3Xo4Na/ + 1tsuCgNmV+58xA== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 39533 + 3600 DNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + VARBBNSEYzAbBYxgdQi/epYgWFaGnL49509p + CeZWg4LO4jhjVT7uyhsSQny2wyahP2Y37YeO + d+sY503BNpqzMQ== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 59324 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144623 59324 example.com. + YRhAwruTjWmu6drb4+iJ/QOwQg8dnGur8LH7 + bsn1ZCHQYNDHiIai8JqikqzkhEYKIK8HIqT8 + F2RY/LqFxKebjg== ) + 3600 CDS 0 0 0 ( + 00 ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144623 39533 example.com. + cHTGBug23nTe/aS09JaakuG4wa9EEbWxL3gu + LQpCK8HV/JMsNSGqh1FsUlX92y4tSIvJn+Lx + vvdN+Qzh+zASHg== ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144623 59324 example.com. + GU9Q/CipUscofDL6uhT2ZmhQoyApLX9zbyfN + dG5XW6sXYaB94hVSiT2DSyt19fyQwYoKK2Br + fJwy4pI890kKoQ== ) + 3600 CDNSKEY 0 3 0 ( + BA== + ) ; ZSK; alg = 0 ; key id = 1792 + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144623 39533 example.com. + CXeUfFxa7aT2tivKLovVQ2CA0HYZxxlUrbm1 + voABTNkU7lb5W9Z7GQ/VDugd8QeKNK8YWOaQ + Tdl79jkL1rQKXw== ) + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144623 59324 example.com. + sd+fzJmLLIoFIcbKCJ+rHE+tOs0PwHjjY9ml + Dsbel1k5sANI4xR8iMv6YAEhcpvb0S+8Nd7h + 7BT45SkKVtyFsQ== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144623 39533 example.com. + VGa9LkgVATBLHOwMBNc6g74iXCCSXnWWNs8O + ndoXk4ZMMRRkmaxSWXH2pBdJLZPL5f26aEVl + 4toVcsE722LoFA== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144623 39533 example.com. + i+94RvIQBBEOza7Y963huNEWYrqt/VT/eE1E + Gqx5kngvZgZ7wO8tcOsaE7ctb69SvgZwRR9c + RBgb2N6ezo9OxA== ) diff --git a/tests/knot/semantic_check_data/cdnskey.delete.invalid.cds b/tests/knot/semantic_check_data/cdnskey.delete.invalid.cds new file mode 100644 index 0000000..9d63eb9 --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.delete.invalid.cds @@ -0,0 +1,113 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144646 56106 example.com. + 1CRyeUic9BIwBWcjk95VQJktQng6f3dLQm64 + JwGGqivUM3Hgp7URguNIx0BsCvfo67NIpk7N + mMIFwMkMGOHmgg== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144646 56106 example.com. + pB4+Z3ltuzY+/NkAeCb9LOS7Zlh7QLfHKimR + JPtvdOuIhd8vB0NZLzcYX0lIkrqyP3LadbrS + u8r9BMIlu4cKpg== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144646 56106 example.com. + x8XhP7r3/glI7AenoSLVmfqhZXQfj6YllgxA + jkVxExiM9OJZOPdyeDTuRyUD1PFiBOEsP7Wu + vNgWA9eyQFOslA== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDS CDNSKEY + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144646 56106 example.com. + TCn7V7sHR2TNY5ywyEpbYZMegZwTX+I/TPeO + 76D3WORu9pN0kJWjGPAebwTvL/a7p8xS8B9U + X9ivUVFORG+mJA== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + cOjtacSzGkoh6bO4clqYPM2y+g5ezQUtCNdx + iRqickHCvQnL9OM/h7V8txqEsSulG5ZCeW+O + LDhDQDUchpNv7A== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 56106 + 3600 DNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + pB2mCNXFJ8e+UaMeMmy1LSCv6TJ92Fs3kFxY + I8NyZPyGvfePpMlzWZr7Bw7wS6G6Jhayhj94 + MMJ4lM/5+ZzVJw== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 45911 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144646 45911 example.com. + uOAPEzDkPNI9Uo2N+iiRkIb2p1Y0VhgqwUom + +Dssd6X0CEdQEmD8YQ43Cuq9ZNwk8Bm+lgm3 + X+ImdIKeE4MvNQ== ) + 3600 CDS 0 0 0 ( + 01 ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144646 45911 example.com. + IN5tLpm7OKjIL4VpucR1ero1Gv5UEyVqjzB9 + rRJefwUtlZFKNaTbU0oQD33vQXEjUiIMr66b + zIC3Ju/YtYFDLg== ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144646 56106 example.com. + f8VJa9GRwSWNmg0AR4nA3OD4X8im7BriZjME + 2ypYUOJkdIafolyb0LDz7XWTaVsFHQWO0z+J + 14g0CgCroTm3pQ== ) + 3600 CDNSKEY 0 3 0 ( + AA== + ) ; ZSK; alg = 0 ; key id = 768 + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144646 45911 example.com. + 89oeIQuH82i2RYIj/fnX/71s8kspDHcI8lIa + R02OZZ9bF37bi6LbGkypdXpmxN9/rEjk4ThF + IHRX2USEPtl+wQ== ) + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144646 56106 example.com. + Hgf4SgtoV0IHsF6feSP8YqeibPTtwZelLpLs + hux/D94MFKtYa6OseyzT3qIDdixav+mlI2ud + 0JyflYZ6MCBlxg== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144646 56106 example.com. + XdhVQ3Na3LsvdtT2HwdsM3ItiD3UH0HO6TZD + W6/jy8r0NA6fTN4b4oVr6wSqHAQIQVYUbWER + 7pav2Ek03LDa0Q== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144646 56106 example.com. + dVTxTNAfZy5sa0SW8eme+KMx3hByBnPIrRlF + zGDsGN1Xzw3OBhsTmuOwhbnZSnnvdBrhBOJw + 8eU/6zpcZypyFQ== ) diff --git a/tests/knot/semantic_check_data/cdnskey.invalid b/tests/knot/semantic_check_data/cdnskey.invalid new file mode 100644 index 0000000..6937db5 --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.invalid @@ -0,0 +1,123 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144725 7800 example.com. + fIUb0+hjrELDVphcGgDZemNVpq1TBgyTt184 + 9YnzaAhADynsscEd5iZRjuA5r7mlI/M9fFtU + l6wpEmqAs7sG5w== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144725 7800 example.com. + 86HnJEU3jP+bL9JmnY+2TGwna7DGtUVvgdhu + slzGQWN3EHb51vx1fHQGGfQlJ4P4ch5US3TE + 1rd/OKNUBE+p7w== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144725 7800 example.com. + 33SrrSRr8KwasK7qfxYAPxP//dj8Y9i95oza + 2Fwvt23QxfZS3TBLqMyMA6G/nmXyavUxsye8 + C+mks7QsS7HJCA== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDS CDNSKEY + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144725 7800 example.com. + WRb17ehBEEjIVl//Zw8vtDmbnTY6eLWe2KQ2 + +E+pCMEK0QE1qXwcethJ9PkM+gKFmN9RscXH + DjrmWIAfgndjsA== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + VxRHPS89GaMJvJ1xL8/HulwW75tDXUZ6nYlI + 8VCFOMB7vU+SoZhaaoZu4YcCZqzjzfZLl8Lt + SEaXZPQbnpkhyA== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 7800 + 3600 DNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + MWndPmlRdffYHO8Z2quMkXq80Nm3PNmWpTix + xJLJ71Oph+ta4XaTuiza6AQgVkCSzrfwoTuJ + UKHL13s4/IrRGg== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 46605 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144725 46605 example.com. + GRVgc202uXoxu8f36V/Tc4r9BzCKK07SCmS6 + MCJ+mXO7PCv4RIzN9Dp8t6sVuDb5smLe6cV6 + 5lgyPYJwr1TVJA== ) + 3600 CDS 53851 8 2 ( + 668159D684EC387C948E6F4B0AC9AA01481C + CEBF7570AFEC582897E7725122D6 ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144725 7800 example.com. + r+OpHWsZ0enCPKtUIZFXSb/8YbLdfYb3Ihpt + n/5kAWbOkkkVzAJX2/sCrVExMCVcP/nFSIIf + hACGKBjTvuLFLA== ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144725 46605 example.com. + buNL2/GqYvtwcXMPSiOeaEB5L6r5InyVxzaJ + 1PaaJigmJHbdNKGFl8ijDiH7WBdQECb8M3oU + zeuWGebSLuy0AQ== ) + 3600 CDNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144725 7800 example.com. + wYB3zuX5/bt3Pg2nz9F0j6MK1bkY19QvDcRb + pk/0rHXLbSjTepbIwy8O0KbJndHy+a70fN5p + 3dBGN5J56KymFg== ) + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144725 46605 example.com. + pXWJCUC0kKqWpjZetDhGJLNPpXGqc8sJZ9wY + HKs4Sd734p+Gr45vnJ94pGYjjtZi9bwPo2nF + DmFP5K3NLACG+Q== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144725 7800 example.com. + Khv6ptUd4l4SgJI/H+L6Ls/gQHnmmQJcg0fB + xv7zECmQfQFguVIJ1bmoz4jP26ejsNH1pG+o + Wz9U7I5oWsDzYg== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144725 7800 example.com. + z8omQAty9S0cNyFATnM8DZ+RbMly/7staAmc + RF+PmOp/E7FtdKOZe5+ega/+aQV9VpePYXMA + UwmIeeYYU2pAJQ== ) diff --git a/tests/knot/semantic_check_data/cdnskey.invalid.param b/tests/knot/semantic_check_data/cdnskey.invalid.param new file mode 100644 index 0000000..2814ddd --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.invalid.param @@ -0,0 +1,123 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144756 33730 example.com. + tBomI7xR670RBUw9IjNL2A5eMVKtYqDUdhiq + XJI3CFdb4j6plfdUF75SfaiCP70aLX8Atzxm + 2RAzpR6M2Q3gbQ== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144756 33730 example.com. + 8mHEeq/7fnXpM/CaOFsIqTKyTrixQVZr8V+P + Lwn641YbbKniEP+KacrJ7Ul2jt2jCT2cnxC0 + b9XicHENmd0phA== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144756 33730 example.com. + f8ZdC3vD/oIltQLyL4zBmwo9rRyijN183BGw + L6iZ6DnH4BASlUyrGa0IceRH4yD5pP+gnhCc + lBzWFgvtEIyPPQ== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDS CDNSKEY + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144756 33730 example.com. + UK+oQx75Gdn82LKBzht8KxrtwPE5JCBhEMcR + hRhHTeMqRUjbbeEOSWRdjg/36329yNYrxC60 + l7bBcqolo9dDmw== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + kr0M2egbhUXhH0i6fYiSl+zRH1pU7XhamCdO + nPhMEgFa3CsGp61kCuZFulpY0ODh8WrAPZcO + qC0tCj5Bz7nWZQ== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 33730 + 3600 DNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + 7fs6TMYYlkkxI1PCunVT9dxcxWVGXu1N7xVv + 2EUyVYMXSn/Z04URNTaxXcoWuDafy99G8rcT + oPycl2oOhc+s0w== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 60664 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144756 60664 example.com. + WpjHrB8ZfAhOSjq79gAaPEiQgSxvEatTi8nC + AYYpGs4dc1n54iYZ4IjCfMW/etlkZsMzXbVE + s6t+Dj/gJ3JKZg== ) + 3600 CDS 53851 4 2 ( + 6F8129D687EC387C948E6F4B0AC9AA01481C + CEBF7570AFEC582897E7725122D6 ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144756 33730 example.com. + IAgBYDhTIYQvmF2vUy72TWoRlPJQGyGErJuT + 0xxZDStaSfoAVM3Hr6VEqIq7R3B+Xel/urDM + WYUbIAinEnvpOw== ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144756 60664 example.com. + IpzPg5fx+O1HUqjN0lR1Bbo6Zx/Lq1wrrJvv + Y518ooGelg8Q2wH7NgScsyhLY342+MHk0fKX + RcxRzfaFohiEZg== ) + 3600 CDNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144756 33730 example.com. + WMqSVG8Tcq7e5E2y8oHThr6Ip7ASu/35m10m + TzsEANrlFf0e1Z6XG5ca/6//NSolXoTu6jBx + 2kvnsX2bA222PA== ) + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144756 60664 example.com. + LLGAWxuAhlKM/3i9+FFGngy6Zqo6NsxdXScR + wgVe3Ilw+3vU/Nih70uRE/xUjZpfFBOlMEk6 + EBSf/DJr6awY/A== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144756 33730 example.com. + mpcGxsR9c/K6wuaJCeFds1kg0af6Xj8K24o6 + FHzqn60w7HXXNnDjxS0jPTHpaVUkWhuKUcCR + 9EcvMW7uwVfULQ== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144756 33730 example.com. + gLwhcu1t0qloiWb5/XHuv0PAQZ+ChmDdMuMS + qS3hi0VPk9cscMjd7ZH7shJBH+9KKMI6YbMz + VGU4MSCj5/kT0A== ) diff --git a/tests/knot/semantic_check_data/cdnskey.nocdnskey b/tests/knot/semantic_check_data/cdnskey.nocdnskey new file mode 100644 index 0000000..a7bac63 --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.nocdnskey @@ -0,0 +1,101 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144854 39620 example.com. + 0JDLQ/bZj4SSmqvLPAzt1v/UUb8mfJQnuLC9 + B1CL4oRD45Hw00KgmbE7xgJVflYZJxfx7KIw + ydsB0/1/dMJzbA== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144854 39620 example.com. + Mnk/oSM7sdAhGYbWUMLpYFR1ahcvULo/8z42 + giRwzAX8HiqvxxkqRCFbvzYeRkZLLw0fYTeR + Mqit0zQuWuc0ow== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144854 39620 example.com. + qPQblbJyzHdmhqYhYx4wfUHWe3SYGUA65hZR + UFYcx99Vhs1CXUobjCk9NBedRbBHR04kQ5Bo + /72fhuCPJFIC1Q== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDS + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144854 39620 example.com. + H5So5m0YdxOBU3k0+pi6KOgPNF2V4hU+GLxa + c0JdGnALP4Wz6lWCdMRPXIaMjImb3TK9vFti + 89lB/2MMDe4dTw== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + 6R8b9KzH06NQ/4AUqrmp8rFmY0AmHpbW/vhj + xLul6ON720xvdeKBzi0nLSeTdUO8/gK8s8jh + RmJ8Fw279eXXZQ== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 39620 + 3600 DNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + hfwsa6JnfqjMRma2PlO+gt8qqLytVIygLZHB + 5APAuz2cheZCMD8A2kyt5NziCCj6szmCK4oZ + fColPGaDgYtpmA== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 6821 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144854 6821 example.com. + UbEQQoX5j1FVOqpkQBqckaG4WnCd7+4dBJax + 5sgjHQnfSSwKGfJx0zxd3ZbPCEKj+Ymrhpsm + nqfPzVRZhUPKuQ== ) + 3600 CDS 53851 8 2 ( + 6F8129D687EC387C948E6F4B0AC9AA01481C + CEBF7570AFEC582897E7725122D6 ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144854 6821 example.com. + Sc/K9xI1C9rzujnllO5o7sKoJiEKFUEfPxt8 + gsxs3sb9Q1s0/uSocrPc2OcaLgEzuFGS5FzA + fg7HcgZN63I5TA== ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144854 39620 example.com. + ykGu61Yjp24MJjp0wIYV20LSQ9ovRHT0zqp2 + CSvlROIVpbUGlNjAAKJdWwYJAqNUD571gJ7E + TkhrLEIX02ySqw== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144854 39620 example.com. + ye5pM/p8OWbdRNhLfbfWsY6lG8lr0Ae80LKv + rVOCMhAowrtKmDL6hUByovCV7MjCIYwGM26C + Vl9CRmrWwJEULw== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144854 39620 example.com. + JHP3TuxCuZ+N0lWtRI7Xl0qIcHSrn/X+WDUr + 0cVBfQTsFrAZs14bJhvw0zMGgONAgnFsXlxg + QmAqIPmpRvKtnA== ) diff --git a/tests/knot/semantic_check_data/cdnskey.nocds b/tests/knot/semantic_check_data/cdnskey.nocds new file mode 100644 index 0000000..ecb3188 --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.nocds @@ -0,0 +1,110 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144849 42608 example.com. + GDfM/H4m+FRVp3M/KsOv//eMFaL1LnyrIi8O + pUSht1KyYDRoVqSL72XTy1aAJJ49Sd0uq+4U + acekI3Xi9OpvXg== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144849 42608 example.com. + ICtOUMZr415dJb22HWsrjbYfW7q6hh6gxD2i + EikMQAkPncdBHHd7dCrjy1/4CPhixn/BnDfV + ZwF87k2Sa7EV8w== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144849 42608 example.com. + IokJy9LCiCaOPsluuBKYnwkesiPwsU/KZdA9 + jK25UmdfD1uU8AA63OOciTZQSv9NI+Q4nzl3 + LyqkRWFKToMz9A== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDNSKEY + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144849 42608 example.com. + kuhtgHhoeIwJ8IG08x+Tp5M7kQ+LzWoH/hTs + V17ZSyPD06YvMEmv9vdB+ATLd+j3uNYnMd4n + HW7Jh/ocOWg6+Q== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + p9BANIrBFV9hX2qwbzydeiubQkm9qstpzvUe + OFMDOEyyQxI+8s2nfHI76KmRliHuM7fOM9B5 + e8wNmEeVd9JJmQ== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 42608 + 3600 DNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + 5sv4MetMS4KWSgyzvn658Prs0A8tLaWFhRJD + E9IznhGY2ogp8Z/uSIqh8QWzf1kQvfDUQiav + kOx4CNa3dSx/ZA== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 8616 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144849 8616 example.com. + DeZBLj99QbyGhalCZ4UOmBJO/RLNgrPsAdaW + swYSg18lvE7jmLn9vxkUVZu0G6z43tulSb+a + lQT8m+U+PlusNA== ) + 3600 CDNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144849 8616 example.com. + IlysaALuak04Zbh0+104PHAuQgnYDBTLpvz+ + BgirzX9Vp+pg4yZVelAXsaDbcj2ZrXrwBjpo + +DHj53HmZygj4g== ) + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144849 42608 example.com. + dJhB1Xmd3G1ueRVnFU+M4yc379LH0UrpBcNS + xHzjVd+vWtpNGPq03Wi3sczA9UUkXE0F5n22 + 6ZNR5XAswf+SYw== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144849 42608 example.com. + 3DTwpPojzX4r9ZWeKo+zmJw+2L/uqrtoAZEv + ncPJG0AGB9QVzjLFiRg0BV4GiDZCl2Hh4onl + OShOi5Nt0GXp5Q== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144849 42608 example.com. + 1m2PpD3S6/5x3Kkes+1JgbHtsm0xlnKrNCmF + xeBvCl55D98zSvs0DjfRjFowAg22nWJkvsWo + 3N1vnfFZpzmPPA== ) diff --git a/tests/knot/semantic_check_data/cdnskey.nodnskey b/tests/knot/semantic_check_data/cdnskey.nodnskey new file mode 100644 index 0000000..461e05a --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.nodnskey @@ -0,0 +1,111 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144347 19649 example.com. + Tng1e4Zs8LvGZJqp75aBSX9Ci9bsncY+w8+K + rfYdoVe/Smq0I+Hgtygcq0Twc7llW0rwtZ8R + jQpbXbp+XNDi3g== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144347 19649 example.com. + OcKfgxtnriGsC/9wV9yI71wIVzR+71j3sZ3+ + ZGVqAo2bWR8QRULa5g5lQpIxlayN7w6xi6vV + IVWY3vauy59pPQ== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144347 19649 example.com. + CtZFcGvbco6ZreotcmfSYl8SlRdN/JiSuoOG + KtdauRz9+a+xkT2k1Wy6dADfLpwHwXL8yElg + /LdNXKEWK96HcQ== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDS CDNSKEY + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144347 19649 example.com. + 6GVUlXemDUb6W9IID4qK+PPDSizeURGJEJlN + Hoof218/H/k8/BLNphFIGpdhCC2jHnAx2Nxd + Af65dTLtt7OBjQ== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + LiJCYpav6haPA3M3GhTZ/L6wtSqS7e9mwKsU + TdBkZ71RS8qmXsITLz5bFHMSy7K8mCuQIdTT + J3cGkbguNBqgJg== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 19649 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + j18Cd+0frtc1WPeWn8bwdxYd9iTe7XsqTwnO + W46ZpPJPGBq/n31+7/N9TRAtXulE2r+rJDRF + mMooK5qrWOtqvw== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 24385 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144347 24385 example.com. + 8O0L6xxTnGMccrMSjaG2/MtljkSOls/BIwoX + eUmB9nJvDQNd8jg9XtNYUGG79dmysetBrNQl + TohQ1BEVGTJwig== ) + 3600 CDS 53851 8 2 ( + 6F8129D687EC387C948E6F4B0AC9AA01481C + CEBF7570AFEC582897E7725122D6 ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144347 19649 example.com. + CLjvJJOAZVToWUQQX06ySDkKo4QO4YcN2vhl + JZZ2a1hA2ranrzpeE8cslGKme5lxHKr8Y1ev + ffWfrz8KoQVW+A== ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144347 24385 example.com. + TaPgzUzL+fPwEUNyusjCb6OZOF3DtlMNh3eY + ZTvogl2eRq84NA+mfzPmh0NXqVDbsVHGHq1B + mJoxuMtIt4G5Rg== ) + 3600 CDNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144347 19649 example.com. + 5sY/Q/1tP9qPMAHyQVMtbFQ0gO24rofCLg/D + /BaXTvjp5bnWhGuv1wFbSCyEreYr072Va08t + JdntIC8Prt/1MQ== ) + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144347 24385 example.com. + UlLhm8Nb6g0jUIs1ldjW4OedzzLXDjCllRSm + +6WQuBK1uA7vboyqYVvLxxyFZCxgz6xV02iK + eawtsKsOnlfGCg== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144347 19649 example.com. + ZRDwnV+YyfKPI58ASagzoCo+qWTscYZZa6j+ + wr4axJ7jtIO6Firy4R1GlO6NXmN5vcjHAj90 + NZ26ezRgCMCFQQ== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144347 19649 example.com. + c5ILb+AR9BIinFp6mCogN+jwR8067Fm9LT9Y + AWaR3pqUC4d+Qdo4pkODLkmhAaSQLJCyPyYB + TQ7OFkQCC49MtA== ) diff --git a/tests/knot/semantic_check_data/cdnskey.orphan.cdnskey b/tests/knot/semantic_check_data/cdnskey.orphan.cdnskey new file mode 100644 index 0000000..70241ab --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.orphan.cdnskey @@ -0,0 +1,135 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144945 39996 example.com. + pdj652v0OfPO/McP8sNpxoE+adY+Qim5je8m + TQPcudU3gm7I2L+YqU/ujX1NUOyhUAhzRng7 + m6nfrudJebq15g== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144945 39996 example.com. + 7/X57I7FmbSlgxxeaE3Xgoot7KxN6nxtDb0E + mEEZNwdLCpjgaftaXXXM3NaZ1W2sdoECCrlz + R4/75kqrmNpYPw== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144945 39996 example.com. + 0tcHIXXPEKy1tpc+Of6s2hTdQ5dGh1IoIoxY + se9paUUfhoF2oH5Pb8HP3rNyWLiTqXh4/lxV + vFLi4rR5zojxLA== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDS CDNSKEY + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144945 39996 example.com. + kbImDj5vgk5VG9MI+4HJ4FtwnJ4ykSbk8vNY + e49ibkZChGsTtIzLwdcNAmOk7w/em67FkGBi + oxqCj6b3G0C45w== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + R4pG7HF8CbXgbo4N6UqdSnE8CaClNUw6v/di + aScNknRS0eLPOKmpANe0tyiwBV1bRQyjpmxq + fgZ9Oxac7plIJw== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 39996 + 3600 DNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + cJdrUmmcxe9JKHwHHAkJ8mO1J63Cm6Qoln56 + CUya+eWuF1A3u9L3wumvY2rAXvzBpplLXeUN + GIN0GgLHejH6QQ== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 56026 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144945 56026 example.com. + srEjUMAQ4Z/yc22bas+P0ly30IVbZaIIlli9 + H7avBz013fn90vDRDLiLuHAMvW++xdDJypcg + Sr+9I9+nv6jzRA== ) + 3600 CDS 53851 8 2 ( + 6F8129D687EC387C948E6F4B0AC9AA01481C + CEBF7570AFEC582897E7725122D6 ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144945 39996 example.com. + inhdpEZ+2W4EM1HSiVZdJa4xT5S319D0x3b5 + eJpskw/EV/Rx1X87FCr8FP18iBOszsWJjQQq + Z66eAxIhpBcb7A== ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144945 56026 example.com. + TA7UxWd+j6bOXKPxo3XuKlIy87/HvIPGoELS + WQyrON5IURgGw/2YWD0M5xw852jl27USezzo + pai940D3+VGeOQ== ) + 3600 CDNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 CDNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144945 39996 example.com. + CSk6oHNIsj3XQgXpPtFOhf4dTv/Wu/vnJfJs + Lpc3IoApBMxrpSIzfM/c72JtjSVzjJcdo6kL + n71WM21CsMcQ4A== ) + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144945 56026 example.com. + hsml4IaJtzvMdvaMTR3MzeCT5fMHJ46rCY0y + 8DTAvK7/Z6LHbF4G7yRh9ozwcyZbB006cMdc + 4XUFDtEPK62DGw== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144945 39996 example.com. + 1cNj6TJEHFxLXFYVt3RU3wC8Wz/F5bfjy8/W + jEJdrnVzo1ihmJWoY48e9MlvsGXnGe4+GUrl + HSS+2bsGOS7DyA== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144945 39996 example.com. + 5mtXYcvidkSnG12dZof3xSEaH2eOsV2fuBvb + 8Eb6XEuPfD9v5g2mweyZYrBtowEsTA9IOsly + 6AWT5PfZbNAe+Q== ) diff --git a/tests/knot/semantic_check_data/cdnskey.orphan.cds b/tests/knot/semantic_check_data/cdnskey.orphan.cds new file mode 100644 index 0000000..54732de --- /dev/null +++ b/tests/knot/semantic_check_data/cdnskey.orphan.cds @@ -0,0 +1,138 @@ +example.com. 3600 IN SOA dns2.example.com. hostmaster.example.com. ( + 2010135808 ; serial + 10800 ; refresh (3 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 7200 ; minimum (2 hours) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201012144942 8996 example.com. + ThTlvNtautK64IeJRxNCr5acLrRu8jXkTR3N + y5TlXrei2DIagbPja++4vLjhUJAcKTGndD+x + wgMrDpCY6pMAYQ== ) + 3600 NS dns2.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201012144942 8996 example.com. + 3OJiG3v9Nq9OHkyysT3A6PNPRVn9sYTQkHNS + 6JL5BzLCQ+uYKJBCu0ZPxDlYpbYnO0HKQ7Ta + iZYCjm7vzqtvwA== ) + 3600 MX 10 mail.example.com. + 3600 RRSIG MX 13 2 3600 ( + 20601231235959 20201012144942 8996 example.com. + 9vi3n2cVyr+ghB0ql4Wc8vhpLfAuclopapXw + BQV328nEwftj0okcPz4Z7Iye9by4X6NDd13x + vzWXDKjZCSxLJg== ) + 7200 NSEC dns2.example.com. NS SOA MX RRSIG NSEC DNSKEY CDS CDNSKEY + 7200 RRSIG NSEC 13 2 7200 ( + 20601231235959 20201012144942 8996 example.com. + HP8iIlUO+EKFRgoHUrQWLcaX8oSGEb/tldEP + GcJKM+rGMeJvxXOJnjSskUm7AyRK1TKK4RqE + xaOHTgIz1uUkzw== ) + 3600 DNSKEY 256 3 8 ( + AwEAAdKraxDdGTL4HDOkXTDI1Md1UdHuYhVw + YkB+u2umVjTJ1H9Qb2oBryqwXI+gklnuCqrH + 1znkDvzGEAeHRQUCbtKbjmqErTAcRRHW3D+6 + jsOGXzbyGCfbyzRBwsbNCLWr3ONpPi5JOWEe + CUJfyc/mRXcmh5uYl1JvzAM1zprtljZt + ) ; ZSK; alg = RSASHA256 ; key id = 48849 + 3600 DNSKEY 256 3 13 ( + bkP3kBcYNsUB6jpKA764AJeNBzGJjNIRPxDl + 2wK1O7I/bvZDILscWSMUsSRmxZuPWGLjevpp + Tve1UMe+dP9VIA== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 8996 + 3600 DNSKEY 257 3 8 ( + AwEAAaulfU2biYVBiUsGwAyCXbA+gm0yWgH2 + Z71S16R2YNERlb0he9Od28DcFd0HbaKdFnw/ + CtX7Z2UWs6/IRu8QmHGn6SKDsLzZ5StdPsJD + KilfvSlEcQeqrRAncug1SnA5BogNQSD0/02Y + w5KDGn7ALCSYlNgOgy7l+D/urlkuxgsPWvqY + XnlxaIcKt96fndwmkfZ5eF+WAqxguaNcvm14 + 6NA53wRrWx8BQbcHk1R+WcQGqFcVOlifCs9z + V+87QJy2H660QKqOVDgt8PF8QmRRJqzOKpu2 + 9T+Vd1dM3zjBJ7deLaNH2E5p7Bbp1eeOCeOt + WpCG6XfaRmZIF3ZWVM6Ways= + ) ; KSK; alg = RSASHA256 ; key id = 56474 + 3600 DNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 DNSKEY 257 3 8 ( + AwEAAetE6qfN/GbtMmvM0PXUTyskauES2FKf + jqLVz7EQlfS8iAFWLi1eHjHXDkueZ1OYRzQ4 + IBy6MIsce4XVXLQoS8njtfaU7c5NZvktH5la + 7JuH32KYr3PdWL5KDsUdED3GSxfNV+DbcYU8 + 0AZxTxy6Bm6EP+DztL1dpYrmqr8JRl+qlSbm + LIrPemZFUEQzhiepcYMWviDUz+ixSVzjEzpM + CLsrNxA30Ziiq9GKA8KKlFHdAmxuNcH0TzRn + dpo6bu5nKyJHiREIazHVuPBEzUmHtcWETCDs + 9UVsbji2Z2ozqLz9cqnfYV/kOD+OZBAqvZ0n + /4lgdSiBtvByLCXoWEYIGRs= + ) ; KSK; alg = RSASHA256 ; key id = 19420 + 3600 DNSKEY 257 3 13 ( + 1OgEqruDg7pI2dTIRMdP9ihhdl3wFngZW9bP + E4jMg4ByKKoKM/C1QN4Q+BQiQDkcprwE9vLf + D/cLgFNspjcBgQ== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 63865 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201012144942 63865 example.com. + 9d2q8pWH1AftoDmPq3DNblta3oPV+6ROZmVR + BvjHj7xJjI27aY514C0qNkQVhioe2mhQjikO + gyxvkWwBV/owPg== ) + 3600 CDS 53851 8 2 ( + 6F8129D687EC387C948E6F4B0AC9AA01481C + CEBF7570AFEC582897E7725122D6 ) + 3600 CDS 56474 8 2 ( + 260E7ADB07D1ECC40DEE79EFF6527CF7119C + 0AFC1CFA5DAC1ADFE342568CF32D ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144942 8996 example.com. + E7iVsJZjRyGbjMUADsi9Chz74+t1W75zTPmm + MYVD77dkRHiEpN41MJB6Z7Fn1lNOE6f8q2B5 + iL/3UXULB1vpwA== ) + 3600 RRSIG CDS 13 2 3600 ( + 20601231235959 20201012144942 63865 example.com. + fsMqYcBDcTBtaDEqDTYrHHivnuQKb629drhm + 77RFfBxFJAxlq176PzaddA++zHfWsBgIlJzy + VHFy3S3huuyfaQ== ) + 3600 CDNSKEY 257 3 8 ( + AwEAAcQ1EqTPebcJyUnpxO3Xjx6ehRtsiZYT + oARoJsJG12XR6Ci9yy4SCCsejtaWIFO4XVfM + 2BHzFWqmABtQHtN7AazXAFMLsrSE4DYbgk5W + mnQv5Jloi6jhhmmXwr8EOi3HR2jdG0gVq/Ta + x7ztNNZsflJrs3rZs2TVO00BkyyOkmO35jCN + bGPUwm5cW1vse137BMa7jAcMyNLPIiQubj1/ + mJcIyzF2duvfpjBTgEmSvNcXqLfYFjK8lG4N + odQG8AcK0MvWqN4mxW/hK0U9nMSjhCnfzPg5 + tjyqdheWRyhkLGjM/mR7gBhtqoSPMr+2KMJQ + EHYAd/AP8YgaovS8N1fJyh0= + ) ; KSK; alg = RSASHA256 ; key id = 53851 + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144942 8996 example.com. + hhpJcQ4cMcq9fLNtZrTEVAMGB2bjMwcDvv4C + Sss9wWDBNxIVOsi4x3j/08PZTqbfmYePWtK8 + k2R5GOOK1lpVlw== ) + 3600 RRSIG CDNSKEY 13 2 3600 ( + 20601231235959 20201012144942 63865 example.com. + xU82j/dJf8oBd1Ti2lHH0YoxBvgCQo2MOdwJ + yOc6fDrT/c39rCMT//VoDmmKj3SavQ92ABBt + 18JqxCXK7+tnYQ== ) +dns2.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201012144942 8996 example.com. + D3O6XOYrOT1tlCieJJvw7zys0ClqXcCvs5+D + qSEpKcE6RNNeJG2d3SJg95fbO+eTkw30MROF + ajnNh5xJ+8xsMQ== ) + 7200 NSEC example.com. A RRSIG NSEC + 7200 RRSIG NSEC 13 3 7200 ( + 20601231235959 20201012144942 8996 example.com. + sGBFze6wRGj8n0B8izUNHO2ufA72sR55U3OQ + RLYTx2XqBRvdmapMKK6QDu/6lmwqgYMbjiBJ + XqDLv/1RP4DisQ== ) diff --git a/tests/knot/semantic_check_data/cname_extra_01.zone b/tests/knot/semantic_check_data/cname_extra_01.zone new file mode 100644 index 0000000..ae3f27a --- /dev/null +++ b/tests/knot/semantic_check_data/cname_extra_01.zone @@ -0,0 +1,18 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111218 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + MX 10 mail + +dns1 A 192.0.2.1 + +; error CNAME, node contains other records +email CNAME mail + A 192.0.2.2 diff --git a/tests/knot/semantic_check_data/cname_extra_02.signed b/tests/knot/semantic_check_data/cname_extra_02.signed new file mode 100644 index 0000000..724a8da --- /dev/null +++ b/tests/knot/semantic_check_data/cname_extra_02.signed @@ -0,0 +1,76 @@ +email.example.com. 3600 IN CNAME mail.example.com. + 3600 RRSIG CNAME 7 3 3600 ( + 20840201000000 20160224073150 29600 example.com. + IxkF8oqOEzhlZDSRBIi4448EGvQwxm0QDFE3 + JExA4Byx2QaJvXo8LoCeyQxS/f9E6bXpXQk2 + 4dgQxUrRZqnKEA== ) + 86400 NSEC example.com. CNAME RRSIG NSEC A + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224073150 29600 example.com. + iKA+5qsYA7A7JN7Df99aJnToYESjqordQgVj + yMS/1RVBYEGE4y3ggehzAxvc8bsNYnUwGeGt + vse5dMVKCcIaPA== ) +; CNAME extra record A +email.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224073150 29600 example.com. + DummySignatureDEADBEEFToYESjqordQgVj + yMS/1RVBYEGE4y3ggehzAxvc8bsNYnUwGeGt + vse5dMVKCcIaPA== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224073150 29600 example.com. + MT+QgXcsDzkrFgncNwFyH8lwXiOTpj1rnPgs + OUIOfIhyJyzT1hpozAHt+IWOPHUkKjBN1C5y + SwyTnlqwJtG0yw== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224073150 29600 example.com. + Mr0Gu7PUu9PsUBflhd8tMhcQ9+ve+z561/ml + kP6PL0MHgLg7V8KVmL2tc7+JAhSOVSpJ4BGQ + c9HKD15lFDFEgw== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224073150 29600 example.com. + oEMpoEhi86OM/SdyobPEh90zF3c3FhOgv68j + paD5BLUsAntf3qU+KoIMb9iVglp+VTGrg0Ol + XdJ2D/xSMA+XHA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224073150 29600 example.com. + WOtx+LBKbS2MOahlpDJMqgeH1TI5dZoQitmA + SOkDRlJgfPsiKeiaGMrnWN9xnPZOVr9MsInE + sKYjh6EZM1nuBQ== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224073150 31323 example.com. + nL4eJLv62C56wexu10DMPHqXCXSE/3vRe4es + 4e0e1CkY9bdj+LgLfgs7CH7UDNXFX2CxKxHd + mL4sp5AtaA8fnQ== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224073150 29600 example.com. + nn2dG+ORbcNQWHT87ijfOddx0SKCSE+8hAxt + SiQQpxAzPw13CZmnbYas8uvFFtth6U689V3h + rMzzZcxQEA1z8w== ) + 86400 NSEC email.example.com. A RRSIG NSEC + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224073150 29600 example.com. + BFz1Z7dbBNgHXDOaufuCoIzGHbwyLUrA+Wad + QBPD9xCYkXHoHfvVOhtEeMR19Rz+fi6ottJI + 4AWItiobBC/DAQ== ) diff --git a/tests/knot/semantic_check_data/cname_multiple.zone b/tests/knot/semantic_check_data/cname_multiple.zone new file mode 100644 index 0000000..971c34f --- /dev/null +++ b/tests/knot/semantic_check_data/cname_multiple.zone @@ -0,0 +1,15 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111214 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + NS dns1 + +dns1 A 192.0.2.1 + +email CNAME mail +email CNAME mail2 diff --git a/tests/knot/semantic_check_data/delegation.signed b/tests/knot/semantic_check_data/delegation.signed new file mode 100644 index 0000000..2007216 --- /dev/null +++ b/tests/knot/semantic_check_data/delegation.signed @@ -0,0 +1,43 @@ +; Delegation NS and glue signed despite mustn't. + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 NS dns1.example.com. + 0 NSEC3PARAM 1 0 10 - + +example.com. 3600 DNSKEY 257 3 13 Yk8KOmyVzOij3x+Zs+eT4J2Up9+ipwXEKOhL9fTYY/DU10yIQt+zYm02UFZJX2oVTdHBCajpBFsZLH2X4ho1yw== +example.com. 3600 DNSKEY 256 3 13 tCoteOM+A4o/A9uxgLyDg3HOg2DClU+3d+1XPQRtTfuaEFOGIpyH6qiFUv2b4DYuvmMyTkL99nxvyhA8yo0Cgg== +example.com. 3600 RRSIG DNSKEY 13 2 3600 20400406103150 20210205090150 25674 example.com. 4tMK6g2B0ITXf2haSSuH45nO53GlpZQ97ofC5Pd/S38oeNzWmhfxIBaGtb597qxRA2NC7rYtGsscLrCa0sthMA== +example.com. 3600 RRSIG NS 13 2 3600 20400406102301 20210205085301 61806 example.com. TrCJZgu1hVoUK532mmhQpZcEcPdw4FezPCymtUuQH9XjZNBn3DP/OhM8NvAbtailiOIX/djosTC2cNDlqSoVCQ== +example.com. 3600 RRSIG SOA 13 2 3600 20400406102301 20210205085301 61806 example.com. h/+XG/WWQsoAuzOM2wiulY8TOslYTj4MyP7Rjj3VXx8frlheIN84yH7NL6Xgt3ibQJpJl7rujkDuoTBH+snnCw== +example.com. 0 RRSIG NSEC3PARAM 13 2 0 20400406102301 20210205085301 61806 example.com. TYk9hqD6hWA8YH/G3VeggrUHb7CwX3ut5GGiAOcl9o8I0gdMIOu8E1uUukexvJsZAt1Fbcjc7ZIbsUmvgs2MVg== +deleg.example.com. 3600 RRSIG NS 13 3 3600 20400406102301 20210205085301 61806 example.com. /Xg/3viyTMyd88hcByGifSMHGo3up83exBQQt4FC6qexZffRyNiLrHOfnoz/2LqFMg/oDVCsvqaEomiMM6FlZw== +dns1.example.com. 3600 RRSIG A 13 3 3600 20400406102301 20210205085301 61806 example.com. zc6VOVGfgoB9C8/0WPHOVrdikBzK6xh25UtrdIYuSzcPWbFlWSsV3+xS1q20MBDb2dj635jcyBWRep+287rDLA== +deleg.example.com. 3600 RRSIG A 13 3 3600 20400406103429 20210205090429 61806 example.com. 8hcIsHOARI1XXMcPXwtlmQC071+FBH+I0a6CufDbE7nPa38brBKomqTjiYF26K1KZ4IQASw5vvF0lFg3eEOZog== + +deleg.example.com. 3600 NS deleg.example.com. +deleg.example.com. 3600 A 192.0.2.1 +dns1.example.com. 3600 A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201008173641 61552 example.com. + URGzLYXySdeOtXWW5ph64pNedd7/cq0WYcbd + nArHBIN2S08knOfV/OHOMDaR7WufUbIF8bPQ + FxDkURlAhZbH9A== ) +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 3600 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 + A RRSIG ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 3600 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + NS RRSIG ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 3600 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +20g1gol477ro51rk9a9nfd54tfqal7iq.example.com. 3600 RRSIG NSEC3 13 3 3600 20400406102301 20210205085301 61806 example.com. LUBULY9667EsrOHecNjp2QkW9JJW1fOSyTmleWul7vGFwuNC1mKVUQu3H3V5ndtwzU1YD69oa6eI2DOERmiJXg== +mjv836rjqej5ubghvksq7n44rso3q938.example.com. 3600 RRSIG NSEC3 13 3 3600 20400406105733 20210205092733 61806 example.com. zYuSttG565eDv3FPeKfZs4FNuJHD204/8nv8cNx+9iqbxMdh5s1XJx4nolWyiOJcBq+G8CmtiuJK6plUs7x67w== +utqvuhu2blk3dhmrr5t1hd9vteohqt0a.example.com. 3600 RRSIG NSEC3 13 3 3600 20400406102301 20210205085301 61806 example.com. aMivM0YOs4Il/WRWqf3SRzh21nZXau7VIJOpX2NK46qxBCW41N/+J7rXaeAT15ayWNjCHP1YoDwyuC/lVZtCqg== diff --git a/tests/knot/semantic_check_data/different_signer_name.signed b/tests/knot/semantic_check_data/different_signer_name.signed new file mode 100644 index 0000000..ff92f7b --- /dev/null +++ b/tests/knot/semantic_check_data/different_signer_name.signed @@ -0,0 +1,52 @@ +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201008164859 49259 example.com. + UH4IJhLwxWI9g2vycAuGAHm5XzsW5LKr6xeI + aoaiMeb1pepw9vAWEUO1Byimg7FfhvYpt7+J + IhYCvpBb6u3ucA== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201008164859 49259 example.com. + ou6B0AgSUxs7//b+c+Gm3XjC83TpgGvRwj9d + F48TEZCMRpdvtVNc1hDnNKa8oXA16TafbkqN + Z0ekrEo2LlN+hw== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 13 2 86400 ( + 20601231235959 20201008164859 49259 example.com. + uCzqU8DU8ZMt3t/h0jwZjdVgSj33HhwtGwhE + ZglZ0gUVDVLndP5Q+psqlz2jBmiXIN16s/+b + di0crJ9LULq0NA== ) + 3600 DNSKEY 256 3 13 ( + qWpA6ejmc17FHZTN/YoYX4WdNN32LC2IlBmm + n2Yoi16OQ1e2ztEusvQaSwzEMbN2pIzfTIlF + YQQ1gzLQAhWIpg== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 49259 + 3600 DNSKEY 257 3 13 ( + rHQi5BOkLnSsZh1v9saRZ38MkzYLL0oGbAK2 + Dp86tH3lpDqPoR7LM98gyBLZgp81m0YHAYnf + 2yK617XStIPw+A== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 3753 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201008164859 3753 example.com. + 81C/yn0gxkwOMUWNZPszGow4UyDuDn1V4WQJ + NXJfNiTvT6edQ0rQakhJPGgVyH4LIwWJV8Uk + fOubCv7BBgu0wg== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201008164859 49259 example.com. + x6z2ftS2deCBR9HJeIazQNrDdzw0lEE04UYp + npUe2zkIx6aH7MvvgZIjcFTwPOVsI00u7gaU + AzuxODSma50TXQ== ) + 86400 NSEC example.com. A RRSIG NSEC +; different signer name in RRSIG + 86400 RRSIG NSEC 13 3 86400 ( + 20601231235959 20201008164859 49259 different.com. + K/URrUmli54Noy0E3REXBo/g0LZ/8gneyVfa + FrGXLB0kvQydPyceL+BFIoJP6d/Gs/0qkUjT + vMQfvF0x3bFS3w== ) diff --git a/tests/knot/semantic_check_data/dname_apex_nsec3.signed b/tests/knot/semantic_check_data/dname_apex_nsec3.signed new file mode 100644 index 0000000..b083ce9 --- /dev/null +++ b/tests/knot/semantic_check_data/dname_apex_nsec3.signed @@ -0,0 +1,25 @@ +; Zone without any semantic error + +;; Zone dump (Knot DNS 2.6.0) +example.com. 3600 SOA dns1.com. hostmaster.com. 2010111217 21600 3600 604800 86400 +example.com. 3600 NS dns1.com. +example.com. 3600 DNAME bar.example.com. +example.com. 0 CDNSKEY 257 3 13 Yk8KOmyVzOij3x+Zs+eT4J2Up9+ipwXEKOhL9fTYY/DU10yIQt+zYm02UFZJX2oVTdHBCajpBFsZLH2X4ho1yw== +example.com. 0 CDS 25674 13 2 2EC05563A3537BD32EA3EB92C44794C644F249EE440785CF28207B903E35322D +example.com. 3600 DNSKEY 256 3 13 tCoteOM+A4o/A9uxgLyDg3HOg2DClU+3d+1XPQRtTfuaEFOGIpyH6qiFUv2b4DYuvmMyTkL99nxvyhA8yo0Cgg== +example.com. 3600 DNSKEY 257 3 13 Yk8KOmyVzOij3x+Zs+eT4J2Up9+ipwXEKOhL9fTYY/DU10yIQt+zYm02UFZJX2oVTdHBCajpBFsZLH2X4ho1yw== +example.com. 0 NSEC3PARAM 1 0 10 151E9F1094FE188F +;; DNSSEC signatures +example.com. 3600 RRSIG NS 13 2 3600 20400406111136 20210205094136 61806 example.com. WIlxYlV/hn9mfojITrVbIV+Giy9b5pAKofkw62Yli+jIspQ3dC/WWLrM5Y4HcQwTfNp7yuhIS0jPzkuy0xuAxg== +example.com. 3600 RRSIG SOA 13 2 3600 20400406111136 20210205094136 61806 example.com. z71ipK0zBRKKokzXdoZdtkxGC75MJbwmICNjSfd+IX/hneIGvFE7mTose1Zbb0WGgKRdUMEoii7hLZLrx7waqg== +example.com. 3600 RRSIG DNAME 13 2 3600 20400406111136 20210205094136 61806 example.com. 5tIYeBwbwpVF0X5ZLoSpHeB8IYLU5/2fFYXqvctZYqTO24T0EBfu+++j66VSERAI38xf2Z0KkYcwx1XeIeivBQ== +example.com. 3600 RRSIG DNSKEY 13 2 3600 20400406111136 20210205094136 25674 example.com. X3n5YVkjpSpK+IOCkhv/wFmF5WIPHUR2LXkNME84i5S4efvQiRRq/jgqos2f7OgfSi/9Q2Q2x6BiMQ1vx/R+Pw== +example.com. 0 RRSIG NSEC3PARAM 13 2 0 20400406111136 20210205094136 61806 example.com. gogp8pZycFopDodl4IOfpaKCbLqXw2v+5DcV2YwmHr/pMwrc28bClQxw4HVGcYQ13HpC9kKmzmcrn3dEumTb3A== +example.com. 0 RRSIG CDS 13 2 0 20400406111136 20210205094136 25674 example.com. zRQEFycg2sNVVB4TOZO8QcMwRwSA7tHJqkc1l9V+WtEdJY8UvYpYPPgAn9FjWMzzhvRMlws89TBSsQzqCemHiQ== +example.com. 0 RRSIG CDNSKEY 13 2 0 20400406111136 20210205094136 25674 example.com. hLOpPxmKXU//dmQoE5OdCqzWkkJsuBHa8QITWB/A3Tc2CXQTaqFKqTspZvTLOAYKNaSVu6BOLWM7Fi2Bq3I0mQ== +;; DNSSEC NSEC3 chain +ple28jlp3q5anh045ssk9f3u7ltd4qlc.example.com. 3600 NSEC3 1 1 10 151E9F1094FE188F ple28jlp3q5anh045ssk9f3u7ltd4qlc NS SOA DNAME RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY +;; DNSSEC NSEC3 signatures +ple28jlp3q5anh045ssk9f3u7ltd4qlc.example.com. 3600 RRSIG NSEC3 13 3 3600 20400406111136 20210205094136 61806 example.com. C3JeKvcKdQO3zTJqg5Z114jTd36tgF7PIL2kCs7X6VnCaVe7E5NtwUuLMLFIw/gUqaLDbE7vQwHMK3Psl536aA== +;; Written 17 records +;; Time 2017-10-06 15:58:57 CEST diff --git a/tests/knot/semantic_check_data/dname_children.zone b/tests/knot/semantic_check_data/dname_children.zone new file mode 100644 index 0000000..5758833 --- /dev/null +++ b/tests/knot/semantic_check_data/dname_children.zone @@ -0,0 +1,16 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111214 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + NS dns1 + +dns1 A 192.0.2.1 + AAAA 2001:DB8::1 + +foo DNAME bar +bar.foo A 192.0.0.1 diff --git a/tests/knot/semantic_check_data/dname_extra_ns.zone b/tests/knot/semantic_check_data/dname_extra_ns.zone new file mode 100644 index 0000000..e188742 --- /dev/null +++ b/tests/knot/semantic_check_data/dname_extra_ns.zone @@ -0,0 +1,16 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111214 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + NS dns1 + +dns1 A 192.0.2.1 + AAAA 2001:DB8::1 + +foo DNAME bar +foo NS dns1 diff --git a/tests/knot/semantic_check_data/dname_multiple.zone b/tests/knot/semantic_check_data/dname_multiple.zone new file mode 100644 index 0000000..2a6c0a2 --- /dev/null +++ b/tests/knot/semantic_check_data/dname_multiple.zone @@ -0,0 +1,16 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111214 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + NS dns1 + +dns1 A 192.0.2.1 + AAAA 2001:DB8::1 + +foo DNAME bar1 +foo DNAME bar2 diff --git a/tests/knot/semantic_check_data/dnskey_param_error.signed b/tests/knot/semantic_check_data/dnskey_param_error.signed new file mode 100644 index 0000000..1a2e936 --- /dev/null +++ b/tests/knot/semantic_check_data/dnskey_param_error.signed @@ -0,0 +1,70 @@ +; Zone without any semantic error + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + W9EprjaR4loSnNW96h4rLsquPDw3LHYvD05k + djkQofHSkMNZAJ7Q+eA3Fs2ik5fnJFM7wi5C + MtFsV2TfqMJFmg== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + I9Je1S7XhZIW9C0fWE8NwFLC2rhHklddNYBO + dxVKL/lxENU4jPPBwZBGrcYn2WVHgkIzjG0n + EOHONAgRFPi3Xw== ) + 3600 DNSKEY 1 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 5 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + vO2UQiTN/CNUZOmSEg8kJlR/UqiAZHc4qMwj + 9u31sbPmOMuni+ZGuVCFFoEMtZerIkkQowkB + sXJFkvCP5oF2rA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 31323 example.com. + Z+aaLu4rmzekfhlj6A0ClREloRi8MloRHf/3 + Dlw/RYY1hrOCfcZKEY6AXeVdUwESEsSkSOco + CbhyGHH10dKAAg== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160229083110 29600 example.com. + d69kc52VdALI8fbdbflsVsltc1m7bI6QsJ5U + IDE9fy5VqcufZecZMKuozPDuF2vBA8ADFIRU + OfYgKs6YNIOLWg== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 1 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + D24JCtCcNzwsY1FXVliAjxMm+x95N2eUTXn0 + M8NK5glSk1yLtnAUKzHxpRExAJLGUiaG4yPu + 2yGZuqwNvJztzw== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + F7y+xW/C7iICgmZeYrF4e7Yx4kWZAZPAMzlu + PtWVuf37ySg1VfEWcQcDP04vF2rXVUqSMEcj + bqUVN5W8Hoazxw== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160229083110 29600 example.com. + MoYrL/lToC4AHo6KCZRiBRmCMWHUAx2Xt32A + P4lDpwA+wiBWkCZSfVTh60AosS/BIGtBb2BK + mszMx8CLBvkjRg== ) diff --git a/tests/knot/semantic_check_data/ds_apex.zone b/tests/knot/semantic_check_data/ds_apex.zone new file mode 100644 index 0000000..9b315d5 --- /dev/null +++ b/tests/knot/semantic_check_data/ds_apex.zone @@ -0,0 +1,15 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + +dns1 A 192.0.2.1 + +@ DS 40920 13 2 70959CF5D6A0A3F53BD0AE42DF4DA6ADE84DA066AE1F95F6B6B610DA53F6E86A diff --git a/tests/knot/semantic_check_data/duplicate.signature b/tests/knot/semantic_check_data/duplicate.signature new file mode 100644 index 0000000..77bf21f --- /dev/null +++ b/tests/knot/semantic_check_data/duplicate.signature @@ -0,0 +1,19 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns1.example.com. hostmaster.example.com. 2010112269 10800 3600 1209600 7200 +example.com. 3600 NS dns1.example.com. +example.com. 3600 DNSKEY 256 3 7 AwEAAd0e6EjJ0PgChDpbjB9QtvJ0ZqwKC/j7wlEOOB9owqefH/taZ37w6QR8Ysvvv2058AflDcCP3qlaOXp+ogq7AhayA+K4kc/UQyTPCe2jXKlX9IB0KAsr8nO9UEXzjYuyBw80Ry86Xxmj7OGYRu8eRm3ruOjVJy8hCrEQ7680an303Iu3Ixnmo8lPTPPMg4dbFXZ/RW6Sanrr/Sy6fre87XY58yywqX9lZOh5eqBeZG9WvU/HycrDkx5AcwD5etVk98tVTnofShY34ePZWDmRHEtvBpMzNObdomgM5we+DawC6P+Z8PFeGz+OgN7WVzkjm+MmYAk1aIeLQyNIE8SyMts= +example.com. 3600 DNSKEY 257 3 7 AwEAAea81n0wL09ZMejh806rJ0Km3MYC+ySPWnOmV70nEmONbnduRPpXWjYSqFmH5kldfNdCH403kI/YCMYDYBAPFPbhxuZuVBaJJqOQVsI4rpwj+XiANfGFAq9pZ0oA8iH7gSoNUCf6+g2hcP0ajYoqCjUZ7ZZQNytV/x6foW5t5PbyPNeAU1AEKxk2VSg1TMfkccZqTIx1ofS0N102Z4tOBn26judPqLc0tXMCJc7wgekqG04IGe7UWfk9xWtwo2SbtX9diErF8DJ93C17OWkb04n1xCm3i8/XZadA/HrBjfX/NvlHF8qnUQzzxN7UGrvBD4hE12R9ICj4YNFZViOTdvs= +dns1.example.com. 3600 A 192.0.2.1 +;; DNSSEC signatures +example.com. 3600 RRSIG NS 7 2 3600 20170403124401 20170403124311 40703 example.com. ltKNDw2O/sIwQUsv3UCKqOtZYvWNJ0mHo2xDxpzZXfAiMbgR4k7jBIkpSEpcBiBlH7EvWom7CYVigPu8Y+j/Jq4uv+wmVF47OVY3YZvuzfprWj+iOQwPlfDJfUPx+U+73SSsZ21B5/+auB5cada730B4gQKmldleVGg5aov4H2+BpEyrsSs2o79qiXNBzLPqrZEmT0nfUAvQC8xhFV/71I8Q5qtfa3vO6DLSOBmBUtAlGKqfpWoZ2w+QDdA6rtOe0haizTZUtghL2ut47bdTR253brhUccL6nnLc5//jTUBToIhmG/p698xLnU9BYnuHIi74xsb3hVr5b46W5gAGKw== +example.com. 3600 RRSIG SOA 7 2 3600 20170403124401 20170403124311 40703 example.com. E9a+I8HDh6ycTVkFgOWkzbH7PWds7ewp1M5lUci13ZzMVWsJeFW7t1tLnnOtvz2H8pq5/BevPB8iZBA7rHH7GxoQ5P8xrxAO6HvuRZT8O4kYAWRZ0QHhMIvY8f6VqTyoOmzgIGt0nJ3BL/XJgxIiFrsiLyih6+dkckEu62F22+FFvlv49ufKkCo+EUQPCzo7ZYODc8xKWo97SmaADzjfz7Hq9UPHraUgLhNkfBDbI9YPCGKaJaAiqCBy/6ih3SyHxVPLcIz95okeo5AJVszFIS+8pNPZssJBpWsLKYyAGzs2dsliRwS9z+a3wkHXJIfbLX+r3kGhcG4lQMYDz9SrFA== +example.com. 7200 RRSIG NSEC 7 2 7200 20170403124401 20170403124311 40703 example.com. poh0BT+nUD3sM05axVGC+k7jj1r3YVNcx4bn/0cviNxzCqLY9RGgImPWsmkTgbJpmCox9SHzpTqL8acIQDNZaciNH9WeYKvn7wkap3z6jtCuQRezM3nUx7E37fzbnNC8MUoWkV37y3FSmtiza9l1isrE5dGkNMOsBcPvIp5wrbQ+dH4cMdcgQuW+NDjee6czIeeYtyarBWhq30S2lxroh8VXlrFDTcbiIY4UoGzJDfevvsonNFQXc+p7qq2fU1fyU1e3Ugty9I23g6fLhLcrmflVbYpcgE8/02K4asu5D7x/dOq21OU/jJfeudk66l6CVw7c3Qh/N63jRn8SsCj0Sg== +example.com. 3600 RRSIG DNSKEY 7 2 3600 20170403124401 20170403124311 5154 example.com. RmAPllqg+CEX+vj5KKmXGYsF8vqbqLoXSYqSOSWbvgWRazKaQU98fpJWdrmqylkR6Xa1fnbvliP4N/0MGremNejsNPvMsJ4GvpyM75Mb4BEf5mwwikW6xov9V/n1AN9grWofj/r5evsZYcxIR7naM9oxV6qJvy8fFIjthG805MO18bYk1/Och2x9TgUf6DTqKNBHQjk1AfrhVvpuLjdNnNT16Ak3izrCLOm2tuNTaflkYkD0n06ZIAsz1krJWztpncA2csnKQmdybSL95wZnFeb6nkmq+P5vk3PuTENIMURYMCNfzBHogLfbVG5HpDhaHkcM2zSe1qATbp9xRZujLw== +dns1.example.com. 3600 RRSIG A 7 3 3600 20170403124401 20170403124311 40703 example.com. iYfVT+HPDqMyH9f8aLrzNK6sOCoo38tlRJ5tjiko0DOpsWp20LLgVQLvKsTs3SfdC0gYzMVQCgzfDMbAgrEvmm4ZEQT/NSUhcO2t08f6pABn6GSdoswFupi0LGdQmgj/MbOET02OTALh9I6g3Ir1+bF+C10GS/8CYqffO/52IEJylc6AzDCwAjfkI/55hsuv2H8Wp5cqEG5yAlL4fK+U2zQWEuAGOtGbEuzeKcEDV6iiAuFge7ClW+CbB3gQxEhDdx5TQNNAcpzHmum5yfsfcFkIezZqIzEvOQWg1nJVcLvYnuBqyMWv/uGbG4CxTDy49U9JB/6QfilMk38VVcitZA== +dns1.example.com. 7200 RRSIG NSEC 7 3 7200 20170403124401 20170403124311 40703 example.com. gtRE8TafAp50tzk3rAub93X69pp4J7uPzXPM0UAAp97oVMqcqvuZh80fICLmKl7xShvBx+AYfV+2CoeMW66CXVHTP8CyIjLyi32EGgL75Y2xs55/lEOaMl8hREgxniopCWGX/5vjmY0SBdGWVQVyeQeb0DbTXFWQNw/1LUPueoM1zqGcHFKFt5Y1GidboUEDsNeCmG3ZzGV9/v9sVUezzDK53uaHm8Ojz6E4N7kg6qXDF32ZAxs0dDjh46bsaTNvMLCEXqO2imHx9Omc2wYyCt/roMoeYiulXQ7yHYt0yQuCYwqxxMqJ4z9jvLNdLxH3YZYV0CVUrNgNC/5vtUILsQ== +dns1.example.com. 3600 RRSIG A 7 3 3600 20170216152943 20170216152853 45258 example.com. j7H3N22L+tqfwuSd4GhIwMyjrFSY3+kypIcOvg0Ipbj4pAHsJOJTiW454Ueq54G/0ntoHxgmGLv3d/EV9prMPPQz8eqtRcYFip2NuEF9bJsIG3SMy+0HolPK+8D7B0MOGFA2TExKNknS7sJy/Jn/yQrf7BHubC61zWnqB+vN7MNlJASXEvy3008oi4FScSsrAVIrZK+z7utY4exkCVfELC7flGenoyPDFR12y8WpN/Tk6q1H37x+EKaQgFj361Bm6f/InPKW8Npn/SNCIJ2DvSWAnj6+2n1mse0sC+rKhRIDMDopu7JzTjpVs9U/p9BY5dtH/3YvST4Vz3syqd1unA== +;; DNSSEC NSEC chain +example.com. 7200 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 7200 NSEC example.com. A RRSIG NSEC +;; Written 13 records +;; Time 2017-04-03 14:43:12 CEST diff --git a/tests/knot/semantic_check_data/glue_apex_both.missing b/tests/knot/semantic_check_data/glue_apex_both.missing new file mode 100644 index 0000000..74e37f6 --- /dev/null +++ b/tests/knot/semantic_check_data/glue_apex_both.missing @@ -0,0 +1,14 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + NS dns2 + +; missing glue for dns1 and dns2 diff --git a/tests/knot/semantic_check_data/glue_apex_one.missing b/tests/knot/semantic_check_data/glue_apex_one.missing new file mode 100644 index 0000000..47ee797 --- /dev/null +++ b/tests/knot/semantic_check_data/glue_apex_one.missing @@ -0,0 +1,16 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + NS dns2 + +dns1 A 192.0.2.1 + +; missing glue for dns2 diff --git a/tests/knot/semantic_check_data/glue_besides.missing b/tests/knot/semantic_check_data/glue_besides.missing new file mode 100644 index 0000000..38ad890 --- /dev/null +++ b/tests/knot/semantic_check_data/glue_besides.missing @@ -0,0 +1,17 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + +dns1 A 192.0.2.1 + +deleg NS dns2 + +; missing glue for dns2 diff --git a/tests/knot/semantic_check_data/glue_deleg.missing b/tests/knot/semantic_check_data/glue_deleg.missing new file mode 100644 index 0000000..291b450 --- /dev/null +++ b/tests/knot/semantic_check_data/glue_deleg.missing @@ -0,0 +1,17 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + +dns1 A 192.0.2.1 + +deleg NS ns1.deleg + +; missing glue for ns1.deleg diff --git a/tests/knot/semantic_check_data/glue_in_apex.missing b/tests/knot/semantic_check_data/glue_in_apex.missing new file mode 100644 index 0000000..a02f6bf --- /dev/null +++ b/tests/knot/semantic_check_data/glue_in_apex.missing @@ -0,0 +1,13 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS @ + +; missing glue for @ diff --git a/tests/knot/semantic_check_data/glue_in_deleg.valid b/tests/knot/semantic_check_data/glue_in_deleg.valid new file mode 100644 index 0000000..42adf6b --- /dev/null +++ b/tests/knot/semantic_check_data/glue_in_deleg.valid @@ -0,0 +1,16 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS ns2.d + +d NS ns1.d +ns1.d A 1.2.3.4 + +; glue below another delegation is not mandatory diff --git a/tests/knot/semantic_check_data/glue_no_foreign.valid b/tests/knot/semantic_check_data/glue_no_foreign.valid new file mode 100644 index 0000000..4cdcbe0 --- /dev/null +++ b/tests/knot/semantic_check_data/glue_no_foreign.valid @@ -0,0 +1,13 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS foreign. + +; glue for foreign. is not mandatory diff --git a/tests/knot/semantic_check_data/glue_wildcard.valid b/tests/knot/semantic_check_data/glue_wildcard.valid new file mode 100644 index 0000000..9e36b5e --- /dev/null +++ b/tests/knot/semantic_check_data/glue_wildcard.valid @@ -0,0 +1,22 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111217 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + + NS dns1 + +dns1 A 1.2.3.4 + +abc NS a.ns.abc +deleg1 NS a.ns.abc +deleg2 NS a.ns.ns.ns.ns.xyz + +; wildcard glue + +*.ns.abc AAAA ::1 +*.ns.xyz AAAA ::2 diff --git a/tests/knot/semantic_check_data/invalid_ds.signed b/tests/knot/semantic_check_data/invalid_ds.signed new file mode 100644 index 0000000..d838172 --- /dev/null +++ b/tests/knot/semantic_check_data/invalid_ds.signed @@ -0,0 +1,108 @@ + + +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + 3600 IN DS 60485 13 0 c5 + 3600 IN DS 60485 13 1 c584e6295950fa2ff90f9229a1da2efd3cc98cec + 3600 IN DS 60485 13 2 c584e6295950fa2ff90f9229a1da2efd3cc98cec3dcdbcaa6eeffc400673246f + 3600 IN DS 60485 13 3 c584e6295950fa2ff90f9229a1da2efd3cc98cec3dcdbcaa6eeffc400673246f + 3600 IN DS 60485 13 4 cbb868ac75fac9327d19f25fd14971158d4b4ad0e4c75d3e7aa35752bfa5ab9c5e9d02cb805b91cf322588f97e1c486d + 3600 IN DS 60485 13 5 c5 + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + 6DFJITU5VML86QNKU9FO2LJDDQQTQPVT + A RRSIG ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 IN NSEC3 1 1 10 - ( + UI312KQOP1NG8IQEIEFNPSLA94KB5Q92 + A RRSIG ) +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + KElp8dLKBKFzgEFV8r5aP9pCyYUD+Z8rLBA9 + KkCDm1y82x5T/Cu5UXuZJwhvDGDzwPqoY5Dr + Qbiek52n6umbEw== ) + +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DPwNyH7r/4wIBfTGxikNv4pY7omY6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + bGk1vLxVuJpcEy7n0gPvQVzfanbvINLJLcbD + eeie4sXZZAOwu6oQZy6kd8tvKtV4mL0OJzpH + XCO6BdZkmk/aQA== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + roe4aBp4G3TqQ4x5eRxbVIjApIh17gXDjfOY + zvRFLOkrwqKz3eX9WrRiCk3bYNn8s1fuenaQ + OSV1D5SL7utX5w== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + c1yhXb8wRGYndpVqG61+lHAAbZg+JcVYGPX3 + Fw0jYigN4G+P0+VUCqPLkC4yfJylzuefyGfk + TUmriM3ihfXxIg== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 31323 example.com. + mZiLLTzbdaj7EJ8uj3TwvcvAfaMxYjyavlGT + qpa+cElfvBDm7R6MF4MaEQ9aZ2ylMt1lppjq + YyYRaaQC6yhm4g== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160302125715 29600 example.com. + K3PkVYZZV8QvZFtDsz9+ZfiM9wDkFu/eO2S5 + tAtCXd1fktcW44TLWL0qADfFEEcMotvzLqv1 + YJrD7TvrFDot8Q== ) + + + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + vlzRtVFa44pRtdD8XZcgDa6021uA9A3TnNEw + 5jRnor4aoftUuVQNAanQMCgrWk63d14XZ2d0 + lqhxunAbh08dsQ== ) + +www.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + NWFuYaSEg3z3K4l/fHu/X9dK+rDZ177BbCNN + ZeFTPCAdOnX0nw1CQys629k7Vzdv1pHaanmy + 0Ru0tX9R65NlKw== ) + + diff --git a/tests/knot/semantic_check_data/missing.signed b/tests/knot/semantic_check_data/missing.signed new file mode 100644 index 0000000..75c7d22 --- /dev/null +++ b/tests/knot/semantic_check_data/missing.signed @@ -0,0 +1,20 @@ +;; Zone dump (Knot DNS 2.5.0-dev) +example.com. 3600 SOA dns1.example.com. hostmaster.example.com. 1081539379 3600 300 3600000 3600 +example.com. 3600 NS dns1.example.com. +example.com. 3600 DNSKEY 256 3 7 AwEAAaBgc4O+4UWd7mzSyelnPb/le/x0q/E90B/xnlf56kgEFMvEGz++o6CMRXr5JfgyxDDsahxTwFoWu30KJry4MjgcwlETM63DFpIYtyDBsi8TlQFEp5NDrlYUWlPGiPfywZBVkHGFMcFct+5/ZalTzYIP39tDytZcPZ/IgQRQZA9qeHYIw51YX9IlNMalHFCtJyrpzCdo22FY/vwBwSbdCa+vzkH1Uu8JkIqyAvAGkuwVisgpMpzWhvJNi5WSAnQfwOcsYCftINAHdRXtuqyG+uU/RDcZ2psx+woi+mYzEPeYV9MEqWpDyIz7jS7e1hK/1o05+qY8Eu2gt4enRj9BQr0= +example.com. 3600 DNSKEY 256 3 7 AwEAAfcfJSUnim+cR3YEc4VfdJ5W65GNlK0LQaAh6vAejH7uol8VYmXdlyz+wlhad+DyRM5Jl+XJVFMMyFUqWx+Q63DPRtl+TlN/2pWU2gsNHUoovFhFpdX1cQMVoxr2QLgsm1ASTeqvZV8Dn0xAlNRihNv877sTySjveaH0JpuVCMpe5DB1zVbAzLgDqFKAvwJCumdycp7RzMi9PqS1XtsEInKi+X/zZteTJbDO7l+tFt9/NgFxiaLgNo8Gz2oVBTQvAbjCDEi2mPA/YJrpOGZWNkB2L9HFSfzZih8BbgUI3Fh4lhS8XCVrfVV7K9YR2F5NBVi7h0Mk15hzNsSS7tRK1FM= +example.com. 3600 DNSKEY 257 3 7 AwEAAcjdwuJkjM8G5rk967z1cJqF88BqpvN2GN/6Tj1XA5AbIx+33qy5JI6K43ehlT/neLizOCk/JyXaw8gcjQaDKcIy0vKysXvI6yK4PNgHTdzQunBqGTfvPDlXKCle550R/DJF2OZH/T7jgX2GhQlem6UB3A23n24YP50IzAmXK9RYdE/dMFXU5jEz+CjcHNkB8ZCb2VrKE9RDjY88vr6lyM2kPbvBtx4UaUSEzwlDMRc3Wf+dBWKm6mKWAPsHZM/cux+S2mca/cxEA1ngCgBBbm7824WjTXgDs14QWuwruMTqLPDujUYND5kbsiuhQsfEFGVq2UyhGEZG/NoIEEg7qLc= +dns1.example.com. 3600 AAAA 2001:db8::3 +;; DNSSEC signatures +example.com. 3600 RRSIG NS 7 2 3600 20840201000000 20160302125715 7242 example.com. B/6k7YAQGkiz6IkssLZblExgMZBE+Flkhv/leVgvM4RLPPpQ2znouYyrSbVCcU5irA7PFLbee5Mn1aWj2S57L8yGJjHBuamQSIO0GcvGcmXi1CrdaYXSofo3PtnKpM8/mG3+8RCUL5YhoxhTK4Y5gJrYGPkRPKsBTw2Qd2TUJFebtYgCuGN8Q3UwbeYPw89rNbqC3a7zsGwJoZKgDnm3NwCWcv6NRTcQA/H5v6T0/QvYbZpBMrjl3EiAWOccdUlQnALngGSzbJ2GnmK933VXYhuAoSKEN6thauOBSLkdCh9afkUzo/t7xhTJszo0F1uuavs8PYf3HjmdnMwdPMkUuQ== +example.com. 3600 RRSIG SOA 7 2 3600 20840201000000 20160302125715 7242 example.com. dHmPqRl9snHFavwkkAFZqHDmvUrI3+e+dmEexqgW9txr30fbrkeGAp6ApdZlqJiDTJ/2q0UoyQxSYe/BzgV4gEBgTTgfmC7m9eHVLTD70KMlNuvwC4jkh1vWT1Zn6IFUsQtJ+54XfRTe/2VHyeK7saqsA/ARRZGOzk6To8CWxNCApUdLZMQO9UTX7uVcXKkPvfMvlhx1fmn4OE8ntwbY1oPosQb987N8V8x9Rb2hINr4DCkXNDydDZAh4vsZO0DHPlmyfkyNguQDmdgnDz1CVbJzguy8tqeMGT7CrwU8AmX3JADQTHoxjnWEidLLUa/gNDRFcRc5YMcdZyImHqdNZQ== +example.com. 3600 RRSIG NSEC 7 2 3600 20840201000000 20160302125715 7242 example.com. bjw2G/BwF2xTP/QSkKqdr7byUS+nqMvfppuhZmH0VcysAKN2oqsV51bn7gWej6dnx0svtX7nCOlwdDFSCMJld5BGZFnAfhS+XVc/wTeZGMi1BkeJxlT3UbGLhf2DuLLyL969HPltL527vSysjBEmi7OsTlH+wXD6SW35ZClajNSRLjxrRpVHTGpA5uyyysHRYNXAKS3+SSc1N/Fovjgzi68exWD0BKTGia7Nf9Fn+bqvhbYh+pMHA7djPFJIsER3OCBx7H1KMxl6rap7Q3rC0I289xnnsOqRh/GnzSVgvobKWozOOs9XXNg+w9ioSos+kbzTxxSEvLKqNBgCbLjUHg== +example.com. 3600 RRSIG DNSKEY 7 2 3600 20840201000000 20160302125715 37855 example.com. EHXazcQ27b5Cjqd1T8TAui2PrUqEq7cBxk45OA8BfBDmOuH2vXFVL+juCM2gCvQ+0oZmcJmpkjMCxUqQekXgxRy21PlEzJfR3VHRDSYCSogR9cCLw9T9OiFXugZAtYcLVXVHddKu0+t5yeQqdStgLBiz9EmeuPFYd/h/BxKI8FGx/TjHNzd06SKgxlZAT/vCGhEswgSIpxJm4Ju561vT2/Hh+NmD4jIKVf0OUSkfRVRbxpzMs0HaZx6s0T2mcL8so/rEXjSIORkw56Q7x3EmYQDxNJjoNo4nHKT0/pciCey+vHj9pxxaiave8wLBG96JpgJgSV7BG8TTbE2q62wX1Q== +dns1.example.com. 3600 RRSIG AAAA 7 3 3600 20840201000000 20160302125715 7242 example.com. h0oZ7ghuhANB27zD+M1m0NyVUHND7g2qI1IfEKDjMzZ34wyqM0xWLm/Izln86ol4naDvJU3a7hsJS/95DdvW/s711Oi2nKhX/Hkjvnzu8WVcf5DvEKYQe/fyZ676hnwviKqFzwmfTAKgIuSvt2uZzJkpcyL8ZE6O/GdPrcR6rTuuDI30F4zXIWPmuMNLR2qJv59DwM0tZScLdmRGKGnZNpdxDvtbCsZrXBUPrOE5XpAw+fe8+oL3UEeKQZq8qFhVvegl4TAuk1a8CS+zG4E1ABQKp86J1h0G4l/ajmWqq2T59lHsBAOuX0IbKHEHIJzwRd9EV7LM59EtJVacx8ZCkw== +dns1.example.com. 3600 RRSIG NSEC 7 3 3600 20840201000000 20160302125715 7242 example.com. Pq6F6akEhyIqch7vwWJ5C53FW1UW/Y8vseFqB6tzql5bnIYjEwikgiWR85uvSUNGvsjHbadBYiVh2i68k80ws/2LecQCvguSH+rMkqqY9go+pBh3pdiNlJaJZp3zJQ6+E35xOA+p0G5t84Et3satJl3OcpVthrdBKuotpDg4P+nOpfLHkI3FO5vehxs71HmESQli5JllhPNMH6WZfWsP74D4DgRjUpIK9hGznCeuZxJT5+S5wL4fzqb+P20W30bsQqMbo9GNdPy5AdbwZoEKJVoN3HC/sv03ScQzWUxjamHCQOeZFys25fFlh7+JU1xYSb3V/fPhUUuf7OsBVvn7+g== +mail.example.com. 7200 RRSIG NSEC 7 3 7200 20840201000000 20160302125715 19578 example.com. gjNXoKVddN+Z3MmHXxs0v4Gv/3zaTAg0mBSLkSp8Ion6qKj/aR2y50QhNfZGVEZSmyerDiaVpfPMN+q9mwx+6xmv4/G97DkadXBYt5IXGR1fXhMCF+RLJb5ePYjQKSk2TfRMJAlk1Mowfvlp8rXFrT576y2F+IXKbpiJOdRt/13Wo5IUbw6LLFDOeZ3fUiZtBmoWTTjBnrGWYdb+ePcSXID+qM5TmRXqIOFceJvt/RhGZ5LYAchgM2sZDf4Asacxg6Z6vS2cA1opTLMAIu+cuEmq61cSJxWHblfXIpPMXFG+4i+nkCxEFxWyxt9edlAeHS/l2AiHQl5QeuzwEjFI2g== +;; DNSSEC NSEC chain +example.com. 3600 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 3600 NSEC example.com. AAAA RRSIG NSEC +;; Written 14 records +;; Time 2017-03-31 15:38:20 CEST diff --git a/tests/knot/semantic_check_data/no_error_delegation_bitmap.signed b/tests/knot/semantic_check_data/no_error_delegation_bitmap.signed new file mode 100644 index 0000000..abbf088 --- /dev/null +++ b/tests/knot/semantic_check_data/no_error_delegation_bitmap.signed @@ -0,0 +1,61 @@ +; Zone without any semantic error + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201008173446 32411 example.com. + /R/djqaZWRo1zCmz7B58/93D8ZxJoZAAKEbH + xuCsAJ5dm2ubvtgvqmhNXMqdVBvpb2OPdBX8 + VF1j9RsjuE7ORQ== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201008173446 32411 example.com. + AmyqpqMfMEztA9S1Urv6yEtKd5yc6kkSedRU + uLp7velyCkipFzWgpzRVDqn+wp2ZaHig0Fod + kryw3j4yHOLlHA== ) + 86400 NSEC deleg.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 13 2 86400 ( + 20601231235959 20201008173446 32411 example.com. + 9tR3kL4pVEYsHzt888pbP0TtS/npeApAEUfZ + L5rXQE0WqBLQGtyEPYxujFuaruvxH0SgLl6r + n6MKCEB07DjhTA== ) + 3600 DNSKEY 256 3 13 ( + C7v6eelCoXgBoUjHe/gKdsnWNw04GH7PpYMo + 2hF5jaeq1zkLSXkF2xS/04MgBTFFYuDU+LGt + 8kMKNc8o2wH2jQ== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 32411 + 3600 DNSKEY 257 3 13 ( + m6KdGBizfDaUhcW+nIHuRdufZFcSYlZ5Xoky + +GcH23OxZtPzPwKwpg5rTx+RCRPlVpmwyiW3 + aC69n0Q8mr8NpA== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 60051 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201008173446 60051 example.com. + SD4149dui/vuky4G6wiJQLUw5b8XpG+Cy/cf + +9CSbuKWHRcC1K0wVEw6xyEah6eD/7Sh0eFA + EECgej5etJbL3A== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + 86400 NSEC dns1.example.com. NS RRSIG NSEC + 86400 RRSIG NSEC 13 3 86400 ( + 20601231235959 20201008173446 32411 example.com. + HFA1XBdjaUvb8lbyhXVDYxTUn8Nr2HNC5ktc + kPBW2AGMQiVUtyR3vPxUIiusxsQn+uyRL2QC + NBG3ANo5exT8ug== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201008173446 32411 example.com. + 4NLhmO0Sa3yk1ZikWSRYEX0FpHK0NkTGk++h + RHJO3E9M6Og1am/PiPf67DAe/2n4ANItC/SH + u/1WSvYQV7OZqg== ) + 86400 NSEC example.com. A RRSIG NSEC + 86400 RRSIG NSEC 13 3 86400 ( + 20601231235959 20201008173446 32411 example.com. + pQgr7WzGpL8gbbAcbeYEIYBLq8lCAuE9NaUf + itYKBFh7Cbg4YrLOoeAV6v6V4tfZPpmNpd2U + 9VUrY9es4QfX6Q== ) diff --git a/tests/knot/semantic_check_data/no_error_nsec3_optout.signed b/tests/knot/semantic_check_data/no_error_nsec3_optout.signed new file mode 100644 index 0000000..a03f4ea --- /dev/null +++ b/tests/knot/semantic_check_data/no_error_nsec3_optout.signed @@ -0,0 +1,29 @@ +; Zone without any semantic error + +;; Zone dump (Knot DNS 3.1.dev.1612270066.d215637a6) +example.com. 3600 SOA dns1.example.com. hostmaster.example.com. 2010111222 21600 3600 604800 86400 +example.com. 3600 NS dns1.example.com. +example.com. 0 CDNSKEY 257 3 13 Yk8KOmyVzOij3x+Zs+eT4J2Up9+ipwXEKOhL9fTYY/DU10yIQt+zYm02UFZJX2oVTdHBCajpBFsZLH2X4ho1yw== +example.com. 0 CDS 25674 13 2 2EC05563A3537BD32EA3EB92C44794C644F249EE440785CF28207B903E35322D +example.com. 3600 DNSKEY 256 3 13 tCoteOM+A4o/A9uxgLyDg3HOg2DClU+3d+1XPQRtTfuaEFOGIpyH6qiFUv2b4DYuvmMyTkL99nxvyhA8yo0Cgg== +example.com. 3600 DNSKEY 257 3 13 Yk8KOmyVzOij3x+Zs+eT4J2Up9+ipwXEKOhL9fTYY/DU10yIQt+zYm02UFZJX2oVTdHBCajpBFsZLH2X4ho1yw== +example.com. 0 NSEC3PARAM 1 0 10 151E9F1094FE188F +deleg.example.com. 3600 NS deleg.example.com. +deleg.example.com. 3600 A 192.0.2.1 +dns1.example.com. 3600 A 192.0.2.1 +;; DNSSEC signatures +example.com. 3600 RRSIG NS 13 2 3600 20400406110811 20210205093811 61806 example.com. VD3IclxLUSi1tgv4+FJ+9e3EWiRny6de1y4jUFn1Ama8+Cl2vZO2Jc34Q9MKY/S9m4id7Xe8MtkkrKThQcaaXw== +example.com. 3600 RRSIG SOA 13 2 3600 20400406110811 20210205093811 61806 example.com. BniH53lEM1hYGcorTmqF7At3+neZkifPT1sM15nGlQUQ6RfkPxh7Uy8Pj3PxLL5v7WDTyFGbLVThEFWZUh/h6w== +example.com. 3600 RRSIG DNSKEY 13 2 3600 20400406110811 20210205093811 25674 example.com. 3FSDEJ9f54++FX/EHWXXnbHW8iJPaDG4kc7qf772y62dtqTfAvb22lq2yKzCOaRFFwpPKEdcS4OEkhx0IbC27w== +example.com. 0 RRSIG NSEC3PARAM 13 2 0 20400406110811 20210205093811 61806 example.com. BTT+7Gj8V2pATxogxJ8xEO5eiVHoVIDxdK60zDS3MWNcbUc/n9vJR8NrCECel9egQUWrejawikO4DkyQxLZpkw== +example.com. 0 RRSIG CDS 13 2 0 20400406110811 20210205093811 25674 example.com. h43kZiM1EFETWQEtMM8Xls/RFDsAkLIpLf+DUnJ+zzxv37xpGvtf/s//3ew9qEhouBnGh/1FWtNr8vjhzh0tsg== +example.com. 0 RRSIG CDNSKEY 13 2 0 20400406110811 20210205093811 25674 example.com. 4mf7C/zyWoFRllUEaLHpdxJdlbEQXIRKNH6JOH3sTKSQMGj1SMmkWm9qlO9tVaUm1ggB6r8TPWgrAUBG+4A9gQ== +dns1.example.com. 3600 RRSIG A 13 3 3600 20400406110811 20210205093811 61806 example.com. lMj63MgZYiCl6Fdf0Q5C4/K99AAXTqCI9HSBQcrc7qiZDjRpZXzBUO8yv7+5JSMIo/A3tJtQL/12VFPGZ9NQ5w== +;; DNSSEC NSEC3 chain +ple28jlp3q5anh045ssk9f3u7ltd4qlc.example.com. 3600 NSEC3 1 1 10 151E9F1094FE188F rvcd9h11kcnenarqcmtmrhusdmb24rm4 NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY +rvcd9h11kcnenarqcmtmrhusdmb24rm4.example.com. 3600 NSEC3 1 1 10 151E9F1094FE188F ple28jlp3q5anh045ssk9f3u7ltd4qlc A RRSIG +;; DNSSEC NSEC3 signatures +ple28jlp3q5anh045ssk9f3u7ltd4qlc.example.com. 3600 RRSIG NSEC3 13 3 3600 20400406110811 20210205093811 61806 example.com. 7AdxaQLQ16ORwtf3t9lNQrzOP1BKu0TOIiKfx8/7o0JKoVtDYjqTC+ilWSD/Mbfb6PI6ND3NQKsIbnApOa2SUA== +rvcd9h11kcnenarqcmtmrhusdmb24rm4.example.com. 3600 RRSIG NSEC3 13 3 3600 20400406110811 20210205093811 61806 example.com. bOUzqzuIhV/SPyXiFOgsJbnS77dijFWcLDY/0X3r9aNiAo3/vSE4OTT0f6CkcBQDka+LjIoRaE7NIaTMl24fdg== +;; Written 21 records +;; Time 2021-02-05 12:08:11 CET diff --git a/tests/knot/semantic_check_data/no_rrsig.signed b/tests/knot/semantic_check_data/no_rrsig.signed new file mode 100644 index 0000000..6a3161b --- /dev/null +++ b/tests/knot/semantic_check_data/no_rrsig.signed @@ -0,0 +1,48 @@ +dns1.example.com. 3600 IN A 192.0.2.1 + 86400 NSEC example.com. A NSEC +; missing RRSIGs + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224081310 29600 example.com. + ieEKhIV69ywg+YFSqdz0t17eE+PLl1eR4kpv + Mq6Q6TfjC7V5/PcFW6KRoP50RFp4m4cD0E7T + GpmpnPF++QV1Vw== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224081310 29600 example.com. + kYbAbCGzyWPBEfc0TH1calUiKsZi12MH3TNV + 7vtjOvIYEqeNmuJkrw899a7nOPNoahB6h7o/ + DXuRlFqYYCC16Q== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224081310 29600 example.com. + PchT9RWRkLCMxWAQ3ut6LZlh4MYT4CkAPThQ + cnIn0ORi/fVgGzlifQ88xfEdEr1ZoXk9PlhT + 5b+wocBOl2HhGg== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224081310 29600 example.com. + JLcSyR8KgSicUou0c7Zs7Ol1DYiaQ8Lfyort + 8a+5OP3em3r3NH1nJkiVfs8+xdvUcGlGkbib + RKlfRWiIcOEalQ== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224081310 31323 example.com. + EQMX5DPXhwa+blMRkzl+swUW3BtzpGJ5tGEU + hkH7bJfM51gIAO5qnUO/mMPnEA8b4dc20nnZ + 8j8lETDjqBLgDQ== ) diff --git a/tests/knot/semantic_check_data/no_rrsig_with_delegation.signed b/tests/knot/semantic_check_data/no_rrsig_with_delegation.signed new file mode 100644 index 0000000..2c36b9b --- /dev/null +++ b/tests/knot/semantic_check_data/no_rrsig_with_delegation.signed @@ -0,0 +1,61 @@ +ns.deleg.example.com. 3600 IN A 192.168.0.2 +deleg.example.com. 3600 IN NS ns.deleg.example.com. + 86400 NSEC dns1.example.com. NS NSEC +; missing RRSIG for NSEC record + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224081610 29600 example.com. + HhnlCtlIaZFVklpzVUnzm6AzFd65CSc4WCJL + f2o7Gkevu+HTnkiPN6gqtERC/BKJz1EKd2fC + KDyLxXw6KeTRAw== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224081610 29600 example.com. + rcHuZd9wTYykzis+9Z8uyqD8V9h22szf2bmE + GYNyJBlHZO0sOmys31xnvDfQ9sdk9hf1TUfB + 9ACGIF5lDHBEog== ) + 86400 NSEC deleg.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224081610 29600 example.com. + YGSe1OINjOY3I8BY1EoxcOJsDZ/DjGCT5nqY + J6BBjTcbT5S1W61SN50xc2sGB4Q8F2KTotAe + arzn4DGDt9mOMw== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224081610 29600 example.com. + rdmqHOUXqhwrJusNt/7FTV+AtO/v6Md3LXzj + /QzR/pCADNC6ZA+FvqaOycnUxoryKk7PY3pM + 5ispCMuEx/1OGA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224081610 31323 example.com. + jELyXsaJx+G4heZJ96dyE12hSyTNFazwWDkq + 1Mkja9/bTTdYAd+t8fhf/c35bUiTVJWMivJe + +YcCwqGf2U+2zw== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224081610 29600 example.com. + ln2xuvghOWBDOfyk19Wwtv3oc8+1go3WQuMf + vel5x/uHVx6voNA25cpFIQ6nPlCo8pmd5R3w + paMxgoQtBkzBcA== ) + 86400 NSEC example.com. A RRSIG NSEC + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224081610 29600 example.com. + EEKcIegUeyn/1FIgxHV+gSX3b/ygQPAcjD8g + aCt1yiO0B1xmVm09RJNxzCLaTKxQENhxIoUZ + 2l7250pBQnrlAQ== ) diff --git a/tests/knot/semantic_check_data/ns_apex.missing b/tests/knot/semantic_check_data/ns_apex.missing new file mode 100644 index 0000000..fd7b7be --- /dev/null +++ b/tests/knot/semantic_check_data/ns_apex.missing @@ -0,0 +1,11 @@ +$ORIGIN example.com. +$TTL 3600 + +@ IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111214 ; serial + 6h ; refresh + 1h ; retry + 1w ; expire + 1d ) ; minimum + +; missing NS in apex diff --git a/tests/knot/semantic_check_data/nsec3_chain_01.signed b/tests/knot/semantic_check_data/nsec3_chain_01.signed new file mode 100644 index 0000000..cd90b9f --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_chain_01.signed @@ -0,0 +1,80 @@ +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 + A RRSIG ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ ; wrong next record + NS ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) +; RRSIGs for NSEC3s +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229140652 29600 example.com. + PjEM7Bxxb7w67366fKCLkR9BVFAL0RI8RJCZ + 5aqoMVuy+ui7MLKxKT2LfeTHgBw1Cww1bbJw + Ip2zu0/ZGPfKzA== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229140652 29600 example.com. + DUMMYDUMMYDUMMYgc7Jx/FgAlruRjwsS/YJa + sZRspDGZhSqK2daV5K0lmK+XL8BoOtp7aXtq + VER5XcWLOebCdw== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229140652 29600 example.com. + XsJa0IUE2ddTohJmiuNVd/Po1ZOK0PDCuU7/ + CS0/wiZ5ZlxPdVUAYXuC7HhGH+ZPsqwZ4oUU + ToDbFqfdzmC1XQ== ) + +; other zone data without error +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160229140652 29600 example.com. + u5QMvOSkZBUM5tLiEAq3A+x4Ha17ZsNUYqeI + SuYA1+NbaBDxAtT6scB9aeA4lOTQ0TZvpGFE + YF/XxGtqvwdZ8g== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160229140652 29600 example.com. + ELZOh4iS9DpAafa8NTaI/eNL3Qwy+lsmgrzF + 7jaoR5yOURl/RZSJY+m9Peaq4ALcROdGJ0O4 + miSpdTIZsBSGZg== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229140652 29600 example.com. + sjxCP/grgOR+4vmXw7HU/hGSx5dS5QxM00IA + gZNJ6Lqf+4OSL3TEa1/qqRSFTl5uv3rqh5W4 + 8p2JoT1ZkcJj6w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229140652 31323 example.com. + jrH48r1iPFRfbyIZWcARQrejVgrE9v8qqt4R + uPHjz5t7PYmZYH544SI9HtaWGkIJ9jzlxr5l + ikCWo1we50y9Lg== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160229140652 29600 example.com. + yIXzhQw8c/c/in+doXX5JmqoGiqoYD2Hhw6d + /aGXc5QLQqxyATXln02vkwt1d7DK/ha1vkfx + bvGdduXDQ7YZ+g== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160229140652 29600 example.com. + aMRzV/1+m9wQHWezSiwkmDEbnS85wB9dA5x/ + u2P7NPsgwMnRdfpVIMfaVhSJH88i5OlLTvL1 + sSK+RADpuoqnLA== ) diff --git a/tests/knot/semantic_check_data/nsec3_chain_02.signed b/tests/knot/semantic_check_data/nsec3_chain_02.signed new file mode 100644 index 0000000..ca70cfa --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_chain_02.signed @@ -0,0 +1,94 @@ +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + 6DFJITU5VML86QNKU9FO2LJDDQQTQPVT + A RRSIG ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ ; wrong next + A RRSIG ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + NS ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 ; wrong next + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + oErbN3Xw+0zAqkz5KC5nOsINblBc4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature+Z8rLBA9 + KkCDm1y82x5T/Cu5UXuZJwhvDGDzwPqoY5Dr + Qbiek52n6umbEw== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + ep1TVqEISn2ZOiBtizK2eyuuhsYyD37X9Bw2 + 9JOkecZnmzCwBqfMCBvRYmNRpMd512+ZnW/I + 1vIViE7CGwkHyA== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySginature6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + bGk1vLxVuJpcEy7n0gPvQVzfanbvINLJLcbD + eeie4sXZZAOwu6oQZy6kd8tvKtV4mL0OJzpH + XCO6BdZkmk/aQA== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + roe4aBp4G3TqQ4x5eRxbVIjApIh17gXDjfOY + zvRFLOkrwqKz3eX9WrRiCk3bYNn8s1fuenaQ + OSV1D5SL7utX5w== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + c1yhXb8wRGYndpVqG61+lHAAbZg+JcVYGPX3 + Fw0jYigN4G+P0+VUCqPLkC4yfJylzuefyGfk + TUmriM3ihfXxIg== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 31323 example.com. + mZiLLTzbdaj7EJ8uj3TwvcvAfaMxYjyavlGT + qpa+cElfvBDm7R6MF4MaEQ9aZ2ylMt1lppjq + YyYRaaQC6yhm4g== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160302125715 29600 example.com. + K3PkVYZZV8QvZFtDsz9+ZfiM9wDkFu/eO2S5 + tAtCXd1fktcW44TLWL0qADfFEEcMotvzLqv1 + YJrD7TvrFDot8Q== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + vlzRtVFa44pRtdD8XZcgDa6021uA9A3TnNEw + 5jRnor4aoftUuVQNAanQMCgrWk63d14XZ2d0 + lqhxunAbh08dsQ== ) + +www.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + NWFuYaSEg3z3K4l/fHu/X9dK+rDZ177BbCNN + ZeFTPCAdOnX0nw1CQys629k7Vzdv1pHaanmy + 0Ru0tX9R65NlKw== ) diff --git a/tests/knot/semantic_check_data/nsec3_chain_03.signed b/tests/knot/semantic_check_data/nsec3_chain_03.signed new file mode 100644 index 0000000..80112f8 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_chain_03.signed @@ -0,0 +1,94 @@ +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A ; wrong next + A RRSIG ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 + A RRSIG ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + 6DFJITU5VML86QNKU9FO2LJDDQQTQPVT ; wrong next + NS ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + KElp8dLKBKFzgEFV8r5aP9pCyYUD+Z8rLBA9 + KkCDm1y82x5T/Cu5UXuZJwhvDGDzwPqoY5Dr + Qbiek52n6umbEw== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignatureD37X9Bw2 + 9JOkecZnmzCwBqfMCBvRYmNRpMd512+ZnW/I + 1vIViE7CGwkHyA== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DPwNyH7r/4wIBfTGxikNv4pY7omY6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + bGk1vLxVuJpcEy7n0gPvQVzfanbvINLJLcbD + eeie4sXZZAOwu6oQZy6kd8tvKtV4mL0OJzpH + XCO6BdZkmk/aQA== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + roe4aBp4G3TqQ4x5eRxbVIjApIh17gXDjfOY + zvRFLOkrwqKz3eX9WrRiCk3bYNn8s1fuenaQ + OSV1D5SL7utX5w== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + c1yhXb8wRGYndpVqG61+lHAAbZg+JcVYGPX3 + Fw0jYigN4G+P0+VUCqPLkC4yfJylzuefyGfk + TUmriM3ihfXxIg== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 31323 example.com. + mZiLLTzbdaj7EJ8uj3TwvcvAfaMxYjyavlGT + qpa+cElfvBDm7R6MF4MaEQ9aZ2ylMt1lppjq + YyYRaaQC6yhm4g== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160302125715 29600 example.com. + K3PkVYZZV8QvZFtDsz9+ZfiM9wDkFu/eO2S5 + tAtCXd1fktcW44TLWL0qADfFEEcMotvzLqv1 + YJrD7TvrFDot8Q== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + vlzRtVFa44pRtdD8XZcgDa6021uA9A3TnNEw + 5jRnor4aoftUuVQNAanQMCgrWk63d14XZ2d0 + lqhxunAbh08dsQ== ) + +www.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + NWFuYaSEg3z3K4l/fHu/X9dK+rDZ177BbCNN + ZeFTPCAdOnX0nw1CQys629k7Vzdv1pHaanmy + 0Ru0tX9R65NlKw== ) diff --git a/tests/knot/semantic_check_data/nsec3_ds.signed b/tests/knot/semantic_check_data/nsec3_ds.signed new file mode 100644 index 0000000..ad5da7c --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_ds.signed @@ -0,0 +1,57 @@ + + +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + 3600 IN DS 60485 5 2 ( 4EFB4310DB01A42E7882E102 + 7A73CC28E2E0FE938F2D5888 + A0DA0005B99E7FF8 ) +deleg.example.com. 3600 IN RRSIG DS 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 3600 IN NSEC3 1 0 10 - ( + 6DFJITU5VML86QNKU9FO2LJDDQQTQPVT + A RRSIG ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 3600 IN NSEC3 1 1 10 - ( + UI312KQOP1NG8IQEIEFNPSLA94KB5Q92 + A RRSIG ) +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 3600 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 3600 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +20g1gol477ro51rk9a9nfd54tfqal7iq.example.com. 3600 RRSIG NSEC3 13 3 3600 20400406101515 20210205084515 61806 example.com. k2hYD9qbLM8cRuN1fcLar/GsSufK/5oQYxRnE9bUDiKvC1WhCDF3pee6MSqybb3LoNkQUeOgGV4jdzvslzDlhQ== +6dfjitu5vml86qnku9fo2ljddqqtqpvt.example.com. 3600 RRSIG NSEC3 13 3 3600 20400406101515 20210205084515 61806 example.com. fGQRezo0T9Hd1tGJqhCXPyLONKSxOPmX1Kl7MjD1OVDLg9l5Ei9DmhrpCFxahXMBGIA4yy1J7mSK3PqelPMyFw== +ui312kqop1ng8iqeiefnpsla94kb5q92.example.com. 3600 RRSIG NSEC3 13 3 3600 20400406101515 20210205084515 61806 example.com. 6AmfjUgzO4Ew9FmW6koVhQ+98Vd7xI7kpFXwj8wb4ObmuM8uFu6tpvcT/jDcUduFuUb//DS5fS9fXraLNL8JUQ== +utqvuhu2blk3dhmrr5t1hd9vteohqt0a.example.com. 3600 RRSIG NSEC3 13 3 3600 20400406101515 20210205084515 61806 example.com. WMvFzIf9Ekvr0UVRzbZpxUAjT2Sf2KgsXek6iG786Iw6nZ/rzPVNlfNLhWvdqQmi5LEDp03UExshDlPz3JgOkQ== + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 NS dns1.example.com. + 0 NSEC3PARAM 1 0 10 - +dns1.example.com. 3600 IN A 192.0.2.1 +www.example.com. 3600 IN A 192.0.2.1 + +example.com. 3600 DNSKEY 257 3 13 Yk8KOmyVzOij3x+Zs+eT4J2Up9+ipwXEKOhL9fTYY/DU10yIQt+zYm02UFZJX2oVTdHBCajpBFsZLH2X4ho1yw== +example.com. 3600 DNSKEY 256 3 13 tCoteOM+A4o/A9uxgLyDg3HOg2DClU+3d+1XPQRtTfuaEFOGIpyH6qiFUv2b4DYuvmMyTkL99nxvyhA8yo0Cgg== +example.com. 3600 RRSIG DNSKEY 13 2 3600 20400405162736 20210204145736 25674 example.com. 5nIsRsT30KNhPS/i8rNhT/C3uPli0jb+7fLYL+eHKggTHk5UK69Z5EHA/ISKnbEOMIQA3QJ98XNreLJk+sTZ4w== + +example.com. 3600 RRSIG NS 13 2 3600 20400405162736 20210204145736 61806 example.com. nzKbYNX9cbrf3zNMSRK4ftG/p4DLn/uB3BM29txIj0nyKxL1cmK0wsTltGmwLzJTegBy/LV1VtMudDLWEFU3sQ== +example.com. 3600 RRSIG SOA 13 2 3600 20400405162736 20210204145736 61806 example.com. HvtxfzCSLHjFSHuAyO+KKymy/vxOGLS8T1DuhfAoUtweHv1zVeYfbFOfCdcfs15PKO31ldqwWRvFWAhM+3hnrA== +example.com. 0 RRSIG NSEC3PARAM 13 2 0 20400405162736 20210204145736 61806 example.com. 8uDKYTVd+XuYFyzf/aNm6kMjZhbI8r+22v1AuuYYqgP5aH6/ZFXusczSGkPdcauVIgKLV1I7dBBQkQm2LNIqAA== +deleg.example.com. 3600 RRSIG A 13 3 3600 20400405162736 20210204145736 61806 example.com. beD3O8cnCQ+8HWZpn35gFrR2tLkb9tGpe143BfUA0aOkAr2PdK9CUBs47uSyWAATYoa11gtxxdFUzW6coa7l/w== +deleg.example.com. 3600 RRSIG NS 13 3 3600 20400405162736 20210204145736 61806 example.com. HJCAXBevueFA2BOP6eOnsbP1X+2VUQRGXRcYI2SDqqq4U2DQHWQMOfI+pKVpkfdc8D6qDYnFZSg6II/dDJQ0AQ== +deleg.example.com. 3600 RRSIG DS 13 3 3600 20400405162736 20210204145736 61806 example.com. DhZsh6wiPACEUz7GY4WpvcIrMOF+sU27kJAGKaCcpxv9jQBY7Jpf/otRf+yn+Bmm32RZUr5swSXMXAvDtCj6qA== +dns1.example.com. 3600 RRSIG A 13 3 3600 20400405162736 20210204145736 61806 example.com. z/pEp4EcGkmy+niefZRLgRo1LraBlJABdgpSo94cYEqJM3GBMHsPZeAKmqnMAYA5Nz0hQtTplqS3rsJHJJdQ7w== +www.example.com. 3600 RRSIG A 13 3 3600 20400405162736 20210204145736 61806 example.com. FpOwodJYlk3NxEEjGvY75r8Ptef13P4Um9N74NxV1QWQlqtBhg+1bndvaY376uBFVDFGsEiDFEgIoFL0Ao+PeA== + + diff --git a/tests/knot/semantic_check_data/nsec3_missing.signed b/tests/knot/semantic_check_data/nsec3_missing.signed new file mode 100644 index 0000000..4974956 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_missing.signed @@ -0,0 +1,120 @@ + +; extra record without corresponding NSEC3 +extra.example.com. 3600 IN A 1.2.3.4 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature12345678 + 123456789123456789123456789123456789 + lqhxunAbh08dsQ== ) +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + 6DFJITU5VML86QNKU9FO2LJDDQQTQPVT + A RRSIG ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 + A RRSIG ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + UI312KQOP1NG8IQEIEFNPSLA94KB5Q92 + NS ) +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN A 1.2.3.4 +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG A 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DPwNyH7r/4wIBfTGxikNv4pY7omY6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + + +UI312KQOP1NG8IQEIEFNPSLA94KB5Q92.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignature4ey0Qcln + uquQZT+z2HIdCE9HeslAkTlu/Xt78vF4+3db + t2Vno21DkteA+w== ) +6DFJITU5VML86QNKU9FO2LJDDQQTQPVT.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + KElp8dLKBKFzgEFV8r5aP9pCyYUD+Z8rLBA9 + KkCDm1y82x5T/Cu5UXuZJwhvDGDzwPqoY5Dr + Qbiek52n6umbEw== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DummySignatureDummySignatureD37X9Bw2 + 9JOkecZnmzCwBqfMCBvRYmNRpMd512+ZnW/I + 1vIViE7CGwkHyA== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160302125715 29600 example.com. + DPwNyH7r/4wIBfTGxikNv4pY7omY6IqpQS6Q + jtTNuStA+5gk98dvcgRjluxqo/+ZlZz4V53f + 1y506ytGbX/q4Q== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + bGk1vLxVuJpcEy7n0gPvQVzfanbvINLJLcbD + eeie4sXZZAOwu6oQZy6kd8tvKtV4mL0OJzpH + XCO6BdZkmk/aQA== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + roe4aBp4G3TqQ4x5eRxbVIjApIh17gXDjfOY + zvRFLOkrwqKz3eX9WrRiCk3bYNn8s1fuenaQ + OSV1D5SL7utX5w== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 29600 example.com. + c1yhXb8wRGYndpVqG61+lHAAbZg+JcVYGPX3 + Fw0jYigN4G+P0+VUCqPLkC4yfJylzuefyGfk + TUmriM3ihfXxIg== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160302125715 31323 example.com. + mZiLLTzbdaj7EJ8uj3TwvcvAfaMxYjyavlGT + qpa+cElfvBDm7R6MF4MaEQ9aZ2ylMt1lppjq + YyYRaaQC6yhm4g== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160302125715 29600 example.com. + K3PkVYZZV8QvZFtDsz9+ZfiM9wDkFu/eO2S5 + tAtCXd1fktcW44TLWL0qADfFEEcMotvzLqv1 + YJrD7TvrFDot8Q== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 + +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + vlzRtVFa44pRtdD8XZcgDa6021uA9A3TnNEw + 5jRnor4aoftUuVQNAanQMCgrWk63d14XZ2d0 + lqhxunAbh08dsQ== ) + +www.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160302125715 29600 example.com. + NWFuYaSEg3z3K4l/fHu/X9dK+rDZ177BbCNN + ZeFTPCAdOnX0nw1CQys629k7Vzdv1pHaanmy + 0Ru0tX9R65NlKw== ) + + diff --git a/tests/knot/semantic_check_data/nsec3_optout.signed b/tests/knot/semantic_check_data/nsec3_optout.signed new file mode 100644 index 0000000..c9caa5d --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_optout.signed @@ -0,0 +1,81 @@ + +; insecure delegation, not covered by NSEC3 or opt-out +zzz.example.com. 3600 IN NS zzz.example.com. + 3600 A 192.0.2.1 + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + W9EprjaR4loSnNW96h4rLsquPDw3LHYvD05k + djkQofHSkMNZAJ7Q+eA3Fs2ik5fnJFM7wi5C + MtFsV2TfqMJFmg== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + I9Je1S7XhZIW9C0fWE8NwFLC2rhHklddNYBO + dxVKL/lxENU4jPPBwZBGrcYn2WVHgkIzjG0n + EOHONAgRFPi3Xw== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + vO2UQiTN/CNUZOmSEg8kJlR/UqiAZHc4qMwj + 9u31sbPmOMuni+ZGuVCFFoEMtZerIkkQowkB + sXJFkvCP5oF2rA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 31323 example.com. + Z+aaLu4rmzekfhlj6A0ClREloRi8MloRHf/3 + Dlw/RYY1hrOCfcZKEY6AXeVdUwESEsSkSOco + CbhyGHH10dKAAg== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160229083110 29600 example.com. + d69kc52VdALI8fbdbflsVsltc1m7bI6QsJ5U + IDE9fy5VqcufZecZMKuozPDuF2vBA8ADFIRU + OfYgKs6YNIOLWg== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938 + A RRSIG ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + D24JCtCcNzwsY1FXVliAjxMm+x95N2eUTXn0 + M8NK5glSk1yLtnAUKzHxpRExAJLGUiaG4yPu + 2yGZuqwNvJztzw== ) +MJV836RJQEJ5UBGHVKSQ7N44RSO3Q938.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + NS ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + jRNMrWLfS4yzRHQOBxs6/GKWIzx6AZV5lyCm + 7bYTV9wS3owDJSQhJ7lft0WbBmUMtV3tP9Xr + Yc+yW48p2Vr+QQ== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + F7y+xW/C7iICgmZeYrF4e7Yx4kWZAZPAMzlu + PtWVuf37ySg1VfEWcQcDP04vF2rXVUqSMEcj + bqUVN5W8Hoazxw== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160229083110 29600 example.com. + MoYrL/lToC4AHo6KCZRiBRmCMWHUAx2Xt32A + P4lDpwA+wiBWkCZSfVTh60AosS/BIGtBb2BK + mszMx8CLBvkjRg== ) diff --git a/tests/knot/semantic_check_data/nsec3_optout_ent.all b/tests/knot/semantic_check_data/nsec3_optout_ent.all new file mode 100644 index 0000000..5ebd917 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_optout_ent.all @@ -0,0 +1,15 @@ +example.com. 3600 SOA dns1.com. hostmaster.com. 2010111217 21600 3600 604800 86400 +example.com. 3600 NS dns1.com. +example.com. 3600 DNSKEY 256 3 13 tCoteOM+A4o/A9uxgLyDg3HOg2DClU+3d+1XPQRtTfuaEFOGIpyH6qiFUv2b4DYuvmMyTkL99nxvyhA8yo0Cgg== +example.com. 3600 DNSKEY 257 3 13 Yk8KOmyVzOij3x+Zs+eT4J2Up9+ipwXEKOhL9fTYY/DU10yIQt+zYm02UFZJX2oVTdHBCajpBFsZLH2X4ho1yw== +example.com. 0 NSEC3PARAM 1 0 10 151E9F1094FE188F +deleg1.ent.example.com. 3600 NS glue.outofzone.net. +deleg2.ent.example.com. 3600 NS glue.outofzone.net. + +example.com. 3600 RRSIG NS 13 2 3600 20400410173442 20210209160442 61806 example.com. laxHzto10anAyWXb/IqVEoBsybVmb/aCMb4SdxEC3YiJFj1IX9rxChVnuXrQ5zgr1f6YaRyc/DDTP8NFvwyTWg== +example.com. 3600 RRSIG SOA 13 2 3600 20400410173442 20210209160442 61806 example.com. /eNl2bkB/SJ6qBX+Jpm5KTXIs5Xi978JWRN2jtbEh5Z9udy7liS73oMkBLlJ33amKc7Gwfqi2+SgdHHud4j0Ug== +example.com. 3600 RRSIG DNSKEY 13 2 3600 20400410173442 20210209160442 25674 example.com. TpePckJM7GcsE72vbfSf49LzEM1chUFIiKBN0VyCHdB3YFpRH5d8Qx+XWh8Vs9AuLoKMWTQ0UD4kZK8yF70N4A== +example.com. 0 RRSIG NSEC3PARAM 13 2 0 20400410173442 20210209160442 61806 example.com. RfPCpoA94H+dm7fqxhZ+GIf4fQwzN19yJVbhmEOtx6if9U/H6mJalvoy4d5UD/L2bferTBbie4I/TzAIXgVETQ== + +ple28jlp3q5anh045ssk9f3u7ltd4qlc.example.com. 3600 NSEC3 1 1 10 151E9F1094FE188F ple28jlp3q5anh045ssk9f3u7ltd4qlc NS SOA RRSIG DNSKEY NSEC3PARAM +ple28jlp3q5anh045ssk9f3u7ltd4qlc.example.com. 3600 RRSIG NSEC3 13 3 3600 20400410181548 20210209164548 61806 example.com. EBPlHXYdARm1T0TaYadx0ETwC6w0g5J1yPR6LB3ur9IItcEWRONhqDrNwUbYGbW5c4nWep/hnJYdmMFq1bTfiw== diff --git a/tests/knot/semantic_check_data/nsec3_optout_ent.invalid b/tests/knot/semantic_check_data/nsec3_optout_ent.invalid new file mode 100644 index 0000000..114d5d7 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_optout_ent.invalid @@ -0,0 +1,18 @@ +example.com. 3600 SOA dns1.com. hostmaster.com. 2010111217 21600 3600 604800 86400 +example.com. 3600 NS dns1.com. +example.com. 3600 DNSKEY 256 3 13 tCoteOM+A4o/A9uxgLyDg3HOg2DClU+3d+1XPQRtTfuaEFOGIpyH6qiFUv2b4DYuvmMyTkL99nxvyhA8yo0Cgg== +example.com. 3600 DNSKEY 257 3 13 Yk8KOmyVzOij3x+Zs+eT4J2Up9+ipwXEKOhL9fTYY/DU10yIQt+zYm02UFZJX2oVTdHBCajpBFsZLH2X4ho1yw== +example.com. 0 NSEC3PARAM 1 0 10 151E9F1094FE188F +deleg1.ent.example.com. 3600 NS glue.outofzone.net. +deleg2.ent.example.com. 3600 NS glue.outofzone.net. + +example.com. 3600 RRSIG NS 13 2 3600 20400410173442 20210209160442 61806 example.com. laxHzto10anAyWXb/IqVEoBsybVmb/aCMb4SdxEC3YiJFj1IX9rxChVnuXrQ5zgr1f6YaRyc/DDTP8NFvwyTWg== +example.com. 3600 RRSIG SOA 13 2 3600 20400410173442 20210209160442 61806 example.com. /eNl2bkB/SJ6qBX+Jpm5KTXIs5Xi978JWRN2jtbEh5Z9udy7liS73oMkBLlJ33amKc7Gwfqi2+SgdHHud4j0Ug== +example.com. 3600 RRSIG DNSKEY 13 2 3600 20400410173442 20210209160442 25674 example.com. TpePckJM7GcsE72vbfSf49LzEM1chUFIiKBN0VyCHdB3YFpRH5d8Qx+XWh8Vs9AuLoKMWTQ0UD4kZK8yF70N4A== +example.com. 0 RRSIG NSEC3PARAM 13 2 0 20400410173442 20210209160442 61806 example.com. RfPCpoA94H+dm7fqxhZ+GIf4fQwzN19yJVbhmEOtx6if9U/H6mJalvoy4d5UD/L2bferTBbie4I/TzAIXgVETQ== + +gtr2v0c3d7eqh7ob8rbad7ta90tq8lci.example.com. 3600 NSEC3 1 1 10 151E9F1094FE188F ple28jlp3q5anh045ssk9f3u7ltd4qlc NS +ple28jlp3q5anh045ssk9f3u7ltd4qlc.example.com. 3600 NSEC3 1 1 10 151E9F1094FE188F gtr2v0c3d7eqh7ob8rbad7ta90tq8lci NS SOA RRSIG DNSKEY NSEC3PARAM + +gtr2v0c3d7eqh7ob8rbad7ta90tq8lci.example.com. 3600 RRSIG NSEC3 13 3 3600 20400410173442 20210209160442 61806 example.com. gb3uKByt54iwCsd284xzOVnnpN97r7ARz6UacMdm2Xs4M8t6Ao9bRG7jvbNpFCALfaU/xDQF7K3v31iKBeVwjw== +ple28jlp3q5anh045ssk9f3u7ltd4qlc.example.com. 3600 RRSIG NSEC3 13 3 3600 20400410173442 20210209160442 61806 example.com. kpuFRuzOhsG5zy0Sdql0AB44IDUtf9ccTwJXdULoIqUNKeRqvgWJ7ekEhBKvntVHlBQZPescgPMvvq7PLcA2Dw== diff --git a/tests/knot/semantic_check_data/nsec3_optout_ent.valid b/tests/knot/semantic_check_data/nsec3_optout_ent.valid new file mode 100644 index 0000000..c9fe657 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_optout_ent.valid @@ -0,0 +1,20 @@ +example.com. 3600 SOA dns1.com. hostmaster.com. 2010111217 21600 3600 604800 86400 +example.com. 3600 NS dns1.com. +example.com. 3600 DNSKEY 256 3 13 tCoteOM+A4o/A9uxgLyDg3HOg2DClU+3d+1XPQRtTfuaEFOGIpyH6qiFUv2b4DYuvmMyTkL99nxvyhA8yo0Cgg== +example.com. 3600 DNSKEY 257 3 13 Yk8KOmyVzOij3x+Zs+eT4J2Up9+ipwXEKOhL9fTYY/DU10yIQt+zYm02UFZJX2oVTdHBCajpBFsZLH2X4ho1yw== +example.com. 0 NSEC3PARAM 1 0 10 151E9F1094FE188F +deleg1.ent.example.com. 3600 NS glue.outofzone.net. +deleg2.ent.example.com. 3600 NS glue.outofzone.net. + +example.com. 3600 RRSIG NS 13 2 3600 20400410173236 20210209160236 61806 example.com. C4ierSNpy03xjH5rQEfb01wCj4SVIzX9b15FVEMIbn3lmDo5jXO6stOrW8Z7OjoVuCaRi1Qj997TeCYqOxNXSQ== +example.com. 3600 RRSIG SOA 13 2 3600 20400410173236 20210209160236 61806 example.com. NNyQzYOcPbfEsqv61I78MuMguN/KIFi/wSJc940pj7rv+riA3J+XVzpaHSSh//q8CmrvpBAk2g8KsQG/6kOXmg== +example.com. 3600 RRSIG DNSKEY 13 2 3600 20400410173236 20210209160236 25674 example.com. ZY3nxZJeOfSOEhs02mfhQgt6N1EgZubtPp3HuV69gStFSu4aCLi8a2aseQGilOFW64dOAYNm3LL/WqhPi7MZ1Q== +example.com. 0 RRSIG NSEC3PARAM 13 2 0 20400410173236 20210209160236 61806 example.com. JITs/EH8nLaFRidlkT6+mcTwEpjgp2TMjb9fU5TBIlKn94og8YtOWFbNmzdEYBKlGLlkg8LwY2ortrSoRHS6Hw== + +ej69a9a2k2j0ntktmdvihrv5ao8fl1jt.example.com. 3600 NSEC3 1 1 10 151E9F1094FE188F gtr2v0c3d7eqh7ob8rbad7ta90tq8lci +gtr2v0c3d7eqh7ob8rbad7ta90tq8lci.example.com. 3600 NSEC3 1 1 10 151E9F1094FE188F ple28jlp3q5anh045ssk9f3u7ltd4qlc NS +ple28jlp3q5anh045ssk9f3u7ltd4qlc.example.com. 3600 NSEC3 1 1 10 151E9F1094FE188F ej69a9a2k2j0ntktmdvihrv5ao8fl1jt NS SOA RRSIG DNSKEY NSEC3PARAM + +ej69a9a2k2j0ntktmdvihrv5ao8fl1jt.example.com. 3600 RRSIG NSEC3 13 3 3600 20400410173236 20210209160236 61806 example.com. yatL/lbFSUyN4UyRtMXymxsiqhOXHp+N+pTI/zNOc0NXCdaaLceh+tZHlc+E4napRfP53XXEhuGavjShTIJ/+g== +gtr2v0c3d7eqh7ob8rbad7ta90tq8lci.example.com. 3600 RRSIG NSEC3 13 3 3600 20400410173236 20210209160236 61806 example.com. 20XNZrfJ4l/JIDjCbsba3mUOrNyOxJ2VuCju/yLc0XbdzqMcKJR87g3u967GEnoYY5f5+rJt/IHsuJWHcLApCQ== +ple28jlp3q5anh045ssk9f3u7ltd4qlc.example.com. 3600 RRSIG NSEC3 13 3 3600 20400410173236 20210209160236 61806 example.com. eLRo9y8Rxf157qcciWM/LSUbtjYks2zLO5xQ9Ff5bidHc9m2XEqjWxqdPZz5gurEf+uPnM8mnix36X4YH4ZXwg== diff --git a/tests/knot/semantic_check_data/nsec3_param_invalid.signed b/tests/knot/semantic_check_data/nsec3_param_invalid.signed new file mode 100644 index 0000000..c7d8d6d --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_param_invalid.signed @@ -0,0 +1,70 @@ +; Zone without any semantic error + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + W9EprjaR4loSnNW96h4rLsquPDw3LHYvD05k + djkQofHSkMNZAJ7Q+eA3Fs2ik5fnJFM7wi5C + MtFsV2TfqMJFmg== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + I9Je1S7XhZIW9C0fWE8NwFLC2rhHklddNYBO + dxVKL/lxENU4jPPBwZBGrcYn2WVHgkIzjG0n + EOHONAgRFPi3Xw== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 29600 example.com. + vO2UQiTN/CNUZOmSEg8kJlR/UqiAZHc4qMwj + 9u31sbPmOMuni+ZGuVCFFoEMtZerIkkQowkB + sXJFkvCP5oF2rA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160229083110 31323 example.com. + Z+aaLu4rmzekfhlj6A0ClREloRi8MloRHf/3 + Dlw/RYY1hrOCfcZKEY6AXeVdUwESEsSkSOco + CbhyGHH10dKAAg== ) + 0 NSEC3PARAM 1 4 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160229083110 29600 example.com. + d69kc52VdALI8fbdbflsVsltc1m7bI6QsJ5U + IDE9fy5VqcufZecZMKuozPDuF2vBA8ADFIRU + OfYgKs6YNIOLWg== ) +deleg.example.com. 3600 IN NS deleg.example.com. + 3600 A 192.0.2.1 +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 1 15 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + D24JCtCcNzwsY1FXVliAjxMm+x95N2eUTXn0 + M8NK5glSk1yLtnAUKzHxpRExAJLGUiaG4yPu + 2yGZuqwNvJztzw== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 4 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) + 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160229083110 29600 example.com. + F7y+xW/C7iICgmZeYrF4e7Yx4kWZAZPAMzlu + PtWVuf37ySg1VfEWcQcDP04vF2rXVUqSMEcj + bqUVN5W8Hoazxw== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160229083110 29600 example.com. + MoYrL/lToC4AHo6KCZRiBRmCMWHUAx2Xt32A + P4lDpwA+wiBWkCZSfVTh60AosS/BIGtBb2BK + mszMx8CLBvkjRg== ) diff --git a/tests/knot/semantic_check_data/nsec3_wrong_bitmap_01.signed b/tests/knot/semantic_check_data/nsec3_wrong_bitmap_01.signed new file mode 100644 index 0000000..a3024d8 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_wrong_bitmap_01.signed @@ -0,0 +1,70 @@ +; example.com -- missing DNSKEY in type bitmap +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG NSEC3PARAM ) +; dns1.example.com +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + li23VC44fumpMHhKwWug2J1C2fwCMiwgofYO + DKydNYsJyYTlyi8ezLJ2KoBlCtOc4Fp0NbqS + aN8CKWh7fQVnkQ== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + Y8olY2OClZgC+QHnOhY52LONVOcctOnl8jNY + /c7sCHZO4TdPPDHDhpbVntQD+Vc4fUTx+cXY + GrF5sLbhddBJXg== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + fx2rZzhyYrp1b4tNH1SmM852VbGEeZdKrD+f + ZoInny1m8sovb1J9ORtVbGkOYOnInDMLWMCX + fghHC2MafuFV+Q== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160225083237 31323 example.com. + TcNU6AlrYhJLrNlkfOPJzO6A77j6C39IPoP4 + OfmY2ClA5Vx2JO0vQ4bIHR7GIW8fiMe6M6tt + ZwQImhVWdG414A== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160225083237 29600 example.com. + iY0WB0dN1hQXoctaMwvvXzn7paQt5xUyucT3 + xwo6HAI8Y+OJlecUfOpkkQ9lqIfsqPTXmgbY + RieoZGrWR6ZvaQ== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160225083237 29600 example.com. + QptUkTNS7umNQ5V6Z9DyGl6z+rG7G3TFmHG8 + p9HGaKifSxjwSFW0nZ9/s86XHQ8ql5+bQmPa + xw39ntBmQLVxfg== ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160225083237 29600 example.com. + CPx6000z5m1zUUpVhki1u9U7P/WMr7PUJAk3 + G0w3v+/Lw56mDzYzNuTpPzS0noe0LKuecqRu + m99KpLyLOx+9QA== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160225083237 29600 example.com. + m2z+hx+8hTA7Phu6QzGJrq+o4MiURpda3fYm + 0wTDmXtfPKsHmojGr3kBlvUMg16s2gpvNyCL + MSlnJ+7KCkI+Mw== ) diff --git a/tests/knot/semantic_check_data/nsec3_wrong_bitmap_02.signed b/tests/knot/semantic_check_data/nsec3_wrong_bitmap_02.signed new file mode 100644 index 0000000..e3e4940 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec3_wrong_bitmap_02.signed @@ -0,0 +1,70 @@ +; example.com +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 IN NSEC3 1 0 10 - ( + 20G1GOL477RO51RK9A9NFD54TFQAL7IQ + NS SOA RRSIG DNSKEY NSEC3PARAM ) +; dns1.example.com -- extra type in bitmap - NSEC +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 IN NSEC3 1 0 10 - ( + UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A + A RRSIG NSEC) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + li23VC44fumpMHhKwWug2J1C2fwCMiwgofYO + DKydNYsJyYTlyi8ezLJ2KoBlCtOc4Fp0NbqS + aN8CKWh7fQVnkQ== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + Y8olY2OClZgC+QHnOhY52LONVOcctOnl8jNY + /c7sCHZO4TdPPDHDhpbVntQD+Vc4fUTx+cXY + GrF5sLbhddBJXg== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160225083237 29600 example.com. + fx2rZzhyYrp1b4tNH1SmM852VbGEeZdKrD+f + ZoInny1m8sovb1J9ORtVbGkOYOnInDMLWMCX + fghHC2MafuFV+Q== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160225083237 31323 example.com. + TcNU6AlrYhJLrNlkfOPJzO6A77j6C39IPoP4 + OfmY2ClA5Vx2JO0vQ4bIHR7GIW8fiMe6M6tt + ZwQImhVWdG414A== ) + 0 NSEC3PARAM 1 0 10 - + 0 RRSIG NSEC3PARAM 7 2 0 ( + 20840201000000 20160225083237 29600 example.com. + iY0WB0dN1hQXoctaMwvvXzn7paQt5xUyucT3 + xwo6HAI8Y+OJlecUfOpkkQ9lqIfsqPTXmgbY + RieoZGrWR6ZvaQ== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160225083237 29600 example.com. + QptUkTNS7umNQ5V6Z9DyGl6z+rG7G3TFmHG8 + p9HGaKifSxjwSFW0nZ9/s86XHQ8ql5+bQmPa + xw39ntBmQLVxfg== ) + +20G1GOL477RO51RK9A9NFD54TFQAL7IQ.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160225083237 29600 example.com. + CPx6000z5m1zUUpVhki1u9U7P/WMr7PUJAk3 + G0w3v+/Lw56mDzYzNuTpPzS0noe0LKuecqRu + m99KpLyLOx+9QA== ) +UTQVUHU2BLK3DHMRR5T1HD9VTEOHQT0A.example.com. 86400 RRSIG NSEC3 7 3 86400 ( + 20840201000000 20160225083237 29600 example.com. + m2z+hx+8hTA7Phu6QzGJrq+o4MiURpda3fYm + 0wTDmXtfPKsHmojGr3kBlvUMg16s2gpvNyCL + MSlnJ+7KCkI+Mw== ) diff --git a/tests/knot/semantic_check_data/nsec_broken_chain_01.signed b/tests/knot/semantic_check_data/nsec_broken_chain_01.signed new file mode 100644 index 0000000..cb41dce --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_broken_chain_01.signed @@ -0,0 +1,72 @@ +; not coherent NSEC chain +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC example.com. A RRSIG NSEC +www.example.com. 86400 NSEC example.com. A RRSIG NSEC + +; signatures for NSECs +example.com. 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224082919 29600 example.com. + FHLUUQTvnVboNzGoQVLpwQAcB+fUEF5xQqMQ + oKhE86sdvlQUiEfUpv2PJ9y3YfXHeYxJUtvm + cY14UkYqsdP3fA== ) +dns1.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + FDPJTLixRBZtMFLqk5wfYTSLnLMZiLtN7uTA + COEqyphK33oW+7XJzfG6ADvwGewY4hTCPQkk + cEg+DBI7qZ88NA== ) +www.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + FDPJTLixRBZtMFLqk5wfYTSLnLMZiLtN7uTA + COEqyphK33oW+7XJzfG6ADvwGewY4hTCPQkk + cEg+DBI7qZ88NA== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + xJIoENJ4d24FIVd9ZSGpQlcWN4zuriU90r/H + +ufcM2qtWcOGR1M1LVNIAWEVJEcD2dBGA2w1 + B7Cx+BILQRev8w== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + vBffD+/kBuxUHfeXKYBVYxeMIbuW5f8BstRM + XJnC1GTGfdNvb8NknHuv5fEytBmnnpH6f9pC + iWLeZzFR1+aJBA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + LMyY8+vWsFB7CziWt8rnR5jfg4Loe/xzy4TQ + /ITEDbz5pkoadG+0mqTHQ0F5XCe6ZJPamcyr + kcMw0GqUzOVb9w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 31323 example.com. + tpHcGRuIkul47hHXVpNAOL48c5YYMsaIJkFE + rlQi9wU4TCiukdJkLuPk7ykk9XrxbiCB/FwD + o63Vcqyy3gZfvA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + HlfZThngg+1xglDUh8kjDtzVn5D5a9T3emMt + Uxfryu9va7bj+xoK4gLADGau69GCZxJNSvwK + TAGEqGRYFSY9Ew== ) +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + FLR8e2k6u7dhQA1xZ3YMxkvuktoydXC+ZNwl + xzW9hLpF3oKoqqY/V+kw7m2OMgnOEu2jWN4Q + EETdmMeQzkiuNw== ) diff --git a/tests/knot/semantic_check_data/nsec_broken_chain_02.signed b/tests/knot/semantic_check_data/nsec_broken_chain_02.signed new file mode 100644 index 0000000..5c5f004 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_broken_chain_02.signed @@ -0,0 +1,65 @@ +; not coherent NSEC chain +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC www.example.com. A RRSIG NSEC +www.example.com. 86400 NSEC www.example.com. A RRSIG NSEC + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201008171141 31772 example.com. + Qwf3qgLbSvE4PmUVU8rpIASe0v1T1K0ie3Lw + g+6o3tpBS8vWcmHMUiKns/6rAvoum7vHQRmO + dH7X3Pp1/X3xCw== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201008171141 31772 example.com. + 92/D4j7CUCKkykxMzdjfJoaNrMwO93OQtZlB + APsfcEyYl+W0sSnow/2RgYvKfX+kdcmp5VXD + vQxTGC0VqdMwCQ== ) + 86400 RRSIG NSEC 13 2 86400 ( + 20601231235959 20201008171141 31772 example.com. + shdsucYBfD8/zV1h1QgUBiC7VgYdFxFEcF1k + FQfY+UHkfD/AyOkiFPQxysimgzqJn2/z5Q+v + GT1CzzzemgzoXw== ) + 3600 DNSKEY 256 3 13 ( + /4RnFpCmaYIIrL/zP1T6LvfhXdpun0ZyYDKL + ho0zuUD+RMDe31IQCzr9AuSn1BAIQWIunxFs + EaTSlvpiUd+CAg== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 31772 + 3600 DNSKEY 257 3 13 ( + /KEwa6qUWHdkpEMGX55UaIvl7do5l2IADCDq + iNnawoCLu7Tm4MU6ylzYS1htz1mTd8Zcuzl0 + gkRe4FXwOmOzvQ== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 14119 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201008171141 14119 example.com. + FPftK2atu4GMOspSR24p5iIvmq2VKgPJMUTu + 5RiwflEf8UgD7s2WFe7A6/JLurwEhqa/313T + eEURk7m313h4jQ== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201008171141 31772 example.com. + +Xvcx4bZ536B8DtNwzurqmPPoDVdtS5nlRhQ + pMZ+OLsHECDnFaI50dSw4F1/c3DERz1ktM0+ + QCC96MZ7QdAYQw== ) + 86400 RRSIG NSEC 13 3 86400 ( + 20601231235959 20201008171141 31772 example.com. + 64MPHHZG8wrbAtk+LY/5ISicI1vU7V19q9lF + wOm0mcpvoBERyDwadgZpmHsvin1sRt/LZYDr + iBKxcnaviHfULg== ) +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201008171141 31772 example.com. + +/+14BFYf5Iq9IIeX1Oz5XqxsaPaw3T6PTPH + neJz6N9QhnI6aKkGZFYBuqY0Zhmcr52zbhPi + 1yZAUTP7OvouhA== ) + 86400 RRSIG NSEC 13 3 86400 ( + 20601231235959 20201008171141 31772 example.com. + fPqL9hFml35JLmfX3MA32hMnMhh9UA1Mc2OZ + nY+0j4wTtVR0PVMWHOv9UaULzTCM+5mlpFXm + nRUMj8sMTGzFzw== ) diff --git a/tests/knot/semantic_check_data/nsec_missing.signed b/tests/knot/semantic_check_data/nsec_missing.signed new file mode 100644 index 0000000..e901607 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_missing.signed @@ -0,0 +1,67 @@ +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC example.com. A RRSIG NSEC +; missing NSEC for www.example.com. + +; signatures for NSECs +example.com. 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224082919 29600 example.com. + FHLUUQTvnVboNzGoQVLpwQAcB+fUEF5xQqMQ + oKhE86sdvlQUiEfUpv2PJ9y3YfXHeYxJUtvm + cY14UkYqsdP3fA== ) +dns1.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + GF3mqBf6Ny481XSbEor1uTzQZtT2DSA/3jU2 + ZcLXXhlmHG3nI/PB49lG+17O83rDrbhcYc8G + cHEbLIGNr/6+Mw== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + xJIoENJ4d24FIVd9ZSGpQlcWN4zuriU90r/H + +ufcM2qtWcOGR1M1LVNIAWEVJEcD2dBGA2w1 + B7Cx+BILQRev8w== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + vBffD+/kBuxUHfeXKYBVYxeMIbuW5f8BstRM + XJnC1GTGfdNvb8NknHuv5fEytBmnnpH6f9pC + iWLeZzFR1+aJBA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + LMyY8+vWsFB7CziWt8rnR5jfg4Loe/xzy4TQ + /ITEDbz5pkoadG+0mqTHQ0F5XCe6ZJPamcyr + kcMw0GqUzOVb9w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 31323 example.com. + tpHcGRuIkul47hHXVpNAOL48c5YYMsaIJkFE + rlQi9wU4TCiukdJkLuPk7ykk9XrxbiCB/FwD + o63Vcqyy3gZfvA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + HlfZThngg+1xglDUh8kjDtzVn5D5a9T3emMt + Uxfryu9va7bj+xoK4gLADGau69GCZxJNSvwK + TAGEqGRYFSY9Ew== ) + +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + FLR8e2k6u7dhQA1xZ3YMxkvuktoydXC+ZNwl + xzW9hLpF3oKoqqY/V+kw7m2OMgnOEu2jWN4Q + EETdmMeQzkiuNw== ) diff --git a/tests/knot/semantic_check_data/nsec_multiple.signed b/tests/knot/semantic_check_data/nsec_multiple.signed new file mode 100644 index 0000000..0cd6aec --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_multiple.signed @@ -0,0 +1,66 @@ +; not coherent NSEC chain +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC www.example.com. A RRSIG NSEC +www.example.com. 86400 NSEC example.com. A RRSIG NSEC +www.example.com. 86400 NSEC www.example.com. A RRSIG NSEC + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201008170543 19445 example.com. + dEcgYVtA8cRE8ErOZGO/aaMat99+KuJdKoDc + 0+8fauQ3dcTUHVg2I+v4hdizjlmAJzGXJN+7 + 6ssZgcvXCnWOsQ== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201008170543 19445 example.com. + 2OEk6Lpt+1c58vnCEHBrV7//7gyoo1bGJSHo + k+oWaF9Uh07XVkVWznq6mmCErqukUPLnW1Bn + rysjk4i5Yflqkg== ) + 86400 RRSIG NSEC 13 2 86400 ( + 20601231235959 20201008170543 19445 example.com. + icB72dzHg9d9klcTL/mW53mGIX6KzF0GLWUt + DKLCcu2Ailyp3kdM64dyJxRYTr7F7KfxyHi4 + 3KJtphYNEA6ZWA== ) + 3600 DNSKEY 256 3 13 ( + H1roLYze5AZ+ouWMduBJtoJ8N5BPFdF3n6Pv + +Nfw5bNHUtCzgvMhmtX2gcRlmZ70Ycv1C/U+ + mCvLWVdfJm08lA== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 19445 + 3600 DNSKEY 257 3 13 ( + MSWkrHjEr7zi143oQdRthBBzl70MXeILunB7 + 8j55a5a9+Q39YKaIiRM4zyCV6WTXpm9H6eOS + RRgdQqGNL1gsKQ== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 23836 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201008170543 23836 example.com. + ejlk2L0CVBWuAxr1g+qivdvyIXqzp3+9U0tu + a2geLUtaVx8ErYnIvUug15S54g75+lZoZ1uK + l2WFWuy751kIsw== ) +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201008170543 19445 example.com. + 8k4wk4+kCs1kO3+8sL6zZdpkHw0U58oua/Ur + C8CHo6TjlLx/jRrLdQKcFy5H7gBMcJY76SDs + mT91HuWH+BpwNA== ) + 86400 RRSIG NSEC 13 3 86400 ( + 20601231235959 20201008170543 19445 example.com. + 3XbwYx32/Y8sLtQ+dW1lg+s1eaOSZlmkdJeO + IsLOAF6U9kq/2zrUTYCtFBMfqs5yYDEISK6X + W5UfBBdFRdYzgw== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 13 3 3600 ( + 20601231235959 20201008170543 19445 example.com. + DDTolVJ5Mxfm8srRVi/SRu0+5y3OBTQCVFuQ + ywdv4IahQoE11pjXRCBUXvroTeDgoHrmD7PD + b1aIBxHLiC/2pg== ) + 86400 RRSIG NSEC 13 3 86400 ( + 20601231235959 20201008170543 19445 example.com. + DDhuGYMEij4vbJZlscX3os8qj/wgq55w63jc + 8mPr/LquDr6o6lrEYdcnZl4Rz22snnF2+po1 + 3SEjRSJ0ROmTbw== ) diff --git a/tests/knot/semantic_check_data/nsec_wrong_bitmap_01.signed b/tests/knot/semantic_check_data/nsec_wrong_bitmap_01.signed new file mode 100644 index 0000000..058a0a3 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_wrong_bitmap_01.signed @@ -0,0 +1,73 @@ +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC www.example.com. A RRSIG NSEC + +; extra AAAA type in NSEC bitmap +www.example.com. 86400 NSEC example.com. A RRSIG NSEC AAAA +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + FLR8e2k6u7dhQA1xZ3YMxkvuktoydXC+ZNwl + xzW9hLpF3oKoqqY/V+kw7m2OMgnOEu2jWN4Q + EETdmMeQzkiuNw== ) + +; signatures for NSECs +example.com. 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224082919 29600 example.com. + FHLUUQTvnVboNzGoQVLpwQAcB+fUEF5xQqMQ + oKhE86sdvlQUiEfUpv2PJ9y3YfXHeYxJUtvm + cY14UkYqsdP3fA== ) +dns1.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + GF3mqBf6Ny481XSbEor1uTzQZtT2DSA/3jU2 + ZcLXXhlmHG3nI/PB49lG+17O83rDrbhcYc8G + cHEbLIGNr/6+Mw== ) +www.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + FDPJTLixRBZtMFLqk5wfYTSLnLMZiLtN7uTA + COEqyphK33oW+7XJzfG6ADvwGewY4hTCPQkk + cEg+DBI7qZ88NA== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + xJIoENJ4d24FIVd9ZSGpQlcWN4zuriU90r/H + +ufcM2qtWcOGR1M1LVNIAWEVJEcD2dBGA2w1 + B7Cx+BILQRev8w== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + vBffD+/kBuxUHfeXKYBVYxeMIbuW5f8BstRM + XJnC1GTGfdNvb8NknHuv5fEytBmnnpH6f9pC + iWLeZzFR1+aJBA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + LMyY8+vWsFB7CziWt8rnR5jfg4Loe/xzy4TQ + /ITEDbz5pkoadG+0mqTHQ0F5XCe6ZJPamcyr + kcMw0GqUzOVb9w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 31323 example.com. + tpHcGRuIkul47hHXVpNAOL48c5YYMsaIJkFE + rlQi9wU4TCiukdJkLuPk7ykk9XrxbiCB/FwD + o63Vcqyy3gZfvA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + HlfZThngg+1xglDUh8kjDtzVn5D5a9T3emMt + Uxfryu9va7bj+xoK4gLADGau69GCZxJNSvwK + TAGEqGRYFSY9Ew== ) diff --git a/tests/knot/semantic_check_data/nsec_wrong_bitmap_02.signed b/tests/knot/semantic_check_data/nsec_wrong_bitmap_02.signed new file mode 100644 index 0000000..dafdc92 --- /dev/null +++ b/tests/knot/semantic_check_data/nsec_wrong_bitmap_02.signed @@ -0,0 +1,73 @@ +example.com. 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY +dns1.example.com. 86400 NSEC www.example.com. A RRSIG NSEC + +; missing A type in NSEC bitmap +www.example.com. 86400 NSEC example.com. RRSIG NSEC +www.example.com. 3600 IN A 192.0.2.2 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + FLR8e2k6u7dhQA1xZ3YMxkvuktoydXC+ZNwl + xzW9hLpF3oKoqqY/V+kw7m2OMgnOEu2jWN4Q + EETdmMeQzkiuNw== ) + +; signatures for NSECs +example.com. 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160224082919 29600 example.com. + FHLUUQTvnVboNzGoQVLpwQAcB+fUEF5xQqMQ + oKhE86sdvlQUiEfUpv2PJ9y3YfXHeYxJUtvm + cY14UkYqsdP3fA== ) +dns1.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + GF3mqBf6Ny481XSbEor1uTzQZtT2DSA/3jU2 + ZcLXXhlmHG3nI/PB49lG+17O83rDrbhcYc8G + cHEbLIGNr/6+Mw== ) +www.example.com. 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160224082919 29600 example.com. + FDPJTLixRBZtMFLqk5wfYTSLnLMZiLtN7uTA + COEqyphK33oW+7XJzfG6ADvwGewY4hTCPQkk + cEg+DBI7qZ88NA== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + xJIoENJ4d24FIVd9ZSGpQlcWN4zuriU90r/H + +ufcM2qtWcOGR1M1LVNIAWEVJEcD2dBGA2w1 + B7Cx+BILQRev8w== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + vBffD+/kBuxUHfeXKYBVYxeMIbuW5f8BstRM + XJnC1GTGfdNvb8NknHuv5fEytBmnnpH6f9pC + iWLeZzFR1+aJBA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 29600 example.com. + LMyY8+vWsFB7CziWt8rnR5jfg4Loe/xzy4TQ + /ITEDbz5pkoadG+0mqTHQ0F5XCe6ZJPamcyr + kcMw0GqUzOVb9w== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160224082919 31323 example.com. + tpHcGRuIkul47hHXVpNAOL48c5YYMsaIJkFE + rlQi9wU4TCiukdJkLuPk7ykk9XrxbiCB/FwD + o63Vcqyy3gZfvA== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160224082919 29600 example.com. + HlfZThngg+1xglDUh8kjDtzVn5D5a9T3emMt + Uxfryu9va7bj+xoK4gLADGau69GCZxJNSvwK + TAGEqGRYFSY9Ew== ) diff --git a/tests/knot/semantic_check_data/rrsig_rdata_ttl.signed b/tests/knot/semantic_check_data/rrsig_rdata_ttl.signed new file mode 100644 index 0000000..28b118c --- /dev/null +++ b/tests/knot/semantic_check_data/rrsig_rdata_ttl.signed @@ -0,0 +1,52 @@ +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201008172615 16105 example.com. + UkbSKt1soIfnM7ZkNAfOcS4D3eHBzMQOef1d + bFK+ne+MtJsKEGM9brUD23v0f0CdvteVkeNS + 2oRrfrb3avZ08A== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201008172615 16105 example.com. + Mu/BsXIC10V5uRFUGR42/ntmT5eYt4192AQe + a5zdWnLo7A3GYHlPcOcZRMdqvsa3SAPOK2Br + UmFkHsWTawhWJQ== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 13 2 86400 ( + 20601231235959 20201008172615 16105 example.com. + IexJzu8x2GxGzGrWlceYZmUbry2D+E67py6B + /7j2K5IPjNQVGKbItfvqjQTUm+eVrdcwFbyK + iiEuVeU7qG5hIw== ) + 3600 DNSKEY 256 3 13 ( + tGxruia7b3JYm32MDdFLYX1M1e44DQJmXpVM + EWDjcNulSNY5sWR/zgDzhqiQSKEKCFolwhB/ + MFVIF71WNjE65Q== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 16105 + 3600 DNSKEY 257 3 13 ( + 24gAMJg6uXIBEdWkrAXmwP6znng79lTelLDg + WxeHbXriSxVPLSTYxrp7SO1FUi2N03v1RXcn + 5jONJdQYlxLtSg== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 17031 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201008172615 17031 example.com. + Tm4MkXCDkavltvRYnEp/enJzzjyjX3EgI8yY + OF2VuJY8uQHD0/uzZF3JTmXj7pkGShAUpFKI + Uzn5e3jrGqtMGA== ) +dns1.example.com. 3600 IN A 192.0.2.1 +; wrong RRSIG original-ttl + 3600 RRSIG A 13 3 600 ( + 20601231235959 20201008172615 16105 example.com. + 7J01Zyly+ky0F94kfaDtERQDVyxhHexzqETa + qgsemJkH0pP9FKsEY/dTkeZUwCY4EFZeps7C + AOKyGTKdqR5N7Q== ) + 86400 NSEC example.com. A RRSIG NSEC + 86400 RRSIG NSEC 13 3 86400 ( + 20601231235959 20201008172615 16105 example.com. + 0evb+3+rXrrx0f8Za//w6q2acUZPvYbW+Ezj + BoJFvwBYHrhyiiVHlfUzmr/jJh9cTEdxPnL3 + ow6ZUsfF0HJ4hg== ) diff --git a/tests/knot/semantic_check_data/rrsig_signed.signed b/tests/knot/semantic_check_data/rrsig_signed.signed new file mode 100644 index 0000000..2798026 --- /dev/null +++ b/tests/knot/semantic_check_data/rrsig_signed.signed @@ -0,0 +1,62 @@ +dns1.example.com. 86400 RRSIG RRSIG 7 3 86400 ( + 20840201000000 20160201000000 29600 example.com. + DummySignatureDEADBEEF8ijooV1IMfEtki + kLbaIvFcgZbPvTnXXHyesHO2OPiRsc7zF576 + Z6prBT8CkMM7bw== ) + +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + kINKkWiBvb9Dpb0vghlLhXyObSzsYYNsOqe9 + pWJN4lI4F2O3T6biPTQPsq3mYMR+6x9gPr6v + ysEPHlGtLdTLag== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + LkagMndC+wJGlQycPDvNmCZ0/QuBB7Zo4UVZ + He5jzQrE3Hnq8tn+/QfJ/yn62qCZ87DETwTT + rGaLqOTYRb1isg== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 7 2 86400 ( + 20840201000000 20160201000000 29600 example.com. + YDJ1tQvNlv8Y7cGioq8nkbaETx7wmyJKqa0B + 8hDLClYA4nf9UtyVXqZCISa2PlgRdBc5GEEh + U5BuLr4wYXqEFA== ) + 3600 DNSKEY 256 3 7 ( + AwEAAcvvW/oJAjcRdntRC8J52baXoNFVWOFz + oVFe3Vgl8aBBiGh3gnbuNt7xKmy9z2qc2/35 + MFwieWYfDdgUnPxyKMM= + ) ; ZSK; alg = NSEC3RSASHA1; key id = 29600 + 3600 DNSKEY 257 3 7 ( + AwEAAeXCF7sHLcFiaCwCFH4xh2CJcCp55i04 + exG41EtzILS2waabEM5byhRkoylbv91q6HY+ + JH9YXitS21LMD0Hqp1s= + ) ; KSK; alg = NSEC3RSASHA1; key id = 31323 + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160201000000 29600 example.com. + FPOm8y3e09jh0fv0ZaOecWbdIXDAoERVKdjz + qsg1Etop1n6nDhO/lW3pwOUe02Zq2vretu2W + DozlDr5E6ZoqPA== ) + 3600 RRSIG DNSKEY 7 2 3600 ( + 20840201000000 20160201000000 31323 example.com. + cZTevjvA8UO9Tqet/pbsN0Peep6aN8heyxMK + XP/Twsj4u0DeClKeIN7pd7Gi7Aac/UV2dev/ + x/90SM22VQVpeQ== ) +dns1.example.com. 3600 IN A 192.0.2.1 + 3600 RRSIG A 7 3 3600 ( + 20840201000000 20160201000000 29600 example.com. + f24sVhH1P/0mEMYTMbFLrWmJtl6kqZF6yzaS + TcyK6JhVM4sDT//YnjizJGsTVGSCelz3FxMj + LdiUm9AD05uY6A== ) + 86400 NSEC example.com. A RRSIG NSEC + 86400 RRSIG NSEC 7 3 86400 ( + 20840201000000 20160201000000 29600 example.com. + FgQ4VD1yDeA+uvJ+o8e1F28ijooV1IMfEtki + kLbaIvFcgZbPvTnXXHyesHO2OPiRsc7zF576 + Z6prBT8CkMM7bw== ) diff --git a/tests/knot/semantic_check_data/rrsig_ttl.signed b/tests/knot/semantic_check_data/rrsig_ttl.signed new file mode 100644 index 0000000..1aeef78 --- /dev/null +++ b/tests/knot/semantic_check_data/rrsig_ttl.signed @@ -0,0 +1,52 @@ +example.com. 3600 IN SOA dns1.example.com. hostmaster.example.com. ( + 2010111220 ; serial + 21600 ; refresh (6 hours) + 3600 ; retry (1 hour) + 604800 ; expire (1 week) + 86400 ; minimum (1 day) + ) + 3600 RRSIG SOA 13 2 3600 ( + 20601231235959 20201008165912 34876 example.com. + NaUbzn4tb3bsVI4O2YgrefFtZPJSYlLKbVKB + HyIqwfQjwdkbIKZ5tqH/IGJagvj8oxeStwF/ + vEoG9c/o/MNs4g== ) + 3600 NS dns1.example.com. + 3600 RRSIG NS 13 2 3600 ( + 20601231235959 20201008165912 34876 example.com. + YZqxQKpj3kxfRHxoQda1z9JD9nmX8uNJTBGV + qdMMU3cPOVamTzOqymseQYjBPaaeoxL1kyqk + K2w/ixOUCFp8qg== ) + 86400 NSEC dns1.example.com. NS SOA RRSIG NSEC DNSKEY + 86400 RRSIG NSEC 13 2 86400 ( + 20601231235959 20201008165912 34876 example.com. + 88QLNDpFWd2FIag2vcKGvY1HQFVeOaRIiMU5 + 2VZfLFOPBmuTniTcnPvCt76i5ObPVsWdwJhM + /7NVMxoRPfMC1w== ) + 3600 DNSKEY 256 3 13 ( + 9+7buhxES5wZQZ54+O1qQGuRcKz3P3URZwws + 30CacknPsdcWAy7RN1yYmUjP80geUrxJVQt3 + boo1BwFW4Rnnsg== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 34876 + 3600 DNSKEY 257 3 13 ( + eYNrBYFUn5JIhTlS3N0i2aFj1YE8127h3tlb + VJP9JAfMMxQT+Mg6lwDpUa0oQkNFbEoHhqrD + 0pcMvp4VeMgJ7g== + ) ; KSK; alg = ECDSAP256SHA256 ; key id = 36952 + 3600 RRSIG DNSKEY 13 2 3600 ( + 20601231235959 20201008165912 36952 example.com. + AVF7u7FzDx2ORApl74nP2hcJd4Szs1o1LXH5 + OWe6JULh80kITEb9zogpCryQu41bYSZYuxMk + yeblfo1OEI2DZg== ) +dns1.example.com. 3600 IN A 192.0.2.1 +; TTL of RRSIG differs from original-ttl + 600 RRSIG A 13 3 3600 ( + 20601231235959 20201008165912 34876 example.com. + +PPg6tDZVS2mbxWXOtVEYTQtjK+CkwRk/WFZ + dWgX3rzHPQ9AIexC9vKbXdont3s0xdHpcV/8 + +Sf+N2h44ZTwMQ== ) + 86400 NSEC example.com. A RRSIG NSEC + 86400 RRSIG NSEC 13 3 86400 ( + 20601231235959 20201008165912 34876 example.com. + OCjWQ/5e4SUIWgR84IJLlghKyuowctiZ+b0q + eXB0o2qpcWoX6wfxzMlYxGtpgyq3OWKF+R8H + UBVCdT+qBt5VOA== ) diff --git a/tests/knot/test_acl.c b/tests/knot/test_acl.c new file mode 100644 index 0000000..2460e8a --- /dev/null +++ b/tests/knot/test_acl.c @@ -0,0 +1,346 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <tap/basic.h> + +#include "test_conf.h" +#include "libknot/libknot.h" +#include "knot/updates/acl.c" +#include "contrib/sockaddr.h" + +#define ZONE "example.zone" +#define ZONE2 "example2.zone" +#define KEY1 "key1_md5" +#define KEY2 "key2_md5" +#define KEY3 "key3_sha256" + +static void check_sockaddr_set(struct sockaddr_storage *ss, int family, + const char *straddr, int port) +{ + int ret = sockaddr_set(ss, family, straddr, port); + ok(ret == 0, "set address '%s'", straddr); +} + +void check_update(conf_t *conf, knot_rrset_t *authority, knot_tsig_key_t *key, + knot_dname_t *zone_name, bool allowed, const char *desc) +{ + struct sockaddr_storage addr; + check_sockaddr_set(&addr, AF_INET, "1.2.3.4", 0); + + knot_pkt_t *query = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, NULL); + assert(query); + knot_pkt_begin(query, KNOT_AUTHORITY); + knot_pkt_put(query, 0, authority, 0); + + knot_pkt_t *parsed = knot_pkt_new(query->wire, query->size, NULL); + ok(knot_pkt_parse(parsed, 0) == KNOT_EOK, "Parse update packet"); + + conf_val_t acl = conf_zone_get(conf, C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + + bool ret = acl_allowed(conf, &acl, ACL_ACTION_UPDATE, &addr, key, + zone_name, parsed, NULL); + ok(ret == allowed, "%s", desc); + + knot_pkt_free(parsed); + knot_pkt_free(query); +} + +static void test_acl_allowed(void) +{ + int ret; + conf_val_t acl; + struct sockaddr_storage addr = { 0 }; + + knot_dname_t *zone_name = knot_dname_from_str_alloc(ZONE); + ok(zone_name != NULL, "create zone dname"); + knot_dname_t *zone2_name = knot_dname_from_str_alloc(ZONE2); + ok(zone2_name != NULL, "create zone2 dname"); + knot_dname_t *key1_name = knot_dname_from_str_alloc(KEY1); + ok(key1_name != NULL, "create "KEY1); + knot_dname_t *key2_name = knot_dname_from_str_alloc(KEY2); + ok(key2_name != NULL, "create "KEY2); + knot_dname_t *key3_name = knot_dname_from_str_alloc(KEY3); + ok(key3_name != NULL, "create "KEY3); + + knot_tsig_key_t key0 = { 0 }; + knot_tsig_key_t key1 = { DNSSEC_TSIG_HMAC_MD5, key1_name }; + knot_tsig_key_t key2 = { DNSSEC_TSIG_HMAC_MD5, key2_name }; + knot_tsig_key_t key3 = { DNSSEC_TSIG_HMAC_SHA256, key3_name }; + + const char *conf_str = + "key:\n" + " - id: "KEY1"\n" + " algorithm: hmac-md5\n" + " secret: Zm9v\n" + " - id: "KEY2"\n" + " algorithm: hmac-md5\n" + " secret: Zm9v\n" + " - id: "KEY3"\n" + " algorithm: hmac-sha256\n" + " secret: Zm8=\n" + "\n" + "remote:\n" + " - id: remote_v6_ko\n" + " address: [ 2009::1 ]\n" + " key: key1_md5\n" + " - id: remote_v6_ok\n" + " address: [ 127.0.0.1, 2001::1 ]\n" + " key: key1_md5\n" + "\n" + "acl:\n" + " - id: acl_key_addr\n" + " remote: [ remote_v6_ko, remote_v6_ok ]\n" + " action: [ transfer ]\n" + " - id: acl_deny\n" + " address: [ 240.0.0.2 ]\n" + " action: [ notify ]\n" + " deny: on\n" + " - id: acl_no_action_deny\n" + " address: [ 240.0.0.3 ]\n" + " deny: on\n" + " - id: acl_multi_addr\n" + " address: [ 192.168.1.1, 240.0.0.0/24 ]\n" + " action: [ notify, update ]\n" + " - id: acl_multi_key\n" + " key: [ key2_md5, key3_sha256 ]\n" + " action: [ notify, update ]\n" + " - id: acl_range_addr\n" + " address: [ 100.0.0.0-100.0.0.5, ::0-::5 ]\n" + " action: [ transfer ]\n" + " - id: acl_deny_no_action_no_key\n" + " address: [ 240.0.0.4 ]\n" + " deny: on\n" + " - id: acl_notify_key\n" + " address: [ 240.0.0.0/24 ]\n" + " key: "KEY1"\n" + " action: [ notify ]\n" + " - id: acl_update_key\n" + " key: "KEY1"\n" + " update-owner: key\n" + " update-type: [ AAAA, A ]\n" + " action: [ update ]\n" + " - id: acl_update_name\n" + " key: "KEY2"\n" + " update-owner: name\n" + " update-owner-name: [ a, b."KEY2". ]\n" + " update-owner-match: equal\n" + " action: [ update ]\n" + "\n" + "zone:\n" + " - domain: "ZONE"\n" + " acl: [ acl_key_addr, acl_deny, acl_no_action_deny ]\n" + " acl: [ acl_multi_addr, acl_multi_key ]\n" + " acl: [ acl_range_addr ]\n" + " - domain: "ZONE2"\n" + " acl: [ acl_deny_no_action_no_key, acl_notify_key ]\n" + " - domain: "KEY1"\n" + " acl: acl_update_key\n" + " - domain: "KEY2"\n" + " acl: acl_update_name"; + + ret = test_conf(conf_str, NULL); + is_int(KNOT_EOK, ret, "Prepare configuration"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_QUERY, &addr, &key1, zone_name, NULL, NULL); + ok(ret == true, "Address, key, empty action"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key1, zone_name, NULL, NULL); + ok(ret == true, "Address, key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::2", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key1, zone_name, NULL, NULL); + ok(ret == false, "Address not match, key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key0, zone_name, NULL, NULL); + ok(ret == false, "Address match, no key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key2, zone_name, NULL, NULL); + ok(ret == false, "Address match, key not match, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "2001::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key1, zone_name, NULL, NULL); + ok(ret == false, "Address, key match, action not match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key0, zone_name, NULL, NULL); + ok(ret == true, "Second address match, no key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key1, zone_name, NULL, NULL); + ok(ret == false, "Second address match, extra key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.2", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key0, zone_name, NULL, NULL); + ok(ret == false, "Denied address match, no key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.2", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_UPDATE, &addr, &key0, zone_name, NULL, NULL); + ok(ret == true, "Denied address match, no key, action not match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.3", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_UPDATE, &addr, &key0, zone_name, NULL, NULL); + ok(ret == false, "Denied address match, no key, no action"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "1.1.1.1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_UPDATE, &addr, &key3, zone_name, NULL, NULL); + ok(ret == true, "Arbitrary address, second key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET, "100.0.0.1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key0, zone_name, NULL, NULL); + ok(ret == true, "IPv4 address from range, no key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone_name); + ok(acl.code == KNOT_EOK, "Get zone ACL"); + check_sockaddr_set(&addr, AF_INET6, "::1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_TRANSFER, &addr, &key0, zone_name, NULL, NULL); + ok(ret == true, "IPv6 address from range, no key, action match"); + + acl = conf_zone_get(conf(), C_ACL, zone2_name); + ok(acl.code == KNOT_EOK, "Get zone2 ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.4", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key1, zone2_name, NULL, NULL); + ok(ret == false, "Address, key, action, denied"); + + acl = conf_zone_get(conf(), C_ACL, zone2_name); + ok(acl.code == KNOT_EOK, "Get zone2 ACL"); + check_sockaddr_set(&addr, AF_INET, "240.0.0.1", 0); + ret = acl_allowed(conf(), &acl, ACL_ACTION_NOTIFY, &addr, &key1, zone2_name, NULL, NULL); + ok(ret == true, "Address, key, action, match"); + + knot_rrset_t A; + knot_rrset_init(&A, key1_name, KNOT_RRTYPE_A, KNOT_CLASS_IN, 3600); + knot_rrset_add_rdata(&A, (uint8_t *)"\x00\x00\x00\x00", 4, NULL); + check_update(conf(), &A, &key1, key1_name, true, "Update, tsig, type"); + + check_update(conf(), &A, &key2, key2_name, false, "Update, tsig, bad name"); + knot_rdataset_clear(&A.rrs, NULL); + + knot_rrset_t MX; + knot_rrset_init(&MX, key1_name, KNOT_RRTYPE_MX, KNOT_CLASS_IN, 3600); + knot_rrset_add_rdata(&MX, (uint8_t *)"\x00\x00\x00", 3, NULL); + check_update(conf(), &MX, &key1, key1_name, false, "Update, tsig, bad type"); + knot_rdataset_clear(&MX.rrs, NULL); + + knot_rrset_t aA; + knot_dname_t *a_key2_name = knot_dname_from_str_alloc("a."KEY2"."); + ok(a_key2_name != NULL, "create a."KEY2"."); + knot_rrset_init(&aA, a_key2_name, KNOT_RRTYPE_A, KNOT_CLASS_IN, 3600); + knot_rrset_add_rdata(&aA, (uint8_t *)"\x00\x00\x00\x00", 4, NULL); + check_update(conf(), &aA, &key2, key2_name, true, "Update, tsig, relative name"); + knot_dname_free(a_key2_name, NULL); + knot_rdataset_clear(&aA.rrs, NULL); + + knot_rrset_t bA; + knot_dname_t *b_key2_name = knot_dname_from_str_alloc("b."KEY2"."); + ok(b_key2_name != NULL, "create b."KEY2"."); + knot_rrset_init(&bA, b_key2_name, KNOT_RRTYPE_A, KNOT_CLASS_IN, 3600); + knot_rrset_add_rdata(&bA, (uint8_t *)"\x00\x00\x00\x00", 4, NULL); + check_update(conf(), &bA, &key2, key2_name, true, "Update, tsig, absolute name"); + knot_dname_free(b_key2_name, NULL); + knot_rdataset_clear(&bA.rrs, NULL); + + knot_rrset_t aaA; + knot_dname_t *aa_key2_name = knot_dname_from_str_alloc("a.a."KEY2); + ok(aa_key2_name != NULL, "create a.a."KEY2); + knot_rrset_init(&aaA, aa_key2_name, KNOT_RRTYPE_A, KNOT_CLASS_IN, 3600); + knot_rrset_add_rdata(&aaA, (uint8_t *)"\x00\x00\x00\x00", 4, NULL); + check_update(conf(), &aaA, &key2, key2_name, false, "Update, tsig, bad name"); + knot_dname_free(aa_key2_name, NULL); + knot_rdataset_clear(&aaA.rrs, NULL); + + conf_free(conf()); + knot_dname_free(zone_name, NULL); + knot_dname_free(zone2_name, NULL); + knot_dname_free(key1_name, NULL); + knot_dname_free(key2_name, NULL); + knot_dname_free(key3_name, NULL); +} + +void check_pattern(const char *name_str, const char *pattern_str, bool match) +{ + knot_dname_t *name = knot_dname_from_str_alloc(name_str); + knot_dname_t *pattern = knot_dname_from_str_alloc(pattern_str); + + ok(match_pattern(name, pattern) == match, "'%s' %s '%s'", + name_str, match ? "matched" : "not matched by", pattern_str); + + knot_dname_free(name, NULL); + knot_dname_free(pattern, NULL); +} + +static void test_match_pattern(void) +{ + check_pattern(".", "*", false); + check_pattern("a", "a", true); + check_pattern("a", "*", true); + check_pattern("*", "*", true); + check_pattern("a", "aa", false); + check_pattern("aa", "a", false); + check_pattern("a.b", "*", false); + check_pattern("a.b", "*.*", true); + check_pattern("a.b", "a.b", true); + check_pattern("a.b", "*.*b", false); + check_pattern("a.b", "*.*.*", false); + check_pattern("abc", "*", true); + check_pattern("a.bc.*", "a.*.*", true); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("acl_allowed"); + test_acl_allowed(); + + diag("match_pattern"); + test_match_pattern(); + + return 0; +} diff --git a/tests/knot/test_changeset.c b/tests/knot/test_changeset.c new file mode 100644 index 0000000..6775b76 --- /dev/null +++ b/tests/knot/test_changeset.c @@ -0,0 +1,166 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <assert.h> +#include <tap/basic.h> + +#include "libknot/errcode.h" +#include "libknot/error.h" +#include "knot/updates/changesets.h" + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // Test with NULL changeset + ok(changeset_size(NULL) == 0, "changeset: NULL size"); + ok(changeset_empty(NULL), "changeset: NULL empty"); + + // Test creation. + knot_dname_t *d = knot_dname_from_str_alloc("test."); + assert(d); + changeset_t *ch = changeset_new(d); + knot_dname_free(d, NULL); + ok(ch != NULL, "changeset: new"); + if (!ch) { + return 1; + } + ok(changeset_empty(ch), "changeset: empty"); + ch->soa_to = (knot_rrset_t *)0xdeadbeef; + ok(!changeset_empty(ch), "changeset: empty SOA"); + ch->soa_to = NULL; + ok(changeset_size(ch) == 0, "changeset: empty size"); + + // Test additions. + d = knot_dname_from_str_alloc("non.terminals.test."); + assert(d); + knot_rrset_t *apex_txt_rr = knot_rrset_new(d, KNOT_RRTYPE_TXT, KNOT_CLASS_IN, 3600, NULL); + assert(apex_txt_rr); + uint8_t data[8] = "\7teststr"; + knot_rrset_add_rdata(apex_txt_rr, data, sizeof(data), NULL); + + int ret = changeset_add_addition(ch, apex_txt_rr, CHANGESET_CHECK); + is_int(KNOT_EOK, ret, "changeset: add RRSet"); + ok(changeset_size(ch) == 1, "changeset: size add"); + ret = changeset_add_removal(ch, apex_txt_rr, CHANGESET_CHECK); + is_int(KNOT_EOK, ret, "changeset: rem RRSet"); + ok(changeset_size(ch) == 0, "changeset: size remove"); + ok(changeset_empty(ch), "changeset: empty"); + changeset_add_addition(ch, apex_txt_rr, CHANGESET_CHECK); + + // Add another RR to node. + knot_rrset_t *apex_spf_rr = knot_rrset_new(d, KNOT_RRTYPE_SPF, KNOT_CLASS_IN, 3600, NULL); + assert(apex_spf_rr); + knot_rrset_add_rdata(apex_spf_rr, data, sizeof(data), NULL); + ret = changeset_add_addition(ch, apex_spf_rr, CHANGESET_CHECK); + is_int(KNOT_EOK, ret, "changeset: add multiple"); + + // Add another node. + knot_dname_free(d, NULL); + d = knot_dname_from_str_alloc("here.come.more.non.terminals.test"); + assert(d); + knot_rrset_t *other_rr = knot_rrset_new(d, KNOT_RRTYPE_TXT, KNOT_CLASS_IN, 3600, NULL); + assert(other_rr); + knot_rrset_add_rdata(other_rr, data, sizeof(data), NULL); + ret = changeset_add_addition(ch, other_rr, CHANGESET_CHECK); + is_int(KNOT_EOK, ret, "changeset: remove multiple"); + + // Test add traversal. + changeset_iter_t it; + ret = changeset_iter_add(&it, ch); + is_int(KNOT_EOK, ret, "changeset: create iter add"); + // Order: non.terminals.test. TXT, SPF, here.come.more.non.terminals.test. TXT. + knot_rrset_t iter = changeset_iter_next(&it); + bool trav_ok = knot_rrset_equal(&iter, apex_txt_rr, true); + iter = changeset_iter_next(&it); + trav_ok = trav_ok && knot_rrset_equal(&iter, apex_spf_rr, true); + iter = changeset_iter_next(&it); + trav_ok = trav_ok && knot_rrset_equal(&iter, other_rr, true); + + ok(trav_ok, "changeset: add traversal"); + + iter = changeset_iter_next(&it); + changeset_iter_clear(&it); + ok(knot_rrset_empty(&iter), "changeset: traversal: skip non-terminals"); + + changeset_add_removal(ch, apex_txt_rr, CHANGESET_CHECK); + changeset_add_removal(ch, apex_txt_rr, CHANGESET_CHECK); + + // Test remove traversal. + ret = changeset_iter_rem(&it, ch); + is_int(KNOT_EOK, ret, "changeset: create iter rem"); + iter = changeset_iter_next(&it); + ok(knot_rrset_equal(&iter, apex_txt_rr, true), + "changeset: rem traversal"); + changeset_iter_clear(&it); + + // Test all traversal - just count. + ret = changeset_iter_all(&it, ch); + is_int(KNOT_EOK, ret, "changeset: create iter all"); + size_t size = 0; + iter = changeset_iter_next(&it); + while (!knot_rrset_empty(&iter)) { + ++size; + iter = changeset_iter_next(&it); + } + changeset_iter_clear(&it); + ok(size == 3, "changeset: iter all"); + + // Create new changeset. + knot_dname_free(d, NULL); + d = knot_dname_from_str_alloc("test."); + assert(d); + changeset_t *ch2 = changeset_new(d); + knot_dname_free(d, NULL); + assert(ch2); + // Add something to add section. + knot_dname_free(apex_txt_rr->owner, NULL); + apex_txt_rr->owner = knot_dname_from_str_alloc("something.test."); + assert(apex_txt_rr->owner); + ret = changeset_add_addition(ch2, apex_txt_rr, CHANGESET_CHECK); + assert(ret == KNOT_EOK); + + // Add something to remove section. + knot_dname_free(apex_txt_rr->owner, NULL); + apex_txt_rr->owner = + knot_dname_from_str_alloc("and.now.for.something.completely.different.test."); + assert(apex_txt_rr->owner); + ret = changeset_add_removal(ch2, apex_txt_rr, CHANGESET_CHECK); + assert(ret == KNOT_EOK); + + // Test merge. + ret = changeset_merge(ch, ch2, 0); + ok(ret == KNOT_EOK && changeset_size(ch) == 5, "changeset: merge"); + + // Test cleanup. + changeset_clear(ch); + ok(changeset_empty(ch), "changeset: clear"); + free(ch); + + list_t chgs; + init_list(&chgs); + add_head(&chgs, &ch2->n); + changesets_clear(&chgs); + ok(changeset_empty(ch2), "changeset: clear list"); + free(ch2); + + knot_rrset_free(apex_txt_rr, NULL); + knot_rrset_free(apex_spf_rr, NULL); + knot_rrset_free(other_rr, NULL); + + return 0; +} diff --git a/tests/knot/test_conf.c b/tests/knot/test_conf.c new file mode 100644 index 0000000..401fba5 --- /dev/null +++ b/tests/knot/test_conf.c @@ -0,0 +1,342 @@ +/* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>. + */ + +#define CONFIG_DIR "/tmp" + +#include <tap/basic.h> + +#include "knot/conf/conf.c" +#include "test_conf.h" + +#define ZONE_ARPA "0/25.2.0.192.in-addr.arpa." +#define ZONE_ROOT "." +#define ZONE_1LABEL "x." +#define ZONE_3LABEL "abc.ab.a." +#define ZONE_UNKNOWN "unknown." + +static void check_name(const char *zone, const char *name, const char *ref) +{ + knot_dname_t *z = knot_dname_from_str_alloc(zone); + + char *file = get_filename(conf(), NULL, z, name); + ok(file != NULL, "Get zonefile path for %s", zone); + if (file != NULL) { + ok(strcmp(file, ref) == 0, "Zonefile path compare %s", name); + free(file); + } + + knot_dname_free(z, NULL); +} + +static void check_name_err(const char *zone, const char *name) +{ + knot_dname_t *z = knot_dname_from_str_alloc(zone); + + char *filename = get_filename(conf(), NULL, z, name); + ok(filename == NULL, "Invalid name %s", name); + free(filename); + + knot_dname_free(z, NULL); +} + +static void test_get_filename(void) +{ + int ret = test_conf("", NULL); + is_int(KNOT_EOK, ret, "Prepare empty configuration"); + + // Name formatter. + char *zone = "abc"; + check_name(zone, "/%s", "/abc"); + + zone = "."; + check_name(zone, "/%s", "/"); + + // Char formatter. + zone = "abc.def.g"; + check_name(zone, "/%c[0]", "/a"); + check_name(zone, "/%c[3]", "/."); + check_name(zone, "/%c[8]", "/g"); + check_name(zone, "/%c[9]", "/."); + check_name(zone, "/%c[10]", "/"); + check_name(zone, "/%c[255]", "/"); + check_name(zone, "/%c[0-1]", "/ab"); + check_name(zone, "/%c[1-1]", "/b"); + check_name(zone, "/%c[1-3]", "/bc."); + check_name(zone, "/%c[1-4]", "/bc.d"); + check_name(zone, "/%c[254-255]", "/"); + check_name_err(zone, "/%c"); + check_name_err(zone, "/%cx"); + check_name_err(zone, "/%c[a]"); + check_name_err(zone, "/%c[:]"); + check_name_err(zone, "/%c[/]"); + check_name_err(zone, "/%c[-1]"); + check_name_err(zone, "/%c[256]"); + check_name_err(zone, "/%c["); + check_name_err(zone, "/%c[1"); + check_name_err(zone, "/%c[1-"); + check_name_err(zone, "/%c[1-2"); + check_name_err(zone, "/%c[1-b]"); + check_name_err(zone, "/%c[8-0]"); + + zone = "abcd"; + check_name(zone, "/%c[2-9]", "/cd."); + check_name(zone, "/%c[3]", "/d"); + check_name(zone, "/%c[4]", "/."); + + zone = "."; + check_name(zone, "/%c[0]", "/."); + check_name(zone, "/%c[1]", "/"); + + // Label formatter. + zone = "abc.def.gh"; + check_name(zone, "/%l[0]", "/gh"); + check_name(zone, "/%l[1]", "/def"); + check_name(zone, "/%l[2]", "/abc"); + check_name(zone, "/%l[3]", "/"); + check_name(zone, "/%l[255]", "/"); + check_name(zone, "/%l[0]-%l[1]-%l[2]", "/gh-def-abc"); + check_name_err(zone, "/%l[0-1]"); + check_name_err(zone, "/%l[-1]"); + check_name_err(zone, "/%l[256]"); + + zone = "."; + check_name(zone, "/%l[0]", "/"); + check_name(zone, "/%l[1]", "/"); + + test_conf_free(); +} + +static void test_conf_zonefile(void) +{ + int ret; + char *file; + + knot_dname_t *zone_arpa = knot_dname_from_str_alloc(ZONE_ARPA); + ok(zone_arpa != NULL, "create dname "ZONE_ARPA); + knot_dname_t *zone_root = knot_dname_from_str_alloc(ZONE_ROOT); + ok(zone_root != NULL, "create dname "ZONE_ROOT); + knot_dname_t *zone_1label = knot_dname_from_str_alloc(ZONE_1LABEL); + ok(zone_1label != NULL, "create dname "ZONE_1LABEL); + knot_dname_t *zone_3label = knot_dname_from_str_alloc(ZONE_3LABEL); + ok(zone_3label != NULL, "create dname "ZONE_3LABEL); + knot_dname_t *zone_unknown = knot_dname_from_str_alloc(ZONE_UNKNOWN); + ok(zone_unknown != NULL, "create dname "ZONE_UNKNOWN); + + const char *conf_str = + "template:\n" + " - id: default\n" + " storage: /tmp\n" + "\n" + "zone:\n" + " - domain: "ZONE_ARPA"\n" + " file: dir/a%%b/%s.suffix/%a\n" + " - domain: "ZONE_ROOT"\n" + " file: /%s\n" + " - domain: "ZONE_1LABEL"\n" + " file: /%s\n" + " - domain: "ZONE_3LABEL"\n"; + + ret = test_conf(conf_str, NULL); + is_int(KNOT_EOK, ret, "Prepare configuration"); + + // Relative path with formatters. + file = conf_zonefile(conf(), zone_arpa); + ok(file != NULL, "Get zonefile path for "ZONE_ARPA); + if (file != NULL) { + ok(strcmp(file, "/tmp/dir/a%b/0_25.2.0.192.in-addr.arpa.suffix/") == 0, + "Zonefile path compare for "ZONE_ARPA); + free(file); + } + + // Absolute path without formatters - root zone. + file = conf_zonefile(conf(), zone_root); + ok(file != NULL, "Get zonefile path for "ZONE_ROOT); + if (file != NULL) { + ok(strcmp(file, "/") == 0, + "Zonefile path compare for "ZONE_ROOT); + free(file); + } + + // Absolute path without formatters - non-root zone. + file = conf_zonefile(conf(), zone_1label); + ok(file != NULL, "Get zonefile path for "ZONE_1LABEL); + if (file != NULL) { + ok(strcmp(file, "/x") == 0, + "Zonefile path compare for "ZONE_1LABEL); + free(file); + } + + // Default zonefile path. + file = conf_zonefile(conf(), zone_3label); + ok(file != NULL, "Get zonefile path for "ZONE_3LABEL); + if (file != NULL) { + ok(strcmp(file, "/tmp/abc.ab.a.zone") == 0, + "Zonefile path compare for "ZONE_3LABEL); + free(file); + } + + // Unknown zone zonefile path. + file = conf_zonefile(conf(), zone_unknown); + ok(file != NULL, "Get zonefile path for "ZONE_UNKNOWN); + if (file != NULL) { + ok(strcmp(file, "/tmp/unknown.zone") == 0, + "Zonefile path compare for "ZONE_UNKNOWN); + free(file); + } + + test_conf_free(); + knot_dname_free(zone_arpa, NULL); + knot_dname_free(zone_root, NULL); + knot_dname_free(zone_1label, NULL); + knot_dname_free(zone_3label, NULL); + knot_dname_free(zone_unknown, NULL); +} + +static void test_mix_ref(void) +{ + const char *conf_string = + "remote:\n" + " - id: r1\n" + " address: ::1\n" + " - id: r2\n" + " address: ::2\n" + " - id: r3\n" + " address: ::3\n" + " - id: r4\n" + " address: ::4\n" + " - id: r5\n" + " address: ::5\n" + "remotes:\n" + " - id: rs2\n" + " remote: [r2]\n" + " - id: rs45\n" + " remote: [r4, r5]\n" + "\n" + "submission:\n" + " - id: t1\n" + " parent: [r1, rs2, r3, rs45]\n" + " - id: t2\n" + " parent: [rs45, r2, r1]\n"; + + int ret = test_conf(conf_string, NULL); + is_int(KNOT_EOK, ret, "Prepare configuration"); + + size_t cnt1 = 0; + conf_val_t test1 = conf_rawid_get(conf(), C_SBM, C_PARENT, (const uint8_t *)"t1", 3); + conf_mix_iter_t iter1; + conf_mix_iter_init(conf(), &test1, &iter1); + while (iter1.id->code == KNOT_EOK) { + cnt1++; + conf_mix_iter_next(&iter1); + } + is_int(5, cnt1, "number of mixed references 1"); + + size_t cnt2 = 0; + conf_val_t test2 = conf_rawid_get(conf(), C_SBM, C_PARENT, (const uint8_t *)"t2", 3); + conf_mix_iter_t iter2; + conf_mix_iter_init(conf(), &test2, &iter2); + while (iter2.id->code == KNOT_EOK) { + cnt2++; + conf_mix_iter_next(&iter2); + } + is_int(4, cnt2, "number of mixed references 2"); + + test_conf_free(); +} + +static void check_addrs(struct sockaddr_storage *addr, struct sockaddr_storage *via, + int family, const char *addr_str, const char *via_str) +{ + struct sockaddr_storage ref = { 0 }; + + int set_ret = sockaddr_set(&ref, family, addr_str, 0); + int cmp_ret = sockaddr_cmp(&ref, addr, true); + is_int(KNOT_EOK, set_ret, "set address '%s'", addr_str); + is_int(KNOT_EOK, cmp_ret, "cmp address '%s'", addr_str); + + if (via_str != NULL) { + set_ret = sockaddr_set(&ref, family, via_str, 0); + cmp_ret = sockaddr_cmp(&ref, via, true); + is_int(KNOT_EOK, set_ret, "set via '%s'", via_str); + is_int(KNOT_EOK, cmp_ret, "cmp via '%s'", via_str); + } else { + is_int(AF_UNSPEC, via->ss_family, "empty via"); + } +} + +static void test_conf_remote(void) +{ + const char *conf_string = + "remote:\n" + " - id: r1\n" + " address: [1::2, 1.0.0.2, 2::2, 3::2, 2.0.0.2]\n" + " via: [1::1, 2::1, 1.0.0.1, 2.0.0.1]\n" + " - id: r2\n" + " address: [1::2, 1.0.0.2, 2::2]\n" + " via: [1::1, 2::1, 3::1]\n" + "template:\n" + " - id: t1\n" + " notify: r1\n" + " - id: t2\n" + " notify: r2\n"; + + int ret = test_conf(conf_string, NULL); + is_int(KNOT_EOK, ret, "Prepare configuration"); + + conf_remote_t r; + conf_val_t id; + + id = conf_rawid_get(conf(), C_TPL, C_NOTIFY, (const uint8_t *)"t1", 3); + r = conf_remote(conf(), &id, 0); + check_addrs(&r.addr, &r.via, AF_INET6, "1::2", "1::1"); + r = conf_remote(conf(), &id, 1); + check_addrs(&r.addr, &r.via, AF_INET, "1.0.0.2", "1.0.0.1"); + r = conf_remote(conf(), &id, 2); + check_addrs(&r.addr, &r.via, AF_INET6, "2::2", "2::1"); + r = conf_remote(conf(), &id, 3); + check_addrs(&r.addr, &r.via, AF_INET6, "3::2", "2::1"); + r = conf_remote(conf(), &id, 4); + check_addrs(&r.addr, &r.via, AF_INET, "2.0.0.2", "2.0.0.1"); + + id = conf_rawid_get(conf(), C_TPL, C_NOTIFY, (const uint8_t *)"t2", 3); + r = conf_remote(conf(), &id, 0); + check_addrs(&r.addr, &r.via, AF_INET6, "1::2", "1::1"); + r = conf_remote(conf(), &id, 1); + check_addrs(&r.addr, &r.via, AF_INET, "1.0.0.2", NULL); + r = conf_remote(conf(), &id, 2); + check_addrs(&r.addr, &r.via, AF_INET6, "2::2", "2::1"); + + test_conf_free(); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("get_filename"); + test_get_filename(); + + diag("conf_zonefile"); + test_conf_zonefile(); + + diag("mixed references"); + test_mix_ref(); + + diag("conf_remote"); + test_conf_remote(); + + return 0; +} diff --git a/tests/knot/test_conf.h b/tests/knot/test_conf.h new file mode 100644 index 0000000..65adffb --- /dev/null +++ b/tests/knot/test_conf.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "knot/conf/conf.h" +#include "libknot/errcode.h" + +/* Prepare server configuration. */ +static inline int test_conf(const char *conf_str, const yp_item_t *schema) +{ + // Use default schema if not specified. + if (schema == NULL) { + schema = conf_schema; + } + + conf_t *new_conf = NULL; + int ret = conf_new(&new_conf, schema, NULL, 2 * 1024 * 1024, CONF_FNONE); + if (ret != KNOT_EOK) { + return ret; + } + + ret = conf_import(new_conf, conf_str, 0); + if (ret != KNOT_EOK) { + conf_free(new_conf); + return ret; + } + + conf_update(new_conf, CONF_UPD_FNONE); + + return KNOT_EOK; +} + +static inline void test_conf_free(void) +{ + conf_update(NULL, CONF_UPD_FNONE); +} diff --git a/tests/knot/test_conf_tools.c b/tests/knot/test_conf_tools.c new file mode 100644 index 0000000..dc83a06 --- /dev/null +++ b/tests/knot/test_conf_tools.c @@ -0,0 +1,74 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/yparser/yptrafo.h" +#include "knot/conf/tools.h" +#include "libknot/libknot.h" + +static void mod_id_test(const char *txt, const char *val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL, + mod_id_to_bin, + mod_id_to_txt } }; + + diag("module id \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(memcmp(b, val, b_len) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void mod_id_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TDATA, YP_VDATA = { 0, NULL, + mod_id_to_bin, + mod_id_to_txt } }; + + diag("module id \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Module id tests. */ + mod_id_test("module/id", "\x06moduleid"); + mod_id_test("module", "\x06module"); + mod_id_bad_test("module/", KNOT_EINVAL); + mod_id_bad_test("/", KNOT_EINVAL); + mod_id_bad_test("/id", KNOT_EINVAL); + + return 0; +} diff --git a/tests/knot/test_confdb.c b/tests/knot/test_confdb.c new file mode 100644 index 0000000..e149f8d --- /dev/null +++ b/tests/knot/test_confdb.c @@ -0,0 +1,489 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "test_conf.h" +#include "knot/conf/confdb.c" + +static void check_db_content(conf_t *conf, knot_db_txn_t *txn, int count) +{ + ok(db_check_version(conf, txn) == KNOT_EOK, "Version check"); + if (count >= 0) { + ok(conf->api->count(txn) == 1 + count, "Check DB entries count"); + } +} + +static void check_code( + conf_t *conf, + knot_db_txn_t *txn, + uint8_t section_code, + const yp_name_t *name, + db_action_t action, + int ret, + uint8_t ref_code) +{ + uint8_t code = 0; + ok(db_code(conf, txn, section_code, name, action, &code) == ret, + "Compare DB code return"); + + if (ret != KNOT_EOK) { + return; + } + + uint8_t k[64] = { section_code, 0 }; + memcpy(k + 2, name + 1, name[0]); + knot_db_val_t key = { .data = k, .len = 2 + name[0] }; + knot_db_val_t val; + + ret = conf->api->find(txn, &key, &val, 0); + switch (action) { + case DB_GET: + case DB_SET: + ok(code == ref_code, "Compare DB code"); + is_int(KNOT_EOK, ret, "Find DB code"); + ok(val.len == 1, "Compare DB code length"); + ok(((uint8_t *)val.data)[0] == code, "Compare DB code value"); + break; + case DB_DEL: + is_int(KNOT_ENOENT, ret, "Find item code"); + break; + } +} + +static void test_db_code(conf_t *conf, knot_db_txn_t *txn) +{ + // Add codes. + check_code(conf, txn, 0, C_SERVER, DB_SET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 1); + check_code(conf, txn, 0, C_LOG, DB_SET, KNOT_EOK, KEY1_FIRST + 1); + check_db_content(conf, txn, 2); + check_code(conf, txn, 2, C_IDENT, DB_SET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 3); + check_code(conf, txn, 0, C_ZONE, DB_SET, KNOT_EOK, KEY1_FIRST + 2); + check_db_content(conf, txn, 4); + check_code(conf, txn, 2, C_VERSION, DB_SET, KNOT_EOK, KEY1_FIRST + 1); + check_db_content(conf, txn, 5); + + // Add existing code (no change). + check_code(conf, txn, 0, C_SERVER, DB_SET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 5); + + // Get codes. + check_code(conf, txn, 0, C_SERVER, DB_GET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 5); + check_code(conf, txn, 0, C_RMT, DB_GET, KNOT_ENOENT, 0); + check_db_content(conf, txn, 5); + + // Delete not existing code. + check_code(conf, txn, 0, C_COMMENT, DB_DEL, KNOT_ENOENT, 0); + check_db_content(conf, txn, 5); + + // Delete codes. + check_code(conf, txn, 0, C_SERVER, DB_DEL, KNOT_EOK, 0); + check_db_content(conf, txn, 4); + check_code(conf, txn, 2, C_IDENT, DB_DEL, KNOT_EOK, 0); + check_db_content(conf, txn, 3); + + // Reuse deleted codes. + check_code(conf, txn, 0, C_ACL, DB_SET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 4); + check_code(conf, txn, 2, C_NSID, DB_SET, KNOT_EOK, KEY1_FIRST); + check_db_content(conf, txn, 5); +} + +static void check_set( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0, + const yp_name_t *key1, + const uint8_t *id, + size_t id_len, + int ret, + const uint8_t *data, + size_t data_len, + const uint8_t *exp_data, + size_t exp_data_len) +{ + ok(conf_db_set(conf, txn, key0, key1, id, id_len, data, data_len) == ret, + "Check set return"); + + if (ret != KNOT_EOK || (key1 == NULL && id == NULL)) { + return; + } + + uint8_t section_code, item_code; + section_code = 0, item_code = 0; // prevents Wuninitialized + ok(db_code(conf, txn, KEY0_ROOT, key0, DB_GET, §ion_code) == KNOT_EOK, + "Get DB section code"); + if (key1 != NULL) { + ok(db_code(conf, txn, section_code, key1, DB_GET, &item_code) == KNOT_EOK, + "Get DB item code"); + } else { + item_code = KEY1_ID; + } + + uint8_t k[64] = { section_code, item_code }; + if (id != NULL) { + memcpy(k + 2, id, id_len); + } + knot_db_val_t key = { .data = k, .len = 2 + id_len }; + knot_db_val_t val; + + ok(conf->api->find(txn, &key, &val, 0) == KNOT_EOK, "Get inserted data"); + ok(val.len == exp_data_len, "Compare data length"); + ok(memcmp(val.data, exp_data, exp_data_len) == 0, "Compare data"); + + check_db_content(conf, txn, -1); +} + +static void test_conf_db_set(conf_t *conf, knot_db_txn_t *txn) +{ + // Set section without item - noop. + check_set(conf, txn, C_INCL, NULL, NULL, 0, KNOT_EOK, NULL, 0, NULL, 0); + + // Set singlevalued item. + check_set(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_EOK, + (uint8_t *)"\0", 1, (uint8_t *)"\0", 1); + check_set(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_EOK, + (uint8_t *)"a b\0", 4, (uint8_t *)"a b\0", 4); + + // Set multivalued item. + check_set(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"\0", 1, (uint8_t *)"\x00\x01""\0", 3); + check_set(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"a\0", 2, (uint8_t *)"\x00\x01""\0""\x00\x02""a\0", 7); + check_set(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"b\0", 2, (uint8_t *)"\x00\x01""\0""\x00\x02""a\0""\x00\x02""b\0", 11); + + // Set group id. + check_set(conf, txn, C_ZONE, NULL, (uint8_t *)"id", 2, KNOT_EOK, + NULL, 0, (uint8_t *)"", 0); + + // Set singlevalued item with id. + check_set(conf, txn, C_ZONE, C_FILE, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"\0", 1, (uint8_t *)"\0", 1); + check_set(conf, txn, C_ZONE, C_FILE, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"a b\0", 4, (uint8_t *)"a b\0", 4); + + // Set multivalued item with id. + check_set(conf, txn, C_ZONE, C_MASTER, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"\0", 1, (uint8_t *)"\x00\x01""\0", 3); + check_set(conf, txn, C_ZONE, C_MASTER, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"a\0", 2, (uint8_t *)"\x00\x01""\0""\x00\x02""a\0", 7); + check_set(conf, txn, C_ZONE, C_MASTER, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"b\0", 2, (uint8_t *)"\x00\x01""\0""\x00\x02""a\0""\x00\x02""b\0", 11); + + // ERR set invalid section. + check_set(conf, txn, C_MASTER, NULL, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0, NULL, 0); + + // ERR set invalid item. + check_set(conf, txn, C_SERVER, C_DOMAIN, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0, NULL, 0); + + // ERR redefine section id. + check_set(conf, txn, C_ZONE, NULL, (uint8_t *)"id", 2, KNOT_CONF_EREDEFINE, + NULL, 0, NULL, 0); + + // ERR set singlevalued item with non-existing id. + check_set(conf, txn, C_ZONE, C_FILE, (uint8_t *)"idx", 3, KNOT_YP_EINVAL_ID, + NULL, 0, NULL, 0); +} + +static void check_get( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0, + const yp_name_t *key1, + const uint8_t *id, + size_t id_len, + int ret, + const uint8_t *exp_data, + size_t exp_data_len) +{ + conf_val_t val; + ok(conf_db_get(conf, txn, key0, key1, id, id_len, &val) == ret, + "Check get return"); + + if (ret != KNOT_EOK) { + return; + } + + ok(val.blob_len == exp_data_len, "Compare data length"); + ok(val.blob != NULL && memcmp(val.blob, exp_data, exp_data_len) == 0, + "Compare data"); + + check_db_content(conf, txn, -1); +} + +static void test_conf_db_get(conf_t *conf, knot_db_txn_t *txn) +{ + // Get singlevalued item. + check_get(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_EOK, + (uint8_t *)"a b\0", 4); + + // Get multivalued item. + check_get(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"\x00\x01""\0""\x00\x02""a\0""\x00\x02""b\0", 11); + + // Get group id. + check_get(conf, txn, C_ZONE, NULL, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"", 0); + + // Get singlevalued item with id. + check_get(conf, txn, C_ZONE, C_FILE, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"a b\0", 4); + + // Get multivalued item with id. + check_get(conf, txn, C_ZONE, C_MASTER, (uint8_t *)"id", 2, KNOT_EOK, + (uint8_t *)"\x00\x01""\0""\x00\x02""a\0""\x00\x02""b\0", 11); + + // ERR get section without item. + check_get(conf, txn, C_INCL, NULL, NULL, 0, KNOT_EINVAL, NULL, 0); + + // ERR get invalid section. + check_get(conf, txn, C_MASTER, NULL, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0); + + // ERR get invalid item. + check_get(conf, txn, C_SERVER, C_DOMAIN, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0); + + // ERR get singlevalued item with non-existing id. + check_get(conf, txn, C_ZONE, C_FILE, (uint8_t *)"idx", 3, KNOT_YP_EINVAL_ID, + NULL, 0); +} + +static void check_unset( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0, + const yp_name_t *key1, + const uint8_t *id, + size_t id_len, + int ret, + const uint8_t *data, + size_t data_len, + const uint8_t *exp_data, + size_t exp_data_len) +{ + ok(conf_db_unset(conf, txn, key0, key1, id, id_len, data, data_len, false) == ret, + "Check unset return"); + + if (ret != KNOT_EOK) { + return; + } + + uint8_t section_code, item_code; + ok(db_code(conf, txn, KEY0_ROOT, key0, DB_GET, §ion_code) == KNOT_EOK, + "Get DB section code"); + if (key1 != NULL) { + ok(db_code(conf, txn, section_code, key1, DB_GET, &item_code) == KNOT_EOK, + "Get DB item code"); + } else { + item_code = KEY1_ID; + } + + uint8_t k[64] = { section_code, item_code }; + if (id != NULL) { + memcpy(k + 2, id, id_len); + } + knot_db_val_t key = { .data = k, .len = 2 + id_len }; + knot_db_val_t val; + + ret = conf->api->find(txn, &key, &val, 0); + if (exp_data != NULL) { + is_int(KNOT_EOK, ret, "Get deleted data"); + ok(val.len == exp_data_len, "Compare data length"); + ok(memcmp(val.data, exp_data, exp_data_len) == 0, "Compare data"); + } else { + is_int(KNOT_ENOENT, ret, "Get deleted data"); + } + + check_db_content(conf, txn, -1); +} + +static void check_unset_key( + conf_t *conf, + knot_db_txn_t *txn, + const yp_name_t *key0, + const yp_name_t *key1, + const uint8_t *id, + size_t id_len, + int ret) +{ + ok(conf_db_unset(conf, txn, key0, key1, id, id_len, NULL, 0, true) == ret, + "Check unset return"); + + if (ret != KNOT_EOK) { + return; + } + + uint8_t section_code, item_code; + ret = db_code(conf, txn, KEY0_ROOT, key0, DB_GET, §ion_code); + if (key1 == NULL && id_len == 0) { + is_int(KNOT_ENOENT, ret, "Get DB section code"); + } else { + is_int(KNOT_EOK, ret, "Get DB section code"); + ret = db_code(conf, txn, section_code, key1, DB_GET, &item_code); + is_int(KNOT_ENOENT, ret, "Get DB item code"); + } + + check_db_content(conf, txn, -1); +} + +static void test_conf_db_unset(conf_t *conf, knot_db_txn_t *txn) +{ + // ERR unset section without item. + check_unset(conf, txn, C_INCL, NULL, NULL, 0, KNOT_ENOENT, + NULL, 0, NULL, 0); + + // ERR unset invalid section. + check_unset(conf, txn, C_MASTER, NULL, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0, NULL, 0); + + // ERR unset invalid item. + check_unset(conf, txn, C_SERVER, C_DOMAIN, NULL, 0, KNOT_YP_EINVAL_ITEM, + NULL, 0, NULL, 0); + + // ERR unset singlevalued item with non-existing id. + check_unset(conf, txn, C_ZONE, C_FILE, (uint8_t *)"idx", 3, KNOT_YP_EINVAL_ID, + NULL, 0, NULL, 0); + + // ERR unset singlevalued item invalid value. + check_unset(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_ENOENT, + (uint8_t *)"x\0", 2, NULL, 0); + + // Unset singlevalued item data. + check_unset(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_EOK, + (uint8_t *)"a b\0", 4, NULL, 0); + // Unset item. + check_unset_key(conf, txn, C_SERVER, C_RUNDIR, NULL, 0, KNOT_EOK); + + // Unset multivalued item. + check_unset(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"a", 2, (uint8_t *)"\x00\x01""\0""\x00\x02""b\0", 7); + check_unset(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"", 1, (uint8_t *)"\x00\x02""b\0", 4); + check_unset(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK, + (uint8_t *)"b", 2, NULL, 0); + // Unset item. + check_unset_key(conf, txn, C_SERVER, C_LISTEN, NULL, 0, KNOT_EOK); + // Unset section. + check_unset_key(conf, txn, C_SERVER, NULL, NULL, 0, KNOT_EOK); + + // Unset singlevalued item with id - all data at one step. + check_unset(conf, txn, C_ZONE, C_FILE, (uint8_t *)"id", 2, KNOT_EOK, + NULL, 0, NULL, 0); + + // Unset multivalued item with id - all data at one step (non-null data!). + check_unset(conf, txn, C_ZONE, C_MASTER, (uint8_t *)"id", 2, KNOT_EOK, + NULL + 1, 0, NULL, 0); + + // Unset group id. + check_unset(conf, txn, C_ZONE, NULL, (uint8_t *)"id", 2, KNOT_EOK, + NULL, 0, NULL, 0); +} + +static void test_conf_db_iter(conf_t *conf, knot_db_txn_t *txn) +{ + const size_t total = 4; + char names[][10] = { "alfa", "beta", "delta", "epsilon" }; + + // Prepare identifiers to iterate through. + for (size_t i = 0; i < total; i++) { + check_set(conf, txn, C_RMT, NULL, (uint8_t *)names[i], + strlen(names[i]), KNOT_EOK, NULL, 0, (uint8_t *)"", 0); + } + + // Create section iterator. + conf_iter_t iter; + int ret = conf_db_iter_begin(conf, txn, C_RMT, &iter); + is_int(KNOT_EOK, ret, "Create iterator"); + + // Iterate through the section. + size_t count = 0; + while (ret == KNOT_EOK) { + const uint8_t *id; + size_t id_len; + id = NULL, id_len = 0; // prevents Wuninitialized + ret = conf_db_iter_id(conf, &iter, &id, &id_len); + is_int(KNOT_EOK, ret, "Get iteration id"); + ok(id_len == strlen(names[count]), "Compare iteration id length"); + ok(memcmp(id, names[count], id_len) == 0, "Compare iteration id"); + + ok(conf_db_iter_del(conf, &iter) == KNOT_EOK, "Delete iteration key"); + + count++; + ret = conf_db_iter_next(conf, &iter); + } + is_int(KNOT_EOF, ret, "Finished iteration"); + ok(count == total, "Check iteration count"); + + // Check empty section. + ret = conf_db_iter_begin(conf, txn, C_RMT, &iter); + is_int(KNOT_ENOENT, ret, "Create iterator"); + + // ERR non-iterable section. + ok(conf_db_iter_begin(conf, txn, C_SERVER, &iter) == KNOT_ENOTSUP, "Create iterator"); + + // ERR empty section. + ok(conf_db_iter_begin(conf, txn, C_ZONE, &iter) == KNOT_ENOENT, "Create iterator"); + + // ERR section with no code. + ok(conf_db_iter_begin(conf, txn, C_LOG, &iter) == KNOT_ENOENT, "Create iterator"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + ok(test_conf("", NULL) == KNOT_EOK, "Prepare configuration"); + check_db_content(conf(), &conf()->read_txn, 0); + + knot_db_txn_t txn; + ok(conf()->api->txn_begin(conf()->db, &txn, 0) == KNOT_EOK, "Begin transaction"); + + diag("db_code"); + test_db_code(conf(), &txn); + + conf()->api->txn_abort(&txn); + + ok(conf()->api->txn_begin(conf()->db, &txn, 0) == KNOT_EOK, "Begin transaction"); + + diag("conf_db_set"); + test_conf_db_set(conf(), &txn); + + diag("conf_db_get"); + test_conf_db_get(conf(), &txn); + + diag("conf_db_unset"); + test_conf_db_unset(conf(), &txn); + + conf()->api->txn_abort(&txn); + + ok(conf()->api->txn_begin(conf()->db, &txn, 0) == KNOT_EOK, "Begin transaction"); + + diag("conf_db_iter"); + test_conf_db_iter(conf(), &txn); + + conf()->api->txn_abort(&txn); + + conf_free(conf()); + + return 0; +} diff --git a/tests/knot/test_confio.c b/tests/knot/test_confio.c new file mode 100644 index 0000000..44bc7c5 --- /dev/null +++ b/tests/knot/test_confio.c @@ -0,0 +1,1101 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "test_conf.h" +#include "knot/conf/confio.h" +#include "knot/conf/tools.h" +#include "libknot/yparser/yptrafo.h" +#include "contrib/string.h" +#include "contrib/openbsd/strlcat.h" + +#define SKIP_OPENBSD skip("Nested transactions are not supported on OpenBSD"); +#define OUT_LEN 1024 +#define ZONE1 "zone1" +#define ZONE2 "zone2" +#define ZONE3 "zone3" + +char *format_key(conf_io_t *io) +{ + knot_dname_txt_storage_t id; + size_t id_len = sizeof(id); + + // Get the textual item id. + if (io->id_len > 0 && !io->id_as_data) { + if (yp_item_to_txt(io->key0->var.g.id, io->id, io->id_len, id, + &id_len, YP_SNOQUOTE) != KNOT_EOK) { + return NULL; + } + } + + // Get the item prefix. + const char *prefix = ""; + switch (io->type) { + case NEW: prefix = "+"; break; + case OLD: prefix = "-"; break; + default: break; + } + + // Format the item key. + return sprintf_alloc( + "%s%.*s%s%.*s%s%s%.*s", + prefix, (int)io->key0->name[0], io->key0->name + 1, + (io->id_len > 0 && !io->id_as_data ? "[" : ""), + (io->id_len > 0 && !io->id_as_data ? (int)id_len : 0), id, + (io->id_len > 0 && !io->id_as_data ? "]" : ""), + (io->key1 != NULL ? "." : ""), + (io->key1 != NULL ? (int)io->key1->name[0] : 0), + (io->key1 != NULL ? io->key1->name + 1 : "")); +} + +static int append_data(const yp_item_t *item, const uint8_t *bin, size_t bin_len, + char *out, size_t out_len) +{ + char buf[YP_MAX_TXT_DATA_LEN + 1] = "\0"; + size_t buf_len = sizeof(buf); + + int ret = yp_item_to_txt(item, bin, bin_len, buf, &buf_len, YP_SNONE); + if (ret != KNOT_EOK) { + return ret; + } + + if (strlcat(out, buf, out_len) >= out_len) { + return KNOT_ESPACE; + } + + return KNOT_EOK; +} + +char *format_data(conf_io_t *io) +{ + char out[YP_MAX_TXT_DATA_LEN + 1] = "\0"; + + // Return the item identifier as the item data. + if (io->id_as_data) { + if (append_data(io->key0->var.g.id, io->id, io->id_len, out, + sizeof(out)) != KNOT_EOK) { + return NULL; + } + + return strdup(out); + } + + // Check for no data. + if (io->data.val == NULL && io->data.bin == NULL) { + return NULL; + } + + const yp_item_t *item = (io->key1 != NULL) ? io->key1 : io->key0; + + // Format explicit binary data value. + if (io->data.bin != NULL) { + if (append_data(item, io->data.bin, io->data.bin_len, out, + sizeof(out)) != KNOT_EOK) { + return NULL; + } + // Format multivalued item data. + } else if (item->flags & YP_FMULTI) { + size_t values = conf_val_count(io->data.val); + for (size_t i = 0; i < values; i++) { + // Skip other values if known index (counted from 1). + if (io->data.index > 0 && + io->data.index != i + 1) { + conf_val_next(io->data.val); + continue; + } + + if (i > 0) { + if (strlcat(out, " ", sizeof(out)) >= sizeof(out)) { + return NULL; + } + } + + conf_val(io->data.val); + if (append_data(item, io->data.val->data, io->data.val->len, + out, sizeof(out)) != KNOT_EOK) { + return NULL; + } + + conf_val_next(io->data.val); + } + // Format singlevalued item data. + } else { + conf_val(io->data.val); + if (append_data(item, io->data.val->data, io->data.val->len, out, + sizeof(out)) != KNOT_EOK) { + return NULL; + } + } + + return strdup(out); +} + +static int format_item(conf_io_t *io) +{ + char *out = (char *)io->misc; + + // Get the item key and data strings. + char *key = format_key(io); + char *data = format_data(io); + + // Format the item. + char *item = sprintf_alloc( + "%s%s%s%s", + (*out != '\0' ? "\n" : ""), + (key != NULL ? key : ""), + (data != NULL ? " = " : ""), + (data != NULL ? data : "")); + free(key); + free(data); + if (item == NULL) { + return KNOT_ENOMEM; + } + + // Append the item. + if (strlcat(out, item, OUT_LEN) >= OUT_LEN) { + free(item); + return KNOT_ESPACE; + } + + free(item); + + return KNOT_EOK; +} + +static void test_conf_io_begin(void) +{ + ok(conf_io_begin(true) == KNOT_TXN_ENOTEXISTS, "begin child txn with no parent"); + ok(conf()->io.txn == NULL, "check txn depth"); + +#if defined(__OpenBSD__) + SKIP_OPENBSD +#else + ok(conf_io_begin(false) == KNOT_EOK, "begin parent txn"); + ok(conf()->io.txn == &(conf()->io.txn_stack[0]), "check txn depth"); + + ok(conf_io_begin(false) == KNOT_TXN_EEXISTS, "begin another parent txn"); + ok(conf()->io.txn == &(conf()->io.txn_stack[0]), "check txn depth"); + + for (int i = 1; i < CONF_MAX_TXN_DEPTH; i++) { + ok(conf_io_begin(true) == KNOT_EOK, "begin child txn"); + ok(conf()->io.txn == &(conf()->io.txn_stack[i]), "check txn depth"); + } + ok(conf_io_begin(true) == KNOT_TXN_EEXISTS, "begin another child txn"); + ok(conf()->io.txn == &(conf()->io.txn_stack[CONF_MAX_TXN_DEPTH - 1]), + "check txn depth"); + + conf_io_abort(false); + ok(conf()->io.txn == NULL, "check txn depth"); +#endif +} + +static void test_conf_io_abort(void) +{ +#if defined(__OpenBSD__) + SKIP_OPENBSD +#else + // Test child persistence after subchild abort. + { + char idx[2] = { '0' }; + ok(conf_io_begin(false) == KNOT_EOK, "begin parent txn"); + ok(conf_io_set("server", "version", NULL, idx) == + KNOT_EOK, "set single value '%s'", idx); + } + + for (int i = 1; i < CONF_MAX_TXN_DEPTH; i++) { + char idx[2] = { '0' + i }; + ok(conf_io_begin(true) == KNOT_EOK, "begin child txn %s", idx); + ok(conf_io_set("server", "version", NULL, idx) == + KNOT_EOK, "set single value '%s'", idx); + } + + for (int i = CONF_MAX_TXN_DEPTH - 1; i > 0; i--) { + char idx[2] = { '0' + i }; + conf_io_abort(true); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + const char *data = conf_str(&val); + ok(*data == (idx[0] - 1), "compare txn data '%s'", data); + } + + conf_io_abort(false); + ok(conf()->io.txn == NULL, "check txn depth"); + + // Test child abort with committed subchild. + ok(conf_io_begin(false) == KNOT_EOK, "begin new parent txn"); + ok(conf_io_begin(true) == KNOT_EOK, "begin child txn"); + ok(conf_io_begin(true) == KNOT_EOK, "begin subchild txn"); + ok(conf_io_set("server", "version", NULL, "text") == + KNOT_EOK, "set single value"); + ok(conf_io_commit(true) == KNOT_EOK, "commit subchild txn"); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + const char *data = conf_str(&val); + ok(strcmp(data, "text") == 0, "compare subchild txn data '%s'", data); + conf_io_abort(true); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); + conf_io_abort(false); + + // Test unchanged read_txn. + val = conf_get_txn(conf(), &conf()->read_txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); +#endif +} + +static void test_conf_io_commit(void) +{ + ok(conf_io_commit(false) == KNOT_TXN_ENOTEXISTS, "commit no txt txn"); + ok(conf_io_commit(true) == KNOT_TXN_ENOTEXISTS, "commit no txt txn"); + +#if defined(__OpenBSD__) + SKIP_OPENBSD +#else + // Test subchild persistence after commit. + { + char idx[2] = { '0' }; + ok(conf_io_begin(false) == KNOT_EOK, "begin parent txn"); + ok(conf_io_set("server", "version", NULL, idx) == + KNOT_EOK, "set single value '%s'", idx); + } + + for (int i = 1; i < CONF_MAX_TXN_DEPTH; i++) { + char idx[2] = { '0' + i }; + ok(conf_io_begin(true) == KNOT_EOK, "begin child txn %s", idx); + ok(conf_io_set("server", "version", NULL, idx) == + KNOT_EOK, "set single value '%s'", idx); + } + + for (int i = CONF_MAX_TXN_DEPTH - 1; i > 0; i--) { + char idx[2] = { '0' + i }; + ok(conf_io_commit(true) == KNOT_EOK, "commit child txn %s", idx); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + const char *data = conf_str(&val); + ok(*data == ('0' + CONF_MAX_TXN_DEPTH - 1), "compare txn data '%s'", data); + } + + ok(conf_io_commit(false) == KNOT_EOK, "commit parent txn"); + ok(conf()->io.txn == NULL, "check txn depth"); + + // Test child persistence after parent commit. + ok(conf_io_begin(false) == KNOT_EOK, "begin new parent txn"); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + char idx[2] = { '0' + CONF_MAX_TXN_DEPTH - 1 }; + const char *data = conf_str(&val); + ok(strcmp(data, idx) == 0, "compare final data '%s'", data); + conf_io_abort(false); + + // Test unchanged read_txn. + val = conf_get_txn(conf(), &conf()->read_txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); +#endif +} + +static void test_conf_io_check(void) +{ + conf_io_t io = { NULL }; + + // ERR no txn. + ok(conf_io_check(&io) == + KNOT_TXN_ENOTEXISTS, "check without active txn"); + + ok(conf_io_begin(false) == KNOT_EOK, "begin txn"); + + // Section check. + ok(conf_io_set("remote", "id", NULL, "remote1") == + KNOT_EOK, "set remote id"); + ok(conf_io_check(&io) == + KNOT_EINVAL, "check missing remote address"); + ok(io.error.code == KNOT_EINVAL, "compare error code"); + + ok(conf_io_set("remote", "address", "remote1", "1.1.1.1") == + KNOT_EOK, "set remote address"); + ok(conf_io_check(&io) == + KNOT_EOK, "check remote address"); + ok(io.error.code == KNOT_EOK, "compare error code"); + + // Item check. + ok(conf_io_set("zone", "domain", NULL, ZONE1) == + KNOT_EOK, "set zone domain "ZONE1); + ok(conf_io_set("zone", "master", ZONE1, "remote1") == + KNOT_EOK, "set zone master"); + + ok(conf_io_check(&io) == + KNOT_EOK, "check all"); + + ok(conf_io_unset("remote", NULL, NULL, NULL) == + KNOT_EOK, "unset remotes"); + + ok(conf_io_check(&io) == + KNOT_ENOENT, "check missing master remote"); + ok(io.error.code == KNOT_ENOENT, "compare error code"); + + conf_io_abort(false); +} + +static void test_conf_io_set(void) +{ + // ERR no txn. + ok(conf_io_set("server", "version", NULL, "text") == + KNOT_TXN_ENOTEXISTS, "set without active txn"); + + ok(conf_io_begin(false) == KNOT_EOK, "begin txn"); + + // ERR. + ok(conf_io_set(NULL, NULL, NULL, NULL) == + KNOT_EINVAL, "set NULL key0"); + ok(conf_io_set("", NULL, NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "set empty key0"); + ok(conf_io_set("unknown", NULL, NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "set unknown key0"); + ok(conf_io_set("server", "unknown", NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "set unknown key1"); + ok(conf_io_set("include", NULL, NULL, NULL) == + KNOT_YP_ENODATA, "set non-group without data"); + ok(conf_io_set("server", "background-workers", NULL, "x") == + KNOT_EINVAL, "set invalid data"); + + // ERR callback + ok(conf_io_set("include", NULL, NULL, "invalid") == + KNOT_EFILE, "set invalid callback value"); + + // Single group, no item, no value. + ok(conf_io_set("server", NULL, NULL, NULL) == + KNOT_ENOTSUP, "set group no value"); + // Single group, no item, value. + ok(conf_io_set("server", NULL, NULL, "text") == + KNOT_YP_ENOTSUP_DATA, "set group value"); + // Single group, item, no value. + ok(conf_io_set("server", "version", NULL, NULL) == + KNOT_YP_ENODATA, "set group item no value"); + + // Single group, single value. + ok(conf_io_set("server", "version", NULL, "text") == + KNOT_EOK, "set single value"); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + ok(strcmp(conf_str(&val), "text") == 0, "check entry value"); + + // Single group, multi value. + ok(conf_io_set("server", "listen", NULL, "1.1.1.1") == + KNOT_EOK, "set multivalue 1"); + ok(conf_io_set("server", "listen", NULL, "1.1.1.2") == + KNOT_EOK, "set multivalue 2"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_EOK, "check entry"); + ok(conf_val_count(&val) == 2, "check entry value count"); + + // Prepare dnames. + knot_dname_t *zone1 = knot_dname_from_str_alloc(ZONE1); + ok(zone1 != NULL, "create dname "ZONE1); + knot_dname_t *zone2 = knot_dname_from_str_alloc(ZONE2); + ok(zone2 != NULL, "create dname "ZONE2); + knot_dname_t *zone3 = knot_dname_from_str_alloc(ZONE3); + ok(zone3 != NULL, "create dname "ZONE3); + + // Multi group no id. + ok(conf_io_set("zone", "domain", NULL, NULL) == + KNOT_YP_ENOID, "set zone empty domain"); + + // Multi group ids. + ok(conf_io_set("zone", "domain", NULL, ZONE1) == + KNOT_EOK, "set zone domain "ZONE1); + ok(conf_io_set("zone", NULL, ZONE2, NULL) == + KNOT_EOK, "set zone domain "ZONE2); + + // Multi group, single value. + ok(conf_io_set("zone", "file", ZONE1, "name") == + KNOT_EOK, "set zone file"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_FILE, zone1); + ok(val.code == KNOT_EOK, "check entry"); + ok(strcmp(conf_str(&val), "name") == 0, "check entry value"); + + // Multi group, single value, bad id. + ok(conf_io_set("zone", "file", ZONE3, "name") == + KNOT_YP_EINVAL_ID, "set zone file"); + + // Multi group, single value, all ids. + ok(conf_io_set("zone", "comment", NULL, "abc") == + KNOT_EOK, "set zones comment"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_EOK, "check entry"); + ok(strcmp(conf_str(&val), "abc") == 0, "check entry value"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_EOK, "check entry"); + ok(strcmp(conf_str(&val), "abc") == 0, "check entry value"); + + // Prepare different comment. + ok(conf_io_set("zone", "domain", NULL, ZONE3) == + KNOT_EOK, "set zone domain "ZONE3); + ok(conf_io_set("zone", "comment", ZONE3, "xyz") == + KNOT_EOK, "set zone comment"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone3); + ok(val.code == KNOT_EOK, "check entry"); + ok(strcmp(conf_str(&val), "xyz") == 0, "check entry value"); + + knot_dname_free(zone1, NULL); + knot_dname_free(zone2, NULL); + knot_dname_free(zone3, NULL); + + ok(conf_io_commit(false) == KNOT_EOK, "commit txn"); + + // Update read-only transaction. + ok(conf_refresh_txn(conf()) == KNOT_EOK, "update read-only txn"); +} + +static void test_conf_io_unset(void) +{ + // ERR no txn. + ok(conf_io_unset("server", "version", NULL, "text") == + KNOT_TXN_ENOTEXISTS, "unset without active txn"); + + ok(conf_io_begin(false) == KNOT_EOK, "begin txn"); + + // ERR. + ok(conf_io_unset("", NULL, NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "unset unknown key0"); + ok(conf_io_unset("unknown", NULL, NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "unset unknown key0"); + ok(conf_io_unset("server", "unknown", NULL, NULL) == + KNOT_YP_EINVAL_ITEM, "unset unknown key1"); + ok(conf_io_unset("include", NULL, NULL, "file") == + KNOT_ENOTSUP, "unset non-group item"); + ok(conf_io_unset("server", "background-workers", NULL, "x") == + KNOT_EINVAL, "unset invalid data"); + + // Single group, single value. + ok(conf_io_unset("server", "version", NULL, "") == + KNOT_ENOENT, "unset zero length text value"); + conf_val_t val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + + ok(conf_io_unset("server", "version", NULL, "bad text") == + KNOT_ENOENT, "unset bad value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_EOK, "check entry"); + + ok(conf_io_unset("server", "version", NULL, "text") == + KNOT_EOK, "unset explicit value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + ok(conf_io_unset("server", "version", NULL, NULL) == + KNOT_EOK, "unset value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); + + // Single group, multi value. + ok(conf_io_unset("server", "listen", NULL, "9.9.9.9") == + KNOT_ENOENT, "unset bad value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_EOK, "check entry"); + + ok(conf_io_unset("server", "listen", NULL, "1.1.1.1") == + KNOT_EOK, "unset explicit value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_EOK, "check entry"); + ok(conf_val_count(&val) == 1, "check entry value count"); + + ok(conf_io_unset("server", "listen", NULL, NULL) == + KNOT_EOK, "unset value"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_ENOENT, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Whole section items. + ok(conf_io_unset("server", NULL, NULL, NULL) == + KNOT_EOK, "unset section"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_ENOENT, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Prepare dnames. + knot_dname_t *zone1 = knot_dname_from_str_alloc(ZONE1); + ok(zone1 != NULL, "create dname "ZONE1); + knot_dname_t *zone2 = knot_dname_from_str_alloc(ZONE2); + ok(zone2 != NULL, "create dname "ZONE2); + knot_dname_t *zone3 = knot_dname_from_str_alloc(ZONE3); + ok(zone3 != NULL, "create dname "ZONE3); + + // Multi group, single value. + ok(conf_io_unset("zone", "file", ZONE1, "name") == + KNOT_EOK, "unset zone file"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_FILE, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + + // Multi group, single bad value, all ids. + ok(conf_io_unset("zone", "comment", NULL, "other") == + KNOT_EOK, "unset zones comment"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_EOK, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_EOK, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone3); + ok(val.code == KNOT_EOK, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Multi group, single value (not all match), all ids. + ok(conf_io_unset("zone", "comment", NULL, "abc") == + KNOT_EOK, "unset some zones comment"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone3); + ok(val.code == KNOT_EOK, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Multi group, single value (all match), all ids. + ok(conf_io_unset("zone", "comment", NULL, NULL) == + KNOT_EOK, "unset all zones comment"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone3); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Multi group, all items, specific id. + ok(conf_io_unset("zone", NULL, ZONE1, NULL) == + KNOT_EOK, "unset zone items"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_FILE, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_EOK, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // Multi group, all items, all ids. + ok(conf_io_unset("zone", NULL, NULL, NULL) == + KNOT_EOK, "unset zone items"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_FILE, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + + // Restart transaction. + conf_io_abort(false); + ok(conf_io_begin(false) == KNOT_EOK, "restart txn"); + + // All groups. + ok(conf_io_unset(NULL, NULL, NULL, NULL) == + KNOT_EOK, "unset all"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_VERSION); + ok(val.code == KNOT_ENOENT, "check entry"); + val = conf_get_txn(conf(), conf()->io.txn, C_SERVER, C_LISTEN); + ok(val.code == KNOT_ENOENT, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_FILE, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone1); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + val = conf_zone_get_txn(conf(), conf()->io.txn, C_COMMENT, zone2); + ok(val.code == KNOT_YP_EINVAL_ID, "check entry"); + + knot_dname_free(zone1, NULL); + knot_dname_free(zone2, NULL); + knot_dname_free(zone3, NULL); + + conf_io_abort(false); +} + +static void test_conf_io_get(void) +{ + const char *ref; + char out[OUT_LEN]; + + conf_io_t io = { + .fcn = format_item, + .misc = out + }; + + // ERR no txn. + ok(conf_io_get("server", "version", NULL, false, &io) == + KNOT_TXN_ENOTEXISTS, "get without active txn"); + + // Get current, no active txn. + *out = '\0'; + ok(conf_io_get("server", "version", NULL, true, &io) == + KNOT_EOK, "get current without active txn"); + ref = "server.version = \"text\""; + ok(strcmp(ref, out) == 0, "compare result"); + + ok(conf_io_begin(false) == KNOT_EOK, "begin txn"); + + // ERR. + ok(conf_io_get("", NULL, NULL, true, &io) == + KNOT_YP_EINVAL_ITEM, "get empty key0"); + ok(conf_io_get("unknown", NULL, NULL, true, &io) == + KNOT_YP_EINVAL_ITEM, "get unknown key0"); + ok(conf_io_get("server", "unknown", NULL, true, &io) == + KNOT_YP_EINVAL_ITEM, "get unknown key1"); + ok(conf_io_get("include", NULL, NULL, true, &io) == + KNOT_ENOTSUP, "get non-group item"); + + // Update item in the active txn. + ok(conf_io_set("server", "version", NULL, "new text") == + KNOT_EOK, "set single value"); + + // Get new, active txn. + *out = '\0'; + ok(conf_io_get("server", "version", NULL, false, &io) == + KNOT_EOK, "get with active txn"); + ref = "server.version = \"new text\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Get current, active txn. + *out = '\0'; + ok(conf_io_get("server", "version", NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "server.version = \"text\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Multi value. + *out = '\0'; + ok(conf_io_get("server", "listen", NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "server.listen = \"1.1.1.1\" \"1.1.1.2\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Single group. + *out = '\0'; + ok(conf_io_get("server", NULL, NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "server.version = \"text\"\n" + "server.listen = \"1.1.1.1\" \"1.1.1.2\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Prepare dnames. + knot_dname_t *zone1 = knot_dname_from_str_alloc(ZONE1); + ok(zone1 != NULL, "create dname "ZONE1); + + // Multi group, all values, all ids. + *out = '\0'; + ok(conf_io_get("zone", NULL, NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "zone.domain = \"zone1.\"\n" + "zone[zone1.].file = \"name\"\n" + "zone[zone1.].comment = \"abc\"\n" + "zone.domain = \"zone2.\"\n" + "zone[zone2.].comment = \"abc\"\n" + "zone.domain = \"zone3.\"\n" + "zone[zone3.].comment = \"xyz\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Multi group ids. + *out = '\0'; + ok(conf_io_get("zone", "domain", NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "zone.domain = \"zone1.\"\n" + "zone.domain = \"zone2.\"\n" + "zone.domain = \"zone3.\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Multi group, all values, single id. + *out = '\0'; + ok(conf_io_get("zone", NULL, ZONE1, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "zone.domain = \"zone1.\"\n" + "zone[zone1.].file = \"name\"\n" + "zone[zone1.].comment = \"abc\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Multi group, single value, single id. + *out = '\0'; + ok(conf_io_get("zone", "file", ZONE1, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "zone[zone1.].file = \"name\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // All groups. + *out = '\0'; + ok(conf_io_get(NULL, NULL, NULL, true, &io) == + KNOT_EOK, "get with active txn"); + ref = "server.version = \"text\"\n" + "server.listen = \"1.1.1.1\" \"1.1.1.2\"\n" + "zone.domain = \"zone1.\"\n" + "zone[zone1.].file = \"name\"\n" + "zone[zone1.].comment = \"abc\"\n" + "zone.domain = \"zone2.\"\n" + "zone[zone2.].comment = \"abc\"\n" + "zone.domain = \"zone3.\"\n" + "zone[zone3.].comment = \"xyz\""; + ok(strcmp(ref, out) == 0, "compare result"); + + knot_dname_free(zone1, NULL); + + conf_io_abort(false); +} + +static void test_conf_io_diff(void) +{ + const char *ref; + char out[OUT_LEN]; + + conf_io_t io = { + .fcn = format_item, + .misc = out + }; + + // ERR no txn. + ok(conf_io_diff("server", "version", NULL, &io) == + KNOT_TXN_ENOTEXISTS, "diff without active txn"); + + ok(conf_io_begin(false) == KNOT_EOK, "begin txn"); + + // ERR. + ok(conf_io_diff("", NULL, NULL, &io) == + KNOT_YP_EINVAL_ITEM, "diff empty key0"); + ok(conf_io_diff("unknown", NULL, NULL, &io) == + KNOT_YP_EINVAL_ITEM, "diff unknown key0"); + ok(conf_io_diff("server", "unknown", NULL, &io) == + KNOT_YP_EINVAL_ITEM, "diff unknown key1"); + ok(conf_io_diff("include", NULL, NULL, &io) == + KNOT_ENOTSUP, "diff non-group item"); + + *out = '\0'; + ok(conf_io_diff(NULL, NULL, NULL, &io) == KNOT_EOK, "diff no change"); + ref = ""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Update singlevalued item. + ok(conf_io_set("server", "version", NULL, "new text") == + KNOT_EOK, "set single value"); + + *out = '\0'; + ok(conf_io_diff("server", "version", NULL, &io) == KNOT_EOK, "diff single item"); + ref = "-server.version = \"text\"\n" + "+server.version = \"new text\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Update multivalued item. + ok(conf_io_unset("server", "listen", NULL, "1.1.1.1") == + KNOT_EOK, "unset multivalue"); + ok(conf_io_set("server", "listen", NULL, "1.1.1.3") == + KNOT_EOK, "set multivalue"); + + *out = '\0'; + ok(conf_io_diff("server", "listen", NULL, &io) == KNOT_EOK, "diff multi item"); + ref = "-server.listen = \"1.1.1.1\" \"1.1.1.2\"\n" + "+server.listen = \"1.1.1.2\" \"1.1.1.3\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Unset single item. + ok(conf_io_unset("zone", "comment", ZONE3, NULL) == + KNOT_EOK, "unset multivalue"); + + *out = '\0'; + ok(conf_io_diff("zone", NULL, ZONE3, &io) == KNOT_EOK, "diff section"); + ref = "-zone[zone3.].comment = \"xyz\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // Unset id. + ok(conf_io_unset("zone", NULL, ZONE1, NULL) == + KNOT_EOK, "unset id"); + ok(conf_io_unset("zone", NULL, ZONE2, NULL) == + KNOT_EOK, "unset id"); + + *out = '\0'; + ok(conf_io_diff("zone", NULL, ZONE2, &io) == KNOT_EOK, "diff id section"); + ref = "-zone.domain = \"zone2.\"\n" + "-zone[zone2.].comment = \"abc\""; + ok(strcmp(ref, out) == 0, "compare result"); + + *out = '\0'; + ok(conf_io_diff("zone", "domain", NULL, &io) == KNOT_EOK, "diff id"); + ref = "-zone.domain = \"zone1.\"\n" + "-zone.domain = \"zone2.\""; + ok(strcmp(ref, out) == 0, "compare result"); + + *out = '\0'; + ok(conf_io_diff(NULL, NULL, NULL, &io) == KNOT_EOK, "diff whole change"); + ref = "-server.version = \"text\"\n" + "+server.version = \"new text\"\n" + "-server.listen = \"1.1.1.1\" \"1.1.1.2\"\n" + "+server.listen = \"1.1.1.2\" \"1.1.1.3\"\n" + "-zone.domain = \"zone1.\"\n" + "-zone[zone1.].file = \"name\"\n" + "-zone[zone1.].comment = \"abc\"\n" + "-zone.domain = \"zone2.\"\n" + "-zone[zone2.].comment = \"abc\"\n" + "-zone[zone3.].comment = \"xyz\""; + ok(strcmp(ref, out) == 0, "compare result"); + + conf_io_abort(false); +} + +static void test_conf_io_list(void) +{ + const char *ref; + char out[OUT_LEN]; + + conf_io_t io = { + .fcn = format_item, + .misc = out + }; + + // ERR. + ok(conf_io_list("", NULL, NULL, false, true, &io) == + KNOT_YP_EINVAL_ITEM, "list empty key0"); + ok(conf_io_list("unknown", NULL, NULL, false, true, &io) == + KNOT_YP_EINVAL_ITEM, "list unknown key0"); + ok(conf_io_list("include", NULL, NULL, false, true, &io) == + KNOT_EOK, "list non-group item"); + ok(conf_io_list("template", NULL, NULL, false, false, &io) == + KNOT_TXN_ENOTEXISTS, "no active txn"); + + // Desc schema. + *out = '\0'; + ok(conf_io_list(NULL, NULL, NULL, true, true, &io) == + KNOT_EOK, "list schema"); + ref = "server\n" + "xdp\n" + "control\n" + "remote\n" + "template\n" + "zone\n" + "include"; + ok(strcmp(ref, out) == 0, "compare result"); + + // Desc group. + *out = '\0'; + ok(conf_io_list("server", NULL, NULL, true, true, &io) == + KNOT_EOK, "list group"); + ref = "server.version\n" + "server.listen\n" + "server.tcp-idle-timeout\n" + "server.tcp-io-timeout\n" + "server.tcp-remote-io-timeout\n" + "server.tcp-max-clients\n" + "server.tcp-reuseport\n" + "server.tcp-fastopen\n" + "server.quic-max-clients\n" + "server.quic-idle-close-timeout\n" + "server.quic-outbuf-max-size\n" + "server.socket-affinity\n" + "server.udp-workers\n" + "server.tcp-workers\n" + "server.background-workers\n" + "server.udp-max-payload\n" + "server.udp-max-payload-ipv4\n" + "server.udp-max-payload-ipv6\n" + "server.edns-client-subnet\n" + "server.answer-rotation\n" + "server.automatic-acl\n" + "server.dbus-event"; + ok(strcmp(ref, out) == 0, "compare result"); + + // List item options. + *out = '\0'; + ok(conf_io_list("zone", "zonefile-load", NULL, true, true, &io) == + KNOT_EOK, "list item options"); + ref = "zone.zonefile-load = \"opt1\"\n" + "zone.zonefile-load = \"opt2\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // List zone identifiers 1. + *out = '\0'; + ok(conf_io_list("zone", NULL, NULL, false, true, &io) == + KNOT_EOK, "list zone identifiers 1"); + ref = "zone[zone1.]\n" + "zone[zone2.]\n" + "zone[zone3.]"; + ok(strcmp(ref, out) == 0, "compare result"); + + // List zone identifiers 2. + *out = '\0'; + ok(conf_io_list("zone", "domain", NULL, false, true, &io) == + KNOT_EOK, "list zone identifiers 2"); + ref = "zone = \"zone1.\"\n" + "zone = \"zone2.\"\n" + "zone = \"zone3.\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // List item values. + *out = '\0'; + ok(conf_io_list("server", "listen", NULL, false, true, &io) == + KNOT_EOK, "list item values"); + ref = "server.listen = \"1.1.1.1\" \"1.1.1.2\""; + ok(strcmp(ref, out) == 0, "compare result"); + + // List multi-group item values. + *out = '\0'; + ok(conf_io_list("zone", "file", "zone1", false, true, &io) == + KNOT_EOK, "list multi-group item values"); + ref = "zone[zone1.].file = \"name\""; + ok(strcmp(ref, out) == 0, "compare result"); +} + +static const yp_item_t desc_server[] = { + { C_VERSION, YP_TSTR, YP_VNONE }, + { C_LISTEN, YP_TADDR, YP_VNONE, YP_FMULTI }, + // Required config cache items - assert fix. + { C_TCP_IDLE_TIMEOUT, YP_TINT, YP_VNONE }, + { C_TCP_IO_TIMEOUT, YP_TINT, YP_VNONE }, + { C_TCP_RMT_IO_TIMEOUT, YP_TINT, YP_VNONE }, + { C_TCP_MAX_CLIENTS, YP_TINT, YP_VNONE }, + { C_TCP_REUSEPORT, YP_TBOOL, YP_VNONE }, + { C_TCP_FASTOPEN, YP_TBOOL, YP_VNONE }, + { C_QUIC_MAX_CLIENTS, YP_TINT, YP_VNONE }, + { C_QUIC_IDLE_CLOSE, YP_TINT, YP_VNONE }, + { C_QUIC_OUTBUF_MAX_SIZE, YP_TINT, YP_VNONE }, + { C_SOCKET_AFFINITY, YP_TBOOL, YP_VNONE }, + { C_UDP_WORKERS, YP_TINT, YP_VNONE }, + { C_TCP_WORKERS, YP_TINT, YP_VNONE }, + { C_BG_WORKERS, YP_TINT, YP_VNONE }, + { C_UDP_MAX_PAYLOAD, YP_TINT, YP_VNONE }, + { C_UDP_MAX_PAYLOAD_IPV4, YP_TINT, YP_VNONE }, + { C_UDP_MAX_PAYLOAD_IPV6, YP_TINT, YP_VNONE }, + { C_ECS, YP_TBOOL, YP_VNONE }, + { C_ANS_ROTATION, YP_TBOOL, YP_VNONE }, + { C_AUTO_ACL, YP_TBOOL, YP_VNONE }, + { C_DBUS_EVENT, YP_TOPT, YP_VNONE }, + { NULL } +}; + +static const yp_item_t desc_xdp[] = { + { C_UDP, YP_TBOOL, YP_VNONE }, + { C_TCP, YP_TBOOL, YP_VNONE }, + { C_QUIC, YP_TBOOL, YP_VNONE }, + { C_TCP_MAX_CLIENTS, YP_TINT, YP_VNONE }, + { C_TCP_INBUF_MAX_SIZE, YP_TINT, YP_VNONE }, + { C_TCP_OUTBUF_MAX_SIZE,YP_TINT, YP_VNONE }, + { C_TCP_IDLE_CLOSE, YP_TINT, YP_VNONE }, + { C_TCP_IDLE_RESET, YP_TINT, YP_VNONE }, + { C_TCP_RESEND, YP_TINT, YP_VNONE }, + { C_ROUTE_CHECK, YP_TBOOL, YP_VNONE }, + { NULL } +}; + +static const yp_item_t desc_control[] = { + { C_TIMEOUT, YP_TINT, YP_VNONE }, + { NULL } +}; + +static const yp_item_t desc_remote[] = { + { C_ID, YP_TSTR, YP_VNONE }, + { C_ADDR, YP_TADDR, YP_VNONE, YP_FMULTI }, + { NULL } +}; + +static const knot_lookup_t opts[] = { + { 1, "opt1" }, + { 2, "opt2" }, + { 0, NULL } +}; + +#define ZONE_ITEMS \ + { C_FILE, YP_TSTR, YP_VNONE }, \ + { C_MASTER, YP_TREF, YP_VREF = { C_RMT }, YP_FMULTI, { check_ref } }, \ + { C_ZONEFILE_LOAD, YP_TOPT, YP_VOPT = { opts, 0 } }, \ + { C_JOURNAL_CONTENT, YP_TOPT, YP_VOPT = { opts, 0 } }, \ + { C_DNSSEC_SIGNING, YP_TBOOL, YP_VNONE }, \ + { C_DNSSEC_VALIDATION, YP_TBOOL, YP_VNONE }, \ + { C_SERIAL_MODULO, YP_TSTR, YP_VSTR = { "0/1" } }, \ + { C_CATALOG_ROLE, YP_TOPT, YP_VOPT = { opts, 0 } }, \ + { C_CATALOG_TPL, YP_TREF, YP_VREF = { C_RMT } }, \ + { C_COMMENT, YP_TSTR, YP_VNONE }, + +static const yp_item_t desc_template[] = { + { C_ID, YP_TSTR, YP_VNONE }, + ZONE_ITEMS + { NULL } +}; + +static const yp_item_t desc_zone[] = { + { C_DOMAIN, YP_TDNAME, YP_VNONE }, + ZONE_ITEMS + { NULL } +}; + +const yp_item_t test_schema[] = { + { C_SRV, YP_TGRP, YP_VGRP = { desc_server } }, + { C_XDP, YP_TGRP, YP_VGRP = { desc_xdp } }, + { C_CTL, YP_TGRP, YP_VGRP = { desc_control } }, + { C_RMT, YP_TGRP, YP_VGRP = { desc_remote }, YP_FMULTI, { check_remote } }, + { C_TPL, YP_TGRP, YP_VGRP = { desc_template }, YP_FMULTI, { check_template } }, + { C_ZONE, YP_TGRP, YP_VGRP = { desc_zone }, YP_FMULTI, { check_zone } }, + { C_INCL, YP_TSTR, YP_VNONE, YP_FNONE, { include_file } }, + { NULL } +}; + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + ok(test_conf("", test_schema) == KNOT_EOK, "Prepare configuration"); + + diag("conf_io_begin"); + test_conf_io_begin(); + + diag("conf_io_abort"); + test_conf_io_abort(); + + diag("conf_io_commit"); + test_conf_io_commit(); + + diag("conf_io_check"); + test_conf_io_check(); + + diag("conf_io_set"); + test_conf_io_set(); + + diag("conf_io_unset"); + test_conf_io_unset(); + + diag("conf_io_get"); + test_conf_io_get(); + + diag("conf_io_diff"); + test_conf_io_diff(); + + diag("conf_io_list"); + test_conf_io_list(); + + conf_free(conf()); + + return 0; +} diff --git a/tests/knot/test_digest.c b/tests/knot/test_digest.c new file mode 100644 index 0000000..a694e49 --- /dev/null +++ b/tests/knot/test_digest.c @@ -0,0 +1,474 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include "knot/zone/digest.h" + +#include <string.h> +#include <tap/basic.h> + +#include "knot/zone/zonefile.h" +#include "libzscanner/scanner.h" + +// copy-pasted from knot/zone/zonefile.c +static void process_data(zs_scanner_t *scanner) +{ + zcreator_t *zc = scanner->process.data; + if (zc->ret != KNOT_EOK) { + scanner->state = ZS_STATE_STOP; + return; + } + + knot_dname_t *owner = knot_dname_copy(scanner->r_owner, NULL); + if (owner == NULL) { + zc->ret = KNOT_ENOMEM; + return; + } + + knot_rrset_t rr; + knot_rrset_init(&rr, owner, scanner->r_type, scanner->r_class, scanner->r_ttl); + + int ret = knot_rrset_add_rdata(&rr, scanner->r_data, scanner->r_data_length, NULL); + if (ret != KNOT_EOK) { + knot_rrset_clear(&rr, NULL); + zc->ret = ret; + return; + } + + ret = knot_rrset_rr_to_canonical(&rr); + if (ret != KNOT_EOK) { + knot_rrset_clear(&rr, NULL); + zc->ret = ret; + return; + } + + zc->ret = zcreator_step(zc, &rr); + knot_rrset_clear(&rr, NULL); +} + +static void process_error(zs_scanner_t *s) +{ + (void)s; + assert(0); +} + +static zone_contents_t *str2contents(const char *zone_str) +{ + knot_dname_txt_storage_t origin_str; + sscanf(zone_str, "%s", origin_str); // NOTE assuming that first token in zone_str is origin name! + + knot_dname_t *origin = knot_dname_from_str_alloc(origin_str); + assert(origin != NULL); + + zone_contents_t *cont = zone_contents_new(origin, false); + assert(cont != NULL); + knot_dname_free(origin, NULL); + + zcreator_t zc = { cont, true, KNOT_EOK }; + + zs_scanner_t sc; + ok(zs_init(&sc, origin_str, KNOT_CLASS_IN, 3600) == 0 && + zs_set_input_string(&sc, zone_str, strlen(zone_str)) == 0 && + zs_set_processing(&sc, process_data, process_error, &zc) == 0 && + zs_parse_all(&sc) == 0, "zscanner initialization"); + zs_deinit(&sc); + + return cont; +} + +static int check_contents(const char *zone_str) +{ + zone_contents_t *cont = str2contents(zone_str); + int ret = zone_contents_digest_verify(cont); + zone_contents_deep_free(cont); + return ret; +} + +const char *simple_zone = "\ +example. 86400 IN SOA ns1 admin 2018031900 ( \n\ + 1800 900 604800 86400 ) \n\ + 86400 IN NS ns1 \n\ + 86400 IN NS ns2 \n\ + 86400 IN ZONEMD 2018031900 1 1 ( \n\ + c68090d90a7aed71 \n\ + 6bc459f9340e3d7c \n\ + 1370d4d24b7e2fc3 \n\ + a1ddc0b9a87153b9 \n\ + a9713b3c9ae5cc27 \n\ + 777f98b8e730044c ) \n\ +ns1 3600 IN A 203.0.113.63 \n\ +ns2 3600 IN AAAA 2001:db8::63"; + +const char *complex_zone = "\ +example. 86400 IN SOA ns1 admin 2018031900 ( \n\ + 1800 900 604800 86400 ) \n\ + 86400 IN NS ns1 \n\ + 86400 IN NS ns2 \n\ + 86400 IN ZONEMD 2018031900 1 1 ( \n\ + a3b69bad980a3504 \n\ + e1cffcb0fd6397f9 \n\ + 3848071c93151f55 \n\ + 2ae2f6b1711d4bd2 \n\ + d8b39808226d7b9d \n\ + b71e34b72077f8fe ) \n\ +ns1 3600 IN A 203.0.113.63 \n\ +NS2 3600 IN AAAA 2001:db8::63 \n\ +occluded.sub 7200 IN TXT \"I'm occluded but must be digested\" \n\ +sub 7200 IN NS ns1 \n\ +duplicate 300 IN TXT \"I must be digested just once\" \n\ +duplicate 300 IN TXT \"I must be digested just once\" \n\ +foo.test. 555 IN TXT \"out-of-zone data must be excluded\" \n\ +UPPERCASE 3600 IN TXT \"canonicalize uppercase owner names\" \n\ +* 777 IN PTR dont-forget-about-wildcards \n\ +mail 3600 IN MX 20 MAIL1 \n\ +mail 3600 IN MX 10 Mail2.Example. \n\ +sortme 3600 IN AAAA 2001:db8::5:61 \n\ +sortme 3600 IN AAAA 2001:db8::3:62 \n\ +sortme 3600 IN AAAA 2001:db8::4:63 \n\ +sortme 3600 IN AAAA 2001:db8::1:65 \n\ +sortme 3600 IN AAAA 2001:db8::2:64 \n\ +non-apex 900 IN ZONEMD 2018031900 1 1 ( \n\ + 616c6c6f77656420 \n\ + 6275742069676e6f \n\ + 7265642e20616c6c \n\ + 6f77656420627574 \n\ + 2069676e6f726564 \n\ + 2e20616c6c6f7765 )"; + +const char *multiple_digests = "\ +example. 86400 IN SOA ns1 admin 2018031900 ( \n\ + 1800 900 604800 86400 ) \n\ +example. 86400 IN NS ns1.example. \n\ +example. 86400 IN NS ns2.example. \n\ +example. 86400 IN ZONEMD 2018031900 1 1 ( \n\ + 62e6cf51b02e54b9 \n\ + b5f967d547ce4313 \n\ + 6792901f9f88e637 \n\ + 493daaf401c92c27 \n\ + 9dd10f0edb1c56f8 \n\ + 080211f8480ee306 ) \n\ +example. 86400 IN ZONEMD 2018031900 1 2 ( \n\ + 08cfa1115c7b948c \n\ + 4163a901270395ea \n\ + 226a930cd2cbcf2f \n\ + a9a5e6eb85f37c8a \n\ + 4e114d884e66f176 \n\ + eab121cb02db7d65 \n\ + 2e0cc4827e7a3204 \n\ + f166b47e5613fd27 ) \n\ +example. 86400 IN ZONEMD 2018031900 1 240 ( \n\ + e2d523f654b9422a \n\ + 96c5a8f44607bbee ) \n\ +example. 86400 IN ZONEMD 2018031900 241 1 ( \n\ + e1846540e33a9e41 \n\ + 89792d18d5d131f6 \n\ + 05fc283e ) \n\ +ns1.example. 3600 IN A 203.0.113.63 \n\ +ns2.example. 86400 IN TXT \"This example has multiple digests\" \n\ +NS2.EXAMPLE. 3600 IN AAAA 2001:db8::63"; + +const char *signed_zone = "\ +uri.arpa. 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. 2018100702 10800 3600 1209600 3600 \n\ +uri.arpa. 3600 IN RRSIG SOA 8 2 3600 20210217232440 20210120232440 37444 uri.arpa. GzQw+QzwLDJr13REPGVmpEChjD1D2XlX0ie1DnWHpgaEw1E/dhs3lCN3 +BmHd4Kx3tffTRgiyq65HxR6feQ5v7VmAifjyXUYB1DZur1eP5q0Ms2y gCB3byoeMgCNsFS1oKZ2LdzNBRpy3oace8xQn1SpmHGfyrsgg+WbHKCT 1dY= \n\ +uri.arpa. 86400 IN NS a.iana-servers.net. \n\ +uri.arpa. 86400 IN NS b.iana-servers.net. \n\ +uri.arpa. 86400 IN NS c.iana-servers.net. \n\ +uri.arpa. 86400 IN NS ns2.lacnic.net. \n\ +uri.arpa. 86400 IN NS sec3.apnic.net. \n\ +uri.arpa. 86400 IN RRSIG NS 8 2 86400 20210217232440 20210120232440 37444 uri.arpa. M+Iei2lcewWGaMtkPlrhM9FpUAHXFkCHTVpeyrjxjEONeNgKtHZor5e4 V4qJBOzNqo8go/qJpWlFBm+T5Hn3asaBZVstFIYky38/C8UeRLPKq1hT THARYUlFrexr5fMtSUAVOgOQPSBfH3xBq/BgSccTdRb9clD+HE7djpqr LS4= \n\ +uri.arpa. 600 IN MX 10 pechora.icann.org. \n\ +uri.arpa. 600 IN RRSIG MX 8 2 600 20210217232440 20210120232440 37444 uri.arpa. kQAJQivmv6A5hqYBK8h6Z13ESY69gmosXwKI6WE09I8RFetfrxr24ecd nYd0lpnDtgNNSoHkYRSOoB+C4+zuJsoyAAzGo9uoWMWj97/2xeGhf3PT C9meQ9Ohi6hul9By7OR76XYmGhdWX8PBi60RUmZ1guslFBfQ8izwPqzu phs= \n\ +uri.arpa. 3600 IN NSEC ftp.uri.arpa. NS SOA MX RRSIG NSEC DNSKEY ZONEMD \n\ +uri.arpa. 3600 IN RRSIG NSEC 8 2 3600 20210217232440 20210120232440 37444 uri.arpa. dU/rXLM/naWd1+1PiWiYVaNJyCkiuyZJSccr91pJI673T8r3685B4ODM YFafZRboVgwnl3ZrXddY6xOhZL3n9V9nxXZwjLJ2HJUojFoKcXTlpnUy YUYvVQ2kj4GHAo6fcGCEp5QFJ2KbCpeJoS+PhKGRRx28icCiNT4/uXQv O2E= \n\ +uri.arpa. 3600 IN DNSKEY 256 3 8 AwEAAbMxuFuLeVDuOwIMzYOTD/bTREjLflo7wOi6ieIJhqltEzgjNzmW Jf9kGwwDmzxU7kbthMEhBNBZNn84zmcyRSCMzuStWveL7xmqqUlE3swL 8kLOvdZvc75XnmpHrk3ndTyEb6eZM7slh2C63Oh6K8VR5VkiZAkEGg0u ZIT3NjsF \n\ +uri.arpa. 3600 IN DNSKEY 257 3 8 AwEAAdkTaWkZtZuRh7/OobBUFxM+ytTst+bCu0r9w+rEwXD7GbDs0pIM hMenrZzoAvmv1fQxw2MGs6Ri6yPKfNULcFOSt9l8i6BVBLI+SKTY6XXe DUQpSEmSaxohHeRPMQFzpysfjxINp/L2rGtZ7yPmxY/XRiFPSO0myqwG Ja9r06Zw9CHM5UDHKWV/E+zxPFq/I7CfPbrrzbUotBX7Z6Vh3Sarllbe 8cGUB2UFNaTRgwB0TwDBPRD5ER3w2Dzbry9NhbElTr7vVfhaGWeOGuqA UXwlXEg6CrNkmJXJ2F1Rzr9WHUzhp7uWxhAbmJREGfi2dEyPAbUAyCjB qhFaqglknvc= \n\ +uri.arpa. 3600 IN DNSKEY 257 3 8 AwEAAenQaBoFmDmvRT+/H5oNbm0Tr5FmNRNDEun0Jpj/ELkzeUrTWhNp QmZeIMC8I0kZ185tEvOnRvn8OvV39B17QIdrvvKGIh2HlgeDRCLolhao jfn2QM0DStjF/WWHpxJOmE6CIuvhqYEU37yoJscGAPpPVPzNvnL1HhYT aao1VRYWQ/maMrJ+bfHg+YX1N6M/8MnRjIKBif1FWjbCKvsn6dnuGGL9 oCWYUFJ3DwofXuhgPyZMkzPc88YkJj5EMvbMH4wtelbCwC+ivx732l0w /rXJn0ciQSOgoeVvDio8dIJmWQITWQAuP+q/ZHFEFHPlrP3gvQh5mcVS 48eLX71Bq7c= \n\ +uri.arpa. 3600 IN RRSIG DNSKEY 8 2 3600 20210217232440 20210120232440 12670 uri.arpa. DBE2gkKAoxJCfz47KKxzoImN/0AKArhIVHE7TyTwy0DdRPo44V5R+vL6 thUxlQ1CJi2Rw0jwAXymx5Y3Q873pOEllH+4bJoIT4dmoBmPXfYWW7Cl vw9UPKHRP0igKHmCVwIeBYDTU3gfLcMTbR4nEWPDN0GxlL1Mf7ITaC2I oabo79Ip3M/MR8I3Vx/xZ4ZKKPHtLn3xUuJluPNanqJrED2gTslL2xWZ 1tqjsAjJv7JnJo2HJ8XVRB5zBto0IaJ2oBlqcjdcQ/0VlyoM8uOy1pDw HQ2BJl7322gNMHBP9HSiUPIOaIDNUCwW8eUcW6DIUk+s9u3GN1uTqwWz sYB/rA== \n\ +uri.arpa. 3600 IN RRSIG DNSKEY 8 2 3600 20210217232440 20210120232440 30577 uri.arpa. Kx6HwP4UlkGc1UZ7SERXtQjPajOF4iUvkwDj7MEG1xbQFB1KoJiEb/ei W0qmSWdIhMDv8myhgauejRLyJxwxz8HDRV4xOeHWnRGfWBk4XGYwkejV zOHzoIArVdUVRbr2JKigcTOoyFN+uu52cNB7hRYu7dH5y1hlc6UbOnzR pMtGxcgVyKQ+/ARbIqGG3pegdEOvV49wTPWEiyY65P2urqhvnRg5ok/j zwAdMx4XGshiib7Ojq0sRVl2ZIzj4rFgY/qsSO8SEXEhMo2VuSkoJNio fVzYoqpxEeGnANkIT7Tx2xJL1BWyJxyc7E8Wr2QSgCcc+rYL6IkHDtJG Hy7TaQ== \n\ +uri.arpa. 3600 IN ZONEMD 2018100702 1 1 0DBC3C4DBFD75777C12CA19C337854B1577799901307C482E9D91D5D 15CD934D16319D98E30C4201CF25A1D5A0254960 \n\ +uri.arpa. 3600 IN RRSIG ZONEMD 8 2 3600 20210217232440 20210120232440 37444 uri.arpa. QDo4XZcL3HMyn8aAHyCUsu/Tqj4Gkth8xY1EqByOb8XOTwVtA4ZNQORE 1siqNqjtJUbeJPtJSbLNqCL7rCq0CzNNnBscv6IIf4gnqJZjlGtHO30o hXtKvEc4z7SU3IASsi6bB3nLmEAyERdYSeU6UBfx8vatQDIRhkgEnnWU Th4= \n\ +ftp.uri.arpa. 604800 IN NAPTR 0 0 \"\" \"\" \"!^ftp://([^:/?#]*).*$!\\\\1!i\" . \n\ +ftp.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 20210217232440 20210120232440 37444 uri.arpa. EygekDgl+Lyyq4NMSEpPyOrOywYf9Y3FAB4v1DT44J3R5QGidaH8l7ZF jHoYFI8sY64iYOCV4sBnX/dh6C1L5NgpY+8l5065Xu3vvjyzbtuJ2k6Y YwJrrCbvl5DDn53zAhhO2hL9uLgyLraZGi9i7TFGd0sm3zNyUF/EVL0C cxU= \n\ +ftp.uri.arpa. 3600 IN NSEC http.uri.arpa. NAPTR RRSIG NSEC \n\ +ftp.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 20210217232440 20210120232440 37444 uri.arpa. pbP4KxevPXCu/bDqcvXiuBppXyFEmtHyiy0eAN5gS7mi6mp9Z9bWFjx/ LdH9+6oFGYa5vGmJ5itu/4EDMe8iQeZbI8yrpM4TquB7RR/MGfBnTd8S +sjyQtlRYG7yqEu77Vd78Fme22BKPJ+MVqjS0JHMUE/YUGomPkAjLJJw wGw= \n\ +http.uri.arpa. 604800 IN NAPTR 0 0 \"\" \"\" \"!^http://([^:/?#]*).*$!\\\\1!i\" . \n\ +http.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 20210217232440 20210120232440 37444 uri.arpa. eTqbWvt1GvTeXozuvm4ebaAfkXFQKrtdu0cEiExto80sHIiCbO0WL8UD a/J3cDivtQca7LgUbOb6c17NESsrsVkc6zNPx5RK2tG7ZQYmhYmtqtfg 1oU5BRdHZ5TyqIXcHlw9Blo2pir1Y9IQgshhD7UOGkbkEmvB1Lrd0aHh AAg= \n\ +http.uri.arpa. 3600 IN NSEC mailto.uri.arpa. NAPTR RRSIG NSEC \n\ +http.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 20210217232440 20210120232440 37444 uri.arpa. R9rlNzw1CVz2N08q6DhULzcsuUm0UKcPaGAWEU40tr81jEDHsFHNM+kh CdOI8nDstzA42aee4rwCEgijxJpRCcY9hrO1Ysrrr2fdqNz60JikMdar vU5O0p0VXeaaJDfJQT44+o+YXaBwI7Qod3FTMx7aRib8i7istvPm1Rr7 ixA= \n\ +mailto.uri.arpa. 604800 IN NAPTR 0 0 \"\" \"\" \"!^mailto:(.*)@(.*)$!\\\\2!i\" . \n\ +mailto.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 20210217232440 20210120232440 37444 uri.arpa. Ch2zTG2F1plEvQPyIH4Yd80XXLjXOPvMbiqDjpJBcnCJsV8QF7kr0wTL nUT3dB+asQudOjPyzaHGwFlMzmrrAsszN4XAMJ6htDtFJdsgTMP/NkHh YRSmVv6rLeAhd+mVfObY12M//b/GGVTjeUI/gJaLW0fLVZxr1Fp5U5CR jyw= \n\ +mailto.uri.arpa. 3600 IN NSEC urn.uri.arpa. NAPTR RRSIG NSEC \n\ +mailto.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 20210217232440 20210120232440 37444 uri.arpa. fQUbSIE6E7JDi2rosah4SpCOTrKufeszFyj5YEavbQuYlQ5cNFvtm8Ku E2xXMRgRI4RGvM2leVqcoDw5hS3m2pOJLxH8l2WE72YjYvWhvnwc5Rof e/8yB/vaSK9WCnqN8y2q6Vmy73AGP0fuiwmuBra7LlkOiqmyx3amSFiz wms= \n\ +urn.uri.arpa. 604800 IN NAPTR 0 0 \"\" \"\" \"/urn:([^:]+)/\\\\1/i\" . \n\ +urn.uri.arpa. 604800 IN RRSIG NAPTR 8 3 604800 20210217232440 20210120232440 37444 uri.arpa. CVt2Tgz0e5ZmaSXqRfNys/8OtVCk9nfP0zhezhN8Bo6MDt6yyKZ2kEEW JPjkN7PCYHjO8fGjnUn0AHZI2qBNv7PKHcpR42VY03q927q85a65weOO 1YE0vPYMzACpua9TOtfNnynM2Ws0uN9URxUyvYkXBdqOC81N3sx1dVEL cwc= \n\ +urn.uri.arpa. 3600 IN NSEC uri.arpa. NAPTR RRSIG NSEC \n\ +urn.uri.arpa. 3600 IN RRSIG NSEC 8 3 3600 20210217232440 20210120232440 37444 uri.arpa. JuKkMiC3/j9iM3V8/izcouXWAVGnSZjkOgEgFPhutMqoylQNRcSkbEZQ zFK8B/PIVdzZF0Y5xkO6zaKQjOzz6OkSaNPIo1a7Vyyl3wDY/uLCRRAH RJfpknuY7O+AUNXvVVIEYJqZggd4kl/Rjh1GTzPYZTRrVi5eQidI1LqC Oeg="; + +const char *nsec3_zone = "\ +arpa. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2021051902 1800 900 604800 86400 \n\ +arpa. 518400 IN NS a.root-servers.net. \n\ +arpa. 518400 IN NS b.root-servers.net. \n\ +arpa. 518400 IN NS c.root-servers.net. \n\ +arpa. 518400 IN NS d.root-servers.net. \n\ +arpa. 518400 IN NS e.root-servers.net. \n\ +arpa. 518400 IN NS f.root-servers.net. \n\ +arpa. 518400 IN NS g.root-servers.net. \n\ +arpa. 518400 IN NS h.root-servers.net. \n\ +arpa. 518400 IN NS i.root-servers.net. \n\ +arpa. 518400 IN NS k.root-servers.net. \n\ +arpa. 518400 IN NS l.root-servers.net. \n\ +arpa. 518400 IN NS m.root-servers.net. \n\ +arpa. 518400 IN RRSIG NS 8 1 518400 20210616170429 20210519170429 29094 arpa. gyq/RdMYEGuTElq9QCbqmZSEUAF3aeBc+MGOMVK0hgmYKfVr8DDrh9UZJy4Ht+24+FHXGgAh8OkW4UbnmiIHQnsSflbQiyHljNYZGX3/H2fUs2FFWAjjAww2iPKuuPUkHgjZZQk0683FQuI9Ium0VK7dXGAvNKFh4Ay4LMjkQ6Y= \n\ +arpa. 86400 IN RRSIG SOA 8 1 86400 20210616170429 20210519170429 29094 arpa. BnSptCxxljkkYItDfsphqUzCz4fALNhOqWrLtYx5aDRWAydcG0N7owhGTqy56VBop+lTzYKmlHfO5/bb/fRCYAXkDhsmVEqS00cDYTqpygTJbVB8Xd+ia1tBeF8cqsbngRhigF4y0cts+bkn7Wrvw21j7nhs01KROimudGH08hs= \n\ +arpa. 86400 IN RRSIG DNSKEY 8 1 86400 20210616170429 20210519170429 18949 arpa. be6sPsu3+7kzDMkAHDsUM0FSoUhULtajWemX95PIVS4wpiEpVMsvF71YLIGRTzw+GfFI2NgsL/idFbUW2Fo7bZIBhbj8JXyZwvsoxt+cLfSfZtVGllKO1XQn5u7/PGU6U8YRSyzRA+ocpdjKqyohkMmOqiqkM7mOSvchDkcZDiw= \n\ +arpa. 3600 IN RRSIG NSEC3PARAM 8 1 3600 20210616170429 20210519170429 29094 arpa. CHmmYN1DJGWraPdMPurcXadDO7ODWoz6gv0B7ln0Gwz5L4Mwb5SEtGAinO5R0T2M4OxQEkN0xhy73VERrZb5FvsxyEGJu0M5S6icvyKkJ1Zq+US5b3FX6MI/bIKu2pI5x7/ubpzWKZJ9itNWBRONBiuBsGT9c3Tb2IreuQWziH0= \n\ +arpa. 86400 IN RRSIG TYPE63 8 1 86400 20210616170429 20210519170429 29094 arpa. Aqb9IQoNaga9euw67potZbiQYeyEAqd/zVYhDFxfLNfC4Qf6v7aPxW8Tyl+foNob91/KX5JGcS5tD4pq+G+IV+heLRH57s+moF3C0lsid8oZLqCbctmR/hr0YUQc5+dGQ/iy2erEPZq1W4eLsWX+YlUsQfajb5y4ggp7OMTmRuY= \n\ +arpa. 86400 IN DNSKEY 256 3 8 AwEAAdMaRW2okM0GrfInisiH9HWsqokdnmeXnJjKUwVQ8dy5sxm0DyCtzNapj54SF4ofgJxYufQCzYoe3Y3WsB6dKW15pTvu6ggqwuTTxvAnkMSHAlMGBE0sybRBIM38WswPcjAXmpITj7Zvgm8qh80dcusK5vwqJhb2CDWHRezUwiIB ;{id = 29094 (zsk), size = 1024b} \n\ +arpa. 86400 IN DNSKEY 257 3 8 AwEAAdQP1t2ookuQYFNUNGDmLHcoA6LFSImvULaUgChKiIO6Vv5yDyHB0Ng6ZkfHM0586cLcbXNBLj/9u5A4vqzOFj8phzW4WLZREZBLYMcuHhvQdqzuDJ0J5mxmLLis5eNaCwukVm6Zpf/otzCJsx9LyrhQBTyx6FF+h7dbSCvjh7tD ;{id = 18949 (ksk), size = 1024b} \n\ +arpa. 3600 IN NSEC3PARAM 1 0 1 - \n\ +arpa. 86400 IN TYPE63 \\# 54 7876cdfe01019a84145013e13e3de2328868888c65aa46b7381213990f83d496c642d2324029cc852e09bffa38afd8e9197977776591 \n\ +0js82oec35lbbc4hl35476cm5icacksf.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. PRVkH4+Nm17QlFgwFLnoqwaiIwWZ4pvscanHdMb6HOKkSxwtDoWAGhZubvYGt/Je735nQkGQPPXW2tkMkJa3D7e6RkX/8AoxcqqXOimC6BlG6LuSL4rSousDlbrulyh87qgIHXkUtrHyYUNAMZMKOjMHo7t5IxwjBO0SGADoglk= \n\ +0js82oec35lbbc4hl35476cm5icacksf.arpa. 86400 IN NSEC3 1 0 1 - 2UB8EN7BK0T6DENIGO3I729IVQVME3VE NS \n\ +2ub8en7bk0t6denigo3i729ivqvme3ve.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. JsSiqDiPs0juQxKEcCKTFvKXzUdvIvCILEzcN79+qAxaiQuulHUxTSMDvrsxm83m9juvoOUYtBlPyZdI9erAfiEkpF71ZIl8iP7AKGgqTeV1C4SHnf2KsFi69qimdLbWeIfFGYEq+54Vj5vF1SrRounvj63avhI/Zf0tTWz11+4= \n\ +2ub8en7bk0t6denigo3i729ivqvme3ve.arpa. 86400 IN NSEC3 1 0 1 - 3MKQ4F9MV3H6JSJNUJ6G31KRJLHKN9KJ NS DS RRSIG \n\ +3mkq4f9mv3h6jsjnuj6g31krjlhkn9kj.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. NAt7ul6uWzK19LyTcxbtfIt0SppVHyVjj4S/j0zxqcOH7gkJwf36+uIsb0lP7QzdYoB7dDeMFKnZfOCjBu+OkXTnOmfdwS5XA5OTM3dpi6g8plVRkcBDoWqz+UtQljD66A2XyuVl5vBmhP3OWe8TnlnA3jrHYO5zneEM/MdsoEE= \n\ +3mkq4f9mv3h6jsjnuj6g31krjlhkn9kj.arpa. 86400 IN NSEC3 1 0 1 - BA4462JFP3IQK2KT4COIMT6532KSV55K NS DS RRSIG \n\ +as112.arpa. 172800 IN NS a.iana-servers.net. \n\ +as112.arpa. 172800 IN NS b.iana-servers.net. \n\ +as112.arpa. 172800 IN NS c.iana-servers.net. \n\ +as112.arpa. 86400 IN DS 20236 8 1 1307e5595598b25fe2eb07bcef767c9d96c3ecdc \n\ +as112.arpa. 86400 IN DS 20236 8 2 72c9e5d15accc54a32c8c76fe5944bcbf3aabc2b13dc417609763e57bd89d515 \n\ +as112.arpa. 86400 IN DS 49400 8 1 0236339d6c1fb0fdf6069a9babe455b443fe2f95 \n\ +as112.arpa. 86400 IN DS 49400 8 2 f8e230e43e20e14200e46beb6e0a67ced274790c8c8c169df7fec5fb7dfa321f \n\ +as112.arpa. 86400 IN DS 53690 8 1 85d712965f3aa6556f40e11ba29c638565444acf \n\ +as112.arpa. 86400 IN DS 53690 8 2 354c6ef7b8b46a4c87ce6a21f3a9043898e68427ad64d029097ce2a38933b82e \n\ +as112.arpa. 86400 IN RRSIG DS 8 2 86400 20210616170429 20210519170429 29094 arpa. Hs6t8f1s8NCPO1yzQIqCWWpGADwHqTVLCRVJIxMkpiWpDPP8zXxQRFp2BHNQ8jAcsp5w5OwIfIR27+5N7O73/y5qjcjDe6Yyzeh7L/nut0fuOuqne47a6VkuXJHmdilGeNFitAFZ+1iP9KnFVxb3NxNLByemx8mO30jYDw14O4Y= \n\ +ba4462jfp3iqk2kt4coimt6532ksv55k.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. MrpAQuo8eH4CAA2jjsLHGiMJ8DexXMDI7LHzQbX7k5L4oUTtBNoTnKFdxqKdxZoEXvO39GB5s0nD0qgR8g5xFAFfj+pcF2y4GC+LqXqV5N6gXKa23zEEN5mfxSuwnQ/JXw95ct2IuQkuU80MIU0ZdE/FVhSyHnlJYMGE3uB2DyY= \n\ +ba4462jfp3iqk2kt4coimt6532ksv55k.arpa. 86400 IN NSEC3 1 0 1 - C26TIAI64HA5JPB4P8KII6P9JHH3TJFH NS DS RRSIG \n\ +c26tiai64ha5jpb4p8kii6p9jhh3tjfh.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. FSQuCmqKEUtYHqhkXDC8uikAIi5ZpMtS14jeaeWEn6Mip3uP1pFNuSQHgFhX9L20hdbeuOG3ribTqs3d4kz9VQ51g4KqD3uhHMVuQZyzpBJWq4Xwynt9cetvSK0f/kaf/wtAARo9HLkciJTBYiYUmYZVdmknIto4TqDNy2kkMrA= \n\ +c26tiai64ha5jpb4p8kii6p9jhh3tjfh.arpa. 86400 IN NSEC3 1 0 1 - DKAS8UE0E261D6338P2GMF52ALH64LA6 NS DS RRSIG \n\ +dkas8ue0e261d6338p2gmf52alh64la6.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. pPD9lqm6kAoLwagCrQwBWBq4McfrHywg4RkQ20ZjuVcnmopggO6UkjlmYUnBn53Si5eqRY9CwtSEvYjKztXcyXnkwbD1xWExAsYucRYVbUPZmOllulYezphTHi1Qp7fRrhEjb/TCYcBUXvLJfU+S9OeVqefruYnIw3VevMPp518= \n\ +dkas8ue0e261d6338p2gmf52alh64la6.arpa. 86400 IN NSEC3 1 0 1 - EARMJ48JEL1C2RDHIGD36N68U3V8Q1KV NS DS RRSIG \n\ +e164.arpa. 172800 IN NS ns3.lacnic.net. \n\ +e164.arpa. 172800 IN NS ns3.afrinic.net. \n\ +e164.arpa. 172800 IN NS ns4.apnic.net. \n\ +e164.arpa. 172800 IN NS pri.authdns.ripe.net. \n\ +e164.arpa. 172800 IN NS rirns.arin.net. \n\ +e164.arpa. 86400 IN DS 46334 8 2 550664875d1121c6edd01f9602577640fed5ad19a749ae1e3fd68476af454578 \n\ +e164.arpa. 86400 IN RRSIG DS 8 2 86400 20210616170429 20210519170429 29094 arpa. A07roaG8r7ns0YydNMhaURb741akipIL8UCgRRMAs3BzzneUtXW3EmS50C7vxb5ikH84a39FerXHOetifGTKETjVMtuQmdPw1F8ClHMkWfdRyR5a+lWwosV3fgnSItoekfbggUZop1dZxzie93pv4RM89Jf/SMlOW/3bYJ1p7Hk= \n\ +earmj48jel1c2rdhigd36n68u3v8q1kv.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. yNYXtZ4dGDdJW3VNoLRtktV93mZmQsQv3Tvy6+iBTGx+W7T0ipSCZq+l5yvblfqGKXXnWWzYf/xKktaLmXnAzvdsacWaKGtudvvtSwLkhlxNWlL018Eoe2md0tsSLd5tSiTbufahrd4p1lv09ne//sGoSw/amfvY5hsRvmnhNhA= \n\ +earmj48jel1c2rdhigd36n68u3v8q1kv.arpa. 86400 IN NSEC3 1 0 1 - H2D0RTQ108UOOUB5UDNN9D2PGQBVABC9 NS DS RRSIG \n\ +h2d0rtq108uooub5udnn9d2pgqbvabc9.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. isNpvWJ3TpDmEl66a9J9Q2GdlNqh9HculGjNFVIbiSfTb5aNgCITkgrKSoxjfZ8go3pDSeqwo5fhaBlbZQ4xGNGlc/T5U2qh2hJPGZpBwHYkR9a1YzMhzMx33oRXfMzsuC+6sasS8BLRHPmS4X89jPeA+lItEJPd1rQlHb1wt1I= \n\ +h2d0rtq108uooub5udnn9d2pgqbvabc9.arpa. 86400 IN NSEC3 1 0 1 - KSH70CK6POGI86ENT4ONT3I9UJ71QE8K NS SOA RRSIG DNSKEY NSEC3PARAM TYPE63 \n\ +home.arpa. 172800 IN NS blackhole-1.iana.org. \n\ +home.arpa. 172800 IN NS blackhole-2.iana.org. \n\ +in-addr.arpa. 172800 IN NS a.in-addr-servers.arpa. \n\ +in-addr.arpa. 172800 IN NS b.in-addr-servers.arpa. \n\ +in-addr.arpa. 172800 IN NS c.in-addr-servers.arpa. \n\ +in-addr.arpa. 172800 IN NS d.in-addr-servers.arpa. \n\ +in-addr.arpa. 172800 IN NS e.in-addr-servers.arpa. \n\ +in-addr.arpa. 172800 IN NS f.in-addr-servers.arpa. \n\ +in-addr.arpa. 86400 IN DS 47054 8 2 5cafccec201d1933b4c9f6a9c8f51e51f3b39979058ac21b8df1b1f281cbc6f2 \n\ +in-addr.arpa. 86400 IN DS 53696 8 2 13e5501c56b20394da921b51412d48b7089c5eb6957a7c58553c4d4d424f04df \n\ +in-addr.arpa. 86400 IN DS 63982 8 2 aaf4fb5d213ef25ae44679032ebe3514c487d7abd99d7f5fec3383d030733c73 \n\ +in-addr.arpa. 86400 IN RRSIG DS 8 2 86400 20210616170429 20210519170429 29094 arpa. lr32Q5rTcwVyBASuYq2Mc1t8XPCSSXJDNtK+MzisWifCZ0b0m/GARo34QKR2y3afqeFdqVXWrYrBVjAF2Rg21izsWqpMNyfLloesNNl63A9uQi4dFT3Zfz3OdQOGhWcy51ydn8KVtieIubRTBQAgExgZsDzyRC4PXjzh4Jj872g= \n\ +in-addr-servers.arpa. 172800 IN NS a.in-addr-servers.arpa. \n\ +in-addr-servers.arpa. 172800 IN NS b.in-addr-servers.arpa. \n\ +in-addr-servers.arpa. 172800 IN NS c.in-addr-servers.arpa. \n\ +in-addr-servers.arpa. 172800 IN NS d.in-addr-servers.arpa. \n\ +in-addr-servers.arpa. 172800 IN NS e.in-addr-servers.arpa. \n\ +in-addr-servers.arpa. 172800 IN NS f.in-addr-servers.arpa. \n\ +in-addr-servers.arpa. 86400 IN DS 1987 8 2 dacfdeb02a489a514c6408d0d54e0904fe6e09a6e111abc9eacb27f6552805e1 \n\ +in-addr-servers.arpa. 86400 IN DS 45104 8 2 50136f7a8d3ffe4f9887ad234ff8ce945cabd331feb12569b2f61f99ce40fdbf \n\ +in-addr-servers.arpa. 86400 IN DS 62996 8 2 836537710efc1e5570e3aeff7c0c80d3957a16ddf8005034bc9082898968dc81 \n\ +in-addr-servers.arpa. 86400 IN RRSIG DS 8 2 86400 20210616170429 20210519170429 29094 arpa. j+2AVMMc1xfd/ua7lHpNQUr95kUTcr8SIQJk6prTkYnPdDvMNZPIhhdVNw7WzFjIvGLF3iumbYY46I3KN3P1eZUKtn0OFvTZ/UG/tlbWaj473XNxWnbwp8sPuT46nuLH6P14gNEhbPGGrh2VE+hFPkM/4ZdfwlCbDC5vEsQNYko= \n\ +a.in-addr-servers.arpa. 172800 IN A 199.180.182.53 \n\ +a.in-addr-servers.arpa. 172800 IN AAAA 2620:37:e000::53 \n\ +b.in-addr-servers.arpa. 172800 IN A 199.253.183.183 \n\ +b.in-addr-servers.arpa. 172800 IN AAAA 2001:500:87::87 \n\ +c.in-addr-servers.arpa. 172800 IN A 196.216.169.10 \n\ +c.in-addr-servers.arpa. 172800 IN AAAA 2001:43f8:110::10 \n\ +d.in-addr-servers.arpa. 172800 IN A 200.10.60.53 \n\ +d.in-addr-servers.arpa. 172800 IN AAAA 2001:13c7:7010::53 \n\ +e.in-addr-servers.arpa. 172800 IN A 203.119.86.101 \n\ +e.in-addr-servers.arpa. 172800 IN AAAA 2001:dd8:6::101 \n\ +f.in-addr-servers.arpa. 172800 IN A 193.0.9.1 \n\ +f.in-addr-servers.arpa. 172800 IN AAAA 2001:67c:e0::1 \n\ +ip6.arpa. 172800 IN NS a.ip6-servers.arpa. \n\ +ip6.arpa. 172800 IN NS b.ip6-servers.arpa. \n\ +ip6.arpa. 172800 IN NS c.ip6-servers.arpa. \n\ +ip6.arpa. 172800 IN NS d.ip6-servers.arpa. \n\ +ip6.arpa. 172800 IN NS e.ip6-servers.arpa. \n\ +ip6.arpa. 172800 IN NS f.ip6-servers.arpa. \n\ +ip6.arpa. 86400 IN DS 13880 8 2 068554efcb5861f42af93ef8e79c442a86c16fc5652e6b6d2419ed527f344d17 \n\ +ip6.arpa. 86400 IN DS 45094 8 2 e6b54e0a20ce1edbfcb6879c02f5782059cecb043a31d804a04afa51af01d5fb \n\ +ip6.arpa. 86400 IN DS 64060 8 2 8a11501086330132be2c23f22dedf0634ad5ff668b4aa1988e172c6a2a4e5f7b \n\ +ip6.arpa. 86400 IN RRSIG DS 8 2 86400 20210616170429 20210519170429 29094 arpa. aNklM0l2ixPusry6KMt0PYGuKgLXqAJArq3KSZgG0QgMjGC0ChVwAO2+vq4wwR8QuqA6vAWHKKpw79l8MYV9I7+a50WPFyEOugl1s+konVjzkgMboPaOZbg52g47mPdQ7Q0N9MPLA8/FJx13cHauimQjZ+1FOiiWhveqgR2Jg8o= \n\ +ip6-servers.arpa. 172800 IN NS a.ip6-servers.arpa. \n\ +ip6-servers.arpa. 172800 IN NS b.ip6-servers.arpa. \n\ +ip6-servers.arpa. 172800 IN NS c.ip6-servers.arpa. \n\ +ip6-servers.arpa. 172800 IN NS d.ip6-servers.arpa. \n\ +ip6-servers.arpa. 172800 IN NS e.ip6-servers.arpa. \n\ +ip6-servers.arpa. 172800 IN NS f.ip6-servers.arpa. \n\ +ip6-servers.arpa. 86400 IN DS 16169 8 2 27fb5354c3c011c2851ee25ba32929b645d63262779ac101a6f28cd631991269 \n\ +ip6-servers.arpa. 86400 IN DS 19720 8 2 f154d00f5759c274de9cad621910cc0b87d720d35b7de4b0b566e135196c38e2 \n\ +ip6-servers.arpa. 86400 IN DS 54832 8 2 ff0d5f44a086a7a31b99c81cfd1135524b5896878e6de78f12b3f609bf7279dc \n\ +ip6-servers.arpa. 86400 IN RRSIG DS 8 2 86400 20210616170429 20210519170429 29094 arpa. fYShlxJWViKV2SbFCqyxUa64AKAedJ2udqcw/VtKNxg2T6i5IQzFc2aPB7V/+MtE64vHWwbrThgOvNC4Xmc7jVqKNsSc1X4Q8ZSQy+/CgmS5pBkI4XpLBb6kTUJMGorgAOI1ek1OMpl25mGmeJ6lE8e5PTNUisz/7ybIx5pBTz0= \n\ +a.ip6-servers.arpa. 172800 IN A 199.180.182.53 \n\ +a.ip6-servers.arpa. 172800 IN AAAA 2620:37:e000::53 \n\ +b.ip6-servers.arpa. 172800 IN A 199.253.182.182 \n\ +b.ip6-servers.arpa. 172800 IN AAAA 2001:500:86::86 \n\ +c.ip6-servers.arpa. 172800 IN A 196.216.169.11 \n\ +c.ip6-servers.arpa. 172800 IN AAAA 2001:43f8:110::11 \n\ +d.ip6-servers.arpa. 172800 IN A 200.7.86.53 \n\ +d.ip6-servers.arpa. 172800 IN AAAA 2001:13c7:7012::53 \n\ +e.ip6-servers.arpa. 172800 IN A 203.119.86.101 \n\ +e.ip6-servers.arpa. 172800 IN AAAA 2001:dd8:6::101 \n\ +f.ip6-servers.arpa. 172800 IN A 193.0.9.2 \n\ +f.ip6-servers.arpa. 172800 IN AAAA 2001:67c:e0::2 \n\ +ipv4only.arpa. 172800 IN NS a.iana-servers.net. \n\ +ipv4only.arpa. 172800 IN NS b.iana-servers.net. \n\ +ipv4only.arpa. 172800 IN NS c.iana-servers.net. \n\ +ipv4only.arpa. 172800 IN NS ns.icann.org. \n\ +iris.arpa. 172800 IN NS a.iana-servers.net. \n\ +iris.arpa. 172800 IN NS b.iana-servers.net. \n\ +iris.arpa. 172800 IN NS c.iana-servers.net. \n\ +iris.arpa. 172800 IN NS ns3.lacnic.net. \n\ +iris.arpa. 172800 IN NS ns4.apnic.net. \n\ +iris.arpa. 86400 IN DS 38534 8 2 163416c9dcaf8d1babfec16552ed109029607907ab80b195e1dab40f1792a59c \n\ +iris.arpa. 86400 IN DS 39464 8 2 1e09a2d6374800d54cfd0e52293906ccf7db7e923dcab7015e4bb697d76d9846 \n\ +iris.arpa. 86400 IN DS 44285 8 2 05cbf77375a8bf5702cf8e261ff947be8c8ab7a0b9485a0241edcfe2f155c7f3 \n\ +iris.arpa. 86400 IN RRSIG DS 8 2 86400 20210616170429 20210519170429 29094 arpa. oikOvs9AfaPv1Po/E76SZ7VBoYjqHqzZEzrA0N4gWXlemmsUKyXh9fiXqtusFIZD7QUBJMvOYkIpWnAOliWnk/oj4lmmwnYMqqLWDMWVoXiUAUtmwQHm89cAjyWc9nRuDVBweKtqH5GQKtEWxu4nkKPIbuUVNHBgxtKZP7Jbzic= \n\ +ksh70ck6pogi86ent4ont3i9uj71qe8k.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. YPnC0imYz+x2dNwUQwvp2CB1Ini1dEcn9Vur9T4KwzAMqVr+PPkheMRiIQcAbmkSLG1D1p/qVzaFEC7ixlaxuEFlvGwM+c5OvukbWek1QtdCDJpgtse3HBajoRTgBDGRwvj+DFej9ppygZpe+vlgSDmiC2fgPMhcG4Z6jMmVAec= \n\ +ksh70ck6pogi86ent4ont3i9uj71qe8k.arpa. 86400 IN NSEC3 1 0 1 - MKQDDR5C3MPRP6DRU5TO19BB27TDVCVT NS DS RRSIG \n\ +mkqddr5c3mprp6dru5to19bb27tdvcvt.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. sUTu2ijBQlhCmn/fNl8O+UofW4ERQ0tgmK0LY8ggHCnvY26k4RCrGieZ6YXl8lCereSyx1DEPuScBA7YRCUEw/FtrW8rCKMo+wQhb4Uon2UUZRl/mrjNNsYxtYwjIN7u/BzfDhBHq2/8vVCybAS8GhqqJhOYpEcDgsITuDKVFOE= \n\ +mkqddr5c3mprp6dru5to19bb27tdvcvt.arpa. 86400 IN NSEC3 1 0 1 - SRGGVLP1DI07IJT2IA31AGJRPFCNC616 NS DS RRSIG \n\ +srggvlp1di07ijt2ia31agjrpfcnc616.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. ep49bJfQ1c1dNMIlFO+EgeG4iW7pHyJvKbK6MJBBj/LJwVfhzwTa8ellqgHp3AH63j8tNPutowc1shlQwE7G/f3KfiVBUwPtAZHtqNYBFdNm0WdxoqRueJmyVR0h+vUfY+r1F4IYzwfjn+ldfj5lhKqQ+gX2HFR3M/FI6H97nHQ= \n\ +srggvlp1di07ijt2ia31agjrpfcnc616.arpa. 86400 IN NSEC3 1 0 1 - SSTSS4TF3ICJ43RCMUQTSJORRDDSRSRL NS \n\ +sstss4tf3icj43rcmuqtsjorrddsrsrl.arpa. 86400 IN RRSIG NSEC3 8 2 86400 20210616170429 20210519170429 29094 arpa. 0GVjQFd8YAYSXMh526fZ5Rx4WDHIf84MTzIsAYuLwM00H6uagrFxQv8mrGExWPummQ+Q+nHDuCBC5lEXjTF4/1qAu7MI627/mKtpcQevTvF3iE2ocf1/vfAFWVCzyLQ3AuFbGGuYQ6nlZzbOu2oRtma6/m4WpDhNszOhuONNlbY= \n\ +sstss4tf3icj43rcmuqtsjorrddsrsrl.arpa. 86400 IN NSEC3 1 0 1 - 0JS82OEC35LBBC4HL35476CM5ICACKSF NS DS RRSIG \n\ +uri.arpa. 172800 IN NS a.iana-servers.net. \n\ +uri.arpa. 172800 IN NS b.iana-servers.net. \n\ +uri.arpa. 172800 IN NS c.iana-servers.net. \n\ +uri.arpa. 172800 IN NS ns3.lacnic.net. \n\ +uri.arpa. 172800 IN NS ns4.apnic.net. \n\ +uri.arpa. 86400 IN DS 15796 8 2 7f8fa18fdd9a826eb08a4d4e9ce94dbba7a5b7b2b3ce1d74afd150242e9f572f \n\ +uri.arpa. 86400 IN DS 28547 8 2 deaefd0c163175350152da7b127dc7c4f9ec8bdf04ccc02829455df86c5ca035 \n\ +uri.arpa. 86400 IN DS 57851 8 2 8feda13f642ed9be2e4aaa3d50099dd422ca6081b6bf8188f804343b58d39cb7 \n\ +uri.arpa. 86400 IN RRSIG DS 8 2 86400 20210616170429 20210519170429 29094 arpa. jwQhmqBE2EWCE2yi14CqgjMfYWq4/W//IuL/EHSRZPJjyP7R7cnUgh/7rDO4JUcYebviO4s9hidjfpnLQWxpR2Jy2SH6aeNERLo76O28UW2Y28eused7aWMDWAnWW4HxURsQSBy2cyQbNwPCLGVLeQZaeZbKRBJUbWJ4MT4UpDE= \n\ +urn.arpa. 172800 IN NS a.iana-servers.net. \n\ +urn.arpa. 172800 IN NS b.iana-servers.net. \n\ +urn.arpa. 172800 IN NS c.iana-servers.net. \n\ +urn.arpa. 172800 IN NS ns3.lacnic.net. \n\ +urn.arpa. 172800 IN NS ns4.apnic.net. \n\ +urn.arpa. 86400 IN DS 28996 8 2 8e66d01a1e5864bcdb8e1f85579aec7c8c536c9d6fc7032ee708e869fd27f3d3 \n\ +urn.arpa. 86400 IN DS 34555 8 2 bd743967def1caf0812fe9eff2371d3adf29e27251db272145a5d523c92f7101 \n\ +urn.arpa. 86400 IN DS 45052 8 2 7685b675f93ada412cfe534820c8dcc55654b1711f677ba83a8564c12943f695 \n\ +urn.arpa. 86400 IN RRSIG DS 8 2 86400 20210616170429 20210519170429 29094 arpa. BHHa1YLYUOABgiloeQQRIMXRKxXNIwRken6E6ETFAWw3Js1ocu6H/X3bcPvBTjID/B+GRGgIyCnDnZ9iWeU41Tw1GnMNT9EM35DmnUgfzUU79shVzRtiYDV6JHF9Kidc90IxNrQOGAcUy0J9jhMa4KYEjfQab8sJSo0M+uJkNMw="; + +const char *no_zonemd = "\ +example. 86400 IN SOA ns1 admin 2018031900 ( \n\ + 1800 900 604800 86400 ) \n\ + 86400 IN NS ns1 \n\ + 86400 IN NS ns2 \n\ +ns1 3600 IN A 203.0.113.63 \n\ +ns2 3600 IN AAAA 2001:db8::63"; + +const char *wrong_soa = "\ +example. 86400 IN SOA ns1 admin 2018031900 ( \n\ + 1800 900 604800 86400 ) \n\ + 86400 IN NS ns1 \n\ + 86400 IN NS ns2 \n\ + 86400 IN ZONEMD 2018031901 1 1 ( \n\ + c68090d90a7aed71 \n\ + 6bc459f9340e3d7c \n\ + 1370d4d24b7e2fc3 \n\ + a1ddc0b9a87153b9 \n\ + a9713b3c9ae5cc27 \n\ + 777f98b8e730044c ) \n\ +ns1 3600 IN A 203.0.113.63 \n\ +ns2 3600 IN AAAA 2001:db8::63"; + +const char *duplicate_schemalg = "\ +example. 86400 IN SOA ns1 admin 2018031900 ( \n\ + 1800 900 604800 86400 ) \n\ + 86400 IN NS ns1 \n\ + 86400 IN NS ns2 \n\ + 86400 IN ZONEMD 2018031900 1 1 ( \n\ + c68090d90a7aed71 \n\ + 6bc459f9340e3d7c \n\ + 1370d4d24b7e2fc3 \n\ + a1ddc0b9a87153b9 \n\ + a9713b3c9ae5cc27 \n\ + 777f98b8e730044c ) \n\ + 86400 IN ZONEMD 2018031901 1 1 ( \n\ + c68090d90a7aed71 \n\ + 6bc459f9340e3d7c \n\ + 1370d4d24b7e2fc3 \n\ + a1ddc0b9a87153b9 \n\ + a9713b3c9ae5cc27 \n\ + 777f98b8e730044c ) \n\ +ns1 3600 IN A 203.0.113.63 \n\ +ns2 3600 IN AAAA 2001:db8::63"; + +const char *wrong_hash = "\ +example. 86400 IN SOA ns1 admin 2018031900 ( \n\ + 1800 900 604800 86400 ) \n\ + 86400 IN NS ns1 \n\ + 86400 IN NS ns2 \n\ + 86400 IN ZONEMD 2018031900 1 1 ( \n\ + c68090d90a7aed71 \n\ + 6bc459f9340e3d7c \n\ + 1370d4d24b7e2fc3 \n\ + a1ddc0b9a87153b9 \n\ + a9713b3c9ae5cc27 \n\ + 777f98b8e730044d ) \n\ +ns1 3600 IN A 203.0.113.63 \n\ +ns2 3600 IN AAAA 2001:db8::63"; + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + int ret = check_contents(simple_zone); + is_int(KNOT_EOK, ret, "simple zone"); + + ret = check_contents(complex_zone); + is_int(KNOT_EOK, ret, "complex zone"); + + ret = check_contents(multiple_digests); + is_int(KNOT_EOK, ret, "multiple digests"); + + ret = check_contents(signed_zone); + is_int(KNOT_EOK, ret, "signed zone"); + + ret = check_contents(nsec3_zone); + is_int(KNOT_EOK, ret, "nsec3 zone"); + + ret = check_contents(no_zonemd); + is_int(KNOT_ENOENT, ret, "no zonemd"); + + ret = check_contents(wrong_soa); + is_int(KNOT_ENOTSUP, ret, "wrong SOA serial"); + // TODO tests for different scheme / algorithm ? + + ret = check_contents(duplicate_schemalg); + is_int(KNOT_ESEMCHECK, ret, "duplicate scheme+algorithm pair"); + + ret = check_contents(wrong_hash); + is_int(KNOT_EMALF, ret, "wrong hash"); + + return 0; +} diff --git a/tests/knot/test_dthreads.c b/tests/knot/test_dthreads.c new file mode 100644 index 0000000..3bdfa3a --- /dev/null +++ b/tests/knot/test_dthreads.c @@ -0,0 +1,148 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <pthread.h> +#include <sched.h> +#include <signal.h> +#include <stdlib.h> +#include <tap/basic.h> + +#include "knot/server/dthreads.h" + +/* Unit runnable data. */ +static pthread_mutex_t _runnable_mx; +static volatile int _runnable_i = 0; +static const int _runnable_cycles = 10000; + +/*! \brief Unit runnable. */ +int runnable(struct dthread *thread) +{ + for (int i = 0; i < _runnable_cycles; ++i) { + + // Increase counter + pthread_mutex_lock(&_runnable_mx); + ++_runnable_i; + pthread_mutex_unlock(&_runnable_mx); + + // Cancellation point + if (dt_is_cancelled(thread)) { + break; + } + + // Yield + sched_yield(); + } + + return 0; +} + +/* Destructor data. */ +static volatile int _destructor_data = 0; +static pthread_mutex_t _destructor_mx; + +/*! \brief Thread destructor. */ +int destruct(struct dthread *thread) +{ + pthread_mutex_lock(&_destructor_mx); + _destructor_data += 1; + pthread_mutex_unlock(&_destructor_mx); + + return 0; +} + +// Signal handler +static void interrupt_handle(int s) +{ +} + +/*! API: run tests. */ +int main(int argc, char *argv[]) +{ + plan_lazy(); + + int cpus = dt_online_cpus(); + ok(cpus > 0, "dthread: online cpus is positive value"); + + // Register service and signal handler + struct sigaction sa; + sa.sa_handler = interrupt_handle; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGALRM, &sa, NULL); // Interrupt + + /* Initialize */ + srand(time(NULL)); + pthread_mutex_init(&_runnable_mx, NULL); + pthread_mutex_init(&_destructor_mx, NULL); + + /* Test 1: Create unit */ + int size = 2; + dt_unit_t *unit = dt_create(size, &runnable, NULL, NULL); + ok(unit != NULL, "dthreads: create unit (size %d)", size); + if (unit == NULL) { + skip_block(7, "No dthreads unit"); + goto skip_all; + } + + /* Test 2: Start tasks. */ + _runnable_i = 0; + ok(dt_start(unit) == 0, "dthreads: start single task"); + + /* Test 3: Wait for tasks. */ + ok(dt_join(unit) == 0, "dthreads: join threads"); + + /* Test 4: Compare counter. */ + int expected = _runnable_cycles * 2; + is_int(expected, _runnable_i, "dthreads: result ok"); + + /* Test 5: Deinitialize */ + dt_delete(&unit); + ok(unit == NULL, "dthreads: delete unit"); + + /* Test 6: Wrong values. */ + unit = dt_create(-1, NULL, NULL, NULL); + ok(unit == NULL, "dthreads: create with negative count"); + + /* Test 7: NULL operations crashing. */ + int ret = 0; + ret += dt_activate(0); + ret += dt_cancel(0); + ret += dt_compact(0); + dt_delete(0); + ret += dt_is_cancelled(0); + ret += dt_join(0); + ret += dt_signalize(0, SIGALRM); + ret += dt_start(0); + ret += dt_stop(0); + ret += dt_unit_lock(0); + ret += dt_unit_unlock(0); + is_int(-198, ret, "dthreads: correct values when passed NULL context"); + + /* Test 8: Thread destructor. */ + _destructor_data = 0; + unit = dt_create(2, 0, destruct, 0); + dt_start(unit); + dt_stop(unit); + dt_join(unit); + is_int(2, _destructor_data, "dthreads: destructor with dt_create_coherent()"); + dt_delete(&unit); + +skip_all: + + pthread_mutex_destroy(&_runnable_mx); + pthread_mutex_destroy(&_destructor_mx); + return 0; +} diff --git a/tests/knot/test_fdset.c b/tests/knot/test_fdset.c new file mode 100644 index 0000000..d0282f0 --- /dev/null +++ b/tests/knot/test_fdset.c @@ -0,0 +1,150 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include <pthread.h> +#include <tap/basic.h> +#include <unistd.h> + +#include "knot/common/fdset.h" +#include "libknot/attribute.h" +#include "contrib/time.h" + +#define PATTERN1 "0x45" +#define PATTERN2 "0xED" + +#define TIMEOUT0 2000 +#define TIMEOUT1 10 +#define TIMEOUT2 400 +#define JITTER (TIMEOUT2 - TIMEOUT1 - 10) + +void *thr_action1(void *arg) +{ + usleep(1000 * TIMEOUT1); + _unused_ int ret = write(*((int *)arg), &PATTERN1, 1); + return NULL; +} + +void *thr_action2(void *arg) +{ + usleep(1000 * TIMEOUT2); + _unused_ int ret = write(*((int *)arg), &PATTERN2, 1); + return NULL; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + fdset_t fdset; + int ret = fdset_init(&fdset, 32); + ok(ret == KNOT_EOK, "fdset_init"); + + int fds0[2], fds1[2], fds2[2]; + + ret = pipe(fds0); + ok(ret >= 0, "create pipe 0"); + ret = fdset_add(&fdset, fds0[0], FDSET_POLLIN, NULL); + ok(ret >= 0, "add pipe 0 to fdset"); + + ret = pipe(fds1); + ok(ret >= 0, "create pipe 1"); + ret = fdset_add(&fdset, fds1[0], FDSET_POLLIN, NULL); + ok(ret >= 0, "add pipe 1 to fdset"); + + ret = pipe(fds2); + ok(ret >= 0, "create pipe 2"); + ret = fdset_add(&fdset, fds2[0], FDSET_POLLIN, NULL); + ok(ret >= 0, "add pipe 2 to fdset"); + + ok(fdset_get_length(&fdset) == 3, "fdset size full"); + + struct timespec time0 = time_now(); + + pthread_t t1, t2; + ret = pthread_create(&t1, 0, thr_action1, &fds1[1]); + ok(ret == 0, "create thread 1"); + ret = pthread_create(&t2, 0, thr_action2, &fds2[1]); + ok(ret == 0, "create thread 2"); + + fdset_it_t it; + ret = fdset_poll(&fdset, &it, 0, TIMEOUT0); + struct timespec time1 = time_now(); + double diff1 = time_diff_ms(&time0, &time1); + ok(ret == 1, "fdset_poll return 1"); + ok(diff1 >= TIMEOUT1 && diff1 < TIMEOUT1 + JITTER, "fdset_poll timeout 1 (%f)", diff1); + for(; !fdset_it_is_done(&it); fdset_it_next(&it)) { + ok(!fdset_it_is_error(&it), "fdset no error"); + ok(fdset_it_is_pollin(&it), "fdset can read"); + + int fd = fdset_it_get_fd(&it); + ok(fd == fds1[0], "fdset_it fd check"); + + char buf = 0x00; + ret = read(fd, &buf, sizeof(buf)); + ok(ret == 1 && buf == PATTERN1[0], "fdset_it value check"); + + fdset_it_remove(&it); + } + fdset_it_commit(&it); + ok(fdset_get_length(&fdset) == 2, "fdset size 2"); + close(fds1[1]); + + int fd2_dup = dup(fds2[0]); + ok(fd2_dup >= 0, "duplicate fd"); + + ret = fdset_poll(&fdset, &it, 0, TIMEOUT0); + struct timespec time2 = time_now(); + double diff2 = time_diff_ms(&time0, &time2); + ok(ret == 1, "fdset_poll return 2"); + ok(diff2 >= TIMEOUT2 && diff2 < TIMEOUT2 + JITTER, "fdset_poll timeout 2 (%f)", diff2); + for(; !fdset_it_is_done(&it); fdset_it_next(&it)) { + ok(!fdset_it_is_error(&it), "fdset no error"); + ok(fdset_it_is_pollin(&it), "fdset can read"); + + int fd = fdset_it_get_fd(&it); + ok(fd == fds2[0], "fdset_it fd check"); + + char buf = 0x00; + ret = read(fd, &buf, sizeof(buf)); + ok(ret == 1 && buf == PATTERN2[0], "fdset_it value check"); + + fdset_it_remove(&it); + } + fdset_it_commit(&it); + ok(fdset_get_length(&fdset) == 1, "fdset size 1"); + + pthread_join(t1, 0); + pthread_join(t2, 0); + + ret = fdset_remove(&fdset, 0); + ok(ret == KNOT_EOK, "fdset remove"); + close(fds0[1]); + ok(fdset_get_length(&fdset) == 0, "fdset size 0"); + + ret = write(fds2[1], &PATTERN2, 1); + ok(ret == 1, "write to removed fd"); + ret = fdset_poll(&fdset, &it, 0, 100); + ok(ret == 0, "fdset_poll return 3"); + + + close(fds2[1]); + if (fd2_dup >= 0) { + close(fd2_dup); + } + fdset_clear(&fdset); + + return 0; +} diff --git a/tests/knot/test_journal.c b/tests/knot/test_journal.c new file mode 100644 index 0000000..748ab02 --- /dev/null +++ b/tests/knot/test_journal.c @@ -0,0 +1,880 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#include <unistd.h> +#include <sys/stat.h> +#include <tap/basic.h> +#include <tap/files.h> + +#include "knot/journal/journal_read.h" +#include "knot/journal/journal_write.h" + +#include "libknot/attribute.h" +#include "libknot/libknot.h" +#include "knot/zone/zone.h" +#include "knot/zone/zone-diff.h" +#include "test_conf.h" + +#define RAND_RR_LABEL 16 +#define RAND_RR_PAYLOAD 64 +#define MIN_SOA_SIZE 22 + +char *test_dir_name; + +knot_lmdb_db_t jdb; +zone_journal_t jj; + +unsigned env_flag; + +static unsigned lmdb_page_size(knot_lmdb_db_t *db) +{ + knot_lmdb_txn_t txn = { 0 }; + knot_lmdb_begin(db, &txn, false); + MDB_stat st = { 0 }; + mdb_stat(txn.txn, txn.db->dbi, &st); + knot_lmdb_abort(&txn); + return st.ms_psize; +} + +static void set_conf(int zonefile_sync, size_t journal_usage, const knot_dname_t *apex) +{ + (void)apex; + char conf_str[512]; + snprintf(conf_str, sizeof(conf_str), + "template:\n" + " - id: default\n" + " zonefile-sync: %d\n" + " journal-max-usage: %zu\n" + " journal-max-depth: 1000\n", + zonefile_sync, journal_usage); + _unused_ int ret = test_conf(conf_str, NULL); + assert(ret == KNOT_EOK); + jj.conf = conf(); +} + +static void unset_conf(void) +{ + conf_update(NULL, CONF_UPD_FNONE); +} + +/*! \brief Generate random string with given length. */ +static int randstr(char* dst, size_t len) +{ + for (int i = 0; i < len - 1; ++i) { + dst[i] = '0' + (int) (('Z'-'0') * (rand() / (RAND_MAX + 1.0))); + } + dst[len - 1] = '\0'; + + return 0; +} + +/*! \brief Init RRSet with type SOA and given serial. */ +static void init_soa(knot_rrset_t *rr, const uint32_t serial, const knot_dname_t *apex) +{ + knot_rrset_init(rr, knot_dname_copy(apex, NULL), KNOT_RRTYPE_SOA, KNOT_CLASS_IN, 3600); + + uint8_t soa_data[MIN_SOA_SIZE] = { 0 }; + _unused_ int ret = knot_rrset_add_rdata(rr, soa_data, sizeof(soa_data), NULL); + knot_soa_serial_set(rr->rrs.rdata, serial); + assert(ret == KNOT_EOK); +} + +/*! \brief Init RRSet with type TXT, random owner and random payload. */ +static void init_random_rr(knot_rrset_t *rr , const knot_dname_t *apex) +{ + /* Create random label. */ + char owner[RAND_RR_LABEL + knot_dname_size(apex)]; + owner[0] = RAND_RR_LABEL - 1; + randstr(owner + 1, RAND_RR_LABEL); + + /* Append zone apex. */ + memcpy(owner + RAND_RR_LABEL, apex, knot_dname_size(apex)); + knot_rrset_init(rr, knot_dname_copy((knot_dname_t *)owner, NULL), + KNOT_RRTYPE_TXT, KNOT_CLASS_IN, 3600); + + /* Create random RDATA. */ + uint8_t txt[RAND_RR_PAYLOAD + 1]; + txt[0] = RAND_RR_PAYLOAD - 1; + randstr((char *)(txt + 1), RAND_RR_PAYLOAD); + + _unused_ int ret = knot_rrset_add_rdata(rr, txt, RAND_RR_PAYLOAD, NULL); + assert(ret == KNOT_EOK); +} + +/*! \brief Init changeset with random changes. */ +static void init_random_changeset(changeset_t *ch, const uint32_t from, const uint32_t to, + const size_t size, const knot_dname_t *apex, bool is_bootstrap) +{ + // Add SOAs + knot_rrset_t soa; + + if (is_bootstrap) { + ch->soa_from = NULL; + zone_contents_deep_free(ch->remove); + ch->remove = NULL; + } else { + init_soa(&soa, from, apex); + ch->soa_from = knot_rrset_copy(&soa, NULL); + assert(ch->soa_from); + knot_rrset_clear(&soa, NULL); + } + + init_soa(&soa, to, apex); + ch->soa_to = knot_rrset_copy(&soa, NULL); + assert(ch->soa_to); + knot_rrset_clear(&soa, NULL); + + // Add RRs to add section + for (size_t i = 0; i < size / 2; ++i) { + knot_rrset_t rr; + init_random_rr(&rr, apex); + _unused_ int ret = changeset_add_addition(ch, &rr, 0); + assert(ret == KNOT_EOK); + knot_rrset_clear(&rr, NULL); + } + + // Add RRs to remove section + for (size_t i = 0; i < size / 2 && !is_bootstrap; ++i) { + knot_rrset_t rr; + init_random_rr(&rr, apex); + _unused_ int ret = changeset_add_removal(ch, &rr, 0); + assert(ret == KNOT_EOK); + knot_rrset_clear(&rr, NULL); + } +} + +static void changeset_set_soa_serials(changeset_t *ch, uint32_t from, uint32_t to, + const knot_dname_t *apex) +{ + knot_rrset_t soa; + + init_soa(&soa, from, apex); + knot_rrset_free(ch->soa_from, NULL); + ch->soa_from = knot_rrset_copy(&soa, NULL); + assert(ch->soa_from); + knot_rrset_clear(&soa, NULL); + + init_soa(&soa, to, apex); + knot_rrset_free(ch->soa_to, NULL); + ch->soa_to = knot_rrset_copy(&soa, NULL); + assert(ch->soa_to); + knot_rrset_clear(&soa, NULL); +} + +/*! \brief Compare two changesets for equality. */ +static bool changesets_eq(const changeset_t *ch1, changeset_t *ch2) +{ + bool bootstrap = (ch1->remove == NULL); + + if (!bootstrap && changeset_size(ch1) != changeset_size(ch2)) { + return false; + } + + if ((bootstrap && ch2->remove != NULL) || + (!bootstrap && ch2->remove == NULL)) { + return false; + } + + changeset_iter_t it1; + changeset_iter_t it2; + if (bootstrap) { + changeset_iter_add(&it1, ch1); + changeset_iter_add(&it2, ch2); + } else { + changeset_iter_all(&it1, ch1); + changeset_iter_all(&it2, ch2); + } + + knot_rrset_t rr1 = changeset_iter_next(&it1); + knot_rrset_t rr2 = changeset_iter_next(&it2); + bool ret = true; + while (!knot_rrset_empty(&rr1)) { + if (!knot_rrset_equal(&rr1, &rr2, true)) { + ret = false; + break; + } + rr1 = changeset_iter_next(&it1); + rr2 = changeset_iter_next(&it2); + } + + changeset_iter_clear(&it1); + changeset_iter_clear(&it2); + + return ret; +} + +static bool changesets_list_eq(list_t *l1, list_t *l2) +{ + node_t *n = NULL; + node_t *k = HEAD(*l2); + WALK_LIST(n, *l1) { + if (k == NULL) { + return false; + } + + changeset_t *ch1 = (changeset_t *) n; + changeset_t *ch2 = (changeset_t *) k; + if (!changesets_eq(ch1, ch2)) { + return false; + } + + k = k->next; + } + + if (k->next != NULL) { + return false; + } + + return true; +} + +/*! \brief Test a list of changesets for continuity. */ +static bool test_continuity(list_t *l) +{ + node_t *n = NULL; + uint32_t key1, key2; + WALK_LIST(n, *l) { + if (n == TAIL(*l)) { + break; + } + changeset_t *ch1 = (changeset_t *) n; + changeset_t *ch2 = (changeset_t *) n->next; + key1 = knot_soa_serial(ch1->soa_to->rrs.rdata); + key2 = knot_soa_serial(ch2->soa_from->rrs.rdata); + if (key1 != key2) { + return KNOT_EINVAL; + } + } + + return KNOT_EOK; +} + +static void test_journal_db(void) +{ + env_flag = journal_env_flags(JOURNAL_MODE_ASYNC, false); + knot_lmdb_init(&jdb, test_dir_name, 2048 * 1024, env_flag, NULL); + + int ret = knot_lmdb_open(&jdb); + is_int(KNOT_EOK, ret, "journal: open db (%s)", knot_strerror(ret)); + + ret = knot_lmdb_reconfigure(&jdb, test_dir_name, 4096 * 1024, env_flag); + is_int(KNOT_EOK, ret, "journal: re-open with bigger mapsize (%s)", knot_strerror(ret)); + + ret = knot_lmdb_reconfigure(&jdb, test_dir_name, 1024 * 1024, env_flag); + is_int(KNOT_EOK, ret, "journal: re-open with smaller mapsize (%s)", knot_strerror(ret)); + + knot_lmdb_deinit(&jdb); +} + +static int load_j_list(zone_journal_t *zj, bool zij, uint32_t serial, + journal_read_t **read, list_t *list) +{ + changeset_t *ch; + init_list(list); + int ret = journal_read_begin(*zj, zij, serial, read); + if (ret == KNOT_EOK) { + while ((ch = calloc(1, sizeof(*ch))) != NULL && + journal_read_changeset(*read, ch)) { + add_tail(list, &ch->n); + } + free(ch); + ret = journal_read_get_error(*read, KNOT_EOK); + } + return ret; +} + +/*! \brief Test behavior with real changesets. */ +static void test_store_load(const knot_dname_t *apex) +{ + set_conf(1000, 512 * 1024, apex); + + knot_lmdb_init(&jdb, test_dir_name, 1536 * 1024, env_flag, NULL); + assert(knot_lmdb_open(&jdb) == KNOT_EOK); + + jj.db = &jdb; + jj.zone = apex; + list_t l, k; + + changeset_t *m_ch = changeset_new(apex), r_ch, e_ch; + init_random_changeset(m_ch, 0, 1, 128, apex, false); + int ret = journal_insert(jj, m_ch, NULL, NULL); + is_int(KNOT_EOK, ret, "journal: store changeset (%s)", knot_strerror(ret)); + ret = journal_sem_check(jj); + is_int(KNOT_EOK, ret, "journal: check after store changeset (%s)", knot_strerror(ret)); + journal_read_t *read = NULL; + + ret = load_j_list(&jj, false, changeset_from(m_ch), &read, &l); + is_int(KNOT_EOK, ret, "journal: read single changeset (%s)", knot_strerror(ret)); + ok(1 == list_size(&l), "journal: read exactly one changeset"); + ok(changesets_eq(m_ch, HEAD(l)), "journal: changeset equal after read"); + changesets_free(&l); + + journal_read_end(read); + ret = journal_set_flushed(jj); + is_int(KNOT_EOK, ret, "journal: first simple flush (%s)", knot_strerror(ret)); + + init_list(&k); + uint32_t serial = 1; + for (; ret == KNOT_EOK && serial < 40000; ++serial) { + changeset_t *m_ch2 = changeset_new(apex); + init_random_changeset(m_ch2, serial, serial + 1, 128, apex, false); + ret = journal_insert(jj, m_ch2, NULL, NULL); + if (ret != KNOT_EOK) { + changeset_free(m_ch2); + break; + } + add_tail(&k, &m_ch2->n); + } + is_int(KNOT_EBUSY, ret, "journal: overfill with changesets (%d inserted) (%d should= %d)", + serial, ret, KNOT_EBUSY); + ret = journal_sem_check(jj); + is_int(KNOT_EOK, ret, "journal check (%s)", knot_strerror(ret)); + + ret = load_j_list(&jj, false, 1, &read, &l); + is_int(KNOT_EOK, ret, "journal: load list (%s)", knot_strerror(ret)); + ok(changesets_list_eq(&l, &k), "journal: changeset lists equal after read"); + ok(test_continuity(&l) == KNOT_EOK, "journal: changesets are in order"); + changesets_free(&l); + journal_read_end(read); + + ret = load_j_list(&jj, false, 1, &read, &l); + is_int(KNOT_EOK, ret, "journal: load list 2nd (%s)", knot_strerror(ret)); + ok(changesets_list_eq(&l, &k), "journal: changeset lists equal after 2nd read"); + changesets_free(&l); + journal_read_end(read); + + ret = journal_set_flushed(jj); + is_int(KNOT_EOK, ret, "journal: flush after overfill (%s)", knot_strerror(ret)); + ret = journal_sem_check(jj); + is_int(KNOT_EOK, ret, "journal check (%s)", knot_strerror(ret)); + + ret = load_j_list(&jj, false, 1, &read, &l); + is_int(KNOT_EOK, ret, "journal: load list (%s)", knot_strerror(ret)); + ok(changesets_list_eq(&l, &k), "journal: changeset lists equal after flush"); + changesets_free(&l); + journal_read_end(read); + + changesets_free(&k); + + changeset_t ch; + ret = changeset_init(&ch, apex); + ok(ret == KNOT_EOK, "journal: changeset init (%d)", ret); + init_random_changeset(&ch, serial, serial + 1, 555, apex, false); + ret = journal_insert(jj, &ch, NULL, NULL); + is_int(KNOT_EOK, ret, "journal: store after flush (%d)", ret); + ret = journal_sem_check(jj); + is_int(KNOT_EOK, ret, "journal check (%s)", knot_strerror(ret)); + ret = load_j_list(&jj, false, serial, &read, &l); + is_int(KNOT_EOK, ret, "journal: load after store after flush after overfill (%s)", knot_strerror(ret)); + is_int(1, list_size(&l), "journal: single changeset in list"); + ok(changesets_eq(&ch, HEAD(l)), "journal: changeset not malformed after overfill"); + changesets_free(&l); + journal_read_end(read); + + changeset_clear(&ch); + + changeset_init(&ch, apex); + init_random_changeset(&ch, 2, 3, 100, apex, false); + ret = journal_insert(jj, &ch, NULL, NULL); + is_int(KNOT_EOK, ret, "journal: insert discontinuous changeset (%s)", knot_strerror(ret)); + ret = journal_sem_check(jj); + is_int(KNOT_EOK, ret, "journal check (%s)", knot_strerror(ret)); + ret = load_j_list(&jj, false, 2, &read, &l); + is_int(KNOT_EOK, ret, "journal: read after discontinuity (%s)", knot_strerror(ret)); + is_int(1, list_size(&l), "journal: discontinuity caused journal to drop"); + changesets_free(&l); + journal_read_end(read); + + // Test for serial number collision handling. We insert changesets + // with valid serial sequence that overflows and then collides with itself. + // The sequence is 0 -> 1 -> 2 -> 2147483647 -> 4294967294 -> 1 which should + // remove changesets 0->1 and 1->2. * + uint32_t serials[6] = { 0, 1, 2, 2147483647, 4294967294, 1 }; + for (int i = 0; i < 5; i++) { + changeset_clear(&ch); + changeset_init(&ch, apex); + init_random_changeset(&ch, serials[i], serials[i + 1], 100, apex, false); + ret = journal_insert(jj, &ch, NULL, NULL); + is_int(i == 4 ? KNOT_EBUSY : KNOT_EOK, ret, "journal: inserting cycle (%s)", knot_strerror(ret)); + ret = journal_sem_check(jj); + is_int(KNOT_EOK, ret, "journal check (%s)", knot_strerror(ret)); + } + ret = journal_set_flushed(jj); + is_int(KNOT_EOK, ret, "journal: flush in cycle (%s)", knot_strerror(ret)); + ret = journal_insert(jj, &ch, NULL, NULL); + is_int(KNOT_EOK, ret, "journal: inserted cycle (%s)", knot_strerror(ret)); + ret = journal_sem_check(jj); + is_int(KNOT_EOK, ret, "journal check (%s)", knot_strerror(ret)); + ret = journal_read_begin(jj, false, 0, &read); + is_int(KNOT_ENOENT, ret, "journal: cycle removed first changeset (%d should= %d)", ret, KNOT_ENOENT); + ret = journal_read_begin(jj, false, 1, &read); + is_int(KNOT_ENOENT, ret, "journal: cycle removed second changeset (%d should= %d)", ret, KNOT_ENOENT); + ret = load_j_list(&jj, false, 4294967294, &read, &l); + is_int(KNOT_EOK, ret, "journal: read after cycle (%s)", knot_strerror(ret)); + ok(3 >= list_size(&l), "journal: cycle caused journal to partly drop"); + ok(changesets_eq(&ch, HEAD(l)), "journal: changeset not malformed after cycle"); + changesets_free(&l); + journal_read_end(read); + changeset_clear(&ch); + changeset_free(m_ch); + + changeset_init(&e_ch, apex); + init_random_changeset(&e_ch, 0, 1, 200, apex, true); + zone_node_t *n = NULL; + zone_contents_add_rr(e_ch.add, e_ch.soa_to, &n); + ret = journal_insert_zone(jj, e_ch.add); + zone_contents_remove_rr(e_ch.add, e_ch.soa_to, &n); + is_int(KNOT_EOK, ret, "journal: insert zone-in-journal (%s)", knot_strerror(ret)); + changeset_init(&r_ch, apex); + init_random_changeset(&r_ch, 1, 2, 200, apex, false); + ret = journal_insert(jj, &r_ch, NULL, NULL); + is_int(KNOT_EOK, ret, "journal: insert after zone-in-journal (%s)", knot_strerror(ret)); + ret = load_j_list(&jj, true, 0, &read, &l); + is_int(KNOT_EOK, ret, "journal: load zone-in-journal (%s)", knot_strerror(ret)); + is_int(2, list_size(&l), "journal: read two changesets from zone-in-journal"); + ok(changesets_eq(&e_ch, HEAD(l)), "journal: zone-in-journal not malformed"); + ok(changesets_eq(&r_ch, TAIL(l)), "journal: after zone-in-journal not malformed"); + changesets_free(&l); + journal_read_end(read); + changeset_clear(&e_ch); + changeset_clear(&r_ch); + + ret = journal_scrape_with_md(jj, true); + is_int(KNOT_EOK, ret, "journal: scrape with md (%s)", knot_strerror(ret)); + + unset_conf(); +} + +static void test_size_control(const knot_dname_t *zone1, const knot_dname_t *zone2) +{ + set_conf(-1, 100 * 1024, zone1); + + zone_journal_t jj2 = { &jdb, zone2, conf() }; + changeset_t *small_ch2 = changeset_new(zone2); + init_random_changeset(small_ch2, 1, 2, 100, zone2, false); + int ret = journal_insert(jj2, small_ch2, NULL, NULL); + is_int(KNOT_EOK, ret, "journal: storing small changeset must be ok"); + + changeset_t *big_zij = changeset_new(zone1); + init_random_changeset(big_zij, 0, 1, 1200, zone1, true); + zone_node_t *n = NULL; + zone_contents_add_rr(big_zij->add, big_zij->soa_to, &n); + ret = journal_insert_zone(jj, big_zij->add); + is_int(KNOT_EOK, ret, "journal: store big zone-in-journal"); + + changeset_t *big_ch2 = changeset_new(zone2); + init_random_changeset(big_ch2, 2, 3, 750, zone2, false); + ret = journal_insert(jj2, big_ch2, NULL, NULL); + is_int(KNOT_EOK, ret, "journal: second zone is not affected by storing big zij of other zone"); + + journal_read_t *read = NULL; + list_t l; + init_list(&l); + changeset_t *medium_ch1 = changeset_new(zone1); + init_random_changeset(medium_ch1, 1, 2, 300, zone1, false); + ret = journal_insert(jj, medium_ch1, NULL, NULL); + is_int(KNOT_EOK, ret, "journal: storing medium changeset must be ok"); + ret = load_j_list(&jj, true, 0, &read, &l); + is_int(KNOT_EOK, ret, "journal: load zone-in-journal (%s)", knot_strerror(ret)); + is_int(2, list_size(&l), "journal: read two changesets from journal"); + changesets_free(&l); + journal_read_end(read); + + changeset_t *small_ch1 = changeset_new(zone1); + init_random_changeset(small_ch1, 2, 3, 100, zone1, false); + ret = journal_insert(jj, small_ch1, NULL, NULL); + is_int(KNOT_EOK, ret, "journal: storing small changeset must be ok"); + ret = load_j_list(&jj, true, 0, &read, &l); + is_int(KNOT_EOK, ret, "journal: load zone-in-journal (%s)", knot_strerror(ret)); + is_int(2, list_size(&l), "journal: previous chs merged into zone-in-journal due to size limits"); + changesets_free(&l); + journal_read_end(read); + + changeset_t *medium_ch1b = changeset_new(zone1); + init_random_changeset(medium_ch1b, 3, 4, 300, zone1, false); + ret = journal_insert(jj, medium_ch1b, NULL, NULL); + is_int(KNOT_ESPACE, ret, "journal: not able to free space for changeset by merging"); + + changeset_t *too_big_zij = changeset_new(zone1); + init_random_changeset(too_big_zij, 0, 1, 2200, zone1, true); + zone_contents_add_rr(too_big_zij->add, too_big_zij->soa_to, &n); + ret = journal_insert_zone(jj, too_big_zij->add); + is_int(KNOT_ESPACE, ret, "journal: store too big zone-in-journal"); + + changeset_free(big_ch2); + changeset_free(big_zij); + changeset_free(too_big_zij); + changeset_free(small_ch2); + changeset_free(small_ch1); + changeset_free(medium_ch1); + changeset_free(medium_ch1b); + + unset_conf(); +} + +const uint8_t *rdA = (const uint8_t *) "\x01\x02\x03\x04"; +const uint8_t *rdB = (const uint8_t *) "\x01\x02\x03\x05"; +const uint8_t *rdC = (const uint8_t *) "\x01\x02\x03\x06"; + +// frees owner +static knot_rrset_t * tm_rrset(knot_dname_t * owner, const uint8_t * rdata) +{ + knot_rrset_t * rrs = knot_rrset_new(owner, KNOT_RRTYPE_A, KNOT_CLASS_IN, 3600, NULL); + knot_rrset_add_rdata(rrs, rdata, 4, NULL); + free(owner); + return rrs; +} + +static knot_dname_t *tm_owner(const char *prefix, const knot_dname_t *apex) +{ + size_t prefix_len = strlen(prefix); + size_t apex_len = knot_dname_size(apex); + + knot_dname_t *out = malloc(prefix_len + apex_len + 2); + out[0] = prefix_len; + memcpy(out + 1, prefix, prefix_len); + memcpy(out + 1 + prefix_len, apex, apex_len); + return out; +} + +static knot_dname_t *tm_owner_int(int x, const knot_dname_t *apex) +{ + char buf[12] = { 0 }; + (void)snprintf(buf, sizeof(buf), "i%d", x); + return tm_owner(buf, apex); +} + +static knot_rrset_t * tm_rrs(const knot_dname_t * apex, int x) +{ + static knot_rrset_t * rrsA = NULL; + static knot_rrset_t * rrsB = NULL; + static knot_rrset_t * rrsC = NULL; + + if (apex == NULL) { + knot_rrset_free(rrsA, NULL); + knot_rrset_free(rrsB, NULL); + knot_rrset_free(rrsC, NULL); + rrsA = rrsB = rrsC = NULL; + return NULL; + } + + if (rrsA == NULL) rrsA = tm_rrset(tm_owner("aaaaaaaaaaaaaaaaa", apex), rdA); + if (rrsB == NULL) rrsB = tm_rrset(tm_owner("bbbbbbbbbbbbbbbbb", apex), rdB); + if (rrsC == NULL) rrsC = tm_rrset(tm_owner("ccccccccccccccccc", apex), rdC); + switch ((x % 3 + 3) % 3) { + case 0: return rrsA; + case 1: return rrsB; + case 2: return rrsC; + } + assert(0); return NULL; +} + +#define TM_RRS_INT_MAX 1000 + +static knot_rrset_t *tm_rrs_int(const knot_dname_t *apex, int x) +{ + assert(x < TM_RRS_INT_MAX); + static knot_rrset_t *stat_rrs[TM_RRS_INT_MAX] = { 0 }; + + if (apex == NULL) { + for (int i = 0; i < TM_RRS_INT_MAX; i++) { + knot_rrset_free(stat_rrs[i], NULL); + stat_rrs[i] = NULL; + } + return NULL; + } + + if (stat_rrs[x] == NULL) { + stat_rrs[x] = tm_rrset(tm_owner_int(x, apex), rdA); + } + return stat_rrs[x]; +} + +int tm_rrcnt(const changeset_t * ch, int flg) +{ + changeset_iter_t it; + int i = 0; + if (flg >= 0) changeset_iter_add(&it, ch); + else changeset_iter_rem(&it, ch); + + knot_rrset_t rri; + while (rri = changeset_iter_next(&it), !knot_rrset_empty(&rri)) i++; + + changeset_iter_clear(&it); + return i; +} + +static changeset_t * tm_chs(const knot_dname_t * apex, int x) +{ + static changeset_t * chsI = NULL, * chsX = NULL, * chsY = NULL; + static uint32_t serial = 0; + if (x < 0) { + serial = 0; + return NULL; + } + + if (apex == NULL) { + changeset_free(chsI); + changeset_free(chsX); + changeset_free(chsY); + chsI = chsX = chsY = NULL; + return NULL; + } + + if (chsI == NULL) { + chsI = changeset_new(apex); + assert(chsI != NULL); + changeset_add_addition(chsI, tm_rrs(apex, 0), 0); + changeset_add_addition(chsI, tm_rrs(apex, 1), 0); + } + if (chsX == NULL) { + chsX = changeset_new(apex); + assert(chsX != NULL); + changeset_add_removal(chsX, tm_rrs(apex, 1), 0); + changeset_add_addition(chsX, tm_rrs(apex, 2), 0); + } + if (chsY == NULL) { + chsY = changeset_new(apex); + assert(chsY != NULL); + changeset_add_removal(chsY, tm_rrs(apex, 2), 0); + changeset_add_addition(chsY, tm_rrs(apex, 1), 0); + } + assert(x >= 0); + changeset_t * ret; + if (x == 0) ret = chsI; + else if (x % 2 == 1) ret = chsX; + else ret = chsY; + + changeset_set_soa_serials(ret, serial, serial + 1, apex); + serial++; + + return ret; +} + +static void tm2_add_all(zone_contents_t *toadd) +{ + assert(toadd != NULL); + for (int i = 1; i < TM_RRS_INT_MAX; i++) { + zone_node_t *unused = NULL; + _unused_ int ret = zone_contents_add_rr(toadd, tm_rrs_int(toadd->apex->owner, i), &unused); + assert(ret == KNOT_EOK); + } +} + +static zone_contents_t *tm2_zone(const knot_dname_t *apex) +{ + zone_contents_t *z = zone_contents_new(apex, false); + if (z != NULL) { + knot_rrset_t soa; + zone_node_t *unused = NULL; + init_soa(&soa, 1, apex); + _unused_ int ret = zone_contents_add_rr(z, &soa, &unused); + knot_rrset_clear(&soa, NULL); + assert(ret == KNOT_EOK); + tm2_add_all(z); + } + return z; +} + +static changeset_t *tm2_chs_unzone(const knot_dname_t *apex) +{ + changeset_t *ch = changeset_new(apex); + if (ch != NULL) { + changeset_set_soa_serials(ch, 1, 2, apex); + tm2_add_all(ch->remove); + _unused_ int ret = changeset_add_addition(ch, tm_rrs_int(apex, 0), 0); + assert(ret == KNOT_EOK); + } + return ch; +} + +static int merged_present(void) +{ + bool exists, has_merged; + return journal_info(jj, &exists, NULL, NULL, NULL, &has_merged, NULL, NULL, NULL) == KNOT_EOK && exists && has_merged; +} + +static void test_merge(const knot_dname_t *apex) +{ + int i, ret; + list_t l; + + // allow merge + set_conf(-1, 400 * 1024, apex); + ok(!journal_allow_flush(jj), "journal: merge allowed"); + + ret = journal_scrape_with_md(jj, false); + is_int(KNOT_EOK, ret, "journal: journal_drop_changesets must be ok"); + + // insert stuff and check the merge + for (i = 0; !merged_present() && i < 40000; i++) { + ret = journal_insert(jj, tm_chs(apex, i), NULL, NULL); + assert(ret == KNOT_EOK); + } + ret = journal_sem_check(jj); + is_int(KNOT_EOK, ret, "journal: sem check (%s)", knot_strerror(ret)); + journal_read_t *read = NULL; + ret = load_j_list(&jj, false, 0, &read, &l); + is_int(KNOT_EOK, ret, "journal: journal_load_changesets must be ok"); + assert(ret == KNOT_EOK); + ok(list_size(&l) == 2, "journal: read the merged and one following"); + changeset_t * mch = (changeset_t *)HEAD(l); + ok(list_size(&l) >= 1 && tm_rrcnt(mch, 1) == 2, "journal: merged additions # = 2"); + ok(list_size(&l) >= 1 && tm_rrcnt(mch, -1) == 0, "journal: merged removals # = 0"); + changesets_free(&l); + journal_read_end(read); + + // insert one more and check the #s of results + ret = journal_insert(jj, tm_chs(apex, i), NULL, NULL); + is_int(KNOT_EOK, ret, "journal: insert one more (%s)", knot_strerror(ret)); + ret = load_j_list(&jj, false, 0, &read, &l); + is_int(KNOT_EOK, ret, "journal: journal_load_changesets2 must be ok"); + ok(list_size(&l) == 3, "journal: read merged together with new changeset"); + changesets_free(&l); + journal_read_end(read); + ret = load_j_list(&jj, false, i - 3, &read, &l); + is_int(KNOT_EOK, ret, "journal: journal_load_changesets3 must be ok"); + ok(list_size(&l) == 4, "journal: read short history of merged/unmerged changesets"); + changesets_free(&l); + journal_read_end(read); + + // insert large zone-in-journal taking more than one chunk + zone_contents_t *bigz = tm2_zone(apex); + ret = journal_insert_zone(jj, bigz); + zone_contents_deep_free(bigz); + is_int(KNOT_EOK, ret, "journal: insert large zone-in-journal"); + + // insert changeset that will cancel it mostly out + changeset_t *bigz_cancelout = tm2_chs_unzone(apex); + ret = journal_insert(jj, bigz_cancelout, NULL, NULL); + changeset_free(bigz_cancelout); + is_int(KNOT_EOK, ret, "journal: insert cancel-out changeset"); + + // now fill up with dumy changesets to enforce merge + tm_chs(apex, -1); + while (changeset_to(tm_chs(apex, 0)) != 2) { } + for (i = 0; i < 1600; i++) { + ret = journal_insert(jj, tm_chs(apex, i), NULL, NULL); + assert(ret == KNOT_EOK); + } + + // finally: the test case. Reading the journal now must be no EMALF and + // the zone-in-journal must be little + ret = load_j_list(&jj, true, 0, &read, &l); + is_int(KNOT_EOK, ret, "journal: read chunks-shrinked zone-in-journal"); + is_int(4, trie_weight(((changeset_t *)HEAD(l))->add->nodes->trie), "journal: small merged zone-in-journal"); + changesets_free(&l); + journal_read_end(read); + + ret = journal_scrape_with_md(jj, false); + assert(ret == KNOT_EOK); + + // disallow merge + unset_conf(); + set_conf(1000, 512 * 1024, apex); + ok(journal_allow_flush(jj), "journal: merge disallowed"); + + tm_rrs(NULL, 0); + tm_chs(NULL, 0); + tm_rrs_int(NULL, 0); + unset_conf(); +} + +static void test_stress_base(const knot_dname_t *apex, + size_t update_size, size_t file_size) +{ + uint32_t serial = 0; + + int ret = knot_lmdb_reconfigure(&jdb, test_dir_name, file_size, journal_env_flags(JOURNAL_MODE_ASYNC, false)); + is_int(KNOT_EOK, ret, "journal: reconfigure to mapsize %zu (%s)", file_size, knot_strerror(ret)); + + set_conf(1000, file_size / 2, apex); + + changeset_t ch; + ret = changeset_init(&ch, apex); + ok(ret == KNOT_EOK, "journal: changeset init (%d)", ret); + init_random_changeset(&ch, serial, serial + 1, update_size, apex, false); + + for (int i = 1; i <= 6; ++i) { + serial = 0; + while (true) { + changeset_set_soa_serials(&ch, serial, serial + 1, apex); + ret = journal_insert(jj, &ch, NULL, NULL); + if (ret == KNOT_EOK) { + serial++; + } else { + break; + } + } + + ret = journal_set_flushed(jj); + if (ret == KNOT_EOK) { + ret = journal_sem_check(jj); + } + ok(serial > 0 && ret == KNOT_EOK, "journal: pass #%d fillup run (%d inserts) (%s)", i, serial, knot_strerror(ret)); + } + + changeset_clear(&ch); + + unset_conf(); +} + +/*! \brief Test behavior when writing to the journal and flushing it. */ +static void test_stress(const knot_dname_t *apex) +{ + diag("stress test: small data"); + test_stress_base(apex, 40, (1024 + 512) * 1024); + + diag("stress test: medium data"); + test_stress_base(apex, 400, 3 * 1024 * 1024); + + diag("stress test: large data"); + test_stress_base(apex, 4000, 10 * 1024 * 1024); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + const knot_dname_t *apex = (const uint8_t *)"\4test"; + const knot_dname_t *apex2 = (const uint8_t *)"\4ufoo"; + + test_dir_name = test_mkdtemp(); + + test_journal_db(); + + test_store_load(apex); + + if (lmdb_page_size(&jdb) == 4096) { + test_size_control(apex, apex2); + } // else it is not manually optimized enough to test correctly + + test_merge(apex); + + test_stress(apex); + + knot_lmdb_deinit(&jdb); + + test_rm_rf(test_dir_name); + free(test_dir_name); + + return 0; +} diff --git a/tests/knot/test_kasp_db.c b/tests/knot/test_kasp_db.c new file mode 100644 index 0000000..e4f9766 --- /dev/null +++ b/tests/knot/test_kasp_db.c @@ -0,0 +1,233 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> + +#include <tap/basic.h> +#include <tap/files.h> + +#include "libknot/libknot.h" +#include "test_conf.h" +#include "knot/dnssec/kasp/kasp_db.c" + +#define CHARS500_1 "kTZgFfrHPP2EOSK24zRjY9GlgCUEkZNBF5UwqsTWisCxGQT4ieinitjXWT1c" \ + "pj+OR8UX/httSugee+MFsm5yOU/4/211BpLKwwOIAt4Yf8K7Bc+oXTdk15cH" \ + "TRZtshM1AtfjRsX9rsLDsnaFCyMXzty9AQoRxSphjxnUUC6fszfrSsRx7htl" \ + "/Xn1PAuwp9Bfn+FxAws98LYVuwiDqUgn4BR5lELdGd16zNOZnN7v023pmPDM" \ + "nGyvIATuqTCPbFeXTfw7aIDyx2DF+y95/kSnPtY3c1b0Yf+oCv4t3Hx2jjWT" \ + "9zuC6H+d+PL6HWqilJBs7ysn2FVpnE/Yo44VrQ8orw8QFZr1kR6z7AOVAcMk" \ + "ac+44swsc8orGCyJx6OlUfN5oU3YahUfLqg9ewl13+P2chmeI6wUyttKsq/4" \ + "Ud0YQAozBabiAKr1O/Eg7sZR6bV1YkCydQyYgmR/+VOu9D8Ld6uO4DcvhiE/" \ + "2AmTkLsKLxtpMnQqsTnx" +#define CHARS500_2 "pzqkMLvpxUYYg0KuMCcBsk9aMm4b5Ny+vJ5UnTq8DVC0jHJJyyGcljKqfpi3" \ + "MkjfrWY0rbzXFZbZZ6i8bmhhRBcSxE+tK/3AU1LR7ZJsTuITuoJo5LKRH7Uu" \ + "MU7RBAzFuk3o+Pcyk+9UdbiRn9p4QqPTvb+2xfYn1pJvGHofJcQsSsPEe9Hw" \ + "ycVW+kdImvWiidn0/e1G6B2xibovnPKDUBFmTbdZIBKHb/eUUoUCNA9CWt5N" \ + "g8MutK2ixlBJlOvA6CA1V/VW56EJpLqvMxLaoRks5VY5Ls7zWAy97GEFH0Pl" \ + "uO/Rba1du5tsC0MAC08hljlmu9uoPhsvHdBYHUnQ7jDuYnu9GN3DN0Z6oVbV" \ + "N01JQZYhKQK/Bl61oM5JubLydtAypryDoG3IH75LhoVC8iGxDoDkxt3zoi/Q" \ + "PVfPZZsm5j5UOs3wrQL0KWylm2IDK42mrHK8F/XebnOYLNLQaan2a90C+fhH" \ + "a6hvu0RorkZzGNAZkq/D" + +const knot_dname_t *zone1 = (const knot_dname_t *)"\x05""zonea"; +const knot_dname_t *zone2 = (const knot_dname_t *)"\x05""zoneb"; + +knot_lmdb_db_t _db, *db = &_db; + +const key_params_t params1 = { .id = "key id 1", .keytag = 1, .timing = { 1, 11, 111, 1111, 11111 }, + .public_key = { 520, (uint8_t *)"pk1 plus 500 chars: " CHARS500_1 } }; +const key_params_t params2 = { .id = "key id 2", .keytag = 2, .timing = { 2, 22, 222, 2222, 22222 }, + .public_key = { 520, (uint8_t *)"pk2 plus 500 chars: " CHARS500_2 } }; + +bool params_eq(const key_params_t *a, const key_params_t *b) +{ + return ((a->keytag == b->keytag) && (a->public_key.size == b->public_key.size) && + (a->timing.retire == b->timing.retire) && (strcmp(a->id, b->id) == 0) && + (memcmp(a->public_key.data, b->public_key.data, b->public_key.size) == 0)); +} + +static void init_key_records(key_records_t *r) +{ + knot_rrset_init(&r->dnskey, knot_dname_copy(zone1, NULL), + KNOT_RRTYPE_DNSKEY, KNOT_CLASS_IN, 3600); + knot_rrset_init(&r->cdnskey, knot_dname_copy(zone1, NULL), + KNOT_RRTYPE_CDNSKEY, KNOT_CLASS_IN, 0); + knot_rrset_init(&r->cds, knot_dname_copy(zone1, NULL), + KNOT_RRTYPE_CDS, KNOT_CLASS_IN, 0); + knot_rrset_init(&r->rrsig, knot_dname_copy(zone1, NULL), + KNOT_RRTYPE_RRSIG, KNOT_CLASS_IN, 3600); + knot_rrset_add_rdata(&r->rrsig, (uint8_t *)CHARS500_1, 500, NULL); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + char *test_dir_name = test_mkdtemp(); + bool ignore = false; + + list_t l; + key_params_t *params; +#define free_params free(params->id); free(params->public_key.data); params->id = NULL; params->public_key.data = NULL; + + knot_lmdb_init(db, test_dir_name, 500*1024*1024, 0, "keys_db"); + int ret = knot_lmdb_open(db); + is_int(KNOT_EOK, ret, "kasp_db: open eok"); + ok(db->env != NULL, "kasp_db: lmdb env notnull"); + + ret = kasp_db_add_key(db, zone1, ¶ms1); + is_int(KNOT_EOK, ret, "kasp_db: add key 1 eok"); + + ret = kasp_db_list_keys(db, zone1, &l); + is_int(KNOT_EOK, ret, "kasp_db: list keys 1 eok"); + is_int(1, list_size(&l), "kasp_db: list keys reports one key 1"); + params = ((ptrnode_t *)HEAD(l))->d; + ok(params_eq(params, ¶ms1), "kasp_db: key params equal 1"); + free_params + ptrlist_deep_free(&l, NULL); + + ret = kasp_db_list_keys(db, zone2, &l); + is_int(KNOT_ENOENT, ret, "kasp_db: list keys 1 enoent"); + is_int(0, list_size(&l), "kasp_db: list keys reports no keys 1"); + ptrlist_deep_free(&l, NULL); + + ret = kasp_db_share_key(db, zone1, zone2, params1.id); + is_int(KNOT_EOK, ret, "kasp_db: share key eok"); + + ret = kasp_db_list_keys(db, zone2, &l); + is_int(KNOT_EOK, ret, "kasp_db: list keys 3 eok"); + is_int(1, list_size(&l), "kasp_db: list keys reports one key 2"); + params = ((ptrnode_t *)HEAD(l))->d; + free_params + ptrlist_deep_free(&l, NULL); + + ret = kasp_db_add_key(db, zone2, ¶ms2); + is_int(KNOT_EOK, ret, "kasp_db: add key 2 eok"); + + ret = kasp_db_list_keys(db, zone2, &l); + is_int(KNOT_EOK, ret, "kasp_db: list keys 4 eok"); + is_int(2, list_size(&l), "kasp_db: list keys reports two keys 1"); + params = ((ptrnode_t *)TAIL(l))->d; + ok(params_eq(params, ¶ms2), "kasp_db: key params equal 2"); + free_params + params = ((ptrnode_t *)HEAD(l))->d; + free_params + ptrlist_deep_free(&l, NULL); + + ret = kasp_db_delete_key(db, zone1, params1.id, &ignore); + is_int(KNOT_EOK, ret, "kasp_db: delete key 1 eok"); + + ret = kasp_db_list_keys(db, zone1, &l); + is_int(KNOT_ENOENT, ret, "kasp_db: list keys 2 enoent"); + is_int(list_size(&l), 0, "kasp_db: list keys reports no keys 2"); + ptrlist_deep_free(&l, NULL); + + dnssec_binary_t salt1 = { 500, (uint8_t *)CHARS500_1 }, salt2 = { 0 }; + knot_time_t time = 0; + ret = kasp_db_store_nsec3salt(db, zone1, &salt1, 1234); + is_int(KNOT_EOK, ret, "kasp_db: store nsec3salt"); + ret = kasp_db_load_nsec3salt(db, zone1, &salt2, &time); + is_int(KNOT_EOK, ret, "kasp_db: load nsec3salt"); + is_int(1234, time, "kasp_db: salt_created preserved"); + is_int(0, dnssec_binary_cmp(&salt1, &salt2), "kasp_db: salt preserved"); + dnssec_binary_free(&salt2); + salt1.size = 0; + ret = kasp_db_store_nsec3salt(db, zone2, &salt1, 0); + is_int(KNOT_EOK, ret, "kasp_db: store empty nsec3salt"); + ret = kasp_db_load_nsec3salt(db, zone2, &salt2, &time); + is_int(KNOT_EOK, ret, "kasp_db: load empty nsec3salt"); + is_int(0, time, "kasp_db: empty salt_created preserved"); + is_int(0, salt2.size, "kasp_db: empty salt preserved"); + dnssec_binary_free(&salt2); + + ret = kasp_db_delete_all(db, zone2); + is_int(KNOT_EOK, ret, "kasp_db: delete all"); + ret = kasp_db_list_keys(db, zone2, &l); + is_int(KNOT_ENOENT, ret, "kasp_db: delete all deleted keys"); + ret = kasp_db_load_nsec3salt(db, zone2, &salt2, &time); + is_int(KNOT_ENOENT, ret, "kasp_db: delete all removed nsec3salt"); + dnssec_binary_free(&salt2); + + ret = kasp_db_store_serial(db, zone2, KASPDB_SERIAL_MASTER, 1); + is_int(KNOT_EOK, ret, "kasp_db: store master_serial"); + ret = kasp_db_store_serial(db, zone2, KASPDB_SERIAL_LASTSIGNED, 2); + is_int(KNOT_EOK, ret, "kasp_db: store lastsigned_serial"); + uint32_t serial = 0; + ret = kasp_db_load_serial(db, zone2, KASPDB_SERIAL_MASTER, &serial); + is_int(KNOT_EOK, ret, "kasp_db: load master_serial"); + is_int(1, serial, "kasp_db: master_serial preserved"); + ret = kasp_db_load_serial(db, zone2, KASPDB_SERIAL_LASTSIGNED, &serial); + is_int(KNOT_EOK, ret, "kasp_db: load lastsigned_serial"); + is_int(2, serial, "kasp_db: lastsigned_serial preserved"); + + ret = kasp_db_add_key(db, zone1, ¶ms1); + ok(ret == KNOT_EOK, "kasp_db: add key1"); + ret = kasp_db_add_key(db, zone2, ¶ms2); + ok(ret == KNOT_EOK, "kasp_db: add key2"); + + ret = kasp_db_set_policy_last(db, "policy1", NULL, zone1, params1.id); + is_int(KNOT_EOK, ret, "kasp_db: set policylast"); + knot_dname_t *zoneX; + char *keyidX; + ret = kasp_db_get_policy_last(db, "policy1", &zoneX, &keyidX); + is_int(KNOT_EOK, ret, "kasp_db: get policylast"); + ok(knot_dname_cmp(zoneX, zone1) == 0 && keyidX != NULL && + strcmp(keyidX, params1.id) == 0, "kasp_db: policy last preserved"); + free(zoneX); + free(keyidX); + ret = kasp_db_set_policy_last(db, "policy1", params1.id, zone2, params2.id); + is_int(KNOT_EOK, ret, "kasp_db: reset policylast"); + ret = kasp_db_get_policy_last(db, "policy1", &zoneX, &keyidX); + is_int(KNOT_EOK, ret, "kasp_db: reget policylast"); + ok(knot_dname_cmp(zoneX, zone2) == 0 && keyidX != NULL && + strcmp(keyidX, params2.id) == 0, "kasp_db: policy last represerved"); + free(zoneX); + free(keyidX); + ret = kasp_db_set_policy_last(db, "policy1", params1.id, zone1, params1.id); + is_int(KNOT_ESEMCHECK, ret, "kasp_db: refused policylast with wrong keyid"); + ret = kasp_db_get_policy_last(db, "policy1", &zoneX, &keyidX); + is_int(KNOT_EOK, ret, "kasp_db: reget policylast2"); + ok(knot_dname_cmp(zoneX, zone2) == 0 && keyidX != NULL && + strcmp(keyidX, params2.id) == 0, "kasp_db: policy last represerved2"); + free(zoneX); + free(keyidX); + + knot_time_t two = 2; + key_records_t kr; + init_key_records(&kr); + ret = kasp_db_store_offline_records(db, 1, &kr); + is_int(KNOT_EOK, ret, "kasp_db: store key records"); + //key_records_clear_rdatasets(&kr); + ret = kasp_db_load_offline_records(db, zone1, &two, &time, &kr); + is_int(KNOT_EOK, ret, "kasp_db: load key records"); + ok(kr.cds.type == KNOT_RRTYPE_CDS && kr.rrsig.rrs.count == 1, "kasp_db: key records ok"); + is_int(0, time, "kasp_db: no next key records"); + key_records_clear(&kr); + ret = kasp_db_delete_offline_records(db, zone1, 1, 3); + is_int(KNOT_EOK, ret, "kasp_db: delete key records"); + ret = kasp_db_load_offline_records(db, zone1, &two, &time, &kr); + is_int(KNOT_ENOENT, ret, "kasp_db: no more key records"); + + knot_lmdb_deinit(db); + + test_rm_rf(test_dir_name); + free(test_dir_name); + + return 0; +} diff --git a/tests/knot/test_node.c b/tests/knot/test_node.c new file mode 100644 index 0000000..e8c6cdb --- /dev/null +++ b/tests/knot/test_node.c @@ -0,0 +1,128 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> + +#include "knot/zone/node.h" +#include "libknot/libknot.h" + +static knot_rrset_t *create_dummy_rrset(const knot_dname_t *owner, uint16_t type) +{ + knot_rrset_t *r = knot_rrset_new(owner, type, KNOT_CLASS_IN, 3600, NULL); + assert(r); + uint8_t wire[16] = { 0 }; + memcpy(wire, "testtest", strlen("testtest")); + int ret = knot_rrset_add_rdata(r, wire, strlen("testtest"), NULL); + assert(ret == KNOT_EOK); + (void)ret; + return r; +} + +static knot_rrset_t *create_dummy_rrsig(const knot_dname_t *owner, uint16_t type) +{ + knot_rrset_t *r = knot_rrset_new(owner, KNOT_RRTYPE_RRSIG, KNOT_CLASS_IN, + 3600, NULL); + assert(r); + uint8_t wire[sizeof(uint16_t)]; + knot_wire_write_u16(wire, type); + int ret = knot_rrset_add_rdata(r, wire, sizeof(uint16_t), NULL); + assert(ret == KNOT_EOK); + (void)ret; + return r; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_dname_t *dummy_owner = knot_dname_from_str_alloc("test."); + // Test new + zone_node_t *node = node_new(dummy_owner, false, false, NULL); + ok(node != NULL, "Node: new"); + assert(node); + ok(knot_dname_is_equal(node->owner, dummy_owner), "Node: new - set fields"); + + // Test RRSet addition + knot_rrset_t *dummy_rrset = create_dummy_rrset(dummy_owner, KNOT_RRTYPE_TXT); + int ret = node_add_rrset(node, dummy_rrset, NULL); + ok(ret == KNOT_EOK && node->rrset_count == 1 && + knot_rdataset_eq(&dummy_rrset->rrs, &node->rrs[0].rrs), "Node: add RRSet."); + + // Test RRSet getters + knot_rrset_t *n_rrset = node_create_rrset(node, KNOT_RRTYPE_TXT); + ok(n_rrset && knot_rrset_equal(n_rrset, dummy_rrset, true), + "Node: create existing RRSet."); + + knot_rrset_free(n_rrset, NULL); + + n_rrset = node_create_rrset(node, KNOT_RRTYPE_SOA); + ok(n_rrset == NULL, "Node: create non-existing RRSet."); + + knot_rrset_t stack_rrset = node_rrset(node, KNOT_RRTYPE_TXT); + ok(knot_rrset_equal(&stack_rrset, dummy_rrset, true), "Node: get existing RRSet."); + stack_rrset = node_rrset(node, KNOT_RRTYPE_SOA); + ok(knot_rrset_empty(&stack_rrset), "Node: get non-existent RRSet."); + + knot_rdataset_t *n_rdataset = node_rdataset(node, KNOT_RRTYPE_TXT); + ok(n_rdataset && knot_rdataset_eq(n_rdataset, &dummy_rrset->rrs), + "Node: get existing rdataset."); + n_rdataset = node_rdataset(node, KNOT_RRTYPE_SOA); + ok(n_rdataset == NULL, "Node: get non-existing rdataset."); + + stack_rrset = node_rrset_at(node, 0); + ok(knot_rrset_equal(&stack_rrset, dummy_rrset, true), + "Node: get existing position."); + stack_rrset = node_rrset_at(node, 1); + ok(knot_rrset_empty(&stack_rrset), "Node: get non-existent position."); + + // Test TTL mismatch + dummy_rrset->ttl = 1800; + ret = node_add_rrset(node, dummy_rrset, NULL); + ok(ret == KNOT_ETTL && node->rrset_count == 1, + "Node: add RRSet, TTL mismatch."); + + knot_rrset_free(dummy_rrset, NULL); + + // Test bool functions + ok(node_rrtype_exists(node, KNOT_RRTYPE_TXT), "Node: type exists."); + ok(!node_rrtype_exists(node, KNOT_RRTYPE_AAAA), "Node: type does not exist."); + ok(!node_rrtype_is_signed(node, KNOT_RRTYPE_TXT), "Node: type is not signed."); + + dummy_rrset = create_dummy_rrsig(dummy_owner, KNOT_RRTYPE_TXT); + ret = node_add_rrset(node, dummy_rrset, NULL); + assert(ret == KNOT_EOK); + + ok(node_rrtype_is_signed(node, KNOT_RRTYPE_TXT), "Node: type is signed."); + + knot_rrset_free(dummy_rrset, NULL); + + // Test remove RRset + node_remove_rdataset(node, KNOT_RRTYPE_AAAA); + ok(node->rrset_count == 2, "Node: remove non-existent rdataset."); + node_remove_rdataset(node, KNOT_RRTYPE_TXT); + ok(node->rrset_count == 1, "Node: remove existing rdataset."); + + // "Test" freeing + node_free_rrsets(node, NULL); + ok(node->rrset_count == 0, "Node: free RRSets."); + + node_free(node, NULL); + + knot_dname_free(dummy_owner, NULL); + + return 0; +} diff --git a/tests/knot/test_process_query.c b/tests/knot/test_process_query.c new file mode 100644 index 0000000..83f62d8 --- /dev/null +++ b/tests/knot/test_process_query.c @@ -0,0 +1,201 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> +#include <tap/files.h> +#include <string.h> +#include <stdlib.h> + +#include "libknot/descriptor.h" +#include "libknot/packet/wire.h" +#include "knot/nameserver/process_query.h" +#include "test_server.h" +#include "contrib/sockaddr.h" +#include "contrib/ucw/mempool.h" + +/* Basic response check (4 TAP tests). */ +static void answer_sanity_check(const uint8_t *query, + const uint8_t *answer, uint16_t answer_len, + uint8_t expected_rcode, const char *name) +{ + ok(answer_len >= KNOT_WIRE_HEADER_SIZE, "ns: len(%s answer) >= DNS header", name); + if (answer_len >= KNOT_WIRE_HEADER_SIZE) { + ok(knot_wire_get_qr(answer), "ns: %s answer has QR=1", name); + is_int(expected_rcode, knot_wire_get_rcode(answer), "ns: %s answer RCODE=%d", name, expected_rcode); + is_int(knot_wire_get_id(query), knot_wire_get_id(answer), "ns: %s MSGID match", name); + } else { + skip_block(3, "ns: can't check DNS header"); + } +} + +/* Resolve query and check answer for sanity (2 TAP tests). */ +static void exec_query(knot_layer_t *layer, const char *name, + knot_pkt_t *query, + uint8_t expected_rcode) +{ + knot_pkt_t *answer = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, NULL); + assert(answer); + + /* Input packet. */ + knot_pkt_parse(query, 0); + knot_layer_consume(layer, query); + + ok(layer->state == KNOT_STATE_PRODUCE || + layer->state == KNOT_STATE_FAIL, "ns: process %s query", name); + + /* Create answer. */ + knot_layer_produce(layer, answer); + if (layer->state == KNOT_STATE_FAIL) { + /* Allow 1 generic error response. */ + knot_layer_produce(layer, answer); + } + + ok(layer->state == KNOT_STATE_DONE, "ns: answer %s query", name); + + /* Check answer. */ + answer_sanity_check(query->wire, answer->wire, answer->size, expected_rcode, name); + + knot_pkt_free(answer); +} + +/* \internal Helpers */ +#define WIRE_COPY(dst, dst_len, src, src_len) \ + memcpy(dst, src, src_len); \ + dst_len = src_len; + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_mm_t mm; + mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE); + + /* Create processing context. */ + knot_layer_t proc; + memset(&proc, 0, sizeof(knot_layer_t)); + knot_layer_init(&proc, &mm, process_query_layer()); + + /* Create temporary storage directory. */ + char *temp_dir = test_mkdtemp(); + ok(temp_dir != NULL, "make temporary directory"); + + /* Create fake server environment. */ + server_t server; + int ret = create_fake_server(&server, proc.mm, temp_dir); + is_int(KNOT_EOK, ret, "ns: fake server initialization"); + if (ret != KNOT_EOK) { + goto fatal; + } + + zone_t *zone = knot_zonedb_find(server.zone_db, ROOT_DNAME); + + /* Prepare. */ + knot_pkt_t *query = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, proc.mm); + + /* Create query processing parameter. */ + struct sockaddr_storage ss; + memset(&ss, 0, sizeof(struct sockaddr_storage)); + sockaddr_set(&ss, AF_INET, "127.0.0.1", 53); + knotd_qdata_params_t params = { + .proto = KNOTD_QUERY_PROTO_TCP, + .remote = &ss, + .server = &server + }; + + /* Query processor (CH zone) */ + knot_layer_begin(&proc, ¶ms); + knot_pkt_clear(query); + knot_pkt_put_question(query, IDSERVER_DNAME, KNOT_CLASS_CH, KNOT_RRTYPE_TXT); + exec_query(&proc, "CH TXT", query, KNOT_RCODE_NOERROR); + + /* Query processor (valid input). */ + knot_layer_reset(&proc); + knot_pkt_clear(query); + knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); + exec_query(&proc, "IN/root", query, KNOT_RCODE_NOERROR); + + /* Query processor (-1 bytes, not enough data). */ + knot_layer_reset(&proc); + query->size -= 1; + exec_query(&proc, "IN/few-data", query, KNOT_RCODE_FORMERR); + query->size += 1; + + /* Query processor (+1 bytes trailing). */ + knot_layer_reset(&proc); + query->wire[query->size] = '\1'; /* Initialize the "garbage" value. */ + query->size += 1; + exec_query(&proc, "IN/trail-garbage", query, KNOT_RCODE_FORMERR); + query->size -= 1; + + /* Forge NOTIFY query from SOA query. */ + knot_layer_reset(&proc); + knot_wire_set_opcode(query->wire, KNOT_OPCODE_NOTIFY); + exec_query(&proc, "IN/notify", query, KNOT_RCODE_NOTAUTH); + + /* Forge AXFR query. */ + knot_layer_reset(&proc); + knot_pkt_clear(query); + knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_AXFR); + exec_query(&proc, "IN/axfr", query, KNOT_RCODE_NOTAUTH); + + /* Forge IXFR query (well formed). */ + knot_layer_reset(&proc); + knot_pkt_clear(query); + knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_IXFR); + /* Append SOA RR. */ + knot_rrset_t soa_rr = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA); + knot_pkt_begin(query, KNOT_AUTHORITY); + knot_pkt_put(query, KNOT_COMPR_HINT_NONE, &soa_rr, 0); + exec_query(&proc, "IN/ixfr", query, KNOT_RCODE_NOTAUTH); + + /* \note Tests below are not possible without proper zone and zone data. */ + /* #189 Process UPDATE query. */ + /* #189 Process AXFR client. */ + /* #189 Process IXFR client. */ + + /* Query processor (smaller than DNS header, ignore). */ + knot_layer_reset(&proc); + knot_pkt_clear(query); + knot_pkt_put_question(query, ROOT_DNAME, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); + size_t orig_query_size = query->size; + query->size = KNOT_WIRE_HEADER_SIZE - 1; + knot_layer_consume(&proc, query); + ok(proc.state == KNOT_STATE_NOOP, "ns: IN/less-than-header query ignored"); + query->size = orig_query_size; + + /* Query processor (response, ignore). */ + knot_layer_reset(&proc); + knot_wire_set_qr(query->wire); + knot_layer_consume(&proc, query); + ok(proc.state == KNOT_STATE_NOOP, "ns: IN/less-than-header query ignored"); + + /* Finish. */ + knot_layer_finish(&proc); + ok(proc.state == KNOT_STATE_NOOP, "ns: processing end" ); + +fatal: + /* Cleanup. */ + mp_delete((struct mempool *)mm.ctx); + server_deinit(&server); + conf_free(conf()); + test_rm_rf(temp_dir); + free(temp_dir); + + return 0; +} + +#undef WIRE_COPY diff --git a/tests/knot/test_query_module.c b/tests/knot/test_query_module.c new file mode 100644 index 0000000..4ab14d2 --- /dev/null +++ b/tests/knot/test_query_module.c @@ -0,0 +1,87 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <string.h> +#include <stdlib.h> + +#include "libknot/libknot.h" +#include "knot/nameserver/query_module.h" +#include "libknot/packet/pkt.h" + +/* Universal processing stage. */ +unsigned state_visit(unsigned state, knot_pkt_t *pkt, knotd_qdata_t *qdata, + knotd_mod_t *mod) +{ + /* Visit current state */ + bool *state_map = (bool *)mod; + state_map[state] = true; + + return state + 1; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Create a map of expected steps. */ + bool state_map[KNOTD_STAGES] = { false }; + + /* Prepare query plan. */ + struct query_plan *plan = query_plan_create(); + ok(plan != NULL, "query_plan: create"); + if (plan == NULL) { + goto fatal; + } + + /* Register all stage visits. */ + int ret = KNOT_EOK; + for (unsigned stage = KNOTD_STAGE_BEGIN; stage < KNOTD_STAGES; ++stage) { + ret = query_plan_step(plan, stage, state_visit, state_map); + if (ret != KNOT_EOK) { + break; + } + } + is_int(KNOT_EOK, ret, "query_plan: planned all steps"); + + /* Execute the plan. */ + int state = 0, next_state = 0; + for (unsigned stage = KNOTD_STAGE_BEGIN; stage < KNOTD_STAGES; ++stage) { + struct query_step *step = NULL; + WALK_LIST(step, plan->stage[stage]) { + next_state = step->process(state, NULL, NULL, step->ctx); + if (next_state != state + 1) { + break; + } + state = next_state; + } + } + ok(state == KNOTD_STAGES, "query_plan: executed all steps"); + + /* Verify if all steps executed their callback. */ + for (state = 0; state < KNOTD_STAGES; ++state) { + if (state_map[state] == false) { + break; + } + } + ok(state == KNOTD_STAGES, "query_plan: executed all callbacks"); + +fatal: + /* Free the query plan. */ + query_plan_free(plan); + + return 0; +} diff --git a/tests/knot/test_requestor.c b/tests/knot/test_requestor.c new file mode 100644 index 0000000..809c62f --- /dev/null +++ b/tests/knot/test_requestor.c @@ -0,0 +1,189 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> + +#include "libknot/descriptor.h" +#include "libknot/errcode.h" +#include "knot/query/layer.h" +#include "knot/query/requestor.h" +#include "contrib/mempattern.h" +#include "contrib/net.h" +#include "contrib/sockaddr.h" +#include "contrib/ucw/mempool.h" + +bool TFO = false; + +/* @note Purpose of this test is not to verify process_answer functionality, + * but simply if the requesting/receiving works, so mirror is okay. */ +static int reset(knot_layer_t *ctx) { return KNOT_STATE_PRODUCE; } +static int begin(knot_layer_t *ctx, void *module_param) { return reset(ctx); } +static int finish(knot_layer_t *ctx) { return reset(ctx); } +static int in(knot_layer_t *ctx, knot_pkt_t *pkt) { return KNOT_STATE_DONE; } +static int out(knot_layer_t *ctx, knot_pkt_t *pkt) { return KNOT_STATE_CONSUME; } + +static const int TIMEOUT = 2000; + +/*! \brief Dummy answer processing module. */ +const knot_layer_api_t dummy_module = { + &begin, &reset, &finish, &in, &out +}; + +static void set_blocking_mode(int sock) +{ + int flags = fcntl(sock, F_GETFL); + flags &= ~O_NONBLOCK; + fcntl(sock, F_SETFL, flags); +} + +static void *responder_thread(void *arg) +{ + int fd = *(int *)arg; + + set_blocking_mode(fd); + uint8_t buf[KNOT_WIRE_MAX_PKTSIZE] = { 0 }; + while (true) { + int client = accept(fd, NULL, NULL); + if (client < 0) { + break; + } + int len = net_dns_tcp_recv(client, buf, sizeof(buf), -1); + if (len < KNOT_WIRE_HEADER_SIZE) { + close(client); + break; + } + knot_wire_set_qr(buf); + net_dns_tcp_send(client, buf, len, -1, NULL); + close(client); + } + + return NULL; +} + +/* Test implementations. */ + +static knot_request_t *make_query(knot_requestor_t *requestor, + const struct sockaddr_storage *dst, + const struct sockaddr_storage *src) +{ + knot_pkt_t *pkt = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, requestor->mm); + assert(pkt); + static const knot_dname_t *root = (uint8_t *)""; + knot_pkt_put_question(pkt, root, KNOT_CLASS_IN, KNOT_RRTYPE_SOA); + + knot_request_flag_t flags = TFO ? KNOT_REQUEST_TFO: KNOT_REQUEST_NONE; + + return knot_request_make_generic(requestor->mm, dst, src, pkt, NULL, + NULL, NULL, NULL, 0, flags); +} + +static void test_disconnected(knot_requestor_t *requestor, + const struct sockaddr_storage *dst, + const struct sockaddr_storage *src) +{ + knot_request_t *req = make_query(requestor, dst, src); + int ret = knot_requestor_exec(requestor, req, TIMEOUT); + /* ECONNREFUSED on FreeBSD, ETIMEOUT on NetBSD/OpenBSD/macOS. */ + ret = (ret == KNOT_ECONNREFUSED || ret == KNOT_ETIMEOUT) ? KNOT_ECONN : ret; + is_int(KNOT_ECONN, ret, "requestor: disconnected/exec"); + knot_request_free(req, requestor->mm); + +} + +static void test_connected(knot_requestor_t *requestor, + const struct sockaddr_storage *dst, + const struct sockaddr_storage *src) +{ + /* Enqueue packet. */ + knot_request_t *req = make_query(requestor, dst, src); + int ret = knot_requestor_exec(requestor, req, TIMEOUT); + is_int(KNOT_EOK, ret, "requestor: connected/exec"); + knot_request_free(req, requestor->mm); +} + +int main(int argc, char *argv[]) +{ +#if defined(__linux__) + FILE *fd = fopen("/proc/sys/net/ipv4/tcp_fastopen", "r"); + if (fd != NULL) { + int val = fgetc(fd); + fclose(fd); + // 0 - disabled, 1 - server TFO (client fallbacks), + // 2 - client TFO, 3 - both + if (val == '1' || val == '3') { + TFO = true; + } + } +#endif + plan_lazy(); + + knot_mm_t mm; + mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE); + + /* Initialize requestor. */ + knot_requestor_t requestor; + knot_requestor_init(&requestor, &dummy_module, NULL, &mm); + + /* Define endpoints. */ + struct sockaddr_storage client = { 0 }; + sockaddr_set(&client, AF_INET, "127.0.0.1", 0); + struct sockaddr_storage server = { 0 }; + sockaddr_set(&server, AF_INET, "127.0.0.1", 0); + + /* Bind to random port. */ + int responder_fd = net_bound_socket(SOCK_STREAM, &server, 0, 0); + assert(responder_fd >= 0); + socklen_t addr_len = sockaddr_len(&server); + int ret = getsockname(responder_fd, (struct sockaddr *)&server, &addr_len); + ok(ret == 0, "check getsockname return"); + + /* Test requestor in disconnected environment. */ + test_disconnected(&requestor, &server, &client); + + /* Start responder. */ + ret = listen(responder_fd, 10); + ok(ret == 0, "check listen return"); + + if (TFO) { + ret = net_bound_tfo(responder_fd, 10); + ok(ret == KNOT_EOK, "check bound TFO return"); + } + + pthread_t thread; + pthread_create(&thread, 0, responder_thread, &responder_fd); + + /* Test requestor in connected environment. */ + test_connected(&requestor, &server, &client); + + /* Terminate responder. */ + int conn = net_connected_socket(SOCK_STREAM, &server, NULL, false); + assert(conn > 0); + conn = net_dns_tcp_send(conn, (uint8_t *)"", 1, TIMEOUT, NULL); + assert(conn > 0); + pthread_join(thread, NULL); + close(responder_fd); + + /* Cleanup. */ + mp_delete((struct mempool *)mm.ctx); + + return 0; +} diff --git a/tests/knot/test_semantic_check.in b/tests/knot/test_semantic_check.in new file mode 100644 index 0000000..cd50ef7 --- /dev/null +++ b/tests/knot/test_semantic_check.in @@ -0,0 +1,171 @@ +#!/bin/sh + +KZONECHECK="@top_builddir@/src/kzonecheck" +DATA="@top_srcdir@/tests/knot/semantic_check_data" + +. "@top_srcdir@/tests/tap/libtap.sh" + +TMPDIR=$(test_tmpdir) +LOG="$TMPDIR/log" + +# Params: zonefile fatal_error expected_erros_count semcheck_err_msg +expect_error() +{ + if [ ! -r "$DATA/$1" ]; then + skip_block 4 "missing zone file for test" + return + fi + + "$KZONECHECK" -o example.com "$DATA/$1" > "$LOG" 2>&1 + ok "$1 - check program return" test $? -eq 1 + + fatal=$(grep -E "^error: serious semantic error detected" $LOG | wc -l) + ok "$1 - check fatal" test $fatal -eq $2 + + errors=$(grep -E "^\[.+\] $4" $LOG | wc -l) + ok "$1 - check errors" test $errors -eq $3 + if [ $errors != $3 ]; then + diag "expected errors $3 but found $errors" + fi +} + +#param zonefile +test_correct() +{ + $KZONECHECK -o example.com "$DATA/$1" > /dev/null 2>&1 + ok "$1 - correct zone, without error" test $? -eq 0 +} + +#param zonefile +test_correct_no_dnssec() +{ + $KZONECHECK -o example.com -d off "$DATA/$1" > /dev/null 2>&1 + ok "$1 - correct zone, without error" test $? -eq 0 +} + +if [ ! -x $KZONECHECK ]; then + skip_all "kzonecheck is missing or is not executable" +fi + +# error messages exported from knot/src/zone/semantic-check.c +CDNSKEY_NONE="missing CDNSKEY" +CDNSKEY_NO_CDS="CDNSKEY without corresponding CDS" +CDNSKEY_DELETE="invalid CDNSKEY/CDS for DNSSEC delete algorithm" +CDS_NONE="missing CDS" +CDS_NOT_MATCH="CDS not match CDNSKEY" +CNAME_EXTRA_RECORDS="another record exists beside CNAME" +CNAME_MULTIPLE="multiple CNAME records" +DNAME_CHILDREN="child record exists under DNAME" +DNAME_MULTIPLE="multiple DNAME records" +DNAME_EXTRA_NS="NS record exists beside DNAME" +DNSKEY_INVALID="invalid DNSKEY" +DS_ALG="unknown algorithm in DS" +DS_APEX="DS at the zone apex" +NSEC3PARAM_FLAGS="invalid flags in NSEC3PARAM" +NSEC_NONE="missing NSEC\(3\) record" +NSEC_RDATA_BITMAP="wrong NSEC\(3\) bitmap" +NSEC_RDATA_CHAIN="inconsistent NSEC\(3\) chain" +NSEC3_INSECURE_DELEGATION_OPT="wrong NSEC3 opt-out" +NS_APEX="missing NS at the zone apex" +NS_GLUE="missing glue record" +RRSIG_UNVERIFIABLE="no valid signature for a record" + +plan_lazy + +expect_error "cname_extra_01.zone" 1 1 "$CNAME_EXTRA_RECORDS" +expect_error "cname_extra_02.signed" 1 1 "$CNAME_EXTRA_RECORDS" +expect_error "cname_multiple.zone" 1 1 "$CNAME_MULTIPLE" +expect_error "dname_children.zone" 1 1 "$DNAME_CHILDREN" +expect_error "dname_multiple.zone" 1 1 "$DNAME_MULTIPLE" +expect_error "dname_extra_ns.zone" 1 1 "$DNAME_EXTRA_NS" +expect_error "ds_apex.zone" 1 1 "$DS_APEX" + +expect_error "ns_apex.missing" 0 1 "$NS_APEX" +expect_error "glue_apex_both.missing" 0 2 "$NS_GLUE" +expect_error "glue_apex_one.missing" 0 1 "$NS_GLUE" +expect_error "glue_besides.missing" 0 1 "$NS_GLUE" +expect_error "glue_deleg.missing" 0 1 "$NS_GLUE" +expect_error "glue_in_apex.missing" 0 1 "$NS_GLUE" +expect_error "different_signer_name.signed" 0 1 "$RRSIG_UNVERIFIABLE" +expect_error "no_rrsig.signed" 0 1 "$RRSIG_UNVERIFIABLE" +expect_error "no_rrsig_with_delegation.signed" 0 1 "$RRSIG_UNVERIFIABLE" +expect_error "nsec_broken_chain_01.signed" 0 1 "$NSEC_RDATA_CHAIN" +expect_error "nsec_broken_chain_02.signed" 0 1 "$NSEC_RDATA_CHAIN" +expect_error "nsec_missing.signed" 0 1 "$NSEC_NONE" +expect_error "nsec_multiple.signed" 0 1 "$NSEC_NONE" +expect_error "nsec_wrong_bitmap_01.signed" 0 1 "$NSEC_RDATA_BITMAP" +expect_error "nsec_wrong_bitmap_02.signed" 0 1 "$NSEC_RDATA_BITMAP" +expect_error "nsec3_missing.signed" 0 1 "$NSEC_NONE" +expect_error "nsec3_optout_ent.invalid" 0 1 "$NSEC_NONE" +expect_error "nsec3_wrong_bitmap_01.signed" 0 1 "$NSEC_RDATA_BITMAP" +expect_error "nsec3_wrong_bitmap_02.signed" 0 1 "$NSEC_RDATA_BITMAP" +expect_error "nsec3_ds.signed" 0 1 "$NSEC_NONE" +expect_error "nsec3_optout.signed" 0 1 "$NSEC3_INSECURE_DELEGATION_OPT" +expect_error "nsec3_chain_01.signed" 0 1 "$NSEC_RDATA_CHAIN" +expect_error "nsec3_chain_02.signed" 0 1 "$NSEC_RDATA_CHAIN" +expect_error "nsec3_chain_03.signed" 0 1 "$NSEC_RDATA_CHAIN" +expect_error "nsec3_param_invalid.signed" 0 1 "$NSEC_NONE" +expect_error "nsec3_param_invalid.signed" 0 1 "$NSEC3PARAM_FLAGS" +expect_error "rrsig_signed.signed" 0 1 "$RRSIG_UNVERIFIABLE" +expect_error "rrsig_rdata_ttl.signed" 0 1 "$RRSIG_UNVERIFIABLE" +expect_error "duplicate.signature" 0 1 "$RRSIG_UNVERIFIABLE" +expect_error "missing.signed" 0 1 "$NSEC_NONE" +expect_error "dnskey_param_error.signed" 0 1 "$DNSKEY_INVALID" +expect_error "invalid_ds.signed" 0 2 "$DS_ALG \(keytag 60485" +expect_error "cdnskey.invalid" 0 1 "$CDS_NOT_MATCH" +expect_error "cdnskey.invalid.param" 0 1 "$CDS_NOT_MATCH" +expect_error "cdnskey.nocds" 0 1 "$CDS_NONE" +expect_error "cdnskey.nocdnskey" 0 1 "$CDNSKEY_NONE" +expect_error "cdnskey.nodnskey" 0 1 "$CDNSKEY_NOT_MATCH" +expect_error "cdnskey.orphan.cds" 0 1 "$CDS_NOT_MATCH" +expect_error "cdnskey.orphan.cdnskey" 0 1 "$CDNSKEY_NO_CDS" +expect_error "cdnskey.delete.invalid.cds" 0 1 "$CDNSKEY_DELETE" +expect_error "cdnskey.delete.invalid.cdnskey" 0 1 "$CDNSKEY_DELETE" +expect_error "delegation.signed" 0 1 "$NSEC_RDATA_BITMAP" + +test_correct "rrsig_ttl.signed" +test_correct "no_error_delegation_bitmap.signed" +test_correct "no_error_nsec3_optout.signed" +test_correct "glue_wildcard.valid" +test_correct "glue_no_foreign.valid" +test_correct "glue_in_deleg.valid" +test_correct "cdnskey.cds" +test_correct "cdnskey.delete.both" +test_correct "dname_apex_nsec3.signed" +test_correct "nsec3_optout_ent.valid" +test_correct "nsec3_optout_ent.all" + +test_correct_no_dnssec "no_rrsig.signed" +test_correct_no_dnssec "no_rrsig_with_delegation.signed" +test_correct_no_dnssec "nsec_broken_chain_01.signed" +test_correct_no_dnssec "nsec_broken_chain_02.signed" +test_correct_no_dnssec "nsec_missing.signed" +test_correct_no_dnssec "nsec_multiple.signed" +test_correct_no_dnssec "nsec_wrong_bitmap_01.signed" +test_correct_no_dnssec "nsec_wrong_bitmap_02.signed" +test_correct_no_dnssec "nsec3_missing.signed" +test_correct_no_dnssec "nsec3_wrong_bitmap_01.signed" +test_correct_no_dnssec "nsec3_wrong_bitmap_02.signed" +test_correct_no_dnssec "nsec3_ds.signed" +test_correct_no_dnssec "nsec3_optout.signed" +test_correct_no_dnssec "nsec3_chain_01.signed" +test_correct_no_dnssec "nsec3_chain_02.signed" +test_correct_no_dnssec "nsec3_chain_03.signed" +test_correct_no_dnssec "nsec3_param_invalid.signed" +test_correct_no_dnssec "rrsig_signed.signed" +test_correct_no_dnssec "rrsig_rdata_ttl.signed" +test_correct_no_dnssec "duplicate.signature" +test_correct_no_dnssec "missing.signed" +test_correct_no_dnssec "dnskey_param_error.signed" +test_correct_no_dnssec "cdnskey.invalid" +test_correct_no_dnssec "cdnskey.invalid.param" +test_correct_no_dnssec "cdnskey.nocds" +test_correct_no_dnssec "cdnskey.nocdnskey" +test_correct_no_dnssec "cdnskey.nodnskey" +test_correct_no_dnssec "cdnskey.orphan.cds" +test_correct_no_dnssec "cdnskey.orphan.cdnskey" +test_correct_no_dnssec "cdnskey.delete.invalid.cds" +test_correct_no_dnssec "cdnskey.delete.invalid.cdnskey" +test_correct_no_dnssec "delegation.signed" + +rm $LOG diff --git a/tests/knot/test_server.c b/tests/knot/test_server.c new file mode 100644 index 0000000..bde3d10 --- /dev/null +++ b/tests/knot/test_server.c @@ -0,0 +1,72 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <signal.h> +#include <tap/basic.h> +#include "knot/server/server.h" +#include "test_conf.h" + +// Signal handler +static void interrupt_handle(int s) +{ +} + +/*! API: run tests. */ +int main(int argc, char *argv[]) +{ + plan(2); + + server_t server; + int ret = 0; + + /* Some random configuration just to apply the default conf schema */ + ret = test_conf("", NULL); + assert(ret == KNOT_EOK); + + /* Register service and signal handler */ + struct sigaction sa; + sa.sa_handler = interrupt_handle; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGALRM, &sa, NULL); // Interrupt + + /* Test server for correct initialization */ + ret = server_init(&server, 1); + is_int(KNOT_EOK, ret, "server: initialized"); + if (ret != KNOT_EOK) { + return 1; + } + + /* Test server startup */ + ret = server_start(&server, false); + is_int(KNOT_EOK, ret, "server: started ok"); + if (ret != KNOT_EOK) { + return 1; + } + + server_stop(&server); + + /* Wait for server to finish. */ + server_wait(&server); + + /* Destroy the server structure. */ + server_deinit(&server); + + /* Remove the configuration. */ + conf_free(conf()); + + return 0; +} diff --git a/tests/knot/test_server.h b/tests/knot/test_server.h new file mode 100644 index 0000000..d68561d --- /dev/null +++ b/tests/knot/test_server.h @@ -0,0 +1,100 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "test_conf.h" +#include "knot/server/server.h" +#include "knot/zone/adjust.h" +#include "contrib/mempattern.h" + +/* Some domain names. */ +#define ROOT_DNAME ((const uint8_t *)"") +#define EXAMPLE_DNAME ((const uint8_t *)"\x7""example") +#define IDSERVER_DNAME ((const uint8_t *)"\2""id""\6""server") + +/* Create fake root zone. */ +static inline void create_root_zone(server_t *server, knot_mm_t *mm) +{ + /* SOA RDATA. */ + #define SOA_RDLEN 30 + static const uint8_t SOA_RDATA[SOA_RDLEN] = { + 0x02, 'n', 's', 0x00, /* ns. */ + 0x04, 'm', 'a', 'i', 'l', 0x00,/* mail. */ + 0x77, 0xdf, 0x1e, 0x63, /* serial */ + 0x00, 0x01, 0x51, 0x80, /* refresh */ + 0x00, 0x00, 0x1c, 0x20, /* retry */ + 0x00, 0x0a, 0x8c, 0x00, /* expire */ + 0x00, 0x00, 0x0e, 0x10 /* min ttl */ + }; + + /* Insert root zone. */ + zone_t *root = zone_new(ROOT_DNAME); + root->server = server; + root->contents = zone_contents_new(root->name, true); + + knot_rrset_t *soa = knot_rrset_new(root->name, KNOT_RRTYPE_SOA, KNOT_CLASS_IN, + 7200, mm); + knot_rrset_add_rdata(soa, SOA_RDATA, SOA_RDLEN, mm); + node_add_rrset(root->contents->apex, soa, NULL); + knot_rrset_free(soa, mm); + + /* Bake the zone. */ + (void)zone_adjust_full(root->contents, 1); + + /* Switch zone db. */ + knot_zonedb_free(&server->zone_db); + server->zone_db = knot_zonedb_new(); + knot_zonedb_insert(server->zone_db, root); +} + +/* Create fake server. */ +static inline int create_fake_server(server_t *server, knot_mm_t *mm, const char *db_storage) +{ + int ret; + + /* Create test configuration. */ + /* String `db_storage' obtained from test_mkdtemp() may be up to 4096 bytes. */ + char conf_str[4096 + 512]; + (void)snprintf(conf_str, sizeof(conf_str), + "server:\n" + " identity: bogus.ns\n" + " version: 0.11\n" + " nsid: \n" + "database:\n" + " storage: %s\n" + "zone:\n" + " - domain: .\n" + " zonefile-sync: -1\n", + db_storage); + + /* Load test configuration. */ + ret = test_conf(conf_str, NULL); + if (ret != KNOT_EOK) { + return ret; + } + + /* Create name server. */ + ret = server_init(server, 1); + if (ret != KNOT_EOK) { + return ret; + } + + /* Insert root zone. */ + create_root_zone(server, mm); + + return KNOT_EOK; +} diff --git a/tests/knot/test_unreachable.c b/tests/knot/test_unreachable.c new file mode 100644 index 0000000..826544d --- /dev/null +++ b/tests/knot/test_unreachable.c @@ -0,0 +1,59 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "knot/common/unreachable.h" + +#include "contrib/sockaddr.h" + +#define UR_TEST_ADDRS 32 +struct sockaddr_storage ur_test_addrs[UR_TEST_ADDRS] = { { 0 } }; +struct sockaddr_storage ur_test_via[2] = { { 0 } }; + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + global_unreachables = knot_unreachables_init(10); + ok(global_unreachables != NULL, "unreachables: init"); + + // ur_test_via[0] left empty - AF_UNSPEC + sockaddr_set(&ur_test_via[1], AF_INET6, "::1", 0); + + for (int i = 0; i < UR_TEST_ADDRS; i++) { + struct sockaddr_storage *s = &ur_test_addrs[i]; + sockaddr_set(s, AF_INET6, "::2", i + 1); + struct sockaddr_storage *via = &ur_test_via[i % 2]; + struct sockaddr_storage *not_via = &ur_test_via[1 - i % 2]; + + ok(!knot_unreachable_is(global_unreachables, s, via), "unreachables: pre[%d]", i); + knot_unreachable_add(global_unreachables, s, via); + ok(knot_unreachable_is(global_unreachables, s, via), "unreachables: post[%d]", i); + ok(!knot_unreachable_is(global_unreachables, s, not_via), "unreachables: via[%d]", i); + + usleep(1000); + if (i >= 10) { + ok(!knot_unreachable_is(global_unreachables, &ur_test_addrs[i - 10], via), + "unreachables: expired[%d]", i - 10); + } + } + + knot_unreachables_deinit(&global_unreachables); + ok(global_unreachables == NULL, "unreachables: deinit"); + + return 0; +} diff --git a/tests/knot/test_worker_pool.c b/tests/knot/test_worker_pool.c new file mode 100644 index 0000000..59dee36 --- /dev/null +++ b/tests/knot/test_worker_pool.c @@ -0,0 +1,152 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <errno.h> +#include <pthread.h> +#include <sched.h> +#include <signal.h> +#include <time.h> + +#include "knot/worker/pool.h" +#include "knot/worker/queue.h" + +#define THREADS 4 +#define TASKS_BATCH 40 + +/*! + * Task execution log. + */ +typedef struct task_log { + pthread_mutex_t mx; + unsigned executed; +} task_log_t; + +/*! + * Get number of executed tasks and clear. + */ +static unsigned executed_reset(task_log_t *log) +{ + pthread_mutex_lock(&log->mx); + unsigned result = log->executed; + log->executed = 0; + pthread_mutex_unlock(&log->mx); + + return result; +} + +/*! + * Simple task, just increases the counter in the log. + */ +static void task_counting(worker_task_t *task) +{ + task_log_t *log = task->ctx; + + pthread_mutex_lock(&log->mx); + log->executed += 1; + pthread_mutex_unlock(&log->mx); +} + +static void interrupt_handle(int s) +{ +} + +int main(void) +{ + plan_lazy(); + + struct sigaction sa; + sa.sa_handler = interrupt_handle; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGALRM, &sa, NULL); // Interrupt + + // create pool + + worker_pool_t *pool = worker_pool_create(THREADS); + ok(pool != NULL, "create worker pool"); + if (!pool) { + return 1; + } + + task_log_t log = { + .mx = PTHREAD_MUTEX_INITIALIZER, + }; + + // schedule jobs while pool is stopped + + worker_task_t task = { .run = task_counting, .ctx = &log }; + for (int i = 0; i < TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + + sched_yield(); + ok(executed_reset(&log) == 0, "executed count before start"); + + // start and wait for finish + + worker_pool_start(pool); + worker_pool_wait(pool); + ok(executed_reset(&log) == TASKS_BATCH, "executed count after start"); + + // add additional jobs while pool is running + + for (int i = 0; i < TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + + worker_pool_wait(pool); + ok(executed_reset(&log) == TASKS_BATCH, "executed count after add"); + + // temporary suspension + + worker_pool_suspend(pool); + + for (int i = 0; i < TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + + sched_yield(); + ok(executed_reset(&log) == 0, "executed count after suspend"); + + worker_pool_resume(pool); + worker_pool_wait(pool); + ok(executed_reset(&log) == TASKS_BATCH, "executed count after resume"); + + // try clean + + pthread_mutex_lock(&log.mx); + for (int i = 0; i < THREADS + TASKS_BATCH; i++) { + worker_pool_assign(pool, &task); + } + sched_yield(); + worker_pool_clear(pool); + pthread_mutex_unlock(&log.mx); + + worker_pool_wait(pool); + ok(executed_reset(&log) <= THREADS, "executed count after clear"); + + // cleanup + + worker_pool_stop(pool); + worker_pool_join(pool); + worker_pool_destroy(pool); + + pthread_mutex_destroy(&log.mx); + + return 0; +} diff --git a/tests/knot/test_worker_queue.c b/tests/knot/test_worker_queue.c new file mode 100644 index 0000000..2d20afd --- /dev/null +++ b/tests/knot/test_worker_queue.c @@ -0,0 +1,57 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "knot/worker/queue.h" + +int main(void) +{ + plan_lazy(); + + worker_task_t task_one = { 0 }; + worker_task_t task_two = { 0 }; + worker_task_t task_three = { 0 }; + + // init + + worker_queue_t queue; + worker_queue_init(&queue); + ok(1, "queue init"); + + // enqueue + + worker_queue_enqueue(&queue, &task_one); + ok(1, "enqueue first"); + worker_queue_enqueue(&queue, &task_two); + ok(1, "enqueue second"); + + // dequeue + + ok(worker_queue_dequeue(&queue) == &task_one, "dequeue first"); + ok(worker_queue_dequeue(&queue) == &task_two, "dequeue second"); + ok(worker_queue_dequeue(&queue) == NULL, "dequeue from empty"); + + // deinit + + worker_queue_enqueue(&queue, &task_three); + ok(1, "enqueue third"); + + worker_queue_deinit(&queue); + ok(1, "queue deinit"); + + return 0; +} diff --git a/tests/knot/test_zone-tree.c b/tests/knot/test_zone-tree.c new file mode 100644 index 0000000..59207ae --- /dev/null +++ b/tests/knot/test_zone-tree.c @@ -0,0 +1,135 @@ +/* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <tap/basic.h> + +#include "libknot/errcode.h" +#include "knot/zone/zone-tree.h" + +#define NCOUNT 4 +static knot_dname_t* NAME[NCOUNT]; +static zone_node_t NODEE[NCOUNT]; +static knot_dname_t* ORDER[NCOUNT]; +static void ztree_init_data(void) +{ + NAME[0] = knot_dname_from_str_alloc("."); + NAME[1] = knot_dname_from_str_alloc("master.ac."); + NAME[2] = knot_dname_from_str_alloc("ac."); + NAME[3] = knot_dname_from_str_alloc("ns."); + + knot_dname_t *order[NCOUNT] = { + NAME[0], NAME[2], NAME[1], NAME[3] + }; + memcpy(ORDER, order, NCOUNT * sizeof(knot_dname_t*)); + + for (unsigned i = 0; i < NCOUNT; ++i) { + memset(NODEE + i, 0, sizeof(zone_node_t)); + NODEE[i].owner = NAME[i]; + NODEE[i].prev = NODEE + ((NCOUNT + i - 1) % NCOUNT); + NODEE[i].rrset_count = 1; /* required for ordered search */ + } +} + +static void ztree_free_data(void) +{ + for (unsigned i = 0; i < NCOUNT; ++i) { + knot_dname_free(NAME[i], NULL); + } +} + +static int ztree_iter_data(zone_node_t *node, void *data) +{ + unsigned *i = (unsigned *)data; + knot_dname_t *owner = node->owner; + int result = KNOT_EOK; + if (owner != ORDER[*i]) { + result = KNOT_ERROR; + char *exp_s = knot_dname_to_str_alloc(ORDER[*i]); + char *owner_s = knot_dname_to_str_alloc(owner); + diag("ztree: at index: %u expected '%s' got '%s'\n", *i, exp_s, owner_s); + free(exp_s); + free(owner_s); + } + ++(*i); + return result; +} + +static int ztree_node_counter(zone_node_t *node, void *data) +{ + (void)node; + int *counter = data; + (*counter)++; + return KNOT_EOK; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + ztree_init_data(); + + /* 1. create test */ + zone_tree_t* t = zone_tree_create(false); + ok(t != NULL, "ztree: created"); + + /* 2. insert test */ + unsigned passed = 1; + for (unsigned i = 0; i < NCOUNT; ++i) { + zone_node_t *node = NODEE + i; + if (zone_tree_insert(t, &node) != KNOT_EOK) { + passed = 0; + break; + } + } + ok(passed, "ztree: insertion"); + + /* 3. check data test */ + passed = 1; + for (unsigned i = 0; i < NCOUNT; ++i) { + zone_node_t *node = zone_tree_get(t, NAME[i]); + if (node == NULL || node != NODEE + i) { + passed = 0; + break; + } + } + ok(passed, "ztree: lookup"); + + /* 4. ordered lookup */ + zone_node_t *node = NULL; + zone_node_t *prev = NULL; + knot_dname_t *tmp_dn = knot_dname_from_str_alloc("z.ac."); + zone_tree_get_less_or_equal(t, tmp_dn, &node, &prev); + knot_dname_free(tmp_dn, NULL); + ok(prev == NODEE + 1, "ztree: ordered lookup"); + + /* 5. ordered traversal */ + unsigned i = 0; + int ret = zone_tree_apply(t, ztree_iter_data, &i); + ok (ret == KNOT_EOK, "ztree: ordered traversal"); + + /* 6. subtree apply */ + int counter = 0; + ret = zone_tree_sub_apply(t, (const knot_dname_t *)"\x02""ac", false, ztree_node_counter, &counter); + ok(ret == KNOT_EOK && counter == 2, "ztree: subtree iteration"); + counter = 0; + ret = zone_tree_sub_apply(t, (const knot_dname_t *)"\x02""ac", true, ztree_node_counter, &counter); + ok(ret == KNOT_EOK && counter == 1, "ztree: subtree iteration excluding root"); + + zone_tree_free(&t); + ztree_free_data(); + return 0; +} diff --git a/tests/knot/test_zone-update.c b/tests/knot/test_zone-update.c new file mode 100644 index 0000000..1346aaf --- /dev/null +++ b/tests/knot/test_zone-update.c @@ -0,0 +1,337 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <pthread.h> +#include <tap/basic.h> +#include <tap/files.h> +#include <unistd.h> + +#include "test_conf.h" +#include "contrib/getline.h" +#include "knot/server/server.h" +#include "knot/updates/zone-update.h" +#include "knot/zone/adjust.h" +#include "knot/zone/node.h" +#include "libzscanner/scanner.h" + +static const char *zone_str1 = "test. 600 IN SOA ns.test. m.test. 1 900 300 4800 900 \n"; +static const char *zone_str2 = "test. 600 IN TXT \"test\"\n"; +static const char *add_str = "test. 600 IN TXT \"test2\"\n"; +static const char *del_str = "test. 600 IN TXT \"test\"\n"; +static const char *node_str1 = "node.test. 601 IN TXT \"abc\"\n"; +static const char *node_str2 = "node.test. 601 IN TXT \"def\"\n"; + +knot_rrset_t rrset; + +/*!< \brief Returns true if node contains given RR in its RRSets. */ +static bool node_contains_rr(const zone_node_t *node, const knot_rrset_t *data) +{ + const knot_rdataset_t *zone_rrs = node_rdataset(node, data->type); + if (zone_rrs != NULL) { + knot_rdata_t *rr = data->rrs.rdata; + for (size_t i = 0; i < data->rrs.count; ++i) { + if (!knot_rdataset_member(zone_rrs, rr)) { + return false; + } + rr = knot_rdataset_next(rr); + } + + return true; + } else { + return false; + } +} + +static void process_rr(zs_scanner_t *scanner) +{ + knot_rrset_init(&rrset, scanner->r_owner, scanner->r_type, scanner->r_class, + scanner->r_ttl); + + int ret = knot_rrset_add_rdata(&rrset, scanner->r_data, + scanner->r_data_length, NULL); + (void)ret; + assert(ret == KNOT_EOK); +} + +static int rr_data_cmp(struct rr_data *a, struct rr_data *b) +{ + if (a->type != b->type) { + return 1; + } + if (a->ttl != b->ttl) { + return 1; + } + if (a->rrs.count != b->rrs.count) { + return 1; + } + if (a->rrs.rdata != b->rrs.rdata) { + return 1; + } + if (a->additional != b->additional) { + return 1; + } + return 0; +} + +static int test_node_unified(zone_node_t *n1, _unused_ void *v) +{ + zone_node_t *n2 = binode_node(n1, false); + if (n2 == n1) { + n2 = binode_node(n1, true); + } + ok(n1->owner == n2->owner, "binode %s has equal %s owner", n1->owner, n2->owner); + ok(n1->rrset_count == n2->rrset_count, "binode %s has equal rrset_count", n1->owner); + for (uint16_t i = 0; i < n1->rrset_count; i++) { + ok(rr_data_cmp(&n1->rrs[i], &n2->rrs[i]) == 0, "binode %s has equal rrs", n1->owner); + } + if (n1->flags & NODE_FLAGS_BINODE) { + ok((n1->flags ^ n2->flags) == NODE_FLAGS_SECOND, "binode %s has correct flags", n1->owner); + } + ok(n1->children == n2->children, "binode %s has equal children count", n1->owner); + return KNOT_EOK; +} + +static void test_zone_unified(zone_t *z) +{ + knot_sem_wait(&z->cow_lock); + zone_tree_apply(z->contents->nodes, test_node_unified, NULL); + knot_sem_post(&z->cow_lock); +} + +void test_full(zone_t *zone, zs_scanner_t *sc) +{ + zone_update_t update; + /* Init update */ + int ret = zone_update_init(&update, zone, UPDATE_FULL); + is_int(KNOT_EOK, ret, "zone update: init full"); + + if (zs_set_input_string(sc, zone_str1, strlen(zone_str1)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + + /* First addition */ + ret = zone_update_add(&update, &rrset); + knot_rdataset_clear(&rrset.rrs, NULL); + is_int(KNOT_EOK, ret, "full zone update: first addition"); + + if (zs_set_input_string(sc, zone_str2, strlen(zone_str2)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + + /* Second addition */ + ret = zone_update_add(&update, &rrset); + zone_node_t *node = (zone_node_t *) zone_update_get_node(&update, rrset.owner); + bool rrset_present = node_contains_rr(node, &rrset); + ok(ret == KNOT_EOK && rrset_present, "full zone update: second addition"); + + /* Removal */ + ret = zone_update_remove(&update, &rrset); + node = (zone_node_t *) zone_update_get_node(&update, rrset.owner); + rrset_present = node_contains_rr(node, &rrset); + ok(ret == KNOT_EOK && !rrset_present, "full zone update: removal"); + + /* Last addition */ + ret = zone_update_add(&update, &rrset); + node = (zone_node_t *) zone_update_get_node(&update, rrset.owner); + rrset_present = node_contains_rr(node, &rrset); + ok(ret == KNOT_EOK && rrset_present, "full zone update: last addition"); + + knot_rdataset_clear(&rrset.rrs, NULL); + + /* Prepare node removal */ + if (zs_set_input_string(sc, node_str1, strlen(node_str1)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + ret = zone_update_add(&update, &rrset); + assert(ret == KNOT_EOK); + knot_rdataset_clear(&rrset.rrs, NULL); + + if (zs_set_input_string(sc, node_str2, strlen(node_str2)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + ret = zone_update_add(&update, &rrset); + assert(ret == KNOT_EOK); + knot_rdataset_clear(&rrset.rrs, NULL); + knot_dname_t *rem_node_name = knot_dname_from_str_alloc("node.test"); + node = (zone_node_t *) zone_update_get_node(&update, rem_node_name); + assert(node && node_rdataset(node, KNOT_RRTYPE_TXT)->count == 2); + /* Node removal */ + ret = zone_update_remove_node(&update, rem_node_name); + node = (zone_node_t *) zone_update_get_node(&update, rem_node_name); + ok(ret == KNOT_EOK && !node, "full zone update: node removal"); + knot_dname_free(rem_node_name, NULL); + + /* Re-add a node for later incremental functionality test */ + if (zs_set_input_string(sc, node_str1, strlen(node_str1)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + ret = zone_update_add(&update, &rrset); + assert(ret == KNOT_EOK); + knot_rdataset_clear(&rrset.rrs, NULL); + + /* Commit */ + ret = zone_update_commit(conf(), &update); + node = zone_contents_find_node_for_rr(zone->contents, &rrset); + rrset_present = node_contains_rr(node, &rrset); + ok(ret == KNOT_EOK && rrset_present, "full zone update: commit (max TTL: %u)", zone->contents->max_ttl); + + test_zone_unified(zone); + + knot_rdataset_clear(&rrset.rrs, NULL); +} + +void test_incremental(zone_t *zone, zs_scanner_t *sc) +{ + int ret = KNOT_EOK; + + /* Init update */ + zone_update_t update; + zone_update_init(&update, zone, UPDATE_INCREMENTAL); + ok(update.zone == zone && changeset_empty(&update.change), + "incremental zone update: init"); + + if (zs_set_input_string(sc, add_str, strlen(add_str)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + + /* Addition */ + ret = zone_update_add(&update, &rrset); + knot_rdataset_clear(&rrset.rrs, NULL); + is_int(KNOT_EOK, ret, "incremental zone update: addition"); + + const zone_node_t *synth_node = update.new_cont->apex; + ok(synth_node && node_rdataset(synth_node, KNOT_RRTYPE_TXT)->count == 2, + "incremental zone update: add change"); + + if (zs_set_input_string(sc, del_str, strlen(del_str)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + /* Removal */ + ret = zone_update_remove(&update, &rrset); + is_int(KNOT_EOK, ret, "incremental zone update: removal"); + knot_rdataset_clear(&rrset.rrs, NULL); + + ok(node_rdataset(synth_node, KNOT_RRTYPE_TXT)->count == 1, + "incremental zone update: del change"); + + /* Prepare node removal */ + if (zs_set_input_string(sc, node_str2, strlen(node_str2)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + ret = zone_update_add(&update, &rrset); + assert(ret == KNOT_EOK); + knot_rdataset_clear(&rrset.rrs, NULL); + + knot_dname_t *rem_node_name = knot_dname_from_str_alloc("node.test"); + synth_node = zone_update_get_node(&update, rem_node_name); + assert(synth_node && node_rdataset(synth_node, KNOT_RRTYPE_TXT)->count == 2); + /* Node Removal */ + ret = zone_update_remove_node(&update, rem_node_name); + synth_node = zone_update_get_node(&update, rem_node_name); + ok(ret == KNOT_EOK && !synth_node, + "incremental zone update: node removal"); + knot_dname_free(rem_node_name, NULL); + + /* Re-add a node for later incremental functionality test */ + if (zs_set_input_string(sc, node_str1, strlen(node_str1)) != 0 || + zs_parse_all(sc) != 0) { + assert(0); + } + ret = zone_update_add(&update, &rrset); + assert(ret == KNOT_EOK); + knot_rdataset_clear(&rrset.rrs, NULL); + + /* Commit */ + ret = zone_update_commit(conf(), &update); + const zone_node_t *iter_node = zone_contents_find_node_for_rr(zone->contents, &rrset); + bool rrset_present = node_contains_rr(iter_node, &rrset); + ok(ret == KNOT_EOK && rrset_present, "incremental zone update: commit"); + + test_zone_unified(zone); + + knot_rdataset_clear(&rrset.rrs, NULL); + + size_t zone_size1 = zone->contents->size; + uint32_t zone_max_ttl1 = zone->contents->max_ttl; + ret = zone_adjust_full(zone->contents, 2); + ok(ret == KNOT_EOK, "zone adjust full shall work"); + size_t zone_size2 = zone->contents->size; + uint32_t zone_max_ttl2 = zone->contents->max_ttl; + ok(zone_size1 == zone_size2, "zone size measured the same incremental vs full (%zu, %zu)", zone_size1, zone_size2); + ok(zone_max_ttl1 == zone_max_ttl2, "zone max TTL measured the same incremental vs full (%u, %u)", zone_max_ttl1, zone_max_ttl2); + // TODO test more things after re-adjust, search for non-unified bi-nodes +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + char *temp_dir = test_mkdtemp(); + ok(temp_dir != NULL, "make temporary directory"); + + char conf_str[512]; + snprintf(conf_str, sizeof(conf_str), + "zone:\n" + " - domain: test.\n" + "database:\n" + " journal-db-max-size: 100M\n" + " storage: %s\n", + temp_dir); + + /* Load test configuration. */ + int ret = test_conf(conf_str, NULL); + is_int(KNOT_EOK, ret, "load configuration"); + + server_t server; + ret = server_init(&server, 1); + is_int(KNOT_EOK, ret, "server init"); + + /* Set up empty zone */ + knot_dname_t *apex = knot_dname_from_str_alloc("test"); + assert(apex); + zone_t *zone = zone_new(apex); + zone->server = &server; + + /* Setup zscanner */ + zs_scanner_t sc; + if (zs_init(&sc, "test.", KNOT_CLASS_IN, 3600) != 0 || + zs_set_processing(&sc, process_rr, NULL, NULL) != 0) { + assert(0); + } + + /* Test FULL update, commit it and use the result to test the INCREMENTAL update */ + test_full(zone, &sc); + test_incremental(zone, &sc); + + zs_deinit(&sc); + zone_free(&zone); + server_deinit(&server); + knot_dname_free(apex, NULL); + conf_free(conf()); + test_rm_rf(temp_dir); + free(temp_dir); + + return 0; +} diff --git a/tests/knot/test_zone_events.c b/tests/knot/test_zone_events.c new file mode 100644 index 0000000..9c95558 --- /dev/null +++ b/tests/knot/test_zone_events.c @@ -0,0 +1,99 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "knot/common/evsched.h" +#include "knot/worker/pool.h" +#include "knot/events/events.h" +#include "knot/zone/zone.h" + +static void test_scheduling(zone_t *zone) +{ + const time_t now = time(NULL); + const unsigned offset = 1000; + + time_t timestamp = 0; + zone_event_type_t event = 0; + + timestamp = zone_events_get_next(zone, &event); + ok(timestamp < 0 && event == ZONE_EVENT_INVALID, "nothing planned"); + + // scheduling + + zone_events_schedule_at(zone, ZONE_EVENT_EXPIRE, now + offset); + zone_events_schedule_at(zone, ZONE_EVENT_FLUSH, now + (offset / 2)); + + for (int i = 0; i < ZONE_EVENT_COUNT; i++) { + time_t t = zone_events_get_time(zone, i); + bool scheduled = i == ZONE_EVENT_EXPIRE || i == ZONE_EVENT_FLUSH; + const char *name = zone_events_get_name(i); + + ok((t > 0) == scheduled && name, "event %s (%s)", name, + scheduled ? "scheduled" : "not scheduled"); + } + + // queuing + + timestamp = zone_events_get_next(zone, &event); + ok(timestamp >= now + (offset / 2) && event == ZONE_EVENT_FLUSH, "flush is next"); + + zone_events_schedule_at(zone, ZONE_EVENT_FLUSH, (time_t)0); + + timestamp = zone_events_get_next(zone, &event); + ok(timestamp >= now + offset && event == ZONE_EVENT_EXPIRE, "expire is next"); + + zone_events_schedule_at(zone, ZONE_EVENT_EXPIRE, (time_t)0); + + timestamp = zone_events_get_next(zone, &event); + ok(timestamp < 0 && event == ZONE_EVENT_INVALID, "nothing planned"); + + // zone_events_enqueue + + // zone_events_freeze + // zone_events_start +} + +int main(void) +{ + plan_lazy(); + + int r; + + evsched_t sched = { 0 }; + worker_pool_t *pool = NULL; + zone_t zone = { 0 }; + + r = evsched_init(&sched, NULL); + ok(r == KNOT_EOK, "create scheduler"); + + pool = worker_pool_create(1); + ok(pool != NULL, "create worker pool"); + + r = zone_events_init(&zone); + ok(r == KNOT_EOK, "zone events init"); + + r = zone_events_setup(&zone, pool, &sched); + ok(r == KNOT_EOK, "zone events setup"); + + test_scheduling(&zone); + + zone_events_deinit(&zone); + worker_pool_destroy(pool); + evsched_deinit(&sched); + + return 0; +} diff --git a/tests/knot/test_zone_serial.c b/tests/knot/test_zone_serial.c new file mode 100644 index 0000000..5728e97 --- /dev/null +++ b/tests/knot/test_zone_serial.c @@ -0,0 +1,214 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <stdlib.h> +#include <time.h> + +#include "knot/zone/serial.h" +#include "knot/conf/schema.h" +#include "contrib/strtonum.h" + +enum serials { + S_LOWEST = 0, // lowest value + S_2LOWEST = 1, // second lowest value + S_BELOW_MIDDLE = 0x7fffffff, // one below middle + S_ABOVE_MIDDLE = 0x80000000, // one above middle + S_2HIGHEST = 0xffffffff - 1, // second highest value + S_HIGHEST = 0xffffffff // highest value +}; + +static uint32_t random_serial(void) +{ + uint32_t s = rand() & 0xff; + s |= (rand() & 0xff) << 8; + s |= (rand() & 0xff) << 16; + s |= (rand() & 0xff) << 24; + + return s; +} + +static void check_unixtime(uint32_t current, uint32_t increment, uint32_t expected, const char *msg) +{ + uint32_t next = serial_next_generic(current, SERIAL_POLICY_UNIXTIME, increment, 0, 1); + ok(next == expected, "unixtime: %s", msg); +} + +/* Test will wrongly fail if the next second starts while running; + * this is unlikely, so not taking any action */ +static void test_unixtime(void) +{ + time_t serial0 = time(NULL); + + check_unixtime(1000000000, 1, serial0, "from old second or policy"); + check_unixtime(serial0, 0, serial0, "reuse current second"); + check_unixtime(serial0, 1, serial0 + 1, "this second's first increment"); + check_unixtime(serial0 + 1, 1, serial0 + 2, "this second's second increment"); + check_unixtime(3000000000, 1, 3000000001, "from future second"); + check_unixtime(3000000000, 0, 3000000000, "at future second"); +} + +static void check_dateserial(uint32_t current, uint32_t increment, uint32_t expected, const char *msg) +{ + uint32_t next = serial_next_generic(current, SERIAL_POLICY_DATESERIAL, increment, 0, 1); + ok(next == expected, "dateserial: %s", msg); +} + +/* Test will wrongly fail if the next day starts while running; + * this is EXTREMELY unlikely, so definitely not taking any action */ +static void test_dateserial(void) +{ + time_t now = time(NULL); + + struct tm *gm_ret = gmtime(&now); + + char str[32]; + int ret1 = strftime(str, sizeof(str), "%Y%m%d00", gm_ret); + + uint32_t serial0 = 0; + int ret2 = str_to_u32(str, &serial0); + + ok(gm_ret != NULL && ret1 > 0 && ret2 == KNOT_EOK, + "dateserial: prepare current value"); + + check_dateserial(2000010100, 1, serial0, "from old date or policy"); + check_dateserial(serial0, 1, serial0 + 1, "today's first increment"); + check_dateserial(serial0 + 98, 1, serial0 + 99, "today's last increment"); + check_dateserial(serial0 + 99, 1, serial0 + 100, "wrap from today"); + check_dateserial(2100010100, 1, 2100010101, "from future date"); + check_dateserial(2100010100, 0, 2100010100, "at future date"); +} + +static void check_modulo(uint32_t current, uint32_t expected, uint8_t rem, uint8_t mod) +{ + uint32_t next = serial_next_generic(current, SERIAL_POLICY_INCREMENT, 1, rem, mod); + ok(next == expected, "modulo: %u->%u %u/%u", current, expected, rem, mod); +} + +static void test_modulo(void) +{ + // mod 1 + + check_modulo(0, 1, 0, 1); + check_modulo(1, 2, 0, 1); + check_modulo(2, 3, 0, 1); + check_modulo(3, 4, 0, 1); + check_modulo(S_2HIGHEST, S_HIGHEST, 0, 1); + check_modulo(S_HIGHEST, S_LOWEST, 0, 1); + + // mod 2 + + check_modulo(0, 2, 0, 2); + check_modulo(1, 2, 0, 2); + check_modulo(2, 4, 0, 2); + check_modulo(3, 4, 0, 2); + check_modulo(4, 6, 0, 2); + check_modulo(S_2HIGHEST, S_LOWEST, 0, 2); + + check_modulo(0, 1, 1, 2); + check_modulo(1, 3, 1, 2); + check_modulo(2, 3, 1, 2); + check_modulo(3, 5, 1, 2); + check_modulo(4, 5, 1, 2); + check_modulo(S_2HIGHEST, S_HIGHEST, 1, 2); + + // mod 3 + + check_modulo(0, 3, 0, 3); + check_modulo(1, 3, 0, 3); + check_modulo(2, 3, 0, 3); + check_modulo(3, 6, 0, 3); + check_modulo(4, 6, 0, 3); + + check_modulo(0, 1, 1, 3); + check_modulo(1, 4, 1, 3); + check_modulo(2, 4, 1, 3); + check_modulo(3, 4, 1, 3); + check_modulo(4, 7, 1, 3); + + check_modulo(0, 2, 2, 3); + check_modulo(1, 2, 2, 3); + check_modulo(2, 5, 2, 3); + check_modulo(3, 5, 2, 3); + check_modulo(4, 5, 2, 3); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Serial compare test. */ + ok(serial_compare(S_LOWEST, S_BELOW_MIDDLE) == SERIAL_LOWER, + "serial compare: lowest < below middle"); + ok(serial_compare(S_BELOW_MIDDLE, S_LOWEST) == SERIAL_GREATER, + "serial compare: below middle > lowest"); + + /* Corner-case: these serials' distance is exactly 2^31. */ + ok(serial_compare(S_LOWEST, S_ABOVE_MIDDLE) == SERIAL_INCOMPARABLE, + "serial compare: lowest < above_middle"); + ok(serial_compare(S_ABOVE_MIDDLE, S_LOWEST) == SERIAL_INCOMPARABLE, + "serial compare: above_middle < lowest"); + + ok(serial_compare(S_LOWEST, S_HIGHEST) == SERIAL_GREATER, + "serial compare: lowest > highest"); + ok(serial_compare(S_HIGHEST, S_LOWEST) == SERIAL_LOWER, + "serial compare: highest < lowest"); + + ok(serial_compare(S_2LOWEST, S_ABOVE_MIDDLE) == SERIAL_LOWER, + "serial compare: 2nd lowest < above middle"); + ok(serial_compare(S_ABOVE_MIDDLE, S_2LOWEST) == SERIAL_GREATER, + "serial compare: above middle > 2nd lowest"); + + /* Corner-case: these serials' distance is exactly 2^31. */ + ok(serial_compare(S_BELOW_MIDDLE, S_HIGHEST) == SERIAL_INCOMPARABLE, + "serial compare: below middle < highest"); + ok(serial_compare(S_HIGHEST, S_BELOW_MIDDLE) == SERIAL_INCOMPARABLE, + "serial compare: highest < below middle"); + + ok(serial_compare(S_BELOW_MIDDLE, S_2HIGHEST) == SERIAL_LOWER, + "serial compare: below middle < 2nd highest"); + ok(serial_compare(S_2HIGHEST, S_BELOW_MIDDLE) == SERIAL_GREATER, + "serial compare: 2nd highest > below middle"); + + ok(serial_compare(S_ABOVE_MIDDLE, S_HIGHEST) == SERIAL_LOWER, + "serial compare: above middle < highest"); + ok(serial_compare(S_HIGHEST, S_ABOVE_MIDDLE) == SERIAL_GREATER, + "serial compare: highest > above middle"); + + ok(serial_compare(S_LOWEST, S_LOWEST) == SERIAL_EQUAL, + "serial compare: lowest == lowest"); + ok(serial_compare(S_HIGHEST, S_HIGHEST) == SERIAL_EQUAL, + "serial compare: highest == highest"); + + ok(serial_compare(S_LOWEST - 1, S_HIGHEST) == SERIAL_EQUAL, + "serial compare: lowest - 1 == highest"); + ok(serial_compare(S_LOWEST, S_HIGHEST + 1) == SERIAL_EQUAL, + "serial compare: lowest== highest + 1"); + + /* Corner-case: these serials' distance is exactly 2^31. */ + uint32_t s1 = random_serial(); + uint32_t s2 = s1 + S_ABOVE_MIDDLE; // exactly the 'opposite' number + ok(serial_compare(s1, s2) == SERIAL_INCOMPARABLE, + "serial compare: random opposites (s1 < s2)"); + ok(serial_compare(s2, s1) == SERIAL_INCOMPARABLE, + "serial compare: random opposites (s2 < s1)"); + + test_dateserial(); + test_unixtime(); + test_modulo(); + + return 0; +} diff --git a/tests/knot/test_zone_timers.c b/tests/knot/test_zone_timers.c new file mode 100644 index 0000000..da1fe99 --- /dev/null +++ b/tests/knot/test_zone_timers.c @@ -0,0 +1,117 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> +#include <tap/files.h> + +#include "knot/zone/timers.h" +#include "libknot/db/db_lmdb.h" +#include "libknot/dname.h" +#include "libknot/error.h" + +static const zone_timers_t MOCK_TIMERS = { + .last_flush = 1474559960, + .next_refresh = 1474559961, + .last_refresh_ok = true, + .last_notified_serial = 123456, + .next_ds_check = 1474559962, + .next_ds_push = 1474559963, + .catalog_member = 1474559964, + .next_expire = 1474559965, + .last_master = { .sin6_family = AF_INET, .sin6_port = 53 }, + .master_pin_hit = 1474559966, +}; + +static bool timers_eq(const zone_timers_t *val, const zone_timers_t *ref) +{ + return val->last_flush == ref->last_flush && + val->next_refresh == ref->next_refresh && + val->last_refresh_ok == ref->last_refresh_ok && + val->last_notified_serial == ref->last_notified_serial && + val->next_ds_check == ref->next_ds_check && + val->next_ds_push == ref->next_ds_push && + val->catalog_member == ref->catalog_member && + val->next_expire == ref->next_expire && + sockaddr_cmp((struct sockaddr_storage *)&val->last_master, + (struct sockaddr_storage *)&ref->last_master, false) == 0 && + val->master_pin_hit == ref->master_pin_hit; +} + +static bool keep_all(const knot_dname_t *zone, void *data) +{ + return true; +} + +static bool remove_all(const knot_dname_t *zone, void *data) +{ + return false; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + assert(knot_db_lmdb_api()); + + char *dbid = test_mkdtemp(); + if (!dbid) { + return EXIT_FAILURE; + } + + const knot_dname_t *zone = (uint8_t *)"\x7""example""\x3""com"; + struct zone_timers timers = MOCK_TIMERS; + + // Create database + knot_lmdb_db_t _db = { 0 }, *db = &_db; + knot_lmdb_init(db, dbid, 1024 * 1024, 0, NULL); + int ret = knot_lmdb_open(db); + ok(ret == KNOT_EOK && db != NULL, "open timers"); + + // Lookup nonexistent + ret = zone_timers_read(db, zone, &timers); + is_int(KNOT_ENOENT, ret, "zone_timer_read() nonexistent"); + + // Write timers + ret = zone_timers_write(db, zone, &timers); + is_int(KNOT_EOK, ret, "zone_timers_write()"); + + // Read timers + memset(&timers, 0, sizeof(timers)); + ret = zone_timers_read(db, zone, &timers); + ok(ret == KNOT_EOK, "zone_timers_read()"); + ok(timers_eq(&timers, &MOCK_TIMERS), "inconsistent timers"); + + // Sweep none + ret = zone_timers_sweep(db, keep_all, NULL); + is_int(KNOT_EOK, ret, "zone_timers_sweep() none"); + ret = zone_timers_read(db, zone, &timers); + is_int(KNOT_EOK, ret, "zone_timers_read()"); + + // Sweep all + ret = zone_timers_sweep(db, remove_all, NULL); + is_int(KNOT_EOK, ret, "zone_timers_sweep() all"); + ret = zone_timers_read(db, zone, &timers); + is_int(KNOT_ENOENT, ret, "zone_timers_read() nonexistent"); + + // Clean up. + knot_lmdb_deinit(db); + test_rm_rf(dbid); + free(dbid); + + return EXIT_SUCCESS; +} diff --git a/tests/knot/test_zonedb.c b/tests/knot/test_zonedb.c new file mode 100644 index 0000000..3ef7632 --- /dev/null +++ b/tests/knot/test_zonedb.c @@ -0,0 +1,115 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "knot/zone/zone.h" +#include "knot/zone/zonedb.h" +#include "contrib/openbsd/strlcat.h" +#include "contrib/openbsd/strlcpy.h" + +#define ZONE_COUNT 10 +static const char *zone_list[ZONE_COUNT] = { + ".", + "com", + "net", + "c.com", + "a.com", + "a.net", + "b.net", + "c.a.com", + "b.b.b.com", + "b.b.b.b.net", +}; + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Create database. */ + knot_dname_txt_storage_t buf; + const char *prefix = "zzz."; + size_t nr_passed = 0; + knot_dname_t *dname = NULL; + zone_t *zones[ZONE_COUNT] = {0}; + knot_zonedb_t *db = knot_zonedb_new(); + ok(db != NULL, "zonedb: new"); + + /* Populate. */ + for (unsigned i = 0; i < ZONE_COUNT; ++i) { + knot_dname_t *zone_name = knot_dname_from_str_alloc(zone_list[i]); + zones[i] = zone_new(zone_name); + knot_dname_free(zone_name, NULL); + + if (zones[i] == NULL) { + goto cleanup; + } + if (knot_zonedb_insert(db, zones[i]) == KNOT_EOK) { + ++nr_passed; + } else { + diag("knot_zonedb_add_zone(%s) failed", zone_list[i]); + } + } + ok(nr_passed == ZONE_COUNT, "zonedb: add zones"); + + /* Lookup of exact names. */ + nr_passed = 0; + for (unsigned i = 0; i < ZONE_COUNT; ++i) { + dname = knot_dname_from_str_alloc(zone_list[i]); + if (knot_zonedb_find(db, dname) == zones[i]) { + ++nr_passed; + } else { + diag("knot_zonedb_find(%s) failed", zone_list[i]); + } + knot_dname_free(dname, NULL); + } + ok(nr_passed == ZONE_COUNT, "zonedb: find exact zones"); + + /* Lookup of sub-names. */ + nr_passed = 0; + for (unsigned i = 0; i < ZONE_COUNT; ++i) { + strlcpy(buf, prefix, sizeof(buf)); + if (strcmp(zone_list[i], ".") != 0) { + strlcat(buf, zone_list[i], sizeof(buf)); + } + dname = knot_dname_from_str_alloc(buf); + if (knot_zonedb_find_suffix(db, dname) == zones[i]) { + ++nr_passed; + } else { + diag("knot_zonedb_find_suffix(%s) failed", buf); + } + knot_dname_free(dname, NULL); + } + ok(nr_passed == ZONE_COUNT, "zonedb: find zones for subnames"); + + /* Remove all zones. */ + nr_passed = 0; + for (unsigned i = 0; i < ZONE_COUNT; ++i) { + dname = knot_dname_from_str_alloc(zone_list[i]); + if (knot_zonedb_del(db, dname) == KNOT_EOK) { + zone_free(&zones[i]); + ++nr_passed; + } else { + diag("knot_zonedb_remove_zone(%s) failed", zone_list[i]); + } + knot_dname_free(dname, NULL); + } + ok(nr_passed == ZONE_COUNT, "zonedb: removed all zones"); + +cleanup: + knot_zonedb_deep_free(&db, false); + return 0; +} diff --git a/tests/libdnssec/sample_keys.h b/tests/libdnssec/sample_keys.h new file mode 100644 index 0000000..cd9f18f --- /dev/null +++ b/tests/libdnssec/sample_keys.h @@ -0,0 +1,498 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <binary.h> + +typedef struct key_parameters { + // DNSSEC fields + uint8_t *name; + uint16_t flags; + uint8_t protocol; + uint8_t algorithm; + dnssec_binary_t public_key; + + // DNSSEC wire format + dnssec_binary_t rdata; + + // Hashes + const char *key_id; + uint16_t keytag; + dnssec_binary_t ds_sha1; + dnssec_binary_t ds_sha256; + dnssec_binary_t ds_sha384; + + // Key information + unsigned bit_size; + + // Private key in PEM + dnssec_binary_t pem; +} key_parameters_t; + +/* + +RSA-SHA-256 + +rsa. IN DNSKEY 256 3 8 AwEAAaqwL+O6GcCPkRZjoObfIJHcHPwQQY9mnAg6kROea2gsyRJOAwBNQPCfXoPtmrU0BiZ0aGBVTVPAvZh+HJRu9NEfTNDPK2HSyHdSucjY1qs6WAub6oWHJuLBxMesftpnUwoLnVZyN+pOblUZUMsvxP3PlS+mA+E6NyQX0F/fcfGL +rsa. IN DS 37335 8 1 2ABEFAAB07A900F8CB5B266FC930EEBEF51766F6 +rsa. IN DS 37335 8 2 30226484F230814C08C6DD9E2DF6E7A3DB860C2552A418CBF70D0FEE94DFA15F +rsa. IN DS 37335 8 4 978E0F7766096E131E3E90C50B63DBD825E7428E864BC5A3D32F3135A3786F0CDC6A070B6B8D760190F0F572B03CA4C0 + +Modulus: qrAv47oZwI+RFmOg5t8gkdwc/BBBj2acCDqRE55raCzJEk4DAE1A8J9eg+2atTQGJnRoYFVNU8C9mH4clG700R9M0M8rYdLId1K5yNjWqzpYC5vqhYcm4sHEx6x+2mdTCgudVnI36k5uVRlQyy/E/c+VL6YD4To3JBfQX99x8Ys= +PublicExponent: AQAB +PrivateExponent: NGDSoVBHfMbRoAw8oPxRk1D3eAZJCAdV1FSclmej0BkGLt7PnvUV+4D8UQHF2ts3E+/e48jpbM0VoUj53jbaWx1ULVmQ1cpJY0XLsRUmaQdOwEnSgXjtQy2htlth8RinB+LnVG8eUS9jWnEEikfvCLH0ptkOa/u6GKFUMj+Q95k= +Prime1: 4ZZj/YD5xvjxEuE0uR0KedsZeGT6iHqwtmJuLNuhFaeXIw5vXXZmg88U/lIo2t0DESYTbfXglw0eu62MwWb+5w== +Prime2: wbMU0wM6MYaDs4FfEeuTXT14P3cXZOFGikJPWiIUGoMGvDgYzxdiFoHzGdLkapsPizTqBKMtYQ9CYQa8g1cXvQ== +Exponent1: ywKuZVqGbdtmB9mHuvc5kEPuffxRwjS3hsq538CfDH/PcYryCagdxYy8lcqWXa/7rJkZbyGQxh7Wg4tBWmM4DQ== +Exponent2: L8MYv29sSgoBL6IW7zRHghZGMGANRLLH0g/HwVHl4yOr5X1voKEDbslcSGHYMPFLQ+goTDxwVB6PH52pnjk7gQ== +Coefficient: USHiV/UQkTz3BlxZc1IAiUQv9/Ba8wtHWSVp+YqPhxt1sfdiyUMXtlA4f6WAKAGMraoRw4wIcYr+N6Wx+wwXZw== + +-----BEGIN PRIVATE KEY----- +MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKqwL+O6GcCPkRZj +oObfIJHcHPwQQY9mnAg6kROea2gsyRJOAwBNQPCfXoPtmrU0BiZ0aGBVTVPAvZh+ +HJRu9NEfTNDPK2HSyHdSucjY1qs6WAub6oWHJuLBxMesftpnUwoLnVZyN+pOblUZ +UMsvxP3PlS+mA+E6NyQX0F/fcfGLAgMBAAECgYA0YNKhUEd8xtGgDDyg/FGTUPd4 +BkkIB1XUVJyWZ6PQGQYu3s+e9RX7gPxRAcXa2zcT797jyOlszRWhSPneNtpbHVQt +WZDVykljRcuxFSZpB07ASdKBeO1DLaG2W2HxGKcH4udUbx5RL2NacQSKR+8IsfSm +2Q5r+7oYoVQyP5D3mQJBAOGWY/2A+cb48RLhNLkdCnnbGXhk+oh6sLZibizboRWn +lyMOb112ZoPPFP5SKNrdAxEmE2314JcNHrutjMFm/ucCQQDBsxTTAzoxhoOzgV8R +65NdPXg/dxdk4UaKQk9aIhQagwa8OBjPF2IWgfMZ0uRqmw+LNOoEoy1hD0JhBryD +Vxe9AkEAywKuZVqGbdtmB9mHuvc5kEPuffxRwjS3hsq538CfDH/PcYryCagdxYy8 +lcqWXa/7rJkZbyGQxh7Wg4tBWmM4DQJAL8MYv29sSgoBL6IW7zRHghZGMGANRLLH +0g/HwVHl4yOr5X1voKEDbslcSGHYMPFLQ+goTDxwVB6PH52pnjk7gQJAUSHiV/UQ +kTz3BlxZc1IAiUQv9/Ba8wtHWSVp+YqPhxt1sfdiyUMXtlA4f6WAKAGMraoRw4wI +cYr+N6Wx+wwXZw== +-----END PRIVATE KEY----- + +*/ + +static const key_parameters_t SAMPLE_RSA_KEY = { + .name = (uint8_t *)"\x03""rsa", + .flags = 256, + .protocol = 3, + .algorithm = 8, + .public_key = { .size = 132, .data = (uint8_t []) { + 0x03, 0x01, 0x00, 0x01, 0xaa, 0xb0, 0x2f, 0xe3, 0xba, 0x19, + 0xc0, 0x8f, 0x91, 0x16, 0x63, 0xa0, 0xe6, 0xdf, 0x20, 0x91, + 0xdc, 0x1c, 0xfc, 0x10, 0x41, 0x8f, 0x66, 0x9c, 0x08, 0x3a, + 0x91, 0x13, 0x9e, 0x6b, 0x68, 0x2c, 0xc9, 0x12, 0x4e, 0x03, + 0x00, 0x4d, 0x40, 0xf0, 0x9f, 0x5e, 0x83, 0xed, 0x9a, 0xb5, + 0x34, 0x06, 0x26, 0x74, 0x68, 0x60, 0x55, 0x4d, 0x53, 0xc0, + 0xbd, 0x98, 0x7e, 0x1c, 0x94, 0x6e, 0xf4, 0xd1, 0x1f, 0x4c, + 0xd0, 0xcf, 0x2b, 0x61, 0xd2, 0xc8, 0x77, 0x52, 0xb9, 0xc8, + 0xd8, 0xd6, 0xab, 0x3a, 0x58, 0x0b, 0x9b, 0xea, 0x85, 0x87, + 0x26, 0xe2, 0xc1, 0xc4, 0xc7, 0xac, 0x7e, 0xda, 0x67, 0x53, + 0x0a, 0x0b, 0x9d, 0x56, 0x72, 0x37, 0xea, 0x4e, 0x6e, 0x55, + 0x19, 0x50, 0xcb, 0x2f, 0xc4, 0xfd, 0xcf, 0x95, 0x2f, 0xa6, + 0x03, 0xe1, 0x3a, 0x37, 0x24, 0x17, 0xd0, 0x5f, 0xdf, 0x71, + 0xf1, 0x8b, + }}, + .rdata = { .size = 136, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x08, + 0x03, 0x01, 0x00, 0x01, 0xaa, 0xb0, 0x2f, 0xe3, 0xba, 0x19, + 0xc0, 0x8f, 0x91, 0x16, 0x63, 0xa0, 0xe6, 0xdf, 0x20, 0x91, + 0xdc, 0x1c, 0xfc, 0x10, 0x41, 0x8f, 0x66, 0x9c, 0x08, 0x3a, + 0x91, 0x13, 0x9e, 0x6b, 0x68, 0x2c, 0xc9, 0x12, 0x4e, 0x03, + 0x00, 0x4d, 0x40, 0xf0, 0x9f, 0x5e, 0x83, 0xed, 0x9a, 0xb5, + 0x34, 0x06, 0x26, 0x74, 0x68, 0x60, 0x55, 0x4d, 0x53, 0xc0, + 0xbd, 0x98, 0x7e, 0x1c, 0x94, 0x6e, 0xf4, 0xd1, 0x1f, 0x4c, + 0xd0, 0xcf, 0x2b, 0x61, 0xd2, 0xc8, 0x77, 0x52, 0xb9, 0xc8, + 0xd8, 0xd6, 0xab, 0x3a, 0x58, 0x0b, 0x9b, 0xea, 0x85, 0x87, + 0x26, 0xe2, 0xc1, 0xc4, 0xc7, 0xac, 0x7e, 0xda, 0x67, 0x53, + 0x0a, 0x0b, 0x9d, 0x56, 0x72, 0x37, 0xea, 0x4e, 0x6e, 0x55, + 0x19, 0x50, 0xcb, 0x2f, 0xc4, 0xfd, 0xcf, 0x95, 0x2f, 0xa6, + 0x03, 0xe1, 0x3a, 0x37, 0x24, 0x17, 0xd0, 0x5f, 0xdf, 0x71, + 0xf1, 0x8b, + }}, + .key_id = "76f0d6c093d8328bc7f0e25bd8cde5575bad9b44", + .keytag = 37335, + .ds_sha1 = { .size = 24, .data = (uint8_t []) { + 0x91, 0xd7, 0x08, 0x01, + 0x2a, 0xbe, 0xfa, 0xab, 0x07, 0xa9, 0x00, 0xf8, 0xcb, 0x5b, + 0x26, 0x6f, 0xc9, 0x30, 0xee, 0xbe, 0xf5, 0x17, 0x66, 0xf6, + }}, + .ds_sha256 = { .size = 36, .data = (uint8_t []) { + 0x91, 0xd7, 0x08, 0x02, + 0x30, 0x22, 0x64, 0x84, 0xf2, 0x30, 0x81, 0x4c, 0x08, 0xc6, + 0xdd, 0x9e, 0x2d, 0xf6, 0xe7, 0xa3, 0xdb, 0x86, 0x0c, 0x25, + 0x52, 0xa4, 0x18, 0xcb, 0xf7, 0x0d, 0x0f, 0xee, 0x94, 0xdf, + 0xa1, 0x5f, + }}, + .ds_sha384 = { .size = 52, .data = (uint8_t []) { + 0x91, 0xd7, 0x08, 0x04, + 0x97, 0x8e, 0x0f, 0x77, 0x66, 0x09, 0x6e, 0x13, 0x1e, 0x3e, + 0x90, 0xc5, 0x0b, 0x63, 0xdb, 0xd8, 0x25, 0xe7, 0x42, 0x8e, + 0x86, 0x4b, 0xc5, 0xa3, 0xd3, 0x2f, 0x31, 0x35, 0xa3, 0x78, + 0x6f, 0x0c, 0xdc, 0x6a, 0x07, 0x0b, 0x6b, 0x8d, 0x76, 0x01, + 0x90, 0xf0, 0xf5, 0x72, 0xb0, 0x3c, 0xa4, 0xc0, + }}, + .bit_size = 1024, + .pem = { .size = 916, .data = (uint8_t []) { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, + 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, + 0x49, 0x43, 0x64, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4e, + 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, + 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43, + 0x41, 0x6d, 0x41, 0x77, 0x67, 0x67, 0x4a, 0x63, 0x41, 0x67, + 0x45, 0x41, 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4b, 0x71, 0x77, + 0x4c, 0x2b, 0x4f, 0x36, 0x47, 0x63, 0x43, 0x50, 0x6b, 0x52, + 0x5a, 0x6a, 0x0a, 0x6f, 0x4f, 0x62, 0x66, 0x49, 0x4a, 0x48, + 0x63, 0x48, 0x50, 0x77, 0x51, 0x51, 0x59, 0x39, 0x6d, 0x6e, + 0x41, 0x67, 0x36, 0x6b, 0x52, 0x4f, 0x65, 0x61, 0x32, 0x67, + 0x73, 0x79, 0x52, 0x4a, 0x4f, 0x41, 0x77, 0x42, 0x4e, 0x51, + 0x50, 0x43, 0x66, 0x58, 0x6f, 0x50, 0x74, 0x6d, 0x72, 0x55, + 0x30, 0x42, 0x69, 0x5a, 0x30, 0x61, 0x47, 0x42, 0x56, 0x54, + 0x56, 0x50, 0x41, 0x76, 0x5a, 0x68, 0x2b, 0x0a, 0x48, 0x4a, + 0x52, 0x75, 0x39, 0x4e, 0x45, 0x66, 0x54, 0x4e, 0x44, 0x50, + 0x4b, 0x32, 0x48, 0x53, 0x79, 0x48, 0x64, 0x53, 0x75, 0x63, + 0x6a, 0x59, 0x31, 0x71, 0x73, 0x36, 0x57, 0x41, 0x75, 0x62, + 0x36, 0x6f, 0x57, 0x48, 0x4a, 0x75, 0x4c, 0x42, 0x78, 0x4d, + 0x65, 0x73, 0x66, 0x74, 0x70, 0x6e, 0x55, 0x77, 0x6f, 0x4c, + 0x6e, 0x56, 0x5a, 0x79, 0x4e, 0x2b, 0x70, 0x4f, 0x62, 0x6c, + 0x55, 0x5a, 0x0a, 0x55, 0x4d, 0x73, 0x76, 0x78, 0x50, 0x33, + 0x50, 0x6c, 0x53, 0x2b, 0x6d, 0x41, 0x2b, 0x45, 0x36, 0x4e, + 0x79, 0x51, 0x58, 0x30, 0x46, 0x2f, 0x66, 0x63, 0x66, 0x47, + 0x4c, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x45, 0x43, 0x67, + 0x59, 0x41, 0x30, 0x59, 0x4e, 0x4b, 0x68, 0x55, 0x45, 0x64, + 0x38, 0x78, 0x74, 0x47, 0x67, 0x44, 0x44, 0x79, 0x67, 0x2f, + 0x46, 0x47, 0x54, 0x55, 0x50, 0x64, 0x34, 0x0a, 0x42, 0x6b, + 0x6b, 0x49, 0x42, 0x31, 0x58, 0x55, 0x56, 0x4a, 0x79, 0x57, + 0x5a, 0x36, 0x50, 0x51, 0x47, 0x51, 0x59, 0x75, 0x33, 0x73, + 0x2b, 0x65, 0x39, 0x52, 0x58, 0x37, 0x67, 0x50, 0x78, 0x52, + 0x41, 0x63, 0x58, 0x61, 0x32, 0x7a, 0x63, 0x54, 0x37, 0x39, + 0x37, 0x6a, 0x79, 0x4f, 0x6c, 0x73, 0x7a, 0x52, 0x57, 0x68, + 0x53, 0x50, 0x6e, 0x65, 0x4e, 0x74, 0x70, 0x62, 0x48, 0x56, + 0x51, 0x74, 0x0a, 0x57, 0x5a, 0x44, 0x56, 0x79, 0x6b, 0x6c, + 0x6a, 0x52, 0x63, 0x75, 0x78, 0x46, 0x53, 0x5a, 0x70, 0x42, + 0x30, 0x37, 0x41, 0x53, 0x64, 0x4b, 0x42, 0x65, 0x4f, 0x31, + 0x44, 0x4c, 0x61, 0x47, 0x32, 0x57, 0x32, 0x48, 0x78, 0x47, + 0x4b, 0x63, 0x48, 0x34, 0x75, 0x64, 0x55, 0x62, 0x78, 0x35, + 0x52, 0x4c, 0x32, 0x4e, 0x61, 0x63, 0x51, 0x53, 0x4b, 0x52, + 0x2b, 0x38, 0x49, 0x73, 0x66, 0x53, 0x6d, 0x0a, 0x32, 0x51, + 0x35, 0x72, 0x2b, 0x37, 0x6f, 0x59, 0x6f, 0x56, 0x51, 0x79, + 0x50, 0x35, 0x44, 0x33, 0x6d, 0x51, 0x4a, 0x42, 0x41, 0x4f, + 0x47, 0x57, 0x59, 0x2f, 0x32, 0x41, 0x2b, 0x63, 0x62, 0x34, + 0x38, 0x52, 0x4c, 0x68, 0x4e, 0x4c, 0x6b, 0x64, 0x43, 0x6e, + 0x6e, 0x62, 0x47, 0x58, 0x68, 0x6b, 0x2b, 0x6f, 0x68, 0x36, + 0x73, 0x4c, 0x5a, 0x69, 0x62, 0x69, 0x7a, 0x62, 0x6f, 0x52, + 0x57, 0x6e, 0x0a, 0x6c, 0x79, 0x4d, 0x4f, 0x62, 0x31, 0x31, + 0x32, 0x5a, 0x6f, 0x50, 0x50, 0x46, 0x50, 0x35, 0x53, 0x4b, + 0x4e, 0x72, 0x64, 0x41, 0x78, 0x45, 0x6d, 0x45, 0x32, 0x33, + 0x31, 0x34, 0x4a, 0x63, 0x4e, 0x48, 0x72, 0x75, 0x74, 0x6a, + 0x4d, 0x46, 0x6d, 0x2f, 0x75, 0x63, 0x43, 0x51, 0x51, 0x44, + 0x42, 0x73, 0x78, 0x54, 0x54, 0x41, 0x7a, 0x6f, 0x78, 0x68, + 0x6f, 0x4f, 0x7a, 0x67, 0x56, 0x38, 0x52, 0x0a, 0x36, 0x35, + 0x4e, 0x64, 0x50, 0x58, 0x67, 0x2f, 0x64, 0x78, 0x64, 0x6b, + 0x34, 0x55, 0x61, 0x4b, 0x51, 0x6b, 0x39, 0x61, 0x49, 0x68, + 0x51, 0x61, 0x67, 0x77, 0x61, 0x38, 0x4f, 0x42, 0x6a, 0x50, + 0x46, 0x32, 0x49, 0x57, 0x67, 0x66, 0x4d, 0x5a, 0x30, 0x75, + 0x52, 0x71, 0x6d, 0x77, 0x2b, 0x4c, 0x4e, 0x4f, 0x6f, 0x45, + 0x6f, 0x79, 0x31, 0x68, 0x44, 0x30, 0x4a, 0x68, 0x42, 0x72, + 0x79, 0x44, 0x0a, 0x56, 0x78, 0x65, 0x39, 0x41, 0x6b, 0x45, + 0x41, 0x79, 0x77, 0x4b, 0x75, 0x5a, 0x56, 0x71, 0x47, 0x62, + 0x64, 0x74, 0x6d, 0x42, 0x39, 0x6d, 0x48, 0x75, 0x76, 0x63, + 0x35, 0x6b, 0x45, 0x50, 0x75, 0x66, 0x66, 0x78, 0x52, 0x77, + 0x6a, 0x53, 0x33, 0x68, 0x73, 0x71, 0x35, 0x33, 0x38, 0x43, + 0x66, 0x44, 0x48, 0x2f, 0x50, 0x63, 0x59, 0x72, 0x79, 0x43, + 0x61, 0x67, 0x64, 0x78, 0x59, 0x79, 0x38, 0x0a, 0x6c, 0x63, + 0x71, 0x57, 0x58, 0x61, 0x2f, 0x37, 0x72, 0x4a, 0x6b, 0x5a, + 0x62, 0x79, 0x47, 0x51, 0x78, 0x68, 0x37, 0x57, 0x67, 0x34, + 0x74, 0x42, 0x57, 0x6d, 0x4d, 0x34, 0x44, 0x51, 0x4a, 0x41, + 0x4c, 0x38, 0x4d, 0x59, 0x76, 0x32, 0x39, 0x73, 0x53, 0x67, + 0x6f, 0x42, 0x4c, 0x36, 0x49, 0x57, 0x37, 0x7a, 0x52, 0x48, + 0x67, 0x68, 0x5a, 0x47, 0x4d, 0x47, 0x41, 0x4e, 0x52, 0x4c, + 0x4c, 0x48, 0x0a, 0x30, 0x67, 0x2f, 0x48, 0x77, 0x56, 0x48, + 0x6c, 0x34, 0x79, 0x4f, 0x72, 0x35, 0x58, 0x31, 0x76, 0x6f, + 0x4b, 0x45, 0x44, 0x62, 0x73, 0x6c, 0x63, 0x53, 0x47, 0x48, + 0x59, 0x4d, 0x50, 0x46, 0x4c, 0x51, 0x2b, 0x67, 0x6f, 0x54, + 0x44, 0x78, 0x77, 0x56, 0x42, 0x36, 0x50, 0x48, 0x35, 0x32, + 0x70, 0x6e, 0x6a, 0x6b, 0x37, 0x67, 0x51, 0x4a, 0x41, 0x55, + 0x53, 0x48, 0x69, 0x56, 0x2f, 0x55, 0x51, 0x0a, 0x6b, 0x54, + 0x7a, 0x33, 0x42, 0x6c, 0x78, 0x5a, 0x63, 0x31, 0x49, 0x41, + 0x69, 0x55, 0x51, 0x76, 0x39, 0x2f, 0x42, 0x61, 0x38, 0x77, + 0x74, 0x48, 0x57, 0x53, 0x56, 0x70, 0x2b, 0x59, 0x71, 0x50, + 0x68, 0x78, 0x74, 0x31, 0x73, 0x66, 0x64, 0x69, 0x79, 0x55, + 0x4d, 0x58, 0x74, 0x6c, 0x41, 0x34, 0x66, 0x36, 0x57, 0x41, + 0x4b, 0x41, 0x47, 0x4d, 0x72, 0x61, 0x6f, 0x52, 0x77, 0x34, + 0x77, 0x49, 0x0a, 0x63, 0x59, 0x72, 0x2b, 0x4e, 0x36, 0x57, + 0x78, 0x2b, 0x77, 0x77, 0x58, 0x5a, 0x77, 0x3d, 0x3d, 0x0a, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, + 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, + }}, +}; + +/* + +ECDSA-P256-SHA256 + +ecdsa. IN DNSKEY 256 3 13 8uD7C4THTM/w7uhryRSToeE/jKT78/p853RX0L5EwrZrSLBubLPiBw7g bvUP6SsIga5ZQ4CSAxNmYA/gZsuXzA== +ecdsa. IN DS 5345 13 1 954103ac7c43810ce9f414e80f30ab1cbe49b236 +ecdsa. IN DS 5345 13 2 bac2107036e735b50f85006ce409a19a3438cab272e70769ebda032239a3d0ca +ecdsa. IN DS 5345 13 4 a0ac6790483872be72a258314200a88ab75cdd70f66a18a09f0f414c074df0989fdb1df0e67d82d4312cda67b93a76c1 + +PrivateKey: iyLIPdk3DOIxVmmSYlmTstbtUPiVlEyDX46psyCwNVQ= + +-----BEGIN PRIVATE KEY----- +MIGUAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHoweAIBAQQhAIsiyD3ZNwziMVZp +kmJZk7LW7VD4lZRMg1+OqbMgsDVUoAoGCCqGSM49AwEHoUQDQgAE8uD7C4THTM/w +7uhryRSToeE/jKT78/p853RX0L5EwrZrSLBubLPiBw7gbvUP6SsIga5ZQ4CSAxNm +YA/gZsuXzA== +-----END PRIVATE KEY----- + +*/ + +static const key_parameters_t SAMPLE_ECDSA_KEY = { + .name = (uint8_t *)"\x05""ecdsa", + .flags = 256, + .protocol = 3, + .algorithm = 13, + .public_key = { .size = 64, .data = (uint8_t []) { + 0xf2, 0xe0, 0xfb, 0x0b, 0x84, 0xc7, 0x4c, 0xcf, 0xf0, 0xee, + 0xe8, 0x6b, 0xc9, 0x14, 0x93, 0xa1, 0xe1, 0x3f, 0x8c, 0xa4, + 0xfb, 0xf3, 0xfa, 0x7c, 0xe7, 0x74, 0x57, 0xd0, 0xbe, 0x44, + 0xc2, 0xb6, 0x6b, 0x48, 0xb0, 0x6e, 0x6c, 0xb3, 0xe2, 0x07, + 0x0e, 0xe0, 0x6e, 0xf5, 0x0f, 0xe9, 0x2b, 0x08, 0x81, 0xae, + 0x59, 0x43, 0x80, 0x92, 0x03, 0x13, 0x66, 0x60, 0x0f, 0xe0, + 0x66, 0xcb, 0x97, 0xcc, + }}, + .rdata = { .size = 68, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x0d, + 0xf2, 0xe0, 0xfb, 0x0b, 0x84, 0xc7, 0x4c, 0xcf, 0xf0, 0xee, + 0xe8, 0x6b, 0xc9, 0x14, 0x93, 0xa1, 0xe1, 0x3f, 0x8c, 0xa4, + 0xfb, 0xf3, 0xfa, 0x7c, 0xe7, 0x74, 0x57, 0xd0, 0xbe, 0x44, + 0xc2, 0xb6, 0x6b, 0x48, 0xb0, 0x6e, 0x6c, 0xb3, 0xe2, 0x07, + 0x0e, 0xe0, 0x6e, 0xf5, 0x0f, 0xe9, 0x2b, 0x08, 0x81, 0xae, + 0x59, 0x43, 0x80, 0x92, 0x03, 0x13, 0x66, 0x60, 0x0f, 0xe0, + 0x66, 0xcb, 0x97, 0xcc, + }}, + .keytag = 5345, + .key_id = "47fd10011e76cc6741af586041eae5519465fc8d", + .ds_sha1 = { .size = 24, .data = (uint8_t []) { + 0x14, 0xe1, 0x0d, 0x01, + 0x95, 0x41, 0x03, 0xac, 0x7c, 0x43, 0x81, 0x0c, 0xe9, 0xf4, + 0x14, 0xe8, 0x0f, 0x30, 0xab, 0x1c, 0xbe, 0x49, 0xb2, 0x36, + }}, + .ds_sha256 = { .size = 36, .data = (uint8_t []) { + 0x14, 0xe1, 0x0d, 0x02, + 0xba, 0xc2, 0x10, 0x70, 0x36, 0xe7, 0x35, 0xb5, 0x0f, 0x85, + 0x00, 0x6c, 0xe4, 0x09, 0xa1, 0x9a, 0x34, 0x38, 0xca, 0xb2, + 0x72, 0xe7, 0x07, 0x69, 0xeb, 0xda, 0x03, 0x22, 0x39, 0xa3, + 0xd0, 0xca, + }}, + .ds_sha384 = { .size = 52, .data = (uint8_t []) { + 0x14, 0xe1, 0x0d, 0x04, + 0xa0, 0xac, 0x67, 0x90, 0x48, 0x38, 0x72, 0xbe, 0x72, 0xa2, + 0x58, 0x31, 0x42, 0x00, 0xa8, 0x8a, 0xb7, 0x5c, 0xdd, 0x70, + 0xf6, 0x6a, 0x18, 0xa0, 0x9f, 0x0f, 0x41, 0x4c, 0x07, 0x4d, + 0xf0, 0x98, 0x9f, 0xdb, 0x1d, 0xf0, 0xe6, 0x7d, 0x82, 0xd4, + 0x31, 0x2c, 0xda, 0x67, 0xb9, 0x3a, 0x76, 0xc1, + }}, + .bit_size = 256, + .pem = { .size = 262, .data = (uint8_t []) { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, + 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, + 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, + 0x47, 0x55, 0x41, 0x67, 0x45, 0x41, 0x4d, 0x42, 0x4d, 0x47, + 0x42, 0x79, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, 0x41, 0x67, + 0x45, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, + 0x41, 0x77, 0x45, 0x48, 0x42, 0x48, 0x6f, 0x77, 0x65, 0x41, + 0x49, 0x42, 0x41, 0x51, 0x51, 0x68, 0x41, 0x49, 0x73, 0x69, + 0x79, 0x44, 0x33, 0x5a, 0x4e, 0x77, 0x7a, 0x69, 0x4d, 0x56, + 0x5a, 0x70, 0x0a, 0x6b, 0x6d, 0x4a, 0x5a, 0x6b, 0x37, 0x4c, + 0x57, 0x37, 0x56, 0x44, 0x34, 0x6c, 0x5a, 0x52, 0x4d, 0x67, + 0x31, 0x2b, 0x4f, 0x71, 0x62, 0x4d, 0x67, 0x73, 0x44, 0x56, + 0x55, 0x6f, 0x41, 0x6f, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, + 0x4d, 0x34, 0x39, 0x41, 0x77, 0x45, 0x48, 0x6f, 0x55, 0x51, + 0x44, 0x51, 0x67, 0x41, 0x45, 0x38, 0x75, 0x44, 0x37, 0x43, + 0x34, 0x54, 0x48, 0x54, 0x4d, 0x2f, 0x77, 0x0a, 0x37, 0x75, + 0x68, 0x72, 0x79, 0x52, 0x53, 0x54, 0x6f, 0x65, 0x45, 0x2f, + 0x6a, 0x4b, 0x54, 0x37, 0x38, 0x2f, 0x70, 0x38, 0x35, 0x33, + 0x52, 0x58, 0x30, 0x4c, 0x35, 0x45, 0x77, 0x72, 0x5a, 0x72, + 0x53, 0x4c, 0x42, 0x75, 0x62, 0x4c, 0x50, 0x69, 0x42, 0x77, + 0x37, 0x67, 0x62, 0x76, 0x55, 0x50, 0x36, 0x53, 0x73, 0x49, + 0x67, 0x61, 0x35, 0x5a, 0x51, 0x34, 0x43, 0x53, 0x41, 0x78, + 0x4e, 0x6d, 0x0a, 0x59, 0x41, 0x2f, 0x67, 0x5a, 0x73, 0x75, + 0x58, 0x7a, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, + 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x0a, + }}, +}; + +/* + * Private-key-format: v1.2 + * Algorithm: 15 (ED25519) + * PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI= + * + * example.com. 3600 IN DNSKEY 256 3 15 ( + * l02Woi0iS8Aa25FQkUd9RMzZHJpBoRQwAQEX1SxZJA4= ) + * + * example.com. 3600 IN DS 3612 15 2 ( + * 3aa5ab37efce57f737fc1627013fee07bdf241bd10f3b1964ab55c78e79 + * a304b ) + * + * example.com. 3600 IN MX 10 mail.example.com. + * + * example.com. 3600 IN RRSIG MX 15 2 3600 ( + * 1440021600 1438207200 3613 example.com. ( + * oL9krJun7xfBOIWcGHi7mag5/hdZrKWw15jPGrHpjQeRAvTdszaPD+QLs3f + * x8A4M3e23mRZ9VrbpMngwcrqNAg== ) + */ + +static const key_parameters_t SAMPLE_ED25519_KEY = { + .name = (uint8_t *)"\x07""ed25519", + .flags = 256, + .protocol = 3, + .algorithm = 15, + .public_key = { .size = 32, .data = (uint8_t []) { + 0x97, 0x4d, 0x96, 0xa2, 0x2d, 0x22, 0x4b, 0xc0, 0x1a, 0xdb, 0x91, 0x50, + 0x91, 0x47, 0x7d, 0x44, 0xcc, 0xd9, 0x1c, 0x9a, 0x41, 0xa1, 0x14, 0x30, + 0x01, 0x01, 0x17, 0xd5, 0x2c, 0x59, 0x24, 0x0e, + }}, + .rdata = { .size = 36, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x0f, + 0x97, 0x4d, 0x96, 0xa2, 0x2d, 0x22, 0x4b, 0xc0, 0x1a, 0xdb, 0x91, 0x50, + 0x91, 0x47, 0x7d, 0x44, 0xcc, 0xd9, 0x1c, 0x9a, 0x41, 0xa1, 0x14, 0x30, + 0x01, 0x01, 0x17, 0xd5, 0x2c, 0x59, 0x24, 0x0e, + }}, + .keytag = 3612, + .key_id = "bea75b99fb22ee1a68106ad6399e4acc43eb9929", + .ds_sha1 = { .size = 24, .data = (uint8_t []) { + 0x0e, 0x1c, 0x0f, 0x01, + 0x50, 0x12, 0x49, 0x72, 0x1e, 0x1f, 0x09, 0xa7, 0x9d, 0x30, 0xd5, 0xc6, + 0xc4, 0xdc, 0xa1, 0xdc, 0x1d, 0xa4, 0xed, 0x5d, + }}, + .ds_sha256 = { .size = 36, .data = (uint8_t []) { + 0x0e, 0x1c, 0x0f, 0x02, + 0x1b, 0x1c, 0x87, 0x66, 0xb2, 0xa9, 0x65, 0x66, 0xff, 0x19, 0x6f, 0x77, + 0xc0, 0xc4, 0x19, 0x4a, 0xf8, 0x6a, 0xaa, 0x10, 0x9c, 0x53, 0x46, 0xff, + 0x60, 0x23, 0x1a, 0x27, 0xd2, 0xb0, 0x7a, 0xc0, + }}, + .ds_sha384 = { .size = 52, .data = (uint8_t []) { + 0x0e, 0x1c, 0x0f, 0x04, + 0xd1, 0x18, 0x31, 0x15, 0x3a, 0xf4, 0x98, 0x5e, 0xfb, 0xd0, 0xae, 0x79, + 0x2c, 0x96, 0x7e, 0xb4, 0xaf, 0xf3, 0xc3, 0x54, 0x88, 0xdb, 0x95, 0xf7, + 0xe2, 0xf8, 0x5d, 0xce, 0xc7, 0x4a, 0xe8, 0xf5, 0x9f, 0x9a, 0x72, 0x64, + 0x17, 0x98, 0xc9, 0x1c, 0x67, 0xc6, 0x75, 0xdb, 0x1d, 0x71, 0x0c, 0x18, + }}, + .bit_size = 256, + .pem = { .size = 119, .data = (uint8_t []) { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, + 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x43, 0x34, 0x43, 0x41, 0x51, 0x41, 0x77, + 0x42, 0x51, 0x59, 0x44, 0x4b, 0x32, 0x56, 0x77, 0x42, 0x43, 0x49, 0x45, + 0x49, 0x44, 0x67, 0x79, 0x4d, 0x6a, 0x59, 0x77, 0x4d, 0x7a, 0x67, 0x30, + 0x4e, 0x6a, 0x49, 0x34, 0x4d, 0x44, 0x67, 0x77, 0x4d, 0x54, 0x49, 0x79, + 0x4e, 0x6a, 0x51, 0x31, 0x4d, 0x54, 0x6b, 0x77, 0x4d, 0x6a, 0x41, 0x30, + 0x4d, 0x54, 0x51, 0x79, 0x4d, 0x6a, 0x59, 0x79, 0x0a, 0x2d, 0x2d, 0x2d, + 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, + 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a + }}, +}; + +/* + * Private-key-format: v1.2 + * Algorithm: 16 (ED448) + * PrivateKey: MEcCAQAwBQYDK2VxBDsEOVsk9cLaP+mD8n97xRET5bCqCUDZpPCIkCGrXLJG + * JgXCGlz4mOxH4qva7fIhEXm/62vtdbd55WRXIA== + * + * example.com. 3600 IN DNSKEY 256 3 16 ( + * 3y0sCUZKI+DSyZQTTbgHOFppOzYz01iZQQVUWw9gCb1bLWNqqC/5qq2PL9T + * c6YaK2vHthBtaY0iA ) + * + * example.com. 3600 IN DS 28205 16 2 ( + * 7a27236ccb5193f696cdb4c5fd58af3500634bd836e6defacaac5dd4d76 + * 6dcbe ) + * + * example.com. 3600 IN MX 10 mail.example.com. + * + * example.com. 3600 IN RRSIG MX 16 2 3600 20211108134038 ( + * 20211105115718 28205 example.com. + * uzvY2twOxxSas25N1HNQPRmhVgIaOHrEm6TccvwU + * WeJkecp2Nd0om5+Em1/91cfJWc/ZCFSYBcIAUFVB + * bMKoK0SXbmY5dM6rl0wQRk+Sl8VLyNttLMn5tpFk + * c74nWRGfXebz/HALT5WTdOidgIR8HCcA ) + */ + +static const key_parameters_t SAMPLE_ED448_KEY = { + .name = (uint8_t *)"\x07""example""\x03""com", + .flags = 256, + .protocol = 3, + .algorithm = 16, + .public_key = { .size = 57, .data = (uint8_t []) { + 0xdf, 0x2d, 0x2c, 0x09, 0x46, 0x4a, 0x23, 0xe0, 0xd2, 0xc9, 0x94, 0x13, + 0x4d, 0xb8, 0x07, 0x38, 0x5a, 0x69, 0x3b, 0x36, 0x33, 0xd3, 0x58, 0x99, + 0x41, 0x05, 0x54, 0x5b, 0x0f, 0x60, 0x09, 0xbd, 0x5b, 0x2d, 0x63, 0x6a, + 0xa8, 0x2f, 0xf9, 0xaa, 0xad, 0x8f, 0x2f, 0xd4, 0xdc, 0xe9, 0x86, 0x8a, + 0xda, 0xf1, 0xed, 0x84, 0x1b, 0x5a, 0x63, 0x48, 0x80, + }}, + .rdata = { .size = 61, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x10, + 0xdf, 0x2d, 0x2c, 0x09, 0x46, 0x4a, 0x23, 0xe0, 0xd2, 0xc9, 0x94, 0x13, + 0x4d, 0xb8, 0x07, 0x38, 0x5a, 0x69, 0x3b, 0x36, 0x33, 0xd3, 0x58, 0x99, + 0x41, 0x05, 0x54, 0x5b, 0x0f, 0x60, 0x09, 0xbd, 0x5b, 0x2d, 0x63, 0x6a, + 0xa8, 0x2f, 0xf9, 0xaa, 0xad, 0x8f, 0x2f, 0xd4, 0xdc, 0xe9, 0x86, 0x8a, + 0xda, 0xf1, 0xed, 0x84, 0x1b, 0x5a, 0x63, 0x48, 0x80, + }}, + .keytag = 28205, + .key_id = "501a69b2d8ad46c721ffabaa9eaf8e7fa49c1454", + .ds_sha1 = { .size = 24, .data = (uint8_t []) { + 0x6e, 0x2d, 0x10, 0x01, + 0x69, 0xac, 0x45, 0x1c, 0xfa, 0xbb, 0xbb, 0x16, 0x5e, 0xf3, 0x82, 0x08, + 0x1f, 0xd3, 0x7e, 0x7a, 0xb4, 0xd9, 0x13, 0xbf, + }}, + .ds_sha256 = { .size = 36, .data = (uint8_t []) { + 0x6e, 0x2d, 0x10, 0x02, + 0x7a, 0x27, 0x23, 0x6c, 0xcb, 0x51, 0x93, 0xf6, 0x96, 0xcd, 0xb4, 0xc5, + 0xfd, 0x58, 0xaf, 0x35, 0x00, 0x63, 0x4b, 0xd8, 0x36, 0xe6, 0xde, 0xfa, + 0xca, 0xac, 0x5d, 0xd4, 0xd7, 0x66, 0xdc, 0xbe, + }}, + .ds_sha384 = { .size = 52, .data = (uint8_t []) { + 0x6e, 0x2d, 0x10, 0x04, + 0x6e, 0x06, 0x6f, 0xfb, 0xd5, 0xa2, 0x6c, 0xf3, 0x04, 0xa1, 0x2b, 0x76, + 0xf1, 0x83, 0xdb, 0xd3, 0x8b, 0x5e, 0x7c, 0xcb, 0x19, 0x79, 0xff, 0x3f, + 0x46, 0xee, 0xf2, 0x61, 0xf7, 0xa0, 0x48, 0x96, 0xbd, 0xe6, 0x6a, 0xe8, + 0xd0, 0x30, 0x54, 0xc8, 0x3a, 0xa1, 0x2d, 0xb3, 0x77, 0x37, 0xf1, 0xbb, + }}, + .bit_size = 456, + .pem = { .size = 156, .data = (uint8_t []) { + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, + 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x45, 0x63, 0x43, 0x41, 0x51, 0x41, 0x77, + 0x42, 0x51, 0x59, 0x44, 0x4b, 0x32, 0x56, 0x78, 0x42, 0x44, 0x73, 0x45, + 0x4f, 0x56, 0x73, 0x6b, 0x39, 0x63, 0x4c, 0x61, 0x50, 0x2b, 0x6d, 0x44, + 0x38, 0x6e, 0x39, 0x37, 0x78, 0x52, 0x45, 0x54, 0x35, 0x62, 0x43, 0x71, + 0x43, 0x55, 0x44, 0x5a, 0x70, 0x50, 0x43, 0x49, 0x6b, 0x43, 0x47, 0x72, + 0x58, 0x4c, 0x4a, 0x47, 0x4a, 0x67, 0x58, 0x43, 0x0a, 0x47, 0x6c, 0x7a, + 0x34, 0x6d, 0x4f, 0x78, 0x48, 0x34, 0x71, 0x76, 0x61, 0x37, 0x66, 0x49, + 0x68, 0x45, 0x58, 0x6d, 0x2f, 0x36, 0x32, 0x76, 0x74, 0x64, 0x62, 0x64, + 0x35, 0x35, 0x57, 0x52, 0x58, 0x49, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, + 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a + }}, + /* raw private key outside of PEM: + * + * 0x5b, 0x24, 0xf5, 0xc2, 0xda, 0x3f, 0xe9, 0x83, 0xf2, 0x7f, 0x7b, 0xc5, + * 0x11, 0x13, 0xe5, 0xb0, 0xaa, 0x09, 0x40, 0xd9, 0xa4, 0xf0, 0x88, 0x90, + * 0x21, 0xab, 0x5c, 0xb2, 0x46, 0x26, 0x05, 0xc2, 0x1a, 0x5c, 0xf8, 0x98, + * 0xec, 0x47, 0xe2, 0xab, 0xda, 0xed, 0xf2, 0x21, 0x11, 0x79, 0xbf, 0xeb, + * 0x6b, 0xed, 0x75, 0xb7, 0x79, 0xe5, 0x64, 0x57, 0x20, + * + */ +}; diff --git a/tests/libdnssec/test_binary.c b/tests/libdnssec/test_binary.c new file mode 100644 index 0000000..4c78556 --- /dev/null +++ b/tests/libdnssec/test_binary.c @@ -0,0 +1,93 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "binary.h" +#include "error.h" + +typedef struct test_string { + const char *encoded; + size_t encoded_size; + const char *decoded; + size_t decoded_size; +} test_string_t; + +static void test_base64(void) +{ + test_string_t data[] = { + { "", 0, "", 0 }, + { "YQ==", 4, "a", 1 }, + { "YWI=", 4, "ab", 2 }, + { "YWJj", 4, "abc", 3 }, + { "YWJjZA==", 8, "abcd", 4 }, + { "YWJjZGU=", 8, "abcde", 5 }, + { "YWJjZGVm", 8, "abcdef", 6 }, + { NULL } + }; + + for (int i = 0; data[i].encoded != NULL; i++) { + test_string_t *ts = &data[i]; + + const dnssec_binary_t base64 = { + .size = ts->encoded_size, + .data = (uint8_t *) ts->encoded + }; + + dnssec_binary_t binary = { 0 }; + + int r = dnssec_binary_from_base64(&base64, &binary); + ok(r == DNSSEC_EOK && + binary.size == ts->decoded_size && + (binary.size == 0 || memcmp(binary.data, ts->decoded, binary.size) == 0), + "dnssec_binary_from_base64() for '%s'", ts->encoded); + + dnssec_binary_t encoded = { 0 }; + r = dnssec_binary_to_base64(&binary, &encoded); + ok(r == DNSSEC_EOK && + encoded.size == ts->encoded_size && + memcmp(encoded.data, ts->encoded, encoded.size) == 0, + "dnssec_binary_to_base64() for '%s'", ts->encoded); + + dnssec_binary_free(&binary); + dnssec_binary_free(&encoded); + } +} + +static void test_dup(void) +{ + dnssec_binary_t src = { .size = 5, .data = (uint8_t *) "ahoj" }; + dnssec_binary_t dst = { 0 }; + + int r = dnssec_binary_dup(&src, &dst); + ok(r == DNSSEC_EOK && + src.size == dst.size && memcmp(src.data, dst.data, src.size) == 0, + "dnssec_binary_dup()"); + + dnssec_binary_free(&dst); +} + +int main(void) +{ + plan_lazy(); + + test_base64(); + test_dup(); + + return 0; +} diff --git a/tests/libdnssec/test_crypto.c b/tests/libdnssec/test_crypto.c new file mode 100644 index 0000000..eb2601d --- /dev/null +++ b/tests/libdnssec/test_crypto.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "crypto.h" + +int main(void) +{ + plan_lazy(); + + // not much we can test + + dnssec_crypto_init(); + ok(1, "dnssec_crypto_init() didn't crash"); + + dnssec_crypto_reinit(); + ok(1, "dnssec_crypto_reinit() didn't crash"); + + dnssec_crypto_cleanup(); + ok(1, "dnssec_crypto_cleanup() didn't crash"); + + return 0; +} diff --git a/tests/libdnssec/test_key.c b/tests/libdnssec/test_key.c new file mode 100644 index 0000000..c3643f0 --- /dev/null +++ b/tests/libdnssec/test_key.c @@ -0,0 +1,215 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <string.h> + +#include "binary.h" +#include "crypto.h" +#include "error.h" +#include "key.h" + +#include "sample_keys.h" + +#define check_attr_scalar(key, type, name, def_val, set_val) { \ + type value = dnssec_key_get_##name(key); \ + ok(value == def_val, #name " default"); \ + r = dnssec_key_set_##name(key, set_val); \ + ok(r == DNSSEC_EOK, #name " set"); \ + value = dnssec_key_get_##name(key); \ + ok(value == set_val, #name " get"); \ +} + +static void check_key_tag(dnssec_key_t *key, const key_parameters_t *params) +{ + uint16_t keytag = dnssec_key_get_keytag(key); + ok(keytag == params->keytag, "get keytag"); +} + +static void check_key_size(dnssec_key_t *key, const key_parameters_t *params) +{ + ok(dnssec_key_get_size(key) == params->bit_size, + "key size %u bits", params->bit_size); +} + +static void check_usage(dnssec_key_t *key, bool ok_verify, bool ok_sign) +{ + ok(dnssec_key_can_verify(key) == ok_verify, + "%s verify", ok_verify ? "can" : "cannot"); + ok(dnssec_key_can_sign(key) == ok_sign, + "%s sign", ok_sign ? "can" : "cannot"); +} + +static void test_public_key(const key_parameters_t *params) +{ + dnssec_key_t *key = NULL; + int r = dnssec_key_new(&key); + ok(r == DNSSEC_EOK && key != NULL, "create key"); + + // create from parameters + + r = dnssec_key_set_pubkey(key, ¶ms->public_key); + ok(r == DNSSEC_INVALID_KEY_ALGORITHM, + "set public key (fails, no algorithm set)"); + + check_attr_scalar(key, uint16_t, flags, 256, params->flags); + check_attr_scalar(key, uint8_t, protocol, 3, params->protocol); + check_attr_scalar(key, uint8_t, algorithm, 0, params->algorithm); + + r = dnssec_key_set_pubkey(key, ¶ms->public_key); + ok(r == DNSSEC_EOK, "set public key (succeeds)"); + + r = dnssec_key_set_pubkey(key, ¶ms->public_key); + ok(r == DNSSEC_KEY_ALREADY_PRESENT, + "set public key (fails, already present)"); + + dnssec_binary_t rdata = { 0 }; + r = dnssec_key_get_rdata(key, &rdata); + ok(r == DNSSEC_EOK && dnssec_binary_cmp(&rdata, ¶ms->rdata) == 0, + "get RDATA"); + + check_key_tag(key, params); + + // create from RDATA + + dnssec_key_clear(key); + r = dnssec_key_set_rdata(key, ¶ms->rdata); + ok(r == DNSSEC_EOK, "set RDATA"); + + check_key_tag(key, params); + check_key_size(key, params); + check_usage(key, true, false); + + // create copy + + dnssec_key_t *copy = dnssec_key_dup(key); + ok(copy != NULL, "duplicate key"); + + check_key_tag(copy, params); + check_key_size(copy, params); + check_usage(copy, true, false); + + dnssec_key_free(copy); + dnssec_key_free(key); +} + +static void test_private_key(const key_parameters_t *params) +{ + dnssec_key_t *key = NULL; + int r = dnssec_key_new(&key); + ok(r == DNSSEC_EOK && key != NULL, "create key"); + + // import to public + + r = dnssec_key_set_rdata(key, ¶ms->rdata); + ok(r == DNSSEC_EOK, "set RDATA"); + + r = dnssec_key_load_pkcs8(key, ¶ms->pem); + ok(r == DNSSEC_EOK, "load private key (1)"); + + ok(dnssec_key_can_verify(key), "can verify"); + ok(dnssec_key_can_sign(key), "can sign"); + + // purely from parameters + + dnssec_key_clear(key); + + dnssec_key_set_algorithm(key, params->algorithm); + dnssec_key_set_flags(key, params->flags); + r = dnssec_key_load_pkcs8(key, ¶ms->pem); + ok(r == DNSSEC_EOK, "load private key (2)"); + + dnssec_binary_t rdata = { 0 }; + r = dnssec_key_get_rdata(key, &rdata); + ok(r == DNSSEC_EOK && dnssec_binary_cmp(&rdata, ¶ms->rdata) == 0, + "get RDATA"); + + check_key_tag(key, params); + check_key_size(key, params); + check_usage(key, true, true); + + // create copy + + dnssec_key_t *copy = dnssec_key_dup(key); + ok(copy != NULL, "duplicate key"); + + check_key_tag(copy, params); + check_key_size(copy, params); + check_usage(copy, true, true); + + dnssec_key_free(copy); + dnssec_key_free(key); +} + +static void test_naming(void) +{ + dnssec_key_t *key = NULL; + dnssec_key_new(&key); + + const uint8_t *input = (uint8_t *)"\x07""eXample""\x03""COM"; + const uint8_t *expected = (uint8_t *)"\x07""example""\x03""com"; + size_t expected_size = 13; + + ok(dnssec_key_get_dname(key) == NULL, "implicit key name"); + + dnssec_key_set_dname(key, input); + const uint8_t *output = dnssec_key_get_dname(key); + + ok(strlen((char *)output) + 1 == 13 && + memcmp(output, expected, expected_size) == 0, + "set key name"); + + dnssec_key_set_dname(key, NULL); + ok(dnssec_key_get_dname(key) == NULL, "clear key name"); + + dnssec_key_free(key); +} + +typedef struct keyinfo { + const char *name; + const key_parameters_t *parameters; +} keyinfo_t; + +int main(void) +{ + plan_lazy(); + + dnssec_crypto_init(); + + static const keyinfo_t keys[] = { + { "RSA", &SAMPLE_RSA_KEY }, + { "ECDSA", &SAMPLE_ECDSA_KEY }, +#ifdef HAVE_ED25519 + { "ED25519", &SAMPLE_ED25519_KEY }, +#endif +#ifdef HAVE_ED448 + { "ED448", &SAMPLE_ED448_KEY }, +#endif + { NULL } + }; + + for (const keyinfo_t *k = keys; k->name != NULL; k += 1) { + diag("%s key", k->name); + test_public_key(k->parameters); + test_private_key(k->parameters); + } + + test_naming(); + + dnssec_crypto_cleanup(); + + return 0; +} diff --git a/tests/libdnssec/test_key_algorithm.c b/tests/libdnssec/test_key_algorithm.c new file mode 100644 index 0000000..6c62106 --- /dev/null +++ b/tests/libdnssec/test_key_algorithm.c @@ -0,0 +1,90 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "error.h" +#include "key.h" + +static void ok_range(dnssec_key_algorithm_t algo, + unsigned exp_min, unsigned exp_max, + const char *name) +{ + unsigned min = 0, max = 0; + int r = dnssec_algorithm_key_size_range(algo, &min, &max); + ok(r == DNSSEC_EOK && min == exp_min && max == exp_max, + "dnssec_algorithm_key_size_range() for %s", name); +} + +static void null_range(void) +{ + dnssec_key_algorithm_t algo = DNSSEC_KEY_ALGORITHM_RSA_SHA256; + unsigned val = 0; + int r; + + r = dnssec_algorithm_key_size_range(algo, NULL, NULL); + ok(r == DNSSEC_EINVAL, "dnssec_algorithm_key_size_range() all null"); + r = dnssec_algorithm_key_size_range(algo, &val, NULL); + ok(r == DNSSEC_EOK && val == 1024, "dnssec_algorithm_key_size_range() min only"); + r = dnssec_algorithm_key_size_range(algo, NULL, &val); + ok(r == DNSSEC_EOK && val == 4096, "dnssec_algorithm_key_size_range() max only"); +} + +static void check_borders(void) +{ + dnssec_key_algorithm_t rsa = DNSSEC_KEY_ALGORITHM_RSA_SHA1; + + ok(dnssec_algorithm_key_size_check(rsa, 1023) == false, "rsa 1023"); + ok(dnssec_algorithm_key_size_check(rsa, 1024) == true, "rsa 1024"); + ok(dnssec_algorithm_key_size_check(rsa, 1025) == true, "rsa 1025"); + ok(dnssec_algorithm_key_size_check(rsa, 4095) == true, "rsa 4095"); + ok(dnssec_algorithm_key_size_check(rsa, 4096) == true, "rsa 4096"); + ok(dnssec_algorithm_key_size_check(rsa, 4097) == false, "rsa 4097"); +} + +static void check_defaults(void) +{ + is_int(2048, dnssec_algorithm_key_size_default(DNSSEC_KEY_ALGORITHM_RSA_SHA1_NSEC3), "rsa default"); + is_int(256, dnssec_algorithm_key_size_default(DNSSEC_KEY_ALGORITHM_ECDSA_P256_SHA256), "ecc default"); +#ifdef HAVE_ED25519 + is_int(256, dnssec_algorithm_key_size_default(DNSSEC_KEY_ALGORITHM_ED25519), "ed25519 default"); +#endif +#ifdef HAVE_ED448 + is_int(456, dnssec_algorithm_key_size_default(DNSSEC_KEY_ALGORITHM_ED448), "ed448 default"); +#endif +} + +int main(void) +{ + plan_lazy(); + + // ranges + ok_range(DNSSEC_KEY_ALGORITHM_RSA_SHA512, 1024, 4096, "RSA/SHA256"); + ok_range(DNSSEC_KEY_ALGORITHM_ECDSA_P384_SHA384, 384, 384, "ECDSA/SHA384"); +#ifdef HAVE_ED25519 + ok_range(DNSSEC_KEY_ALGORITHM_ED25519, 256, 256, "ED25519"); +#endif +#ifdef HAVE_ED448 + ok_range(DNSSEC_KEY_ALGORITHM_ED448, 456, 456, "ED448"); +#endif + null_range(); + + check_borders(); + + check_defaults(); + + return 0; +} diff --git a/tests/libdnssec/test_key_ds.c b/tests/libdnssec/test_key_ds.c new file mode 100644 index 0000000..fbc6327 --- /dev/null +++ b/tests/libdnssec/test_key_ds.c @@ -0,0 +1,122 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <stddef.h> +#include <string.h> + +#include "libdnssec/crypto.h" +#include "libdnssec/error.h" +#include "libdnssec/key.h" +#include "sample_keys.h" + +static void test_key(const char *name, const struct key_parameters *params) +{ + dnssec_key_t *key = NULL; + + dnssec_key_new(&key); + dnssec_key_set_dname(key, params->name); + dnssec_key_set_rdata(key, ¶ms->rdata); + + struct ds_type { + const char *name; + dnssec_key_digest_t digest; + size_t params_offset; + }; + + static const struct ds_type DS_TYPES[] = { + { "SHA-1", DNSSEC_KEY_DIGEST_SHA1, offsetof(typeof(*params), ds_sha1) }, + { "SHA-256", DNSSEC_KEY_DIGEST_SHA256, offsetof(typeof(*params), ds_sha256) }, + { "SHA-384", DNSSEC_KEY_DIGEST_SHA384, offsetof(typeof(*params), ds_sha384) }, + { NULL } + }; + + for (const struct ds_type *dt = DS_TYPES; dt->name != NULL; dt++) { + dnssec_binary_t ds = { 0 }; + int r = dnssec_key_create_ds(key, dt->digest, &ds); + + const dnssec_binary_t *expect = (void *)params + dt->params_offset; + + ok(r == DNSSEC_EOK && + ds.size == expect->size && + memcmp(ds.data, expect->data, ds.size) == 0, + "dnssec_key_create_ds() for %s/%s", name, dt->name); + + dnssec_binary_free(&ds); + } + + dnssec_key_free(key); +} + +static void test_errors(const struct key_parameters *params) +{ + dnssec_key_t *key = NULL; + dnssec_binary_t ds = { 0 }; + + int r = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA1, &ds); + is_int(DNSSEC_EINVAL, r, "dnssec_key_create_ds() no key"); + dnssec_binary_free(&ds); + + dnssec_key_new(&key); + r = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA1, &ds); + is_int(DNSSEC_INVALID_KEY_NAME, r, "dnssec_key_create_ds() no key name"); + + dnssec_key_set_dname(key, params->name); + r = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA1, &ds); + is_int(DNSSEC_INVALID_PUBLIC_KEY, r, "dnssec_key_create_ds() no public key"); + + dnssec_key_set_rdata(key, ¶ms->rdata); + r = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA1, NULL); + is_int(DNSSEC_EINVAL, r, "dnssec_key_create_ds() no RDATA buffer"); + + r = dnssec_key_create_ds(key, 3, &ds); + is_int(DNSSEC_INVALID_DS_ALGORITHM, r, "dnssec_key_create_ds() unsupported algorithm"); + + r = dnssec_key_create_ds(key, DNSSEC_KEY_DIGEST_SHA1, &ds); + is_int(DNSSEC_EOK, r, "dnssec_key_create_ds() valid parameters"); + + dnssec_binary_free(&ds); + dnssec_key_free(key); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + dnssec_crypto_init(); + + test_key("RSA", &SAMPLE_RSA_KEY); + test_key("ECDSA", &SAMPLE_ECDSA_KEY); +#ifdef HAVE_ED25519 + test_key("ED25519", &SAMPLE_ED25519_KEY); +#endif +#ifdef HAVE_ED448 + test_key("ED448", &SAMPLE_ED448_KEY); +#endif + + test_errors(&SAMPLE_ECDSA_KEY); +#ifdef HAVE_ED25519 + test_errors(&SAMPLE_ED25519_KEY); +#endif +#ifdef HAVE_ED448 + test_errors(&SAMPLE_ED448_KEY); +#endif + + dnssec_crypto_cleanup(); + + return 0; +} diff --git a/tests/libdnssec/test_keyid.c b/tests/libdnssec/test_keyid.c new file mode 100644 index 0000000..10b6297 --- /dev/null +++ b/tests/libdnssec/test_keyid.c @@ -0,0 +1,82 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <stdlib.h> +#include <string.h> + +#include "error.h" +#include "keyid.h" + +static void test_keyid_is_valid_run(const char *param, bool should_ok) +{ + ok(dnssec_keyid_is_valid(param) == should_ok, + "dnssec_keyid_is_valid(\"%s\")", param == NULL ? "(null)" : param); +} + +static void test_keyid_is_valid(void) +{ + test_keyid_is_valid_run(NULL, false); + test_keyid_is_valid_run("a1b1", true); + test_keyid_is_valid_run("3e90c5cb1fad5f8512da2028fda3808e749d3bf", false); + test_keyid_is_valid_run("9aa6dAAC706fb6fe4aceb327452a7b5FEA457544", true); + test_keyid_is_valid_run("eac45c184b7f476472c16d5b0c4f0c52389848001", false); + test_keyid_is_valid_run("9aa6daac706fb6fe4aceb32g452a7b5fea457544", false); +} + +static void test_keyid_normalize(void) +{ + char id[] = "3711927404f64CE7df88253d763e442CE39f9B5c"; + const char *id_norm = "3711927404f64ce7df88253d763e442ce39f9b5c"; + + dnssec_keyid_normalize(id); + ok(strcmp(id, id_norm) == 0, "dnssec_keyid_normalize()"); +} + +static void test_keyid_copy(void) +{ + const char *id = "21669f1eca6418f9aBBBf0007e6f73463d467424"; + const char *expected = "21669f1eca6418f9abbbf0007e6f73463d467424"; + + char *copy = dnssec_keyid_copy(id); + ok(copy && strcmp(copy, expected) == 0, "dnssec_keyid_copy()"); + + free(copy); +} + +static void test_keyid_equal(void) +{ + const char *id = "dd63237d4a07867de715499690c9ad12990519f0"; + const char *id_case = "dd63237d4a07867de715499690C9AD12990519F0"; + const char *id_diff = "dd63237d4a07867de715499690c9ad12990519f1"; + + ok(dnssec_keyid_equal(id, NULL) == false, "dnssec_keyid_equal(id, NULL)"); + ok(dnssec_keyid_equal(id, id) == true, "dnssec_keyid_equal(id, id)"); + ok(dnssec_keyid_equal(id, id_case) == true, "dnssec_keyid_equal(id, ID)"); + ok(dnssec_keyid_equal(id, id_diff) == false, "dnssec_keyid_equal(ida, idb)"); +} + +int main(void) +{ + plan_lazy(); + + test_keyid_is_valid(); + test_keyid_normalize(); + test_keyid_copy(); + test_keyid_equal(); + + return 0; +} diff --git a/tests/libdnssec/test_keystore_pkcs11.c b/tests/libdnssec/test_keystore_pkcs11.c new file mode 100644 index 0000000..9828fce --- /dev/null +++ b/tests/libdnssec/test_keystore_pkcs11.c @@ -0,0 +1,421 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <tap/files.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include "libdnssec/crypto.h" +#include "libdnssec/error.h" +#include "libdnssec/keystore.h" +#include "libdnssec/sign.h" + +#include "sample_keys.h" + +#define ENV_SOFTHSM_DSO "KNOT_SOFTHSM2_DSO" +#define ENV_SOFTHSM_UTIL "KNOT_SOFTHSM2_UTIL" + +#define SOFTHSM_DSO "libsofthsm2.so" +#define SOFTHSM_CONF "softhsm2.conf" +#define SOFTHSM_CONF_ENV "SOFTHSM2_CONF" +#define SOFTHSM_UTIL "softhsm2-util" + +#define TOKEN_LABEL "libdnssec-test" +#define TOKEN_PIN "1234" +#define TOKEN_SOPIN "123456" + +#define EXIT_EXEC_FAILED 127 + +#ifndef LIBDIR +# include <bits/wordsize.h> +# if __WORDSIZE == 32 +# define LIBDIR "/usr/lib32" +# elif __WORDSIZE == 64 +# define LIBDIR "/usr/lib64" +# endif +#endif + +#define MSG_SOFTWARE "soft -" +#define MSG_PKCS11 "p11 -" + +/*! + * Get SoftHSM DSO path. + */ +static char *libsofthsm_dso(void) +{ + // prefer environment variable + + const char *env = getenv(ENV_SOFTHSM_DSO); + if (env) { + return (env[0] != '\0' ? strdup(env) : NULL); + } + + // autodetection + + static const char *paths[] = { + LIBDIR "/pkcs11/" SOFTHSM_DSO, + LIBDIR "/softhsm/" SOFTHSM_DSO, + LIBDIR "/" SOFTHSM_DSO, + NULL + }; + + for (const char **path_ptr = paths; *path_ptr; path_ptr += 1) { + const char *path = *path_ptr; + if (access(path, R_OK|X_OK) == 0) { + return strdup(path); + } + } + + return NULL; +} + +/*! + * Get SoftHSM utility path. + */ +static char *libsofthsm_util(void) +{ + // prefer environment variable + + const char *env = getenv(ENV_SOFTHSM_UTIL); + if (env && env[0] != '\0') { + return strdup(env); + } + + // fallback, will rely on PATH + + return strdup(SOFTHSM_UTIL); +} + +/*! + * Path to temporary token data. + */ +static char *token_path = NULL; + +/*! + * Cleanup token test data. + */ +static void token_cleanup(void) +{ + test_rm_rf(token_path); + free(token_path); +} + +/*! + * Initialize token using the support tool. + */ +static bool token_init_exec(const char *util) +{ + pid_t child = fork(); + if (child == -1) { + return false; + } + + // child + + if (child == 0) { + fclose(stdin); + fclose(stdout); + fclose(stderr); + + const char *basename = strrchr(util, '/'); + if (basename) { + basename += 1; + } else { + basename = util; + } + + execlp(util, basename, + "--init-token", "--slot=0", "--label=" TOKEN_LABEL, + "--pin=" TOKEN_PIN, "--so-pin=" TOKEN_SOPIN, + NULL); + + exit(EXIT_EXEC_FAILED); + } + + // parent + + int status = 0; + if (waitpid(child, &status, 0) == -1) { + return false; + } + + int exit_code = WIFEXITED(status) ? WEXITSTATUS(status) : -1; + if (exit_code != 0) { + diag("%s exit status %d", util, exit_code); + if (exit_code == EXIT_EXEC_FAILED) { + diag("set %s environment variable to adjust the path", + ENV_SOFTHSM_UTIL); + } + } + + return exit_code == 0; +} + +/*! + * Initialize environment and token for testing. + */ +static bool token_init(void) +{ + token_path = test_mkdtemp(); + if (!token_path) { + return false; + } + + // generate configuration file for unit test + + char config[4096] = { 0 }; + int r = snprintf(config, sizeof(config), "%s/%s", token_path, SOFTHSM_CONF); + if (r <= 0 || r >= sizeof(config)) { + return false; + } + + FILE *file = fopen(config, "w"); + if (!file) { + return false; + } + + fprintf(file, "directories.tokendir = %s\n", token_path); + fprintf(file, "objectstore.backend = file\n"); + fprintf(file, "log.level = INFO\n"); + fprintf(file, "slots.removable = false\n"); + + fclose(file); + + // update environment to use the config + + if (setenv(SOFTHSM_CONF_ENV, config, 1) != 0) { + return false; + } + + // initialize token + + char *util = libsofthsm_util(); + if (!util) { + return false; + } + + bool inited = token_init_exec(util); + free(util); + + return inited; +} + +static void create_dnskeys(dnssec_keystore_t *keystore, + dnssec_key_algorithm_t algorithm, const char *id, + dnssec_key_t **p11_key_ptr, dnssec_key_t **soft_key_ptr) +{ + int r; + + // construct PKCS #11 privkey-pubkey key pair + + dnssec_key_t *p11_key = NULL; + r = dnssec_key_new(&p11_key); + ok(r == DNSSEC_EOK && p11_key != NULL, MSG_PKCS11 " dnssec_key_new()"); + + r = dnssec_key_set_algorithm(p11_key, algorithm); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_key_set_algorithm()"); + + r = dnssec_keystore_get_private(keystore, id, p11_key); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_keystore_get_private()"); + + // construct software public key + + dnssec_key_t *soft_key = NULL; + r = dnssec_key_new(&soft_key); + ok(r == DNSSEC_EOK && soft_key != NULL, MSG_SOFTWARE " dnssec_key_new()"); + + dnssec_binary_t rdata = { 0 }; + dnssec_key_get_rdata(p11_key, &rdata); + r = dnssec_key_set_rdata(soft_key, &rdata); + ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_key_set_rdata()"); + + *p11_key_ptr = p11_key; + *soft_key_ptr = soft_key; +} + +static void test_sign(dnssec_key_t *p11_key, dnssec_key_t *soft_key) +{ + int r; + + static const dnssec_binary_t input = { + .data = (uint8_t *)"So Long, and Thanks for All the Fish.", + .size = 37 + }; + + dnssec_binary_t sign = { 0 }; + + // usage constraints + + ok(dnssec_key_can_sign(p11_key), MSG_PKCS11 " dnssec_key_can_sign()"); + ok(dnssec_key_can_verify(p11_key), MSG_PKCS11 " dnssec_key_can_verify()"); + + ok(!dnssec_key_can_sign(soft_key), MSG_SOFTWARE " dnssec_key_can_sign()"); + ok(dnssec_key_can_verify(soft_key), MSG_SOFTWARE " dnssec_key_can_verify()"); + + // PKCS #11 key signature + + dnssec_sign_ctx_t *ctx = NULL; + r = dnssec_sign_new(&ctx, p11_key); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_init() "); + + r = dnssec_sign_add(ctx, &input); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_add()"); + + r = dnssec_sign_write(ctx, DNSSEC_SIGN_NORMAL, &sign); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_write()"); + + // PKCS #11 key verification + + r = dnssec_sign_init(ctx); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_init()"); + + r = dnssec_sign_add(ctx, &input); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_add()"); + + r = dnssec_sign_verify(ctx, false, &sign); + ok(r == DNSSEC_EOK, MSG_PKCS11 " dnssec_sign_verify()"); + + // software verification + + dnssec_sign_free(ctx); + ctx = NULL; + + r = dnssec_sign_new(&ctx, soft_key); + ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_init()"); + + r = dnssec_sign_add(ctx, &input); + ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_add()"); + + r = dnssec_sign_verify(ctx, false, &sign); + ok(r == DNSSEC_EOK, MSG_SOFTWARE " dnssec_sign_verify()"); + + dnssec_binary_free(&sign); + dnssec_sign_free(ctx); +} + +static void test_key_use(dnssec_keystore_t *store, + dnssec_key_algorithm_t algorithm, + const char *keyid) +{ + dnssec_key_t *p11_key = NULL; + dnssec_key_t *soft_key = NULL; + + create_dnskeys(store, algorithm, keyid, &p11_key, &soft_key); + test_sign(p11_key, soft_key); + + dnssec_key_free(p11_key); + dnssec_key_free(soft_key); +} + +static void test_algorithm(dnssec_keystore_t *store, + const key_parameters_t *params) +{ + char *id_generate = NULL; + char *id_import = NULL; + + int r; + + diag("algorithm %d, generated key", params->algorithm); + + r = dnssec_keystore_generate(store, params->algorithm, params->bit_size, + NULL, &id_generate); + ok(r == DNSSEC_EOK && id_generate != NULL, "dnssec_keystore_generate()"); + test_key_use(store, params->algorithm, id_generate); + + diag("algorithm %d, imported key", params->algorithm); + + r = dnssec_keystore_import(store, ¶ms->pem, &id_import); + ok(r == DNSSEC_EOK && id_import != NULL, "dnssec_keystore_import()"); + test_key_use(store, params->algorithm, id_import); + + free(id_generate); + free(id_import); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + dnssec_crypto_init(); + + // PKCS #11 initialization + + dnssec_keystore_t *store = NULL; + int r = dnssec_keystore_init_pkcs11(&store); + if (r == DNSSEC_NOT_IMPLEMENTED_ERROR) { + skip_all("not supported"); + goto done; + } + ok(r == DNSSEC_EOK && store, "dnssec_keystore_init_pkcs11()"); + + char *dso_name = libsofthsm_dso(); + if (!dso_name) { + skip_all("%s not found, set %s environment variable", + SOFTHSM_DSO, ENV_SOFTHSM_DSO); + goto done; + } + ok(dso_name != NULL, "find token DSO"); + + bool success = token_init(); + if (!success) { + skip_all("failed to configure and initialize the token"); + goto done; + } + ok(success, "initialize the token"); + + char config[4096] = { 0 }; + r = snprintf(config, sizeof(config), "pkcs11:token=%s;pin-value=%s %s", + TOKEN_LABEL, TOKEN_PIN, dso_name); + free(dso_name); + ok(r > 0 && r < sizeof(config), "build configuration"); + + // key store access + + r = dnssec_keystore_init(store, config); + ok(r == DNSSEC_EOK, "dnssec_keystore_init()"); + + r = dnssec_keystore_open(store, config); + ok(r == DNSSEC_EOK, "dnssec_keystore_open()"); + + // key manipulation + + static const int KEYS_COUNT = 2; + static const key_parameters_t *KEYS[] = { + &SAMPLE_RSA_KEY, + &SAMPLE_ECDSA_KEY, + }; + assert(KEYS_COUNT == sizeof(KEYS) / sizeof(*KEYS)); + + for (int i = 0; i < KEYS_COUNT; i++) { + test_algorithm(store, KEYS[i]); + } + + r = dnssec_keystore_close(store); + ok(r == DNSSEC_EOK, "dnssec_keystore_close()"); +done: + dnssec_keystore_deinit(store); + dnssec_crypto_cleanup(); + token_cleanup(); + + return 0; +} diff --git a/tests/libdnssec/test_keystore_pkcs8.c b/tests/libdnssec/test_keystore_pkcs8.c new file mode 100644 index 0000000..26acbd4 --- /dev/null +++ b/tests/libdnssec/test_keystore_pkcs8.c @@ -0,0 +1,98 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <tap/files.h> + +#include "error.h" +#include "key.h" +#include "keystore.h" + +int main(void) +{ + plan_lazy(); + + char *dir = test_tmpdir(); + if (!dir) { + return 1; + } + + // create context + + dnssec_keystore_t *store = NULL; + int r = dnssec_keystore_init_pkcs8(&store); + ok(r == DNSSEC_EOK, "dnssec_keystore_init_pkcs8()"); + + r = dnssec_keystore_init(store, dir); + ok(r == DNSSEC_EOK, "init"); + + r = dnssec_keystore_open(store, dir); + ok(r == DNSSEC_EOK, "open"); + + // writing new content + + char *id_A = NULL; + r = dnssec_keystore_generate(store, DNSSEC_KEY_ALGORITHM_RSA_SHA256, + 1024, NULL, &id_A); + ok(r == DNSSEC_EOK, "generate A"); + + char *id_B = NULL; + r = dnssec_keystore_generate(store, DNSSEC_KEY_ALGORITHM_RSA_SHA256, + 1024, NULL, &id_B); + ok(r == DNSSEC_EOK, "generate B"); + + // reading existing content + + dnssec_key_t *key = NULL; + dnssec_key_new(&key); + dnssec_key_set_algorithm(key, DNSSEC_KEY_ALGORITHM_RSA_SHA256); + r = dnssec_keystore_get_private(store, id_A, key); + ok(r == DNSSEC_EOK, "read A"); + dnssec_key_free(key); + + dnssec_key_new(&key); + dnssec_key_set_algorithm(key, DNSSEC_KEY_ALGORITHM_RSA_SHA256); + r = dnssec_keystore_get_private(store, id_B, key); + ok(r == DNSSEC_EOK, "read B"); + dnssec_key_free(key); + + // content removal + + r = dnssec_keystore_remove(store, id_A); + ok(r == DNSSEC_EOK, "remove A"); + + dnssec_key_new(&key); + dnssec_key_set_algorithm(key, DNSSEC_KEY_ALGORITHM_RSA_SHA256); + r = dnssec_keystore_get_private(store, id_A, key); + ok(r == DNSSEC_ENOENT, "read removed"); + dnssec_key_free(key); + + // cleanup + + free(id_A); + free(id_B); + + r = dnssec_keystore_close(store); + ok(r == DNSSEC_EOK, "close"); + + r = dnssec_keystore_deinit(store); + ok(r == DNSSEC_EOK, "deinit"); + + test_rm_rf(dir); + free(dir); + + return 0; +} diff --git a/tests/libdnssec/test_keytag.c b/tests/libdnssec/test_keytag.c new file mode 100644 index 0000000..ac5f57a --- /dev/null +++ b/tests/libdnssec/test_keytag.c @@ -0,0 +1,61 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <stdint.h> + +#include "binary.h" +#include "error.h" +#include "keytag.h" + +int main(void) +{ + plan_lazy(); + + const dnssec_binary_t rsa_md5_rdata = { .size = 72, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x01, + 0x03, 0x01, 0x00, 0x01, 0xa6, 0x83, 0x41, 0x42, 0x58, 0x1b, + 0xc2, 0xa7, 0xc7, 0xd5, 0xef, 0xb5, 0x6c, 0xec, 0x34, 0xc5, + 0xc9, 0x5e, 0x84, 0xa8, 0x35, 0x4a, 0xe0, 0xc2, 0x70, 0xf5, + 0x40, 0xe9, 0x92, 0x06, 0x70, 0x45, 0x88, 0xd3, 0x86, 0xcf, + 0xf5, 0xff, 0x83, 0x08, 0x06, 0x98, 0xe7, 0x8a, 0xa9, 0x2c, + 0xe7, 0xe1, 0x4d, 0xa6, 0x46, 0xef, 0x3a, 0x96, 0x93, 0x8c, + 0xc1, 0x02, 0x00, 0x6f, 0x31, 0x9f, 0xa2, 0x1d + }}; + + uint16_t tag = 0; + ok(dnssec_keytag(&rsa_md5_rdata, &tag) == DNSSEC_EOK && tag == 40866, + "keytag for RSA/MD5"); + + const dnssec_binary_t ecdsa_rdata = { .size = 100, .data = (uint8_t []) { + 0x01, 0x00, 0x03, 0x0e, + 0xbe, 0x8f, 0x42, 0x92, 0x34, 0xa0, 0x06, 0x5f, 0x18, 0xa1, + 0x15, 0x01, 0x84, 0x50, 0x33, 0x1f, 0x44, 0xa2, 0xbb, 0x61, + 0x2a, 0xc8, 0x86, 0x9c, 0xf3, 0x4b, 0x2e, 0xf9, 0x63, 0xd1, + 0x81, 0x72, 0x56, 0x96, 0xc7, 0x67, 0x34, 0xa1, 0x55, 0xc2, + 0xf3, 0x1d, 0x03, 0xbe, 0x1b, 0x39, 0xeb, 0xa7, 0xb8, 0x2c, + 0x72, 0x2e, 0x58, 0x75, 0x56, 0x42, 0x0b, 0x6f, 0x21, 0xa2, + 0x33, 0xf4, 0x21, 0x00, 0xb7, 0x0f, 0x5a, 0xf7, 0x1a, 0xf0, + 0xe9, 0x94, 0xfa, 0x43, 0xb0, 0x4a, 0x48, 0xb8, 0x64, 0x89, + 0x7b, 0xc9, 0xe0, 0xf7, 0x97, 0x52, 0xf4, 0x85, 0x0f, 0xb4, + 0xf4, 0xfc, 0xe2, 0x10, 0xd4, 0x26 + }}; + + ok(dnssec_keytag(&ecdsa_rdata, &tag) == DNSSEC_EOK && tag == 61768, + "keytag for ECDSA/SHA384"); + + return 0; +} diff --git a/tests/libdnssec/test_nsec_bitmap.c b/tests/libdnssec/test_nsec_bitmap.c new file mode 100644 index 0000000..f013131 --- /dev/null +++ b/tests/libdnssec/test_nsec_bitmap.c @@ -0,0 +1,102 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> + +#include "nsec.h" +#include "libknot/descriptor.h" + +#define TEST_BITMAP_SIZE 18 + +int main(void) +{ + plan_lazy(); + + // Which rrtypes will be contained in the bitmap. + int test_contains_count = 8; + enum knot_rr_type test_contains[] = { + KNOT_RRTYPE_A, + KNOT_RRTYPE_NS, + KNOT_RRTYPE_SOA, + KNOT_RRTYPE_RRSIG, + KNOT_RRTYPE_NSEC, + KNOT_RRTYPE_DNSKEY, + KNOT_RRTYPE_SPF, + KNOT_RRTYPE_CAA + }; + + // Which rrtypes will not be contained in the bitmap. + int test_not_contains_count = 4; + enum knot_rr_type test_not_contains[] = { + KNOT_RRTYPE_AAAA, + KNOT_RRTYPE_MX, + KNOT_RRTYPE_AXFR, + KNOT_RRTYPE_CNAME + }; + + // Allocate new bitmap. + dnssec_nsec_bitmap_t *bitmap = dnssec_nsec_bitmap_new(); + ok(bitmap != NULL, "allocate bitmap"); + if (!bitmap) { + return 1; + } + + // Add the desired RR types to bitmap. + for (int i = 0; i < test_contains_count; i++) { + dnssec_nsec_bitmap_add(bitmap, test_contains[i]); + } + + size_t size = dnssec_nsec_bitmap_size(bitmap); + ok(size == TEST_BITMAP_SIZE, "valid bitmap size"); + if (size != TEST_BITMAP_SIZE) { + dnssec_nsec_bitmap_free(bitmap); + return 1; + } + + const uint8_t expected[TEST_BITMAP_SIZE] = { + 0x00, 0x0D, 0x62, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x01, 0x01, 0x40 + }; + uint8_t encoded[TEST_BITMAP_SIZE] = { 0 }; + dnssec_nsec_bitmap_write(bitmap, encoded); + + ok(memcmp(encoded, expected, TEST_BITMAP_SIZE) == 0, "valid bitmap"); + + // Test contained types. + char rrtype_str[50]; + for (int i = 0; i < test_contains_count; i++) { + bool contains = dnssec_nsec_bitmap_contains(encoded, size, test_contains[i]); + (void)knot_rrtype_to_string(test_contains[i], rrtype_str, 50); + ok(contains, "bitmap contains %s", rrtype_str); + } + + // Test not contained types. + for (int i = 0; i < test_not_contains_count; i++) { + bool contains = dnssec_nsec_bitmap_contains(encoded, size, test_not_contains[i]); + (void)knot_rrtype_to_string(test_not_contains[i], rrtype_str, 50); + ok(!contains, "bitmap does not contain %s", rrtype_str); + } + + dnssec_nsec_bitmap_clear(bitmap); + ok(dnssec_nsec_bitmap_size(bitmap) == 0, "bitmap clear"); + + dnssec_nsec_bitmap_free(bitmap); + return 0; +} diff --git a/tests/libdnssec/test_nsec_hash.c b/tests/libdnssec/test_nsec_hash.c new file mode 100644 index 0000000..595a314 --- /dev/null +++ b/tests/libdnssec/test_nsec_hash.c @@ -0,0 +1,114 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <tap/basic.h> + +#include "crypto.h" +#include "error.h" +#include "nsec.h" + +static const dnssec_binary_t RDATA = { .size = 9, .data = (uint8_t []) { + 0x01, // algorithm + 0x00, // flags + 0x00, 0x0a, // iterations + 0x04, // salt length + 'a', 'b', 'c', 'd' // salt +}}; + +static void test_length(void) +{ + ok(dnssec_nsec3_hash_length(DNSSEC_NSEC3_ALGORITHM_SHA1) == 20, + "dnssec_nsec3_hash_length() for SHA1"); +} + +static void test_parsing(void) +{ + + dnssec_nsec3_params_t params = { 0 }; + int result = dnssec_nsec3_params_from_rdata(¶ms, &RDATA); + ok(result == DNSSEC_EOK, "dnssec_nsec3_params_from_rdata()"); + + ok(params.algorithm == 1, "algorithm"); + ok(params.flags == 0, "flags"); + ok(params.iterations == 10, "iterations"); + ok(params.salt.size == 4, "salt length"); + ok(params.salt.data != NULL && memcmp(params.salt.data, "abcd", 4) == 0, + "salt content"); + + dnssec_nsec3_params_free(¶ms); + ok(params.salt.data == NULL, "dnssec_nsec3_params_free()"); +} + +static void test_hashing(void) +{ + const dnssec_binary_t dname = { + .size = 13, + .data = (uint8_t *) "\x08""knot-dns""\x02""cz" + }; + + const dnssec_nsec3_params_t params = { + .algorithm = DNSSEC_NSEC3_ALGORITHM_SHA1, + .flags = 0, + .iterations = 7, + .salt = { .size = 14, .data = (uint8_t *) "happywithnsec3" } + }; + + const dnssec_binary_t expected = { .size = 20, .data = (uint8_t []) { + 0x72, 0x40, 0x55, 0x83, 0x92, 0x93, 0x95, 0x28, 0xee, 0xa2, + 0xcc, 0xe1, 0x13, 0xbe, 0xcd, 0x41, 0xee, 0x8a, 0x71, 0xfd + }}; + + dnssec_binary_t hash = { 0 }; + + int result = dnssec_nsec3_hash(&dname, ¶ms, &hash); + ok(result == DNSSEC_EOK, "dnssec_nsec3_hash()"); + + ok(hash.size == expected.size && hash.data != NULL && + memcmp(hash.data, expected.data, expected.size) == 0, + "valid hash"); + + dnssec_binary_free(&hash); +} + +static void test_clear(void) +{ + const dnssec_nsec3_params_t empty = { 0 }; + dnssec_nsec3_params_t params = { 0 }; + + int result = dnssec_nsec3_params_from_rdata(¶ms, &RDATA); + ok(result == DNSSEC_EOK, "dnssec_nsec3_params_from_rdata()"); + + ok(memcmp(¶ms, &empty, sizeof(dnssec_nsec3_params_t)) != 0, + "non-empty after dnssec_nsec3_params_from_rdata()"); + + dnssec_nsec3_params_free(¶ms); + + ok(memcmp(¶ms, &empty, sizeof(dnssec_nsec3_params_t)) == 0, + "cleared after dnssec_nsec3_params_free()"); +} + +int main(void) +{ + plan_lazy(); + + test_length(); + test_parsing(); + test_hashing(); + test_clear(); + + return 0; +} diff --git a/tests/libdnssec/test_random.c b/tests/libdnssec/test_random.c new file mode 100644 index 0000000..622c967 --- /dev/null +++ b/tests/libdnssec/test_random.c @@ -0,0 +1,82 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "crypto.h" +#include "error.h" +#include "random.h" + +int check_buffer(void) +{ + const size_t buffer_size = 128; + uint8_t buffer_prev[buffer_size]; + memset(buffer_prev, 0, buffer_size); + uint8_t buffer[buffer_size]; + memset(buffer, 0, buffer_size); + + for (int i = 0; i < 10; i++) { + int result = dnssec_random_buffer(buffer, buffer_size); + if (result != DNSSEC_EOK) { + return 1; + } + + if (memcmp(buffer, buffer_prev, buffer_size) == 0) { + return 1; + } + + memmove(buffer_prev, buffer, buffer_size); + } + + return 0; +} + +int check_random_type(void) +{ + uint16_t numbers[1000] = { 0 }; + int conflicts = 0; + + for (int i = 0; i < 1000; i++) { + numbers[i] = dnssec_random_uint16_t(); + // check all previous + for (int j = 0; j < i; j++) { + if (numbers[i] == numbers[j]) { + conflicts += 1; + } + } + } + + // allow 5 % of conflicts + return conflicts <= 50 ? 0 : 1; +} + +int main(void) +{ + plan_lazy(); + + dnssec_crypto_init(); + + // quite stupid, just check if it does something + + ok(check_buffer() == 0, "dnssec_random_buffer()"); + ok(check_random_type() == 0, "dnssec_random_uint16_t()"); + + dnssec_crypto_cleanup(); + + return 0; +} diff --git a/tests/libdnssec/test_shared_bignum.c b/tests/libdnssec/test_shared_bignum.c new file mode 100644 index 0000000..6571d90 --- /dev/null +++ b/tests/libdnssec/test_shared_bignum.c @@ -0,0 +1,128 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <string.h> + +#include "bignum.c" +#include "binary.h" + +#define bin_init(array) { .data = array, .size = sizeof(array) } + +#define test_size(value, usize, ssize, msg) \ + dnssec_binary_t __bin = bin_init(value); \ + is_int(usize, bignum_size_u(&__bin), "bignum_size_u, " msg); \ + is_int(ssize, bignum_size_s(&__bin), "bignum_size_s, " msg) + +#define test_write(num, expect, msg) \ + uint8_t __buffer[sizeof(expect)]; \ + memset(__buffer, 0xaa, sizeof(__buffer)); \ + wire_ctx_t __ctx = wire_ctx_init(__buffer, sizeof(expect)); \ + dnssec_binary_t __num = bin_init(num); \ + dnssec_binary_t __exp = bin_init(expect); \ + bignum_write(&__ctx, sizeof(expect), &__num); \ + dnssec_binary_t __dst = bin_init(__buffer); \ + ok(dnssec_binary_cmp(&__dst, &__exp) == 0, "bignum_write, " msg) + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + { + uint8_t num[] = { }; + test_size(num, 1, 1, "empty string"); + } + + { + uint8_t num[] = { 0x00 }; + test_size(num, 1, 1, "zero"); + } + + { + uint8_t num[] = { 0x00, 0x00, 0x00 }; + test_size(num, 1, 1, "long zero"); + } + + { + uint8_t num[] = { 0x01, 0x02, 0x03 }; + test_size(num, 3, 3, "no MSB"); + } + + { + uint8_t num[] = { 0x7f, 0xff, 0x00, 0x00, 0x00 }; + test_size(num, 5, 5, "no MSB but all other bits"); + } + + { + uint8_t num[] = { 0x84, 0x42 }; + test_size(num, 2, 3, "MSB"); + } + + { + uint8_t num[] = { 0x00, 0x84, 0x42 }; + test_size(num, 2, 3, "MSB and leading zero"); + } + + { + uint8_t num[] = { 0x00, 0x00, 0x00, 0x00, 0xfc, 0xe1, 0xda }; + test_size(num, 3, 4, "MSB, many leading zeroes"); + } + + { + uint8_t num[] = { 0x00, 0x00, 0x00, 0x01 }; + test_size(num, 1, 1, "no MSB, many leading zeroes"); + } + + // test writing + + { + uint8_t num[] = { }; + uint8_t exp[] = { 0x00 }; + test_write(num, exp, "empty string"); + } + + { + uint8_t num[] = { 0x00 }; + uint8_t exp[] = { 0x00 }; + test_write(num, exp, "zero"); + } + + { + uint8_t num[] = { 0x11, 0x22, 0x33 }; + uint8_t exp[] = { 0x00, 0x00, 0x00, 0x11, 0x22, 0x33 }; + test_write(num, exp, "no MSB, right-aligned"); + } + + { + uint8_t num[] = { 0xff, 0xee, 0xdd }; + uint8_t exp[] = { 0x00, 0x00, 0x00, 0xff, 0xee, 0xdd }; + test_write(num, exp, "MSB, right-aligned"); + } + + { + uint8_t num[] = { 0x11, 0x22, 0x33 }; + uint8_t exp[] = { 0x11, 0x22, 0x33 }; + test_write(num, exp, "no MSB, fitting exactly"); + } + + { + uint8_t num[] = { 0xff, 0xee, 0xdd }; + uint8_t exp[] = { 0xff, 0xee, 0xdd }; + test_write(num, exp, "MSB, fitting exactly"); + } + + return 0; +} diff --git a/tests/libdnssec/test_shared_dname.c b/tests/libdnssec/test_shared_dname.c new file mode 100644 index 0000000..c3d8fd2 --- /dev/null +++ b/tests/libdnssec/test_shared_dname.c @@ -0,0 +1,79 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <string.h> +#include <tap/basic.h> + +#include "dname.c" + +static void ok_length(const char *dname, size_t length, const char *info) +{ + ok(dname_length((uint8_t *)dname) == length, + "dname_length() for %s", info); +} + +static void test_length(void) +{ + ok_length(NULL, 0, "NULL"); + ok_length("", 1, "."); + ok_length("\x2""cz", 4, "cz."); + ok_length("\x7""example""\x3""com", 13, "example.com."); +} + +static bool dname_binary_equal(const uint8_t *one, const uint8_t *two) +{ + return one && two && strcmp((char *)one, (char *)two) == 0; +} + +static void test_copy(void) +{ + const uint8_t *dname = (uint8_t *)"\x3""www""\x8""KNOT-DNS""\x2""cz"; + uint8_t *copy = dname_copy(dname); + ok(dname_binary_equal(dname, copy), "dname_copy()"); + free(copy); +} + +static void test_equal(void) +{ + #define eq(a, b) dname_equal((uint8_t *)a, (uint8_t *)b) + + ok(eq("\x4""kiwi""\x4""limo", "\x4""kiwi""\x4""limo") == true, + "dname_equal() same"); + ok(eq("\x6""orange", "\x6""ORANGE") == true, + "dname_equal() case single label"); + ok(eq("\x6""Banana""\03""Tea", "\x6""bANAna""\x3""tea") == true, + "dname_equal() case two labels"); + ok(eq("\x4""Coco""\x4""MILK", "\x3""cow""\x4""milk") == false, + "dname_equal() different first"); + ok(eq("\x4""LIME""\x5""syrup", "\x4""LIme""\x4""beer") == false, + "dname_equal() different last"); + ok(eq("\x5""apple", "\x5""apple""\x5""shake") == false, + "dname_equal() a prefix of b"); + ok(eq("\x5""apple""\x5""juice", "\x5""apple") == false, + "dname_equal() b prefix of a"); +} + +int main(void) +{ + plan_lazy(); + + test_length(); + test_copy(); + test_equal(); + + return 0; +} diff --git a/tests/libdnssec/test_sign.c b/tests/libdnssec/test_sign.c new file mode 100644 index 0000000..8f57a41 --- /dev/null +++ b/tests/libdnssec/test_sign.c @@ -0,0 +1,203 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <tap/basic.h> + +#include "sample_keys.h" + +#include "binary.h" +#include "crypto.h" +#include "error.h" +#include "key.h" +#include "sign.h" + +static const dnssec_binary_t input_data = { + .size = 25, + .data = (uint8_t *)"Very good, young padawan." +}; + +static const dnssec_binary_t signed_rsa = { .size = 128, .data = (uint8_t []) { + 0x21, 0xba, 0xff, 0x0c, 0x15, 0x10, 0x73, 0x25, 0xa7, 0x8e, + 0xf4, 0x71, 0x4b, 0xd3, 0x97, 0x6d, 0x95, 0x52, 0xc2, 0x0b, + 0x43, 0xb3, 0x7d, 0x82, 0xe4, 0x3e, 0x2a, 0xc3, 0xb7, 0x17, + 0x5b, 0x05, 0xe9, 0x1e, 0x13, 0xac, 0x27, 0x6f, 0x20, 0x93, + 0x1a, 0xeb, 0xe2, 0x2c, 0x72, 0x70, 0x14, 0xe6, 0x49, 0xa7, + 0x62, 0xdd, 0x4c, 0x72, 0x1e, 0x1d, 0xd8, 0xf9, 0xba, 0xbc, + 0x96, 0x0e, 0xc3, 0xd4, 0xc1, 0x8f, 0x95, 0xdb, 0x01, 0x18, + 0x24, 0x43, 0xbd, 0x2b, 0x52, 0x9b, 0x10, 0x1f, 0xba, 0x0a, + 0x76, 0xbe, 0x0e, 0xaa, 0x91, 0x27, 0x7b, 0x9f, 0xed, 0x5a, + 0xad, 0x96, 0x1a, 0x02, 0x97, 0x42, 0x91, 0x30, 0x03, 0x2b, + 0x5c, 0xb8, 0xcc, 0x6b, 0xcf, 0x39, 0x62, 0x5e, 0x47, 0xae, + 0x6d, 0x5b, 0x43, 0xd2, 0xc2, 0xd8, 0x22, 0x5d, 0xf5, 0x5e, + 0x0a, 0x97, 0x65, 0x41, 0xc7, 0xaa, 0x28, 0x67, +}}; + +static const dnssec_binary_t signed_ecdsa = { .size = 64, .data = (uint8_t []) { + 0xa2, 0x95, 0x76, 0xb5, 0xf5, 0x7e, 0xbd, 0xdd, 0xf5, 0x62, + 0xa2, 0xc3, 0xa4, 0x8d, 0xd4, 0x53, 0x5c, 0xba, 0x29, 0x71, + 0x8c, 0xcc, 0x28, 0x7b, 0x58, 0xf3, 0x1e, 0x4e, 0x58, 0xe2, + 0x36, 0x7e, + 0xa0, 0x1a, 0xb6, 0xe6, 0x29, 0x71, 0x1b, 0xd3, 0x8c, 0x88, + 0xc3, 0xee, 0x12, 0x0e, 0x69, 0x70, 0x55, 0x99, 0xec, 0xd5, + 0xf6, 0x4f, 0x4b, 0xe2, 0x41, 0xd9, 0x10, 0x7e, 0x67, 0xe5, + 0xad, 0x2f, +}}; + +#ifdef HAVE_ED25519 +static const dnssec_binary_t signed_ed25519 = { .size = 64, .data = (uint8_t []) { + 0x0a, 0x9e, 0x51, 0x5f, 0x16, 0x89, 0x49, 0x27, + 0x0e, 0x98, 0x34, 0xd3, 0x48, 0xef, 0x5a, 0x6e, + 0x85, 0x2f, 0x7c, 0xd6, 0xd7, 0xc8, 0xd0, 0xf4, + 0x2c, 0x68, 0x8c, 0x1f, 0xf7, 0xdf, 0xeb, 0x7c, + 0x25, 0xd6, 0x1a, 0x76, 0x3e, 0xaf, 0x28, 0x1f, + 0x1d, 0x08, 0x10, 0x20, 0x1c, 0x01, 0x77, 0x1b, + 0x5a, 0x48, 0xd6, 0xe5, 0x1c, 0xf9, 0xe3, 0xe0, + 0x70, 0x34, 0x5e, 0x02, 0x49, 0xfb, 0x9e, 0x05, + }}; +#endif + +#ifdef HAVE_ED448 +static const dnssec_binary_t signed_ed448 = { .size = 114, .data = (uint8_t []) { + 0x8d, 0x79, 0x27, 0xbd, 0xe2, 0xc4, 0x23, 0xd8, 0x26, 0xc1, 0xd4, 0xab, + 0x6a, 0x0d, 0xdf, 0xe5, 0x5c, 0xf1, 0x8d, 0x3f, 0x1b, 0x13, 0x81, 0x94, + 0xb2, 0x2d, 0xf0, 0x94, 0x58, 0x38, 0x6c, 0xf7, 0xe8, 0xc0, 0x92, 0xab, + 0x33, 0x1f, 0x1c, 0xe8, 0x18, 0x3f, 0xab, 0x24, 0x41, 0x10, 0xf7, 0x04, + 0xf5, 0x81, 0x68, 0x0d, 0x0c, 0x38, 0x8d, 0xd6, 0x80, 0xb4, 0x6b, 0xe8, + 0x65, 0xc1, 0xce, 0x73, 0xc7, 0x54, 0x20, 0x32, 0x21, 0x7c, 0x63, 0x5e, + 0x55, 0xe0, 0xdf, 0x2b, 0xdd, 0xd7, 0xd1, 0x82, 0xe0, 0x41, 0x75, 0xd4, + 0xe9, 0xb9, 0x76, 0xb8, 0xa6, 0xa9, 0x0a, 0x4f, 0x18, 0xe1, 0x62, 0x27, + 0x74, 0x99, 0x01, 0x98, 0x5f, 0xdb, 0xea, 0xdf, 0xab, 0x59, 0x6c, 0x79, + 0xe2, 0xc2, 0x2a, 0x91, 0x29, 0x00 + }}; +#endif + +static dnssec_binary_t binary_set_string(char *str) +{ + dnssec_binary_t result = { .data = (uint8_t *)str, .size = strlen(str) }; + return result; +} + +static void check_key(const key_parameters_t *key_data, const dnssec_binary_t *data, + const dnssec_binary_t *signature, bool signature_match) +{ + int r; + + // initialize key from public parameters + + dnssec_key_t *key = NULL; + r = dnssec_key_new(&key); + ok(r == DNSSEC_EOK && key != NULL, "create key"); + r = dnssec_key_set_rdata(key, &key_data->rdata); + ok(r == DNSSEC_EOK, "set RDATA"); + + // check validation on static signature + + dnssec_sign_ctx_t *ctx = NULL; + r = dnssec_sign_new(&ctx, key); + ok(r == DNSSEC_EOK, "create signing context"); + r = dnssec_sign_add(ctx, data); + ok(r == DNSSEC_EOK, "add data to be signed"); + r = dnssec_sign_verify(ctx, false, signature); + ok(r == DNSSEC_EOK, "signature verified"); + + // create new signature and self-validate + + r = dnssec_key_load_pkcs8(key, &key_data->pem); + ok(r == DNSSEC_EOK, "load private key"); + + if (signature_match) { + r = dnssec_sign_init(ctx); + ok(r == DNSSEC_EOK, "reinitialize context"); + r = dnssec_sign_add(ctx, data); + ok(r == DNSSEC_EOK, "add data to be signed"); + dnssec_binary_t new_signature = { 0 }; + r = dnssec_sign_write(ctx, DNSSEC_SIGN_NORMAL, &new_signature); + ok(r == DNSSEC_EOK, "write the signature"); + ok(dnssec_binary_cmp(signature, &new_signature) == 0, + "signature exact match"); + r = dnssec_sign_verify(ctx, false, &new_signature); + ok(r == DNSSEC_EOK, "reverify the new signature"); + dnssec_binary_free(&new_signature); + } + + // context reinitialization + + dnssec_binary_t tmp = { 0 }; + + r = dnssec_sign_init(ctx); + ok(r == DNSSEC_EOK, "reinitialize context"); + + tmp = binary_set_string("bind"); + r = dnssec_sign_add(ctx, &tmp); + ok(r == DNSSEC_EOK, "add data (1)"); + + r = dnssec_sign_init(ctx); + ok(r == DNSSEC_EOK, "reinitialize context"); + + tmp = binary_set_string("knot"); + r = dnssec_sign_add(ctx, &tmp); + ok(r == DNSSEC_EOK, "add data (2)"); + + tmp = binary_set_string(" is the best"); + r = dnssec_sign_add(ctx, &tmp); + ok(r == DNSSEC_EOK, "add data (3)"); + + dnssec_binary_t new_signature = { 0 }; + r = dnssec_sign_write(ctx, DNSSEC_SIGN_NORMAL, &new_signature); + ok(r == DNSSEC_EOK, "write signature"); + + r = dnssec_sign_init(ctx); + ok(r == DNSSEC_EOK, "reinitialize context"); + + tmp = binary_set_string("knot is the best"); + r = dnssec_sign_add(ctx, &tmp); + ok(r == DNSSEC_EOK, "add data (4)"); + + r = dnssec_sign_verify(ctx, false, &new_signature); + ok(r == DNSSEC_EOK, "verify signature"); + + dnssec_binary_free(&new_signature); + + // cleanup + + dnssec_sign_free(ctx); + dnssec_key_free(key); +} + +int main(void) +{ + plan_lazy(); + + dnssec_crypto_init(); + + diag("RSA signing"); + check_key(&SAMPLE_RSA_KEY, &input_data, &signed_rsa, true); + diag("ECDSA signing"); + check_key(&SAMPLE_ECDSA_KEY, &input_data, &signed_ecdsa, false); +#ifdef HAVE_ED25519 + diag("ED25519 signing"); + check_key(&SAMPLE_ED25519_KEY, &input_data, &signed_ed25519, true); +#endif +#ifdef HAVE_ED448 + diag("ED448 signing"); + check_key(&SAMPLE_ED448_KEY, &input_data, &signed_ed448, true); +#endif + + dnssec_crypto_cleanup(); + + return 0; +} diff --git a/tests/libdnssec/test_sign_der.c b/tests/libdnssec/test_sign_der.c new file mode 100644 index 0000000..18745a9 --- /dev/null +++ b/tests/libdnssec/test_sign_der.c @@ -0,0 +1,203 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <stdint.h> +#include <string.h> +#include <stdbool.h> + +#include "bignum.c" +#include "binary.h" +#include "error.h" +#include "sign/der.c" + +static int binary_eq(const dnssec_binary_t *a, const dnssec_binary_t *b) +{ + return a && b && + a->size == b->size && + memcmp(a->data, b->data, a->size) == 0; +} + +#define DECODE_OK(der, r, s, message) \ + dnssec_binary_t __der = { .data = der, .size = sizeof(der) }; \ + dnssec_binary_t __r = { .data = r, .size = sizeof(r) }; \ + dnssec_binary_t __s = { .data = s, .size = sizeof(s) }; \ + dnssec_binary_t __out_s = { 0 }; \ + dnssec_binary_t __out_r = { 0 }; \ + int _result = dss_sig_value_decode(&__der, &__out_r, &__out_s); \ + ok(_result == DNSSEC_EOK && \ + binary_eq(&__r, &__out_r) && \ + binary_eq(&__s, &__out_s), \ + "decode ok, " message) + +#define DECODE_FAIL(der, message) \ + dnssec_binary_t __der = { .data = der, .size = sizeof(der) }; \ + dnssec_binary_t __out_r = { 0 }; \ + dnssec_binary_t __out_s = { 0 }; \ + int _result = dss_sig_value_decode(&__der, &__out_r, &__out_s); \ + ok(_result != DNSSEC_EOK, \ + "decode fail, " message) + +#define ENCODE_OK(r, s, der, message) \ + dnssec_binary_t __r = { .data = r, .size = sizeof(r) }; \ + dnssec_binary_t __s = { .data = s, .size = sizeof(s) }; \ + dnssec_binary_t __der = { .data = der, .size = sizeof(der) }; \ + dnssec_binary_t __out_der = { 0 }; \ + int _result = dss_sig_value_encode(&__r, &__s, &__out_der); \ + ok(_result == DNSSEC_EOK && \ + binary_eq(&__der, &__out_der), \ + "encode ok, " message); \ + dnssec_binary_free(&__out_der) + +#define ENCODE_FAIL(r, s, message) \ + dnssec_binary_t __r = { .data = r, .size = sizeof(r) }; \ + dnssec_binary_t __s = { .data = s, .size = sizeof(s) }; \ + dnssec_binary_t __out_der = { 0 }; \ + int _result = dss_sig_value_encode(&__r, &__s, &__out_der); \ + ok(_result != DNSSEC_EOK, \ + "encode fail, " message); \ + dnssec_binary_free(&__out_der) + +#define ONE_64_TIMES \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, \ + 0x01,0x01,0x01,0x01 + +#define ONE_128_TIMES \ + ONE_64_TIMES, ONE_64_TIMES + +int main(void) +{ + plan_lazy(); + + { + uint8_t der[] = { 0x30,0x08, 0x02,0x02,0x1a,0x2b, 0x02,0x02,0x3c,0x4d }; + uint8_t r[] = { 0x1a, 0x2b }; + uint8_t s[] = { 0x3c, 0x4d }; + DECODE_OK(der, r, s, "simple without MSB"); + } + + { + uint8_t der[] = { 0x30,0x08, 0x02,0x02,0xff,0xff, 0x02,0x02,0x80,0x00 }; + uint8_t r[] = { 0xff, 0xff }; + uint8_t s[] = { 0x80, 0x00 }; + DECODE_OK(der, r, s, "simple with MSB"); + } + + { + uint8_t der[] = { 0x30,0x09, 0x02,0x04,0x00,0x00,0x00,0xfa, 0x02,0x01,0x07 }; + uint8_t r[] = { 0xfa }; + uint8_t s[] = { 0x07 }; + DECODE_OK(der, r, s, "leading zeros"); + } + + { + uint8_t der[] = { 0x30,0x07, 0x02,0x01,0x00, 0x02,0x02,0x00,0x00 }; + uint8_t r[] = { 0x00 }; + uint8_t s[] = { 0x00 }; + DECODE_OK(der, r, s, "zero values" ); + } + + { + uint8_t der[] = { }; + DECODE_FAIL(der, "empty input"); + } + + { + uint8_t der[] = { 0x30,0x04, 0x02,0x01,0x01 }; + DECODE_FAIL(der, "partial sequence"); + } + + { + uint8_t der[] = { 0x30,0x06, 0x02,0x01,0x01, 0x02,0x02,0x01 }; + DECODE_FAIL(der, "partial integer"); + } + + { + uint8_t der[] = { 0x30,0x00 }; + DECODE_FAIL(der, "zero-length sequence"); + } + + { + uint8_t der[] = { 0x30,0x05, 0x02,0x01,0xff, 0x02,0x00 }; + DECODE_FAIL(der, "zero-length integer"); + } + + { + uint8_t der[] = { 0x30,0x84, 0x02,0x40,ONE_64_TIMES, 0x02,0x40,ONE_64_TIMES }; + DECODE_FAIL(der, "unsupported size"); + } + + { + uint8_t r[] = { 0x01, }; + uint8_t s[] = { 0x02,0x03 }; + uint8_t der[] = { 0x30,0x07, 0x02,0x01,0x01, 0x02,0x02,0x02,0x03 }; + ENCODE_OK(r, s, der, "simple"); + } + + { + uint8_t r[] = { 0x00,0x01, }; + uint8_t s[] = { 0x00,0x00,0x02,0x03 }; + uint8_t der[] = { 0x30,0x07, 0x02,0x01,0x01, 0x02,0x02,0x02,0x03 }; + ENCODE_OK(r, s, der, "unnecessary leading zeros"); + } + + { + uint8_t r[] = { 0x00,0x8f }; + uint8_t s[] = { 0x00,0x00,0xff }; + uint8_t der[] = { 0x30,0x08, 0x02,0x02,0x00,0x8f, 0x02,0x02,0x00,0xff }; + ENCODE_OK(r, s, der, "required zero not removed"); + } + + { + uint8_t r[] = { 0x8c }; + uint8_t s[] = { 0xff,0xee }; + uint8_t der[] = { 0x30,0x09, 0x02,0x02,0x00,0x8c, 0x02,0x03,0x00,0xff,0xee }; + ENCODE_OK(r, s, der, "implicitly added zero"); + } + + { + uint8_t r[] = { 0x00 }; + uint8_t s[] = { 0x00,0x00 }; + uint8_t der[] = { 0x30,0x06, 0x02,0x01,0x00, 0x02,0x01,0x00 }; + ENCODE_OK(r, s, der, "zero"); + } + + { + uint8_t r[] = { 0x01 }; + uint8_t s[] = { }; + uint8_t der[] = { 0x30,0x06, 0x02,0x01,0x01, 0x02,0x01,0x00 }; + ENCODE_OK(r, s, der, "zero-length input"); + } + + { + uint8_t r[] = { ONE_128_TIMES }; + uint8_t s[] = { 0x01 }; + ENCODE_FAIL(r, s, "input too long"); + } + + { + uint8_t r[] = { ONE_64_TIMES }; + uint8_t s[] = { ONE_64_TIMES }; + ENCODE_FAIL(r, s, "result too long"); + } + + return 0; +} diff --git a/tests/libdnssec/test_tsig.c b/tests/libdnssec/test_tsig.c new file mode 100644 index 0000000..bddb17f --- /dev/null +++ b/tests/libdnssec/test_tsig.c @@ -0,0 +1,145 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <string.h> + +#include "binary.h" +#include "dname.c" +#include "tsig.h" + +static const dnssec_binary_t payload = { + .size = 40, + .data = (uint8_t []){ + 0xfd, 0x07, 0xca, 0x30, 0xf9, 0xff, 0x38, 0xb1, 0x32, 0x54, + 0xd1, 0x16, 0x24, 0xaa, 0x81, 0x2c, 0x97, 0xa0, 0x7a, 0xac, + 0x68, 0x7a, 0x3a, 0x60, 0xde, 0xc9, 0xf7, 0x7a, 0x5a, 0x58, + 0xff, 0xc9, 0x0c, 0xef, 0x31, 0xc7, 0x45, 0x2c, 0xee, 0x9d, + } +}; + +static const dnssec_binary_t key = { + .size = 16, + .data = (uint8_t []){ + 0xa8, 0x05, 0x9c, 0x5c, 0x20, 0xc5, 0x00, 0x22, 0x6f, 0xad, + 0xf2, 0x55, 0xdf, 0x89, 0x8a, 0x68 + } +}; + +typedef struct hmac { + int algorithm; + const char *name; + const dnssec_binary_t hmac; +} hmac_t; + +static const hmac_t HMACS[] = { + { DNSSEC_TSIG_HMAC_MD5, "md5", { .size = 16, .data = (uint8_t []) { + 0x12, 0x38, 0x17, 0x4f, 0xa9, 0xc7, 0x5b, 0xcf, 0xd7, 0x08, + 0x19, 0x97, 0xf9, 0x3d, 0x5e, 0xe7 + }}}, + { DNSSEC_TSIG_HMAC_SHA1, "sha1", { .size = 20, .data = (uint8_t []) { + 0xb8, 0x18, 0x2a, 0x5d, 0xf8, 0x2e, 0xa0, 0xb7, 0xcc, 0xcc, + 0xed, 0xc1, 0xaa, 0x34, 0xeb, 0x92, 0x48, 0xf9, 0x65, 0x7b + }}}, + { DNSSEC_TSIG_HMAC_SHA224, "sha224", { .size = 28, .data = (uint8_t []) { + 0xb7, 0x43, 0xcd, 0x0d, 0x9d, 0x51, 0x8c, 0x61, 0xc6, 0x43, + 0x98, 0x73, 0x5c, 0x16, 0x01, 0x1b, 0xfc, 0x82, 0xe9, 0x99, + 0xc2, 0x21, 0xde, 0x16, 0xb1, 0x94, 0x2d, 0xd5 + }}}, + { DNSSEC_TSIG_HMAC_SHA256, "sha256", { .size = 32, .data = (uint8_t []) { + 0x16, 0x5e, 0xf6, 0xed, 0x9b, 0x1a, 0xe5, 0x67, 0x58, 0x7b, + 0xf1, 0x35, 0x9e, 0x59, 0xbd, 0x50, 0x6d, 0x72, 0xf8, 0x87, + 0x0e, 0x22, 0xda, 0x65, 0x00, 0xd6, 0x76, 0x91, 0xde, 0x5f, + 0xec, 0xd8 + }}}, + { DNSSEC_TSIG_HMAC_SHA384, "sha384", { .size = 48, .data = (uint8_t []) { + 0x8a, 0xcf, 0xf3, 0xb7, 0x1c, 0xbe, 0x5c, 0x3e, 0x05, 0x74, + 0x97, 0x46, 0x04, 0x79, 0x3a, 0xe7, 0x8a, 0x5b, 0x7b, 0x12, + 0xca, 0xcd, 0xf2, 0xe2, 0xdf, 0xa9, 0x17, 0xfc, 0x8e, 0x61, + 0xc5, 0x86, 0x3e, 0xdc, 0xad, 0x84, 0x9e, 0x13, 0x0d, 0xa0, + 0x04, 0xb6, 0x6f, 0x7c, 0x85, 0x1b, 0x5c, 0xdf + }}}, + { DNSSEC_TSIG_HMAC_SHA512, "sha512", { .size = 64, .data = (uint8_t []) { + 0xc3, 0x41, 0xd0, 0x96, 0x50, 0xd7, 0xf7, 0xfd, 0x59, 0x73, + 0xde, 0xd6, 0xc7, 0x4c, 0xda, 0xf1, 0x5d, 0xe1, 0x59, 0x34, + 0x79, 0xdc, 0x93, 0x23, 0xcb, 0xf2, 0x1f, 0x25, 0x4e, 0x35, + 0xb0, 0xd0, 0x9f, 0xfc, 0x22, 0xf1, 0xea, 0xbf, 0x9c, 0x18, + 0xd8, 0xcc, 0xcd, 0xb6, 0xb1, 0x4a, 0x06, 0x09, 0xc4, 0x3f, + 0x28, 0x93, 0x71, 0xd6, 0xca, 0xce, 0xf3, 0xa6, 0x08, 0x38, + 0xe3, 0x99, 0xc1, 0xb2 + }}}, + { 0 } +}; + +static void test_lookup_dname(const uint8_t *dname, int algorithm) +{ + dnssec_tsig_algorithm_t alg = dnssec_tsig_algorithm_from_dname(dname); + const char *name = dnssec_tsig_algorithm_to_name(algorithm); + if (name == NULL) name = "invalid"; + ok(alg == algorithm, "dnssec_tsig_algorithm_from_dname(%s)", name); + + const uint8_t *reverse = dnssec_tsig_algorithm_to_dname(algorithm); + ok((algorithm == DNSSEC_TSIG_UNKNOWN && reverse == NULL) || + (algorithm != DNSSEC_TSIG_UNKNOWN && dname_equal(reverse, dname)), + "dnssec_tsig_algorithm_to_dname(%d)", algorithm); +} + +static void test_lookup_name(const char *name, int algorithm) +{ + ok(dnssec_tsig_algorithm_from_name(name) == algorithm, + "dnssec_tsig_algorithm_from_name(%s)", name); + + const char *reverse = dnssec_tsig_algorithm_to_name(algorithm); + ok((algorithm == DNSSEC_TSIG_UNKNOWN && reverse == NULL) || + (algorithm != DNSSEC_TSIG_UNKNOWN && strcasecmp(reverse, name) == 0), + "dnssec_tsig_algorithm_to_name(%d)", algorithm); +} + +static void test_tsig_hmac(const hmac_t *params) +{ + dnssec_tsig_ctx_t *ctx = NULL; + dnssec_tsig_new(&ctx, params->algorithm, &key); + dnssec_tsig_add(ctx, &payload); + + size_t size = dnssec_tsig_size(ctx); + uint8_t hmac[size]; + dnssec_tsig_write(ctx, hmac); + dnssec_tsig_free(ctx); + + ok(size == params->hmac.size && memcmp(hmac, params->hmac.data, size) == 0, + "dnssec_tsig_write(%s)", params->name); +} + +int main(void) +{ + plan_lazy(); + + test_lookup_dname((uint8_t *)"\x08""HMAC-MD5""\x07""SIG-ALG""\x03""REG""\x03""INT", + DNSSEC_TSIG_HMAC_MD5); + test_lookup_dname((uint8_t *)"\x0B""hmac-sha224", DNSSEC_TSIG_HMAC_SHA224); + test_lookup_dname((uint8_t *)"\x06""foobar", DNSSEC_TSIG_UNKNOWN); + + test_lookup_name("hmac-md5", DNSSEC_TSIG_HMAC_MD5); + test_lookup_name("hmac-sha512", DNSSEC_TSIG_HMAC_SHA512); + test_lookup_name("barfoo", DNSSEC_TSIG_UNKNOWN); + test_lookup_name("hmac-foo", DNSSEC_TSIG_UNKNOWN); + + for (const hmac_t *h = HMACS; h->algorithm != 0; h++) { + test_tsig_hmac(h); + } + + return 0; +} diff --git a/tests/libknot/test_control.c b/tests/libknot/test_control.c new file mode 100644 index 0000000..3846f31 --- /dev/null +++ b/tests/libknot/test_control.c @@ -0,0 +1,221 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <sys/wait.h> +#include <unistd.h> +#include <tap/basic.h> +#include <tap/files.h> + +#define CTL_BUFF_SIZE 18 +#include "libknot/control/control.c" + +#define fake_ok(condition, msg, ...) \ + if (!(condition)) { \ + if (msg != NULL) { \ + printf("error: " msg "\n", ##__VA_ARGS__); \ + } \ + exit(-1); \ + } + +static void ctl_client(const char *socket, size_t argc, knot_ctl_data_t *argv) +{ + knot_ctl_t *ctl = knot_ctl_alloc(); + fake_ok(ctl != NULL, "Allocate control"); + + int ret; + for (int i = 0; i < 20; i++) { + ret = knot_ctl_connect(ctl, socket); + if (ret == KNOT_EOK) { + break; + } + usleep(100000); + } + fake_ok(ret == KNOT_EOK, "Connect to socket"); + + diag("BEGIN: Client -> Server"); + + if (argc > 0) { + for (size_t i = 0; i < argc; i++) { + if (argv[i][KNOT_CTL_IDX_CMD] != NULL && + argv[i][KNOT_CTL_IDX_CMD][0] == '\0') { + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_BLOCK, NULL); + fake_ok(ret == KNOT_EOK, "Client send data block end type"); + } else { + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_DATA, &argv[i]); + fake_ok(ret == KNOT_EOK, "Client send data %zu", i); + } + } + } + + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_END, NULL); + fake_ok(ret == KNOT_EOK, "Client send final data"); + + diag("END: Client -> Server"); + diag("BEGIN: Client <- Server"); + + size_t count = 0; + knot_ctl_data_t data; + knot_ctl_type_t type = KNOT_CTL_TYPE_DATA; + while ((ret = knot_ctl_receive(ctl, &type, &data)) == KNOT_EOK) { + if (type == KNOT_CTL_TYPE_END) { + break; + } + if (argv[count][KNOT_CTL_IDX_CMD] != NULL && + argv[count][KNOT_CTL_IDX_CMD][0] == '\0') { + fake_ok(type == KNOT_CTL_TYPE_BLOCK, "Receive block end type"); + } else { + fake_ok(type == KNOT_CTL_TYPE_DATA, "Check data type"); + for (size_t i = 0; i < KNOT_CTL_IDX__COUNT; i++) { + fake_ok((data[i] == NULL && argv[count][i] == NULL) || + (data[i] != NULL && argv[count][i] != NULL), + "Client compare input item occupation %zu", i); + if (data[i] == NULL) { + continue; + } + + fake_ok(strcmp(data[i], argv[count][i]) == 0, + "Client compare input item '%s", argv[count][i]); + } + } + count++; + } + fake_ok(ret == KNOT_EOK, "Receive OK check"); + fake_ok(type == KNOT_CTL_TYPE_END, "Receive EOF type"); + fake_ok(count == argc, "Client compare input count '%zu'", argc); + + diag("END: Client <- Server"); + + knot_ctl_close(ctl); + knot_ctl_free(ctl); +} + +static void ctl_server(const char *socket, size_t argc, knot_ctl_data_t *argv) +{ + knot_ctl_t *ctl = knot_ctl_alloc(); + ok(ctl != NULL, "Allocate control"); + + int ret = knot_ctl_bind(ctl, socket); + is_int(KNOT_EOK, ret, "Bind control socket"); + + ret = knot_ctl_accept(ctl); + is_int(KNOT_EOK, ret, "Accept a connection"); + + diag("BEGIN: Server <- Client"); + + size_t count = 0; + knot_ctl_data_t data; + knot_ctl_type_t type = KNOT_CTL_TYPE_DATA; + while ((ret = knot_ctl_receive(ctl, &type, &data)) == KNOT_EOK) { + if (type == KNOT_CTL_TYPE_END) { + break; + } + if (argv[count][KNOT_CTL_IDX_CMD] != NULL && + argv[count][KNOT_CTL_IDX_CMD][0] == '\0') { + ok(type == KNOT_CTL_TYPE_BLOCK, "Receive block end type"); + } else { + ok(type == KNOT_CTL_TYPE_DATA, "Check data type"); + for (size_t i = 0; i < KNOT_CTL_IDX__COUNT; i++) { + ok((data[i] == NULL && argv[count][i] == NULL) || + (data[i] != NULL && argv[count][i] != NULL), + "Server compare input item occupation %zu", i); + if (data[i] == NULL) { + continue; + } + + ok(strcmp(data[i], argv[count][i]) == 0, + "Server compare input item '%s", argv[count][i]); + } + } + count++; + } + is_int(KNOT_EOK, ret, "Receive OK check"); + ok(type == KNOT_CTL_TYPE_END, "Receive EOF type"); + ok(count == argc, "Server compare input count '%zu'", argc); + + diag("END: Server <- Client"); + diag("BEGIN: Server -> Client"); + + if (argc > 0) { + for (size_t i = 0; i < argc; i++) { + if (argv[i][KNOT_CTL_IDX_CMD] != NULL && + argv[i][KNOT_CTL_IDX_CMD][0] == '\0') { + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_BLOCK, NULL); + is_int(KNOT_EOK, ret, "Client send data block end type"); + } else { + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_DATA, &argv[i]); + is_int(KNOT_EOK, ret, "Server send data %zu", i); + } + } + } + + ret = knot_ctl_send(ctl, KNOT_CTL_TYPE_END, NULL); + is_int(KNOT_EOK, ret, "Server send final data"); + + diag("END: Server -> Client"); + + knot_ctl_close(ctl); + knot_ctl_unbind(ctl); + knot_ctl_free(ctl); +} + +static void test_client_server_client(void) +{ + char *socket = test_mktemp(); + ok(socket != NULL, "Make a temporary socket file '%s'", socket); + + size_t data_len = 5; + knot_ctl_data_t data[] = { + { "command", "error", "section", "item", "identifier", + "zone", "owner", "ttl", "type", "data" }, + { [KNOT_CTL_IDX_DATA] = "\x01\x02" }, + { [KNOT_CTL_IDX_CMD] = "\0" }, // This means block end in this test! + { NULL }, + { [KNOT_CTL_IDX_ERROR] = "Ultra long message" } + }; + + // Fork a client process. + pid_t child_pid = fork(); + if (child_pid == -1) { + ok(child_pid >= 0, "Process fork"); + return; + } + if (child_pid == 0) { + ctl_client(socket, data_len, data); + free(socket); + return; + } else { + ctl_server(socket, data_len, data); + } + + int status = 0; + wait(&status); + ok(WIFEXITED(status), "Wait for client"); + + test_rm_rf(socket); + free(socket); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("Client -> Server -> Client"); + test_client_server_client(); + + return 0; +} diff --git a/tests/libknot/test_cookies.c b/tests/libknot/test_cookies.c new file mode 100644 index 0000000..82ba502 --- /dev/null +++ b/tests/libknot/test_cookies.c @@ -0,0 +1,174 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> +#include <time.h> + +#include "libknot/cookies.h" +#include "libknot/endian.h" +#include "libknot/errcode.h" +#include "contrib/sockaddr.h" + +static knot_edns_cookie_t client_generate( + struct sockaddr_storage *s_addr, const uint8_t *c_secret, + const char *msg, int code, const char *ref) +{ + knot_edns_cookie_params_t params = { + .server_addr = s_addr, + }; + memcpy(params.secret, c_secret, sizeof(params.secret)); + + knot_edns_cookie_t cc; + int ret = knot_edns_cookie_client_generate(&cc, ¶ms); + is_int(code, ret, "client_generate ret: %s", msg); + if (ret == KNOT_EOK) { + ok(cc.len == KNOT_EDNS_COOKIE_CLNT_SIZE && memcmp(cc.data, ref, cc.len) == 0, + "client_generate value: %s", msg); + } + return cc; +} + +static knot_edns_cookie_t server_generate( + struct sockaddr_storage *c_addr, const uint8_t *s_secret, uint32_t timestamp, + const knot_edns_cookie_t *cc, const char *msg, int code, const char *ref) +{ + knot_edns_cookie_params_t params = { + .version = KNOT_EDNS_COOKIE_VERSION, + .timestamp = timestamp, + .client_addr = c_addr, + }; + memcpy(params.secret, s_secret, sizeof(params.secret)); + + knot_edns_cookie_t sc; + int ret = knot_edns_cookie_server_generate(&sc, cc, ¶ms); + is_int(code, ret, "server_generate ret: %s", msg); + if (ret == KNOT_EOK) { + ok(sc.len == 16 && memcmp(sc.data, ref, sc.len) == 0, + "server_generate value: %s", msg); + } + return sc; +} + +static void client_check( + struct sockaddr_storage *s_addr, const uint8_t *secret, + knot_edns_cookie_t *cc, const char *msg, int code) +{ + knot_edns_cookie_params_t params = { + .server_addr = s_addr, + }; + memcpy(params.secret, secret, sizeof(params.secret)); + + int ret = knot_edns_cookie_client_check(cc, ¶ms); + is_int(code, ret, "client_check ret: %s", msg); +} + +static void server_check( + struct sockaddr_storage *c_addr, const uint8_t *secret, + knot_edns_cookie_t *sc, knot_edns_cookie_t *cc, uint32_t timestamp, + const char *msg, int code) +{ + knot_edns_cookie_params_t params = { + .version = KNOT_EDNS_COOKIE_VERSION, + .timestamp = timestamp, + .lifetime_before = 3600, + .lifetime_after = 300, + .client_addr = c_addr, + }; + memcpy(params.secret, secret, sizeof(params.secret)); + + int ret = knot_edns_cookie_server_check(sc, cc, ¶ms); + is_int(code, ret, "server_check ret: %s", msg); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_edns_cookie_t cc; + knot_edns_cookie_t sc; + + const uint8_t c_secret1[] = "\x3F\x66\x51\xC9\x81\xC1\xD7\x3E\x58\x79\x25\xD2\xF9\x98\x5F\x08"; + const uint8_t c_secret2[] = "\x4C\x31\x15\x17\xFA\xB6\xBF\xE2\xE1\x49\xAB\x74\xEC\x1B\xC9\xA0"; + const uint8_t s_secret1[] = "\xE5\xE9\x73\xE5\xA6\xB2\xA4\x3F\x48\xE7\xDC\x84\x9E\x37\xBF\xCF"; + + struct sockaddr_storage c4_sa1 = { 0 }; + struct sockaddr_storage c4_sa2 = { 0 }; + struct sockaddr_storage s4_sa = { 0 }; + sockaddr_set(&c4_sa1, AF_INET, "198.51.100.100", 0); + sockaddr_set(&c4_sa2, AF_INET, "203.0.113.203", 0); + sockaddr_set(&s4_sa, AF_INET, "192.0.2.53", 0); + + struct sockaddr_storage c6_sa = { 0 }; + struct sockaddr_storage s6_sa = { 0 }; + sockaddr_set(&c6_sa, AF_INET6, "2001:db8:220:1:59de:d0f4:8769:82b8", 0); + sockaddr_set(&s6_sa, AF_INET6, "2001:db8:8f::53", 0); + + const uint8_t c_secret6[] = "\x3B\x49\x5B\xA6\xA5\xB7\xFD\x87\x73\x5B\xD5\x8F\x1E\xF7\x26\x1D"; + const uint8_t s_secret6[] = "\xDD\x3B\xDF\x93\x44\xB6\x78\xB1\x85\xA6\xF5\xCB\x60\xFC\xA7\x15"; + const uint8_t s_secret7[] = "\x44\x55\x36\xBC\xD2\x51\x32\x98\x07\x5A\x5D\x37\x96\x63\xC9\x62"; + + // Learning a new Server Cookie + + cc = client_generate(&s4_sa, c_secret1, "IPv4", KNOT_EOK, + "\x24\x64\xC4\xAB\xCF\x10\xC9\x57"); + client_check(&s4_sa, c_secret1, &cc, "IPv4", KNOT_EOK); + sc = server_generate(&c4_sa1, s_secret1, 1559731985, &cc, "IPv4", KNOT_EOK, + "\x01\x00\x00\x00\x5C\xF7\x9F\x11\x1F\x81\x30\xC3\xEE\xE2\x94\x80"); + server_check(&c4_sa1, s_secret1, &sc, &cc, 1559731985, "IPv4", KNOT_EOK); + + // The same client learning a renewed (fresh) Server Cookie + + server_generate(&c4_sa1, s_secret1, 1559734385, &cc, "IPv4", KNOT_EOK, + "\x01\x00\x00\x00\x5C\xF7\xA8\x71\xD4\xA5\x64\xA1\x44\x2A\xCA\x77"); + + // Another client learning a renewed Server Cookie + + cc = client_generate(&s4_sa, c_secret2, "IPv4", KNOT_EOK, + "\xFC\x93\xFC\x62\x80\x7D\xDB\x86"); + char *sc_reserved = "\x01\xAB\xCD\xEF\x5C\xF7\x8F\x71\xA3\x14\x22\x7B\x66\x79\xEB\xF5"; + memcpy(sc.data, sc_reserved, strlen(sc_reserved)); + server_check(&c4_sa2, s_secret1, &sc, &cc, 1559727985, "IPv4", KNOT_EOK); + + // Version check + + sc.data[0] = 10; + server_check(&c4_sa2, s_secret1, &sc, &cc, 1559727985, "version", KNOT_ENOTSUP); + + // IPv6 query with rolled over secret + + cc = client_generate(&s6_sa, c_secret6, "IPv6", KNOT_EOK, + "\x22\x68\x1A\xB9\x7D\x52\xC2\x98"); + client_check(&s6_sa, c_secret6, &cc, "IPv6", KNOT_EOK); + sc = server_generate(&c6_sa, s_secret6, 1559741817, &cc, "IPv6", KNOT_EOK, + "\x01\x00\x00\x00\x5C\xF7\xC5\x79\x26\x55\x6B\xD0\x93\x4C\x72\xF8"); + server_check(&c6_sa, s_secret6, &sc, &cc, 1559741961, "IPv6", KNOT_EOK); + sc = server_generate(&c6_sa, s_secret7, 1559741961, &cc, "IPv6", KNOT_EOK, + "\x01\x00\x00\x00\x5C\xF7\xC6\x09\xA6\xBB\x79\xD1\x66\x25\x50\x7A"); + + // Past lifetime check + + server_check(&c6_sa, s_secret7, &sc, &cc, 1559741961 + 3600, "last old", KNOT_EOK); + server_check(&c6_sa, s_secret7, &sc, &cc, 1559741961 + 3601, "too old", KNOT_ERANGE); + + // Future lifetime check + + server_check(&c6_sa, s_secret7, &sc, &cc, 1559741961 - 300, "last new", KNOT_EOK); + server_check(&c6_sa, s_secret7, &sc, &cc, 1559741961 - 301, "too new", KNOT_ERANGE); + + return 0; +} diff --git a/tests/libknot/test_db.c b/tests/libknot/test_db.c new file mode 100644 index 0000000..e409ad8 --- /dev/null +++ b/tests/libknot/test_db.c @@ -0,0 +1,287 @@ +/* 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <tap/basic.h> +#include <tap/files.h> + +#include "contrib/string.h" +#include "libknot/libknot.h" +#include "contrib/mempattern.h" +#include "contrib/openbsd/strlcpy.h" +#include "contrib/ucw/mempool.h" + +/* UCW array sorting defines. */ +#define ASORT_PREFIX(X) str_key_##X +#define ASORT_KEY_TYPE char* +#define ASORT_LT(x, y) (strcmp((x), (y)) < 0) +#include "contrib/ucw/array-sort.h" + +/* Constants. */ +#define KEY_MAXLEN 64 +#define KEY_SET(key, str) key.data = (str); key.len = strlen(str) + 1 + +/*! \brief Generate random key. */ +static const char *alphabet = "abcdefghijklmn0123456789"; +static char *str_key_rand(size_t len, knot_mm_t *pool) +{ + char *s = mm_alloc(pool, len); + memset(s, 0, len); + for (unsigned i = 0; i < len - 1; ++i) { + s[i] = alphabet[rand() % strlen(alphabet)]; + } + return s; +} + +static void knot_db_test_set(unsigned nkeys, char **keys, void *opts, + const knot_db_api_t *api, knot_mm_t *pool) +{ + if (api == NULL) { + skip("API not compiled in"); + return; + } + + /* Create database */ + knot_db_t *db = NULL; + int ret = api->init(&db, pool, opts); + ok(ret == KNOT_EOK && db != NULL, "%s: create", api->name); + + /* Start WR transaction. */ + knot_db_txn_t txn; + ret = api->txn_begin(db, &txn, 0); + is_int(KNOT_EOK, ret, "%s: txn_begin(WR)", api->name); + + /* Insert keys */ + knot_db_val_t key, val; + bool passed = true; + for (unsigned i = 0; i < nkeys; ++i) { + KEY_SET(key, keys[i]); + val.len = sizeof(void*); + val.data = &key.data; + + ret = api->insert(&txn, &key, &val, 0); + if (ret != KNOT_EOK && ret != KNOT_EEXIST) { + passed = false; + break; + } + } + ok(passed, "%s: insert", api->name); + + /* Commit WR transaction. */ + ret = api->txn_commit(&txn); + is_int(KNOT_EOK, ret, "%s: txn_commit(WR)", api->name); + + /* Start RD transaction. */ + ret = api->txn_begin(db, &txn, KNOT_DB_RDONLY); + is_int(KNOT_EOK, ret, "%s: txn_begin(RD)", api->name); + + /* Lookup all keys */ + passed = true; + for (unsigned i = 0; i < nkeys; ++i) { + KEY_SET(key, keys[i]); + + ret = api->find(&txn, &key, &val, 0); + if (ret != KNOT_EOK) { + passed = false; + break; + } + + const char **stored_key = val.data; + if (strcmp(*stored_key, keys[i]) != 0) { + diag("%s: mismatch on element '%u'", api->name, i); + passed = false; + break; + } + } + ok(passed, "%s: lookup all keys", api->name); + + /* Fetch dataset size. */ + int db_size = api->count(&txn); + ok(db_size > 0 && db_size <= nkeys, "%s: count %d", api->name, db_size); + + /* Unsorted iteration */ + int iterated = 0; + knot_db_iter_t *it = api->iter_begin(&txn, 0); + while (it != NULL) { + ++iterated; + it = api->iter_next(it); + } + api->iter_finish(it); + is_int(db_size, iterated, "%s: unsorted iteration", api->name); + + /* Sorted iteration. */ + char first_key[KEY_MAXLEN] = { '\0' }; + char second_key[KEY_MAXLEN] = { '\0' }; + char last_key[KEY_MAXLEN] = { '\0' }; + char key_buf[KEY_MAXLEN] = {'\0'}; + iterated = 0; + memset(&key, 0, sizeof(key)); + it = api->iter_begin(&txn, KNOT_DB_SORTED); + while (it != NULL) { + api->iter_key(it, &key); + if (iterated > 0) { /* Only if previous exists. */ + if (strcmp(key_buf, key.data) > 0) { + diag("%s: iter_sort '%s' <= '%s' FAIL\n", + api->name, key_buf, (const char *)key.data); + break; + } + if (iterated == 1) { + memcpy(second_key, key.data, key.len); + } + } else { + memcpy(first_key, key.data, key.len); + } + ++iterated; + memcpy(key_buf, key.data, key.len); + it = api->iter_next(it); + } + strlcpy(last_key, key_buf, sizeof(last_key)); + is_int(db_size, iterated, "%s: sorted iteration", api->name); + api->iter_finish(it); + + /* Interactive iteration. */ + it = api->iter_begin(&txn, KNOT_DB_NOOP); + if (it != NULL) { /* If supported. */ + ret = 0; + /* Check if first and last keys are reachable */ + it = api->iter_seek(it, NULL, KNOT_DB_FIRST); + ret += api->iter_key(it, &key); + is_string(first_key, key.data, "%s: iter_set(FIRST)", api->name); + /* Check left/right iteration. */ + it = api->iter_seek(it, &key, KNOT_DB_NEXT); + ret += api->iter_key(it, &key); + is_string(second_key, key.data, "%s: iter_set(NEXT)", api->name); + it = api->iter_seek(it, &key, KNOT_DB_PREV); + ret += api->iter_key(it, &key); + is_string(first_key, key.data, "%s: iter_set(PREV)", api->name); + it = api->iter_seek(it, &key, KNOT_DB_LAST); + ret += api->iter_key(it, &key); + is_string(last_key, key.data, "%s: iter_set(LAST)", api->name); + /* Check if prev(last_key + 1) is the last_key */ + strlcpy(key_buf, last_key, sizeof(key_buf)); + key_buf[0] += 1; + KEY_SET(key, key_buf); + it = api->iter_seek(it, &key, KNOT_DB_LEQ); + ret += api->iter_key(it, &key); + is_string(last_key, key.data, "%s: iter_set(LEQ)", api->name); + /* Check if next(first_key - 1) is the first_key */ + strlcpy(key_buf, first_key, sizeof(key_buf)); + key_buf[0] -= 1; + KEY_SET(key, key_buf); + it = api->iter_seek(it, &key, KNOT_DB_GEQ); + ret += api->iter_key(it, &key); + is_string(first_key, key.data, "%s: iter_set(GEQ)", api->name); + api->iter_finish(it); + is_int(ret, 0, "%s: iter_* error codes", api->name); + } + api->txn_abort(&txn); + + /* Deleting during iteration. */ + const uint8_t DEL_MAX_CNT = 3; + api->txn_begin(db, &txn, 0); + api->clear(&txn); + for (uint8_t i = 0; i < DEL_MAX_CNT; ++i) { + key.data = &i; + key.len = sizeof(i); + val.data = NULL; + val.len = 0; + + ret = api->insert(&txn, &key, &val, 0); + is_int(KNOT_EOK, ret, "%s: add key '%u'", api->name, i); + } + it = api->iter_begin(&txn, KNOT_DB_NOOP); + if (it != NULL) { /* If supported. */ + is_int(DEL_MAX_CNT, api->count(&txn), "%s: key count before", api->name); + it = api->iter_seek(it, NULL, KNOT_DB_FIRST); + uint8_t pos = 0; + while (it != NULL) { + ret = api->iter_key(it, &key); + is_int(KNOT_EOK, ret, "%s: iter key before del", api->name); + is_int(pos, ((uint8_t *)(key.data))[0], "%s: iter compare key '%u'", + api->name, pos); + + ret = knot_db_lmdb_iter_del(it); + is_int(KNOT_EOK, ret, "%s: iter del", api->name); + + it = api->iter_next(it); + + ret = api->iter_key(it, &key); + if (++pos < DEL_MAX_CNT) { + is_int(KNOT_EOK, ret, "%s: iter key after del", api->name); + is_int(pos, ((uint8_t *)key.data)[0], "%s: iter compare key '%u", + api->name, pos); + } else { + is_int(KNOT_EINVAL, ret, "%s: iter key after del", api->name); + } + } + api->iter_finish(it); + is_int(0, api->count(&txn), "%s: key count after", api->name); + } + api->txn_abort(&txn); + + /* Clear database and recheck. */ + ret = api->txn_begin(db, &txn, 0); + ret += api->clear(&txn); + ret += api->txn_commit(&txn); + is_int(0, ret, "%s: clear()", api->name); + + /* Check if the database is empty. */ + api->txn_begin(db, &txn, KNOT_DB_RDONLY); + db_size = api->count(&txn); + is_int(0, db_size, "%s: count after clear = %d", api->name, db_size); + api->txn_abort(&txn); + + api->deinit(db); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_mm_t pool; + mm_ctx_mempool(&pool, MM_DEFAULT_BLKSIZE); + + char *dbid = test_mkdtemp(); + ok(dbid != NULL, "make temporary directory"); + + /* Random keys. */ + unsigned nkeys = 10000; + char **keys = mm_alloc(&pool, sizeof(char*) * nkeys); + for (unsigned i = 0; i < nkeys; ++i) { + keys[i] = str_key_rand(KEY_MAXLEN, &pool); + } + + /* Sort random keys. */ + str_key_sort(keys, nkeys); + + /* Execute test set for all backends. */ + struct knot_db_lmdb_opts lmdb_opts = KNOT_DB_LMDB_OPTS_INITIALIZER; + lmdb_opts.path = dbid; + struct knot_db_trie_opts trie_opts = KNOT_DB_TRIE_OPTS_INITIALIZER; + knot_db_test_set(nkeys, keys, &lmdb_opts, knot_db_lmdb_api(), &pool); + knot_db_test_set(nkeys, keys, &trie_opts, knot_db_trie_api(), &pool); + + /* Cleanup. */ + mp_delete(pool.ctx); + test_rm_rf(dbid); + free(dbid); + + return 0; +} diff --git a/tests/libknot/test_descriptor.c b/tests/libknot/test_descriptor.c new file mode 100644 index 0000000..8c25e2c --- /dev/null +++ b/tests/libknot/test_descriptor.c @@ -0,0 +1,361 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/descriptor.h" + +#define BUF_LEN 256 + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + const knot_rdata_descriptor_t *descr; + char name[BUF_LEN] = ""; + int ret; + uint16_t num; + + // Get descriptor, type num to string: + // 1. TYPE0 + descr = knot_get_rdata_descriptor(0); + ok(descr->type_name == 0, "get TYPE0 descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get TYPE0 descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get TYPE0 descriptor 2. item type"); + + ret = knot_rrtype_to_string(0, name, BUF_LEN); + ok(ret != -1, "get TYPE0 ret"); + ok(strcmp(name, "TYPE0") == 0, "get TYPE0 name"); + + // 2. A + descr = knot_get_rdata_descriptor(1); + ok(strcmp(descr->type_name, "A") == 0, "get A descriptor name"); + ok(descr->block_types[0] == 4, + "get A descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get A descriptor 2. item type"); + + ret = knot_rrtype_to_string(1, name, BUF_LEN); + ok(ret != -1, "get A ret"); + ok(strcmp(name, "A") == 0, "get A name"); + + // 3. CNAME + descr = knot_get_rdata_descriptor(5); + ok(strcmp(descr->type_name, "CNAME") == 0, "get CNAME descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_COMPRESSIBLE_DNAME, + "get CNAME descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get CNAME descriptor 2. item type"); + + ret = knot_rrtype_to_string(5, name, BUF_LEN); + ok(ret != -1, "get CNAME ret"); + ok(strcmp(name, "CNAME") == 0, "get CNAME name"); + + // 4. TYPE38 (A6) + descr = knot_get_rdata_descriptor(38); + ok(descr->type_name == 0, "get TYPE38 descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get TYPE38 descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get TYPE38 descriptor 2. item type"); + + ret = knot_rrtype_to_string(38, name, BUF_LEN); + ok(ret != -1, "get TYPE38 ret"); + ok(strcmp(name, "TYPE38") == 0, "get TYPE38 name"); + + // 5. ANY + descr = knot_get_rdata_descriptor(255); + ok(strcmp(descr->type_name, "ANY") == 0, "get ANY descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get ANY descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get ANY descriptor 2. item type"); + + ret = knot_rrtype_to_string(255, name, BUF_LEN); + ok(ret != -1, "get ANY ret"); + ok(strcmp(name, "ANY") == 0, "get ANY name"); + + // 6. TYPE65535 + descr = knot_get_rdata_descriptor(65535); + ok(descr->type_name == 0, "get TYPE65535 descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get TYPE65535 descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get TYPE65535 descriptor 2. item type"); + + ret = knot_rrtype_to_string(65535, name, BUF_LEN); + ok(ret != -1, "get TYPE65535 ret"); + ok(strcmp(name, "TYPE65535") == 0, "get TYPE65535 name"); + + // Class num to string: + // 7. CLASS0 + ret = knot_rrclass_to_string(0, name, BUF_LEN); + ok(ret != -1, "get CLASS0 ret"); + ok(strcmp(name, "CLASS0") == 0, "get CLASS0 name"); + + // 8. IN + ret = knot_rrclass_to_string(1, name, BUF_LEN); + ok(ret != -1, "get IN ret"); + ok(strcmp(name, "IN") == 0, "get IN name"); + + // 9. ANY + ret = knot_rrclass_to_string(255, name, BUF_LEN); + ok(ret != -1, "get ANY ret"); + ok(strcmp(name, "ANY") == 0, "get ANY name"); + + // 10. CLASS65535 + ret = knot_rrclass_to_string(65535, name, BUF_LEN); + ok(ret != -1, "get CLASS65535 ret"); + ok(strcmp(name, "CLASS65535") == 0, "get CLASS65535 name"); + + // String to type num: + // 11. A + ret = knot_rrtype_from_string("A", &num); + ok(ret != -1, "get A num ret"); + ok(num == 1, "get A num"); + + // 12. a + ret = knot_rrtype_from_string("a", &num); + ok(ret != -1, "get a num ret"); + ok(num == 1, "get a num"); + + // 13. AaAa + ret = knot_rrtype_from_string("AaAa", &num); + ok(ret != -1, "get AaAa num ret"); + ok(num == 28, "get AaAa num"); + + // 14. "" + ret = knot_rrtype_from_string("", &num); + ok(ret == -1, "get "" num ret"); + + // 15. DUMMY + ret = knot_rrtype_from_string("DUMMY", &num); + ok(ret == -1, "get DUMMY num ret"); + + // 16. TypE33 + ret = knot_rrtype_from_string("TypE33", &num); + ok(ret != -1, "get TypE33 num ret"); + ok(num == 33, "get TypE33 num"); + + // 17. TYPE + ret = knot_rrtype_from_string("TYPE", &num); + ok(ret == -1, "get TYPE num ret"); + + // 18. TYPE0 + ret = knot_rrtype_from_string("TYPE0", &num); + ok(ret != -1, "get TYPE0 num ret"); + ok(num == 0, "get TYPE0 num"); + + // 19. TYPE65535 + ret = knot_rrtype_from_string("TYPE65535", &num); + ok(ret != -1, "get TYPE65535 num ret"); + ok(num == 65535, "get TYPE65535 num"); + + // 20. TYPE65536 + ret = knot_rrtype_from_string("TYPE65536", &num); + ok(ret == -1, "get TYPE65536 num ret"); + + // String to class num: + // 21. In + ret = knot_rrclass_from_string("In", &num); + ok(ret != -1, "get In num ret"); + ok(num == 1, "get In num"); + + // 22. ANY + ret = knot_rrclass_from_string("ANY", &num); + ok(ret != -1, "get ANY num ret"); + ok(num == 255, "get ANY num"); + + // 23. "" + ret = knot_rrclass_from_string("", &num); + ok(ret == -1, "get "" num ret"); + + // 24. DUMMY + ret = knot_rrclass_from_string("DUMMY", &num); + ok(ret == -1, "get DUMMY num ret"); + + // 25. CLass33 + ret = knot_rrclass_from_string("CLass33", &num); + ok(ret != -1, "get CLass33 num ret"); + ok(num == 33, "get CLass33 num"); + + // 26. CLASS + ret = knot_rrclass_from_string("CLASS", &num); + ok(ret == -1, "get CLASS num ret"); + + // 27. CLASS0 + ret = knot_rrclass_from_string("CLASS0", &num); + ok(ret != -1, "get CLASS0 num ret"); + ok(num == 0, "get CLASS0 num"); + + // 28. CLASS65535 + ret = knot_rrclass_from_string("CLASS65535", &num); + ok(ret != -1, "get CLASS65535 num ret"); + ok(num == 65535, "get CLASS65535 num"); + + // 29. CLASS65536 + ret = knot_rrclass_from_string("CLASS65536", &num); + ok(ret == -1, "get CLASS65536 num ret"); + + // Get obsolete descriptor: + // 30. TYPE0 + descr = knot_get_obsolete_rdata_descriptor(0); + ok(descr->type_name == 0, "get TYPE0 descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get TYPE0 descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get TYPE0 descriptor 2. item type"); + + // 31. MD + descr = knot_get_obsolete_rdata_descriptor(3); + ok(strcmp(descr->type_name, "MD") == 0, "get MD descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_DECOMPRESSIBLE_DNAME, + "get A descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get A descriptor 2. item type"); + + // 32. NXT + descr = knot_get_obsolete_rdata_descriptor(30); + ok(strcmp(descr->type_name, "NXT") == 0, "get NXT descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_DECOMPRESSIBLE_DNAME, + "get CNAME descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_REMAINDER, + "get CNAME descriptor 2. item type"); + ok(descr->block_types[2] == KNOT_RDATA_WF_END, + "get CNAME descriptor 3. item type"); + + // 33. TYPE38 (A6) + descr = knot_get_obsolete_rdata_descriptor(38); + ok(descr->type_name == 0, "get TYPE38 descriptor name"); + ok(descr->block_types[0] == KNOT_RDATA_WF_REMAINDER, + "get TYPE38 descriptor 1. item type"); + ok(descr->block_types[1] == KNOT_RDATA_WF_END, + "get TYPE38 descriptor 2. item type"); + + // knot_rrtype_to_string invalid output buffer size + ret = knot_rrtype_to_string(1, NULL, 0); + ok(ret == -1, "knot_rrtype_to_string: invalid output buffer size"); + + // knot_rrclass_to_string invalid output buffer size + ret = knot_rrclass_to_string(1, NULL, 0); + ok(ret == -1, "knot_rrclass_to_string: invalid output buffer size"); + + // knot_rrtype_is_metatype + ok(knot_rrtype_is_metatype(0) == 0, + "rrtype is not metatype"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_SIG) != 0, + "rrtype is SIG"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_OPT) != 0, + "rrtype is OPT"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_TKEY) != 0, + "rrtype is TKEY"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_TSIG) != 0, + "rrtype is TSIG"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_IXFR) != 0, + "rrtype is IXFR"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_AXFR) != 0, + "rrtype is AXFR"); + ok(knot_rrtype_is_metatype(KNOT_RRTYPE_ANY) != 0, + "rrtype is ANY"); + + // knot_rrtype_is_dnssec + ok(knot_rrtype_is_dnssec(0) == 0, + "rrtype is not DNSSEC"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_DNSKEY) != 0, + "rrtype is DNSKEY"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_RRSIG) != 0, + "rrtype is RRSIG"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_NSEC) != 0, + "rrtype is NSEC"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_NSEC3) != 0, + "rrtype is NSEC3"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_NSEC3PARAM) != 0, + "rrtype is NSEC3PARAM"); + ok(knot_rrtype_is_dnssec(KNOT_RRTYPE_CDNSKEY) != 0, + "rrtype is CDNSKEY"); + + // knot_rrtype_additional_needed + ok(knot_rrtype_additional_needed(0) == 0, + "rrtype is not additional needed"); + ok(knot_rrtype_additional_needed(KNOT_RRTYPE_NS) != 0, + "rrtype is NS"); + ok(knot_rrtype_additional_needed(KNOT_RRTYPE_MX) != 0, + "rrtype is MX"); + ok(knot_rrtype_additional_needed(KNOT_RRTYPE_SRV) != 0, + "rrtype is SRV"); + + // knot_rrtype_should_be_lowercased + ok(knot_rrtype_should_be_lowercased(0) == 0, + "rrtype should not be lowercased"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_NS) != 0, + "rrtype is NS"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MD) != 0, + "rrtype is MD"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MF) != 0, + "rrtype is MF"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_CNAME) != 0, + "rrtype is CNAME"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_SOA) != 0, + "rrtype is SOA"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MB) != 0, + "rrtype is MB"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MG) != 0, + "rrtype is MG"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MR) != 0, + "rrtype is MR"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_PTR) != 0, + "rrtype is PTR"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MINFO) != 0, + "rrtype is MINFO"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_MX) != 0, + "rrtype is MX"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_RP) != 0, + "rrtype is RP"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_AFSDB) != 0, + "rrtype is AFSDB"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_RT) != 0, + "rrtype is RT"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_SIG) != 0, + "rrtype is SIG"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_PX) != 0, + "rrtype is PX"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_NXT) != 0, + "rrtype is NXT"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_NAPTR) != 0, + "rrtype is NAPTR"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_KX) != 0, + "rrtype is KX"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_SRV) != 0, + "rrtype is SRV"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_DNAME) != 0, + "rrtype is DNAME"); + ok(knot_rrtype_should_be_lowercased(KNOT_RRTYPE_RRSIG) != 0, + "rrtype is RRSIG"); + + ret = knot_opt_code_to_string(0, name, BUF_LEN); + ok(ret != -1 && strcmp(name, "CODE0") == 0, "opt to str, code 0"); + ret = knot_opt_code_to_string(10, name, BUF_LEN); + ok(ret != -1 && strcmp(name, "COOKIE") == 0, "opt to str, code 10"); + ret = knot_opt_code_to_string(65535, name, BUF_LEN); + ok(ret != -1 && strcmp(name, "CODE65535") == 0, "opt to str, code 65535"); + + return 0; +} diff --git a/tests/libknot/test_dname.c b/tests/libknot/test_dname.c new file mode 100644 index 0000000..2480135 --- /dev/null +++ b/tests/libknot/test_dname.c @@ -0,0 +1,618 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/dname.h" + +/* Test dname_parse_from_wire */ +static int test_fw(size_t l, const char *w) { + const uint8_t *np = NULL; + if (w != NULL) { + np = (const uint8_t *)w + l; + } + return knot_dname_wire_check((const uint8_t *)w, np, NULL) > 0; +} + +/* Test dname to/from string operations */ +static void test_str(const char *in_str, const char *in_bin, size_t bin_len) +{ + knot_dname_storage_t d1; + knot_dname_txt_storage_t s1; + knot_dname_t *d2 = NULL, *aux_d = NULL; + char *s2 = NULL, *aux_s = NULL; + int ret = 0; + + /* dname_from_str */ + aux_d = knot_dname_from_str(d1, in_str, sizeof(d1)); + ok(aux_d != NULL, "dname_from_str: %s", in_str); + if (aux_d == NULL) { + skip_block(10, "dname_from_str: %s", in_str); + return; + } + + /* dname_wire_check */ + ret = knot_dname_wire_check(d1, d1 + sizeof(d1), NULL); + ok(ret == bin_len, "dname_wire_check: %s", in_str); + + /* dname compare */ + ok(memcmp(d1, in_bin, bin_len) == 0, "dname compare: %s", in_str); + + /* dname_to_str */ + aux_s = knot_dname_to_str(s1, d1, sizeof(s1)); + ok(aux_s != NULL, "dname_to_str: %s", in_str); + if (aux_s == NULL) { + skip_block(7, "dname_to_str: %s", in_str); + return; + } + + /* dname_from_str_alloc */ + d2 = knot_dname_from_str_alloc(s1); + ok(d2 != NULL, "dname_from_str_alloc: %s", s1); + if (d2 == NULL) { + skip_block(6, "dname_from_str_alloc: %s", s1); + return; + } + + /* dname_wire_check */ + ret = knot_dname_wire_check(d2, d2 + bin_len, NULL); + ok(ret == bin_len, "dname_wire_check: %s", s1); + + /* dname compare */ + ok(d2 && memcmp(d2, in_bin, bin_len) == 0, "dname compare: %s", s1); + + /* dname_to_str_alloc */ + s2 = knot_dname_to_str_alloc(d2); + knot_dname_free(d2, NULL); + ok(s2 != NULL, "dname_to_str_alloc: %s", s1); + if (s2 == NULL) { + skip_block(3, "dname_to_str_alloc: %s", s1); + return; + } + + /* As the string representation is ambiguous, the following steps + * are just for comparison in wire form. + */ + d2 = knot_dname_from_str_alloc(s2); + ok(d2 != NULL, "dname_from_str_alloc: %s", s2); + if (aux_d == NULL) { + skip_block(2, "dname_from_str_alloc: %s", s2); + free(s2); + return; + } + + /* dname_wire_check */ + ret = knot_dname_wire_check(d2, d2 + bin_len, NULL); + ok(ret == bin_len, "dname_wire_check: %s", s2); + + /* dname compare */ + ok(d2 && memcmp(d2, in_bin, bin_len) == 0, "dname compare: %s", s2); + + knot_dname_free(d2, NULL); + free(s2); +} + +static void test_dname_lf(void) +{ + knot_dname_storage_t storage; + + /* Maximal DNAME length */ + const knot_dname_t *in = (uint8_t *) + "\x3f""iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" + "\x3f""hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh" + "\x3f""ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg" + "\x1f""fffffffffffffffffffffffffffffff" + "\x0f""eeeeeeeeeeeeeee" + "\x07""ddddddd" + "\x03""ccc" + "\x01""b" + "\x00"; + const uint8_t *ref = (uint8_t *) + "\xFE" + "b""\x00" + "ccc""\00" + "ddddddd""\x00" + "eeeeeeeeeeeeeee""\x00" + "fffffffffffffffffffffffffffffff""\x00" + "ggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg""\x00" + "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh""\x00" + "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii""\x00"; + assert(strlen((const char *)in) == KNOT_DNAME_MAXLEN - 1); + uint8_t *out = knot_dname_lf(in, storage); + ok(out != NULL && memcmp(ref, out, KNOT_DNAME_MAXLEN) == 0, + "knot_dname_lf: max-length DNAME converted"); + + /* Zero label DNAME*/ + in = (uint8_t *) "\x00"; + out = knot_dname_lf(in, storage); + ok(out != NULL && out[0] == '\x00', "knot_dname_lf: zero-label DNAME converted"); +} + +static void test_dname_storage(void) +{ + const knot_dname_t *dname = (uint8_t *)"\x04""test"; + size_t dname_len = knot_dname_size(dname); + + knot_dname_storage_t storage; + size_t store_len = knot_dname_store(storage, dname); + size_t storage_len = knot_dname_size(storage); + + ok(store_len == dname_len && storage_len == dname_len && + memcmp(storage, dname, dname_len) == 0, + "knot_dname_storage: valid name"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_dname_t *d = NULL, *d2 = NULL; + const char *w = NULL, *t = NULL; + char *s = NULL; + + /* DNAME WIRE CHECKS */ + + /* NULL wire */ + ok(!test_fw(0, NULL), "parsing NULL dname"); + + /* empty label */ + ok(test_fw(1, ""), "parsing empty dname"); + + /* incomplete dname */ + ok(!test_fw(5, "\x08" "dddd"), "parsing incomplete wire"); + + /* non-fqdn */ + ok(!test_fw(3, "\x02" "ab"), "parsing non-fqdn name"); + + /* label length == 63 */ + w = "\x3f" "123456789012345678901234567890123456789012345678901234567890123"; + ok(test_fw(1 + 63 + 1, w), "parsing label length == 63"); + + /* label length > 63 */ + w = "\x40" "1234567890123456789012345678901234567890123456789012345678901234"; + ok(!test_fw(1 + 64 + 1, w), "parsing label length > 63"); + + /* label count == 127 (also maximal dname length) */ + w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"; + ok(test_fw(127 * 2 + 1, w), "parsing label count == 127"); + + /* label count > 127 */ + w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"; + ok(!test_fw(128 * 2 + 1, w), "parsing label count > 127"); + + /* dname length > 255 */ + w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x02\x64\x64"; + ok(!test_fw(126 * 2 + 3 + 1, w), "parsing dname len > 255"); + + /* DNAME STRING CHECKS */ + + /* root dname */ + test_str(".", "\x00", 1); + + /* 1-char dname */ + test_str("a.", "\x01""a", 2 + 1); + + /* 1-char dname - non-fqdn */ + test_str("a", "\x01""a", 2 + 1); + + /* wildcard and asterisks */ + test_str("*.*a.a*a.**.", + "\x01" "*" "\x02" "*a" "\x03" "a*a" "\x02" "**", + 2 + 3 + 4 + 3 + 1); + + /* special label */ + test_str("\\000\\0320\\ \\\\\\\"\\.\\@\\*.", + "\x09" "\x00\x20\x30\x20\x5c\x22.@*", + 10 + 1); + + /* unescaped special characters */ + test_str("_a.b-c./d.", + "\x02" "_a" "\x03" "b-c" "\x02" "/d", + 3 + 4 + 3 + 1); + + /* all possible characters */ + test_str("\\000\\001\\002\\003\\004\\005\\006\\007\\008\\009\\010\\011\\012\\013\\014\\015\\016\\017\\018\\019", + "\x14" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13", + 22); + test_str("\\020\\021\\022\\023\\024\\025\\026\\027\\028\\029\\030\\031\\032\\033\\034\\035\\036\\037\\038\\039", + "\x14" "\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27", + 22); + test_str("\\040\\041\\042\\043\\044\\045\\046\\047\\048\\049\\050\\051\\052\\053\\054\\055\\056\\057\\058\\059", + "\x14" "\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b", + 22); + test_str("\\060\\061\\062\\063\\064\\065\\066\\067\\068\\069\\070\\071\\072\\073\\074\\075\\076\\077\\078\\079", + "\x14" "\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f", + 22); + test_str("\\080\\081\\082\\083\\084\\085\\086\\087\\088\\089\\090\\091\\092\\093\\094\\095\\096\\097\\098\\099", + "\x14" "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63", + 22); + test_str("\\100\\101\\102\\103\\104\\105\\106\\107\\108\\109\\110\\111\\112\\113\\114\\115\\116\\117\\118\\119", + "\x14" "\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77", + 22); + test_str("\\120\\121\\122\\123\\124\\125\\126\\127\\128\\129\\130\\131\\132\\133\\134\\135\\136\\137\\138\\139", + "\x14" "\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b", + 22); + test_str("\\140\\141\\142\\143\\144\\145\\146\\147\\148\\149\\150\\151\\152\\153\\154\\155\\156\\157\\158\\159", + "\x14" "\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f", + 22); + test_str("\\160\\161\\162\\163\\164\\165\\166\\167\\168\\169\\170\\171\\172\\173\\174\\175\\176\\177\\178\\179", + "\x14" "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3", + 22); + test_str("\\180\\181\\182\\183\\184\\185\\186\\187\\188\\189\\190\\191\\192\\193\\194\\195\\196\\197\\198\\199", + "\x14" "\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7", + 22); + test_str("\\200\\201\\202\\203\\204\\205\\206\\207\\208\\209\\210\\211\\212\\213\\214\\215\\216\\217\\218\\219", + "\x14" "\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb", + 22); + test_str("\\220\\221\\222\\223\\224\\225\\226\\227\\228\\229\\230\\231\\232\\233\\234\\235\\236\\237\\238\\239", + "\x14" "\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef", + 22); + test_str("\\240\\241\\242\\243\\244\\245\\246\\247\\248\\249\\250\\251\\252\\253\\254\\255", + "\x10" "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", + 18); + + /* maximal dname label length */ + test_str("12345678901234567890123456789012345678901234567890123456789012\\063", + "\x3f" "12345678901234567890123456789012345678901234567890123456789012?", + 65); + + /* maximal dname length */ + test_str("1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "\\#234567890123456789012345678901234567890123456789012\\063", + "\x31" "1234567890123456789012345678901234567890123456789" + "\x31" "1234567890123456789012345678901234567890123456789" + "\x31" "1234567890123456789012345678901234567890123456789" + "\x31" "1234567890123456789012345678901234567890123456789" + "\x35" "#234567890123456789012345678901234567890123456789012?", + 255); + + /* NULL output, positive maxlen */ + w = "\x02" "aa"; + s = knot_dname_to_str(NULL, (const uint8_t *)w, 1); + ok(s != NULL, "dname_to_str: null dname"); + if (s != NULL) { + ok(memcmp(s, "aa.", 4) == 0, "dname_to_str: null dname compare"); + free(s); + } else { + skip("dname_to_str: null dname"); + } + + /* non-NULL output, zero maxlen */ + char s_small[2]; + s = knot_dname_to_str(s_small, (const uint8_t *)w, 0); + ok(s == NULL, "dname_to_str: non-NULL output, zero maxlen"); + + /* small buffer */ + s = knot_dname_to_str(s_small, (const uint8_t *)w, 1); + ok(s == NULL, "dname_to_str: small buffer"); + + /* NULL dname */ + s = knot_dname_to_str_alloc(NULL); + ok(s == NULL, "dname_to_str: null dname"); + + /* empty dname is considered as a root dname */ + w = ""; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: empty dname"); + if (s != NULL) { + ok(memcmp(s, ".", 1) == 0, "dname_to_str: empty dname is root dname"); + free(s); + } else { + skip("dname_to_str: empty dname"); + } + + /* incomplete dname */ + /* ASAN: global-buffer-overflow + w = "\x08" "dddd"; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: incomplete dname"); + free(s); + */ + + /* non-fqdn */ + w = "\x02" "ab"; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: non-fqdn"); + free(s); + + /* label length > 63 */ + w = "\x40" "1234567890123456789012345678901234567890123456789012345678901234"; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: label length > 63"); + free(s); + + /* label count > 127 */ + w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64"; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: label count > 127"); + free(s); + + /* dname length > 255 */ + w = "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64" + "\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x01\x64\x02\x64\x64"; + s = knot_dname_to_str_alloc((const uint8_t *)w); + ok(s != NULL, "dname_to_str: dname length > 255"); + free(s); + + /* output overflow sanity check */ + uint8_t in[4] = "\x02""\x00\x00""\x00"; + for (uint16_t i = 0; i < UINT16_MAX; i++) { + memcpy(in + 1, &i, sizeof(i)); + for (int j = 3; j < 8; j++) { + char tmp[j]; + char *out_static = knot_dname_to_str(tmp, in, sizeof(tmp)); + char *out_dynamic = knot_dname_to_str_alloc(in); + if (out_dynamic == NULL) { + ok(out_dynamic != NULL, "dname_to_str_alloc: invalid input"); + } else if (strlen(out_dynamic) < sizeof(tmp) - 1 && + out_static == NULL) { + ok(out_static != NULL, "dname_to_str: invalid input"); + } + free(out_dynamic); + } + } + + /* NULL output, positive maxlen */ + s = "aa."; + d = knot_dname_from_str(NULL, s, 1); + ok(s != NULL, "dname_from_str: null name"); + if (s != NULL) { + ok(memcmp(d, "\x02" "aa", 4) == 0, "dname_from_str: null name compare"); + free(d); + } else { + skip("dname_from_str: null name"); + } + + /* non-NULL output, zero maxlen */ + uint8_t d_small[2]; + d = knot_dname_from_str(d_small, s, 0); + ok(d == NULL, "dname_from_str: non-NULL output, zero maxlen"); + + /* small buffer */ + d = knot_dname_from_str(d_small, s, 1); + ok(d == NULL, "dname_from_str: small buffer"); + + /* NULL string */ + d = knot_dname_from_str_alloc(NULL); + ok(d == NULL, "dname_from_str: null string"); + + /* empty string */ + t = ""; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: empty string"); + + /* empty label */ + t = ".."; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: empty label"); + + /* leading dot */ + t = ".a"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: leading dot"); + + /* incomplete decimal notation I */ + t = "\\1"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: incomplete decimal I"); + + /* incomplete decimal notation II */ + t = "\\12"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: incomplete decimal II"); + + /* invalid decimal notation I */ + t = "\\256"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: invalid decimal I"); + + /* invalid decimal notation II */ + t = "\\2x6"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: invalid decimal II"); + + /* invalid escape notation */ + t = "\\2"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: invalid escape"); + + /* label length > 63 I */ + t = "1234567890123456789012345678901234567890123456789012345678901234"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: label length > 63 I"); + + /* label length > 63 II */ + t = "123456789012345678901234567890123456789012345678901234567890123\\?"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: label length > 63 II"); + + /* label length > 63 III */ + t = "123456789012345678901234567890123456789012345678901234567890123\\063"; + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: label length > 63 III"); + + /* dname length > 255 */ + t = "1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "1234567890123456789012345678901234567890123456789." + "123456789012345678901234567890123456789012345678901234.", + d = knot_dname_from_str_alloc(t); + ok(d == NULL, "dname_from_str: dname length > 255"); + + /* DNAME SUBDOMAIN CHECKS */ + + /* equal name is subdomain */ + t = "ab.cd.ef"; + d2 = knot_dname_from_str_alloc(t); + t = "ab.cd.ef"; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_in_bailiwick(d, d2) == 0, "dname_subdomain: equal name"); + knot_dname_free(d, NULL); + + /* true subdomain */ + t = "0.ab.cd.ef"; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_in_bailiwick(d, d2) == 1, "dname_subdomain: true subdomain"); + knot_dname_free(d, NULL); + + /* not subdomain */ + t = "cd.ef"; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_in_bailiwick(d, d2) < 0, "dname_subdomain: not subdomain"); + knot_dname_free(d, NULL); + + /* root subdomain */ + t = "."; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_in_bailiwick(d2, d) == 3, "dname_subdomain: root subdomain"); + knot_dname_free(d, NULL); + knot_dname_free(d2, NULL); + + /* DNAME EQUALITY CHECKS */ + + t = "ab.cd.ef"; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_is_equal(d, d), "dname_is_equal: equal names"); + + t = "ab.cd.fe"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_equal(d, d2), "dname_is_equal: same label count"); + knot_dname_free(d2, NULL); + + t = "ab.cd"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_equal(d, d2), "dname_is_equal: len(d1) < len(d2)"); + knot_dname_free(d2, NULL); + + t = "ab.cd.ef.gh"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_equal(d, d2), "dname_is_equal: len(d1) > len(d2)"); + knot_dname_free(d2, NULL); + + t = "ab.cd.efe"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_equal(d, d2), "dname_is_equal: last label longer"); + knot_dname_free(d2, NULL); + + t = "ab.cd.e"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_equal(d, d2), "dname_is_equal: last label shorter"); + knot_dname_free(d2, NULL); + + knot_dname_free(d, NULL); + + /* DNAME EQUALITY CHECKS IGNORING CASE */ + + t = "aB.cd.ef"; + d = knot_dname_from_str_alloc(t); + ok(knot_dname_is_case_equal(d, d), "dname_is_case_equal: equal case"); + + t = "aB.cD.ef"; + d2 = knot_dname_from_str_alloc(t); + ok(knot_dname_is_case_equal(d, d2), "dname_is_case_equal: different case"); + knot_dname_free(d2, NULL); + + t = "aB.dc.ef"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_case_equal(d, d2), "dname_is_case_equal: different name"); + knot_dname_free(d2, NULL); + + t = "aB.cd"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_case_equal(d, d2), "dname_is_case_equal: different length"); + knot_dname_free(d2, NULL); + + t = "aB.cdx.ef"; + d2 = knot_dname_from_str_alloc(t); + ok(!knot_dname_is_case_equal(d, d2), "dname_is_case_equal: different label"); + knot_dname_free(d2, NULL); + + knot_dname_free(d, NULL); + + /* OTHER CHECKS */ + + test_dname_lf(); + + test_dname_storage(); + + return 0; +} diff --git a/tests/libknot/test_dynarray.c b/tests/libknot/test_dynarray.c new file mode 100644 index 0000000..ac1e0f1 --- /dev/null +++ b/tests/libknot/test_dynarray.c @@ -0,0 +1,137 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <tap/basic.h> + +#include "libknot/dynarray.h" + +#define test_capacity 5 +// minimum 3 + +typedef struct { + int x; + int x2; +} quadrate_t; + +knot_dynarray_declare(q, quadrate_t, DYNARRAY_VISIBILITY_STATIC, test_capacity); +knot_dynarray_define(q, quadrate_t, DYNARRAY_VISIBILITY_STATIC); + +static q_dynarray_t q_fill(size_t howmany) +{ + quadrate_t q = { 0 }; + q_dynarray_t qd = { 0 }; + + for (size_t i = 0; i < howmany; i++) { + q.x2 = q.x * q.x; + q_dynarray_add(&qd, &q); + q.x++; + } + return qd; +} + +static void check_arr(q_dynarray_t *q, size_t count, size_t index, const char *msg) +{ + quadrate_t *arr = q->arr(q); + ok(arr[index].x == index && arr[index].x2 == index * index, + "%s check: index %zu", msg, index); + + size_t i = 0; + knot_dynarray_foreach(q, quadrate_t, p, *q) { + ok(p->x == i && p->x2 == i * i, "%s foreach: index %zu", msg, i); + i++; + } + + ok(i == count, "%s foreach: whole array", msg); +} + +static size_t q_set_dups(q_dynarray_t *q, double dup_percentage, const quadrate_t *dupval) +{ + size_t dup_cnt = 0; + int threshold = (int)(dup_percentage / 100 * ((double)RAND_MAX + 1.0)); + + knot_dynarray_foreach(q, quadrate_t, item, *q) { + if (rand() < threshold && q_dynarray_memb_cmp(item, dupval) != 0) { + *item = *dupval; + dup_cnt++; + } + } + + return dup_cnt; +} + +static void check_dups(q_dynarray_t *q, const quadrate_t *dupval, + const size_t expected, const char *msg) +{ + size_t cnt = 0; + knot_dynarray_foreach(q, quadrate_t, item, *q) { + if (q_dynarray_memb_cmp(item, dupval) == 0) { + cnt++; + } + } + ok(cnt == expected, "duplicate items: %s", msg); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // first fill + q_dynarray_t q = q_fill(test_capacity - 1); + check_arr(&q, test_capacity - 1, test_capacity - 3, "initial"); + q_dynarray_free(&q); + + // second fill + q = q_fill(test_capacity + 3); + check_arr(&q, test_capacity + 3, test_capacity + 1, "second"); + q_dynarray_free(&q); + + // third fill + q = q_fill(test_capacity * 5); + check_arr(&q, test_capacity * 5, test_capacity * 4, "third"); + q_dynarray_free(&q); + + // duplicate items removal test + q = q_fill(test_capacity * 10); + quadrate_t dup_item = { .x = 0, .x2 = 0 }; // matches the first item + size_t dups = q_set_dups(&q, 50, &dup_item); + ok(q.size == test_capacity * 10, "duplicate items: created"); + check_dups(&q, &dup_item, dups + 1, "created all"); + + q_dynarray_remove(&q, &dup_item); + ok(q.size == test_capacity * 10 - dups - 1, "duplicate items: removed"); + check_dups(&q, &dup_item, 0, "removed all"); + + q_dynarray_free(&q); + + // binary search removal test + q = q_fill(test_capacity * 10); + for (int i = 0; i < test_capacity * 10; i++) { + quadrate_t qu = { i, i * i }; + if ((qu.x % 2) == 0) { + q_dynarray_remove(&q, &qu); + } + } + q_dynarray_sort(&q); + for (int i = 0; i < test_capacity * 10; i++) { + quadrate_t qu = { i, i * i }; + int present = (q_dynarray_bsearch(&q, &qu) != NULL ? 1 : 0); + ok(present == (i % 2), "presence in sorted array %d", i); + } + q_dynarray_free(&q); + + return 0; +} diff --git a/tests/libknot/test_edns.c b/tests/libknot/test_edns.c new file mode 100644 index 0000000..d2b4fd8 --- /dev/null +++ b/tests/libknot/test_edns.c @@ -0,0 +1,502 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include <assert.h> +#include "libknot/libknot.h" +#include "libknot/rrtype/opt.h" +#include "libknot/descriptor.h" +#include "libknot/wire.h" +#include "contrib/sockaddr.h" + +static const uint16_t E_MAX_PLD = 10000; +static const uint16_t E_MAX_PLD2 = 20000; +static const uint8_t E_VERSION = 1; +static const uint8_t E_VERSION2 = 2; +static const uint8_t E_RCODE = 0; +static const uint8_t E_RCODE2 = 200; + +static const char *E_NSID_STR = "FooBar"; +static const char *E_NSID_STR2 = "BarFoo"; +static const uint16_t E_NSID_LEN = 6; + +#define E_NSID_SIZE (4 + E_NSID_LEN) + +static const uint16_t E_OPT3_CODE = 15; +static const char *E_OPT3_FAKE_DATA = "Not used"; +static const char *E_OPT3_DATA = NULL; +static const uint16_t E_OPT3_LEN = 0; +static const uint16_t E_OPT3_FAKE_LEN = 8; + +#define E_OPT3_SIZE (4 + E_OPT3_LEN) + +static const uint16_t E_OPT4_CODE = 30; +static const char *E_OPT4_DATA = NULL; +static const uint16_t E_OPT4_LEN = 0; + +#define E_OPT4_SIZE (4 + E_OPT4_LEN) + +enum offsets { + /*! \brief Offset of Extended RCODE in wire order of TTL. */ + OFFSET_ERCODE = 0, + /*! \brief Offset of Version in wire order of TTL. */ + OFFSET_VER = 1, + /*! \brief Offset of Flags in wire order of TTL. */ + OFFSET_FLAGS = 2, + /*! \brief Offset of OPTION code in one OPTION in RDATA. */ + OFFSET_OPT_CODE = 0, + /*! \brief Offset of OPTION size in one OPTION in RDATA. */ + OFFSET_OPT_SIZE = 2, + /*! \brief Offset of OPTION data in one OPTION in RDATA. */ + OFFSET_OPT_DATA = 4 +}; + +static const uint16_t DO_FLAG = (uint16_t)1 << 15; + +static void check_ttl(knot_rrset_t *rrset, uint8_t ext_rcode, uint8_t ver, + uint16_t flags, char *msg) +{ + if (rrset == NULL) { + return; + } + + /* TTL should be stored in machine byte order. + We need network byte order to compare its parts. */ + uint8_t ttl_wire[4] = { 0, 0, 0, 0 }; + knot_wire_write_u32(ttl_wire, rrset->ttl); + + /* Convert Flags from EDNS parameters to wire format for comparison. */ + uint8_t flags_wire[2] = { 0, 0 }; + knot_wire_write_u16(flags_wire, flags); + + /* TTL = Ext RCODE + Version + Flags */ + bool check = (ttl_wire[OFFSET_ERCODE] == ext_rcode); + ok(check, "%s: extended RCODE", msg); + + check = (ttl_wire[OFFSET_VER] == ver); + ok(check, "%s: version", msg); + + check = (memcmp(flags_wire, ttl_wire + OFFSET_FLAGS, 2) == 0); + ok(check, "%s: flags", msg); +} + +static void check_option(knot_rdata_t *rdata, uint16_t opt_code, + uint16_t opt_len, uint8_t *opt_data, char *msg) +{ + assert(rdata != NULL); + + uint8_t *data = rdata->data; + uint16_t data_len = rdata->len; + + /* Check RDLENGTH according to given data length. */ + bool check = (data_len >= 4 + opt_len); + ok(check, "%s: RDLENGTH (%u)", msg, data_len); + + /* Find the desired option. */ + bool found = false; + int pos = 0; + while (pos <= data_len - 4) { + uint16_t code = knot_wire_read_u16(data + pos + OFFSET_OPT_CODE); + if (code == opt_code) { + found = true; + break; + } + uint16_t len = knot_wire_read_u16(data + pos + OFFSET_OPT_SIZE); + pos += 4 + len; + } + + /* Check that the option is present. */ + ok(found, "%s: find OPTION %u in OPT RR", msg, opt_code); + + /* Check that the first OPTION's size si the size of the option data. */ + uint16_t opt_size = knot_wire_read_u16(data + pos + OFFSET_OPT_SIZE); + check = (opt_size == opt_len); + ok(check, "%s: OPTION data size", msg); + + /* Check the actual NSID data. */ + check = (opt_data == 0 || memcmp(data + pos + OFFSET_OPT_DATA, opt_data, opt_len) == 0); + ok(check, "%s: OPTION data", msg); +} + +static void check_header(knot_rrset_t *opt_rr, uint16_t payload, uint8_t ver, + uint16_t flags, uint8_t ext_rcode, char *msg) +{ + assert(opt_rr != NULL); + bool check; + + /* Check values in OPT RR by hand. */ + /* CLASS == Max UDP payload */ + check = (opt_rr->rclass == payload); + ok(check, "%s: max payload", msg); + + /* The OPT RR should have exactly one RDATA. */ + check = (opt_rr->rrs.count == 1); + ok(check, "%s: RR count == 1", msg); + + knot_rdata_t *rdata = opt_rr->rrs.rdata; + check = (rdata != NULL); + ok(check, "%s: RDATA exists", msg); + + check_ttl(opt_rr, ext_rcode, ver, flags, msg); +} + +static void test_getters(knot_rrset_t *opt_rr) +{ + assert(opt_rr != NULL); + + /* These values should be set from the setters test: + * Max UDP payload: E_MAX_PLD2 + * Version: E_VERSION2 + * RCODE: E_RCODE2 + * Flags: E_FLAGS | KNOT_EDNS_FLAG_DO + * OPTIONs: 1) KNOT_EDNS_OPTION_NSID, E_NSID_LEN, E_NSID_STR + * 2) E_OPT3_CODE, 0, 0 + * 3) E_OPT4_CODE, 0, 0 + * 4) KNOT_EDNS_OPTION_NSID, E_NSID_LEN, E_NSID_STR2 + */ + + /* Payload */ + bool check = (knot_edns_get_payload(opt_rr) == E_MAX_PLD2); + ok(check, "OPT RR getters: payload"); + + /* Extended RCODE */ + check = (knot_edns_get_ext_rcode(opt_rr) == E_RCODE2); + ok(check, "OPT RR getters: extended RCODE"); + + /* Extended RCODE */ + check = (knot_edns_get_version(opt_rr) == E_VERSION2); + ok(check, "OPT RR getters: version"); + + /* DO bit */ + check = knot_edns_do(opt_rr); + ok(check, "OPT RR getters: DO bit check"); + + /* Wire size */ + size_t total_size = KNOT_EDNS_MIN_SIZE + + 2 * E_NSID_SIZE + E_OPT3_SIZE + E_OPT4_SIZE; + size_t actual_size = knot_edns_wire_size(opt_rr); + check = actual_size == total_size; + ok(check, "OPT RR getters: wire size (expected: %zu, actual: %zu)", + total_size, actual_size); + + /* NSID */ + uint8_t *nsid1 = knot_edns_get_option(opt_rr, KNOT_EDNS_OPTION_NSID, NULL); + check = nsid1 != NULL; + ok(check, "OPT RR getters: NSID check"); + check = memcmp(knot_edns_opt_get_data(nsid1), E_NSID_STR, knot_edns_opt_get_length(nsid1)) == 0; + ok(check, "OPT RR getters: NSID value check"); + + /* Another NSID */ + uint8_t *nsid2 = knot_edns_get_option(opt_rr, KNOT_EDNS_OPTION_NSID, nsid1); + check = nsid2 != NULL; + ok(check, "OPT RR getters: another NSID check"); + check = memcmp(knot_edns_opt_get_data(nsid2), E_NSID_STR2, knot_edns_opt_get_length(nsid2)) == 0; + ok(check, "OPT RR getters: another NSID value check"); + + /* Other OPTIONs */ + check = knot_edns_get_option(opt_rr, E_OPT3_CODE, NULL) != NULL; + ok(check, "OPT RR getters: empty option 1"); + + check = knot_edns_get_option(opt_rr, E_OPT4_CODE, NULL) != NULL; + ok(check, "OPT RR getters: empty option 2"); + + uint16_t code = knot_edns_opt_get_code((const uint8_t *)"\x00\x0a" "\x00\x00"); + ok(code == KNOT_EDNS_OPTION_COOKIE, "OPT RR getters: EDNS OPT code"); +} + +static void test_setters(knot_rrset_t *opt_rr) +{ + assert(opt_rr != NULL); + + /* Header-related setters. */ + knot_edns_set_payload(opt_rr, E_MAX_PLD2); + knot_edns_set_ext_rcode(opt_rr, E_RCODE2); + knot_edns_set_version(opt_rr, E_VERSION2); + knot_edns_set_do(opt_rr); + + check_header(opt_rr, E_MAX_PLD2, E_VERSION2, DO_FLAG, E_RCODE2, + "OPT RR setters"); + + /* OPTION(RDATA)-related setters. */ + + /* Proper option NSID. */ + int ret = knot_edns_add_option(opt_rr, KNOT_EDNS_OPTION_NSID, + E_NSID_LEN, (uint8_t *)E_NSID_STR, NULL); + is_int(KNOT_EOK, ret, "OPT RR setters: add option with data (ret = %s)", + knot_strerror(ret)); + + /* Wrong argument: no OPT RR. */ + ret = knot_edns_add_option(NULL, E_OPT3_CODE, E_OPT3_FAKE_LEN, + (uint8_t *)E_OPT3_FAKE_DATA, NULL); + is_int(KNOT_EINVAL, ret, "OPT RR setters: add option (rr == NULL) " + "(ret = %s)", knot_strerror(ret)); + + /* Wrong argument: option length != 0 && data == NULL. */ + ret = knot_edns_add_option(opt_rr, E_OPT3_CODE, E_OPT3_FAKE_LEN, NULL, + NULL); + is_int(KNOT_EINVAL, ret, "OPT RR setters: add option (data == NULL, " + "len != 0) (ret = %s)", knot_strerror(ret)); + + /* Empty OPTION (length 0, data != NULL). */ + ret = knot_edns_add_option(opt_rr, E_OPT3_CODE, E_OPT3_LEN, + (uint8_t *)E_OPT3_FAKE_DATA, NULL); + is_int(KNOT_EOK, ret, "OPT RR setters: add empty option 1 (ret = %s)", + knot_strerror(ret)); + + /* Empty OPTION (length 0, data == NULL). */ + ret = knot_edns_add_option(opt_rr, E_OPT4_CODE, E_OPT4_LEN, + (uint8_t *)E_OPT4_DATA, NULL); + is_int(KNOT_EOK, ret, "OPT RR setters: add empty option 2 (ret = %s)", + knot_strerror(ret)); + + /* Another option NSID. */ + ret = knot_edns_add_option(opt_rr, KNOT_EDNS_OPTION_NSID, + E_NSID_LEN, (uint8_t *)E_NSID_STR2, NULL); + is_int(KNOT_EOK, ret, "OPT RR setters: add option with data (ret = %s)", + knot_strerror(ret)); + + knot_rdata_t *rdata = opt_rr->rrs.rdata; + ok(rdata != NULL, "OPT RR setters: non-empty RDATA"); + + /* Check proper option NSID */ + check_option(rdata, KNOT_EDNS_OPTION_NSID, E_NSID_LEN, + (uint8_t *)E_NSID_STR, "OPT RR setters (proper option)"); + + /* Check empty option 1 */ + check_option(rdata, E_OPT3_CODE, E_OPT3_LEN, + (uint8_t *)E_OPT3_DATA, "OPT RR setters (empty option 1)"); + + /* Check empty option 2 */ + check_option(rdata, E_OPT4_CODE, E_OPT4_LEN, + (uint8_t *)E_OPT4_DATA, "OPT RR setters (empty option 2)"); +} + +static void test_alignment(void) +{ + int ret; + + ret = knot_edns_alignment_size(1, 1, 1); + ok(ret == -1, "no alignment"); + + ret = knot_edns_alignment_size(1, 1, 2); + ok(ret == -1, "no alignment"); + + ret = knot_edns_alignment_size(1, 1, 3); + ok(ret == (6 - (1 + 1 + KNOT_EDNS_OPTION_HDRLEN)), "%i-Byte alignment", ret); + + ret = knot_edns_alignment_size(1, 1, 4); + ok(ret == (8 - (1 + 1 + KNOT_EDNS_OPTION_HDRLEN)), "%i-Byte alignment", ret); + + ret = knot_edns_alignment_size(1, 1, 512); + ok(ret == (512 - (1 + 1 + KNOT_EDNS_OPTION_HDRLEN)), "%i-Byte alignment", ret); +} + +static void test_keepalive(void) +{ + typedef struct { + char *msg; + uint16_t opt_len; + char *opt; + uint16_t val; + } test_t; + + // OK tests. + + static const test_t TESTS[] = { + { "ok 0", 0, "", 0 }, + { "ok 1", 2, "\x00\x01", 1 }, + { "ok 258", 2, "\x01\x02", 258 }, + { "ok 65535", 2, "\xFF\xFF", 65535 }, + { NULL } + }; + + for (const test_t *t = TESTS; t->msg != NULL; t++) { + uint16_t len = knot_edns_keepalive_size(t->val); + ok(len == t->opt_len, "%s: %s, size", __func__, t->msg); + + uint8_t wire[8] = { 0 }; + int ret = knot_edns_keepalive_write(wire, sizeof(wire), t->val); + is_int(KNOT_EOK, ret, "%s: %s, write, return", __func__, t->msg); + ok(memcmp(wire, t->opt, t->opt_len) == 0, "%s: %s, write, value", + __func__, t->msg); + + uint16_t timeout = 0; + ret = knot_edns_keepalive_parse(&timeout, (uint8_t *)t->opt, t->opt_len); + is_int(KNOT_EOK, ret, "%s: %s, parse, return", __func__, t->msg); + ok(timeout == t->val, "%s: %s, parse, value", __func__, t->msg); + } + + // Error tests. + + uint8_t wire[8] = { 0 }; + ok(knot_edns_keepalive_write(NULL, 0, 0) == KNOT_EINVAL, + "%s: write, NULL", __func__); + ok(knot_edns_keepalive_write(wire, 1, 1) == KNOT_ESPACE, + "%s: write, no room", __func__); + + uint16_t timeout = 0; + ok(knot_edns_keepalive_parse(NULL, (const uint8_t *)"", 0) == KNOT_EINVAL, + "%s: parse, NULL", __func__); + ok(knot_edns_keepalive_parse(&timeout, NULL, 0) == KNOT_EINVAL, + "%s: parse, NULL", __func__); + ok(knot_edns_keepalive_parse(&timeout, (const uint8_t *)"\x01", 1) == KNOT_EMALF, + "%s: parse, malformed", __func__); +} + +static void test_chain(void) +{ + typedef struct { + char *msg; + uint16_t opt_len; + knot_dname_t *dname; + } test_t; + + // OK tests. + + static const test_t TESTS[] = { + { ".", 1, (knot_dname_t *)"" }, + { "a.", 3, (knot_dname_t *)"\x01" "a" }, + { NULL } + }; + + for (const test_t *t = TESTS; t->msg != NULL; t++) { + uint16_t len = knot_edns_chain_size(t->dname); + ok(len == t->opt_len, "%s: dname %s, size", __func__, t->msg); + + uint8_t wire[8] = { 0 }; + int ret = knot_edns_chain_write(wire, sizeof(wire), t->dname); + is_int(KNOT_EOK, ret, "%s: dname %s, write, return", __func__, t->msg); + ok(memcmp(wire, t->dname, t->opt_len) == 0, "%s: dname %s, write, value", + __func__, t->msg); + + knot_dname_t *dname = NULL; + ret = knot_edns_chain_parse(&dname, (uint8_t *)t->dname, t->opt_len, NULL); + is_int(KNOT_EOK, ret, "%s: dname %s, parse, return", __func__, t->msg); + ok(knot_dname_is_equal(dname, t->dname), "%s: dname %s, parse, value", + __func__, t->msg); + knot_dname_free(dname, NULL); + } + + // Error tests. + + ok(knot_edns_chain_size(NULL) == 0, "%s: size, NULL", __func__); + + uint8_t wire[8] = { 0 }; + ok(knot_edns_chain_write(NULL, 0, wire) == KNOT_EINVAL, + "%s: write, NULL", __func__); + ok(knot_edns_chain_write(wire, 0, NULL) == KNOT_EINVAL, + "%s: write, NULL", __func__); + ok(knot_edns_chain_write(wire, 0, (const knot_dname_t *)"") == KNOT_ESPACE, + "%s: write, no room", __func__); + + knot_dname_t *dname = NULL; + ok(knot_edns_chain_parse(NULL, wire, 0, NULL) == KNOT_EINVAL && dname == NULL, + "%s: parse, NULL", __func__); + ok(knot_edns_chain_parse(&dname, NULL, 0, NULL) == KNOT_EINVAL && dname == NULL, + "%s: parse, NULL", __func__); + ok(knot_edns_chain_parse(&dname, (const uint8_t *)"\x01", 1, NULL) == KNOT_EMALF && + dname == NULL, "%s: parse, malformed", __func__); +} + +static void check_cookie_parse(const char *opt, knot_edns_cookie_t *cc, + knot_edns_cookie_t *sc, int code, const char *msg) +{ + const uint8_t *data = NULL; + uint16_t data_len = 0; + if (opt != NULL) { + data = knot_edns_opt_get_data((uint8_t *)opt); + data_len = knot_edns_opt_get_length((uint8_t *)opt); + } + + int ret = knot_edns_cookie_parse(cc, sc, data, data_len); + is_int(code, ret, "cookie parse ret: %s", msg); +} + +static void ok_cookie_check(const char *opt, knot_edns_cookie_t *cc, + knot_edns_cookie_t *sc, uint16_t cc_len, uint16_t sc_len, + const char *msg) +{ + check_cookie_parse(opt, cc, sc, KNOT_EOK, msg); + + is_int(cc->len, cc_len, "cookie parse cc len: %s", msg); + is_int(sc->len, sc_len, "cookie parse cc len: %s", msg); + + uint16_t size = knot_edns_cookie_size(cc, sc); + is_int(size, cc_len + sc_len, "cookie len: %s", msg); + + uint8_t buf[64]; + int ret = knot_edns_cookie_write(buf, sizeof(buf), cc, sc); + is_int(KNOT_EOK, ret, "cookie write ret: %s", msg); +} + +static void test_cookie(void) +{ + const char *good[] = { + "\x00\x0a" "\x00\x08" "\x00\x01\x02\x03\x04\x05\x06\x07", /* Only client cookie. */ + "\x00\x0a" "\x00\x10" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", /* 8 octets long server cookie. */ + "\x00\x0a" "\x00\x28" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27" /* 32 octets long server cookie. */ + }; + + const char *bad[] = { + "\x00\x0a" "\x00\x00", /* Zero length cookie. */ + "\x00\x0a" "\x00\x01" "\x00", /* Short client cookie. */ + "\x00\x0a" "\x00\x07" "\x00\x01\x02\x03\x04\x05\x06", /* Short client cookie. */ + "\x00\x0a" "\x00\x09" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08", /* Short server cookie. */ + "\x00\x0a" "\x00\x0f" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e", /* Short server cookie. */ + "\x00\x0a" "\x00\x29" "\x00\x01\x02\x03\x04\x05\x06\x07" "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28", /* Long server cookie. */ + }; + + knot_edns_cookie_t cc, sc; + + ok_cookie_check(good[0], &cc, &sc, 8, 0, "good cookie 0"); + ok_cookie_check(good[1], &cc, &sc, 8, 8, "good cookie 1"); + ok_cookie_check(good[2], &cc, &sc, 8, 32, "good cookie 2"); + + check_cookie_parse(NULL, &cc, &sc, KNOT_EINVAL, "no data"); + check_cookie_parse(good[0], NULL, &sc, KNOT_EINVAL, "no client cookie"); + check_cookie_parse(good[1], &cc, NULL, KNOT_EINVAL, "no server cookie"); + + check_cookie_parse(bad[0], &cc, &sc, KNOT_EMALF, "bad cookie 0"); + check_cookie_parse(bad[1], &cc, &sc, KNOT_EMALF, "bad cookie 1"); + check_cookie_parse(bad[2], &cc, &sc, KNOT_EMALF, "bad cookie 2"); + check_cookie_parse(bad[3], &cc, &sc, KNOT_EMALF, "bad cookie 3"); + check_cookie_parse(bad[4], &cc, &sc, KNOT_EMALF, "bad cookie 4"); + check_cookie_parse(bad[5], &cc, &sc, KNOT_EMALF, "bad cookie 5"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_rrset_t opt_rr; + int ret = knot_edns_init(&opt_rr, E_MAX_PLD, E_RCODE, E_VERSION, NULL); + is_int(KNOT_EOK, ret, "OPT RR: init"); + + /* Check initialized values (no NSID yet). */ + check_header(&opt_rr, E_MAX_PLD, E_VERSION, 0, E_RCODE, "OPT RR: check header"); + + test_setters(&opt_rr); + test_getters(&opt_rr); + test_alignment(); + test_keepalive(); + test_chain(); + test_cookie(); + + knot_rrset_clear(&opt_rr, NULL); + + return 0; +} diff --git a/tests/libknot/test_edns_ecs.c b/tests/libknot/test_edns_ecs.c new file mode 100644 index 0000000..9397d84 --- /dev/null +++ b/tests/libknot/test_edns_ecs.c @@ -0,0 +1,271 @@ +/* Copyright (C) 2020 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> + +#include <sys/socket.h> +#include <sys/types.h> +#include <netdb.h> + +#include "contrib/sockaddr.h" +#include "libknot/errcode.h" +#include "libknot/rrtype/opt.h" + +#define GARBAGE_BYTE 0xdb + +static void test_size(void) +{ + struct test { + const char *msg; + size_t expected; + knot_edns_client_subnet_t ecs; + }; + + static struct test const TESTS[] = { + // invalid + { "zero family", 0, { 0 } }, + { "zero family & source", 0, { 0, 1 } }, + { "unknown family", 0, { 42, 0 } }, + { "unknown family & source", 0, { 42, 1 } }, + // IPv4 bit ops + { "IPv4, zero source", 4, { 1 } }, + { "IPv4, 7 bits in last byte", 7, { 1, 23 } }, + { "IPv4, 8 bits in last byte", 7, { 1, 24 } }, + { "IPv4, 1 bit in last byte", 8, { 1, 25 } }, + // IPv6 bit ops + { "IPv6, zero source", 4, { 2 } }, + { "IPv6, 7 bits in last byte", 19, { 2, 113 } }, + { "IPv6, 8 bits in last byte", 19, { 2, 120 } }, + { "IPv6, 1 bit in last byte", 20, { 2, 121 } }, + // sources + { "IPv4, source < max", 8, { 1, 31 } }, + { "IPv4, source = max", 8, { 1, 32 } }, + { "IPv4, source > max", 0, { 1, 33 } }, + // scopes + { "IPv6, scope < source", 12, { 2, 64, 48 } }, + { "IPv6, scope = source", 20, { 2, 128, 128 } }, + { "IPv6, scope > max", 0, { 2, 128, 129 } }, + { NULL } + }; + + is_int(0, knot_edns_client_subnet_size(NULL), "%s: null", __func__); + + for (struct test const *t = TESTS; t->msg != NULL; t++) { + int r = knot_edns_client_subnet_size(&t->ecs); + is_int(t->expected, r, "%s: %s", __func__, t->msg); + } +} + +struct test_io { + const char *msg; + int expected; + size_t option_len; + const char *option; + knot_edns_client_subnet_t ecs; +}; + +static void test_write(void) +{ + static struct test_io const TESTS[] = { + // invalid + { "unset family", KNOT_EINVAL, 0, NULL, { 0 } }, + { "invalid family", KNOT_EINVAL, 0, NULL, { 3 } }, + { "small buffer", KNOT_ESPACE, 4, NULL, { 1, 1 } }, + // IPv4 prefix + { "IPv4, zero source", KNOT_EOK, 4, "\x00\x01\x00\x00", { 1 } }, + { "IPv4, 7 bits in LSB", KNOT_EOK, 6, "\x00\x01\x0f\x00\xff\xfe", { 1, 15, 0, "\xff\xff\xff\xff" } }, + { "IPv4, 8 bits in LSB", KNOT_EOK, 6, "\x00\x01\x10\x00\xff\xff", { 1, 16, 0, "\xff\xff\xff\xff" } }, + { "IPv4, 1 bit in LSB", KNOT_EOK, 7, "\x00\x01\x11\x00\xff\xff\x80", { 1, 17, 0, "\xff\xff\xff\xff" } }, + { "IPv4, source = max", KNOT_EOK, 8, "\x00\x01\x20\x00\xaa\xbb\xcc\xdd", { 1, 32, 0, "\xaa\xbb\xcc\xdd" } }, + { "IPv6, source > max", KNOT_EINVAL, 0, NULL, { 2, 129 } }, + // IPv6 scope + { "IPv6, scope < source", KNOT_EOK, 6, "\x00\x02\x10\x0e\xff\xff", { 2, 16, 14, "\xff\xff\xff\xff" } }, + { "IPv6, scope = source", KNOT_EOK, 6, "\x00\x02\x08\x08\xff", { 2, 8, 8, "\xff\xff\xff\xff" } }, + { "IPv6, scope > max", KNOT_EINVAL, 0, NULL, { 2, 128, 129 } }, + // other + { "larger buffer", KNOT_EOK, 7, "\x00\x01\x10\x0e\xff\xff\x00", { 1, 16, 14, "\xff\xff\xff\xff" } }, + { NULL } + }; + + for (struct test_io const *t = TESTS; t->msg != NULL; t++) { + uint8_t option[64]; + assert(sizeof(option) >= t->option_len); + memset(option, GARBAGE_BYTE, sizeof(option)); + + int r = knot_edns_client_subnet_write(option, t->option_len, &t->ecs); + ok(r == t->expected && + (t->expected != KNOT_EOK || memcmp(option, t->option, t->option_len) == 0), + "%s: %s", __func__, t->msg); + } +} + +static void test_parse(void) +{ + static struct test_io const TESTS[] = { + // invalid + { "null", KNOT_EINVAL, 0, NULL }, + { "empty buffer", KNOT_EMALF, 0, "" }, + { "incomplete header", KNOT_EMALF, 3, "\x00\x01\x00" }, + { "incomplete source", KNOT_EMALF, 5, "\x00\x0a\x00\x00\xff\xff" }, + { "zero family", KNOT_EMALF, 4, "\x00\x00\x00\x00" }, + { "unknown family", KNOT_EMALF, 4, "\x00\x03\x00\x00" }, + // IPv4 prefix + { "IPv4, zero source", KNOT_EOK, 4, "\x00\x01\x00\x00", { 1 } }, + { "IPv4, 7 bits in LSB", KNOT_EOK, 6, "\x00\x01\x0f\x00\xff\xfe", { 1, 15, 0, "\xff\xfe" } }, + { "IPv4, 9 bits in LSB", KNOT_EOK, 6, "\x00\x01\x10\x00\xff\xff", { 1, 16, 0, "\xff\xff" } }, + { "IPv4, 1 bit in LSB", KNOT_EOK, 7, "\x00\x01\x11\x00\xff\xff\x80", { 1, 17, 0, "\xff\xff\x80" } }, + { "IPv4, source = max", KNOT_EOK, 8, "\x00\x01\x20\x00\xaa\xbb\xcc\xdd", { 1, 32, 0, "\xaa\xbb\xcc\xdd" } }, + { "IPv4, dirty source", KNOT_EOK, 8, "\x00\x01\x0b\x00\xff\xff\xff\xff", { 1, 11, 0, "\xff\xe0" } }, + { "IPv4, source > max", KNOT_EMALF, 9, "\x00\x01\x21\x00\xaa\xbb\xcc\xdd\xee" }, + // IPv6 scope + { "IPv6 scope < source", KNOT_EOK, 5, "\x00\x02\x07\x05\xff", { 2, 7, 5, "\xfe" } }, + { "IPv6 scope = source", KNOT_EOK, 5, "\x00\x02\x06\x06\xff", { 2, 6, 6, "\xfc" } }, + { "IPv6 scope > max", KNOT_EMALF, 5, "\x00\x02\x06\x81\xff" }, + // extra buffer size + { "extra space", KNOT_EOK, 6, "\x00\x01\x00\x00\xff\x00", { 1 } }, + { "extra space", KNOT_EOK, 6, "\x00\x01\x01\x00\xff\x00", { 1, 1, 0, "\x80" } }, + { NULL } + }; + + for (struct test_io const *t = TESTS; t->msg != NULL; t++) { + knot_edns_client_subnet_t ecs = { 0 }; + memset(&ecs, GARBAGE_BYTE, sizeof(ecs)); + + int r = knot_edns_client_subnet_parse(&ecs, (uint8_t *)t->option, t->option_len); + ok(r == t->expected && + (t->expected != KNOT_EOK || memcmp(&ecs, &t->ecs, sizeof(ecs)) == 0), + "%s: %s", __func__, t->msg); + } +} + +static struct sockaddr_storage addr_init(const char *addr) +{ + struct sockaddr_storage sa = { 0 }; + + struct addrinfo hints = { .ai_flags = AI_NUMERICHOST }; + struct addrinfo *info = NULL; + int r = getaddrinfo(addr, NULL, &hints, &info); + (void)r; + assert(r == 0); + memcpy(&sa, info->ai_addr, info->ai_addrlen); + freeaddrinfo(info); + + return sa; +} + +static void test_set_address(void) +{ + int r; + knot_edns_client_subnet_t ecs = { 0 }; + struct sockaddr_storage ss = { 0 }; + + r = knot_edns_client_subnet_set_addr(NULL, &ss); + is_int(KNOT_EINVAL, r, "%s: missing ECS", __func__); + + r = knot_edns_client_subnet_set_addr(&ecs, NULL); + is_int(KNOT_EINVAL, r, "%s: missing address", __func__); + + memset(&ecs, GARBAGE_BYTE, sizeof(ecs)); + ss = addr_init("198.51.100.42"); + assert(ss.ss_family == AF_INET); + const uint8_t raw4[4] = { 198, 51, 100, 42 }; + + r = knot_edns_client_subnet_set_addr(&ecs, &ss); + ok(r == KNOT_EOK && + ecs.family == 1 && ecs.source_len == 32 && ecs.scope_len == 0 && + memcmp(ecs.address, raw4, sizeof(raw4)) == 0, + "%s: IPv4", __func__); + + memset(&ecs, GARBAGE_BYTE, sizeof(ecs)); + ss = addr_init("2001:db8::dead:beef"); + assert(ss.ss_family == AF_INET6); + const uint8_t raw6[16] = "\x20\x01\x0d\xb8\x00\x00\x00\x00" + "\x00\x00\x00\x00\xde\xad\xbe\xef"; + r = knot_edns_client_subnet_set_addr(&ecs, &ss); + ok(r == KNOT_EOK && + ecs.family == 2 && ecs.source_len == 128 && ecs.scope_len == 0 && + memcmp(ecs.address, raw6, sizeof(raw6)) == 0, + "%s: IPv6", __func__); + + const struct sockaddr_storage ss_unix = { .ss_family = AF_UNIX }; + r = knot_edns_client_subnet_set_addr(&ecs, &ss_unix); + is_int(KNOT_ENOTSUP, r, "%s: UNIX not supported", __func__); +} + +static bool sockaddr_eq(const struct sockaddr_storage *a, const struct sockaddr_storage *b) +{ + return sockaddr_cmp(a, b, true) == 0; +} + +static void test_get_address(void) +{ + struct test { + const char *msg; + int expected; + const char *addr_str; + knot_edns_client_subnet_t ecs; + }; + + static struct test const TESTS[] = { + // invalid + { "unset family", KNOT_ENOTSUP, NULL, { 0 } }, + { "unknown family", KNOT_ENOTSUP, NULL, { 3 } }, + // zero source + { "IPv4, any", KNOT_EOK, "0.0.0.0", { 1 } }, + { "IPv6, any", KNOT_EOK, "::0" , { 2 } }, + // IPv4 + { "IPv4, 7 bits in LSB", KNOT_EOK, "198.50.0.0", { 1, 15, 0, "\xc6\x33\xff\xff" } }, + { "IPv4, 8 bits in LSB", KNOT_EOK, "198.51.0.0", { 1, 16, 0, "\xc6\x33\xff\xff" } }, + { "IPv4, 1 bit in LSB", KNOT_EOK, "198.51.128.0", { 1, 17, 0, "\xc6\x33\xff\xff" } }, + { "IPv4, source = max", KNOT_EOK, "198.51.128.1", { 1, 32, 0, "\xc6\x33\x80\x01" } }, + // IPv6 + { "IPv6, 7 bits in LSB", KNOT_EOK, "2001:db8:200::", { 2, 39, 0, "\x20\x01\x0d\xb8\x03\xff" } }, + { "IPv6, 8 bits in LSB", KNOT_EOK, "2001:db8:100::", { 2, 40, 0, "\x20\x01\x0d\xb8\x01\xff" } }, + { "IPv6, 1 bit in LSB", KNOT_EOK, "2001:db8:180::", { 2, 41, 0, "\x20\x01\x0d\xb8\x01\xff" } }, + { "IPv6, source = max", KNOT_EOK, "2001:db8::1", { 2, 128, 0, "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" } }, + { NULL } + }; + + for (struct test const *t = TESTS; t->msg != NULL; t++) { + struct sockaddr_storage result = { 0 }; + int r = knot_edns_client_subnet_get_addr(&result, &t->ecs); + bool valid = false; + + if (t->expected == KNOT_EOK) { + struct sockaddr_storage addr = addr_init(t->addr_str); + assert(addr.ss_family != AF_UNSPEC); + valid = (r == t->expected && sockaddr_eq(&result, &addr)); + } else { + valid = (r == t->expected); + } + + ok(valid, "%s: %s", __func__, t->msg); + } +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_size(); + test_write(); + test_parse(); + test_set_address(); + test_get_address(); + + return 0; +} diff --git a/tests/libknot/test_endian.c b/tests/libknot/test_endian.c new file mode 100644 index 0000000..30f16f7 --- /dev/null +++ b/tests/libknot/test_endian.c @@ -0,0 +1,70 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/endian.h" + +int main(int argc, char *argv[]) +{ + plan(12); + + typedef union { + uint16_t value; + uint8_t array[2]; + } trafo16_t; + + const uint16_t host16 = 0x0102; + const trafo16_t be16 = { .array = { 0x01, 0x02 } }; + const trafo16_t le16 = { .array = { 0x02, 0x01 } }; + ok(htobe16(host16) == be16.value, "htobe16"); + ok(htole16(host16) == le16.value, "htole16"); + ok(be16toh(be16.value) == host16, "be16toh"); + ok(le16toh(le16.value) == host16, "le16toh"); + + typedef union { + uint32_t value; + uint8_t array[4]; + } trafo32_t; + + const uint32_t host32 = 0x01020304; + const trafo32_t be32 = { .array = { 0x01, 0x02, 0x03, 0x04 } }; + const trafo32_t le32 = { .array = { 0x04, 0x03, 0x02, 0x01 } }; + ok(htobe32(host32) == be32.value, "htobe32"); + ok(htole32(host32) == le32.value, "htole32"); + ok(be32toh(be32.value) == host32, "be32toh"); + ok(le32toh(le32.value) == host32, "le32toh"); + + typedef union { + uint64_t value; + uint8_t array[8]; + } trafo64_t; + + const uint64_t host64 = 0x0102030405060708; + const trafo64_t be64 = { .array = { 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08 } }; + const trafo64_t le64 = { .array = { 0x08, 0x07, 0x06, 0x05, + 0x04, 0x03, 0x02, 0x01 } }; + ok(htobe64(host64) == be64.value, "htobe64"); + ok(htole64(host64) == le64.value, "htole64"); + ok(be64toh(be64.value) == host64, "be64toh"); + ok(le64toh(le64.value) == host64, "le64toh"); + + return 0; +} diff --git a/tests/libknot/test_lookup.c b/tests/libknot/test_lookup.c new file mode 100644 index 0000000..3f7b514 --- /dev/null +++ b/tests/libknot/test_lookup.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2014 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "libknot/lookup.h" + +const knot_lookup_t test_table[] = { + { 0, "test item 0" }, + { 10, "" }, + { 2, "test item 2" }, + { -1, "test item -1" }, + { 0, NULL } +}; + +int main(int argc, char *argv[]) +{ + plan(9); + + /* Lookup by ID. */ + const knot_lookup_t *found = knot_lookup_by_id(test_table, 3); + ok(found == NULL, "lookup table: find by id - non-existent ID"); + + found = knot_lookup_by_id(test_table, 2); + ok(found && found->id == 2 && strcmp(found->name, "test item 2") == 0, + "lookup table: find by id - ID 2 (unordered IDs)"); + + found = knot_lookup_by_id(NULL, 2); + ok(found == NULL, "lookup table: find by id - table == NULL"); + + /* Lookup by name. */ + found = knot_lookup_by_name(test_table, "test item 2"); + ok(found && found->id == 2 && strcmp(found->name, "test item 2") == 0, + "lookup table: find by name - existent"); + + found = knot_lookup_by_name(test_table, ""); + ok(found && found->id == 10 && strcmp(found->name, "") == 0, + "lookup table: find by name - empty string"); + + found = knot_lookup_by_name(test_table, NULL); + ok(found == NULL, "lookup table: find by name - NULL name"); + + found = knot_lookup_by_name(NULL, "test item 2"); + ok(found == NULL, "lookup table: find by name - NULL table"); + + found = knot_lookup_by_name(NULL, NULL); + ok(found == NULL, "lookup table: find by name - NULL table & NULL name"); + + found = knot_lookup_by_name(test_table, "non existent name"); + ok(found == NULL, "lookup table: find by name - non-existent name"); + + return 0; +} diff --git a/tests/libknot/test_pkt.c b/tests/libknot/test_pkt.c new file mode 100644 index 0000000..fe31d3c --- /dev/null +++ b/tests/libknot/test_pkt.c @@ -0,0 +1,199 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "libknot/libknot.h" +#include "libknot/packet/pkt.c" +#include "contrib/ucw/mempool.h" + +#define TTL 7200 +#define NAMECOUNT 3 +#define DATACOUNT 3 +const char *g_names[NAMECOUNT] = { + "example.com", + "ns1.example.com", + "ns2.example.com" +}; + +const char *g_rdata[DATACOUNT] = { + "\x04" "\xc2\x0c\x00\x01", /* 4B, 194.0.12.1" */ + "\x11" "\x03""ns1""\x07""example""\x03""com""\x00", /* domain name */ + "\x11" "\x03""ns2""\x07""example""\x03""com""\x00", /* domain name */ +}; + +#define RDVAL(i) ((const uint8_t*)(g_rdata[(i)] + 1)) +#define RDLEN(i) ((uint16_t)(g_rdata[(i)][0])) + +/* @note Packet equivalence test, 5 checks. */ +static void packet_match(knot_pkt_t *in, knot_pkt_t *out) +{ + assert(in); + assert(out); + + /* Check counts */ + is_int(knot_wire_get_qdcount(out->wire), + knot_wire_get_qdcount(in->wire), "pkt: QD match"); + is_int(knot_wire_get_ancount(out->wire), + knot_wire_get_ancount(in->wire), "pkt: AN match"); + is_int(knot_wire_get_nscount(out->wire), + knot_wire_get_nscount(in->wire), "pkt: NS match"); + is_int(knot_wire_get_arcount(out->wire), + knot_wire_get_arcount(in->wire), "pkt: AR match"); + + /* Check RRs */ + int rr_matched = 0; + for (unsigned i = 0; i < NAMECOUNT; ++i) { + if (knot_rrset_equal(&out->rr[i], &in->rr[i], true) > 0) { + ++rr_matched; + } + } + is_int(NAMECOUNT, rr_matched, "pkt: RR content match"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Create memory pool context. */ + int ret = 0; + knot_mm_t mm; + mm_ctx_mempool(&mm, MM_DEFAULT_BLKSIZE); + + /* Create names and data. */ + knot_dname_t* dnames[NAMECOUNT] = {0}; + knot_rrset_t* rrsets[NAMECOUNT] = {0}; + for (unsigned i = 0; i < NAMECOUNT; ++i) { + dnames[i] = knot_dname_from_str_alloc(g_names[i]); + } + + uint8_t *edns_str = (uint8_t *)"ab"; + /* Create OPT RR. */ + knot_rrset_t opt_rr = { 0 }; + ret = knot_edns_init(&opt_rr, 1024, 0, 0, &mm); + is_int(KNOT_EOK, ret, "initialize OPT RR"); + + /* Add NSID */ + ret = knot_edns_add_option(&opt_rr, KNOT_EDNS_OPTION_NSID, + strlen((char *)edns_str), edns_str, &mm); + is_int(KNOT_EOK, ret, "initialize NSID in OPT RR"); + + /* + * Packet writer tests. + */ + + /* Create packet. */ + knot_pkt_t *out = knot_pkt_new(NULL, MM_DEFAULT_BLKSIZE, &mm); + ok(out != NULL, "pkt: new"); + assert(out); + + /* Mark as response (not part of the test). */ + knot_wire_set_qr(out->wire); + + /* Secure packet. */ + const char *tsig_secret = "abcd"; + knot_tsig_key_t tsig_key; + tsig_key.algorithm = DNSSEC_TSIG_HMAC_MD5; + tsig_key.name = dnames[0]; + tsig_key.secret.data = (uint8_t *)strdup(tsig_secret); + tsig_key.secret.size = strlen(tsig_secret); + ret = knot_pkt_reserve(out, knot_tsig_wire_size(&tsig_key)); + is_int(KNOT_EOK, ret, "pkt: set TSIG key"); + + /* Write question. */ + ret = knot_pkt_put_question(out, dnames[0], KNOT_CLASS_IN, KNOT_RRTYPE_A); + is_int(KNOT_EOK, ret, "pkt: put question"); + + /* Add OPT to packet (empty NSID). */ + ret = knot_pkt_reserve(out, knot_edns_wire_size(&opt_rr)); + is_int(KNOT_EOK, ret, "pkt: reserve OPT RR"); + + /* Begin ANSWER section. */ + ret = knot_pkt_begin(out, KNOT_ANSWER); + is_int(KNOT_EOK, ret, "pkt: begin ANSWER"); + + /* Write ANSWER section. */ + rrsets[0] = knot_rrset_new(dnames[0], KNOT_RRTYPE_A, KNOT_CLASS_IN, TTL, NULL); + knot_dname_free(dnames[0], NULL); + knot_rrset_add_rdata(rrsets[0], RDVAL(0), RDLEN(0), NULL); + ret = knot_pkt_put(out, KNOT_COMPR_HINT_QNAME, rrsets[0], 0); + is_int(KNOT_EOK, ret, "pkt: write ANSWER"); + + /* Begin AUTHORITY. */ + ret = knot_pkt_begin(out, KNOT_AUTHORITY); + is_int(KNOT_EOK, ret, "pkt: begin AUTHORITY"); + + /* Write rest to AUTHORITY. */ + ret = KNOT_EOK; + for (unsigned i = 1; i < NAMECOUNT; ++i) { + rrsets[i] = knot_rrset_new(dnames[i], KNOT_RRTYPE_NS, KNOT_CLASS_IN, TTL, NULL); + knot_dname_free(dnames[i], NULL); + knot_rrset_add_rdata(rrsets[i], RDVAL(i), RDLEN(i), NULL); + ret |= knot_pkt_put(out, KNOT_COMPR_HINT_NONE, rrsets[i], 0); + } + is_int(KNOT_EOK, ret, "pkt: write AUTHORITY(%u)", NAMECOUNT - 1); + + /* Begin ADDITIONALS */ + ret = knot_pkt_begin(out, KNOT_ADDITIONAL); + is_int(KNOT_EOK, ret, "pkt: begin ADDITIONALS"); + + /* Encode OPT RR. */ + ret = knot_pkt_put(out, KNOT_COMPR_HINT_NONE, &opt_rr, 0); + is_int(KNOT_EOK, ret, "pkt: write OPT RR"); + + /* + * Packet reader tests. + */ + + /* Create new packet from query packet. */ + knot_pkt_t *in = knot_pkt_new(out->wire, out->size, &out->mm); + ok(in != NULL, "pkt: create packet for parsing"); + + /* Read packet header. */ + ret = knot_pkt_parse_question(in); + is_int(KNOT_EOK, ret, "pkt: read header"); + + /* Read packet payload. */ + ret = parse_payload(in, 0); + is_int(KNOT_EOK, ret, "pkt: read payload"); + + /* Compare parsed packet to written packet. */ + packet_match(in, out); + + /* + * Copied packet tests. + */ + knot_pkt_t *copy = knot_pkt_new(NULL, in->max_size, &in->mm); + ret = knot_pkt_copy(copy, in); + is_int(KNOT_EOK, ret, "pkt: create packet copy"); + + /* Compare copied packet to original. */ + packet_match(in, copy); + + /* Free packets. */ + knot_pkt_free(copy); + knot_pkt_free(out); + knot_pkt_free(in); + + /* Free extra data. */ + for (unsigned i = 0; i < NAMECOUNT; ++i) { + knot_rrset_free(rrsets[i], NULL); + } + free(tsig_key.secret.data); + mp_delete((struct mempool *)mm.ctx); + + return 0; +} diff --git a/tests/libknot/test_probe.c b/tests/libknot/test_probe.c new file mode 100644 index 0000000..37437f4 --- /dev/null +++ b/tests/libknot/test_probe.c @@ -0,0 +1,96 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <tap/files.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#include "contrib/sockaddr.h" +#include "libknot/packet/pkt.c" +#include "libknot/probe/probe.h" + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + knot_probe_t *probe_out = knot_probe_alloc(); + ok(probe_out != NULL, "probe: initialize output probe"); + knot_probe_t *probe_in = knot_probe_alloc(); + ok(probe_in != NULL, "probe: initialize input probe"); + + int fd = knot_probe_fd(probe_out); + ok(fd < 0, "probe: unavailable fd"); + + char *workdir = test_mkdtemp(); + ok(workdir != NULL, "probe: create temporary workdir"); + + int ret = knot_probe_set_producer(probe_out, workdir, 1); + ok(ret == KNOT_ECONN, "probe: connect producer"); + + ret = knot_probe_set_consumer(probe_in, workdir, 1); + ok(ret == KNOT_EOK, "probe: connect consumer"); + fd = knot_probe_fd(probe_in); + ok(fd >= 0, "probe: get input probe fd"); + + ret = knot_probe_set_producer(probe_out, workdir, 1); + ok(ret == KNOT_EOK, "probe: reconnect producer"); + fd = knot_probe_fd(probe_out); + ok(fd >= 0, "probe: get output probe fd"); + + struct sockaddr_storage addr; + ret = sockaddr_set(&addr, AF_INET, "192.168.0.1", 53); + ok(ret == KNOT_EOK, "probe: set address"); + + knot_pkt_t *query = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, NULL); + ok(query != NULL, "probe: create query"); + knot_pkt_t *reply = knot_pkt_new(NULL, KNOT_WIRE_MAX_PKTSIZE, NULL); + ok(reply != NULL, "probe: create reply"); + + ret = knot_pkt_put_question(query, (const uint8_t *)"\x04test\x00", + KNOT_CLASS_IN, KNOT_RRTYPE_SOA); + ok(ret == KNOT_EOK, "probe: put query"); + + knot_probe_data_t data_out; + ret = knot_probe_data_set(&data_out, KNOT_PROBE_PROTO_UDP, + &addr, &addr, query, reply, KNOT_RCODE_NXDOMAIN); + ok(ret == KNOT_EOK, "probe: connect producer"); + + knot_pkt_free(query); + knot_pkt_free(reply); + + ret = knot_probe_produce(probe_out, &data_out, 1); + ok(ret == KNOT_EOK, "probe: produce datagram"); + + knot_probe_data_t data_in; + ret = knot_probe_consume(probe_in, &data_in, 1, 20); + ok(ret == 1, "probe: consume datagram"); + + ret = memcmp(&data_in, &data_out, offsetof(knot_probe_data_t, query.qname)); + ok(ret == 0, "probe: data comparison"); + + ret = knot_dname_cmp(data_in.query.qname, data_out.query.qname); + ok(ret == 0, "probe: qname comparison"); + + knot_probe_free(probe_in); + knot_probe_free(probe_out); + + test_rm_rf(workdir); + free(workdir); + + return 0; +} diff --git a/tests/libknot/test_rdata.c b/tests/libknot/test_rdata.c new file mode 100644 index 0000000..754cd7f --- /dev/null +++ b/tests/libknot/test_rdata.c @@ -0,0 +1,60 @@ +/* Copyright (C) 2017 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> +#include <tap/basic.h> + +#include "libknot/rdata.h" + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // Test array size + ok(knot_rdata_size(1) == 2 + 1 + 1, "rdata: array size odd."); + ok(knot_rdata_size(2) == 2 + 2, "rdata: array size even."); + + // Test init + const size_t data_size = 16; + uint8_t buf1[knot_rdata_size(data_size)]; + knot_rdata_t *rdata = (knot_rdata_t *)buf1; + uint8_t payload[] = "abcdefghijklmnop"; + knot_rdata_init(rdata, data_size, payload); + const bool set_ok = rdata->len == data_size && + memcmp(rdata->data, payload, data_size) == 0; + ok(set_ok, "rdata: init."); + + // Test compare + rdata->len = data_size; + ok(knot_rdata_cmp(rdata, rdata) == 0, "rdata: cmp eq."); + + knot_rdata_t *lower = rdata; + uint8_t buf2[knot_rdata_size(data_size)]; + knot_rdata_t *greater = (knot_rdata_t *)buf2; + knot_rdata_init(greater, data_size, (uint8_t *)"qrstuvwxyz123456"); + ok(knot_rdata_cmp(lower, greater) < 0, "rdata: cmp lower."); + ok(knot_rdata_cmp(greater, lower) > 0, "rdata: cmp greater."); + + // Payloads will be the same. + memcpy(greater->data, lower->data, data_size); + assert(knot_rdata_cmp(lower, greater) == 0); + + lower->len = data_size - 1; + ok(knot_rdata_cmp(lower, greater) < 0, "rdata: cmp lower size."); + ok(knot_rdata_cmp(greater, lower) > 0, "rdata: cmp greater size."); + + return 0; +} diff --git a/tests/libknot/test_rdataset.c b/tests/libknot/test_rdataset.c new file mode 100644 index 0000000..d364be3 --- /dev/null +++ b/tests/libknot/test_rdataset.c @@ -0,0 +1,227 @@ +/* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> +#include <string.h> + +#include "libknot/rdataset.c" +#include "libknot/libknot.h" + +// Inits rdataset with given rdata. +#define RDATASET_INIT_WITH(set, rdata) \ + knot_rdataset_clear(&set, NULL); \ + ret = knot_rdataset_add(&set, rdata, NULL); \ + assert(ret == KNOT_EOK); + +static size_t rdataset_size(const knot_rdataset_t *rrs) +{ + if (rrs == NULL || rrs->count == 0) { + return 0; + } + + const knot_rdata_t *last = rr_seek(rrs, rrs->count - 1); + return (uint8_t *)last + knot_rdata_size(last->len) - (uint8_t *)rrs->rdata; +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // Test init + knot_rdataset_t rdataset; + knot_rdataset_init(&rdataset); + ok(rdataset.rdata == NULL && rdataset.count == 0 && rdataset.size == 0, "rdataset: init."); + + // Test rdata addition + uint8_t buf_gt[knot_rdata_size(4)]; + knot_rdata_t *rdata_gt = (knot_rdata_t *)buf_gt; + knot_rdata_init(rdata_gt, 4, (uint8_t *)"wxyz"); + + int ret = knot_rdataset_add(NULL, NULL, NULL); + is_int(KNOT_EINVAL, ret, "rdataset: add NULL."); + ret = knot_rdataset_add(&rdataset, rdata_gt, NULL); + bool add_ok = ret == KNOT_EOK && rdataset.count == 1 && + knot_rdata_cmp(rdata_gt, rdataset.rdata) == 0; + ok(add_ok, "rdataset: add."); + + uint8_t buf_lo[knot_rdata_size(4)]; + knot_rdata_t *rdata_lo = (knot_rdata_t *)buf_lo; + knot_rdata_init(rdata_lo, 4, (uint8_t *)"abcd"); + ret = knot_rdataset_add(&rdataset, rdata_lo, NULL); + add_ok = ret == KNOT_EOK && rdataset.count == 2 && + knot_rdata_cmp(rdata_lo, rdataset.rdata) == 0; + ok(add_ok, "rdataset: add lower."); + + // Test getters + ok(knot_rdata_cmp(knot_rdataset_at(&rdataset, 0), rdata_lo) == 0 && + knot_rdata_cmp(knot_rdataset_at(&rdataset, 1), rdata_gt) == 0, + "rdataset: at."); + + ok(rdataset_size(&rdataset) == knot_rdata_size(4) * 2, + "rdataset: size."); + ok(rdataset.size == rdataset_size(&rdataset), "rdataset: size precomputed (%u %zu).", + rdataset.size, rdataset_size(&rdataset)); + + // Test copy + ok(knot_rdataset_copy(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: copy NULL."); + knot_rdataset_t copy; + ret = knot_rdataset_copy(©, &rdataset, NULL); + const bool copy_ok = ret == KNOT_EOK && copy.count == rdataset.count && + rdataset_size(©) == rdataset_size(&rdataset) && + rdataset.rdata != NULL && copy.rdata != NULL && + memcmp(rdataset.rdata, copy.rdata, + rdataset_size(&rdataset)) == 0; + ok(copy_ok, "rdataset: copy"); + ok(copy.size == rdataset_size(©), "copy: size precomputed."); + + // Test eq + ok(knot_rdataset_eq(&rdataset, ©), "rdataset: equal"); + + // Test clear + knot_rdataset_clear(©, NULL); + ok(copy.count == 0 && copy.rdata == NULL, "rdataset: clear."); + + // Test not equal (different count) + ok(!knot_rdataset_eq(&rdataset, ©), "rdataset: not equal - count"); + + // Test member + uint8_t buf_not[knot_rdata_size(1)]; + knot_rdata_t *not_a_member = (knot_rdata_t *)buf_not; + knot_rdata_init(not_a_member, 1, (uint8_t *)"?"); + ok(knot_rdataset_member(&rdataset, rdata_gt), "rdataset: is member."); + ok(!knot_rdataset_member(&rdataset, not_a_member), "rdataset: is not member."); + + // Test merge + ok(knot_rdataset_merge(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: merge NULL."); + knot_rdataset_t empty; + knot_rdataset_init(&empty); + ret = knot_rdataset_merge(&empty, &rdataset, NULL); + bool merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&empty, &rdataset); + ok(merge_ok, "rdataset: merge empty."); + knot_rdata_t *data_before = rdataset.rdata; + ret = knot_rdataset_merge(&rdataset, &rdataset, NULL); + merge_ok = ret == KNOT_EOK && rdataset.count == 2 && + data_before == rdataset.rdata; + ok(merge_ok, "rdataset: merge self."); + + knot_rdataset_clear(&empty, NULL); + + // Init structs for merge sort testing + knot_rdataset_t rdataset_lo; // "Lower" rdataset + knot_rdataset_init(&rdataset_lo); + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + knot_rdataset_t rdataset_gt; // "Greater" rdataset + knot_rdataset_init(&rdataset_gt); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + + // Test not equal - different data + ok(!knot_rdataset_eq(&rdataset_gt, &rdataset_lo), "rdataset: data not equal."); + + // Test that merge keeps the sorted order + ret = knot_rdataset_merge(&rdataset_lo, &rdataset_gt, NULL); + merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset_lo, &rdataset); + ok(merge_ok, "rdataset: merge into lower."); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + ret = knot_rdataset_merge(&rdataset_gt, &rdataset_lo, NULL); + merge_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset_gt, &rdataset); + ok(merge_ok, "rdataset: merge into greater."); + + // Test intersect + ok(knot_rdataset_intersect(NULL, NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: intersect NULL."); + + knot_rdataset_t intersection; + ret = knot_rdataset_intersect(&rdataset, &rdataset, &intersection, NULL); + bool intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset, &intersection); + ok(intersect_ok, "rdataset: intersect self."); + knot_rdataset_clear(&intersection, NULL); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + ret = knot_rdataset_intersect(&rdataset_lo, &rdataset_gt, &intersection, NULL); + intersect_ok = ret == KNOT_EOK && intersection.count == 0; + ok(intersect_ok, "rdataset: intersect no common."); + + ret = knot_rdataset_intersect(&rdataset, &rdataset_lo, &intersection, NULL); + intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(&intersection, &rdataset_lo); + ok(intersect_ok, "rdataset: intersect normal."); + knot_rdataset_clear(&intersection, NULL); + + // Test intersect2 + ok(knot_rdataset_intersect2(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: intersect2 NULL."); + + ret = knot_rdataset_intersect2(&rdataset, &rdataset, NULL); + intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(&rdataset, &rdataset); + ok(intersect_ok, "rdataset: intersect2 self."); + knot_rdataset_clear(&intersection, NULL); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + ret = knot_rdataset_intersect2(&rdataset_lo, &rdataset_gt, NULL); + intersect_ok = ret == KNOT_EOK && rdataset_lo.count == 0; + ok(intersect_ok, "rdataset: intersect2 no common."); + + ret = knot_rdataset_copy(©, &rdataset, NULL); + assert(ret == KNOT_EOK); + ret = knot_rdataset_intersect2(©, &rdataset_lo, NULL); + intersect_ok = ret == KNOT_EOK && knot_rdataset_eq(©, &rdataset_lo); + ok(intersect_ok, "rdataset: intersect2 normal."); + knot_rdataset_clear(©, NULL); + + // Test subtract + ok(knot_rdataset_subtract(NULL, NULL, NULL) == KNOT_EINVAL, + "rdataset: subtract NULL."); + ret = knot_rdataset_copy(©, &rdataset, NULL); + assert(ret == KNOT_EOK); + ok(knot_rdataset_subtract(©, ©, NULL) == KNOT_EOK && + copy.count == 0, "rdataset: subtract self."); + + ret = knot_rdataset_copy(©, &rdataset, NULL); + assert(ret == KNOT_EOK); + ret = knot_rdataset_subtract(©, &rdataset, NULL); + bool subtract_ok = ret == KNOT_EOK && copy.count == 0; + ok(subtract_ok, "rdataset: subtract identical."); + + RDATASET_INIT_WITH(rdataset_lo, rdata_lo); + RDATASET_INIT_WITH(rdataset_gt, rdata_gt); + data_before = rdataset_lo.rdata; + ret = knot_rdataset_subtract(&rdataset_lo, &rdataset_gt, NULL); + subtract_ok = ret == KNOT_EOK && rdataset_lo.count == 1 && + rdataset_lo.rdata == data_before; + ok(subtract_ok, "rdataset: subtract no common."); + + ret = knot_rdataset_subtract(&rdataset, &rdataset_gt, NULL); + subtract_ok = ret == KNOT_EOK && rdataset.count == 1; + ok(subtract_ok, "rdataset: subtract the second."); + + ret = knot_rdataset_subtract(&rdataset, &rdataset_lo, NULL); + subtract_ok = ret == KNOT_EOK && rdataset.count == 0 && + rdataset.rdata == NULL; + ok(subtract_ok, "rdataset: subtract last."); + + knot_rdataset_clear(©, NULL); + knot_rdataset_clear(&rdataset, NULL); + knot_rdataset_clear(&rdataset_lo, NULL); + knot_rdataset_clear(&rdataset_gt, NULL); + + return EXIT_SUCCESS; +} diff --git a/tests/libknot/test_rrset-wire.c b/tests/libknot/test_rrset-wire.c new file mode 100644 index 0000000..35dc1bc --- /dev/null +++ b/tests/libknot/test_rrset-wire.c @@ -0,0 +1,264 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <tap/basic.h> + +#include "libknot/packet/rrset-wire.h" +#include "libknot/descriptor.h" +#include "libknot/errcode.h" + +// Wire initializers + +#define MESSAGE_HEADER(AN, AUTH, ADD) 0xd4, 0xec, 0x81, 0xa0, 0x00, 0x01, \ + 0x00, AN, 0x00, AUTH, 0x00, ADD + +#define QUERY(qname, type) qname, 0x00, type, 0x00, 0x01 + +#define RR_HEADER(owner, type, rdlength0, rdlength1) owner, 0x00, type, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, rdlength0, rdlength1 + +#define QNAME_POINTER 0xc0, 0x0c + +// Initializers' sizes + +#define QUERY_SIZE 12 + 4 +#define RR_HEADER_SIZE 10 + +// Sample domain names + +#define QNAME 0x03, 0x6e, 0x69, 0x63, 0x02, 0x63, 0x7a, 0x00 +#define QNAME_SIZE 8 +#define QNAME_LONG \ +0x3f,'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', \ +'m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', \ +'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', \ +'m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'w', 'y', \ +'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 0x3f,\ +'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', \ +'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', \ +'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', \ +'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'x', 'y', 'z', \ +'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 0x3f,'a', \ +'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', \ +'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', \ +'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', \ +'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'x', 'y', 'z', 'a', \ +'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'i', 'k', 0x3d,'a', 'b', \ +'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', \ +'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', \ +'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', \ +'p', 'q', 'r', 's', 't', 'u', 'v', 'x', 'x', 'y', 'z', 'a', 'b', \ +'c', 'd', 'e', 'f', 'g', 'h', 'i', 0x00 +#define QNAME_LONG_SIZE 255 +#define POINTER_SIZE 2 + +struct wire_data { + uint8_t wire[65535]; + size_t size; + size_t pos; + int code; + const char *msg; +}; + +#define FROM_CASE_COUNT 17 + +static const struct wire_data FROM_CASES[FROM_CASE_COUNT] = { +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A)}, + .size = QUERY_SIZE + QNAME_SIZE, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "No header" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A), 0x00, 0x00, 0x01}, + .size = QUERY_SIZE + QNAME_SIZE + 3, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "Partial header" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A), + RR_HEADER(QNAME, KNOT_RRTYPE_A, 0x00, 0x04) }, + .size = QUERY_SIZE + RR_HEADER_SIZE + QNAME_SIZE * 2, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "No RDATA" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A), + RR_HEADER(QNAME, KNOT_RRTYPE_A, 0x00, 0x04), 0x01 }, + .size = QUERY_SIZE + RR_HEADER_SIZE + QNAME_SIZE * 2 + 1, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "Partial RDATA" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A), + RR_HEADER(QNAME, KNOT_RRTYPE_A, 0x00, 0x04), 0x01, 0x02, 0x03, 0x04 }, + .size = QUERY_SIZE + RR_HEADER_SIZE + QNAME_SIZE * 2 + 4, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "OK RDATA" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_A), + RR_HEADER(QNAME, KNOT_RRTYPE_A, 0x00, 0x05), 0x01, 0x02, 0x03, 0x04, 0x05 }, + .size = QUERY_SIZE + RR_HEADER_SIZE + QNAME_SIZE * 2 + 5, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "Trailing RDATA" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME_LONG, KNOT_RRTYPE_SOA), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_SOA, 0x00, 0x18), QNAME_POINTER, QNAME_POINTER, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + .size = QUERY_SIZE + RR_HEADER_SIZE + QNAME_LONG_SIZE + 6 + 20, + .pos = QUERY_SIZE + QNAME_LONG_SIZE, + .code = KNOT_EOK, + .msg = "Max DNAME" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_SIG), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_SIG, 0xff, 0xdb), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, QNAME }, + .size = 65535, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "Max RDLENGTH" }, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME_LONG, KNOT_RRTYPE_SIG), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_SIG, 0xff, 0xff), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, QNAME_POINTER }, + .size = 65535 + QNAME_LONG_SIZE + QUERY_SIZE + RR_HEADER_SIZE + 2, + .pos = QUERY_SIZE + QNAME_LONG_SIZE, + .code = KNOT_EMALF, + .msg = "Max RDLENGTH + compression"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_NSEC), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_NSEC, 0x00, 0x03), + QNAME_POINTER, 0x00}, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 2 + 1, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "DNAME wrong compression"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_NAPTR), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_NAPTR, 0x00, 0x01), + 0x00}, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 1, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "NAPTR missing header"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_NAPTR), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_NAPTR, 0x00, 0x09), + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, QNAME_POINTER}, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 9, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "NAPTR bad offset"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_NAPTR), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_NAPTR, 0x00, 0x09), + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 7, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "NAPTR no DNAME"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_NAPTR), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_NAPTR, 0x00, 0x0c), + 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x01, 0xff, 0x01, 0xff, QNAME_POINTER}, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 10 + 2, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "NAPTR valid"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_APL), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_APL, 0x00, 0x00) }, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "Valid 0 RDATA"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_TXT), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_TXT, 0x00, 0x00) }, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EMALF, + .msg = "Invalid 0 RDATA"}, +{ .wire = { MESSAGE_HEADER(1, 0, 0), QUERY(QNAME, KNOT_RRTYPE_PX), + RR_HEADER(QNAME_POINTER, KNOT_RRTYPE_PX, 0x00, 0x06), + 0x00, 0x00, QNAME_POINTER, QNAME_POINTER }, + .size = QUERY_SIZE + QNAME_SIZE + RR_HEADER_SIZE + 2 + 6, + .pos = QUERY_SIZE + QNAME_SIZE, + .code = KNOT_EOK, + .msg = "Obsolete RR type"}, +}; + +#define TEST_CASE_FROM(rrset, i) size_t _pos##i = FROM_CASES[i].pos; \ + ok(knot_rrset_rr_from_wire(FROM_CASES[i].wire, &_pos##i, FROM_CASES[i].size, \ + rrset, NULL, true) == FROM_CASES[i].code, "rrset wire: %s", FROM_CASES[i].msg) + +static void test_inputs(void) +{ + for (size_t i = 0; i < FROM_CASE_COUNT; ++i) { + knot_rrset_t rrset; + knot_rrset_init_empty(&rrset); + TEST_CASE_FROM(&rrset, i); + knot_rrset_clear(&rrset, NULL); + } +} + +static void check_canon(uint8_t *wire, size_t size, size_t pos, bool canon, + knot_dname_t *qname, knot_dname_t *dname) +{ + knot_rrset_t rrset; + knot_rrset_init_empty(&rrset); + + int ret = knot_rrset_rr_from_wire(wire, &pos, size, &rrset, NULL, canon); + is_int(KNOT_EOK, ret, "OK %s canonization", canon ? "with" : "without"); + ok(memcmp(rrset.owner, qname, knot_dname_size(qname)) == 0, "compare owner"); + + uint8_t *rdata = rrset.rrs.rdata->data; + ok(memcmp(rdata, dname, knot_dname_size(dname)) == 0, "compare rdata dname"); + + knot_rrset_clear(&rrset, NULL); +} + +static void test_canonization(void) +{ + #define UPP_QNAME_SIZE 5 + #define UPP_QNAME 0x01, 0x41, 0x01, 0x5a, 0x00 // A.Z. + #define LOW_QNAME 0x01, 0x61, 0x01, 0x7a, 0x00 // a.z. + + #define UPP_DNAME_SIZE 3 + #define UPP_DNAME 0x01, 0x58, 0x00 // X. + #define LOW_DNAME 0x01, 0x78, 0x00 // x. + + uint8_t wire[] = { + MESSAGE_HEADER(1, 0, 0), QUERY(UPP_QNAME, KNOT_RRTYPE_NS), + RR_HEADER(UPP_QNAME, KNOT_RRTYPE_NS, 0x00, UPP_DNAME_SIZE), UPP_DNAME + }; + size_t size = QUERY_SIZE + RR_HEADER_SIZE + UPP_QNAME_SIZE * 2 + UPP_DNAME_SIZE; + size_t pos = QUERY_SIZE + UPP_QNAME_SIZE; + + knot_dname_t upp_qname[] = { UPP_QNAME }; + knot_dname_t upp_dname[] = { UPP_DNAME }; + check_canon(wire, size, pos, false, upp_qname, upp_dname); + + knot_dname_t low_qname[] = { LOW_QNAME }; + knot_dname_t low_dname[] = { LOW_DNAME }; + check_canon(wire, size, pos, true, low_qname, low_dname); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("Test NULL parameters"); + int ret = knot_rrset_rr_from_wire(NULL, NULL, 0, NULL, NULL, true); + is_int(KNOT_EINVAL, ret, "rr wire: Invalid params"); + + diag("Test various inputs"); + test_inputs(); + + diag("Test canonization"); + test_canonization(); + + return 0; +} diff --git a/tests/libknot/test_rrset.c b/tests/libknot/test_rrset.c new file mode 100644 index 0000000..cc67e0f --- /dev/null +++ b/tests/libknot/test_rrset.c @@ -0,0 +1,121 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <assert.h> +#include <inttypes.h> +#include <tap/basic.h> + +#include "libknot/rrset.h" +#include "libknot/descriptor.h" + +static bool check_rrset(const knot_rrset_t *rrset, const knot_dname_t *owner, + uint16_t type, uint16_t rclass, uint32_t ttl) +{ + if (!rrset) { + return false; + } + + const bool dname_cmp = owner == NULL ? rrset->owner == NULL : + knot_dname_is_equal(rrset->owner, owner); + return rrset->type == type && rrset->rclass == rclass && dname_cmp && + rrset->ttl == ttl && rrset->rrs.count == 0; // We do not test rdataset here +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // Test new + knot_dname_t *dummy_owner = knot_dname_from_str_alloc("test."); + assert(dummy_owner); + + knot_rrset_t *rrset = knot_rrset_new(dummy_owner, KNOT_RRTYPE_TXT, + KNOT_CLASS_IN, 3600, NULL); + ok(rrset != NULL, "rrset: create."); + assert(rrset); + + ok(check_rrset(rrset, dummy_owner, KNOT_RRTYPE_TXT, KNOT_CLASS_IN, 3600), + "rrset: set fields during create."); + + // Test init + knot_dname_free(dummy_owner, NULL); + dummy_owner = knot_dname_from_str_alloc("test2."); + assert(dummy_owner); + + knot_dname_free(rrset->owner, NULL); + knot_rrset_init(rrset, dummy_owner, KNOT_RRTYPE_A, KNOT_CLASS_CH, 7200); + ok(check_rrset(rrset, dummy_owner, KNOT_RRTYPE_A, KNOT_CLASS_CH, 7200), + "rrset: init."); + + // Test copy + knot_rrset_t *copy = knot_rrset_copy(rrset, NULL); + ok(copy != NULL, "rrset: copy."); + ok(check_rrset(copy, rrset->owner, rrset->type, rrset->rclass, 7200), + "rrset: set fields during copy."); + ok(knot_rrset_copy(NULL, NULL) == NULL, "rrset: copy NULL."); + assert(copy); + + // Test equal - same TTL + ok(knot_rrset_equal(rrset, copy, true), "rrset: cmp same TTL"); + + // Test equal - different TTL + copy->ttl++; + ok(!knot_rrset_equal(rrset, copy, true), "rrset: cmp different TTL"); + + // Test equal - ignore TTL + ok(knot_rrset_equal(rrset, copy, false), "rrset: cmp ignore TTL"); + + copy->ttl = rrset->ttl; + + // Test equal - different type + copy->type++; + ok(!knot_rrset_equal(rrset, copy, true), "rrset: cmp different type"); + + copy->type = rrset->type; + + // Test equal - owners + knot_dname_free(rrset->owner, NULL); + rrset->owner = NULL; + ok(!knot_rrset_equal(rrset, copy, true), "rrset: cmp NULL owner"); + + knot_dname_free(copy->owner, NULL); + copy->owner = NULL; + ok(knot_rrset_equal(rrset, copy, true), "rrset: cmp NULL owners"); + + // Test equal - different rdata + knot_rrset_add_rdata(copy, (const uint8_t *)"abc", 3, NULL); + ok(!knot_rrset_equal(rrset, copy, true), "rrset: cmp different rdata"); + + // Test clear + knot_rrset_clear(rrset, NULL); + ok(rrset->owner == NULL, "rrset: clear."); + + // Test empty + ok(knot_rrset_empty(rrset), "rrset: empty."); + ok(knot_rrset_empty(NULL), "rrset: empty NULL."); + copy->rrs.count = 1; + ok(!knot_rrset_empty(copy), "rrset: not empty."); + + // Test init empty + knot_rrset_init_empty(rrset); + ok(check_rrset(rrset, NULL, 0, KNOT_CLASS_IN, 0), "rrset: init empty."); + + // "Test" freeing + knot_rrset_free(rrset, NULL); + knot_rrset_free(copy, NULL); + + return 0; +} diff --git a/tests/libknot/test_tsig.c b/tests/libknot/test_tsig.c new file mode 100644 index 0000000..a34e7ca --- /dev/null +++ b/tests/libknot/test_tsig.c @@ -0,0 +1,204 @@ +/* Copyright (C) 2015 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <assert.h> +#include <stdbool.h> +#include <string.h> +#include <unistd.h> + +#include "libknot/errcode.h" +#include "libknot/tsig.h" + +static bool key_is_eq(const knot_tsig_key_t *a, const knot_tsig_key_t *b) +{ + if (a == NULL && b == NULL) { + return true; + } + + if (a == NULL || b == NULL) { + return false; + } + + return a->algorithm == b->algorithm && + knot_dname_is_equal(a->name, b->name) && + dnssec_binary_cmp(&a->secret, &b->secret) == 0; +} + +#define test_function(function, msg, expected, ...) \ + knot_tsig_key_t key = { 0 }; \ + int r = function(&key, __VA_ARGS__); \ + ok((r != KNOT_EOK && expected == NULL) || \ + (r == KNOT_EOK && key_is_eq(&key, expected)), \ + "%s: %s", #function, msg); \ + knot_tsig_key_deinit(&key); + +static void test_init(const char *msg, const knot_tsig_key_t *expected, + const char *algo, const char *name, const char *secret) +{ + test_function(knot_tsig_key_init, msg, expected, algo, name, secret); +} + +static void test_init_str(const char *msg, const knot_tsig_key_t *expected, + const char *params) +{ + test_function(knot_tsig_key_init_str, msg, expected, params); +} + +static void test_init_file(const char *msg, const knot_tsig_key_t *expected, + const char *filename) +{ + test_function(knot_tsig_key_init_file, msg, expected, filename); +} + +static void test_init_file_content(const char *msg, + const knot_tsig_key_t *expected, + const char *content) +{ + char filename[] = "testkey.XXXXXX"; + + int fd = mkstemp(filename); + if (fd == -1) { + bail("failed to create temporary file"); + return; + } + + ok(write(fd, content, strlen(content)) != -1, "file write"); + close(fd); + + test_init_file(msg, expected, filename); + + unlink(filename); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // initialization from parameters + + test_init("missing name", NULL, "hmac-md5", NULL, "Wg=="); + test_init("missing secret", NULL, "hmac-md5", "name", NULL); + test_init("invalid HMAC", NULL, "hmac-sha11", "name", "Wg=="); + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA256, + .name = (uint8_t *)"\x3""key""\x4""name", + .secret.size = 1, + .secret.data = (uint8_t *)"\x5a" + }; + test_init("default algorithm", &key, NULL, "key.name", "Wg=="); + } + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA1, + .name = (uint8_t *)"\x4""knot""\x3""dns", + .secret.size = 6, + .secret.data = (uint8_t *)"secret" + }; + test_init("sha1", &key, "hmac-sha1", "knot.dns.", "c2VjcmV0"); + } + + // initialization from string + + test_init_str("missing value", NULL, NULL); + test_init_str("malformed", NULL, "this is malformed"); + test_init_str("invalid HMAC", NULL, "hmac-sha51299:key:Wg=="); + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA256, + .name = (uint8_t *)"\x4""tsig""\x3""key", + .secret.size = 9, + .secret.data = (uint8_t *)"bananakey" + }; + test_init_str("default algorithm", &key, "tsig.key:YmFuYW5ha2V5"); + } + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA384, + .name = (uint8_t *)"\x6""strong""\x3""key", + .secret.size = 8, + .secret.data = (uint8_t *)"applekey" + }; + test_init_str("sha384", &key, "hmac-sha384:strong.KEY:YXBwbGVrZXk="); + } + + // initialization from a file + + test_init_file("no filename", NULL, NULL); + test_init_file("not-existing", NULL, "/this-really-should-not-exist"); + test_init_file_content("malformed content", NULL, "malformed\n"); + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA512, + .name = (uint8_t *)"\x6""django""\x3""one", + .secret.size = 40, + .secret.data = (uint8_t *)"Who's that stumbling around in the dark?" + }; + test_init_file_content("sha512", &key, + "hmac-sha512:django.one:V2hvJ3MgdGhhdCB" + "zdHVtYmxpbmcgYXJvdW5kIGluIHRoZSBkYXJrP" + "w==\n\n\n"); + } + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA512, + .name = (uint8_t *)"\x6""django""\x3""two", + .secret.size = 22, + .secret.data = (uint8_t *)"Prepare to get winged!" + }; + test_init_file_content("sha512 without newline", &key, + "hmac-sha512:django.two:UHJlcGFyZSB0byB" + "nZXQgd2luZ2VkIQ=="); + } + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA1, + .name = (uint8_t *)"\x4""test", + .secret.size = 1, + .secret.data = (uint8_t *)"\x5a" + }; + test_init_file_content("leading and trailing white spaces", &key, + "\thmac-sha1:test:Wg== \n"); + } + + // tsig key duplication + + { + static const knot_tsig_key_t key = { + .algorithm = DNSSEC_TSIG_HMAC_SHA1, + .name = (uint8_t *)"\x4""copy""\x2""me", + .secret.size = 6, + .secret.data = (uint8_t *)"orange" + }; + + knot_tsig_key_t copy = { 0 }; + int r; + + r = knot_tsig_key_copy(NULL, &key); + ok(r != KNOT_EOK, "knot_tsig_key_copy: no destination"); + r = knot_tsig_key_copy(©, NULL); + ok(r != KNOT_EOK, "knot_tsig_key_copy: no source"); + r = knot_tsig_key_copy(©, &key); + ok(r == KNOT_EOK && key_is_eq(©, &key) && + copy.secret.data != key.secret.data && copy.name != key.name, + "knot_tsig_key_copy: simple copy"); + + knot_tsig_key_deinit(©); + } + + return 0; +} diff --git a/tests/libknot/test_wire.c b/tests/libknot/test_wire.c new file mode 100644 index 0000000..3e2468c --- /dev/null +++ b/tests/libknot/test_wire.c @@ -0,0 +1,46 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "libknot/wire.h" + +#define write_test(size, value, ...) { \ + const uint8_t expect[] = { __VA_ARGS__ }; \ + uint8_t wdata[sizeof(expect)] = { 0x00 }; \ + knot_wire_write_u ## size(wdata, value); \ + ok(memcmp(wdata, expect, sizeof(expect)) == 0, "%d-bit write", size); \ +} + +int main(int argc, char *argv[]) +{ + plan(8); + + const uint8_t rdata[] = { 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + + is_hex( 0x8899, knot_wire_read_u16(rdata), "16-bit read"); + is_hex( 0x8899aabb, knot_wire_read_u32(rdata), "32-bit read"); + is_hex( 0x8899aabbccdd, knot_wire_read_u48(rdata), "48-bit read"); + is_hex(0x8899aabbccddeeff, knot_wire_read_u64(rdata), "64-bit read"); + + write_test(16, 0x1122, 0x11, 0x22); + write_test(32, 0x66778899, 0x66, 0x77, 0x88, 0x99); + write_test(48, 0xbbccdd778899, 0xbb, 0xcc, 0xdd, 0x77, 0x88, 0x99); + write_test(64, 0xbbccddee66778899, 0xbb, 0xcc, 0xdd, 0xee, + 0x66, 0x77, 0x88, 0x99); + + return 0; +} diff --git a/tests/libknot/test_xdp_tcp.c b/tests/libknot/test_xdp_tcp.c new file mode 100644 index 0000000..3e366b1 --- /dev/null +++ b/tests/libknot/test_xdp_tcp.c @@ -0,0 +1,638 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <unistd.h> + +#include "tap/basic.h" +#include "libknot/error.h" +#include "libknot/xdp/msg_init.h" +#include "libknot/xdp/tcp.c" +#include "libknot/xdp/tcp_iobuf.c" +#include "libknot/xdp/bpf-user.h" + +#define INFTY INT32_MAX + +knot_tcp_table_t *test_table = NULL; +knot_tcp_table_t *test_syn_table = NULL; +#define TEST_TABLE_SIZE 100 + +size_t sent_acks = 0; +size_t sent_rsts = 0; +size_t sent_syns = 0; +size_t sent_fins = 0; +uint32_t sent_seqno = 0; +uint32_t sent_ackno = 0; +size_t sent2_data = 0; +size_t send2_mss = 0; + +knot_xdp_socket_t *test_sock = NULL; + +struct sockaddr_in test_addr = { AF_INET, 0, { 127 + (1 << 24) }, { 0 } }; + +knot_tcp_conn_t *test_conn = NULL; + +/*! + * \brief Length of timeout-watching list. + */ +static size_t tcp_table_timeout_length(knot_tcp_table_t *table) +{ + return list_size(tcp_table_timeout(table)); +} + +/*! + * \brief Clean up old TCP connection w/o sending RST or FIN. + * + * \param tcp_table TCP connection table to clean up. + * \param timeout Remove connections older than this (usecs). + * \param at_least Remove at least this number of connections. + */ +static void tcp_cleanup(knot_tcp_table_t *tcp_table, uint32_t timeout, + uint32_t at_least) +{ + uint32_t now = get_timestamp(), i = 0; + knot_tcp_conn_t *conn, *next; + WALK_LIST_DELSAFE(conn, next, *tcp_table_timeout(tcp_table)) { + if (i++ < at_least || now - conn->last_active >= timeout) { + tcp_table_remove(tcp_table_re_lookup(conn, tcp_table), tcp_table); + del_conn(conn); + } + } +} + +/*! + * \brief Find connection related to incoming message. + */ +static knot_tcp_conn_t *tcp_table_find(knot_tcp_table_t *table, knot_xdp_msg_t *msg_recv) +{ + uint64_t unused = 0; + return *tcp_table_lookup(&msg_recv->ip_from, &msg_recv->ip_to, &unused, table); +} + +static int mock_send(_unused_ knot_xdp_socket_t *sock, const knot_xdp_msg_t msgs[], + uint32_t n_msgs, _unused_ uint32_t *sent) +{ + ok(n_msgs <= 20, "send: not too many at once"); + for (uint32_t i = 0; i < n_msgs; i++) { + const knot_xdp_msg_t *msg = msgs + i; + + ok(msg->flags & KNOT_XDP_MSG_TCP, "send: is TCP message"); + ok(msg->payload.iov_len == 0, "send: is empty payload"); + + if (msg->flags & KNOT_XDP_MSG_RST) { + ok(!(msg->flags & KNOT_XDP_MSG_ACK), "send: no RST+ACK"); + sent_rsts++; + } else if (msg->flags & KNOT_XDP_MSG_SYN) { + ok(msg->flags & KNOT_XDP_MSG_ACK, "send: is SYN+ACK"); + sent_syns++; + } else if (msg->flags & KNOT_XDP_MSG_FIN) { + ok(msg->flags & KNOT_XDP_MSG_ACK, "send: FIN has always ACK"); + sent_fins++; + } else { + ok(msg->flags & KNOT_XDP_MSG_ACK, "send: is ACK"); + sent_acks++; + } + + sent_seqno = msg->seqno; + sent_ackno = msg->ackno; + } + return KNOT_EOK; +} + +static int mock_send_nocheck(_unused_ knot_xdp_socket_t *sock, const knot_xdp_msg_t msgs[], + uint32_t n_msgs, _unused_ uint32_t *sent) +{ + for (uint32_t i = 0; i < n_msgs; i++) { + const knot_xdp_msg_t *msg = msgs + i; + if (msg->flags & KNOT_XDP_MSG_RST) { + sent_rsts++; + } else if (msg->flags & KNOT_XDP_MSG_SYN) { + sent_syns++; + } else if (msg->flags & KNOT_XDP_MSG_FIN) { + sent_fins++; + } else { + sent_acks++; + } + sent_seqno = msg->seqno; + sent_ackno = msg->ackno; + } + return KNOT_EOK; +} + +static int mock_send2(_unused_ knot_xdp_socket_t *sock, const knot_xdp_msg_t msgs[], + uint32_t n_msgs, _unused_ uint32_t *sent) +{ + ok(n_msgs <= 20, "send2: not too many at once"); + for (uint32_t i = 0; i < n_msgs; i++) { + const knot_xdp_msg_t *msg = msgs + i; + ok(msg->flags & KNOT_XDP_MSG_TCP, "send2: is TCP message"); + ok(msg->flags & KNOT_XDP_MSG_ACK, "send2: has ACK"); + ok(msg->payload.iov_len <= send2_mss, "send2: fulfilled MSS"); + sent2_data += msg->payload.iov_len; + + sent_seqno = msg->seqno; + sent_ackno = msg->ackno; + } + return KNOT_EOK; +} + +static void clean_table(void) +{ + (void)tcp_cleanup(test_table, 0, INFTY); +} + +static void clean_sent(void) +{ + sent_acks = 0; + sent_rsts = 0; + sent_syns = 0; + sent_fins = 0; +} + +static void check_sent(size_t expect_acks, size_t expect_rsts, size_t expect_syns, size_t expect_fins) +{ + is_int(expect_acks, sent_acks, "sent ACKs"); + is_int(expect_rsts, sent_rsts, "sent RSTs"); + is_int(expect_syns, sent_syns, "sent SYNs"); + is_int(expect_fins, sent_fins, "sent FINs"); + clean_sent(); +} + +static void prepare_msg(knot_xdp_msg_t *msg, int flags, uint16_t sport, uint16_t dport) +{ + msg_init(msg, flags | KNOT_XDP_MSG_TCP); + memcpy(&msg->ip_from, &test_addr, sizeof(test_addr)); + memcpy(&msg->ip_to, &test_addr, sizeof(test_addr)); + msg->ip_from.sin6_port = htobe16(sport); + msg->ip_to.sin6_port = htobe16(dport); +} + +static void prepare_seqack(knot_xdp_msg_t *msg, int seq_shift, int ack_shift) +{ + msg->seqno = sent_ackno + seq_shift; + msg->ackno = sent_seqno + ack_shift; +} + +static void prepare_data(knot_xdp_msg_t *msg, const char *bytes, size_t n) +{ + msg->payload.iov_len = n; + msg->payload.iov_base = (void *)bytes; +} + +static void fix_seqack(knot_xdp_msg_t *msg) +{ + knot_tcp_conn_t *conn = tcp_table_find(test_table, msg); + if (conn == NULL) { + conn = tcp_table_find(test_syn_table, msg); + } + assert(conn != NULL); + msg->seqno = conn->seqno; + msg->ackno = conn->ackno; +} + +static void fix_seqacks(knot_xdp_msg_t *msgs, size_t count) +{ + for (size_t i = 0; i < count; i++) { + fix_seqack(&msgs[i]); + } +} + +void test_syn(void) +{ + knot_xdp_msg_t msg; + knot_tcp_relay_t rl = { 0 }; + prepare_msg(&msg, KNOT_XDP_MSG_SYN, 1, 2); + int ret = knot_tcp_recv(&rl, &msg, 1, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "SYN: relay OK"); + ret = knot_tcp_send(test_sock, &rl, 1, 1); + is_int(KNOT_EOK, ret, "SYN: send OK"); + is_int(msg.seqno + 1, sent_ackno, "SYN: ackno"); + check_sent(0, 0, 1, 0); + is_int(XDP_TCP_SYN, rl.action, "SYN: relay action"); + is_int(XDP_TCP_NOOP, rl.answer, "SYN: relay answer"); + ok(NULL == rl.inbf, "SYN: no payload"); + is_int(0, test_table->usage, "SYN: no connection in normal table"); + is_int(1, test_syn_table->usage, "SYN: one connection in SYN table"); + knot_tcp_conn_t *conn = tcp_table_find(test_syn_table, &msg); + ok(conn != NULL, "SYN: connection present"); + assert(conn); + ok(conn == rl.conn, "SYN: relay points to connection"); + is_int(XDP_TCP_ESTABLISHING, conn->state, "SYN: connection state"); + ok(memcmp(&conn->ip_rem, &msg.ip_from, sizeof(msg.ip_from)) == 0, "SYN: conn IP from"); + ok(memcmp(&conn->ip_loc, &msg.ip_to, sizeof(msg.ip_to)) == 0, "SYN: conn IP to"); + + knot_tcp_cleanup(test_syn_table, &rl, 1); + test_conn = conn; +} + +void test_establish(void) +{ + knot_xdp_msg_t msg; + knot_tcp_relay_t rl = { 0 }; + prepare_msg(&msg, KNOT_XDP_MSG_ACK, 1, 2); + prepare_seqack(&msg, 0, 1); + int ret = knot_tcp_recv(&rl, &msg, 1, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "establish: relay OK"); + is_int(0, test_syn_table->usage, "SYN: no connection in SYN table"); + is_int(1, test_table->usage, "SYN: one connection in normal table"); + ret = knot_tcp_send(test_sock, &rl, 1, 1); + is_int(KNOT_EOK, ret, "establish: send OK"); + check_sent(0, 0, 0, 0); + is_int(0, rl.auto_answer, "establish: no auto answer"); + + knot_tcp_cleanup(test_table, &rl, 1); + clean_table(); +} + +void test_syn_ack(void) +{ + knot_xdp_msg_t msg; + knot_tcp_relay_t rl = { 0 }; + prepare_msg(&msg, KNOT_XDP_MSG_SYN | KNOT_XDP_MSG_ACK, 1000, 2000); + int ret = knot_tcp_recv(&rl, &msg, 1, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "SYN+ACK: relay OK"); + ret = knot_tcp_send(test_sock, &rl, 1, 1); + is_int(KNOT_EOK, ret, "SYN+ACK: send OK"); + is_int(msg.seqno + 1, sent_ackno, "SYN+ACK: ackno"); + check_sent(1, 0, 0, 0); + is_int(XDP_TCP_ESTABLISH, rl.action, "SYN+ACK: relay action"); + ok(rl.conn != NULL, "SYN+ACK: connection present"); + + test_conn = rl.conn; + knot_tcp_cleanup(test_table, &rl, 1); +} + +void test_data_fragments(void) +{ + const size_t CONNS = 4; + knot_xdp_msg_t msgs[CONNS]; + knot_tcp_relay_t rls[CONNS]; + memset(rls, 0, CONNS * sizeof(*rls)); + + // first msg contains one whole payload and one fragment + prepare_msg(&msgs[0], KNOT_XDP_MSG_ACK, 1000, 2000); + prepare_seqack(&msgs[0], 0, 0); + prepare_data(&msgs[0], "\x00\x03""xyz""\x00\x04""ab", 9); + + // second msg contains just fragment not completing anything + prepare_msg(&msgs[1], KNOT_XDP_MSG_ACK, 1000, 2000); + prepare_seqack(&msgs[1], 9, 0); + prepare_data(&msgs[1], "c", 1); + + // third msg finishes fragment, contains one whole, and starts new fragment by just half of length info + prepare_msg(&msgs[2], KNOT_XDP_MSG_ACK, 1000, 2000); + prepare_seqack(&msgs[2], 10, 0); + prepare_data(&msgs[2], "d""\x00\x01""i""\x00", 5); + + // fourth msg completes fragment and starts never-finishing one + prepare_msg(&msgs[3], KNOT_XDP_MSG_ACK, 1000, 2000); + prepare_seqack(&msgs[3], 15, 0); + prepare_data(&msgs[3], "\x02""AB""\xff\xff""abcdefghijklmnopqrstuvwxyz...", 34); + + assert(test_table); + int ret = knot_tcp_recv(rls, msgs, CONNS, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "fragments: relay OK"); + assert(test_sock); + ret = knot_tcp_send(test_sock, rls, CONNS, CONNS); + is_int(KNOT_EOK, ret, "fragments: send OK"); + is_int(msgs[3].ackno, sent_seqno, "fragments: seqno"); + is_int(msgs[3].seqno + msgs[3].payload.iov_len, sent_ackno, "fragments: ackno"); + check_sent(4, 0, 0, 0); + + is_int(KNOT_XDP_MSG_ACK, rls[0].auto_answer, "fragments[0]: auto answer"); + ok(rls[0].conn != NULL, "fragments0: connection present"); + ok(rls[0].conn == test_conn, "fragments0: same connection"); + is_int(1, rls[0].inbf->n_inbufs, "fragments0: inbufs count"); + struct iovec *inbufs = rls[0].inbf->inbufs; + is_int(3, inbufs[0].iov_len, "fragments0: data length"); + is_int(0, memcmp("xyz", inbufs[0].iov_base, inbufs[0].iov_len), "fragments0: data"); + + is_int(KNOT_XDP_MSG_ACK, rls[1].auto_answer, "fragments[1]: auto answer"); + is_int(XDP_TCP_NOOP, rls[1].action, "fragments[1]: action"); // NOTE: NOOP + ok(rls[0].conn != NULL, "fragments1: connection present"); + ok(rls[0].conn == test_conn, "fragments1: same connection"); + ok(NULL == rls[1].inbf, "fragments1: inbufs count"); + + is_int(KNOT_XDP_MSG_ACK, rls[2].auto_answer, "fragments[2]: auto answer"); + ok(rls[0].conn != NULL, "fragments2: connection present"); + ok(rls[0].conn == test_conn, "fragments2: same connection"); + is_int(2, rls[2].inbf->n_inbufs, "fragments2: inbufs count"); + inbufs = rls[2].inbf->inbufs; + is_int(4, inbufs[0].iov_len, "fragments2-0: data length"); + is_int(0, memcmp("abcd", inbufs[0].iov_base, inbufs[0].iov_len), "fragments2-0: data"); + is_int(1, inbufs[1].iov_len, "fragments2-1: data length"); + is_int(0, memcmp("i", inbufs[1].iov_base, inbufs[1].iov_len), "fragments2-1: data"); + + is_int(KNOT_XDP_MSG_ACK, rls[3].auto_answer, "fragments[3]: auto answer"); + ok(rls[0].conn != NULL, "fragments3: connection present"); + ok(rls[0].conn == test_conn, "fragments3: same connection"); + is_int(1, rls[3].inbf->n_inbufs, "fragments3: inbufs count"); + inbufs = rls[3].inbf->inbufs; + is_int(2, inbufs[0].iov_len, "fragments3: data length"); + is_int(0, memcmp("AB", inbufs[0].iov_base, inbufs[0].iov_len), "fragments3: data"); + + knot_tcp_cleanup(test_table, rls, 4); +} + +void test_close(void) +{ + size_t conns_pre = test_table->usage; + + knot_xdp_msg_t msg; + knot_tcp_relay_t rl = { 0 }; + prepare_msg(&msg, KNOT_XDP_MSG_FIN | KNOT_XDP_MSG_ACK, + be16toh(test_conn->ip_rem.sin6_port), + be16toh(test_conn->ip_loc.sin6_port)); + prepare_seqack(&msg, 0, 0); + + // test wrong ackno synack, shall reply with RST with same + knot_xdp_msg_t wrong = msg; + wrong.seqno += INT32_MAX; + wrong.ackno += INT32_MAX; + int ret = knot_tcp_recv(&rl, &wrong, 1, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "close: relay 0 OK"); + is_int(KNOT_XDP_MSG_RST, rl.auto_answer, "close: reset wrong ackno"); + is_int(rl.auto_seqno, wrong.ackno, "close: reset seqno"); + ret = knot_tcp_send(test_sock, &rl, 1, 1); + is_int(KNOT_EOK, ret, "close: send 0 OK"); + check_sent(0, 1, 0, 0); + is_int(sent_seqno, wrong.ackno, "close: reset seqno sent"); + + ret = knot_tcp_recv(&rl, &msg, 1, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "close: relay 1 OK"); + ret = knot_tcp_send(test_sock, &rl, 1, 1); + is_int(KNOT_EOK, ret, "close: send OK"); + check_sent(0, 0, 0, 1); + is_int(XDP_TCP_CLOSE, rl.action, "close: relay action"); + assert(rl.conn); + ok(rl.conn == test_conn, "close: same connection"); + is_int(XDP_TCP_CLOSING2, rl.conn->state, "close: conn state"); + + msg.flags &= ~KNOT_XDP_MSG_FIN; + prepare_seqack(&msg, 0, 0); + ret = knot_tcp_recv(&rl, &msg, 1, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "close: relay 2 OK"); + ret = knot_tcp_send(test_sock, &rl, 1, 1); + is_int(KNOT_EOK, ret, "close: send 2 OK"); + check_sent(0, 0, 0, 0); + is_int(conns_pre - 1, test_table->usage, "close: connection removed"); + is_int(conns_pre - 1, tcp_table_timeout_length(test_table), "close: timeout list size"); + knot_tcp_cleanup(test_table, &rl, 1); +} + +void test_many(void) +{ + size_t CONNS = test_table->size * test_table->size; + size_t i_survive = CONNS / 2; + uint32_t timeout_time = 1000000; + + knot_xdp_msg_t *msgs = malloc(CONNS * sizeof(*msgs)); + assert(msgs != NULL); + for (size_t i = 0; i < CONNS; i++) { + prepare_msg(&msgs[i], KNOT_XDP_MSG_SYN, i + 2, 1); + } + knot_tcp_relay_t *rls = malloc(CONNS * sizeof(*rls)); + + int ret = knot_tcp_recv(rls, msgs, CONNS, test_table, NULL, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "many: relay OK"); + ret = knot_tcp_send(test_sock, rls, CONNS, CONNS); + is_int(KNOT_EOK, ret, "many: relay send OK"); + check_sent(0, 0, CONNS, 0); + is_int(CONNS, test_table->usage, "many: table usage"); + + knot_tcp_cleanup(test_table, rls, CONNS); + memset(rls, 0, CONNS * sizeof(*rls)); + usleep(timeout_time); + knot_xdp_msg_t *survive = &msgs[i_survive]; + knot_tcp_relay_t surv_rl = { 0 }; + survive->flags = (KNOT_XDP_MSG_TCP | KNOT_XDP_MSG_ACK); + knot_tcp_conn_t *surv_conn = tcp_table_find(test_table, survive); + fix_seqack(survive); + prepare_data(survive, "\x00\x00", 2); + assert(test_table); + ret = knot_tcp_recv(&surv_rl, survive, 1, test_table, NULL, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "many/survivor: OK"); + clean_sent(); + + knot_sweep_stats_t stats = { 0 }; + ret = knot_tcp_sweep(test_table, timeout_time, INFTY, INFTY, INFTY, INFTY, + INFTY, rls, CONNS, &stats); + is_int(KNOT_EOK, ret, "many/timeout1: OK"); + is_int(CONNS - 1, stats.counters[KNOT_SWEEP_CTR_TIMEOUT], "many/timeout1: close count"); + is_int(0, stats.counters[KNOT_SWEEP_CTR_LIMIT_CONN], "may/timeout1: reset count"); + ret = knot_tcp_send(test_sock, rls, CONNS, CONNS); + is_int(KNOT_EOK, ret, "many/timeout1: send OK"); + check_sent(0, 0, 0, CONNS - 1); + + knot_sweep_stats_reset(&stats); + ret = knot_tcp_sweep(test_table, INFTY, timeout_time, INFTY, INFTY, INFTY, + INFTY, rls, CONNS, &stats); + is_int(KNOT_EOK, ret, "many/timeout2: OK"); + is_int(0, stats.counters[KNOT_SWEEP_CTR_TIMEOUT], "many/timeout2: close count"); + is_int(CONNS - 1, stats.counters[KNOT_SWEEP_CTR_TIMEOUT_RST], "may/timeout2: reset count"); + ret = knot_tcp_send(test_sock, rls, CONNS, CONNS); + is_int(KNOT_EOK, ret, "many/timeout2: send OK"); + check_sent(0, CONNS - 1, 0, 0); + knot_tcp_cleanup(test_table, rls, CONNS); + is_int(1, test_table->usage, "many/timeout: one survivor"); + is_int(1, tcp_table_timeout_length(test_table), "many/timeout: one survivor in timeout list"); + ok(surv_conn != NULL, "many/timeout: survivor connection present"); + ok(surv_conn == surv_rl.conn, "many/timeout: same connection"); + knot_tcp_cleanup(test_table, &surv_rl, 1); + + free(msgs); + free(rls); +} + +void test_ibufs_size(void) +{ + int CONNS = 4; + knot_xdp_msg_t msgs[CONNS]; + knot_tcp_relay_t rls[CONNS]; + + // just open connections + for (int i = 0; i < CONNS; i++) { + prepare_msg(&msgs[i], KNOT_XDP_MSG_SYN, i + 2000, 1); + } + int ret = knot_tcp_recv(rls, msgs, CONNS, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "ibufs: open OK"); + ret = knot_tcp_send(test_sock, rls, CONNS, CONNS); + is_int(KNOT_EOK, ret, "ibufs: first send OK"); + check_sent(0, 0, CONNS, 0); + for (int i = 0; i < CONNS; i++) { + msgs[i].flags = KNOT_XDP_MSG_TCP | KNOT_XDP_MSG_ACK; + } + fix_seqacks(msgs, CONNS); + (void)knot_tcp_recv(rls, msgs, CONNS, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + + is_int(0, test_table->inbufs_total, "inbufs: initial total zero"); + + // first connection will start a fragment buf then finish it + fix_seqack(&msgs[0]); + prepare_data(&msgs[0], "\x00\x0a""lorem", 7); + ret = knot_tcp_recv(&rls[0], &msgs[0], 1, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "ibufs: must be OK"); + ret = knot_tcp_send(test_sock, &rls[0], 1, 1); + is_int(KNOT_EOK, ret, "ibufs: must send OK"); + check_sent(1, 0, 0, 0); + is_int(64, test_table->inbufs_total, "inbufs: first inbuf"); + knot_tcp_cleanup(test_table, &rls[0], 1); + + // other connection will just store fragments + fix_seqacks(msgs, CONNS); + prepare_data(&msgs[0], "ipsum", 5); + prepare_data(&msgs[1], "\x00\xff""12345", 7); + prepare_data(&msgs[2], "\xff\xff""abcde", 7); + prepare_data(&msgs[3], "\xff\xff""abcde", 7); + ret = knot_tcp_recv(rls, msgs, CONNS, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "inbufs: relay OK"); + ret = knot_tcp_send(test_sock, rls, CONNS, CONNS); + is_int(KNOT_EOK, ret, "inbufs: send OK"); + check_sent(CONNS, 0, 0, 0); + is_int(192, test_table->inbufs_total, "inbufs: after change"); + is_int(0, rls[1].action, "inbufs: one relay"); + is_int(10, rls[0].inbf->inbufs[0].iov_len, "inbufs: data length"); + knot_tcp_cleanup(test_table, rls, CONNS); + + // now free some + knot_sweep_stats_t stats = { 0 }; + ret = knot_tcp_sweep(test_table, INFTY, INFTY, INFTY, INFTY, + 64, INFTY, rls, + CONNS, &stats); + is_int(KNOT_EOK, ret, "inbufs: timeout OK"); + ret = knot_tcp_send(test_sock, rls, CONNS, CONNS); + is_int(KNOT_EOK, ret, "inbufs: timeout send OK"); + check_sent(0, 2, 0, 0); + is_int(0, stats.counters[KNOT_SWEEP_CTR_TIMEOUT], "inbufs: close count"); + is_int(2, stats.counters[KNOT_SWEEP_CTR_LIMIT_IBUF], "inbufs: reset count"); + knot_tcp_cleanup(test_table, rls, CONNS); + is_int(64, test_table->inbufs_total, "inbufs: final state"); + ok(NULL != tcp_table_find(test_table, &msgs[0]), "inbufs: first conn survived"); + ok(NULL == tcp_table_find(test_table, &msgs[1]), "inbufs: second conn not survived"); + ok(NULL == tcp_table_find(test_table, &msgs[2]), "inbufs: third conn not survived"); + ok(NULL != tcp_table_find(test_table, &msgs[3]), "inbufs: fourth conn survived"); + + clean_table(); +} + +void test_obufs(void) +{ + knot_xdp_msg_t msg; + knot_tcp_relay_t rl = { 0 }; + + prepare_msg(&msg, KNOT_XDP_MSG_SYN, 1, 2); + (void)knot_tcp_recv(&rl, &msg, 1, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); // SYN + (void)knot_tcp_send(test_sock, &rl, 1, 1); // SYN+ACK + prepare_msg(&msg, KNOT_XDP_MSG_ACK, 1, 2); + prepare_seqack(&msg, 0, 1); + (void)knot_tcp_recv(&rl, &msg, 1, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); // ACK + + size_t TEST_MSS = 1111; + size_t DATA_LEN = 65535; // with 2-byte len prefix, this is > 64k == window_size + uint8_t *data = calloc(DATA_LEN, 1); + assert(rl.conn); + rl.conn->mss = TEST_MSS; + rl.conn->window_size = 65536; + send2_mss = TEST_MSS; + + int ret = knot_tcp_reply_data(&rl, test_table, false, data, DATA_LEN), i = 0; + is_int(KNOT_EOK, ret, "obufs: fill with data"); + for (knot_tcp_outbuf_t *ob = rl.conn->outbufs; ob != NULL; ob = ob->next, i++) { + if (ob->next == NULL) { + ok(ob->len > 0, "init last ob[%d]: non-trivial", i); + ok(ob->len <= TEST_MSS, "init last ob[%d]: fulfills MSS", i); + } else { + is_int(TEST_MSS, ob->len, "init ob[%d]: exactly MSS", i); + } + ok(!ob->sent, "init ob[%d]: not sent", i); + } + ret = knot_tcp_send(test_sock, &rl, 1, 20), i = 0; + is_int(KNOT_EOK, ret, "obufs: send OK"); + is_int((DATA_LEN + 2) / TEST_MSS * TEST_MSS, sent2_data, "obufs: sent all but one MSS"); + for (knot_tcp_outbuf_t *ob = rl.conn->outbufs; ob != NULL; ob = ob->next, i++) { + if (ob->next == NULL) { + ok(!ob->sent, "last ob[%d]: not sent", i); + } else { + ok(ob->sent, "ob[%d]: sent", i); + if (ob->next->next != NULL) { + is_int(ob->seqno + ob->len, ob->next->seqno, "init ob[%d+1]: seqno", i); + } + } + } + knot_tcp_cleanup(test_table, &rl, 1); + memset(&rl, 0, sizeof(rl)); + + prepare_seqack(&msg, 0, TEST_MSS); + ret = knot_tcp_recv(&rl, &msg, 1, test_table, test_syn_table, XDP_TCP_IGNORE_NONE); + is_int(KNOT_EOK, ret, "obufs: ACKed data"); + assert(rl.conn); + rl.conn->window_size = 65536; + knot_tcp_outbuf_t *surv_ob = rl.conn->outbufs; + ok(surv_ob != NULL, "obufs: unACKed survived"); + assert(surv_ob); + ok(surv_ob->next == NULL, "obufs: just one survived"); + ok(!surv_ob->sent, "obufs: survivor not sent"); + ret = knot_tcp_send(test_sock, &rl, 1, 20); + is_int(KNOT_EOK, ret, "obufs: send rest OK"); + is_int(DATA_LEN + 2, sent2_data, "obufs: sent all"); + ok(surv_ob->sent, "obufs: survivor sent"); + is_int(sent_seqno, surv_ob->seqno, "obufs: survivor seqno"); + + knot_tcp_cleanup(test_table, &rl, 1); + clean_table(); + free(data); +} + +static void init_mock(knot_xdp_socket_t **socket, void *send_mock) +{ + *socket = calloc(1, sizeof(**socket)); + if (*socket != NULL) { + (*socket)->send_mock = send_mock; + } +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + test_table = knot_tcp_table_new(TEST_TABLE_SIZE, NULL); + assert(test_table != NULL); + test_syn_table = knot_tcp_table_new(TEST_TABLE_SIZE, test_table); + + init_mock(&test_sock, mock_send); + + test_syn(); + test_establish(); + + test_syn_ack(); + test_data_fragments(); + test_close(); + + test_ibufs_size(); + + knot_xdp_deinit(test_sock); + init_mock(&test_sock, mock_send_nocheck); + test_many(); + + knot_xdp_deinit(test_sock); + init_mock(&test_sock, mock_send2); + test_obufs(); + + knot_xdp_deinit(test_sock); + knot_tcp_table_free(test_table); + knot_tcp_table_free(test_syn_table); + + return 0; +} diff --git a/tests/libknot/test_yparser.c b/tests/libknot/test_yparser.c new file mode 100644 index 0000000..8655096 --- /dev/null +++ b/tests/libknot/test_yparser.c @@ -0,0 +1,346 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/yparser/yparser.h" +#include "libknot/libknot.h" + +const char *syntax_ok = + "#comment\n" + " # comment\n" + "a:\n" + "a :\n" + "a : #comment\n" + "\n" + "b: \"b\"\n" + "b: b #comment\n" + "b : b\n" + "b: [ b] # comment\n" + "b: [b ]\n" + "b: [ b ]\n" + "\n" + " f: \"f\"\n" + " f: f #comment\n" + " f : f\n" + " f: [ f] # comment\n" + " f: [f ]\n" + " f: [ f ]\n" + " f: [ \"f\" ]\n" + "\n" + "c: [a,b]\n" + "c: [a, b]\n" + "c: [a ,b]\n" + "c: [a , b]\n" + "c: [ a , b ]\n" + "c: [ \"a\" , \"b\" ]\n" + "\n" + "- d: d\n" + "- d : d # comment\n" + "\n" + "e: \"a#b' c[d,]\"\n" + "\n" + "zone:\n" + "#comment\n" + " # comment\n" + " - domain: example. # comment\n" + " master: bind\n" + " - domain: example.\n" + " master: bind\n" + "zone2:\n" + " - a: b # different indentation"; + +const char *syntax_error1 = + "f:\n" + " - a: b\n" + " - b: c\n"; + +const char *syntax_error2 = + "f:\n" + " - a: b\n" + " c: d\n"; + +const char *syntax_error3 = + "f:\n" + " a: b\n" + " c: d\n"; + +const char *tab_error1 = + "a:\n" + "b:\t\n"; + +const char *tab_error2 = + "a:\n" + "b: c\t\n"; + +const char *tab_error3 = + "a:\n" + "\t\n"; + +const char *dname_ok = + ".:\n" + "dom-ain:\n" + "\\070-\\071.\\072.:\n" + "*.wildchar.com:\n" + "_ldap._tcp.example.com:\n"; + +const char *quotes_ok = + "g: \"\"\n" + "g: a\\ b\n" + "g: \"\\# 1 00\"\n" + "g: \"\\\"\\\"\"\n" + "g: \" a \\\" b \\\" \\\"c\\\" \"\n" + "g: \"\\@ \\[ \\# \\, \\]\"\n"; + +const char *utf8_ok = + "key: pÅ™ÃÅ¡era\n"; + +static void test_syntax_ok(yp_parser_t *yp) +{ + // OK input. + int ret = yp_set_input_string(yp, syntax_ok, strlen(syntax_ok)); + is_int(KNOT_EOK, ret, "set input string"); + + size_t line = 3; + for (int i = 0; i < 3; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key0", i); + ok(yp->key_len == 1 && yp->key[0] == 'a' && + yp->data_len == 0 && yp->event == YP_EKEY0 && + yp->line_count == line + i, "compare %i. key0", i); + } + + line += 4; + for (int i = 0; i < 6; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key0 with value", i); + ok(yp->key_len == 1 && yp->key[0] == 'b' && + yp->data_len == 1 && yp->data[0] == 'b' && + yp->event == YP_EKEY0 && yp->line_count == line + i, + "compare %i. key0 with value", i); + } + + line += 7; + for (int i = 0; i < 7; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key1 with value", i); + ok(yp->key_len == 1 && yp->key[0] == 'f' && + yp->data_len == 1 && yp->data[0] == 'f' && + yp->event == YP_EKEY1 && yp->line_count == line + i, + "compare %i. key1 with value", i); + } + + line += 8; + for (int i = 0; i < 6; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key0 with first value", i); + ok(yp->key_len == 1 && yp->key[0] == 'c' && + yp->data_len == 1 && yp->data[0] == 'a' && + yp->event == YP_EKEY0 && yp->line_count == line + i, + "compare %i. key0 with first value", i); + + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key0 with second value", i); + ok(yp->key_len == 1 && yp->key[0] == 'c' && + yp->data_len == 1 && yp->data[0] == 'b' && + yp->event == YP_EKEY0 && yp->line_count == line + i, + "compare %i. key0 with second value", i); + } + + line += 7; + for (int i = 0; i < 2; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. id", i); + ok(yp->key_len == 1 && yp->key[0] == 'd' && + yp->data_len == 1 && yp->data[0] == 'd' && + yp->event == YP_EID && yp->line_count == line + i, + "compare %i. id", i); + } + + line += 3; + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key0 with quoted value"); + ok(yp->key_len == 1 && yp->key[0] == 'e' && yp->data_len == 10 && + memcmp(yp->data, "a#b' c[d,]", yp->data_len) == 0 && + yp->event == YP_EKEY0 && yp->line_count == line, + "compare key0 with quoted value"); + + line += 2; + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key0"); + ok(yp->key_len == 4 && strcmp(yp->key, "zone") == 0 && + yp->data_len == 0 && + yp->event == YP_EKEY0 && yp->line_count == line, + "compare key0 value"); + + line += 3; + for (int i = 0; i < 2; i++) { + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. id", i); + ok(yp->key_len == 6 && strcmp(yp->key, "domain") == 0 && + yp->data_len == 8 && strcmp(yp->data, "example.") == 0 && + yp->event == YP_EID && yp->line_count == line + 2 * i, + "compare id"); + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse %i. key1", i); + ok(yp->key_len == 6 && strcmp(yp->key, "master") == 0 && + yp->data_len == 4 && strcmp(yp->data, "bind") == 0 && + yp->event == YP_EKEY1 && yp->line_count == line + 2 * i + 1, + "compare key1"); + } + + line += 4; + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key0"); + ok(yp->key_len == 5 && strcmp(yp->key, "zone2") == 0 && + yp->data_len == 0 && + yp->event == YP_EKEY0 && yp->line_count == line, + "compare key0 value"); + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key1"); + ok(yp->key_len == 1 && strcmp(yp->key, "a") == 0 && + yp->data_len == 1 && strcmp(yp->data, "b") == 0 && + yp->event == YP_EID && yp->line_count == line + 1, + "compare key1 value"); + + ret = yp_parse(yp); + is_int(KNOT_EOF, ret, "parse EOF"); +} + +static void test_syntax_error(yp_parser_t *yp, const char *input) +{ + static int count = 1; + + int ret = yp_set_input_string(yp, input, strlen(input)); + is_int(KNOT_EOK, ret, "set syntax error input string %i", count++); + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key0"); + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key1"); + ret = yp_parse(yp); + is_int(KNOT_YP_EINVAL_INDENT, ret, "parse key1 - invalid indentation"); + is_int(yp->line_count, 3, "invalid indentation line"); +} + +static void test_tab_error(yp_parser_t *yp, const char *input) +{ + static int count = 1; + + int ret = yp_set_input_string(yp, input, strlen(input)); + is_int(KNOT_EOK, ret, "set tab error input string %i", count++); + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key0"); + ret = yp_parse(yp); + is_int(KNOT_YP_ECHAR_TAB, ret, "invalid tabulator"); + is_int(yp->line_count, 2, "invalid tabulator line"); +} + +static void test_dname(yp_parser_t *yp) +{ +#define CHECK_DNAME(str) \ + ret = yp_parse(yp); \ + is_int(KNOT_EOK, ret, "parse dname " str); \ + ok(yp->key_len == strlen(str) && strcmp(yp->key, str) == 0 && yp->data_len == 0 && \ + yp->event == YP_EKEY0 && yp->line_count == line++, "compare " str); + + // Dname key value. + int ret = yp_set_input_string(yp, dname_ok, strlen(dname_ok)); + is_int(KNOT_EOK, ret, "set input string"); + + size_t line = 1; + CHECK_DNAME("."); + CHECK_DNAME("dom-ain"); + CHECK_DNAME("\\070-\\071.\\072."); + CHECK_DNAME("*.wildchar.com"); + CHECK_DNAME("_ldap._tcp.example.com"); +} + +static void test_quotes(yp_parser_t *yp) +{ +#define CHECK_QUOTE(str) \ + ret = yp_parse(yp); \ + is_int(KNOT_EOK, ret, "parse quoted " str); \ + ok(yp->key_len == 1 && yp->key[0] == 'g' && \ + yp->data_len == strlen(str) && strcmp(yp->data, str) == 0 && \ + yp->event == YP_EKEY0 && yp->line_count == line++, "compare " str); + + int ret = yp_set_input_string(yp, quotes_ok, strlen(quotes_ok)); + is_int(KNOT_EOK, ret, "set input string"); + + size_t line = 1; + CHECK_QUOTE(""); + CHECK_QUOTE("a\\ b"); + CHECK_QUOTE("\\# 1 00"); + CHECK_QUOTE("\"\""); + CHECK_QUOTE(" a \" b \" \"c\" "); + CHECK_QUOTE("\\@ \\[ \\# \\, \\]"); +} + +// Check that wrong wildcard dname is NOT parsed as valid dname. +static void test_wildcard(yp_parser_t *yp) +{ +#define CHECK_NOT_WILDCARD(str) \ + ret = yp_set_input_string(yp, str, strlen(str)); \ + is_int(KNOT_EOK, ret, "set input string");\ + ret = yp_parse(yp); \ + is_int(KNOT_EPARSEFAIL, ret, str " is not wildcard"); \ + ok(yp->key_len != strlen(str) || strcmp(yp->key, str) != 0 || \ + yp->event != YP_EKEY0, "compare " str); + + int ret; + CHECK_NOT_WILDCARD("a.*.example.com."); + CHECK_NOT_WILDCARD("**.example.com."); + CHECK_NOT_WILDCARD("*example.com."); +} + +static void test_utf8(yp_parser_t *yp) +{ + int ret = yp_set_input_string(yp, utf8_ok, strlen(utf8_ok)); + is_int(KNOT_EOK, ret, "set input string"); + + ret = yp_parse(yp); + is_int(KNOT_EOK, ret, "parse key with a value in UTF-8"); + ok(yp->key_len == 3 && strcmp(yp->key, "key") == 0 && + yp->data_len == 10 && strcmp(yp->data, "p""\xC5\x99\xC3\xAD\xC5\xA1""era") == 0, + "compare UTF-8 value"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + yp_parser_t yp; + yp_init(&yp); + + test_syntax_ok(&yp); + test_syntax_error(&yp, syntax_error1); + test_syntax_error(&yp, syntax_error2); + test_syntax_error(&yp, syntax_error3); + test_tab_error(&yp, tab_error1); + test_tab_error(&yp, tab_error2); + test_tab_error(&yp, tab_error3); + test_dname(&yp); + test_quotes(&yp); + test_wildcard(&yp); + test_utf8(&yp); + + yp_deinit(&yp); + + return 0; +} diff --git a/tests/libknot/test_ypschema.c b/tests/libknot/test_ypschema.c new file mode 100644 index 0000000..728a847 --- /dev/null +++ b/tests/libknot/test_ypschema.c @@ -0,0 +1,417 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/yparser/ypschema.h" +#include "libknot/yparser/yptrafo.h" +#include "libknot/libknot.h" + +#define C_ID "\x02""id" +#define C_INT "\x07""integer" +#define C_BOOL "\x04""bool" +#define C_OPT "\x06""option" +#define C_STR "\x06""string" +#define C_ADDR "\x07""address" +#define C_DNAME "\x05""dname" +#define C_HEX "\x03""hex" +#define C_BASE64 "\x06""base64" +#define C_DATA "\x04""data" +#define C_REF "\x09""reference" +#define C_GRP "\x05""group" +#define C_MULTIGRP "\x0B""multi-group" + +static const yp_item_t group[] = { + { C_INT, YP_TINT, YP_VINT = { 0, 100, YP_NIL } }, + { C_STR, YP_TSTR, YP_VNONE, YP_FMULTI }, + { NULL } +}; + +static const yp_item_t multi_group[] = { + { C_ID, YP_TSTR, YP_VNONE }, + { C_HEX, YP_THEX, YP_VNONE }, + { C_BASE64, YP_TB64, YP_VNONE }, + { NULL } +}; + +static const knot_lookup_t opts[] = { + { 1, "one" }, + { 10, "ten" }, + { 0, NULL } + }; + +static const yp_item_t static_schema[] = { + { C_OPT, YP_TOPT, YP_VOPT = { opts } }, + { C_BOOL, YP_TBOOL, YP_VNONE }, + { C_DNAME, YP_TDNAME, YP_VNONE }, + { C_GRP, YP_TGRP, YP_VGRP = { group } }, + { C_MULTIGRP, YP_TGRP, YP_VGRP = { multi_group }, YP_FMULTI }, + { C_REF, YP_TREF, YP_VREF = { C_MULTIGRP } }, + { C_DATA, YP_TDATA, YP_VNONE }, + { NULL } +}; + +static void schema_find_test(void) +{ + yp_item_t *schema = NULL; + + int ret = yp_schema_copy(&schema, static_schema); + is_int(KNOT_EOK, ret, "schema copy"); + + const yp_item_t *i = yp_schema_find(C_OPT, NULL, schema); + ok(i != NULL, "schema find"); + if (i == NULL) { + goto error_schema; + } + ok(strcmp(&i->name[1], &C_OPT[1]) == 0, "name check"); + + i = yp_schema_find(C_STR, C_GRP, schema); + ok(i != NULL, "schema find with parent"); + if (i == NULL) { + goto error_schema; + } + ok(strcmp(&i->name[1], &C_STR[1]) == 0, "name check"); + + i = yp_schema_find(C_ADDR, NULL, schema); + ok(i == NULL, "schema not find"); + + i = yp_schema_find(C_ADDR, C_GRP, schema); + ok(i == NULL, "schema not find with parent"); + +error_schema: + yp_schema_free(schema); +} + +static void schema_merge_test(void) +{ + static const yp_item_t items1[] = { + { "\x01""1", YP_TSTR, YP_VNONE }, + { "\x01""2", YP_TSTR, YP_VNONE }, + { NULL } + }; + + static const yp_item_t items2[] = { + { "\x01""3", YP_TSTR, YP_VNONE }, + { "\x01""4", YP_TSTR, YP_VNONE }, + { NULL } + }; + + yp_item_t *schema = NULL; + yp_item_t *tmp = NULL; + + int ret = yp_schema_copy(&tmp, items1); + is_int(KNOT_EOK, ret, "schema copy"); + + ret = yp_schema_merge(&schema, items1, items2); + is_int(KNOT_EOK, ret, "schema merge"); + + yp_schema_free(tmp); + + for (uint8_t i = 0; i < 4; i++) { + yp_name_t name[3] = { '\x01', '1' + i }; + const yp_item_t *item = yp_schema_find(name, NULL, schema); + ok(item != NULL, "schema find"); + } + + yp_schema_free(schema); +} + +#define SET_INPUT_STR(str) \ + ret = yp_set_input_string(yp, str, strlen(str)); \ + is_int(KNOT_EOK, ret, "set input string"); + +#define PARSER_CHECK(depth) \ + ret = yp_parse(yp); \ + is_int(KNOT_EOK, ret, "parse"); \ + ret = yp_schema_check_parser(ctx, yp); \ + is_int(KNOT_EOK, ret, "check parser"); \ + node = &ctx->nodes[ctx->current]; \ + parent = node->parent; \ + ok(ctx->current == depth, "depth check"); + +#define PARSER_RET_CHECK(code) \ + ret = yp_parse(yp); \ + is_int(KNOT_EOK, ret, "parse"); \ + ret = yp_schema_check_parser(ctx, yp); \ + ok(ret == code, "return check parser"); + +static void parser_test(void) +{ + yp_parser_t yparser; + yp_parser_t *yp = &yparser; + yp_item_t *schema = NULL; + yp_check_ctx_t *ctx = NULL; + + yp_init(yp); + + int ret = yp_schema_copy(&schema, static_schema); + is_int(KNOT_EOK, ret, "schema copy"); + if (ret != KNOT_EOK) { + goto error_parser; + } + + ctx = yp_schema_check_init(&schema); + ok(ctx != NULL, "create check ctx"); + if (ctx == NULL) { + goto error_parser; + } + + yp_node_t *node; + yp_node_t *parent; + const yp_item_t *id; + + diag("parser key0 test"); + SET_INPUT_STR("option: one"); + PARSER_CHECK(0); + ok(strcmp(node->item->name + 1, "option") == 0, "name check"); + ok(node->item->type == YP_TOPT, "type check"); + ok(yp_opt(node->data) == 1, "value check"); + + diag("parser group test"); + SET_INPUT_STR("group:\n integer: 20\n string: [short, \"long string\"]"); + PARSER_CHECK(0); + ok(strcmp(node->item->name + 1, "group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + PARSER_CHECK(1); + ok(strcmp(node->item->name + 1, "integer") == 0, "name check"); + ok(node->item->type == YP_TINT, "type check"); + ok(yp_int(node->data) == 20, "value check"); + PARSER_CHECK(1); + ok(strcmp(node->item->name + 1, "string") == 0, "name check"); + ok(node->item->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->data), "short") == 0, "value check"); + PARSER_CHECK(1); + ok(strcmp(node->item->name + 1, "string") == 0, "name check"); + ok(node->item->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->data), "long string") == 0, "value check"); + + diag("parser multi-group test"); + SET_INPUT_STR("multi-group:\n - id: foo\n base64: Zm9vYmFy\nreference: foo"); + PARSER_CHECK(0); + ok(strcmp(node->item->name + 1, "multi-group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + PARSER_CHECK(0); + ok(node->id_len > 0, "id check"); + ok(strcmp(node->item->name + 1, "multi-group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + id = node->item->var.g.id; + ok(strcmp(id->name + 1, "id") == 0, "name check"); + ok(id->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->id), "foo") == 0, "value check"); + PARSER_CHECK(1); + id = parent->item->var.g.id; + ok(strcmp(parent->item->name + 1, "multi-group") == 0, "name check"); + ok(parent->item->type == YP_TGRP, "type check"); + ok(parent->data_len == 0, "value length check"); + ok(strcmp(yp_str(parent->id), "foo") == 0, "value check"); + ok(strcmp(id->name + 1, "id") == 0, "name check"); + ok(id->type == YP_TSTR, "type check"); + ok(strcmp(node->item->name + 1, "base64") == 0, "name check"); + ok(node->item->type == YP_TB64, "type check"); + ok(memcmp(yp_bin(node->data), "foobar", yp_bin_len(node->data)) == 0, + "value check"); + ok(node->id_len == 0, "id length check"); + PARSER_CHECK(0); + ok(strcmp(node->item->name + 1, "reference") == 0, "name check"); + ok(node->item->type == YP_TREF, "type check"); + ok(strcmp(yp_str(node->data), "foo") == 0, "value check"); + + diag("parser check return"); + SET_INPUT_STR("unknown:"); + PARSER_RET_CHECK(KNOT_YP_EINVAL_ITEM); + + SET_INPUT_STR("group:\n unknown:"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_YP_EINVAL_ITEM); + + SET_INPUT_STR("group:\n - unknown: data"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_YP_EINVAL_ITEM); + + SET_INPUT_STR("group:\n - hex: data"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_YP_EINVAL_ITEM); + + SET_INPUT_STR("dname:"); + PARSER_RET_CHECK(KNOT_EINVAL); + + SET_INPUT_STR("group: data"); + PARSER_RET_CHECK(KNOT_YP_ENOTSUP_DATA); + + SET_INPUT_STR("group:\n integer:"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_EINVAL); + + SET_INPUT_STR("multi-group:\n id:"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_YP_ENODATA); + + SET_INPUT_STR("multi-group:\n hex:"); + PARSER_RET_CHECK(KNOT_EOK); + PARSER_RET_CHECK(KNOT_YP_ENOID); + +error_parser: + yp_schema_check_deinit(ctx); + yp_schema_free(schema); + yp_deinit(yp); +} + +#define STR_CHECK(depth, key0, key1, id, data) \ + ret = yp_schema_check_str(ctx, key0, key1, id, data); \ + is_int(KNOT_EOK, ret, "check str"); \ + ok(ctx->current == depth, "depth check"); \ + node = &ctx->nodes[ctx->current]; \ + parent = node->parent; + +#define STR_RET_CHECK(code, key0, key1, id, data) \ + ret = yp_schema_check_str(ctx, key0, key1, id, data); \ + ok(ret == code, "return check str"); + +static void str_test(void) +{ + yp_item_t *schema; + yp_check_ctx_t *ctx = NULL; + + int ret = yp_schema_copy(&schema, static_schema); + is_int(KNOT_EOK, ret, "schema copy"); + if (ret != KNOT_EOK) { + goto error_str; + } + + ctx = yp_schema_check_init(&schema); + ok(ctx != NULL, "create check ctx"); + if (ctx == NULL) { + goto error_str; + } + + yp_node_t *node; + yp_node_t *parent; + const yp_item_t *id; + + diag("str key0 test"); + STR_CHECK(0, "option", NULL, NULL, "one"); + ok(strcmp(node->item->name + 1, "option") == 0, "name check"); + ok(node->item->type == YP_TOPT, "type check"); + ok(yp_opt(node->data) == 1, "value check"); + + diag("str group test"); + STR_CHECK(0, "group", NULL, NULL, NULL); + ok(strcmp(node->item->name + 1, "group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + STR_CHECK(1, "group", "integer", NULL, "20"); + ok(strcmp(node->item->name + 1, "integer") == 0, "name check"); + ok(node->item->type == YP_TINT, "type check"); + ok(yp_int(node->data) == 20, "value check"); + STR_CHECK(1, "group", "string", NULL, "short"); + ok(strcmp(node->item->name + 1, "string") == 0, "name check"); + ok(node->item->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->data), "short") == 0, "value check"); + STR_CHECK(1, "group", "string", NULL, "long string"); + ok(strcmp(node->item->name + 1, "string") == 0, "name check"); + ok(node->item->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->data), "long string") == 0, "value check"); + + diag("str multi-group test"); + STR_CHECK(0, "multi-group", NULL, NULL, NULL); + ok(strcmp(node->item->name + 1, "multi-group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + STR_CHECK(0, "multi-group", NULL, "foo", NULL); + ok(node->id_len > 0, "id check"); + ok(strcmp(node->item->name + 1, "multi-group") == 0, "name check"); + ok(node->item->type == YP_TGRP, "type check"); + ok(node->data_len == 0, "value length check"); + id = node->item->var.g.id; + ok(strcmp(id->name + 1, "id") == 0, "name check"); + ok(id->type == YP_TSTR, "type check"); + ok(strcmp(yp_str(node->id), "foo") == 0, "value check"); + STR_CHECK(1, "multi-group", "base64", "foo", "Zm9vYmFy"); + id = parent->item->var.g.id; + ok(strcmp(parent->item->name + 1, "multi-group") == 0, "name check"); + ok(parent->item->type == YP_TGRP, "type check"); + ok(parent->data_len == 0, "value length check"); + ok(strcmp(yp_str(parent->id), "foo") == 0, "value check"); + ok(strcmp(id->name + 1, "id") == 0, "name check"); + ok(id->type == YP_TSTR, "type check"); + ok(strcmp(node->item->name + 1, "base64") == 0, "name check"); + ok(node->item->type == YP_TB64, "type check"); + ok(memcmp(yp_bin(node->data), "foobar", yp_bin_len(node->data)) == 0, + "value check"); + ok(node->id_len == 0, "id length check"); + STR_CHECK(0, "reference", NULL, NULL, "foo"); + ok(strcmp(node->item->name + 1, "reference") == 0, "name check"); + ok(node->item->type == YP_TREF, "type check"); + ok(strcmp(yp_str(node->data), "foo") == 0, "value check"); + + diag("str check return"); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, "", "", "", ""); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, NULL, NULL, NULL, NULL); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, "unknown", NULL, NULL, NULL); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, NULL, "unknown", NULL, NULL); + STR_RET_CHECK(KNOT_EINVAL, "dname", "", "", ""); + STR_RET_CHECK(KNOT_EOK, "dname", NULL, NULL, NULL); + STR_RET_CHECK(KNOT_EOK, "dname", NULL, NULL, "."); + STR_RET_CHECK(KNOT_EINVAL, "dname", NULL, NULL, ".."); + STR_RET_CHECK(KNOT_YP_ENOTSUP_ID, "dname", NULL, "id", NULL); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, "dname", "unknown", NULL, NULL); + + STR_RET_CHECK(KNOT_EOK, "group", "", "", ""); + STR_RET_CHECK(KNOT_EOK, "group", NULL, NULL, NULL); + STR_RET_CHECK(KNOT_YP_ENOTSUP_DATA, "group", "", "", "data"); + STR_RET_CHECK(KNOT_YP_EINVAL_ITEM, "group", "unknown", NULL, NULL); + STR_RET_CHECK(KNOT_EOK, "group", "string", NULL, NULL); + STR_RET_CHECK(KNOT_EOK, "group", "string", NULL, "data"); + STR_RET_CHECK(KNOT_EOK, "group", "string", NULL, ""); + STR_RET_CHECK(KNOT_YP_ENOTSUP_ID, "group", "", "id", NULL); + STR_RET_CHECK(KNOT_YP_ENOTSUP_ID, "group", "string", "id", NULL); + + STR_RET_CHECK(KNOT_EOK, "multi-group", "", "", ""); + STR_RET_CHECK(KNOT_EOK, "multi-group", NULL, NULL, NULL); + STR_RET_CHECK(KNOT_YP_ENOTSUP_DATA, "multi-group", NULL, NULL, "data"); + STR_RET_CHECK(KNOT_EOK, "multi-group", NULL, "idval", NULL); + STR_RET_CHECK(KNOT_YP_ENOTSUP_DATA, "multi-group", NULL, "idval", "data"); + STR_RET_CHECK(KNOT_EOK, "multi-group", "hex", "idval", NULL); + STR_RET_CHECK(KNOT_EOK, "multi-group", "hex", "idval", "data"); + STR_RET_CHECK(KNOT_EOK, "multi-group", "hex", NULL, NULL); + STR_RET_CHECK(KNOT_EOK, "multi-group", "hex", NULL, "data"); + STR_RET_CHECK(KNOT_EOK, "multi-group", "id", "", NULL); + STR_RET_CHECK(KNOT_EOK, "multi-group", "id", NULL, "idval"); + STR_RET_CHECK(KNOT_EOK, "multi-group", "id", "idval", NULL); + STR_RET_CHECK(KNOT_YP_ENOTSUP_DATA, "multi-group", "id", "idval", "data"); + +error_str: + yp_schema_check_deinit(ctx); + yp_schema_free(schema); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + schema_find_test(); + schema_merge_test(); + parser_test(); + str_test(); + + return 0; +} diff --git a/tests/libknot/test_yptrafo.c b/tests/libknot/test_yptrafo.c new file mode 100644 index 0000000..cd26632 --- /dev/null +++ b/tests/libknot/test_yptrafo.c @@ -0,0 +1,405 @@ +/* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <sys/socket.h> +#include <tap/basic.h> + +#include "libknot/yparser/yptrafo.h" +#include "libknot/libknot.h" + +static void int_test(const char *txt, int64_t num, yp_style_t s, + int64_t min, int64_t max) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TINT, YP_VINT = { min, max, YP_NIL, s } }; + + diag("integer \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(yp_int(b) == num, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, s | YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void int_bad_test(const char *txt, int code, yp_style_t s, + int64_t min, int64_t max) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TINT, YP_VINT = { min, max, YP_NIL, s } }; + + diag("integer \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void bool_test(const char *txt, bool val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TBOOL, YP_VNONE }; + + diag("boolean \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(yp_bool(b) == val, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void bool_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TBOOL, YP_VNONE }; + + diag("boolean \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void opt_test(const char *txt, unsigned val, const knot_lookup_t *opts) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TOPT, YP_VOPT = { opts } }; + + diag("option \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(b_len == 1, "compare length"); + ok(yp_opt(b) == val, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void opt_bad_test(const char *txt, int code, const knot_lookup_t *opts) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TOPT, YP_VOPT = { opts } }; + + diag("option \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void str_test(const char *txt, const char *val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TSTR, YP_VNONE }; + + diag("string \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(b_len == strlen(txt) + 1, "compare length"); + ok(memcmp(yp_str(b), val, b_len) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void addr_test(const char *txt, bool port) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TADDR, YP_VNONE }; + + diag("address \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + bool no_port; + yp_addr(b, &no_port); + ok(no_port == port, "compare port presence"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void addr_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TADDR, YP_VNONE }; + + diag("address \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void addr_range_test(const char *txt) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TNET, YP_VNONE }; + + diag("address range \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void addr_range_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_TNET, YP_VNONE }; + + diag("address range \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void dname_test(const char *txt, const char *val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TDNAME, YP_VNONE }; + + diag("dname \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(memcmp(yp_dname(b), val, b_len) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void hex_test(const char *txt, const char *val, const char *txt_out) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_THEX, YP_VNONE }; + + if (txt_out == NULL) { + txt_out = txt; + } + + diag("hex \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(memcmp(yp_bin(b), val, yp_bin_len(b)) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt_out) == t_len, "txt length"); + ok(memcmp(txt_out, t, t_len) == 0, "compare"); +} + +static void hex_bad_test(const char *txt, int code) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + yp_item_t i = { NULL, YP_THEX, YP_VNONE }; + + diag("hex \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + ok(ret == code, "invalid txt to bin"); +} + +static void base64_test(const char *txt, const char *val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t i = { NULL, YP_TB64, YP_VNONE }; + + diag("base64 \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(memcmp(yp_bin(b), val, yp_bin_len(b)) == 0, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +static void ref_test(const char *txt, bool val) +{ + int ret; + uint8_t b[64]; + size_t b_len = sizeof(b); + char t[64]; + size_t t_len = sizeof(t); + yp_item_t id = { NULL, YP_TBOOL, YP_VNONE }; + yp_item_t ref = { NULL, YP_TGRP, YP_VNONE }; + yp_item_t i = { NULL, YP_TREF, YP_VNONE }; + ref.var.g.id = &id; + i.var.r.ref = &ref; + + diag("reference to boolean \"%s\":", txt); + ret = yp_item_to_bin(&i, txt, strlen(txt), b, &b_len); + is_int(KNOT_EOK, ret, "txt to bin"); + ok(yp_bool(b) == val, "compare"); + ret = yp_item_to_txt(&i, b, b_len, t, &t_len, YP_SNOQUOTE); + is_int(KNOT_EOK, ret, "bin to txt"); + ok(strlen(t) == t_len, "txt ret length"); + ok(strlen(txt) == t_len, "txt length"); + ok(memcmp(txt, t, t_len) == 0, "compare"); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + /* Integer tests. */ + int64_t min = -20000000000, max = 20000000000; + int_test("5", 5, YP_SNONE, min, max); + int_test("0", 0, YP_SNONE, min, max); + int_test("-5", -5, YP_SNONE, min, max); + int_test("20000000000", max, YP_SNONE, min, max); + int_test("-20000000000", min, YP_SNONE, min, max); + int_test("11B", 11LL * 1, YP_SSIZE, min, max); + int_test("11K", 11LL * 1024, YP_SSIZE, min, max); + int_test("11M", 11LL * 1024 * 1024, YP_SSIZE, min, max); + int_test("11G", 11LL * 1024 * 1024 * 1024, YP_SSIZE, min, max); + int_test("11s", 11LL * 1, YP_STIME, min, max); + int_test("11m", 11LL * 60, YP_STIME, min, max); + int_test("11h", 11LL * 3600, YP_STIME, min, max); + int_test("11d", 11LL * 24 * 3600, YP_STIME, min, max); + int_test("1025B", 1025LL, YP_SSIZE, min, max); + int_test("61s", 61LL, YP_STIME, min, max); + int_bad_test("20000000001", KNOT_ERANGE, YP_SNONE, min, max); + int_bad_test("-20000000001", KNOT_ERANGE, YP_SNONE, min, max); + int_bad_test("1x", KNOT_EINVAL, YP_SNONE, min, max); + int_bad_test("1sx", KNOT_EINVAL, YP_STIME, min, max); + + /* Boolean tests. */ + bool_test("on", true); + bool_test("off", false); + bool_bad_test("onx", KNOT_EINVAL); + bool_bad_test("enable", KNOT_EINVAL); + + /* Option tests. */ + static const knot_lookup_t opts[] = { + { 1, "one" }, + { 10, "ten" }, + { 255, "max" }, + { 0, NULL } + }; + opt_test("one", 1, opts); + opt_test("ten", 10, opts); + opt_test("max", 255, opts); + opt_bad_test("onex", KNOT_EINVAL, opts); + opt_bad_test("word", KNOT_EINVAL, opts); + + /* String tests. */ + str_test("Test string!", "Test string!"); + + /* Address tests. */ + addr_test("192.168.123.1", true); + addr_test("192.168.123.1@12345", false); + addr_test("2001:db8::1", true); + addr_test("::1@12345", false); + addr_test("/tmp/test.sock", true); + addr_test("eth1@53", true); + addr_bad_test("192.168.123.x", KNOT_EINVAL); + addr_bad_test("192.168.123.1@", KNOT_EINVAL); + addr_bad_test("192.168.123.1@1x", KNOT_EINVAL); + addr_bad_test("192.168.123.1@65536", KNOT_ERANGE); + + /* Address range tests. */ + addr_range_test("/tmp/unix.sock"); + addr_range_test("1.1.1.1"); + addr_range_test("1.1.1.1/0"); + addr_range_test("1.1.1.1/32"); + addr_range_test("1.1.1.1-1.2.3.4"); + addr_range_test("::1"); + addr_range_test("::1/0"); + addr_range_test("::1/32"); + addr_range_test("1::-5::"); + addr_range_bad_test("unix", KNOT_EINVAL); + addr_range_bad_test("1.1.1", KNOT_EINVAL); + addr_range_bad_test("1.1.1.1/", KNOT_EINVAL); + addr_range_bad_test("1.1.1.1/33", KNOT_ERANGE); + addr_range_bad_test("1.1.1.1-", KNOT_EINVAL); + addr_range_bad_test("1.1.1.1-::1", KNOT_EINVAL); + + /* Dname tests. */ + dname_test("example.com.", "\x07""example""\x03""com""\x00"); + + /* Hex tests. */ + hex_test("", "", NULL); + hex_test("0x", "", ""); + hex_test("Hello World!", "Hello World!", NULL); + hex_test("0x0155FF", "\x01\x55\xFF", NULL); + hex_bad_test("0xA", KNOT_EINVAL); + + /* Base64 tests. */ + base64_test("Zm9vYmFy", "foobar"); + + /* Ref tests. */ + ref_test("on", true); + + return 0; +} diff --git a/tests/libzscanner/TESTS b/tests/libzscanner/TESTS new file mode 100644 index 0000000..227cdb4 --- /dev/null +++ b/tests/libzscanner/TESTS @@ -0,0 +1,86 @@ +00-0_general +00-1_general +00-2_general +00-3_general +00-4_general +01_owner +02_class +03_rrttl +04-0_ORIGIN +04-1_ORIGIN +04-2_ORIGIN +04-3_ORIGIN +04-4_ORIGIN +04-5_ORIGIN +04-6_ORIGIN +04-7_ORIGIN +04-8_ORIGIN +04-9_ORIGIN +05-0_TTL +05-1_TTL +05-2_TTL +05-3_TTL +05-4_TTL +06-0_INCLUDE +06-1_INCLUDE +06-2_INCLUDE +06-3_INCLUDE +06-4_INCLUDE +06-5_INCLUDE +06-6_INCLUDE +06-7_INCLUDE +06-8_INCLUDE +07-0-rdata +07-1-rdata +07-2-rdata +07-3-rdata +07-4-rdata +10_A +11_AAAA +12_TXT +13_SPF +14_NS +15_CNAME +16_PTR +17_DNAME +18_MX +19_AFSDB +20_RT +21_KX +22_HINFO +23_MINFO +24_RP +25_SOA +26_SRV +27_NAPTR +28_TYPE +29_CERT +30_KEY +31_DNSKEY +32_APL +33_DS +34_SSHFP +35_IPSECKEY +36_RRSIG +37_NSEC +38_DHCID +39_NSEC3 +40_NSEC3PARAM +41_TLSA +42_LOC +43_EUI48 +44_EUI64 +45_NID +46_L32 +47_L64 +48_LP +49_CDS +50_CDNSKEY +51_URI +52_CAA +53_SMIMEA +54_OPENPGPKEY +55_CSYNC +56_ZONEMD +57_SVCB +58_HTTPS diff --git a/tests/libzscanner/data/00-0_general.in b/tests/libzscanner/data/00-0_general.in new file mode 100644 index 0000000..21e9d03 --- /dev/null +++ b/tests/libzscanner/data/00-0_general.in @@ -0,0 +1,27 @@ +$ORIGIN . +$TTL 1 + +; OK +t01 IN 10 NS @ ; All items are mentioned + IN 10 NS @ ; Same as above without OWNER +t02 20 IN NS @ ; Switched CLASS and TTL + 20 IN NS @ ; Same as above without OWNER +t03 30 NS @ ; Missing CLASS + 30 NS @ ; Same as above without OWNER +t04 IN NS @ ; Missing TTL + IN NS @ ; Same as above without OWNER +t05 NS @ ; Missing CLASS and TTL + NS @ ; Same as above without OWNER + +@ ( ) NS ( ; Multiline 1/5 + ) () ( ; Multiline 2/5 + + @ ; Multiline 4/5 + ) ( +) ; Multiline 6/6 + +; KO +@ A ( + 1.1.1 + ) ; Error in multiline +@ NS ((@)) ; Nested parentheses - ERROR = STOP PROCESSING! diff --git a/tests/libzscanner/data/00-0_general.out b/tests/libzscanner/data/00-0_general.out new file mode 100644 index 0000000..522b3a6 --- /dev/null +++ b/tests/libzscanner/data/00-0_general.out @@ -0,0 +1,70 @@ +OWNER=0374303100 +CLASS=0001 +RRTTL=0000000A +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303100 +CLASS=0001 +RRTTL=0000000A +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303200 +CLASS=0001 +RRTTL=00000014 +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303200 +CLASS=0001 +RRTTL=00000014 +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303300 +CLASS=0001 +RRTTL=0000001E +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303300 +CLASS=0001 +RRTTL=0000001E +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303500 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0374303500 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +WARNG=ZS_BAD_IPV4 +------ +ERROR=ZS_LEFT_PARENTHESIS +------ diff --git a/tests/libzscanner/data/00-1_general.in b/tests/libzscanner/data/00-1_general.in new file mode 100644 index 0000000..2423909 --- /dev/null +++ b/tests/libzscanner/data/00-1_general.in @@ -0,0 +1,7 @@ +$ORIGIN . +$TTL 1 + +; KO +@ TXT ( "text" ; Unclosed multiline block + +;comment diff --git a/tests/libzscanner/data/00-1_general.out b/tests/libzscanner/data/00-1_general.out new file mode 100644 index 0000000..85b0653 --- /dev/null +++ b/tests/libzscanner/data/00-1_general.out @@ -0,0 +1,2 @@ +ERROR=ZS_UNCLOSED_MULTILINE +------ diff --git a/tests/libzscanner/data/00-2_general.in b/tests/libzscanner/data/00-2_general.in new file mode 100644 index 0000000..460eeb5 --- /dev/null +++ b/tests/libzscanner/data/00-2_general.in @@ -0,0 +1 @@ +$ORIGIN .
diff --git a/tests/libzscanner/data/00-2_general.out b/tests/libzscanner/data/00-2_general.out new file mode 100644 index 0000000..79776a7 --- /dev/null +++ b/tests/libzscanner/data/00-2_general.out @@ -0,0 +1,2 @@ +ERROR=ZS_DOS_NEWLINE +------ diff --git a/tests/libzscanner/data/00-3_general.in b/tests/libzscanner/data/00-3_general.in new file mode 100644 index 0000000..6ce107c --- /dev/null +++ b/tests/libzscanner/data/00-3_general.in @@ -0,0 +1,4 @@ +$ORIGIN . +$TTL 1 + +. NS @ ; No newline
\ No newline at end of file diff --git a/tests/libzscanner/data/00-3_general.out b/tests/libzscanner/data/00-3_general.out new file mode 100644 index 0000000..bc06672 --- /dev/null +++ b/tests/libzscanner/data/00-3_general.out @@ -0,0 +1,6 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ diff --git a/tests/libzscanner/data/00-4_general.in b/tests/libzscanner/data/00-4_general.in new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/libzscanner/data/00-4_general.in diff --git a/tests/libzscanner/data/00-4_general.out b/tests/libzscanner/data/00-4_general.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/libzscanner/data/00-4_general.out diff --git a/tests/libzscanner/data/01_owner.in b/tests/libzscanner/data/01_owner.in new file mode 100644 index 0000000..0108be3 --- /dev/null +++ b/tests/libzscanner/data/01_owner.in @@ -0,0 +1,37 @@ +$ORIGIN . +$TTL 1 + +; OK +. NS @ ; The simplest owner +tld. NS @ ; FQD tld owner +tld NS @ ; Relative form + NS @ ; The previous owner +*. NS @ ; FQD with asterisk +* NS @ ; Alone asterisk +*.* NS @ ; More asterisks +*a.a*a.** NS @ ; Also possible +@ NS @ ; Use origin +0123456789 NS @ ; Digits +0/25.2.0.192.in-addr.arpa. NS @ ; CIDR notation +_a_.-b-c-./d/. NS @ ; Allowed characters '_' '-' '/' anywhere +ABCDEFGHIJKLMNOPQRSTUVWXYZ NS @ ; All upper-case letters +abcdefghijklmnopqrstuvwxyz NS @ ; All lower-case letters +\000\0320\ \\\"\.\@\*.tld. NS @ ; Label with special chars +b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. NS @ ; IPv6 reverse +12345678901234567890123456789012345678901234567890123456789012\051.tld. NS @ ; Label of maximal length +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901. NS @ ; Domain name of maximal length +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901 NS @ ; Domain name of maximal length (after appending origin) + +; KO +& NS @ ; Bad (unslashed) character + NS @ ; Bad previous +.a NS @ ; Leading dot +@@ NS @ ; Double @@ +.. NS @ ; Missing label between dots +\1 NS @ ; Slash notation requires 3 digits +\12 NS @ ; Slash notation requires 3 digits +12345678901234567890123456789012345678901234567890123456789012\0514.tld. NS @ ; Label exceeded maximal length +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012. NS @ ; Domain name exceeded maximal length +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012 NS @ ; Domain name exceeded maximal length (after appending origin) +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.1 NS @ ; Domain name exceeded maximal length (maximal dname length check is after each valid label) +123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901.123456789012345678901234567890123456789012345678901234567890123 NS @ ; Domain name exceeded maximal length (maximal dname length check is after each valid label) diff --git a/tests/libzscanner/data/01_owner.out b/tests/libzscanner/data/01_owner.out new file mode 100644 index 0000000..26a8454 --- /dev/null +++ b/tests/libzscanner/data/01_owner.out @@ -0,0 +1,138 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=012A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=012A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=012A012A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=022A6103612A61022A2A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0A3031323334353637383900 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=04302F3235013201300331393207696E2D61646472046172706100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=035F615F052D622D632D032F642F00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=1A4142434445464748494A4B4C4D4E4F505152535455565758595A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=1A6162636465666768696A6B6C6D6E6F707172737475767778797A00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=09002030205C222E402A03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=3F31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +WARNG=ZS_BAD_OWNER +------ +WARNG=ZS_BAD_PREVIOUS_OWNER +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_LABEL_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ diff --git a/tests/libzscanner/data/02_class.in b/tests/libzscanner/data/02_class.in new file mode 100644 index 0000000..c4347e7 --- /dev/null +++ b/tests/libzscanner/data/02_class.in @@ -0,0 +1,10 @@ +$ORIGIN . +$TTL 1 + +; OK +@ IN NS @ ; The only accepted class IN +@ in NS @ ; Class in lower-case + +; KO +@ CH NS @ ; Unsupported class +@ CLASS1 NS @ ; Unsupported notation diff --git a/tests/libzscanner/data/02_class.out b/tests/libzscanner/data/02_class.out new file mode 100644 index 0000000..69daae3 --- /dev/null +++ b/tests/libzscanner/data/02_class.out @@ -0,0 +1,16 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +WARNG=ZS_UNSUPPORTED_TYPE +------ +WARNG=ZS_UNSUPPORTED_TYPE +------ diff --git a/tests/libzscanner/data/03_rrttl.in b/tests/libzscanner/data/03_rrttl.in new file mode 100644 index 0000000..7c57d73 --- /dev/null +++ b/tests/libzscanner/data/03_rrttl.in @@ -0,0 +1,26 @@ +$ORIGIN . +$TTL 1 + +; OK +@ 0 NS @ ; Minimal ttl +@ 3600 NS @ ; Inner value +@ 4294967295 NS @ ; Maximal ttl +@ 1S NS @ ; 1 second (upper-case) +@ 1s NS @ ; 1 second (lower-case) +@ 1M NS @ ; 1 minute (upper-case) +@ 1m NS @ ; 1 minute (lower-case) +@ 1H NS @ ; 1 hour (upper-case) +@ 1h NS @ ; 1 hour (lower-case) +@ 1D NS @ ; 1 day (upper-case) +@ 1d NS @ ; 1 day (lower-case) +@ 1W NS @ ; 1 week (upper-case) +@ 1w NS @ ; 1 week (lower-case) +@ 1w1d1h1m1s NS @ ; More time units +@ 1s1m1m NS @ ; Same time units, non decreasing order + +; KO +@ -1 NS @ ; Negative ttl +@ 4294967296 NS @ ; 32bit overflow +@ 100000000W NS @ ; 32bit overflow +@ 4294967295s1w NS @ ; 32bit overflow +@ 1x NS @ ; Unknown time unit diff --git a/tests/libzscanner/data/03_rrttl.out b/tests/libzscanner/data/03_rrttl.out new file mode 100644 index 0000000..f5cc907 --- /dev/null +++ b/tests/libzscanner/data/03_rrttl.out @@ -0,0 +1,100 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000000 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=FFFFFFFF +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=0000003C +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=0000003C +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00015180 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00015180 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00093A80 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00093A80 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=000A9A4D +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000079 +RTYPE=0002 +RDATA=00 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_BAD_TIME_UNIT +------ diff --git a/tests/libzscanner/data/04-0_ORIGIN.in b/tests/libzscanner/data/04-0_ORIGIN.in new file mode 100644 index 0000000..4d65ec4 --- /dev/null +++ b/tests/libzscanner/data/04-0_ORIGIN.in @@ -0,0 +1,29 @@ +$TTL 1 + +; OK +$ORIGIN . ; Root domain +@ NS @ ; Use origin +a. NS @ ; Absolute dname +a NS @ ; Relative dname +$ORIGIN tld. ; 1. level domain +@ NS @ ; Use origin +a. NS @ ; Absolute dname +a NS @ ; Relative dname +$ORIGIN second.tld. ; 2. level domain +@ NS @ ; Use origin +a. NS @ ; Absolute dname +a NS @ ; Relative dname +$ORIGIN \0320\ \\\"\.\@\*.tld. ; Label with special chars +@ NS @ ; Use origin +$ORIGIN b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. ; IPv6 reverse +@ NS @ ; Use origin +$ORIGIN 12345678901234567890123456789012345678901234567890123456789012\051.tld. ; Label of maximal length +@ NS @ ; Use origin +$ORIGIN 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901. ; Domain name of maximal length +@ NS @ ; Use origin +$origin . ; Lower-case +@ NS @ ; Use origin + +; KO +$ORIGIN ; Empty input +. NS . ; Is OK, but shouldn't be processed due to previous error stop! diff --git a/tests/libzscanner/data/04-0_ORIGIN.out b/tests/libzscanner/data/04-0_ORIGIN.out new file mode 100644 index 0000000..92dc459 --- /dev/null +++ b/tests/libzscanner/data/04-0_ORIGIN.out @@ -0,0 +1,86 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=016100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=016103746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=067365636F6E6403746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=067365636F6E6403746C6400 +------ +OWNER=016100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=067365636F6E6403746C6400 +------ +OWNER=0161067365636F6E6403746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=067365636F6E6403746C6400 +------ +OWNER=082030205C222E402A03746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=082030205C222E402A03746C6400 +------ +OWNER=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100 +------ +OWNER=3F31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=3F31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746C6400 +------ +OWNER=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +ERROR=ZS_BAD_ORIGIN +------ diff --git a/tests/libzscanner/data/04-1_ORIGIN.in b/tests/libzscanner/data/04-1_ORIGIN.in new file mode 100644 index 0000000..871c064 --- /dev/null +++ b/tests/libzscanner/data/04-1_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN tld ; Not FQD diff --git a/tests/libzscanner/data/04-1_ORIGIN.out b/tests/libzscanner/data/04-1_ORIGIN.out new file mode 100644 index 0000000..467de10 --- /dev/null +++ b/tests/libzscanner/data/04-1_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_ORIGIN +------ diff --git a/tests/libzscanner/data/04-2_ORIGIN.in b/tests/libzscanner/data/04-2_ORIGIN.in new file mode 100644 index 0000000..8dd2e20 --- /dev/null +++ b/tests/libzscanner/data/04-2_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN % ; Bad (unslashed) character diff --git a/tests/libzscanner/data/04-2_ORIGIN.out b/tests/libzscanner/data/04-2_ORIGIN.out new file mode 100644 index 0000000..467de10 --- /dev/null +++ b/tests/libzscanner/data/04-2_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_ORIGIN +------ diff --git a/tests/libzscanner/data/04-3_ORIGIN.in b/tests/libzscanner/data/04-3_ORIGIN.in new file mode 100644 index 0000000..26d1872 --- /dev/null +++ b/tests/libzscanner/data/04-3_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN .. ; Missing label between dots diff --git a/tests/libzscanner/data/04-3_ORIGIN.out b/tests/libzscanner/data/04-3_ORIGIN.out new file mode 100644 index 0000000..b7d67e5 --- /dev/null +++ b/tests/libzscanner/data/04-3_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/04-4_ORIGIN.in b/tests/libzscanner/data/04-4_ORIGIN.in new file mode 100644 index 0000000..0be4721 --- /dev/null +++ b/tests/libzscanner/data/04-4_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN \1 ; Slash notation requires 3 digits diff --git a/tests/libzscanner/data/04-4_ORIGIN.out b/tests/libzscanner/data/04-4_ORIGIN.out new file mode 100644 index 0000000..03a0738 --- /dev/null +++ b/tests/libzscanner/data/04-4_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/04-5_ORIGIN.in b/tests/libzscanner/data/04-5_ORIGIN.in new file mode 100644 index 0000000..170d465 --- /dev/null +++ b/tests/libzscanner/data/04-5_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN \12 ; Slash notation requires 3 digits diff --git a/tests/libzscanner/data/04-5_ORIGIN.out b/tests/libzscanner/data/04-5_ORIGIN.out new file mode 100644 index 0000000..03a0738 --- /dev/null +++ b/tests/libzscanner/data/04-5_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/04-6_ORIGIN.in b/tests/libzscanner/data/04-6_ORIGIN.in new file mode 100644 index 0000000..db9652d --- /dev/null +++ b/tests/libzscanner/data/04-6_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN .tld ; Leading dot diff --git a/tests/libzscanner/data/04-6_ORIGIN.out b/tests/libzscanner/data/04-6_ORIGIN.out new file mode 100644 index 0000000..b7d67e5 --- /dev/null +++ b/tests/libzscanner/data/04-6_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/04-7_ORIGIN.in b/tests/libzscanner/data/04-7_ORIGIN.in new file mode 100644 index 0000000..556646c --- /dev/null +++ b/tests/libzscanner/data/04-7_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN tld. x ; Unexpected item diff --git a/tests/libzscanner/data/04-7_ORIGIN.out b/tests/libzscanner/data/04-7_ORIGIN.out new file mode 100644 index 0000000..b7d67e5 --- /dev/null +++ b/tests/libzscanner/data/04-7_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/04-8_ORIGIN.in b/tests/libzscanner/data/04-8_ORIGIN.in new file mode 100644 index 0000000..445cbec --- /dev/null +++ b/tests/libzscanner/data/04-8_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN 12345678901234567890123456789012345678901234567890123456789012\0514.tld. ; Label exceeded maximal length diff --git a/tests/libzscanner/data/04-8_ORIGIN.out b/tests/libzscanner/data/04-8_ORIGIN.out new file mode 100644 index 0000000..788a495 --- /dev/null +++ b/tests/libzscanner/data/04-8_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_LABEL_OVERFLOW +------ diff --git a/tests/libzscanner/data/04-9_ORIGIN.in b/tests/libzscanner/data/04-9_ORIGIN.in new file mode 100644 index 0000000..e0a4b95 --- /dev/null +++ b/tests/libzscanner/data/04-9_ORIGIN.in @@ -0,0 +1,4 @@ +$TTL 1 + +; KO +$ORIGIN 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012. ; Domain name exceeded maximal length diff --git a/tests/libzscanner/data/04-9_ORIGIN.out b/tests/libzscanner/data/04-9_ORIGIN.out new file mode 100644 index 0000000..eef0ab5 --- /dev/null +++ b/tests/libzscanner/data/04-9_ORIGIN.out @@ -0,0 +1,2 @@ +ERROR=ZS_DNAME_OVERFLOW +------ diff --git a/tests/libzscanner/data/05-0_TTL.in b/tests/libzscanner/data/05-0_TTL.in new file mode 100644 index 0000000..baa8f38 --- /dev/null +++ b/tests/libzscanner/data/05-0_TTL.in @@ -0,0 +1,36 @@ +$ORIGIN . + +; OK +$TTL 0 ; Minimal ttl +@ NS @ ; Use ttl +$TTL 3600 ; Inner value +@ NS @ ; Use ttl +$TTL 4294967295 ; Maximal ttl +@ NS @ ; Use ttl +$TTL 1S ; 1 second (upper-case) +@ NS @ ; Use ttl +$TTL 1s ; 1 second (lower-case) +@ NS @ ; Use ttl +$TTL 1M ; 1 minute (upper-case) +@ NS @ ; Use ttl +$TTL 1m ; 1 minute (lower-case) +@ NS @ ; Use ttl +$TTL 1H ; 1 hour (upper-case) +@ NS @ ; Use ttl +$TTL 1h ; 1 hour (lower-case) +@ NS @ ; Use ttl +$TTL 1D ; 1 day (upper-case) +@ NS @ ; Use ttl +$TTL 1d ; 1 day (lower-case) +@ NS @ ; Use ttl +$TTL 1W ; 1 week (upper-case) +@ NS @ ; Use ttl +$TTL 1w ; 1 week (lower-case) +@ NS @ ; Use ttl +$TTL 1w1d1h1m1s ; More time units +@ NS @ ; Use ttl +$TTL 1s1m1m ; Same time units, non decreasing order +@ NS @ ; Use ttl + +; KO +$TTL -1 ; Negative ttl diff --git a/tests/libzscanner/data/05-0_TTL.out b/tests/libzscanner/data/05-0_TTL.out new file mode 100644 index 0000000..93c7651 --- /dev/null +++ b/tests/libzscanner/data/05-0_TTL.out @@ -0,0 +1,92 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000000 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=FFFFFFFF +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=0000003C +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=0000003C +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00015180 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00015180 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00093A80 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00093A80 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=000A9A4D +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000079 +RTYPE=0002 +RDATA=00 +------ +ERROR=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/05-1_TTL.in b/tests/libzscanner/data/05-1_TTL.in new file mode 100644 index 0000000..519fe79 --- /dev/null +++ b/tests/libzscanner/data/05-1_TTL.in @@ -0,0 +1,4 @@ +$ORIGIN . + +; KO +$TTL 4294967296 ; 32bit overflow diff --git a/tests/libzscanner/data/05-1_TTL.out b/tests/libzscanner/data/05-1_TTL.out new file mode 100644 index 0000000..1849267 --- /dev/null +++ b/tests/libzscanner/data/05-1_TTL.out @@ -0,0 +1,2 @@ +ERROR=ZS_NUMBER32_OVERFLOW +------ diff --git a/tests/libzscanner/data/05-2_TTL.in b/tests/libzscanner/data/05-2_TTL.in new file mode 100644 index 0000000..ed112da --- /dev/null +++ b/tests/libzscanner/data/05-2_TTL.in @@ -0,0 +1,4 @@ +$ORIGIN . + +; KO +$TTL 100000000W ; 32bit overflow diff --git a/tests/libzscanner/data/05-2_TTL.out b/tests/libzscanner/data/05-2_TTL.out new file mode 100644 index 0000000..1849267 --- /dev/null +++ b/tests/libzscanner/data/05-2_TTL.out @@ -0,0 +1,2 @@ +ERROR=ZS_NUMBER32_OVERFLOW +------ diff --git a/tests/libzscanner/data/05-3_TTL.in b/tests/libzscanner/data/05-3_TTL.in new file mode 100644 index 0000000..d96c9ba --- /dev/null +++ b/tests/libzscanner/data/05-3_TTL.in @@ -0,0 +1,4 @@ +$ORIGIN . + +; KO +$TTL 4294967295s1w ; 32bit overflow diff --git a/tests/libzscanner/data/05-3_TTL.out b/tests/libzscanner/data/05-3_TTL.out new file mode 100644 index 0000000..1849267 --- /dev/null +++ b/tests/libzscanner/data/05-3_TTL.out @@ -0,0 +1,2 @@ +ERROR=ZS_NUMBER32_OVERFLOW +------ diff --git a/tests/libzscanner/data/05-4_TTL.in b/tests/libzscanner/data/05-4_TTL.in new file mode 100644 index 0000000..efaf4d0 --- /dev/null +++ b/tests/libzscanner/data/05-4_TTL.in @@ -0,0 +1,4 @@ +$ORIGIN . + +; KO +$TTL 1x ; Unknown time unit diff --git a/tests/libzscanner/data/05-4_TTL.out b/tests/libzscanner/data/05-4_TTL.out new file mode 100644 index 0000000..d4bef98 --- /dev/null +++ b/tests/libzscanner/data/05-4_TTL.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_TIME_UNIT +------ diff --git a/tests/libzscanner/data/06-0_INCLUDE.in b/tests/libzscanner/data/06-0_INCLUDE.in new file mode 100644 index 0000000..962e6c9 --- /dev/null +++ b/tests/libzscanner/data/06-0_INCLUDE.in @@ -0,0 +1,29 @@ +$ORIGIN . +$TTL 1 + +; OK +0. NS @ + +$INCLUDE ./includes/include1 ; Relative path without origin +1. NS @ + +$INCLUDE "./includes/include2" . ; Quoted filename and the simplest origin +2. NS @ + +$INCLUDE ./includes/include\050 tld. ; Simple origin +3. NS @ + +$INCLUDE \./includes/include2 _a_.-b-c-./d/. ; Slashed character in file name, allowed characters in origin +4. NS @ + +$INCLUDE ./includes/include2 \0320\ \\\"\.\@\*.tld. ; Origin with special chars +5. NS @ + +$INCLUDE @TMPDIR@/includes/include2 ; Absolute path without origin +6. NS @ + +$INCLUDE @TMPDIR@/includes/include2 tld. ; Absolute path with origin +7. NS @ + +; KO (DISABLED - different results) +;$INCLUDE ; Empty parameters diff --git a/tests/libzscanner/data/06-0_INCLUDE.out b/tests/libzscanner/data/06-0_INCLUDE.out new file mode 100644 index 0000000..2536f72 --- /dev/null +++ b/tests/libzscanner/data/06-0_INCLUDE.out @@ -0,0 +1,138 @@ +OWNER=013000 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016105746C64316100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=016105746C64316200 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=05746C64316200 +------ +OWNER=013100 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016200 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013200 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016203746C6400 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013300 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0162035F615F052D622D632D032F642F00 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=035F615F052D622D632D032F642F00 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=0162082030205C222E402A03746C6400 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=082030205C222E402A03746C6400 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013500 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016200 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013600 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=016203746C6400 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ +OWNER=013700 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ diff --git a/tests/libzscanner/data/06-1_INCLUDE.in b/tests/libzscanner/data/06-1_INCLUDE.in new file mode 100644 index 0000000..194fb52 --- /dev/null +++ b/tests/libzscanner/data/06-1_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include1 a ; Origin is not FQDN diff --git a/tests/libzscanner/data/06-1_INCLUDE.out b/tests/libzscanner/data/06-1_INCLUDE.out new file mode 100644 index 0000000..6634921 --- /dev/null +++ b/tests/libzscanner/data/06-1_INCLUDE.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_INCLUDE_ORIGIN +------ diff --git a/tests/libzscanner/data/06-2_INCLUDE.in b/tests/libzscanner/data/06-2_INCLUDE.in new file mode 100644 index 0000000..21bcf05 --- /dev/null +++ b/tests/libzscanner/data/06-2_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include1 % ; Bad origin diff --git a/tests/libzscanner/data/06-2_INCLUDE.out b/tests/libzscanner/data/06-2_INCLUDE.out new file mode 100644 index 0000000..6634921 --- /dev/null +++ b/tests/libzscanner/data/06-2_INCLUDE.out @@ -0,0 +1,2 @@ +ERROR=ZS_BAD_INCLUDE_ORIGIN +------ diff --git a/tests/libzscanner/data/06-3_INCLUDE.in b/tests/libzscanner/data/06-3_INCLUDE.in new file mode 100644 index 0000000..f7079b4 --- /dev/null +++ b/tests/libzscanner/data/06-3_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE @TMPDIR@/ ; Given file is a directory diff --git a/tests/libzscanner/data/06-3_INCLUDE.out b/tests/libzscanner/data/06-3_INCLUDE.out new file mode 100644 index 0000000..6823154 --- /dev/null +++ b/tests/libzscanner/data/06-3_INCLUDE.out @@ -0,0 +1,2 @@ +ERROR=ZS_FILE_INVALID +------ diff --git a/tests/libzscanner/data/06-4_INCLUDE.in b/tests/libzscanner/data/06-4_INCLUDE.in new file mode 100644 index 0000000..3cdc79d --- /dev/null +++ b/tests/libzscanner/data/06-4_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE @TMPDIR@/file-doesnt-exist ; File doesn't exist diff --git a/tests/libzscanner/data/06-4_INCLUDE.out b/tests/libzscanner/data/06-4_INCLUDE.out new file mode 100644 index 0000000..e09e5d1 --- /dev/null +++ b/tests/libzscanner/data/06-4_INCLUDE.out @@ -0,0 +1,2 @@ +ERROR=ZS_FILE_OPEN +------ diff --git a/tests/libzscanner/data/06-5_INCLUDE.in b/tests/libzscanner/data/06-5_INCLUDE.in new file mode 100644 index 0000000..1d65812 --- /dev/null +++ b/tests/libzscanner/data/06-5_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include3 ; Blank include file diff --git a/tests/libzscanner/data/06-5_INCLUDE.out b/tests/libzscanner/data/06-5_INCLUDE.out new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/libzscanner/data/06-5_INCLUDE.out diff --git a/tests/libzscanner/data/06-6_INCLUDE.in b/tests/libzscanner/data/06-6_INCLUDE.in new file mode 100644 index 0000000..cbfda64 --- /dev/null +++ b/tests/libzscanner/data/06-6_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include4 ; Include file contains warning diff --git a/tests/libzscanner/data/06-6_INCLUDE.out b/tests/libzscanner/data/06-6_INCLUDE.out new file mode 100644 index 0000000..a9c0259 --- /dev/null +++ b/tests/libzscanner/data/06-6_INCLUDE.out @@ -0,0 +1,4 @@ +WARNG=ZS_BAD_RDATA +------ +ERROR=ZS_UNPROCESSED_INCLUDE +------ diff --git a/tests/libzscanner/data/06-7_INCLUDE.in b/tests/libzscanner/data/06-7_INCLUDE.in new file mode 100644 index 0000000..24deef7 --- /dev/null +++ b/tests/libzscanner/data/06-7_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include5 ; Include file contains error diff --git a/tests/libzscanner/data/06-7_INCLUDE.out b/tests/libzscanner/data/06-7_INCLUDE.out new file mode 100644 index 0000000..cbbb0c1 --- /dev/null +++ b/tests/libzscanner/data/06-7_INCLUDE.out @@ -0,0 +1,4 @@ +ERROR=ZS_BAD_NUMBER +------ +ERROR=ZS_UNPROCESSED_INCLUDE +------ diff --git a/tests/libzscanner/data/06-8_INCLUDE.in b/tests/libzscanner/data/06-8_INCLUDE.in new file mode 100644 index 0000000..c856668 --- /dev/null +++ b/tests/libzscanner/data/06-8_INCLUDE.in @@ -0,0 +1,5 @@ +$ORIGIN . +$TTL 1 + +; KO +$INCLUDE ./includes/include6 ; Include file contains include diff --git a/tests/libzscanner/data/06-8_INCLUDE.out b/tests/libzscanner/data/06-8_INCLUDE.out new file mode 100644 index 0000000..4581388 --- /dev/null +++ b/tests/libzscanner/data/06-8_INCLUDE.out @@ -0,0 +1,12 @@ +OWNER=016200 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=00 +------ +OWNER=016205746C64316100 +CLASS=0001 +RRTTL=00000E10 +RTYPE=0002 +RDATA=05746C64316100 +------ diff --git a/tests/libzscanner/data/07-0-rdata.in b/tests/libzscanner/data/07-0-rdata.in new file mode 100644 index 0000000..a79403f --- /dev/null +++ b/tests/libzscanner/data/07-0-rdata.in @@ -0,0 +1 @@ +@ A \
\ No newline at end of file diff --git a/tests/libzscanner/data/07-0-rdata.out b/tests/libzscanner/data/07-0-rdata.out new file mode 100644 index 0000000..ed303f6 --- /dev/null +++ b/tests/libzscanner/data/07-0-rdata.out @@ -0,0 +1,2 @@ +WARNG=ZS_BAD_ADDRESS_CHAR +------ diff --git a/tests/libzscanner/data/07-1-rdata.in b/tests/libzscanner/data/07-1-rdata.in new file mode 100644 index 0000000..7a5a11a --- /dev/null +++ b/tests/libzscanner/data/07-1-rdata.in @@ -0,0 +1 @@ +@ TXT \
\ No newline at end of file diff --git a/tests/libzscanner/data/07-1-rdata.out b/tests/libzscanner/data/07-1-rdata.out new file mode 100644 index 0000000..1702677 --- /dev/null +++ b/tests/libzscanner/data/07-1-rdata.out @@ -0,0 +1,2 @@ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/07-2-rdata.in b/tests/libzscanner/data/07-2-rdata.in new file mode 100644 index 0000000..7a4c8fe --- /dev/null +++ b/tests/libzscanner/data/07-2-rdata.in @@ -0,0 +1 @@ +@ TXT \092
\ No newline at end of file diff --git a/tests/libzscanner/data/07-2-rdata.out b/tests/libzscanner/data/07-2-rdata.out new file mode 100644 index 0000000..3f52437 --- /dev/null +++ b/tests/libzscanner/data/07-2-rdata.out @@ -0,0 +1,6 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000000 +RTYPE=0010 +RDATA=015C +------ diff --git a/tests/libzscanner/data/07-3-rdata.in b/tests/libzscanner/data/07-3-rdata.in new file mode 100644 index 0000000..338b212 --- /dev/null +++ b/tests/libzscanner/data/07-3-rdata.in @@ -0,0 +1 @@ +@ TXT \\
\ No newline at end of file diff --git a/tests/libzscanner/data/07-3-rdata.out b/tests/libzscanner/data/07-3-rdata.out new file mode 100644 index 0000000..3f52437 --- /dev/null +++ b/tests/libzscanner/data/07-3-rdata.out @@ -0,0 +1,6 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000000 +RTYPE=0010 +RDATA=015C +------ diff --git a/tests/libzscanner/data/07-4-rdata.in b/tests/libzscanner/data/07-4-rdata.in new file mode 100644 index 0000000..74a45dd --- /dev/null +++ b/tests/libzscanner/data/07-4-rdata.in @@ -0,0 +1 @@ +@ TXT \# 2 015C
\ No newline at end of file diff --git a/tests/libzscanner/data/07-4-rdata.out b/tests/libzscanner/data/07-4-rdata.out new file mode 100644 index 0000000..3f52437 --- /dev/null +++ b/tests/libzscanner/data/07-4-rdata.out @@ -0,0 +1,6 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000000 +RTYPE=0010 +RDATA=015C +------ diff --git a/tests/libzscanner/data/10_A.in b/tests/libzscanner/data/10_A.in new file mode 100644 index 0000000..6c7c90a --- /dev/null +++ b/tests/libzscanner/data/10_A.in @@ -0,0 +1,19 @@ +$ORIGIN . +$TTL 1 + +; OK +@ A 0.0.0.0 ; Minimal ipv4 address +@ A 255.255.255.255 ; Maximal ipv4 address +@ A \# 4 00000000 ; Hexadecimal rdata +@ TYPE1 \# 4 00000000 ; TYPE + Hexadecimal rdata +@ TYPE1 0.0.0.0 ; TYPE +@ a 0.0.0.0 ; Type in lower-case + +; KO +@ A +@ A ; Empty rdata +@ A \# 0 ; Hex empty rdata +@ A 0.0.0.256 ; 8bit overflow +@ A 0.0.0 ; Short address +@ A 0.0.0.A ; Bad character +@ A 0.0.0.0 1.1.1.1 ; Unexpected item diff --git a/tests/libzscanner/data/10_A.out b/tests/libzscanner/data/10_A.out new file mode 100644 index 0000000..dda68ab --- /dev/null +++ b/tests/libzscanner/data/10_A.out @@ -0,0 +1,50 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/11_AAAA.in b/tests/libzscanner/data/11_AAAA.in new file mode 100644 index 0000000..48c4b37 --- /dev/null +++ b/tests/libzscanner/data/11_AAAA.in @@ -0,0 +1,21 @@ +$ORIGIN . +$TTL 1 + +; OK +@ AAAA 0:0:0:0:0:0:0:0 ; Minimal ipv6 address +@ AAAA FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF ; Maximal ipv6 address +@ AAAA \# 16 00000000 00000000 00000000 00000000 ; Hexadecimal rdata +@ TYPE28 \# 16 00000000 00000000 00000000 00000000 ; TYPE + Hexadecimal rdata +@ TYPE28 0:0:0:0:0:0:0:0 ; TYPE +@ AAAA 0::1.2.3.4 ; ipv6 address based on ipv4 address +@ AAAA :: ; Double colon +@ aaAA :: ; Type in lower-case + +; KO +@ AAAA +@ AAAA ; Empty rdata +@ AAAA \# 0 ; Hex empty rdata +@ AAAA 0::FFFFF ; 16bit overflow +@ AAAA 0:0:0:0:0:0:0 ; Short address +@ AAAA 0:0:0:0:0:0:0:X ; Bad character +@ AAAA :: :: ; Unexpected item diff --git a/tests/libzscanner/data/11_AAAA.out b/tests/libzscanner/data/11_AAAA.out new file mode 100644 index 0000000..0cb174a --- /dev/null +++ b/tests/libzscanner/data/11_AAAA.out @@ -0,0 +1,62 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000001020304 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001C +RDATA=00000000000000000000000000000000 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_IPV6 +------ +WARNG=ZS_BAD_IPV6 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/12_TXT.in b/tests/libzscanner/data/12_TXT.in new file mode 100644 index 0000000..cdd0eaa --- /dev/null +++ b/tests/libzscanner/data/12_TXT.in @@ -0,0 +1,37 @@ +$ORIGIN . +$TTL 1 + +; OK +@ TXT "" ; Blank string +@ TXT a ; One char string +@ TXT \ ; One space char +@ TXT "\ " ; One space char in quotes +@ TXT \021 ; One unprintable char +@ TXT "\\ \"" ; Special chars +@ TXT "" "test1" "\255" test2 ; Array of text strings +@ TXT "" "" "" ; Array of blank strings +@ TXT first \# "\#" ; Array with special string +@ TXT \0320\ \\\"\;\.\@\*.tld. ; Special domain as a string +@ TXT " !\"#$%&'()*+,-./0123456789:;<=>?@" ; First part of all printables +@ TXT "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" ; Second part of all printables +@ TXT "abcdefghijklmnopqrstuvwxyz{|}~" ; Third part of all printables +@ TXT \# 1 00 ; Hexadecimal rdata +@ TYPE16 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE16 "" ; TYPE +@ TXT ( ; Special multi-line string +"first +second" +third ; Second string +) +@ TXT "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\053" ; Text string of maximal length (255 chars) +@ TXT "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\0536" ; Minimum overflowed text string which should be divided into two strings. +@ TXT "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\053\054" ; Minimum overflowed text string which should be divided into two strings (decimal version). +@ txt "" ; Type in lower-case + +; KO +@ TXT +@ TXT ; Empty rdata +@ TXT \# 0 ; Hex empty rdata +@ TXT \01 ; Missing digit in decimal notation +@ TXT \256 ; 8bit overflow in decimal notation +@ TXT """ ; '"' char without forward slash diff --git a/tests/libzscanner/data/12_TXT.out b/tests/libzscanner/data/12_TXT.out new file mode 100644 index 0000000..283b1e0 --- /dev/null +++ b/tests/libzscanner/data/12_TXT.out @@ -0,0 +1,138 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0120 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0120 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0115 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=035C2022 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0005746573743101FF057465737432 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=05666972737401230123 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0E2030205C223B2E402A2E746C642E +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=21202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F40 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=204142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=1E6162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=0C66697273740A7365636F6E64057468697264 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E3132333435 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E31323334350136 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E31323334350136 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0010 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_TEXT +------ diff --git a/tests/libzscanner/data/13_SPF.in b/tests/libzscanner/data/13_SPF.in new file mode 100644 index 0000000..0ad6c84 --- /dev/null +++ b/tests/libzscanner/data/13_SPF.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The SPF is the same as the TXT, so there are the differences and basics only. + +; OK +@ SPF "" "test1" "\255" test2 ; Array of text strings +@ SPF \# 1 00 ; Hexadecimal rdata +@ TYPE99 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE99 "" ; TYPE +@ spf "" ; Type in lower-case + +; KO +@ SPF diff --git a/tests/libzscanner/data/13_SPF.out b/tests/libzscanner/data/13_SPF.out new file mode 100644 index 0000000..be7fb35 --- /dev/null +++ b/tests/libzscanner/data/13_SPF.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0063 +RDATA=0005746573743101FF057465737432 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0063 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0063 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0063 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0063 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/14_NS.in b/tests/libzscanner/data/14_NS.in new file mode 100644 index 0000000..b56a579 --- /dev/null +++ b/tests/libzscanner/data/14_NS.in @@ -0,0 +1,38 @@ +$ORIGIN . +$TTL 1 + +; OK +@ NS . ; The simplest owner +@ NS tld. ; FQD tld owner +@ NS tld ; Relative form +@ NS *. ; FQD with asterisk +@ NS * ; Alone asterisk +@ NS *.* ; More asterisks +@ NS *a.a*a.** ; Also possible +@ NS @ ; Use origin +@ NS 0123456789 ; Digits +@ NS _a_.-b-c-./d/. ; Allowed characters '_' '-' '/' anywhere +@ NS ABCDEFGHIJKLMNOPQRSTUVWXYZ ; All upper-case letters +@ NS abcdefghijklmnopqrstuvwxyz ; All lower-case letters +@ NS \0320\ \\\"\.\@\*.tld. ; Label with special chars +@ NS b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. ; IPv6 reverse +@ NS 123456789012345678901234567890123456789012345678901234567890123.tld. ; Label of maximal length +@ NS 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901. ; Domain name of maximal length +@ NS 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.1234567890123456789012345678901234567890123456789012345678901 ; Domain name of maximal length (after appending origin) +@ TYPE2 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE2 @ ; TYPE +@ ns @ ; Type in lower-case + +; KO +@ NS +@ NS ; Empty rdata +@ NS \# 0 ; Hex empty rdata +@ NS & ; Bad (unslashed) character +@ NS @@ ; Double @@ +@ NS .. ; Missing label between dots +@ NS \1 ; Slash notation requires 3 digits +@ NS \12 ; Slash notation requires 3 digits +@ NS 1234567890123456789012345678901234567890123456789012345678901234.tld. ; Label exceeded maximal length +@ NS 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012. ; Domain name exceeded maximal length +@ NS 123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.12345678901234567890123456789012345678901234567890123456789012 ; Domain name exceeded maximal length (after appending origin) +@ NS . x ; Unexpected item diff --git a/tests/libzscanner/data/14_NS.out b/tests/libzscanner/data/14_NS.out new file mode 100644 index 0000000..08d739a --- /dev/null +++ b/tests/libzscanner/data/14_NS.out @@ -0,0 +1,144 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=012A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=012A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=012A012A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=022A6103612A61022A2A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=0A3031323334353637383900 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=035F615F052D622D632D032F642F00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=1A4142434445464748494A4B4C4D4E4F505152535455565758595A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=1A6162636465666768696A6B6C6D6E6F707172737475767778797A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=082030205C222E402A03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=0162016101390138013701360135013001300130013001300130013001300130013001300130013001300130013001300138016201640130013101300130013203697036046172706100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=3F31323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323303746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=3F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333F3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333D3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0002 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_LABEL_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ +WARNG=ZS_DNAME_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/15_CNAME.in b/tests/libzscanner/data/15_CNAME.in new file mode 100644 index 0000000..806b8f9 --- /dev/null +++ b/tests/libzscanner/data/15_CNAME.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The CNAME is the same as the NS, so there are the differences and basics only. + +; OK +@ CNAME test.example.com ; Relative dname +@ CNAME \# 1 00 ; Hexadecimal rdata +@ TYPE5 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE5 @ ; TYPE +@ cname @ ; Type in lower-case + +; KO +@ CNAME diff --git a/tests/libzscanner/data/15_CNAME.out b/tests/libzscanner/data/15_CNAME.out new file mode 100644 index 0000000..3c3a55d --- /dev/null +++ b/tests/libzscanner/data/15_CNAME.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0005 +RDATA=0474657374076578616D706C6503636F6D00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0005 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0005 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0005 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0005 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/16_PTR.in b/tests/libzscanner/data/16_PTR.in new file mode 100644 index 0000000..3694e7d --- /dev/null +++ b/tests/libzscanner/data/16_PTR.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The PTR is the same as the NS, so there are the differences and basics only. + +; OK +@ PTR test.example.com ; Relative dname +@ PTR \# 1 00 ; Hexadecimal rdata +@ TYPE12 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE12 @ ; TYPE +@ ptr @ ; Type in lower-case + +; KO +@ PTR diff --git a/tests/libzscanner/data/16_PTR.out b/tests/libzscanner/data/16_PTR.out new file mode 100644 index 0000000..55d94b9 --- /dev/null +++ b/tests/libzscanner/data/16_PTR.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000C +RDATA=0474657374076578616D706C6503636F6D00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000C +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000C +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000C +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000C +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/17_DNAME.in b/tests/libzscanner/data/17_DNAME.in new file mode 100644 index 0000000..5e9ba71 --- /dev/null +++ b/tests/libzscanner/data/17_DNAME.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The DNAME is the same as the NS, so there are the differences and basics only. + +; OK +@ DNAME test.example.com ; Relative dname +@ DNAME \# 1 00 ; Hexadecimal rdata +@ TYPE39 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE39 @ ; TYPE +@ dname @ ; Type in lower-case + +; KO +@ DNAME diff --git a/tests/libzscanner/data/17_DNAME.out b/tests/libzscanner/data/17_DNAME.out new file mode 100644 index 0000000..35f11d8 --- /dev/null +++ b/tests/libzscanner/data/17_DNAME.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0027 +RDATA=0474657374076578616D706C6503636F6D00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0027 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0027 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0027 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0027 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/18_MX.in b/tests/libzscanner/data/18_MX.in new file mode 100644 index 0000000..61e6afb --- /dev/null +++ b/tests/libzscanner/data/18_MX.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; For more tests on dname see NS test (same processing) + +; OK +@ MX 0 @ ; Minimal priority +@ MX 65535 @ ; Maximal priority +@ MX 1 mail ; Relative dname +@ MX 1 mail.tld. ; Absolute dname +@ MX \# 3 0001 00 ; Hexadecimal rdata +@ TYPE15 \# 3 0001 00 ; TYPE + Hexadecimal rdata +@ TYPE15 1 @ ; TYPE +@ mx 1 @ ; Type in lower-case + +; KO +@ MX +@ MX ; Empty rdata +@ MX \# 0 ; Hex empty rdata +@ MX -1 @ ; Negative number +@ MX 65536 @ ; 16bit overflow +@ MX 1 $ ; Bad dname +@ MX 0 @ x ; Unexpected item diff --git a/tests/libzscanner/data/18_MX.out b/tests/libzscanner/data/18_MX.out new file mode 100644 index 0000000..0a50038 --- /dev/null +++ b/tests/libzscanner/data/18_MX.out @@ -0,0 +1,62 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=FFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=0001046D61696C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=0001046D61696C03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000F +RDATA=000100 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/19_AFSDB.in b/tests/libzscanner/data/19_AFSDB.in new file mode 100644 index 0000000..be569e4 --- /dev/null +++ b/tests/libzscanner/data/19_AFSDB.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The AFSDB is the same as the MX, so there are the differences and basics only. + +; OK +@ AFSDB 1 mail ; Relative dname +@ AFSDB \# 3 0001 00 ; Hexadecimal rdata +@ TYPE18 \# 3 0001 00 ; TYPE + Hexadecimal rdata +@ TYPE18 1 @ ; TYPE +@ afsdb 1 @ ; Type in lower-case + +; KO +@ AFSDB diff --git a/tests/libzscanner/data/19_AFSDB.out b/tests/libzscanner/data/19_AFSDB.out new file mode 100644 index 0000000..b5c77eb --- /dev/null +++ b/tests/libzscanner/data/19_AFSDB.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0012 +RDATA=0001046D61696C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0012 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0012 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0012 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0012 +RDATA=000100 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/20_RT.in b/tests/libzscanner/data/20_RT.in new file mode 100644 index 0000000..3bc774d --- /dev/null +++ b/tests/libzscanner/data/20_RT.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The RT is the same as the MX, so there are the differences and basics only. + +; OK +@ RT 1 mail ; Relative dname +@ RT \# 3 0001 00 ; Hexadecimal rdata +@ TYPE21 \# 3 0001 00 ; TYPE + Hexadecimal rdata +@ TYPE21 1 @ ; TYPE +@ rt 1 @ ; Type in lower-case + +; KO +@ RT diff --git a/tests/libzscanner/data/20_RT.out b/tests/libzscanner/data/20_RT.out new file mode 100644 index 0000000..8be89a3 --- /dev/null +++ b/tests/libzscanner/data/20_RT.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0015 +RDATA=0001046D61696C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0015 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0015 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0015 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0015 +RDATA=000100 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/21_KX.in b/tests/libzscanner/data/21_KX.in new file mode 100644 index 0000000..529480d --- /dev/null +++ b/tests/libzscanner/data/21_KX.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The KX is the same as the MX, so there are the differences and basics only. + +; OK +@ KX 1 mail ; Relative dname +@ KX \# 3 0001 00 ; Hexadecimal rdata +@ TYPE36 \# 3 0001 00 ; TYPE + Hexadecimal rdata +@ TYPE36 1 @ ; TYPE +@ kx 1 @ ; Type in lower-case + +; KO +@ KX diff --git a/tests/libzscanner/data/21_KX.out b/tests/libzscanner/data/21_KX.out new file mode 100644 index 0000000..1bc91e6 --- /dev/null +++ b/tests/libzscanner/data/21_KX.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0024 +RDATA=0001046D61696C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0024 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0024 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0024 +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0024 +RDATA=000100 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/22_HINFO.in b/tests/libzscanner/data/22_HINFO.in new file mode 100644 index 0000000..4cd5ab8 --- /dev/null +++ b/tests/libzscanner/data/22_HINFO.in @@ -0,0 +1,26 @@ +$ORIGIN . +$TTL 1 + +; OK +@ HINFO "" "" ; Blank string +@ HINFO a b ; One char string +@ HINFO \ \ ; One space char +@ HINFO "\ " "\ " ; One space char in quotes +@ HINFO \021 \022 ; One unprintable char +@ HINFO "\\ \"" "\\ \"" ; Special chars +@ HINFO first \# ; Array with special string +@ HINFO \# 2 00 00 ; Hexadecimal rdata +@ TYPE13 \# 2 00 00 ; TYPE + Hexadecimal rdata +@ TYPE13 "" "" ; TYPE +@ HINFO "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\053" "" ; Text string of maximal length (255 chars) +@ hinfo "" "" ; Type in lower-case + +; KO +@ HINFO +@ HINFO ; Empty rdata +@ HINFO \# 0 ; Hex empty rdata +@ HINFO \01 "" ; Missing digit in decimal notation +@ HINFO \256 "" ; 8bit overflow in decimal notation +@ HINFO """ "" ; '"' char without forward slash +@ HINFO "" "" "" ; Unexpected item +@ HINFO "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\0536" "" ; Maximal length overflow diff --git a/tests/libzscanner/data/22_HINFO.out b/tests/libzscanner/data/22_HINFO.out new file mode 100644 index 0000000..fa66729 --- /dev/null +++ b/tests/libzscanner/data/22_HINFO.out @@ -0,0 +1,88 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=01610162 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=01200120 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=01200120 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=01150116 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=035C2022035C2022 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0566697273740123 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E313233343500 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000D +RDATA=0000 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_TEXT +------ +WARNG=ZS_BAD_REST +------ +WARNG=ZS_ITEM_OVERFLOW +------ diff --git a/tests/libzscanner/data/23_MINFO.in b/tests/libzscanner/data/23_MINFO.in new file mode 100644 index 0000000..7b34c60 --- /dev/null +++ b/tests/libzscanner/data/23_MINFO.in @@ -0,0 +1,18 @@ +$ORIGIN . +$TTL 1 + +; For more tests on dname see NS test (same processing) + +; OK +@ MINFO . . ; The simplest dnames +@ MINFO @ @ ; Use origin +@ MINFO mail mail.tld. ; Relative and absolute dnames +@ MINFO \# 2 00 00 ; Hexadecimal rdata +@ TYPE14 \# 2 00 00 ; TYPE + Hexadecimal rdata +@ TYPE14 @ @ ; TYPE +@ minfo @ @ ; Type in lower-case + +; KO +@ MINFO +@ MINFO ; Empty rdata +@ MINFO \# 0 ; Hex empty rdata diff --git a/tests/libzscanner/data/23_MINFO.out b/tests/libzscanner/data/23_MINFO.out new file mode 100644 index 0000000..8154c0c --- /dev/null +++ b/tests/libzscanner/data/23_MINFO.out @@ -0,0 +1,48 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=046D61696C00046D61696C03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=000E +RDATA=0000 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/24_RP.in b/tests/libzscanner/data/24_RP.in new file mode 100644 index 0000000..a70d792 --- /dev/null +++ b/tests/libzscanner/data/24_RP.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The RP is the same as the MINFO, so there are the differences and basics only. + +; OK +@ RP mail mail.tld. ; Relative and absolute dnames +@ RP \# 2 00 00 ; Hexadecimal rdata +@ TYPE17 \# 2 00 00 ; TYPE + Hexadecimal rdata +@ TYPE17 @ @ ; TYPE +@ rp @ @ ; Type in lower-case + +; KO +@ RP diff --git a/tests/libzscanner/data/24_RP.out b/tests/libzscanner/data/24_RP.out new file mode 100644 index 0000000..d13b1ba --- /dev/null +++ b/tests/libzscanner/data/24_RP.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0011 +RDATA=046D61696C00046D61696C03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0011 +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0011 +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0011 +RDATA=0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0011 +RDATA=0000 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/25_SOA.in b/tests/libzscanner/data/25_SOA.in new file mode 100644 index 0000000..bf093d4 --- /dev/null +++ b/tests/libzscanner/data/25_SOA.in @@ -0,0 +1,31 @@ +$ORIGIN . +$TTL 1 + +; OK +@ SOA @ @ 0 0 0 0 0 ; The simplest variant +@ SOA tld. tld 0 0 0 0 0 ; Absolute and relative dnames. +@ SOA @ @ 4294967295 0 0 0 0 ; Maximal serial +@ SOA @ @ 0 4294967295 4294967295 4294967295 4294967295 ; Maximal times +@ SOA @ @ 0 1d 1h 1m 1s ; Time units +@ TYPE6 \# 22 00 00 0000000000000000000000000000000000000000 ; TYPE + Hexadecimal rdata +@ TYPE6 @ @ 0 0 0 0 0 ; TYPE +@ SOA ns.tld. first\.second.tld. ( ; Multiline record + 2007120710 + 1w2d3h4m5s + 2h + 3m + 4s +) +@ soa @ @ 0 0 0 0 0 ; Type in lower-case + +; KO +@ SOA +@ SOA ; Empty rdata +@ SOA \# 0 ; Hex empty rdata +@ SOA @ @ 1h 0 0 0 0 ; Bad number +@ SOA @ @ 4294967296 0 0 0 0 ; Serial overflow +@ SOA @ @ 0 4294967296 0 0 0 ; Refresh overflow +@ SOA @ @ 0 0 4294967296 0 0 ; Retry overflow +@ SOA @ @ 0 0 0 4294967296 0 ; Expire overflow +@ SOA @ @ 0 0 0 0 4294967296 ; Minimum overflow +@ SOA @ @ 0 0 0 0 0 x ; Unexpected item diff --git a/tests/libzscanner/data/25_SOA.out b/tests/libzscanner/data/25_SOA.out new file mode 100644 index 0000000..f658442 --- /dev/null +++ b/tests/libzscanner/data/25_SOA.out @@ -0,0 +1,74 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=00000000000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=03746C640003746C64000000000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=0000FFFFFFFF00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=0000000000000001518000000E100000003C00000001 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=00000000000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=00000000000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=026E7303746C64000C66697273742E7365636F6E6403746C640077A23B46000C08A500001C20000000B400000004 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0006 +RDATA=00000000000000000000000000000000000000000000 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/26_SRV.in b/tests/libzscanner/data/26_SRV.in new file mode 100644 index 0000000..001e1e6 --- /dev/null +++ b/tests/libzscanner/data/26_SRV.in @@ -0,0 +1,25 @@ +$ORIGIN . +$TTL 1 + +; OK +@ SRV 0 0 0 @ ; The simplest variant +_ldap._tcp.test.tld. SRV 0 0 0 @ ; Underscores in owner +@ SRV 65535 65535 65535 @ ; Maximal numbers +@ SRV 0 0 0 \0320\ \\\"\.\@\*.tld. ; Dname with specials +@ TYPE33 \# 7 000000000000 00 ; TYPE + Hexadecimal rdata +@ TYPE33 0 0 0 @ ; TYPE +@ srv 0 0 0 @ ; Type in lower-case + +; KO +@ SRV +@ SRV ; Empty rdata +@ SRV \# 0 ; Hex empty rdata +@ SRV 1h 0 0 @ ; Bad priority +@ SRV 0 1h 0 @ ; Bad weight +@ SRV 0 0 1h @ ; Bad port +@ SRV 0 0 0 % ; Bad target +@ SRV 65536 0 0 @ ; Priority overflow +@ SRV 0 65536 0 @ ; Weight overflow +@ SRV 0 0 65536 @ ; Port overflow +@ SRV 0 0 0 @ x ; Unexpected item +@ SRV 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/26_SRV.out b/tests/libzscanner/data/26_SRV.out new file mode 100644 index 0000000..eadb804 --- /dev/null +++ b/tests/libzscanner/data/26_SRV.out @@ -0,0 +1,66 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=00000000000000 +------ +OWNER=055F6C646170045F746370047465737403746C6400 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=00000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=FFFFFFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=000000000000082030205C222E402A03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=00000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=00000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0021 +RDATA=00000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/27_NAPTR.in b/tests/libzscanner/data/27_NAPTR.in new file mode 100644 index 0000000..44fd346 --- /dev/null +++ b/tests/libzscanner/data/27_NAPTR.in @@ -0,0 +1,20 @@ +$ORIGIN . +$TTL 1 + +; OK +@ NAPTR 0 0 "" "" "" @ ; The simplest variant +@ NAPTR 65535 65535 "" "" "" @ ; Maximal numbers +@ NAPTR 65535 65535 "" "" "!^urn:cid:.+@([^\.]+\.)(.*)$!\\2!i" @ ; Regexp example +@ NAPTR 0 0 "" "" "" \0320\ \\\"\.\@\*.tld. ; Dname with specials +@ TYPE35 \# 8 00000000000000 00 ; TYPE + Hexadecimal rdata +@ TYPE35 0 0 "" "" "" @ ; TYPE +@ naptr 0 0 "" "" "" @ ; Type in lower-case + +; KO +@ NAPTR +@ NAPTR ; Empty rdata +@ NAPTR \# 0 ; Hex empty rdata +@ NAPTR 65536 0 "" "" "" @ ; Order overflow +@ NAPTR 0 65536 "" "" "" @ ; Preference overflow +@ NAPTR 0 0 "" "" "" @ x ; Unexpected item +@ NAPTR 0 0 "" "" "" ; Missing item diff --git a/tests/libzscanner/data/27_NAPTR.out b/tests/libzscanner/data/27_NAPTR.out new file mode 100644 index 0000000..cc34e26 --- /dev/null +++ b/tests/libzscanner/data/27_NAPTR.out @@ -0,0 +1,56 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=FFFFFFFF00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=FFFFFFFF00001F215E75726E3A6369643A2E2B40285B5E2E5D2B2E29282E2A2924215C32216900 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=00000000000000082030205C222E402A03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0023 +RDATA=0000000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/28_TYPE.in b/tests/libzscanner/data/28_TYPE.in new file mode 100644 index 0000000..f8189e8 --- /dev/null +++ b/tests/libzscanner/data/28_TYPE.in @@ -0,0 +1,27 @@ +$ORIGIN . +$TTL 1 + +; OK +@ TYPE0 \# 0 ; Minimal type number +@ TYPE65535 \# 0 ; Maximal type number +@ TYPE55555 \# 0 ; Without hex rdata +@ TYPE55555 \# 1 00 ; Without hex rdata +@ TYPE1 \# 4 00000000 ; Known type +@ TYPE1 0.0.0.0 ; Known type in text format +@ TYPE55555 ( ; Multiline begin + \# + 5 + 0102 03 + 04 05 + ) ; Multiline end +@ type55555 \# 0 ; Type in lower-case + +; KO +@ TYPE55555 +@ TYPE55555 ; Without text rdata +@ TYPE65536 ; Type number overflow +@ TYPE65535x ; Bad type +@ TYPE55555 \# ; Missing hex length +@ TYPE55555 \# 1 0000 ; Too long rdata +@ TYPE55555 \# 2 00 ; Bad rdata length +@ TYPE55555 \# 1 00 x ; Unexpected data diff --git a/tests/libzscanner/data/28_TYPE.out b/tests/libzscanner/data/28_TYPE.out new file mode 100644 index 0000000..0aa409a --- /dev/null +++ b/tests/libzscanner/data/28_TYPE.out @@ -0,0 +1,64 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0000 +RDATA= +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=FFFF +RDATA= +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=D903 +RDATA= +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=D903 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0001 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=D903 +RDATA=0102030405 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=D903 +RDATA= +------ +WARNG=ZS_CANNOT_TEXT_DATA +------ +WARNG=ZS_CANNOT_TEXT_DATA +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_RDATA_LENGTH +------ +WARNG=ZS_BAD_RDATA_LENGTH +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/29_CERT.in b/tests/libzscanner/data/29_CERT.in new file mode 100644 index 0000000..ee70ce2 --- /dev/null +++ b/tests/libzscanner/data/29_CERT.in @@ -0,0 +1,58 @@ +$ORIGIN . +$TTL 1 + +; OK +@ CERT 0 0 0 AA== ; The simplest variant +@ CERT 65535 65535 255 AA== ; Maximal numbers +@ CERT PKIX 0 0 AA== ; Certificate type mnemo +@ CERT SPKI 0 0 AA== ; Certificate type mnemo +@ CERT PGP 0 0 AA== ; Certificate type mnemo +@ CERT IPKIX 0 0 AA== ; Certificate type mnemo +@ CERT ISPKI 0 0 AA== ; Certificate type mnemo +@ CERT IPGP 0 0 AA== ; Certificate type mnemo +@ CERT ACPKIX 0 0 AA== ; Certificate type mnemo +@ CERT IACPKIX 0 0 AA== ; Certificate type mnemo +@ CERT URI 0 0 AA== ; Certificate type mnemo +@ CERT OID 0 0 AA== ; Certificate type mnemo +@ CERT 0 0 RSAMD5 AA== ; Algorithm mnemo +@ CERT 0 0 DH AA== ; Algorithm mnemo +@ CERT 0 0 DSA AA== ; Algorithm mnemo +@ CERT 0 0 RSASHA1 AA== ; Algorithm mnemo +@ CERT 0 0 DSA-NSEC3-SHA1 AA== ; Algorithm mnemo +@ CERT 0 0 RSASHA1-NSEC3-SHA1 AA== ; Algorithm mnemo +@ CERT 0 0 RSASHA256 AA== ; Algorithm mnemo +@ CERT 0 0 RSASHA512 AA== ; Algorithm mnemo +@ CERT 0 0 ECC-GOST AA== ; Algorithm mnemo +@ CERT 0 0 ECDSAP256SHA256 AA== ; Algorithm mnemo +@ CERT 0 0 ECDSAP384SHA384 AA== ; Algorithm mnemo +@ CERT 0 0 ED25519 AA== ; Algorithm mnemo +@ CERT 0 0 ED448 AA== ; Algorithm mnemo +@ CERT 0 0 INDIRECT AA== ; Algorithm mnemo +@ CERT 0 0 PRIVATEDNS AA== ; Algorithm mnemo +@ CERT 0 0 PRIVATEOID AA== ; Algorithm mnemo +@ CERT 0 0 0 Zm8= ; One char padding +@ CERT 0 0 0 Zm9v ; Without padding +@ CERT 0 0 0 Zm9vYg== ; Two base64 blocks +@ CERT 0 0 0 Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE37 \# 6 000000000000 ; TYPE + Hexadecimal rdata +@ TYPE37 0 0 0 AA== ; TYPE +@ cert 0 0 0 AA== ; Type in lower-case + +; KO +@ CERT +@ CERT ; Empty rdata +@ CERT \# 0 ; Hex empty rdata +@ CERT 65536 0 0 AA== ; Type overflow +@ CERT X 0 0 AA== ; Bad type mnemonic +@ CERT 0 65536 0 AA== ; Key tag overflow +@ CERT 0 0 256 AA== ; Algorithm overflow +@ CERT 0 0 0 A ; Continuous block length must be multiple of 4 +@ CERT 0 0 0 AB ; Continuous block length must be multiple of 4 +@ CERT 0 0 0 ABC ; Continuous block length must be multiple of 4 +@ CERT 0 0 0 AA == ; Continuous block length must be multiple of 4 +@ CERT 0 0 0 A=== ; Bad padding +@ CERT 0 0 0 = ; Bad padding +@ CERT 0 0 0 == ; Bad padding +@ CERT 0 0 0 === ; Bad padding +@ CERT 0 0 0 ==== ; Bad padding +@ CERT 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/29_CERT.out b/tests/libzscanner/data/29_CERT.out new file mode 100644 index 0000000..da2c897 --- /dev/null +++ b/tests/libzscanner/data/29_CERT.out @@ -0,0 +1,244 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=FFFFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000100000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000200000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000300000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000400000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000500000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000600000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000700000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000800000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=00FD00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=00FE00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000200 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000300 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000500 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000600 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000700 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000800 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000A00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000D00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000E00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000F00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000001000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=00000000FC00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=00000000FD00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=00000000FE00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=0000000000666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=0000000000666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=0000000000666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=0000000000666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0025 +RDATA=000000000000 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_CERT_TYPE +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/30_KEY.in b/tests/libzscanner/data/30_KEY.in new file mode 100644 index 0000000..263fa03 --- /dev/null +++ b/tests/libzscanner/data/30_KEY.in @@ -0,0 +1,31 @@ +$ORIGIN . +$TTL 1 + +; OK +@ KEY 0 0 0 AA== ; The simplest variant +@ KEY 65535 255 255 AA== ; Maximal numbers +@ KEY 0 0 0 Zm8= ; One char padding +@ KEY 0 0 0 Zm9v ; Without padding +@ KEY 0 0 0 Zm9vYg== ; Two base64 blocks +@ KEY 0 0 0 Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE25 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE25 0 0 0 AA== ; TYPE +@ key 0 0 0 AA== ; Type in lower-case + +; KO +@ KEY +@ KEY ; Empty rdata +@ KEY \# 0 ; Hex empty rdata +@ KEY 65536 0 0 AA== ; Type overflow +@ KEY 0 256 0 AA== ; Key tag overflow +@ KEY 0 0 256 AA== ; Algorithm overflow +@ KEY 0 0 0 A ; Continuous block length must be multiple of 4 +@ KEY 0 0 0 AB ; Continuous block length must be multiple of 4 +@ KEY 0 0 0 ABC ; Continuous block length must be multiple of 4 +@ KEY 0 0 0 AA == ; Continuous block length must be multiple of 4 +@ KEY 0 0 0 A=== ; Bad padding +@ KEY 0 0 0 = ; Bad padding +@ KEY 0 0 0 == ; Bad padding +@ KEY 0 0 0 === ; Bad padding +@ KEY 0 0 0 ==== ; Bad padding +@ KEY 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/30_KEY.out b/tests/libzscanner/data/30_KEY.out new file mode 100644 index 0000000..1ec998b --- /dev/null +++ b/tests/libzscanner/data/30_KEY.out @@ -0,0 +1,86 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=00000000666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=00000000666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=00000000666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=00000000666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0019 +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/31_DNSKEY.in b/tests/libzscanner/data/31_DNSKEY.in new file mode 100644 index 0000000..871de97 --- /dev/null +++ b/tests/libzscanner/data/31_DNSKEY.in @@ -0,0 +1,32 @@ +$ORIGIN . +$TTL 1 + +; OK +@ DNSKEY 0 0 0 AA== ; The simplest variant +@ DNSKEY 65535 255 255 AA== ; Maximal numbers +@ DNSKEY 0 0 RSAMD5 AA== ; Algorithm mnemonic +@ DNSKEY 0 0 0 Zm8= ; One char padding +@ DNSKEY 0 0 0 Zm9v ; Without padding +@ DNSKEY 0 0 0 Zm9vYg== ; Two base64 blocks +@ DNSKEY 0 0 0 Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE48 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE48 0 0 0 AA== ; TYPE +@ dnskey 0 0 0 AA== ; Type in lower-case + +; KO +@ DNSKEY +@ DNSKEY ; Empty rdata +@ DNSKEY \# 0 ; Hex empty rdata +@ DNSKEY 65536 0 0 AA== ; Type overflow +@ DNSKEY 0 256 0 AA== ; Key tag overflow +@ DNSKEY 0 0 256 AA== ; Algorithm overflow +@ DNSKEY 0 0 0 A ; Continuous block length must be multiple of 4 +@ DNSKEY 0 0 0 AB ; Continuous block length must be multiple of 4 +@ DNSKEY 0 0 0 ABC ; Continuous block length must be multiple of 4 +@ DNSKEY 0 0 0 AA == ; Continuous block length must be multiple of 4 +@ DNSKEY 0 0 0 A=== ; Bad padding +@ DNSKEY 0 0 0 = ; Bad padding +@ DNSKEY 0 0 0 == ; Bad padding +@ DNSKEY 0 0 0 === ; Bad padding +@ DNSKEY 0 0 0 ==== ; Bad padding +@ DNSKEY 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/31_DNSKEY.out b/tests/libzscanner/data/31_DNSKEY.out new file mode 100644 index 0000000..fa034c5 --- /dev/null +++ b/tests/libzscanner/data/31_DNSKEY.out @@ -0,0 +1,92 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=0000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=00000000666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=00000000666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=00000000666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=00000000666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0030 +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/32_APL.in b/tests/libzscanner/data/32_APL.in new file mode 100644 index 0000000..ea9a747 --- /dev/null +++ b/tests/libzscanner/data/32_APL.in @@ -0,0 +1,30 @@ +$ORIGIN . +$TTL 1 + +; OK +@ APL ; The simplest variant - blank list +@ APL 1:0.0.0.0/0 ; Minimal ipv4 prefix length +@ APL 1:255.255.255.255/32 ; Maximal ipv4 prefix length +@ APL 1:255.255.255.255/30 ; Prefix length isn't multiple of 8 +@ APL 2:::/0 ; Minimal ipv6 address +@ APL 2:0::0/0 ; Minimal ipv6 prefix length +@ APL 2:0::0/128 ; Maximal ipv6 prefix length +@ APL 2:FFFF:FFFF:FFFF::/2 ; Trailing zeroes test +@ APL !1:0.0.0.0/0 ; Negation flag +@ APL 1:0.0.0.0/0 1:255.255.255.255/32 ; More APLs +@ TYPE42 \# 4 00010000 ; TYPE + Hexadecimal rdata +@ TYPE42 1:0.0.0.0/0 ; TYPE +@ APL \# 0 ; Zero length rdata +@ apl 1:0.0.0.0/0 ; Type in lower-case + +; KO +@ APL 0:0.0.0.0/32 ; Bad address family +@ APL x:0.0.0.0/32 ; Bad address family +@ APL !x:0.0.0.0/32 ; Bad address family +@ APL 2:0.0.0.0/32 ; Address family mismatch +@ APL 1:0::0/32 ; Address family mismatch +@ APL 1:0.0.0.0/33 ; Prefix length is too long +@ APL 2:0::0/129 ; Prefix length is too long +@ APL 2::/0 ; Bad ipv6 address +@ APL 2:0::0/x ; Bad prefix length +@ APL 1:0.0.0.0/ ; Missing prefix length diff --git a/tests/libzscanner/data/32_APL.out b/tests/libzscanner/data/32_APL.out new file mode 100644 index 0000000..50ec101 --- /dev/null +++ b/tests/libzscanner/data/32_APL.out @@ -0,0 +1,104 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA= +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00010000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00012004FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00011E04FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00020000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00020000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00028000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00020206FFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00010080 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=0001000000012004FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00010000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00010000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA= +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002A +RDATA=00010000 +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_IPV6 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_IPV6 +------ +WARNG=ZS_BAD_APL +------ +WARNG=ZS_BAD_APL +------ diff --git a/tests/libzscanner/data/33_DS.in b/tests/libzscanner/data/33_DS.in new file mode 100644 index 0000000..a5d805c --- /dev/null +++ b/tests/libzscanner/data/33_DS.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; OK +@ DS 0 0 0 00 ; The simplest variant +@ DS 65535 255 255 00 ; Maximal numbers +@ DS 0 RSAMD5 0 00 ; Algorithm mnemonic +@ DS 0 0 0 01 02 0304 ; Hex block with blank spaces between them +@ TYPE43 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE43 0 0 0 00 ; TYPE +@ ds 0 0 0 00 ; Type in lower-case + +; KO +@ DS +@ DS ; Empty rdata +@ DS \# 0 ; Hex empty rdata +@ DS 65536 0 0 00 ; Key tag overflow +@ DS 0 256 0 00 ; Algorithm overflow +@ DS 0 0 256 00 ; Digest type overflow +@ DS 0 0 0 0 ; Continuous block length must be multiple of 2 +@ DS 0 0 0 00 0 ; Continuous block length must be multiple of 2 +@ DS 0 0 0 XX ; Bad hex character +@ DS 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/33_DS.out b/tests/libzscanner/data/33_DS.out new file mode 100644 index 0000000..2257119 --- /dev/null +++ b/tests/libzscanner/data/33_DS.out @@ -0,0 +1,62 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000010000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000000001020304 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002B +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/34_SSHFP.in b/tests/libzscanner/data/34_SSHFP.in new file mode 100644 index 0000000..89c4de3 --- /dev/null +++ b/tests/libzscanner/data/34_SSHFP.in @@ -0,0 +1,21 @@ +$ORIGIN . +$TTL 1 + +; OK +@ SSHFP 0 0 00 ; The simplest variant +@ SSHFP 255 255 00 ; Maximal numbers +@ SSHFP 0 0 01 02 0304 ; Hex block with blank spaces between them +@ TYPE44 \# 3 000000 ; TYPE + Hexadecimal rdata +@ TYPE44 0 0 00 ; TYPE +@ sshfp 0 0 00 ; Type in lower-case + +; KO +@ SSHFP +@ SSHFP ; Empty rdata +@ SSHFP \# 0 ; Hex empty rdata +@ SSHFP 256 0 00 ; Algorithm overflow +@ SSHFP 0 256 00 ; Fp type overflow +@ SSHFP 0 0 0 ; Continuous block length must be multiple of 2 +@ SSHFP 0 0 00 0 ; Continuous block length must be multiple of 2 +@ SSHFP 0 0 XX ; Bad hex character +@ SSHFP 0 0 ; Missing item diff --git a/tests/libzscanner/data/34_SSHFP.out b/tests/libzscanner/data/34_SSHFP.out new file mode 100644 index 0000000..da8ce6d --- /dev/null +++ b/tests/libzscanner/data/34_SSHFP.out @@ -0,0 +1,54 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=FFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=000001020304 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002C +RDATA=000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/35_IPSECKEY.in b/tests/libzscanner/data/35_IPSECKEY.in new file mode 100644 index 0000000..dc56bd7 --- /dev/null +++ b/tests/libzscanner/data/35_IPSECKEY.in @@ -0,0 +1,29 @@ +$ORIGIN . +$TTL 1 + +; OK +@ IPSECKEY 0 0 0 . ; The simplest variant - no gw, no key +@ IPSECKEY 255 3 255 . AA== ; Maximal numbers +@ IPSECKEY 0 1 0 0.0.0.0 ; IPv4 address +@ IPSECKEY 0 2 0 :: ; IPv6 address +@ IPSECKEY 0 3 0 \0320\ \\\"\.\@\*.tld. ; Special chars in domain name +@ IPSECKEY 0 0 1 . Zm8= ; One char padding +@ IPSECKEY 0 0 1 . Zm9v ; Without padding +@ IPSECKEY 0 0 1 . Zm9vYg== ; Two base64 blocks +@ IPSECKEY 0 0 1 . Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE45 \# 3 000000 ; TYPE + Hexadecimal rdata +@ TYPE45 0 0 1 . AA== ; TYPE +@ ipseckey 0 0 1 . AA== ; Type in lower-case + +; KO +@ IPSECKEY +@ IPSECKEY ; Empty rdata +@ IPSECKEY \# 0 ; Hex empty rdata +@ IPSECKEY 256 0 0 . ; Precedence overflow +@ IPSECKEY 0 4 0 . ; Unknown gateway +@ IPSECKEY 0 0 256 . AA== ; Algorithm overflow +@ IPSECKEY 0 0 0 . AA== ; If alg is 0 then key shouldn't be given +@ IPSECKEY 0 0 0 a% ; Bad domain name char +@ IPSECKEY 0 0 1 . A ; Continuous block length must be multiple of 4 +@ IPSECKEY 0 0 1 . = ; Bad padding +@ IPSECKEY 0 0 ; Missing item diff --git a/tests/libzscanner/data/35_IPSECKEY.out b/tests/libzscanner/data/35_IPSECKEY.out new file mode 100644 index 0000000..718ce22 --- /dev/null +++ b/tests/libzscanner/data/35_IPSECKEY.out @@ -0,0 +1,94 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=FF03FF0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=00010000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=00020000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000300082030205C222E402A03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000001666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000001666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000001666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000001666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=00000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002D +RDATA=00000100 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_GATEWAY +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_GATEWAY_KEY +------ +WARNG=ZS_BAD_GATEWAY +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_GATEWAY_KEY +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/36_RRSIG.in b/tests/libzscanner/data/36_RRSIG.in new file mode 100644 index 0000000..cb873fc --- /dev/null +++ b/tests/libzscanner/data/36_RRSIG.in @@ -0,0 +1,46 @@ +$ORIGIN . +$TTL 1 + +; OK +@ RRSIG TYPE0 0 0 0 0 0 0 . AA== ; The simplest variant +@ RRSIG A 2 3 4 5 6 7 \008. CQ== ; Human visual test - block numbering +@ RRSIG TYPE65535 255 255 4294967295 4294967295 4294967295 65535 . AA== ; Maximal numbers +@ RRSIG TYPE0 RSAMD5 0 0 0 0 0 . AA== ; Algorithm mnemonic +@ RRSIG A 0 0 0 19700101000000 0 0 . AA== ; Minimal date format +@ RRSIG A 0 0 0 0 21051231235959 0 . AA== ; Maximal date format (zscanner original limit) +@ RRSIG A 0 0 0 0 22251231235959 0 . AA== ; Maximal date format (zscanner limit) +@ RRSIG TYPE0 0 0 0 0 0 0 \0320\ \\\"\.\@\*.tld. AA== ; Special chars in domain name +@ RRSIG A 0 0 0 0 0 0 . Zm8= ; One char padding +@ RRSIG A 0 0 0 0 0 0 . Zm9v ; Without padding +@ RRSIG A 0 0 0 0 0 0 . Zm9vYg== ; Two base64 blocks +@ RRSIG A 0 0 0 0 0 0 . Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE46 \# 20 000100000000000000000000000000000000 00 00 ; TYPE + Hexadecimal rdata +@ TYPE46 A 0 0 0 0 0 0 . AA== ; TYPE +@ rrsig A 0 0 0 0 0 0 . AA== ; Type in lower-case + +; KO +@ RRSIG +@ RRSIG ; Empty rdata +@ RRSIG \# 0 ; Hex empty rdata +@ RRSIG X 0 0 0 0 0 0 . AA== ; Unknown type +@ RRSIG TYPE65536 0 0 0 0 0 0 . AA== ; Type overflow +@ RRSIG A 256 0 0 0 0 0 . AA== ; Algorithm overflow +@ RRSIG A 0 256 0 0 0 0 . AA== ; Labels overflow +@ RRSIG A 0 0 4294967296 0 0 0 . AA== ; TTL overflow +@ RRSIG A 0 0 0 9294967296 0 0 . AA== ; Sig. exp. overflow +@ RRSIG A 0 0 0 0 4294967296 0 . AA== ; Sig. inc. overflow +@ RRSIG A 0 0 0 0 0 65536 . AA== ; Key tag overflow +@ RRSIG A 0 0 0 0 22260101000000 0 . AA== ; Date overflow +@ RRSIG A 0 0 0 0 2226010100000x 0 . AA== ; Bad timestamp char +@ RRSIG A 0 0 0 0 222601010000000 0 . AA== ; Bad timestamp length +@ RRSIG A 0 0 0 0 0 0 a% AA== ; Bad domain char +@ RRSIG A 0 0 0 0 0 0 . A ; Continuous block length must be multiple of 4 +@ RRSIG A 0 0 0 0 0 0 . AB ; Continuous block length must be multiple of 4 +@ RRSIG A 0 0 0 0 0 0 . ABC ; Continuous block length must be multiple of 4 +@ RRSIG A 0 0 0 0 0 0 . AA == ; Continuous block length must be multiple of 4 +@ RRSIG A 0 0 0 0 0 0 . A=== ; Bad padding +@ RRSIG A 0 0 0 0 0 0 . = ; Bad padding +@ RRSIG A 0 0 0 0 0 0 . == ; Bad padding +@ RRSIG A 0 0 0 0 0 0 . === ; Bad padding +@ RRSIG A 0 0 0 0 0 0 . ==== ; Bad padding +@ RRSIG A 0 0 0 0 0 0 . ; Missing item diff --git a/tests/libzscanner/data/36_RRSIG.out b/tests/libzscanner/data/36_RRSIG.out new file mode 100644 index 0000000..dff1471 --- /dev/null +++ b/tests/libzscanner/data/36_RRSIG.out @@ -0,0 +1,140 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0000000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=00010203000000040000000500000006000701080009 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0000010000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0001000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=000100000000000000000000FFCEDD7F00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=000100000000000000000000E1853CFF00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=000000000000000000000000000000000000082030205C222E402A03746C640000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=00010000000000000000000000000000000000666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=00010000000000000000000000000000000000666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=00010000000000000000000000000000000000666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=00010000000000000000000000000000000000666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0001000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0001000000000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002E +RDATA=0001000000000000000000000000000000000000 +------ +WARNG=ZS_UNSUPPORTED_TYPE +------ +WARNG=ZS_UNSUPPORTED_TYPE +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_UNSUPPORTED_TYPE +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_DATE +------ +WARNG=ZS_BAD_TIMESTAMP_CHAR +------ +WARNG=ZS_BAD_TIMESTAMP_LENGTH +------ +WARNG=ZS_BAD_DNAME_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/37_NSEC.in b/tests/libzscanner/data/37_NSEC.in new file mode 100644 index 0000000..1efa4ea --- /dev/null +++ b/tests/libzscanner/data/37_NSEC.in @@ -0,0 +1,20 @@ +$ORIGIN . +$TTL 1 + +; OK +@ NSEC . ; The simplest variant - without bitmap +@ NSEC \0320\ \\\"\.\@\*.tld. ; Special chars in domain name +@ NSEC . TYPE0 ; Minimal type number +@ NSEC . TYPE65535 ; Maximal type number +@ NSEC . TYPE0 A NS ; First bitmap window +@ NSEC . TYPE0 TYPE256 TYPE512 TYPE32768 ; First, second, third and 128. bitmap window +@ TYPE47 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE47 . ; TYPE +@ nsec . ; Type in lower-case + +; KO +@ NSEC +@ NSEC ; Empty rdata +@ NSEC \# 0 ; Hex empty rdata +@ NSEC . TYPE65536 ; Type number overflow +@ NSEC . X ; Unknown type diff --git a/tests/libzscanner/data/37_NSEC.out b/tests/libzscanner/data/37_NSEC.out new file mode 100644 index 0000000..7a62def --- /dev/null +++ b/tests/libzscanner/data/37_NSEC.out @@ -0,0 +1,64 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=082030205C222E402A03746C6400 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00000180 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00FF200000000000000000000000000000000000000000000000000000000000000001 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=000001E0 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00000180010180020180800180 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=002F +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_BITMAP +------ diff --git a/tests/libzscanner/data/38_DHCID.in b/tests/libzscanner/data/38_DHCID.in new file mode 100644 index 0000000..4c0642a --- /dev/null +++ b/tests/libzscanner/data/38_DHCID.in @@ -0,0 +1,26 @@ +$ORIGIN . +$TTL 1 + +; OK +@ DHCID AA== ; The simplest variant +@ DHCID Zm8= ; One char padding +@ DHCID Zm9v ; Without padding +@ DHCID Zm9vYg== ; Two base64 blocks +@ DHCID Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE49 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE49 AA== ; TYPE +@ dhcid AA== ; Type in lower-case + +; KO +@ DHCID +@ DHCID ; Empty rdata +@ DHCID \# 0 ; Hex empty rdata +@ DHCID A ; Continuous block length must be multiple of 4 +@ DHCID AB ; Continuous block length must be multiple of 4 +@ DHCID ABC ; Continuous block length must be multiple of 4 +@ DHCID AA == ; Continuous block length must be multiple of 4 +@ DHCID A=== ; Bad padding +@ DHCID = ; Bad padding +@ DHCID == ; Bad padding +@ DHCID === ; Bad padding +@ DHCID ==== ; Bad padding diff --git a/tests/libzscanner/data/38_DHCID.out b/tests/libzscanner/data/38_DHCID.out new file mode 100644 index 0000000..8dc8ec9 --- /dev/null +++ b/tests/libzscanner/data/38_DHCID.out @@ -0,0 +1,72 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0031 +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/39_NSEC3.in b/tests/libzscanner/data/39_NSEC3.in new file mode 100644 index 0000000..cadbfa9 --- /dev/null +++ b/tests/libzscanner/data/39_NSEC3.in @@ -0,0 +1,46 @@ +$ORIGIN . +$TTL 1 + +; OK +@ NSEC3 0 0 0 - 00====== ; The simplest variant - without bitmap +@ NSEC3 255 255 65535 - 00====== ; Maximal numbers +@ NSEC3 0 0 0 00FF 00====== ; Hex string +@ NSEC3 0 0 0 - 00====== ; Eight char padding +@ NSEC3 0 0 0 - CPNG==== ; Four char padding +@ NSEC3 0 0 0 - CPNMU=== ; Three char padding +@ NSEC3 0 0 0 - CPNMUOG= ; One char padding +@ NSEC3 0 0 0 - CPNMUOJ1 ; Without padding +@ NSEC3 0 0 0 - CPNMUOJ1E8====== ; Two base32hex blocks +@ NSEC3 0 0 0 - 00====== TYPE0 ; Minimal type number +@ NSEC3 0 0 0 - 00====== TYPE65535 ; Maximal type number +@ NSEC3 0 0 0 - 00====== TYPE0 A NS ; First bitmap window +@ NSEC3 0 0 0 - 00====== TYPE0 TYPE256 TYPE512 TYPE32768 ; First, second, third and 128. bitmap window +@ TYPE50 \# 7 00000000000100 ; TYPE + Hexadecimal rdata +@ TYPE50 0 0 0 - 00====== ; TYPE +@ nsec3 0 0 0 - 00====== ; Type in lower-case + +; KO +@ NSEC3 +@ NSEC3 ; Empty rdata +@ NSEC3 \# 0 ; Hex empty rdata +@ NSEC3 256 0 0 - 00====== ; Algorithm overflow +@ NSEC3 0 256 0 - 00====== ; Flags overflow +@ NSEC3 0 0 65536 - 00====== ; Iterations overflow +@ NSEC3 0 0 0 0 00====== ; Hex block must be multiple of 2 +@ NSEC3 0 0 0 0X 00====== ; Bad hex char +@ NSEC3 0 0 0 00 FF 00====== ; Hex string with blank space inside +@ NSEC3 0 0 0 - 1 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 12 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 123 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 1234 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 12345 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 123456 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 1234567 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - 123456 78 ; Continuous block length must be multiple of 8 +@ NSEC3 0 0 0 - ======== ; Bad padding +@ NSEC3 0 0 0 - 1======= ; Bad padding +@ NSEC3 0 0 0 - 123===== ; Bad padding +@ NSEC3 0 0 0 - 123456== ; Bad padding +@ NSEC3 0 0 0 - CPNMUOJ1 E8====== ; Two base32hex blocks with blank space between them +@ NSEC3 0 0 0 - 00====== TYPE65536 ; Type number overflow +@ NSEC3 0 0 0 - 00====== X ; Unknown type diff --git a/tests/libzscanner/data/39_NSEC3.out b/tests/libzscanner/data/39_NSEC3.out new file mode 100644 index 0000000..1aaec4f --- /dev/null +++ b/tests/libzscanner/data/39_NSEC3.out @@ -0,0 +1,144 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=FFFFFFFF000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000200FF0100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000002666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000003666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000004666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000005666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000006666F6F626172 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100000180 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100FF200000000000000000000000000000000000000000000000000000000000000001 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=000000000001000001E0 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100000180010180020180800180 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0032 +RDATA=00000000000100 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BASE32HEX_CHAR +------ +WARNG=ZS_BAD_BITMAP +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_BITMAP +------ diff --git a/tests/libzscanner/data/40_NSEC3PARAM.in b/tests/libzscanner/data/40_NSEC3PARAM.in new file mode 100644 index 0000000..694e3f7 --- /dev/null +++ b/tests/libzscanner/data/40_NSEC3PARAM.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; OK +@ NSEC3PARAM 0 0 0 - ; The simplest variant +@ NSEC3PARAM 255 255 65535 - ; Maximal numbers +@ NSEC3PARAM 0 0 0 0102FF ; Hex string +@ TYPE51 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE51 0 0 0 - ; TYPE +@ nsec3param 0 0 0 - ; Type in lower-case + +; KO +@ NSEC3PARAM +@ NSEC3PARAM ; Empty rdata +@ NSEC3PARAM \# 0 ; Hex empty rdata +@ NSEC3PARAM 256 0 0 00 ; Algorithm overflow +@ NSEC3PARAM 0 256 0 00 ; Flags overflow +@ NSEC3PARAM 0 0 65536 00 ; Iterations overflow +@ NSEC3PARAM 0 0 0 0 ; Hex block length must be multiple of 2 +@ NSEC3PARAM 0 0 0 0x ; Bad hex char +@ NSEC3PARAM 0 0 0 00 00 ; Hex block must not contain blank spaces +@ NSEC3PARAM 0 0 0 00 x ; Unexpected item +@ NSEC3PARAM 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/40_NSEC3PARAM.out b/tests/libzscanner/data/40_NSEC3PARAM.out new file mode 100644 index 0000000..83b9bb1 --- /dev/null +++ b/tests/libzscanner/data/40_NSEC3PARAM.out @@ -0,0 +1,58 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=00000000030102FF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0033 +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_REST +------ +WARNG=ZS_BAD_REST +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/41_TLSA.in b/tests/libzscanner/data/41_TLSA.in new file mode 100644 index 0000000..927498e --- /dev/null +++ b/tests/libzscanner/data/41_TLSA.in @@ -0,0 +1,21 @@ +$ORIGIN . +$TTL 1 + +; OK +@ TLSA 0 0 0 00 ; The simplest variant +@ TLSA 255 255 255 00 ; Maximal numbers +@ TLSA 0 0 0 0102 00 FF ; Hex string with blank spaces inside +@ TYPE52 \# 4 00000000 ; TYPE + Hexadecimal rdata +@ TYPE52 0 0 0 00 ; TYPE +@ tlsa 0 0 0 00 ; Type in lower-case + +; KO +@ TLSA +@ TLSA ; Empty rdata +@ TLSA \# 0 ; Hex empty rdata +@ TLSA 256 0 0 00 ; Algorithm overflow +@ TLSA 0 256 0 00 ; Flags overflow +@ TLSA 0 0 256 00 ; Iterations overflow +@ TLSA 0 0 0 0 ; Hex block length must be multiple of 2 +@ TLSA 0 0 0 0x ; Bad hex char +@ TLSA 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/41_TLSA.out b/tests/libzscanner/data/41_TLSA.out new file mode 100644 index 0000000..6f5b6a1 --- /dev/null +++ b/tests/libzscanner/data/41_TLSA.out @@ -0,0 +1,54 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=FFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=000000010200FF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0034 +RDATA=00000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/42_LOC.in b/tests/libzscanner/data/42_LOC.in new file mode 100644 index 0000000..9eaae1d --- /dev/null +++ b/tests/libzscanner/data/42_LOC.in @@ -0,0 +1,64 @@ +$ORIGIN . +$TTL 1 + +; OK +@ LOC 1 N 1 E 0 ; The simplest case +@ LOC 0 1 N 1 E 0 ; Combination of parameters +@ LOC 0 0 1 N 1 E 0 ; Combination of parameters +@ LOC 1 N 0 1 E 0 ; Combination of parameters +@ LOC 1 N 0 0 1 E 0 ; Combination of parameters +@ LOC 1 N 0 0 1 E 0m ; Combination of parameters +@ LOC 1 N 1 E 0 1 ; Combination of parameters +@ LOC 1 N 1 E 0 1m ; Combination of parameters +@ LOC 1 N 1 E 0 0 1 ; Combination of parameters +@ LOC 1 N 1 E 0 0 1m ; Combination of parameters +@ LOC 1 N 1 E 0 0 0 1 ; Combination of parameters +@ LOC 1 N 1 E 0 0 0 1m ; Combination of parameters +@ LOC 0 0 0 N 0 0 0 E -100000.00 0 0 0 ; Minimal values +@ LOC 90 59 59.999 S 180 59 59.999 W 42849672.95m 90000000.00m 90000000.00m 90000000.00m ; Maximal values +@ LOC 0 S 0 0 0.001 W 0 ; Float dd.ddd test +@ LOC 0 S 0 0 0.01 W 0 ; Float dd.ddd test +@ LOC 0 S 0 0 0.1 W 0 ; Float dd.ddd test +@ LOC 0 S 0 0 1.0 W 0 ; Float dd.ddd test +@ LOC 0 S 0 0 10 W 0 ; Float dd.ddd test +@ LOC 0 S 0 W 0 0.01 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 0.10 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 1.0 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 10 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 100 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 1000 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 10000 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 100000 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 1000000 ; Number to [mantisa,exponent] test +@ LOC 0 S 0 W 0 10000000 ; Number to [mantisa,exponent] test +@ LOC \# 16 00 00 00 00 00000000 00000000 00000000 ; Hexadecimal rdata +@ TYPE29 \# 16 00 00 00 00 00000000 00000000 00000000 ; TYPE + Hexadecimal rdata +@ TYPE29 0 N 0 E 0 ; TYPE +@ loc 0 N 0 E 0 ; Type in lower-case + +; KO +@ LOC +@ LOC ; Empty rdata +@ LOC \# 0 ; Hex empty rdata +@ LOC 91 0 0 N 0 0 0 E 0 0 0 0 ; Degree overflow +@ LOC 0 60 0 N 0 0 0 E 0 0 0 0 ; Minute overflow +@ LOC 0 0 60 0 N 0 0 0 E 0 0 0 0 ; Second overflow +@ LOC 0 0 0 N 181 0 0 E 0 0 0 0 ; Degree overflow +@ LOC 0 0 0 N 0 60 0 E 0 0 0 0 ; Minute overflow +@ LOC 0 0 0 N 0 0 60 E 0 0 0 0 ; Second overflow +@ LOC 0 0 0 N 0 0 0 E 42849672.96 0 0 0 ; Altitude overflow +@ LOC 0 0 0 N 0 0 0 E 42849673 0 0 0 ; Altitude overflow +@ LOC 0 0 0 N 0 0 0 E -100000.01 0 0 0 ; Altitude underflow +@ LOC 0 0 0 N 0 0 0 E -100001 0 0 0 ; Altitude underflow +@ LOC 0 0 0 N 0 0 0 E 0 90000000.01 0 0 ; Size overflow +@ LOC 0 0 0 N 0 0 0 E 0 90000001 0 0 ; Size overflow +@ LOC 0 0 0 N 0 0 0 E 0 0 90000000.01 0 ; HP overflow +@ LOC 0 0 0 N 0 0 0 E 0 0 90000001 0 ; HP overflow +@ LOC 0 0 0 N 0 0 0 E 0 0 0 90000000.01 ; VP overflow +@ LOC 0 0 0 N 0 0 0 E 0 0 0 90000001 ; VP overflow +@ LOC 1 1 E 0 ; Missing N or S +@ LOC 1 x 1 E 0 ; Bad letter +@ LOC 1 N 1 0 ; Missing E or W +@ LOC 1 N 1 x 0 ; Bad letter +@ LOC 1 N 1 E ; Missing altitude +@ LOC 0 0 0 N 0 0 0 E 0 0 0 0 x ; Unexpected item diff --git a/tests/libzscanner/data/42_LOC.out b/tests/libzscanner/data/42_LOC.out new file mode 100644 index 0000000..730cc3b --- /dev/null +++ b/tests/libzscanner/data/42_LOC.out @@ -0,0 +1,248 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138000EA608036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800003E88036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE808000EA6000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE80800003E800989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE80800003E800989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=001216138036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=000012138036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=000012138036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=000000128036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=000000128036EE808036EE8000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00000000800000008000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=009999996C79388159295F81FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000007FFFFFFF00989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000007FFFFFF600989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000007FFFFF9C00989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000007FFFFC1800989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000007FFFD8F000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00101613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00111613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00131613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00141613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00151613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00161613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00171613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00181613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00191613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00000000000000000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000008000000000989680 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=001D +RDATA=00121613800000008000000000989680 +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ +WARNG=ZS_BAD_LOC_DATA +------ diff --git a/tests/libzscanner/data/43_EUI48.in b/tests/libzscanner/data/43_EUI48.in new file mode 100644 index 0000000..a2abbec --- /dev/null +++ b/tests/libzscanner/data/43_EUI48.in @@ -0,0 +1,22 @@ +$ORIGIN . +$TTL 1 + +; OK +@ EUI48 00-00-00-00-00-00 ; The simplest case +@ EUI48 FF-FF-FF-FF-FF-FF ; The maximal case +@ EUI48 aa-bb-cc-dd-ee-ff ; Lower-case +@ EUI48 \# 6 000000000000 ; Hexadecimal rdata +@ TYPE108 \# 6 000000000000 ; TYPE + Hexadecimal rdata +@ TYPE108 00-00-00-00-00-00 ; TYPE +@ eui48 00-00-00-00-00-00 ; Type in lower-case + +; KO +@ EUI48 +@ EUI48 ; Empty rdata +@ EUI48 \# 0 ; Hex empty rdata +@ EUI48 00-00-00-00-00 ; Too few hex pairs +@ EUI48 00-00-00-00-00-00-00 ; Too many hex pairs +@ EUI48 00-00-00-00-00-0 ; Missing char in a hex pair +@ EUI48 00:00-00-00-00-00 ; Bad separator +@ EUI48 00-00-00-x0-00-00 ; Bad character +@ EUI48 00-00-00-00-00-00 x ; Unexpected item diff --git a/tests/libzscanner/data/43_EUI48.out b/tests/libzscanner/data/43_EUI48.out new file mode 100644 index 0000000..a54a314 --- /dev/null +++ b/tests/libzscanner/data/43_EUI48.out @@ -0,0 +1,60 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=FFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=AABBCCDDEEFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006C +RDATA=000000000000 +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_EUI_LENGTH +------ +WARNG=ZS_BAD_EUI_LENGTH +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_CHAR_DASH +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/44_EUI64.in b/tests/libzscanner/data/44_EUI64.in new file mode 100644 index 0000000..10f6346 --- /dev/null +++ b/tests/libzscanner/data/44_EUI64.in @@ -0,0 +1,22 @@ +$ORIGIN . +$TTL 1 + +; OK +@ EUI64 00-00-00-00-00-00-00-00 ; The simplest case +@ EUI64 FF-FF-FF-FF-FF-FF-FF-FF ; The maximal case +@ EUI64 aa-bb-cc-dd-ee-ff-01-02 ; Lower-case +@ EUI64 \# 8 0000000000000000 ; Hexadecimal rdata +@ TYPE109 \# 8 0000000000000000 ; TYPE + Hexadecimal rdata +@ TYPE109 00-00-00-00-00-00-00-00 ; TYPE +@ eui64 00-00-00-00-00-00-00-00 ; Type in lower-case + +; KO +@ EUI64 +@ EUI64 ; Empty rdata +@ EUI64 \# 0 ; Hex empty rdata +@ EUI64 00-00-00-00-00-00-00 ; Too few hex pairs +@ EUI64 00-00-00-00-00-00-00-00-00 ; Too many hex pairs +@ EUI64 00-00-00-00-00-00-00-0 ; Missing char in a hex pair +@ EUI64 00:00-00-00-00-00-00-00 ; Bad separator +@ EUI64 00-00-00-x0-00-00-00-00 ; Bad character +@ EUI64 00-00-00-00-00-00-00-00 x ; Unexpected item diff --git a/tests/libzscanner/data/44_EUI64.out b/tests/libzscanner/data/44_EUI64.out new file mode 100644 index 0000000..4cce5f5 --- /dev/null +++ b/tests/libzscanner/data/44_EUI64.out @@ -0,0 +1,60 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=FFFFFFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=AABBCCDDEEFF0102 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=0000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006D +RDATA=0000000000000000 +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_EUI_LENGTH +------ +WARNG=ZS_BAD_EUI_LENGTH +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_CHAR_DASH +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/45_NID.in b/tests/libzscanner/data/45_NID.in new file mode 100644 index 0000000..a85f9c3 --- /dev/null +++ b/tests/libzscanner/data/45_NID.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The NID is the same as the L64, so there are the differences and basics only. + +; OK +@ NID 0 0000:0000:0000:0000 ; The simplest case +@ NID \# 10 00000000000000000000 ; Hexadecimal rdata +@ TYPE104 \# 10 00000000000000000000 ; TYPE + Hexadecimal rdata +@ TYPE104 0 0000:0000:0000:0000 ; TYPE +@ nid 0 0000:0000:0000:0000 ; Type in lower-case + +; KO +@ NID diff --git a/tests/libzscanner/data/45_NID.out b/tests/libzscanner/data/45_NID.out new file mode 100644 index 0000000..a2bfb4c --- /dev/null +++ b/tests/libzscanner/data/45_NID.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0068 +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0068 +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0068 +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0068 +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0068 +RDATA=00000000000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/46_L32.in b/tests/libzscanner/data/46_L32.in new file mode 100644 index 0000000..866e953 --- /dev/null +++ b/tests/libzscanner/data/46_L32.in @@ -0,0 +1,21 @@ +$ORIGIN . +$TTL 1 + +; OK +@ L32 0 0.0.0.0 ; The simplest case +@ L32 65535 255.255.255.255 ; The maximal case +@ L32 \# 6 000000000000 ; Hexadecimal rdata +@ TYPE105 \# 6 000000000000 ; TYPE + Hexadecimal rdata +@ TYPE105 0 0.0.0.0 ; TYPE +@ l32 0 0.0.0.0 ; Type in lower-case + +; KO +@ L32 +@ L32 ; Empty rdata +@ L32 \# 0 ; Hex empty rdata +@ L32 65536 0.0.0.0 ; Too big preference +@ L32 0 0.0.0.256 ; 8-bit overflow +@ L32 0 0.0.0 ; Short address +@ L32 0 0.0.0.0.0 ; Long address +@ L32 0 0.0.0.x ; Bad character +@ L32 0 0.0.0.0 x ; Unexpected item diff --git a/tests/libzscanner/data/46_L32.out b/tests/libzscanner/data/46_L32.out new file mode 100644 index 0000000..e9c77b5 --- /dev/null +++ b/tests/libzscanner/data/46_L32.out @@ -0,0 +1,54 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=FFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0069 +RDATA=000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/47_L64.in b/tests/libzscanner/data/47_L64.in new file mode 100644 index 0000000..b4aabf3 --- /dev/null +++ b/tests/libzscanner/data/47_L64.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; OK +@ L64 0 0000:0000:0000:0000 ; The simplest case +@ L64 65535 FFFF:FFFF:FFFF:FFFF ; The maximal case +@ L64 0 abcd:ef00:0000:0000 ; Lower-case +@ L64 \# 10 00000000000000000000 ; Hexadecimal rdata +@ TYPE106 \# 10 00000000000000000000 ; TYPE + Hexadecimal rdata +@ TYPE106 0 0000:0000:0000:0000 ; TYPE +@ l64 0 0000:0000:0000:0000 ; Type in lower-case + +; KO +@ L64 +@ L64 ; Empty rdata +@ L64 \# 0 ; Hex empty rdata +@ L64 65536 ; Too big preference +@ L64 0 0000:0000:0000 ; Missing label +@ L64 0 0000:0000:0000:0000:0000 ; Too many labels +@ L64 0 0000:0000:0000:000 ; Missing hex character +@ L64 0 0000:0000:0000-0000 ; Bad separator +@ L64 0 0000:0000:0000:x000 ; Bad hex character +@ L64 0 0000:0000:0000:0000 x ; Unexpected item diff --git a/tests/libzscanner/data/47_L64.out b/tests/libzscanner/data/47_L64.out new file mode 100644 index 0000000..106ee58 --- /dev/null +++ b/tests/libzscanner/data/47_L64.out @@ -0,0 +1,62 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=FFFFFFFFFFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=0000ABCDEF0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=00000000000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006A +RDATA=00000000000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_L64_LENGTH +------ +WARNG=ZS_BAD_L64_LENGTH +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_CHAR_COLON +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/48_LP.in b/tests/libzscanner/data/48_LP.in new file mode 100644 index 0000000..bc537d0 --- /dev/null +++ b/tests/libzscanner/data/48_LP.in @@ -0,0 +1,14 @@ +$ORIGIN . +$TTL 1 + +; The LP is the same as the MX, so there are the differences and basics only. + +; OK +@ LP 1 mail ; Relative dname +@ LP \# 3 0001 00 ; Hexadecimal rdata +@ TYPE107 \# 3 0001 00 ; TYPE + Hexadecimal rdata +@ TYPE107 1 @ ; TYPE +@ lp 1 @ ; Type in lower-case + +; KO +@ LP diff --git a/tests/libzscanner/data/48_LP.out b/tests/libzscanner/data/48_LP.out new file mode 100644 index 0000000..4961c7e --- /dev/null +++ b/tests/libzscanner/data/48_LP.out @@ -0,0 +1,32 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006B +RDATA=0001046D61696C00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006B +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006B +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006B +RDATA=000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=006B +RDATA=000100 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/49_CDS.in b/tests/libzscanner/data/49_CDS.in new file mode 100644 index 0000000..7b6c347 --- /dev/null +++ b/tests/libzscanner/data/49_CDS.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; OK +@ CDS 0 0 0 00 ; The simplest variant +@ CDS 65535 255 255 00 ; Maximal numbers +@ CDS 0 RSAMD5 0 00 ; Algorithm mnemonic +@ CDS 0 0 0 01 02 0304 ; Hex block with blank spaces between them +@ TYPE59 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE59 0 0 0 00 ; TYPE +@ cds 0 0 0 00 ; Type in lower-case + +; KO +@ CDS +@ CDS ; Empty rdata +@ CDS \# 0 ; Hex empty rdata +@ CDS 65536 0 0 00 ; Key tag overflow +@ CDS 0 256 0 00 ; Algorithm overflow +@ CDS 0 0 256 00 ; Digest type overflow +@ CDS 0 0 0 0 ; Continuous block length must be multiple of 2 +@ CDS 0 0 0 00 0 ; Continuous block length must be multiple of 2 +@ CDS 0 0 0 XX ; Bad hex character +@ CDS 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/49_CDS.out b/tests/libzscanner/data/49_CDS.out new file mode 100644 index 0000000..de40722 --- /dev/null +++ b/tests/libzscanner/data/49_CDS.out @@ -0,0 +1,62 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000010000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000000001020304 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003B +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/50_CDNSKEY.in b/tests/libzscanner/data/50_CDNSKEY.in new file mode 100644 index 0000000..dc91462 --- /dev/null +++ b/tests/libzscanner/data/50_CDNSKEY.in @@ -0,0 +1,32 @@ +$ORIGIN . +$TTL 1 + +; OK +@ CDNSKEY 0 0 0 AA== ; The simplest variant +@ CDNSKEY 65535 255 255 AA== ; Maximal numbers +@ CDNSKEY 0 0 RSAMD5 AA== ; Algorithm mnemonic +@ CDNSKEY 0 0 0 Zm8= ; One char padding +@ CDNSKEY 0 0 0 Zm9v ; Without padding +@ CDNSKEY 0 0 0 Zm9vYg== ; Two base64 blocks +@ CDNSKEY 0 0 0 Zm9v YmE= ; Two base64 blocks with blank space between them +@ TYPE60 \# 5 0000000000 ; TYPE + Hexadecimal rdata +@ TYPE60 0 0 0 AA== ; TYPE +@ cdnskey 0 0 0 AA== ; Type in lower-case + +; KO +@ CDNSKEY +@ CDNSKEY ; Empty rdata +@ CDNSKEY \# 0 ; Hex empty rdata +@ CDNSKEY 65536 0 0 AA== ; Type overflow +@ CDNSKEY 0 256 0 AA== ; Key tag overflow +@ CDNSKEY 0 0 256 AA== ; Algorithm overflow +@ CDNSKEY 0 0 0 A ; Continuous block length must be multiple of 4 +@ CDNSKEY 0 0 0 AB ; Continuous block length must be multiple of 4 +@ CDNSKEY 0 0 0 ABC ; Continuous block length must be multiple of 4 +@ CDNSKEY 0 0 0 AA == ; Continuous block length must be multiple of 4 +@ CDNSKEY 0 0 0 A=== ; Bad padding +@ CDNSKEY 0 0 0 = ; Bad padding +@ CDNSKEY 0 0 0 == ; Bad padding +@ CDNSKEY 0 0 0 === ; Bad padding +@ CDNSKEY 0 0 0 ==== ; Bad padding +@ CDNSKEY 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/50_CDNSKEY.out b/tests/libzscanner/data/50_CDNSKEY.out new file mode 100644 index 0000000..3100313 --- /dev/null +++ b/tests/libzscanner/data/50_CDNSKEY.out @@ -0,0 +1,92 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=FFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=0000000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=00000000666F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=00000000666F6F +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=00000000666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=00000000666F6F6261 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=0000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003C +RDATA=0000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_BASE64_CHAR +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/51_URI.in b/tests/libzscanner/data/51_URI.in new file mode 100644 index 0000000..8d18f42 --- /dev/null +++ b/tests/libzscanner/data/51_URI.in @@ -0,0 +1,22 @@ +$ORIGIN . +$TTL 1 + +; OK +@ URI 0 0 a ; The simplest variant +@ URI 65535 65535 ftp://a ; Maximal priority and weight +@ URI 0 0 "ftp://a" ; Quoted target +@ URI 0 0 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 ; Target longer than 255 +@ TYPE256 \# 5 0000000061 ; TYPE + Hexadecimal rdata +@ TYPE256 0 0 a ; TYPE +@ uri 0 0 a ; Type in lower-case + +; OK extensions +@ URI 0 0 "" ; Empty target + +; KO +@ URI +@ URI ; Empty rdata +@ URI \# 0 ; Hex empty rdata +@ URI 65536 0 a ; Priority overflow +@ URI 0 65536 a ; Weight overflow +@ URI 0 0 a a ; Unexpected item diff --git a/tests/libzscanner/data/51_URI.out b/tests/libzscanner/data/51_URI.out new file mode 100644 index 0000000..9dcf933 --- /dev/null +++ b/tests/libzscanner/data/51_URI.out @@ -0,0 +1,60 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=0000000061 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=FFFFFFFF6674703A2F2F61 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=000000006674703A2F2F61 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=00000000303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=0000000061 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=0000000061 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=0000000061 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0100 +RDATA=00000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/52_CAA.in b/tests/libzscanner/data/52_CAA.in new file mode 100644 index 0000000..7043ce5 --- /dev/null +++ b/tests/libzscanner/data/52_CAA.in @@ -0,0 +1,23 @@ +$ORIGIN . +$TTL 1 + +; OK +@ CAA 0 a a ; The simplest variant +@ CAA 255 a a ; Maximal flags +@ CAA 0 a "a ; b" ; Quoted value +@ CAA 0 a 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789 ; Value longer than 255 +@ TYPE257 \# 4 00016161 ; TYPE + Hexadecimal rdata +@ TYPE257 0 a a ; TYPE +@ caa 0 a a ; Type in lower-case + +; OK fallbacks and extensions +@ CAA 0 "" a ; Empty tag +@ CAA 0 "a" a ; Quoted tag +@ CAA 0 abcdefghijklmnopqrstuvwxyz0123456789 a ; All allowed characters, longer than 15 + +; KO +@ CAA +@ CAA ; Empty rdata +@ CAA \# 0 ; Hex empty rdata +@ CAA 256 a a ; Flags overflow +@ CAA 0 a a a ; Unexpected item diff --git a/tests/libzscanner/data/52_CAA.out b/tests/libzscanner/data/52_CAA.out new file mode 100644 index 0000000..e5eefdf --- /dev/null +++ b/tests/libzscanner/data/52_CAA.out @@ -0,0 +1,70 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=FF016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161203B2062 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=000161303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=000061 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00016161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0101 +RDATA=00246162636465666768696A6B6C6D6E6F707172737475767778797A3031323334353637383961 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_REST +------ diff --git a/tests/libzscanner/data/53_SMIMEA.in b/tests/libzscanner/data/53_SMIMEA.in new file mode 100644 index 0000000..aec390f --- /dev/null +++ b/tests/libzscanner/data/53_SMIMEA.in @@ -0,0 +1,13 @@ +$ORIGIN . +$TTL 1 + +; SMIMEA is the same as TLSA, so there are differences and basics only. + +; OK +@ SMIMEA 0 0 0 00 ; The simplest variant +@ TYPE53 \# 4 00000000 ; TYPE + Hexadecimal rdata +@ TYPE53 0 0 0 00 ; TYPE +@ smimea 0 0 0 00 ; Type in lower-case + +; KO +@ SMIMEA diff --git a/tests/libzscanner/data/53_SMIMEA.out b/tests/libzscanner/data/53_SMIMEA.out new file mode 100644 index 0000000..c270a7d --- /dev/null +++ b/tests/libzscanner/data/53_SMIMEA.out @@ -0,0 +1,26 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0035 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0035 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0035 +RDATA=00000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0035 +RDATA=00000000 +------ +WARNG=ZS_BAD_NUMBER +------ diff --git a/tests/libzscanner/data/54_OPENPGPKEY.in b/tests/libzscanner/data/54_OPENPGPKEY.in new file mode 100644 index 0000000..a788a28 --- /dev/null +++ b/tests/libzscanner/data/54_OPENPGPKEY.in @@ -0,0 +1,13 @@ +$ORIGIN . +$TTL 1 + +; OPENPGPKEY is the same as DHCID, so there are differences and basics only. + +; OK +@ OPENPGPKEY AA== ; The simplest variant +@ TYPE61 \# 1 00 ; TYPE + Hexadecimal rdata +@ TYPE61 AA== ; TYPE +@ openpgpkey AA== ; Type in lower-case + +; KO +@ OPENPGPKEY diff --git a/tests/libzscanner/data/54_OPENPGPKEY.out b/tests/libzscanner/data/54_OPENPGPKEY.out new file mode 100644 index 0000000..8741e4e --- /dev/null +++ b/tests/libzscanner/data/54_OPENPGPKEY.out @@ -0,0 +1,26 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003D +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003D +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003D +RDATA=00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003D +RDATA=00 +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/55_CSYNC.in b/tests/libzscanner/data/55_CSYNC.in new file mode 100644 index 0000000..97dcfa2 --- /dev/null +++ b/tests/libzscanner/data/55_CSYNC.in @@ -0,0 +1,22 @@ +$ORIGIN . +$TTL 1 + +; OK +@ CSYNC 0 0 ; The simplest variant - without bitmap +@ CSYNC 4294967295 65535 ; Maximal numbers +@ CSYNC 0 0 TYPE0 ; Minimal type number +@ CSYNC 0 0 TYPE65535 ; Maximal type number +@ CSYNC 0 0 TYPE0 A NS ; First bitmap window +@ CSYNC 0 0 TYPE0 TYPE256 TYPE512 TYPE32768 ; First, second, third and 128. bitmap window +@ TYPE62 \# 6 000000000000 ; TYPE + Hexadecimal rdata +@ TYPE62 0 0 ; TYPE +@ csync 0 0 ; Type in lower-case + +; KO +@ CSYNC +@ CSYNC ; Empty rdata +@ CSYNC \# 0 ; Hex empty rdata +@ CSYNC 4294967296 0 ; Serial overflow +@ CSYNC 0 65536 ; Flags overflow +@ CSYNC 0 0 TYPE65536 ; Type number overflow +@ CSYNC 0 0 X ; Unknown type diff --git a/tests/libzscanner/data/55_CSYNC.out b/tests/libzscanner/data/55_CSYNC.out new file mode 100644 index 0000000..d762c2b --- /dev/null +++ b/tests/libzscanner/data/55_CSYNC.out @@ -0,0 +1,68 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003E +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003E +RDATA=FFFFFFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003E +RDATA=000000000000000180 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003E +RDATA=000000000000FF200000000000000000000000000000000000000000000000000000000000000001 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003E +RDATA=0000000000000001E0 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003E +RDATA=000000000000000180010180020180800180 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003E +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003E +RDATA=000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003E +RDATA=000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_BITMAP +------ diff --git a/tests/libzscanner/data/56_ZONEMD.in b/tests/libzscanner/data/56_ZONEMD.in new file mode 100644 index 0000000..2342350 --- /dev/null +++ b/tests/libzscanner/data/56_ZONEMD.in @@ -0,0 +1,21 @@ +$ORIGIN . +$TTL 1 + +; OK +@ ZONEMD 0 0 0 00 ; The simplest variant +@ ZONEMD 4294967295 255 255 00 ; Maximal numbers +@ ZONEMD 0 0 0 0102 00 FF ; Hex string with blank spaces inside +@ TYPE63 \# 7 00000000000000 ; TYPE + Hexadecimal rdata +@ TYPE63 0 0 0 00 ; TYPE +@ zonemd 0 0 0 00 ; Type in lower-case + +; KO +@ ZONEMD +@ ZONEMD ; Empty rdata +@ ZONEMD \# 0 ; Hex empty rdata +@ ZONEMD 4294967296 0 0 00 ; Serial overflow +@ ZONEMD 0 256 0 00 ; Type overflow +@ ZONEMD 0 0 256 00 ; Reserved overflow +@ ZONEMD 0 0 0 0 ; Hex block length must be multiple of 2 +@ ZONEMD 0 0 0 0x ; Bad hex char +@ ZONEMD 0 0 0 ; Missing item diff --git a/tests/libzscanner/data/56_ZONEMD.out b/tests/libzscanner/data/56_ZONEMD.out new file mode 100644 index 0000000..0f56c24 --- /dev/null +++ b/tests/libzscanner/data/56_ZONEMD.out @@ -0,0 +1,54 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003F +RDATA=00000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003F +RDATA=FFFFFFFFFFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003F +RDATA=000000000000010200FF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003F +RDATA=00000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003F +RDATA=00000000000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=003F +RDATA=00000000000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER32_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_NUMBER8_OVERFLOW +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_BAD_HEX_CHAR +------ diff --git a/tests/libzscanner/data/57_SVCB.in b/tests/libzscanner/data/57_SVCB.in new file mode 100644 index 0000000..c4ce534 --- /dev/null +++ b/tests/libzscanner/data/57_SVCB.in @@ -0,0 +1,102 @@ +$ORIGIN . +$TTL 1 + +; OK +@ SVCB 0 . +@ SVCB 0 @ ; Comment +@ SVCB 65535 . mandatory=alpn alpn=h2 +@ SVCB 1 . mandatory="alpn" alpn=h2 +@ SVCB 1 . alpn=h2 +@ SVCB 1 . alpn="abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\053" ; Text string of maximal length (255 chars) +@ SVCB 1 . alpn="part1,part2,part3\\,part4\\\\" +@ SVCB 1 . alpn=part1\,\p\a\r\t2\044part3\092,part4\092\\ +@ SVCB 1 . no-default-alpn +@ SVCB 1 . port=0 +@ SVCB 1 . port="65535" +@ SVCB 1 . ipv4hint=0.0.0.0 +@ SVCB 1 . ipv4hint="255.255.255.255" +@ SVCB 1 . ech=AA== +@ SVCB 1 . ech="Zm9vYg==" +@ SVCB 1 . ipv6hint=::1 +@ SVCB 1 . ipv6hint="::1" +@ SVCB 1 . key7 +@ SVCB 1 . key65535 +@ SVCB 1 . key65535=a +@ SVCB 1 . key65535="a" +@ SVCB 1 . key65535="a" key1000=b port=4 key7 mandatory=key7,port +@ TYPE64 \# 3 000000 +@ TYPE64 0 . +@ svcb 0 . + +; RFC OK examples +example.com. HTTPS 0 foo.example.com. +example.com. SVCB 1 . +example.com. SVCB 16 foo.example.com. port=53 +example.com. SVCB 1 foo.example.com. key667=hello +example.com. SVCB 1 foo.example.com. key667="hello\210qoo" +example.com. SVCB 1 foo.example.com. ( + ipv6hint="2001:db8::1,2001:db8::53:1" + ) +example.com. SVCB 1 example.com. ipv6hint="::ffff:198.51.100.100" +example.com. SVCB 16 foo.example.org. ( + alpn=h2,h3-19 mandatory=ipv4hint,alpn + ipv4hint=192.0.2.1 + ) +example.com. SVCB 16 foo.example.org. alpn="f\\\\oo\\,bar,h2" +example.com. SVCB 16 foo.example.org. alpn=f\\\092oo\092,bar,h2 + +; KO +@ SVCB +@ SVCB ; Empty rdata +@ SVCB \# 0 ; Hex empty rdata +@ SVCB 65536 . ; Priority overflow +@ SVCB 0 ; Missing item +@ SVCB 1 . bogus ; Unknown parameter +@ SVCB 1 . PORT=0 ; Capital letter in parameter name +@ SVCB 1 . mandatory +@ SVCB 1 . mandatory= +@ SVCB 1 . mandatory=a, +@ SVCB 1 . mandatory=a,,b +@ SVCB 1 . mandatory=mandatory +@ SVCB 1 . mandatory=bogus +@ SVCB 1 . alpn +@ SVCB 1 . alpn= +@ SVCB 1 . alpn=a, +@ SVCB 1 . alpn=a,,b +@ SVCB 1 . alpn="abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMN1234\0536" ; Text string overflow (256 chars) +@ SVCB 1 . no-default-alpn= +@ SVCB 1 . no-default-alpn=h1 +@ SVCB 1 . no-default-alpn="h1" +@ SVCB 1 . port +@ SVCB 1 . port= +@ SVCB 1 . port=65536 +@ SVCB 1 . port=1,2 +@ SVCB 1 . ipv4hint +@ SVCB 1 . ipv4hint= +@ SVCB 1 . ipv4hint=1.2.3 +@ SVCB 1 . ipv4hint=1.2.3.4, +@ SVCB 1 . ipv4hint=1.2.3.4,,2.3.4.5 +@ SVCB 1 . ech +@ SVCB 1 . ech= +@ SVCB 1 . ech=AA==,AA== +@ SVCB 1 . ech=W +@ SVCB 1 . ipv6hint +@ SVCB 1 . ipv6hint= +@ SVCB 1 . ipv6hint=::1,,::2 +@ SVCB 1 . ipv6hint=::W + +; RFC KO examples +example.com. SVCB 1 foo.example.com. ( + key123=abc key123=def + ) +example.com. SVCB 1 foo.example.com. mandatory +example.com. SVCB 1 foo.example.com. alpn +example.com. SVCB 1 foo.example.com. port +example.com. SVCB 1 foo.example.com. ipv4hint +example.com. SVCB 1 foo.example.com. ipv6hint +example.com. SVCB 1 foo.example.com. no-default-alpn=abc +example.com. SVCB 1 foo.example.com. mandatory=key123 +example.com. SVCB 1 foo.example.com. mandatory=mandatory +example.com. SVCB 1 foo.example.com. ( + mandatory=key123,key123 key123=abc + ) diff --git a/tests/libzscanner/data/57_SVCB.out b/tests/libzscanner/data/57_SVCB.out new file mode 100644 index 0000000..a799eb7 --- /dev/null +++ b/tests/libzscanner/data/57_SVCB.out @@ -0,0 +1,306 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=FFFF0000000002000100010003026832 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=00010000000002000100010003026832 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=00010000010003026832 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=00010000010100FF6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E6162636465666768696A6B6C6D6E6F707172737475767778797A313233343536373839304142434445464748494A4B4C4D4E3132333435 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000100000100190570617274310570617274320C70617274332C70617274345C +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000100000100190570617274310570617274320C70617274332C70617274345C +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=00010000020000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000100000300020000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=00010000030002FFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=0001000004000400000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=00010000040004FFFFFFFF +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=0001000005000100 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=00010000050004666F6F62 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=0001000006001000000000000000000000000000000001 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=0001000006001000000000000000000000000000000001 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=00010000070000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000100FFFF0000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000100FFFF000161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000100FFFF000161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=00010000000004000300070003000200040007000003E8000162FFFF000161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000000 +------ +OWNER=076578616D706C6503636F6D00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0041 +RDATA=000003666F6F076578616D706C6503636F6D00 +------ +OWNER=076578616D706C6503636F6D00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000100 +------ +OWNER=076578616D706C6503636F6D00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=001003666F6F076578616D706C6503636F6D00000300020035 +------ +OWNER=076578616D706C6503636F6D00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000103666F6F076578616D706C6503636F6D00029B000568656C6C6F +------ +OWNER=076578616D706C6503636F6D00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000103666F6F076578616D706C6503636F6D00029B000968656C6C6FD2716F6F +------ +OWNER=076578616D706C6503636F6D00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=000103666F6F076578616D706C6503636F6D000006002020010DB800000000000000000000000120010DB8000000000000000000530001 +------ +OWNER=076578616D706C6503636F6D00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=0001076578616D706C6503636F6D000006001000000000000000000000FFFFC6336464 +------ +OWNER=076578616D706C6503636F6D00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=001003666F6F076578616D706C65036F7267000000000400010004000100090268320568332D313900040004C0000201 +------ +OWNER=076578616D706C6503636F6D00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=001003666F6F076578616D706C65036F7267000001000C08665C6F6F2C626172026832 +------ +OWNER=076578616D706C6503636F6D00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0040 +RDATA=001003666F6F076578616D706C65036F7267000001000C08665C6F6F2C626172026832 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_RDATA +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_MANDATORY +------ +WARNG=ZS_BAD_SVCB_MANDATORY +------ +WARNG=ZS_BAD_SVCB_MANDATORY +------ +WARNG=ZS_BAD_SVCB_MANDATORY +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_EMPTY_LIST_ITEM +------ +WARNG=ZS_EMPTY_LIST_ITEM +------ +WARNG=ZS_ITEM_OVERFLOW +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_IPV4 +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_BAD_ADDRESS_CHAR +------ +WARNG=ZS_DUPLICATE_SVCB_KEY +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_BAD_SVCB_PARAM +------ +WARNG=ZS_MISSING_SVCB_MANDATORY +------ +WARNG=ZS_BAD_SVCB_MANDATORY +------ +WARNG=ZS_DUPLICATE_SVCB_MANDATORY +------ diff --git a/tests/libzscanner/data/58_HTTPS.in b/tests/libzscanner/data/58_HTTPS.in new file mode 100644 index 0000000..674f865 --- /dev/null +++ b/tests/libzscanner/data/58_HTTPS.in @@ -0,0 +1,19 @@ +$ORIGIN . +$TTL 1 + +; HTTPS is the same as SVCB, so there are the differences and basics only. + +; OK +@ HTTPS 0 . +@ HTTPS 65535 @ ; Comment +@ HTTPS 1 . key65535="a" key1000=b port=4 key7 mandatory=key7,port +@ TYPE65 \# 3 000000 +@ TYPE65 0 . +@ https 0 . + +; KO +@ HTTPS +@ HTTPS ; Empty rdata +@ HTTPS \# 0 ; Hex empty rdata +@ HTTPS 65536 . ; Priority overflow +@ HTTPS 0 ; Missing item diff --git a/tests/libzscanner/data/58_HTTPS.out b/tests/libzscanner/data/58_HTTPS.out new file mode 100644 index 0000000..8ec9a35 --- /dev/null +++ b/tests/libzscanner/data/58_HTTPS.out @@ -0,0 +1,46 @@ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0041 +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0041 +RDATA=FFFF00 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0041 +RDATA=00010000000004000300070003000200040007000003E8000162FFFF000161 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0041 +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0041 +RDATA=000000 +------ +OWNER=00 +CLASS=0001 +RRTTL=00000001 +RTYPE=0041 +RDATA=000000 +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_NUMBER +------ +WARNG=ZS_BAD_HEX_CHAR +------ +WARNG=ZS_NUMBER16_OVERFLOW +------ +WARNG=ZS_BAD_RDATA +------ diff --git a/tests/libzscanner/data/includes/include1 b/tests/libzscanner/data/includes/include1 new file mode 100644 index 0000000..9de1859 --- /dev/null +++ b/tests/libzscanner/data/includes/include1 @@ -0,0 +1,9 @@ +$TTL 1 + +a NS @ + +$ORIGIN tld1a. +a NS @ + +$ORIGIN tld1b. +a NS @ diff --git a/tests/libzscanner/data/includes/include2 b/tests/libzscanner/data/includes/include2 new file mode 100644 index 0000000..1e14e96 --- /dev/null +++ b/tests/libzscanner/data/includes/include2 @@ -0,0 +1,6 @@ +$TTL 1H + +b NS @ + +$ORIGIN tld1a. +b NS @ diff --git a/tests/libzscanner/data/includes/include3 b/tests/libzscanner/data/includes/include3 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/libzscanner/data/includes/include3 diff --git a/tests/libzscanner/data/includes/include4 b/tests/libzscanner/data/includes/include4 new file mode 100644 index 0000000..7e8d5e2 --- /dev/null +++ b/tests/libzscanner/data/includes/include4 @@ -0,0 +1 @@ +a NS ; Missing data diff --git a/tests/libzscanner/data/includes/include5 b/tests/libzscanner/data/includes/include5 new file mode 100644 index 0000000..ac98e01 --- /dev/null +++ b/tests/libzscanner/data/includes/include5 @@ -0,0 +1 @@ +$TTL x ; Bad number diff --git a/tests/libzscanner/data/includes/include6 b/tests/libzscanner/data/includes/include6 new file mode 100644 index 0000000..b5e8cb8 --- /dev/null +++ b/tests/libzscanner/data/includes/include6 @@ -0,0 +1 @@ +$INCLUDE include2 ; Include in include diff --git a/tests/libzscanner/processing.c b/tests/libzscanner/processing.c new file mode 100644 index 0000000..22066dd --- /dev/null +++ b/tests/libzscanner/processing.c @@ -0,0 +1,184 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <inttypes.h> +#include <stdlib.h> +#include <stdio.h> +#include <time.h> + +#include "libzscanner/scanner.h" +#include "libzscanner/functions.c" +#include "libzscanner/processing.h" +#include "libknot/descriptor.c" + +const char *separator = "------\n"; + +static void print_wire_dname(const uint8_t *dname, uint32_t dname_length) +{ + uint32_t label_length = 0, i = 0; + + for (i = 0; i < dname_length; i++) { + if (label_length == 0) { + label_length = dname[i]; + printf("(%u)", label_length); + continue; + } + printf("%c", (char)dname[i]); + label_length--; + } +} + +void debug_process_error(zs_scanner_t *s) +{ + if (s->error.fatal) { + printf("LINE(%03"PRIu64") ERROR(%s) FILE(%s) NEAR(%s)\n", + s->line_counter, + zs_strerror(s->error.code), + s->file.name, + s->buffer); + } else { + printf("LINE(%03"PRIu64") WARNING(%s) FILE(%s) NEAR(%s)\n", + s->line_counter, + zs_strerror(s->error.code), + s->file.name, + s->buffer); + } + fflush(stdout); +} + +void debug_process_record(zs_scanner_t *s) +{ + uint32_t i; + + char rclass[32]; + char rtype[32]; + + if (knot_rrclass_to_string(s->r_class, rclass, sizeof(rclass)) > 0 && + knot_rrtype_to_string(s->r_type, rtype, sizeof(rtype)) > 0) { + printf("LINE(%03"PRIu64") %s %6u %*s ", + s->line_counter, rclass, s->r_ttl, 5, rtype); + } else { + printf("LINE(%03"PRIu64") %u %6u %*u ", + s->line_counter, s->r_class, s->r_ttl, 5, s->r_type); + } + + print_wire_dname(s->r_owner, s->r_owner_length); + + printf(" \\# %u ", s->r_data_length); + + int block = *((int *)(s->process.data)); + for (i = 0; i < s->r_data_length; i++) { + if (block > 0 && i > 0 && (i % block) == 0) { + printf(" "); + } + printf("%02X", (s->r_data)[i]); + } + printf("\n"); + fflush(stdout); +} + +void debug_process_comment(zs_scanner_t *s) +{ + printf("LINE(%03"PRIu64") COMMENT(%.*s)\n", s->line_counter, + (int)s->buffer_length, s->buffer); + fflush(stdout); +} + +void test_process_error(zs_scanner_t *s) +{ + if (s->error.fatal) { + printf("ERROR=%s\n%s", zs_errorname(s->error.code), separator); + } else { + printf("WARNG=%s\n%s", zs_errorname(s->error.code), separator); + } + fflush(stdout); +} + +void test_process_record(zs_scanner_t *s) +{ + uint32_t i; + + printf("OWNER="); + for (i = 0; i < s->r_owner_length; i++) { + printf("%02X", s->r_owner[i]); + } + printf("\n"); + printf("CLASS=%04X\n", s->r_class); + printf("RRTTL=%08X\n", s->r_ttl); + printf("RTYPE=%04X\n", s->r_type); + printf("RDATA="); + for (i = 0; i < s->r_data_length; i++) { + printf("%02X", (s->r_data)[i]); + } + printf("\n%s", separator); + fflush(stdout); +} + +int test_date_to_timestamp(void) +{ + time_t ref_timestamp, max_timestamp; + uint32_t test_timestamp; + uint8_t buffer[16]; + uint64_t val1, val2; // For time_t type unification. + struct tm tm; + + // Set UTC for strftime. + putenv("TZ=UTC"); + tzset(); + + // Get maximal allowed timestamp. + strptime("22251231235959", "%Y%m%d%H%M%S", &tm); + max_timestamp = mktime(&tm); + + // Testing loop over whole input interval. + for (ref_timestamp = 0; + ref_timestamp < max_timestamp; + ref_timestamp += 1) { + struct tm result; + // Get reference (correct) timestamp. + strftime((char*)buffer, sizeof(buffer), "%Y%m%d%H%M%S", + gmtime_r(&ref_timestamp, &result)); + + // Get testing timestamp. + test_timestamp = 0U; // prevents Wuninitialized + date_to_timestamp(buffer, &test_timestamp); + + // Some continuous logging. + if (ref_timestamp % 10000000 == 0) { + val1 = ref_timestamp; + printf("%s = %"PRIu32"\n", buffer, (uint32_t)val1); + } + + // Comparing results. + if ((uint32_t)ref_timestamp != test_timestamp) { + val1 = ref_timestamp; + + if (ref_timestamp > test_timestamp) { + val2 = ref_timestamp - test_timestamp; + printf("%s = %"PRIu64", in - out = %"PRIu64"\n", + buffer, val1, val2); + } else { + val2 = test_timestamp - ref_timestamp; + printf("%s = %"PRIu64", out - in = %"PRIu64"\n", + buffer, val1, val2); + } + + return -1; + } + } + + return 0; +} diff --git a/tests/libzscanner/processing.h b/tests/libzscanner/processing.h new file mode 100644 index 0000000..47cf03b --- /dev/null +++ b/tests/libzscanner/processing.h @@ -0,0 +1,31 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "libzscanner/scanner.h" + +void debug_process_error(zs_scanner_t *scanner); + +void debug_process_record(zs_scanner_t *scanner); + +void debug_process_comment(zs_scanner_t *scanner); + +void test_process_error(zs_scanner_t *scanner); + +void test_process_record(zs_scanner_t *scanner); + +int test_date_to_timestamp(void); diff --git a/tests/libzscanner/test_zscanner.in b/tests/libzscanner/test_zscanner.in new file mode 100644 index 0000000..10d2b5c --- /dev/null +++ b/tests/libzscanner/test_zscanner.in @@ -0,0 +1,41 @@ +#!/bin/sh + +SOURCE=@top_srcdir@/tests/libzscanner +BUILD=@top_builddir@/tests/libzscanner + +. @top_srcdir@/tests/tap/libtap.sh + +cd "$BUILD" + +TMPDIR=$(test_tmpdir) +TESTS_DIR="$SOURCE"/data +ZSCANNER_TOOL="$BUILD"/zscanner-tool + +plan 86 + +mkdir -p "$TMPDIR"/includes/ +for a in 1 2 3 4 5 6; do + cat "$TESTS_DIR"/includes/include"$a" > "$TMPDIR"/includes/include"$a"; +done + +for case in $(cat "$SOURCE"/TESTS); do + casein=$(test_file_path data/"$case".in) + caseout=$(test_file_path data/"$case".out) + filein="$TMPDIR"/"$case".in + fileout="$TMPDIR"/"$case".out + + sed -e "s|@TMPDIR@|$TMPDIR|;" < "$casein" > "$filein" + + "$ZSCANNER_TOOL" -m 2 . "$filein" > "$fileout" + + if cmp -s "$fileout" "$caseout"; then + ok "$case: output matches" true + rm "$filein" + rm "$fileout" + else + ok "$case: output differs" false + diff -urNap "$caseout" "$fileout" | while read line; do diag "$line"; done + fi +done + +rm -rf "$TMPDIR"/includes/ diff --git a/tests/libzscanner/zscanner-tool.c b/tests/libzscanner/zscanner-tool.c new file mode 100644 index 0000000..d5f514d --- /dev/null +++ b/tests/libzscanner/zscanner-tool.c @@ -0,0 +1,257 @@ +/* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>. + */ + +#include <getopt.h> +#include <inttypes.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +#include "libzscanner/processing.h" +#include "libzscanner/scanner.h" + +#define DEFAULT_MODE 1 +#define DEFAULT_CLASS 1 +#define DEFAULT_TTL 0 + +static void *timestamp_worker(void *data) +{ + int *ret = (int *)data; + *ret = test_date_to_timestamp(); + return NULL; +} + +static void help(void) +{ + printf("\nZone scanner testing tool.\n" + "Usage: zscanner-tool [parameters] origin zonefile\n" + "\n" + "Parameters:\n" + " -m [0,1,2] Processing mode.\n" + " 0 Empty output.\n" + " 1 Debug output (DEFAULT).\n" + " 2 Test output.\n" + " -b <num> Divide hex string to blocks of length <num>.\n" + " -s State parsing mode.\n" + " -t Launch unit tests.\n" + " -h Print this help.\n"); +} + +static int time_test(void) +{ + pthread_t t1, t2, t3; + int ret1, ret2, ret3; + + pthread_create(&t1, NULL, timestamp_worker, &ret1); + pthread_create(&t2, NULL, timestamp_worker, &ret2); + pthread_create(&t3, NULL, timestamp_worker, &ret3); + + pthread_join(t1, NULL); + pthread_join(t2, NULL); + pthread_join(t3, NULL); + + if (ret1 != 0 || ret2 != 0 || ret3 != 0) { + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} + +static int include(zs_scanner_t *s); + +static int state_parsing(zs_scanner_t *s) +{ + while (zs_parse_record(s) == 0) { + switch (s->state) { + case ZS_STATE_DATA: + if (s->process.record != NULL) { + s->process.record(s); + } + break; + case ZS_STATE_ERROR: + if (s->process.error != NULL) { + s->process.error(s); + } + if (s->error.fatal) { + return -1; + } + break; + case ZS_STATE_INCLUDE: + if (include(s) != 0) { + return -1; + } + break; + default: + return (s->error.counter == 0) ? 0 : -1; + } + } + + return -1; +} + +static int include(zs_scanner_t *s) +{ + zs_scanner_t *ss; + int ret = 0; + + if ((ss = malloc(sizeof(zs_scanner_t))) == NULL || + zs_init(ss, (char *)s->buffer, s->default_class, s->default_ttl) != 0 || + zs_set_input_file(ss, (char *)(s->include_filename)) != 0 || + zs_set_processing(ss, s->process.record, s->process.error, s->process.data) != 0 || + state_parsing(ss) != 0) { + if (ss == NULL) { + s->error.code = ZS_ENOMEM; + } else if (ss->error.counter > 0) { + s->error.counter += ss->error.counter; + s->error.code = ZS_UNPROCESSED_INCLUDE; + } else { + s->error.code = ss->error.code; + } + + if (s->process.error != NULL) { + s->buffer[0] = '\0'; // Clear unrelated content. + s->buffer_length = 0; + s->error.counter++; + s->error.fatal = true; + s->process.error(s); + } + + ret = -1; + } + + zs_deinit(ss); + free(ss); + + return ret; +} + +int main(int argc, char *argv[]) +{ + int mode = DEFAULT_MODE, block = 0, state = 0, test = 0; + + // Command line long options. + struct option opts[] = { + { "mode", required_argument, NULL, 'm' }, + { "block", required_argument, NULL, 'b' }, + { "state", no_argument, NULL, 's' }, + { "test", no_argument, NULL, 't' }, + { "help", no_argument, NULL, 'h' }, + { NULL } + }; + + // Parsed command line arguments. + int opt = 0, li = 0; + while ((opt = getopt_long(argc, argv, "m:b:sth", opts, &li)) != -1) { + switch (opt) { + case 'm': + mode = atoi(optarg); + break; + case 'b': + block = atoi(optarg); + break; + case 's': + state = 1; + break; + case 't': + test = 1; + break; + case 'h': + help(); + return EXIT_SUCCESS; + default: + help(); + return EXIT_FAILURE; + } + } + + if (test == 1) { + return time_test(); + } + + // Check if there are 2 remaining non-options. + if (argc - optind != 2) { + help(); + return EXIT_FAILURE; + } + + const char *origin = argv[optind]; + const char *zone_file = argv[optind + 1]; + + // Create a zone scanner. + zs_scanner_t *s = malloc(sizeof(zs_scanner_t)); + if (s == NULL) { + printf("Scanner create error!\n"); + return EXIT_FAILURE; + } + if (zs_init(s, origin, DEFAULT_CLASS, DEFAULT_TTL) != 0) { + printf("Scanner init error!\n"); + free(s); + return EXIT_FAILURE; + } + if (zs_set_input_file(s, zone_file) != 0) { + printf("Scanner file error!\n"); + zs_deinit(s); + free(s); + return EXIT_FAILURE; + } + + // Set the processing mode. + int ret; + switch (mode) { + case 0: + ret = 0; + break; + case 1: + ret = zs_set_processing(s, debug_process_record, debug_process_error, &block); + ret += zs_set_processing_comment(s, debug_process_comment); + break; + case 2: + ret = zs_set_processing(s, test_process_record, test_process_error, NULL); + break; + default: + printf("Bad mode number!\n"); + help(); + return EXIT_FAILURE; + } + if (ret != 0) { + printf("Processing setup error!\n"); + return EXIT_FAILURE; + } + + // Parse the file. + ret = state ? state_parsing(s) : zs_parse_all(s); + if (ret == 0) { + if (mode == DEFAULT_MODE) { + printf("Zone file has been processed successfully\n"); + } + + zs_deinit(s); + free(s); + return EXIT_SUCCESS; + } else { + if (s->error.counter > 0 && mode == DEFAULT_MODE) { + printf("Zone processing has stopped with " + "%"PRIu64" warnings/errors!\n", + s->error.counter); + } else if (mode == DEFAULT_MODE) { + printf("%s\n", zs_strerror(s->error.code)); + } + + zs_deinit(s); + free(s); + return EXIT_FAILURE; + } +} diff --git a/tests/modules/test_onlinesign.c b/tests/modules/test_onlinesign.c new file mode 100644 index 0000000..fbddb6e --- /dev/null +++ b/tests/modules/test_onlinesign.c @@ -0,0 +1,203 @@ +/* Copyright (C) 2018 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> +#include <assert.h> + +#include "knot/modules/onlinesign/nsec_next.h" +#include "libknot/consts.h" +#include "libknot/dname.h" +#include "libknot/errcode.h" + +/*! + * \brief Assert that a domain name in a static buffer is valid. + */ +#define _assert_dname(name) \ + assert(knot_dname_wire_check(name, name + KNOT_DNAME_MAXLEN, NULL) > 0) + +static void _test_nsec_next(const char *msg, + const knot_dname_t *input, + const knot_dname_t *apex, + const knot_dname_t *expected) +{ + knot_dname_t *next = online_nsec_next(input, apex); + ok(next != NULL && knot_dname_is_equal(next, expected), + "nsec_next, %s", msg); + knot_dname_free(next, NULL); +} + +/*! + * \brief Check \a online_nsec_next. + * + * Intentionally implemented as a macro. The input domain names are copied + * into static buffers and validated. + */ +#define test_nsec_next(msg, _input, _apex, _expected) \ +{ \ + uint8_t input[KNOT_DNAME_MAXLEN] = _input; \ + uint8_t apex[KNOT_DNAME_MAXLEN] = _apex; \ + uint8_t expected[KNOT_DNAME_MAXLEN] = _expected; \ + \ + _assert_dname(input); \ + _assert_dname(apex); \ + _assert_dname(expected); \ + \ + _test_nsec_next(msg, input, apex, expected); \ +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + // adding a single zero-byte label + + test_nsec_next( + "zero-byte label, apex", + "\x7""example""\x3""com", + "\x7""example""\x3""com", + "\x01\x00""\x07""example""\x03""com" + ); + + test_nsec_next( + "zero-byte label, subdomain", + "\x02""nx""\x7""example""\x3""com", + "\x7""example""\x3""com", + "\x01\x00""\x02""nx""\x07""example""\x03""com" + ); + + test_nsec_next( + "zero-byte label, binary", + "\x02\xff\xff""\x7""example""\x3""com", + "\x07""example""\x3""com", + "\x01\x00""\x02\xff\xff""\x7""example""\x3""com" + ); + + // zero byte label won't fit, increment + #define APEX \ + "\x05""bacon""\x05""salad" + + #define LONG_SUFFIX \ + "\x2e""xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ + "\x2e""iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii" \ + "\x2e""mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm" \ + "\x2e""qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq" \ + "\x2c""zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz" \ + APEX + assert(sizeof(LONG_SUFFIX) == 245 + 1); + + test_nsec_next( + "increment first label (simple)", + "\x08""icecream" LONG_SUFFIX, + APEX, + "\x08""icecrean" LONG_SUFFIX + ); + + test_nsec_next( + "increment first label (binary)", + "\x08""walrus\xff\xff" LONG_SUFFIX, + APEX, + "\x08""walrut\x00\x00" LONG_SUFFIX + ); + + test_nsec_next( + "increment first label (in place)", + "\x07""lobster" LONG_SUFFIX, + APEX, + "\x07""lobstes" LONG_SUFFIX + ); + + test_nsec_next( + "increment first label (extend)", + "\x07""\xff\xff\xff\xff\xff\xff\xff" LONG_SUFFIX, + APEX, + "\x08""\xff\xff\xff\xff\xff\xff\xff\x00" LONG_SUFFIX + ); + + // name too long + + test_nsec_next( + "name to long, strip label and increase next (simple)", + "\x03""\xff\xff\xff""\x04""newt" LONG_SUFFIX, + APEX, + "\x04""newu" LONG_SUFFIX + ); + + test_nsec_next( + "name to long, strip label and increase next (binary)", + "\x03""\xff\xff\xff""\x04""cc\xff\xff" LONG_SUFFIX, + APEX, + "\x04""cd\x00\x00" LONG_SUFFIX + ); + + test_nsec_next( + "name to long, strip label and increase next (extend)", + "\x04""\xff\xff\xff\xff""\x03""\xff\xff\xff" LONG_SUFFIX, + APEX, + "\x04""\xff\xff\xff\x00" LONG_SUFFIX + ); + + // label too long + + #define MAX_LABEL "\x3f" /* 63 */ \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" \ + "\xff\xff\xff" + assert(sizeof(MAX_LABEL) == 64 + 1); + + #define PAD_LABEL "\x28" /* 40 */ \ + "iiiiiiiiiioooooooooottttttttttssssssssss" + assert(sizeof(PAD_LABEL) == 41 + 1); + + test_nsec_next( + "label too long, strip and increase next (simple)", + MAX_LABEL "\x08""mandrill" MAX_LABEL MAX_LABEL PAD_LABEL APEX, + APEX, + "\x08""mandrilm" MAX_LABEL MAX_LABEL PAD_LABEL APEX + ); + + test_nsec_next( + "label too long, strip and increase next (extend)", + MAX_LABEL "\x07""\xff\xff\xff\xff\xff\xff\xff" MAX_LABEL MAX_LABEL PAD_LABEL APEX, + APEX, + "\x08""\xff\xff\xff\xff\xff\xff\xff\x00" MAX_LABEL MAX_LABEL PAD_LABEL APEX + ); + + test_nsec_next( + "label too long, strip multiple", + MAX_LABEL MAX_LABEL "\x08""flamingo" MAX_LABEL PAD_LABEL APEX, + APEX, + "\x08""flamingp" MAX_LABEL PAD_LABEL APEX + ); + + test_nsec_next( + "label too long, wrap around to apex", + "\x31" /* 49 */ + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff" + MAX_LABEL MAX_LABEL MAX_LABEL APEX, + APEX, + APEX + ); + + return 0; +} diff --git a/tests/modules/test_rrl.c b/tests/modules/test_rrl.c new file mode 100644 index 0000000..6a5210f --- /dev/null +++ b/tests/modules/test_rrl.c @@ -0,0 +1,178 @@ +/* Copyright (C) 2019 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 <https://www.gnu.org/licenses/>. + */ + +#include <tap/basic.h> + +#include "libdnssec/crypto.h" +#include "libdnssec/random.h" +#include "libknot/libknot.h" +#include "contrib/sockaddr.h" +#include "knot/modules/rrl/functions.c" +#include "stdio.h" + +/* Enable time-dependent tests. */ +//#define ENABLE_TIMED_TESTS +#define RRL_SIZE 196613 +#define RRL_THREADS 8 +#define RRL_INSERTS (RRL_SIZE/(5*RRL_THREADS)) /* lf = 1/5 */ + +/* Disabled as default as it depends on random input. + * Table may be consistent even if some collision occur (and they may occur). + * Note: Disabled due to reported problems when running on VMs due to time + * flow inconsistencies. Should work alright on a host machine. + */ +#ifdef ENABLE_TIMED_TESTS +struct bucketmap { + unsigned i; + uint64_t x; +}; + +/*! \brief Unit runnable. */ +struct runnable_data { + int passed; + rrl_table_t *rrl; + struct sockaddr_storage *addr; + rrl_req_t *rq; + knot_dname_t *zone; +}; + +static void* rrl_runnable(void *arg) +{ + struct runnable_data *d = (struct runnable_data *)arg; + struct sockaddr_storage addr; + memcpy(&addr, d->addr, sizeof(struct sockaddr_storage)); + int lock = -1; + uint32_t now = time(NULL); + struct bucketmap *m = malloc(RRL_INSERTS * sizeof(struct bucketmap)); + for (unsigned i = 0; i < RRL_INSERTS; ++i) { + m[i].i = dnssec_random_uint32_t(); + ((struct sockaddr_in *) &addr)->sin_addr.s_addr = m[i].i; + rrl_item_t *b = rrl_hash(d->rrl, &addr, d->rq, d->zone, now, &lock); + rrl_unlock(d->rrl, lock); + m[i].x = b->netblk; + } + for (unsigned i = 0; i < RRL_INSERTS; ++i) { + ((struct sockaddr_in *) &addr)->sin_addr.s_addr = m[i].i; + rrl_item_t *b = rrl_hash(d->rrl, &addr, d->rq, d->zone, now, &lock); + rrl_unlock(d->rrl, lock); + if (b->netblk != m[i].x) { + d->passed = 0; + } + } + free(m); + return NULL; +} + +static void rrl_hopscotch(struct runnable_data* rd) +{ + rd->passed = 1; + pthread_t thr[RRL_THREADS]; + for (unsigned i = 0; i < RRL_THREADS; ++i) { + pthread_create(thr + i, NULL, &rrl_runnable, rd); + } + for (unsigned i = 0; i < RRL_THREADS; ++i) { + pthread_join(thr[i], NULL); + } +} +#endif + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + dnssec_crypto_init(); + + /* Prepare query. */ + knot_pkt_t *query = knot_pkt_new(NULL, 512, NULL); + if (query == NULL) { + return KNOT_ERROR; /* Fatal */ + } + + knot_dname_t *qname = knot_dname_from_str_alloc("beef."); + int ret = knot_pkt_put_question(query, qname, KNOT_CLASS_IN, KNOT_RRTYPE_A); + knot_dname_free(qname, NULL); + if (ret != KNOT_EOK) { + knot_pkt_free(query); + return KNOT_ERROR; /* Fatal */ + } + + /* Prepare response */ + uint8_t rbuf[65535]; + size_t rlen = sizeof(rbuf); + memcpy(rbuf, query->wire, query->size); + knot_wire_flags_set_qr(rbuf); + + rrl_req_t rq; + rq.wire = rbuf; + rq.len = rlen; + rq.query = query; + rq.flags = 0; + + /* 1. create rrl table */ + const uint32_t rate = 10; + rrl_table_t *rrl = rrl_create(RRL_SIZE, rate); + ok(rrl != NULL, "rrl: create"); + + /* 2. N unlimited requests. */ + knot_dname_t *zone = knot_dname_from_str_alloc("rrl."); + + struct sockaddr_storage addr; + struct sockaddr_storage addr6; + sockaddr_set(&addr, AF_INET, "1.2.3.4", 0); + sockaddr_set(&addr6, AF_INET6, "1122:3344:5566:7788::aabb", 0); + ret = 0; + for (unsigned i = 0; i < rate * RRL_CAPACITY; ++i) { + if (rrl_query(rrl, &addr, &rq, zone, NULL) != KNOT_EOK || + rrl_query(rrl, &addr6, &rq, zone, NULL) != KNOT_EOK) { + ret = KNOT_ELIMIT; + break; + } + } + is_int(0, ret, "rrl: unlimited IPv4/v6 requests"); + + /* 3. Endian-independent hash input buffer. */ + uint8_t buf[RRL_CLSBLK_MAXLEN]; + // CLS_LARGE + remote + dname wire. + uint8_t expectedv4[] = "\x10\x01\x02\x03\x00\x00\x00\x00\x00\x04""beef"; + rrl_classify(buf, sizeof(buf), &addr, &rq, qname); + is_int(0, memcmp(buf, expectedv4, sizeof(expectedv4)), "rrl: IPv4 hash input buffer"); + uint8_t expectedv6[] = "\x10\x11\x22\x33\x44\x55\x66\x77\x00\x04""beef"; + rrl_classify(buf, sizeof(buf), &addr6, &rq, qname); + is_int(0, memcmp(buf, expectedv6, sizeof(expectedv6)), "rrl: IPv6 hash input buffer"); + +#ifdef ENABLE_TIMED_TESTS + /* 5. limited request */ + ret = rrl_query(rrl, &addr, &rq, zone, NULL); + is_int(KNOT_ELIMIT, ret, "rrl: throttled IPv4 request"); + + /* 6. limited IPv6 request */ + ret = rrl_query(rrl, &addr6, &rq, zone, NULL); + is_int(KNOT_ELIMIT, ret, "rrl: throttled IPv6 request"); + + /* 8. hopscotch test */ + struct runnable_data rd = { + 1, rrl, &addr, &rq, zone + }; + rrl_hopscotch(&rd); + ok(rd.passed, "rrl: hashtable is ~ consistent"); +#endif + + knot_dname_free(zone, NULL); + knot_pkt_free(query); + rrl_destroy(rrl); + dnssec_crypto_cleanup(); + return 0; +} diff --git a/tests/tap/basic.c b/tests/tap/basic.c new file mode 100644 index 0000000..23b595c --- /dev/null +++ b/tests/tap/basic.c @@ -0,0 +1,605 @@ +/* + * Some utility routines for writing tests. + * + * Here are a variety of utility routines for writing tests compatible with + * the TAP protocol. All routines of the form ok() or is*() take a test + * number and some number of appropriate arguments, check to be sure the + * results match the expected output using the arguments, and print out + * something appropriate for that test number. Other utility routines help in + * constructing more complex tests, skipping tests, reporting errors, setting + * up the TAP output format, or finding things in the test environment. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2009, 2010, 2011, 2012 Russ Allbery <rra@stanford.edu> + * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2013 + * The Board of Trustees of the Leland Stanford Junior University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef _WIN32 +# include <direct.h> +#else +# include <sys/stat.h> +#endif +#include <sys/types.h> +#include <unistd.h> + +#include "basic.h" + +/* Windows provides mkdir and rmdir under different names. */ +#ifdef _WIN32 +# define mkdir(p, m) _mkdir(p) +# define rmdir(p) _rmdir(p) +#endif + +/* + * The test count. Always contains the number that will be used for the next + * test status. + */ +unsigned long testnum = 1; + +/* + * Status information stored so that we can give a test summary at the end of + * the test case. We store the planned final test and the count of failures. + * We can get the highest test count from testnum. + * + * We also store the PID of the process that called plan() and only summarize + * results when that process exits, so as to not misreport results in forked + * processes. + * + * If _lazy is true, we're doing lazy planning and will print out the plan + * based on the last test number at the end of testing. + */ +static unsigned long _planned = 0; +static unsigned long _failed = 0; +static pid_t _process = 0; +static int _lazy = 0; + +/* + * Our exit handler. Called on completion of the test to report a summary of + * results provided we're still in the original process. This also handles + * printing out the plan if we used plan_lazy(), although that's suppressed if + * we never ran a test (due to an early bail, for example). + */ +static void +finish(void) +{ + unsigned long highest = testnum - 1; + + if (_planned == 0 && !_lazy) + return; + fflush(stderr); + if (_process != 0 && getpid() == _process) { + if (_lazy && highest > 0) { + printf("1..%lu\n", highest); + _planned = highest; + } + if (_planned > highest) + printf("# Looks like you planned %lu test%s but only ran %lu\n", + _planned, (_planned > 1 ? "s" : ""), highest); + else if (_planned < highest) + printf("# Looks like you planned %lu test%s but ran %lu extra\n", + _planned, (_planned > 1 ? "s" : ""), highest - _planned); + else if (_failed > 0) + printf("# Looks like you failed %lu test%s of %lu\n", _failed, + (_failed > 1 ? "s" : ""), _planned); + else if (_planned > 1) + printf("# All %lu tests successful or skipped\n", _planned); + else + printf("# %lu test successful or skipped\n", _planned); + } +} + +/* + * Initialize things. Turns on line buffering on stdout and then prints out + * the number of tests in the test suite. + */ +void +plan(unsigned long count) +{ + if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0) + fprintf(stderr, "# cannot set stdout to line buffered: %s\n", + strerror(errno)); + fflush(stderr); + printf("1..%lu\n", count); + testnum = 1; + _planned = count; + _process = getpid(); + atexit(finish); +} + +/* + * Initialize things for lazy planning, where we'll automatically print out a + * plan at the end of the program. Turns on line buffering on stdout as well. + */ +void +plan_lazy(void) +{ + if (setvbuf(stdout, NULL, _IOLBF, BUFSIZ) != 0) + fprintf(stderr, "# cannot set stdout to line buffered: %s\n", + strerror(errno)); + testnum = 1; + _process = getpid(); + _lazy = 1; + atexit(finish); +} + +/* + * Skip the entire test suite and exits. Should be called instead of plan(), + * not after it, since it prints out a special plan line. + */ +void +skip_all(const char *format, ...) +{ + fflush(stderr); + printf("1..0 # skip"); + if (format != NULL) { + va_list args; + + putchar(' '); + va_start(args, format); + vprintf(format, args); + va_end(args); + } + putchar('\n'); + exit(0); +} + +/* + * Print the test description. + */ +static void +print_desc(const char *format, va_list args) +{ + printf(" - "); + vprintf(format, args); +} + +/* + * Takes a boolean success value and assumes the test passes if that value + * is true and fails if that value is false. + */ +void +ok(int success, const char *format, ...) +{ + fflush(stderr); + printf("%sok %lu", success ? "" : "not ", testnum++); + if (!success) + _failed++; + if (format != NULL) { + va_list args; + + va_start(args, format); + print_desc(format, args); + va_end(args); + } + putchar('\n'); +} + +/* + * Same as ok(), but takes the format arguments as a va_list. + */ +void +okv(int success, const char *format, va_list args) +{ + fflush(stderr); + printf("%sok %lu", success ? "" : "not ", testnum++); + if (!success) + _failed++; + if (format != NULL) + print_desc(format, args); + putchar('\n'); +} + +/* + * Skip a test. + */ +void +skip(const char *reason, ...) +{ + fflush(stderr); + printf("ok %lu # skip", testnum++); + if (reason != NULL) { + va_list args; + + va_start(args, reason); + putchar(' '); + vprintf(reason, args); + va_end(args); + } + putchar('\n'); +} + +/* + * Report the same status on the next count tests. + */ +void +ok_block(unsigned long count, int status, const char *format, ...) +{ + unsigned long i; + + fflush(stderr); + for (i = 0; i < count; i++) { + printf("%sok %lu", status ? "" : "not ", testnum++); + if (!status) + _failed++; + if (format != NULL) { + va_list args; + + va_start(args, format); + print_desc(format, args); + va_end(args); + } + putchar('\n'); + } +} + +/* + * Skip the next count tests. + */ +void +skip_block(unsigned long count, const char *reason, ...) +{ + unsigned long i; + + fflush(stderr); + for (i = 0; i < count; i++) { + printf("ok %lu # skip", testnum++); + if (reason != NULL) { + va_list args; + + va_start(args, reason); + putchar(' '); + vprintf(reason, args); + va_end(args); + } + putchar('\n'); + } +} + +/* + * Takes an expected integer and a seen integer and assumes the test passes + * if those two numbers match. + */ +void +is_int(long long wanted, long long seen, const char *format, ...) +{ + fflush(stderr); + if (wanted == seen) + printf("ok %lu", testnum++); + else { + printf("# wanted: %lld\n# seen: %lld\n", wanted, seen); + printf("not ok %lu", testnum++); + _failed++; + } + if (format != NULL) { + va_list args; + + va_start(args, format); + print_desc(format, args); + va_end(args); + } + putchar('\n'); +} + +/* + * Takes a string and what the string should be, and assumes the test passes + * if those strings match (using strcmp). + */ +void +is_string(const char *wanted, const char *seen, const char *format, ...) +{ + if (wanted == NULL) + wanted = "(null)"; + if (seen == NULL) + seen = "(null)"; + fflush(stderr); + if (strcmp(wanted, seen) == 0) + printf("ok %lu", testnum++); + else { + printf("# wanted: %s\n# seen: %s\n", wanted, seen); + printf("not ok %lu", testnum++); + _failed++; + } + if (format != NULL) { + va_list args; + + va_start(args, format); + print_desc(format, args); + va_end(args); + } + putchar('\n'); +} + +/* + * Takes an expected unsigned long and a seen unsigned long and assumes the + * test passes if the two numbers match. Otherwise, reports them in hex. + */ +void +is_hex(unsigned long long wanted, unsigned long long seen, + const char *format, ...) +{ + fflush(stderr); + if (wanted == seen) + printf("ok %lu", testnum++); + else { + printf("# wanted: %llx\n# seen: %llx\n", + (unsigned long long) wanted, + (unsigned long long) seen); + printf("not ok %lu", testnum++); + _failed++; + } + if (format != NULL) { + va_list args; + + va_start(args, format); + print_desc(format, args); + va_end(args); + } + putchar('\n'); +} + +/* + * Bail out with an error. + */ +void +bail(const char *format, ...) +{ + va_list args; + + fflush(stderr); + fflush(stdout); + printf("Bail out! "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); + exit(255); +} + +/* + * Bail out with an error, appending strerror(errno). + */ +void +sysbail(const char *format, ...) +{ + va_list args; + int oerrno = errno; + + fflush(stderr); + fflush(stdout); + printf("Bail out! "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf(": %s\n", strerror(oerrno)); + exit(255); +} + +/* + * Report a diagnostic to stderr. + */ +void +diag(const char *format, ...) +{ + va_list args; + + fflush(stderr); + fflush(stdout); + printf("# "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf("\n"); +} + +/* + * Report a diagnostic to stderr, appending strerror(errno). + */ +void +sysdiag(const char *format, ...) +{ + va_list args; + int oerrno = errno; + + fflush(stderr); + fflush(stdout); + printf("# "); + va_start(args, format); + vprintf(format, args); + va_end(args); + printf(": %s\n", strerror(oerrno)); +} + +/* + * Allocate cleared memory, reporting a fatal error with bail on failure. + */ +void * +bcalloc(size_t n, size_t size) +{ + void *p; + + p = calloc(n, size); + if (p == NULL) + sysbail("failed to calloc %lu", (unsigned long)(n * size)); + return p; +} + +/* + * Allocate memory, reporting a fatal error with bail on failure. + */ +void * +bmalloc(size_t size) +{ + void *p; + + p = malloc(size); + if (p == NULL) + sysbail("failed to malloc %lu", (unsigned long) size); + return p; +} + +/* + * Reallocate memory, reporting a fatal error with bail on failure. + */ +void * +brealloc(void *p, size_t size) +{ + p = realloc(p, size); + if (p == NULL) + sysbail("failed to realloc %lu bytes", (unsigned long) size); + return p; +} + +/* + * Copy a string, reporting a fatal error with bail on failure. + */ +char * +bstrdup(const char *s) +{ + char *p; + size_t len; + + len = strlen(s) + 1; + p = malloc(len); + if (p == NULL) + sysbail("failed to strdup %lu bytes", (unsigned long) len); + memcpy(p, s, len); + return p; +} + +/* + * Copy up to n characters of a string, reporting a fatal error with bail on + * failure. Don't use the system strndup function, since it may not exist and + * the TAP library doesn't assume any portability support. + */ +char * +bstrndup(const char *s, size_t n) +{ + const char *p; + char *copy; + size_t length; + + /* Don't assume that the source string is nul-terminated. */ + for (p = s; (size_t) (p - s) < n && *p != '\0'; p++) + ; + length = p - s; + copy = malloc(length + 1); + if (p == NULL) + sysbail("failed to strndup %lu bytes", (unsigned long) length); + memcpy(copy, s, length); + copy[length] = '\0'; + return copy; +} + +/* + * Locate a test file. Given the partial path to a file, look under BUILD and + * then SOURCE for the file and return the full path to the file. Returns + * NULL if the file doesn't exist. A non-NULL return should be freed with + * test_file_path_free(). + * + * This function uses sprintf because it attempts to be independent of all + * other portability layers. The use immediately after a memory allocation + * should be safe without using snprintf or strlcpy/strlcat. + */ +char * +test_file_path(const char *file) +{ + char *base; + char *path = NULL; + size_t length; + const char *envs[] = { "BUILD", "SOURCE", NULL }; + int i; + + for (i = 0; envs[i] != NULL; i++) { + base = getenv(envs[i]); + if (base == NULL) + continue; + length = strlen(base) + 1 + strlen(file) + 1; + path = bmalloc(length); + snprintf(path, length, "%s/%s", base, file); + if (access(path, R_OK) == 0) + break; + free(path); + path = NULL; + } + return path; +} + +/* + * Free a path returned from test_file_path(). This function exists primarily + * for Windows, where memory must be freed from the same library domain that + * it was allocated from. + */ +void +test_file_path_free(char *path) +{ + if (path != NULL) + free(path); +} + +/* + * Create a temporary directory, tmp, under BUILD if set and the current + * directory if it does not. Returns the path to the temporary directory in + * newly allocated memory, and calls bail on any failure. The return value + * should be freed with test_tmpdir_free. + * + * This function uses sprintf because it attempts to be independent of all + * other portability layers. The use immediately after a memory allocation + * should be safe without using snprintf or strlcpy/strlcat. + */ +char * +test_tmpdir(void) +{ + const char *build; + char *path = NULL; + size_t length; + + build = getenv("BUILD"); + if (build == NULL) + build = "."; + length = strlen(build) + strlen("/tmp") + 1; + path = bmalloc(length); + snprintf(path, length, "%s/tmp", build); + if (access(path, X_OK) < 0) + if (mkdir(path, 0777) < 0) + sysbail("error creating temporary directory %s", path); + return path; +} + +/* + * Free a path returned from test_tmpdir() and attempt to remove the + * directory. If we can't delete the directory, don't worry; something else + * that hasn't yet cleaned up may still be using it. + */ +void +test_tmpdir_free(char *path) +{ + rmdir(path); + if (path != NULL) + free(path); +} diff --git a/tests/tap/basic.h b/tests/tap/basic.h new file mode 100644 index 0000000..2e1b7e3 --- /dev/null +++ b/tests/tap/basic.h @@ -0,0 +1,132 @@ +/* + * Basic utility routines for the TAP protocol. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2009, 2010, 2011, 2012 Russ Allbery <rra@stanford.edu> + * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012 + * The Board of Trustees of the Leland Stanford Junior University + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "macros.h" +#include <stdarg.h> /* va_list */ +#include <sys/types.h> /* size_t */ + +/* + * Used for iterating through arrays. ARRAY_SIZE returns the number of + * elements in the array (useful for a < upper bound in a for loop) and + * ARRAY_END returns a pointer to the element past the end (ISO C99 makes it + * legal to refer to such a pointer as long as it's never dereferenced). + */ +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) +#define ARRAY_END(array) (&(array)[ARRAY_SIZE(array)]) + +BEGIN_DECLS + +/* + * The test count. Always contains the number that will be used for the next + * test status. + */ +extern unsigned long testnum; + +/* Print out the number of tests and set standard output to line buffered. */ +void plan(unsigned long count); + +/* + * Prepare for lazy planning, in which the plan will be printed automatically + * at the end of the test program. + */ +void plan_lazy(void); + +/* Skip the entire test suite. Call instead of plan. */ +void skip_all(const char *format, ...) + __attribute__((__noreturn__, __format__(printf, 1, 2))); + +/* + * Basic reporting functions. The okv() function is the same as ok() but + * takes the test description as a va_list to make it easier to reuse the + * reporting infrastructure when writing new tests. + */ +void ok(int success, const char *format, ...) + __attribute__((__format__(printf, 2, 3))); +void okv(int success, const char *format, va_list args); +void skip(const char *reason, ...) + __attribute__((__format__(printf, 1, 2))); + +/* Report the same status on, or skip, the next count tests. */ +void ok_block(unsigned long count, int success, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +void skip_block(unsigned long count, const char *reason, ...) + __attribute__((__format__(printf, 2, 3))); + +/* Check an expected value against a seen value. */ +void is_int(long long wanted, long long seen, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +void is_string(const char *wanted, const char *seen, const char *format, ...) + __attribute__((__format__(printf, 3, 4))); +void is_hex(unsigned long long wanted, unsigned long long seen, + const char *format, ...) + __attribute__((__format__(printf, 3, 4))); + +/* Bail out with an error. sysbail appends strerror(errno). */ +void bail(const char *format, ...) + __attribute__((__noreturn__, __nonnull__, __format__(printf, 1, 2))); +void sysbail(const char *format, ...) + __attribute__((__noreturn__, __nonnull__, __format__(printf, 1, 2))); + +/* Report a diagnostic to stderr prefixed with #. */ +void diag(const char *format, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); +void sysdiag(const char *format, ...) + __attribute__((__nonnull__, __format__(printf, 1, 2))); + +/* Allocate memory, reporting a fatal error with bail on failure. */ +void *bcalloc(size_t, size_t) + __attribute__((__alloc_size__(1, 2), __malloc__)); +void *bmalloc(size_t) + __attribute__((__alloc_size__(1), __malloc__)); +void *brealloc(void *, size_t) + __attribute__((__alloc_size__(2), __malloc__)); +char *bstrdup(const char *) + __attribute__((__malloc__, __nonnull__)); +char *bstrndup(const char *, size_t) + __attribute__((__malloc__, __nonnull__)); + +/* + * Find a test file under BUILD or SOURCE, returning the full path. The + * returned path should be freed with test_file_path_free(). + */ +char *test_file_path(const char *file) + __attribute__((__malloc__, __nonnull__)); +void test_file_path_free(char *path); + +/* + * Create a temporary directory relative to BUILD and return the path. The + * returned path should be freed with test_tmpdir_free. + */ +char *test_tmpdir(void) + __attribute__((__malloc__)); +void test_tmpdir_free(char *path); + +END_DECLS diff --git a/tests/tap/files.c b/tests/tap/files.c new file mode 100644 index 0000000..f979d07 --- /dev/null +++ b/tests/tap/files.c @@ -0,0 +1,66 @@ +/* Copyright (C) 2016 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 <https://www.gnu.org/licenses/>. + */ + +#include "files.h" + +#include "../../src/contrib/string.c" +#include "../../src/contrib/files.c" + +#include <stdlib.h> + +static char *make_temp(bool is_directory) +{ + char *tmpdir = getenv("TMPDIR"); + if (!tmpdir) { + tmpdir = "/tmp"; + } + + char tmp[4096] = { 0 }; + int r = snprintf(tmp, sizeof(tmp), "%s/knot_unit.XXXXXX", tmpdir); + if (r <= 0 || r >= sizeof(tmp)) { + return NULL; + } + + if (is_directory) { + char *ret = mkdtemp(tmp); + if (ret == NULL) { + return NULL; + } + } else { + int ret = mkstemp(tmp); + if (ret == -1) { + return NULL; + } + close(ret); + } + + return strdup(tmp); +} + +char *test_mktemp(void) +{ + return make_temp(false); +} + +char *test_mkdtemp(void) +{ + return make_temp(true); +} + +bool test_rm_rf(const char *path) +{ + return remove_path(path); +} diff --git a/tests/tap/files.h b/tests/tap/files.h new file mode 100644 index 0000000..04c9956 --- /dev/null +++ b/tests/tap/files.h @@ -0,0 +1,44 @@ +/* Copyright (C) 2016 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 <https://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <stdbool.h> + +/*! + * \brief Create a temporary file. + * + * If TMPDIR environment variable is set, the file is created within + * that directory. If the variable is not set, the file is created + * within /tmp. + */ +char *test_mktemp(void); + +/*! + * \brief Create a temporary directory. + * + * If TMPDIR environment variable is set, the directory is created within + * that directory. If the variable is not set, the directory is created + * within /tmp. + */ +char *test_mkdtemp(void); + +/*! + * \brief Delete file or directory (recursive). + * + * \return true on success, false when one or more files failed to be removed. + */ +bool test_rm_rf(const char *path); diff --git a/tests/tap/float.c b/tests/tap/float.c new file mode 100644 index 0000000..5c0c643 --- /dev/null +++ b/tests/tap/float.c @@ -0,0 +1,67 @@ +/* + * Utility routines for writing floating point tests. + * + * Currently provides only one function, which checks whether a double is + * equal to an expected value within a given epsilon. This is broken into a + * separate source file from the rest of the basic C TAP library because it + * may require linking with -lm on some platforms, and the package may not + * otherwise care about floating point. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2008, 2010, 2012 Russ Allbery <rra@stanford.edu> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* Required for isnan() and isinf(). */ +#if defined(__STRICT_ANSI__) || defined(PEDANTIC) +# ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 600 +# endif +#endif + +#include <math.h> +#include <stdarg.h> +#include <stdio.h> + +#include "basic.h" +#include "float.h" + +/* + * Takes an expected double and a seen double and assumes the test passes if + * those two numbers are within delta of each other. + */ +void +is_double(double wanted, double seen, double epsilon, const char *format, ...) +{ + va_list args; + + va_start(args, format); + fflush(stderr); + if ((isnan(wanted) && isnan(seen)) + || (isinf(wanted) && isinf(seen) && wanted == seen) + || fabs(wanted - seen) <= epsilon) + okv(1, format, args); + else { + printf("# wanted: %g\n# seen: %g\n", wanted, seen); + okv(0, format, args); + } +} diff --git a/tests/tap/float.h b/tests/tap/float.h new file mode 100644 index 0000000..5c58b5b --- /dev/null +++ b/tests/tap/float.h @@ -0,0 +1,39 @@ +/* + * Floating point check function for the TAP protocol. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2008, 2010, 2012 Russ Allbery <rra@stanford.edu> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +#include "macros.h" + +BEGIN_DECLS + +/* Check an expected value against a seen value within epsilon. */ +void is_double(double wanted, double seen, double epsilon, + const char *format, ...) + __attribute__((__format__(printf, 4, 5))); + +END_DECLS diff --git a/tests/tap/libtap.sh b/tests/tap/libtap.sh new file mode 100644 index 0000000..0ffab2d --- /dev/null +++ b/tests/tap/libtap.sh @@ -0,0 +1,246 @@ +# Shell function library for test cases. +# +# Note that while many of the functions in this library could benefit from +# using "local" to avoid possibly hammering global variables, Solaris /bin/sh +# doesn't support local and this library aspires to be portable to Solaris +# Bourne shell. Instead, all private variables are prefixed with "tap_". +# +# This file provides a TAP-compatible shell function library useful for +# writing test cases. It is part of C TAP Harness, which can be found at +# <http://www.eyrie.org/~eagle/software/c-tap-harness/>. +# +# Written by Russ Allbery <rra@stanford.edu> +# Copyright 2009, 2010, 2011, 2012 Russ Allbery <rra@stanford.edu> +# Copyright 2006, 2007, 2008, 2013 +# The Board of Trustees of the Leland Stanford Junior University +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Print out the number of test cases we expect to run. +plan () { + count=1 + planned="$1" + failed=0 + echo "1..$1" + trap finish 0 +} + +# Prepare for lazy planning. +plan_lazy () { + count=1 + planned=0 + failed=0 + trap finish 0 +} + +# Report the test status on exit. +finish () { + tap_highest=`expr "$count" - 1` + if [ "$planned" = 0 ] ; then + echo "1..$tap_highest" + planned="$tap_highest" + fi + tap_looks='# Looks like you' + if [ "$planned" -gt 0 ] ; then + if [ "$planned" -gt "$tap_highest" ] ; then + if [ "$planned" -gt 1 ] ; then + echo "$tap_looks planned $planned tests but only ran" \ + "$tap_highest" + else + echo "$tap_looks planned $planned test but only ran" \ + "$tap_highest" + fi + elif [ "$planned" -lt "$tap_highest" ] ; then + tap_extra=`expr "$tap_highest" - "$planned"` + if [ "$planned" -gt 1 ] ; then + echo "$tap_looks planned $planned tests but ran" \ + "$tap_extra extra" + else + echo "$tap_looks planned $planned test but ran" \ + "$tap_extra extra" + fi + elif [ "$failed" -gt 0 ] ; then + if [ "$failed" -gt 1 ] ; then + echo "$tap_looks failed $failed tests of $planned" + else + echo "$tap_looks failed $failed test of $planned" + fi + elif [ "$planned" -gt 1 ] ; then + echo "# All $planned tests successful or skipped" + else + echo "# $planned test successful or skipped" + fi + fi +} + +# Skip the entire test suite. Should be run instead of plan. +skip_all () { + tap_desc="$1" + if [ -n "$tap_desc" ] ; then + echo "1..0 # skip $tap_desc" + else + echo "1..0 # skip" + fi + exit 0 +} + +# ok takes a test description and a command to run and prints success if that +# command is successful, false otherwise. The count starts at 1 and is +# updated each time ok is printed. +ok () { + tap_desc="$1" + if [ -n "$tap_desc" ] ; then + tap_desc=" - $tap_desc" + fi + shift + if "$@" ; then + echo ok "$count$tap_desc" + else + echo not ok "$count$tap_desc" + failed=`expr $failed + 1` + fi + count=`expr $count + 1` +} + +# Skip the next test. Takes the reason why the test is skipped. +skip () { + echo "ok $count # skip $*" + count=`expr $count + 1` +} + +# Report the same status on a whole set of tests. Takes the count of tests, +# the description, and then the command to run to determine the status. +ok_block () { + tap_i=$count + tap_end=`expr $count + $1` + shift + while [ "$tap_i" -lt "$tap_end" ] ; do + ok "$@" + tap_i=`expr $tap_i + 1` + done +} + +# Skip a whole set of tests. Takes the count and then the reason for skipping +# the test. +skip_block () { + tap_i=$count + tap_end=`expr $count + $1` + shift + while [ "$tap_i" -lt "$tap_end" ] ; do + skip "$@" + tap_i=`expr $tap_i + 1` + done +} + +# Portable variant of printf '%s\n' "$*". In the majority of cases, this +# function is slower than printf, because the latter is often implemented +# as a builtin command. The value of the variable IFS is ignored. +# +# This macro must not be called via backticks inside double quotes, since this +# will result in bizarre escaping behavior and lots of extra backslashes on +# Solaris. +puts () { + cat << EOH +$@ +EOH +} + +# Run a program expected to succeed, and print ok if it does and produces the +# correct output. Takes the description, expected exit status, the expected +# output, the command to run, and then any arguments for that command. +# Standard output and standard error are combined when analyzing the output of +# the command. +# +# If the command may contain system-specific error messages in its output, +# add strip_colon_error before the command to post-process its output. +ok_program () { + tap_desc="$1" + shift + tap_w_status="$1" + shift + tap_w_output="$1" + shift + tap_output=`"$@" 2>&1` + tap_status=$? + if [ $tap_status = $tap_w_status ] \ + && [ x"$tap_output" = x"$tap_w_output" ] ; then + ok "$tap_desc" true + else + echo "# saw: ($tap_status) $tap_output" + echo "# not: ($tap_w_status) $tap_w_output" + ok "$tap_desc" false + fi +} + +# Strip a colon and everything after it off the output of a command, as long +# as that colon comes after at least one whitespace character. (This is done +# to avoid stripping the name of the program from the start of an error +# message.) This is used to remove system-specific error messages (coming +# from strerror, for example). +strip_colon_error() { + tap_output=`"$@" 2>&1` + tap_status=$? + tap_output=`puts "$tap_output" | sed 's/^\([^ ]* [^:]*\):.*/\1/'` + puts "$tap_output" + return $tap_status +} + +# Bail out with an error message. +bail () { + echo 'Bail out!' "$@" + exit 255 +} + +# Output a diagnostic on standard error, preceded by the required # mark. +diag () { + echo '#' "$@" +} + +# Search for the given file first in $BUILD and then in $SOURCE and echo the +# path where the file was found, or the empty string if the file wasn't +# found. +# +# This macro uses puts, so don't run it using backticks inside double quotes +# or bizarre quoting behavior will happen with Solaris sh. +test_file_path () { + if [ -n "$BUILD" ] && [ -f "$BUILD/$1" ] ; then + puts "$BUILD/$1" + elif [ -n "$SOURCE" ] && [ -f "$SOURCE/$1" ] ; then + puts "$SOURCE/$1" + else + echo '' + fi +} + +# Create $BUILD/tmp for use by tests for storing temporary files and return +# the path (via standard output). +# +# This macro uses puts, so don't run it using backticks inside double quotes +# or bizarre quoting behavior will happen with Solaris sh. +test_tmpdir () { + if [ -z "$BUILD" ] ; then + tap_tmpdir="./tmp" + else + tap_tmpdir="$BUILD"/tmp + fi + if [ ! -d "$tap_tmpdir" ] ; then + mkdir "$tap_tmpdir" || bail "Error creating $tap_tmpdir" + fi + puts "$tap_tmpdir" +} diff --git a/tests/tap/macros.h b/tests/tap/macros.h new file mode 100644 index 0000000..31081a4 --- /dev/null +++ b/tests/tap/macros.h @@ -0,0 +1,85 @@ +/* + * Helpful macros for TAP header files. + * + * This is not, strictly speaking, related to TAP, but any TAP add-on is + * probably going to need these macros, so define them in one place so that + * everyone can pull them in. + * + * This file is part of C TAP Harness. The current version plus supporting + * documentation is at <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2008, 2012 Russ Allbery <rra@stanford.edu> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#pragma once + +/* + * __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7 + * could you use the __format__ form of the attributes, which is what we use + * (to avoid confusion with other macros), and only with gcc 2.96 can you use + * the attribute __malloc__. 2.96 is very old, so don't bother trying to get + * the other attributes to work with GCC versions between 2.7 and 2.96. + */ +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) +# define __attribute__(spec) /* empty */ +# endif +#endif + +/* + * We use __alloc_size__, but it was only available in fairly recent versions + * of GCC. Suppress warnings about the unknown attribute if GCC is too old. + * We know that we're GCC at this point, so we can use the GCC variadic macro + * extension, which will still work with versions of GCC too old to have C99 + * variadic macro support. + */ +#if !defined(__attribute__) && !defined(__alloc_size__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define __alloc_size__(spec, args...) /* empty */ +# endif +#endif + +/* + * LLVM and Clang pretend to be GCC but don't support all of the __attribute__ + * settings that GCC does. For them, suppress warnings about unknown + * attributes on declarations. This unfortunately will affect the entire + * compilation context, but there's no push and pop available. + */ +#if !defined(__attribute__) && (defined(__llvm__) || defined(__clang__)) +# pragma GCC diagnostic ignored "-Wattributes" +#endif + +/* Used for unused parameters to silence gcc warnings. */ +/* #define UNUSED __attribute__((__unused__)) */ + +/* + * BEGIN_DECLS is used at the beginning of declarations so that C++ + * compilers don't mangle their names. END_DECLS is used at the end. + */ +#undef BEGIN_DECLS +#undef END_DECLS +#ifdef __cplusplus +# define BEGIN_DECLS extern "C" { +# define END_DECLS } +#else +# define BEGIN_DECLS /* empty */ +# define END_DECLS /* empty */ +#endif diff --git a/tests/tap/runtests.c b/tests/tap/runtests.c new file mode 100644 index 0000000..bd9d106 --- /dev/null +++ b/tests/tap/runtests.c @@ -0,0 +1,1401 @@ +/* + * Run a set of tests, reporting results. + * + * Usage: + * + * runtests [-b <build-dir>] [-s <source-dir>] <test-list> + * runtests -o [-b <build-dir>] [-s <source-dir>] <test> + * + * In the first case, expects a list of executables located in the given file, + * one line per executable. For each one, runs it as part of a test suite, + * reporting results. Test output should start with a line containing the + * number of tests (numbered from 1 to this number), optionally preceded by + * "1..", although that line may be given anywhere in the output. Each + * additional line should be in the following format: + * + * ok <number> + * not ok <number> + * ok <number> # skip + * not ok <number> # todo + * + * where <number> is the number of the test. An optional comment is permitted + * after the number if preceded by whitespace. ok indicates success, not ok + * indicates failure. "# skip" and "# todo" are a special cases of a comment, + * and must start with exactly that formatting. They indicate the test was + * skipped for some reason (maybe because it doesn't apply to this platform) + * or is testing something known to currently fail. The text following either + * "# skip" or "# todo" and whitespace is the reason. + * + * As a special case, the first line of the output may be in the form: + * + * 1..0 # skip some reason + * + * which indicates that this entire test case should be skipped and gives a + * reason. + * + * Any other lines are ignored, although for compliance with the TAP protocol + * all lines other than the ones in the above format should be sent to + * standard error rather than standard output and start with #. + * + * This is a subset of TAP as documented in Test::Harness::TAP or + * TAP::Parser::Grammar, which comes with Perl. + * + * If the -o option is given, instead run a single test and display all of its + * output. This is intended for use with failing tests so that the person + * running the test suite can get more details about what failed. + * + * If built with the C preprocessor symbols SOURCE and BUILD defined, C TAP + * Harness will export those values in the environment so that tests can find + * the source and build directory and will look for tests under both + * directories. These paths can also be set with the -b and -s command-line + * options, which will override anything set at build time. + * + * Any bug reports, bug fixes, and improvements are very much welcome and + * should be sent to the e-mail address below. This program is part of C TAP + * Harness <http://www.eyrie.org/~eagle/software/c-tap-harness/>. + * + * Copyright 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010, 2011 + * Russ Allbery <rra@stanford.edu> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. +*/ + +/* Required for fdopen(), getopt(), and putenv(). */ +#if defined(__STRICT_ANSI__) || defined(PEDANTIC) +# ifndef _XOPEN_SOURCE +# define _XOPEN_SOURCE 500 +# endif +#endif + +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <time.h> +#include <unistd.h> + +/* sys/time.h must be included before sys/resource.h on some platforms. */ +#include <sys/resource.h> + +/* AIX doesn't have WCOREDUMP. */ +#ifndef WCOREDUMP +# define WCOREDUMP(status) ((unsigned)(status) & 0x80) +#endif + +/* + * Used for iterating through arrays. Returns the number of elements in the + * array (useful for a < upper bound in a for loop). + */ +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + +/* + * The source and build versions of the tests directory. This is used to set + * the SOURCE and BUILD environment variables and find test programs, if set. + * Normally, this should be set as part of the build process to the test + * subdirectories of $(abs_top_srcdir) and $(abs_top_builddir) respectively. + */ +#ifndef SOURCE +# define SOURCE NULL +#endif +#ifndef BUILD +# define BUILD NULL +#endif + +/* Test status codes. */ +enum test_status { + TEST_FAIL, + TEST_PASS, + TEST_SKIP, + TEST_INVALID +}; + +/* Indicates the state of our plan. */ +enum plan_status { + PLAN_INIT, /* Nothing seen yet. */ + PLAN_FIRST, /* Plan seen before any tests. */ + PLAN_PENDING, /* Test seen and no plan yet. */ + PLAN_FINAL /* Plan seen after some tests. */ +}; + +/* Error exit statuses for test processes. */ +#define CHILDERR_DUP 100 /* Couldn't redirect stderr or stdout. */ +#define CHILDERR_EXEC 101 /* Couldn't exec child process. */ +#define CHILDERR_STDERR 102 /* Couldn't open stderr file. */ + +/* Structure to hold data for a set of tests. */ +struct testset { + char *file; /* The file name of the test. */ + char *path; /* The path to the test program. */ + enum plan_status plan; /* The status of our plan. */ + unsigned long count; /* Expected count of tests. */ + unsigned long current; /* The last seen test number. */ + unsigned int length; /* The length of the last status message. */ + unsigned long passed; /* Count of passing tests. */ + unsigned long failed; /* Count of failing lists. */ + unsigned long skipped; /* Count of skipped tests (passed). */ + unsigned long allocated; /* The size of the results table. */ + enum test_status *results; /* Table of results by test number. */ + unsigned int aborted; /* Whether the set was aborted. */ + unsigned int killed; /* Whether the set was killed. */ + int reported; /* Whether the results were reported. */ + int status; /* The exit status of the test. */ + unsigned int all_skipped; /* Whether all tests were skipped. */ + char *reason; /* Why all tests were skipped. */ +}; + +/* Structure to hold a linked list of test sets. */ +struct testlist { + struct testset *ts; + struct testlist *next; +}; + +/* + * Usage message. Should be used as a printf format with four arguments: the + * path to runtests, given three times, and the usage_description. This is + * split into variables to satisfy the pedantic ISO C90 limit on strings. + */ +static const char usage_message[] = "\ +Usage: %s [-b <build-dir>] [-s <source-dir>] <test> ...\n\ + %s [-b <build-dir>] [-s <source-dir>] -l <test-list> -L <log-file>\n\ + %s -o [-b <build-dir>] [-s <source-dir>] <test>\n\ +\n%s"; +static const char usage_extra[] = "\ +Options:\n\ + -b <build-dir> Set the build directory to <build-dir>\n\ + -l <list> Take the list of tests to run from <test-list>\n\ + -o Run a single test rather than a list of tests\n\ + -s <source-dir> Set the source directory to <source-dir>\n\ + -L <log-file> Set log file for a list of tests\n\ +\n\ +runtests normally runs each test listed on the command line. With the -l\n\ +option, it instead runs every test listed in a file. With the -o option,\n\ +it instead runs a single test and shows its complete output.\n"; + +/* + * Header used for test output. %s is replaced by the file name of the list + * of tests. + */ +static const char banner[] = "\n\ +Running all tests listed in %s. If any tests fail, run the failing\n\ +test program with runtests -o to see more details.\n\n"; + +/* Header for reports of failed tests. */ +static const char header[] = "\n\ +Failed Set Fail/Total (%) Skip Stat Failing Tests\n\ +-------------------------- -------------- ---- ---- ------------------------"; + +/* Include the file name and line number in malloc failures. */ +#define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__) +#define xmalloc(size) x_malloc((size), __FILE__, __LINE__) +#define xrealloc(p, size) x_realloc((p), (size), __FILE__, __LINE__) +#define xstrdup(p) x_strdup((p), __FILE__, __LINE__) + +/* + * __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7 + * could you use the __format__ form of the attributes, which is what we use + * (to avoid confusion with other macros). + */ +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __attribute__(spec) /* empty */ +# endif +#endif + +/* + * We use __alloc_size__, but it was only available in fairly recent versions + * of GCC. Suppress warnings about the unknown attribute if GCC is too old. + * We know that we're GCC at this point, so we can use the GCC variadic macro + * extension, which will still work with versions of GCC too old to have C99 + * variadic macro support. + */ +#if !defined(__attribute__) && !defined(__alloc_size__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define __alloc_size__(spec, args...) /* empty */ +# endif +#endif + +/* + * LLVM and Clang pretend to be GCC but don't support all of the __attribute__ + * settings that GCC does. For them, suppress warnings about unknown + * attributes on declarations. This unfortunately will affect the entire + * compilation context, but there's no push and pop available. + */ +#if !defined(__attribute__) && (defined(__llvm__) || defined(__clang__)) +# pragma GCC diagnostic ignored "-Wattributes" +#endif + +/* Declare internal functions that benefit from compiler attributes. */ +static void sysdie(const char *, ...) + __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2))); +static void *x_calloc(size_t, size_t, const char *, int) + __attribute__((__alloc_size__(1, 2), __malloc__, __nonnull__)); +static void *x_malloc(size_t, const char *, int) + __attribute__((__alloc_size__(1), __malloc__, __nonnull__)); +static void *x_realloc(void *, size_t, const char *, int) + __attribute__((__alloc_size__(2), __malloc__, __nonnull__(3))); +static char *x_strdup(const char *, const char *, int) + __attribute__((__malloc__, __nonnull__)); + +/* + * Report a fatal error, including the results of strerror, and exit. + */ +static void +sysdie(const char *format, ...) +{ + int oerrno; + va_list args; + + oerrno = errno; + fflush(stdout); + fprintf(stderr, "runtests: "); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, ": %s\n", strerror(oerrno)); + exit(1); +} + +/* + * Allocate zeroed memory, reporting a fatal error and exiting on failure. + */ +static void * +x_calloc(size_t n, size_t size, const char *file, int line) +{ + void *p; + + n = (n > 0) ? n : 1; + size = (size > 0) ? size : 1; + p = calloc(n, size); + if (p == NULL) + sysdie("failed to calloc %lu bytes at %s line %d", + (unsigned long) size, file, line); + return p; +} + +/* + * Allocate memory, reporting a fatal error and exiting on failure. + */ +static void * +x_malloc(size_t size, const char *file, int line) +{ + void *p; + + p = malloc(size); + if (p == NULL) + sysdie("failed to malloc %lu bytes at %s line %d", + (unsigned long) size, file, line); + return p; +} + +/* + * Reallocate memory, reporting a fatal error and exiting on failure. + */ +static void * +x_realloc(void *p, size_t size, const char *file, int line) +{ + p = realloc(p, size); + if (p == NULL) + sysdie("failed to realloc %lu bytes at %s line %d", + (unsigned long) size, file, line); + return p; +} + +/* + * Copy a string, reporting a fatal error and exiting on failure. + */ +static char * +x_strdup(const char *s, const char *file, int line) +{ + char *p; + size_t len; + + len = strlen(s) + 1; + p = malloc(len); + if (p == NULL) + sysdie("failed to strdup %lu bytes at %s line %d", + (unsigned long) len, file, line); + memcpy(p, s, len); + return p; +} + +/* + * Given a struct timeval, return the number of seconds it represents as a + * double. Use difftime() to convert a time_t to a double. + */ +static double +tv_seconds(const struct timeval *tv) +{ + return difftime(tv->tv_sec, 0) + tv->tv_usec * 1e-6; +} + +/* + * Given two struct timevals, return the difference in seconds. + */ +static double +tv_diff(const struct timeval *tv1, const struct timeval *tv0) +{ + return tv_seconds(tv1) - tv_seconds(tv0); +} + +/* + * Given two struct timevals, return the sum in seconds as a double. + */ +static double +tv_sum(const struct timeval *tv1, const struct timeval *tv2) +{ + return tv_seconds(tv1) + tv_seconds(tv2); +} + +/* + * Given a pointer to a string, skip any leading whitespace and return a + * pointer to the first non-whitespace character. + */ +static const char * +skip_whitespace(const char *p) +{ + while (isspace((unsigned char)(*p))) + p++; + return p; +} + +/* + * Start a program, connecting its output (stdout and stderr) to a pipe on our + * end, and storing the file descriptor to read from in the second argument. + * Returns the PID of the new process. Errors are fatal. + */ +static pid_t +test_start(const char *path, int *fd) +{ + int fds[2]; + pid_t child; + + if (pipe(fds) == -1) { + puts("ABORTED"); + fflush(stdout); + sysdie("can't create pipe"); + } + child = fork(); + if (child == (pid_t) -1) { + puts("ABORTED"); + fflush(stdout); + sysdie("can't fork"); + } else if (child == 0) { + /* In child. Set up our stdout and stderr. */ + close(fds[0]); + if (dup2(fds[1], STDOUT_FILENO) == -1) + _exit(CHILDERR_DUP); + if (dup2(fds[1], STDERR_FILENO) == -1) + _exit(CHILDERR_DUP); + + /* Now, exec our process. */ + if (execl(path, path, (char *) 0) == -1) + _exit(CHILDERR_EXEC); + } else { + /* In parent. Close the extra file descriptor. */ + close(fds[1]); + } + *fd = fds[0]; + return child; +} + +/* + * Back up over the output saying what test we were executing. + */ +static void +test_backspace(struct testset *ts) +{ + unsigned int i; + + if (!isatty(STDOUT_FILENO)) + return; + for (i = 0; i < ts->length; i++) + putchar('\b'); + for (i = 0; i < ts->length; i++) + putchar(' '); + for (i = 0; i < ts->length; i++) + putchar('\b'); + ts->length = 0; +} + +/* + * Read the plan line of test output, which should contain the range of test + * numbers. We may initialize the testset structure here if we haven't yet + * seen a test. Return true if initialization succeeded and the test should + * continue, false otherwise. + */ +static int +test_plan(const char *line, struct testset *ts) +{ + unsigned long i; + long n; + + /* + * Accept a plan without the leading 1.. for compatibility with older + * versions of runtests. This will only be allowed if we've not yet seen + * a test result. + */ + line = skip_whitespace(line); + if (strncmp(line, "1..", 3) == 0) + line += 3; + + /* + * Get the count, check it for validity, and initialize the struct. If we + * have something of the form "1..0 # skip foo", the whole file was + * skipped; record that. If we do skip the whole file, zero out all of + * our statistics, since they're no longer relevant. strtol is called + * with a second argument to advance the line pointer past the count to + * make it simpler to detect the # skip case. + */ + n = strtol(line, (char **) &line, 10); + if (n == 0) { + line = skip_whitespace(line); + if (*line == '#') { + line = skip_whitespace(line + 1); + if (strncasecmp(line, "skip", 4) == 0) { + line = skip_whitespace(line + 4); + if (*line != '\0') { + ts->reason = xstrdup(line); + ts->reason[strlen(ts->reason) - 1] = '\0'; + } + ts->all_skipped = 1; + ts->aborted = 1; + ts->count = 0; + ts->passed = 0; + ts->skipped = 0; + ts->failed = 0; + ts->killed = 0; + return 0; + } + } + } + if (n <= 0) { + puts("ABORTED (invalid test count)"); + ts->aborted = 1; + ts->reported = 1; + return 0; + } + if (ts->plan == PLAN_INIT && ts->allocated == 0) { + ts->count = n; + ts->allocated = n; + ts->plan = PLAN_FIRST; + ts->results = xmalloc(ts->count * sizeof(enum test_status)); + for (i = 0; i < ts->count; i++) + ts->results[i] = TEST_INVALID; + } else if (ts->plan == PLAN_PENDING) { + if ((unsigned long) n < ts->count) { + test_backspace(ts); + printf("ABORTED (invalid test number %lu)\n", ts->count); + ts->aborted = 1; + ts->reported = 1; + return 0; + } + ts->count = n; + if ((unsigned long) n > ts->allocated) { + ts->results = xrealloc(ts->results, n * sizeof(enum test_status)); + for (i = ts->allocated; i < ts->count; i++) + ts->results[i] = TEST_INVALID; + ts->allocated = n; + } + ts->plan = PLAN_FINAL; + } + return 1; +} + +/* + * Given a single line of output from a test, parse it and return the success + * status of that test. Anything printed to stdout not matching the form + * /^(not )?ok \d+/ is ignored. Sets ts->current to the test number that just + * reported status. + */ +static void +test_checkline(const char *line, struct testset *ts) +{ + enum test_status status = TEST_PASS; + const char *bail; + char *end; + long number; + unsigned long i, current; + int outlen; + + /* Before anything, check for a test abort. */ + bail = strstr(line, "Bail out!"); + if (bail != NULL) { + bail = skip_whitespace(bail + strlen("Bail out!")); + if (*bail != '\0') { + size_t length; + + length = strlen(bail); + if (bail[length - 1] == '\n') + length--; + test_backspace(ts); + printf("ABORTED (%.*s)\n", (int) length, bail); + ts->reported = 1; + } + ts->aborted = 1; + return; + } + + /* + * If the given line isn't newline-terminated, it was too big for an + * fgets(), which means ignore it. + */ + if (line[strlen(line) - 1] != '\n') + return; + + /* If the line begins with a hash mark, ignore it. */ + if (line[0] == '#') + return; + + /* If we haven't yet seen a plan, look for one. */ + if (ts->plan == PLAN_INIT && isdigit((unsigned char)(*line))) { + if (!test_plan(line, ts)) + return; + } else if (strncmp(line, "1..", 3) == 0) { + if (ts->plan == PLAN_PENDING) { + if (!test_plan(line, ts)) + return; + } else { + test_backspace(ts); + puts("ABORTED (multiple plans)"); + ts->aborted = 1; + ts->reported = 1; + return; + } + } + + /* Parse the line, ignoring something we can't parse. */ + if (strncmp(line, "not ", 4) == 0) { + status = TEST_FAIL; + line += 4; + } + if (strncmp(line, "ok", 2) != 0) + return; + line = skip_whitespace(line + 2); + errno = 0; + number = strtol(line, &end, 10); + if (errno != 0 || end == line) + number = ts->current + 1; + current = number; + if (number <= 0 || (current > ts->count && ts->plan == PLAN_FIRST)) { + test_backspace(ts); + printf("ABORTED (invalid test number %lu)\n", current); + ts->aborted = 1; + ts->reported = 1; + return; + } + + /* We have a valid test result. Tweak the results array if needed. */ + if (ts->plan == PLAN_INIT || ts->plan == PLAN_PENDING) { + ts->plan = PLAN_PENDING; + if (current > ts->count) + ts->count = current; + if (current > ts->allocated) { + unsigned long n; + + n = (ts->allocated == 0) ? 32 : ts->allocated * 2; + if (n < current) + n = current; + ts->results = xrealloc(ts->results, n * sizeof(enum test_status)); + for (i = ts->allocated; i < n; i++) + ts->results[i] = TEST_INVALID; + ts->allocated = n; + } + } + + /* + * Handle directives. We should probably do something more interesting + * with unexpected passes of todo tests. + */ + while (isdigit((unsigned char)(*line))) + line++; + line = skip_whitespace(line); + if (*line == '#') { + line = skip_whitespace(line + 1); + if (strncasecmp(line, "skip", 4) == 0) + status = TEST_SKIP; + if (strncasecmp(line, "todo", 4) == 0) + status = (status == TEST_FAIL) ? TEST_SKIP : TEST_FAIL; + } + + /* Make sure that the test number is in range and not a duplicate. */ + if (ts->results[current - 1] != TEST_INVALID) { + test_backspace(ts); + printf("ABORTED (duplicate test number %lu)\n", current); + ts->aborted = 1; + ts->reported = 1; + return; + } + + /* Good results. Increment our various counters. */ + switch (status) { + case TEST_PASS: ts->passed++; break; + case TEST_FAIL: ts->failed++; break; + case TEST_SKIP: ts->skipped++; break; + case TEST_INVALID: break; + } + ts->current = current; + ts->results[current - 1] = status; + if (isatty(STDOUT_FILENO)) { + test_backspace(ts); + if (ts->plan == PLAN_PENDING) + outlen = printf("%lu/?", current); + else + outlen = printf("%lu/%lu", current, ts->count); + ts->length = (outlen >= 0) ? outlen : 0; + fflush(stdout); + } +} + +/* + * Print out a range of test numbers, returning the number of characters it + * took up. Takes the first number, the last number, the number of characters + * already printed on the line, and the limit of number of characters the line + * can hold. Add a comma and a space before the range if chars indicates that + * something has already been printed on the line, and print ... instead if + * chars plus the space needed would go over the limit (use a limit of 0 to + * disable this). + */ +static unsigned int +test_print_range(unsigned long first, unsigned long last, unsigned int chars, + unsigned int limit) +{ + unsigned int needed = 0; + unsigned long n; + + for (n = first; n > 0; n /= 10) + needed++; + if (last > first) { + for (n = last; n > 0; n /= 10) + needed++; + needed++; + } + if (chars > 0) + needed += 2; + if (limit > 0 && chars + needed > limit) { + needed = 0; + if (chars <= limit) { + if (chars > 0) { + printf(", "); + needed += 2; + } + printf("..."); + needed += 3; + } + } else { + if (chars > 0) + printf(", "); + if (last > first) + printf("%lu-", first); + printf("%lu", last); + } + return needed; +} + +/* + * Summarize a single test set. The second argument is 0 if the set exited + * cleanly, a positive integer representing the exit status if it exited + * with a non-zero status, and a negative integer representing the signal + * that terminated it if it was killed by a signal. + */ +static void +test_summarize(struct testset *ts, int status) +{ + unsigned long i; + unsigned long missing = 0; + unsigned long failed = 0; + unsigned long first = 0; + unsigned long last = 0; + + if (ts->aborted) { + fputs("ABORTED", stdout); + if (ts->count > 0) + printf(" (passed %lu/%lu)", ts->passed, ts->count - ts->skipped); + } else { + for (i = 0; i < ts->count; i++) { + if (ts->results[i] == TEST_INVALID) { + if (missing == 0) + fputs("MISSED ", stdout); + if (first && i == last) + last = i + 1; + else { + if (first) + test_print_range(first, last, missing - 1, 0); + missing++; + first = i + 1; + last = i + 1; + } + } + } + if (first) + test_print_range(first, last, missing - 1, 0); + first = 0; + last = 0; + for (i = 0; i < ts->count; i++) { + if (ts->results[i] == TEST_FAIL) { + if (missing && !failed) + fputs("; ", stdout); + if (failed == 0) + fputs("FAILED ", stdout); + if (first && i == last) + last = i + 1; + else { + if (first) + test_print_range(first, last, failed - 1, 0); + failed++; + first = i + 1; + last = i + 1; + } + } + } + if (first) + test_print_range(first, last, failed - 1, 0); + if (!missing && !failed) { + fputs(!status ? "ok" : "dubious", stdout); + if (ts->skipped > 0) { + if (ts->skipped == 1) + printf(" (skipped %lu test)", ts->skipped); + else + printf(" (skipped %lu tests)", ts->skipped); + } + } + } + if (status > 0) + printf(" (exit status %d)", status); + else if (status < 0) + printf(" (killed by signal %d%s)", -status, + WCOREDUMP(ts->status) ? ", core dumped" : ""); + putchar('\n'); +} + +/* + * Given a test set, analyze the results, classify the exit status, handle a + * few special error messages, and then pass it along to test_summarize() for + * the regular output. Returns true if the test set ran successfully and all + * tests passed or were skipped, false otherwise. + */ +static int +test_analyze(struct testset *ts) +{ + if (ts->reported) + return 0; + if (ts->all_skipped) { + if (ts->reason == NULL) + puts("skipped"); + else + printf("skipped (%s)\n", ts->reason); + return 1; + } else if (WIFEXITED(ts->status) && WEXITSTATUS(ts->status) != 0) { + switch (WEXITSTATUS(ts->status)) { + case CHILDERR_DUP: + if (!ts->reported) + puts("ABORTED (can't dup file descriptors)"); + break; + case CHILDERR_EXEC: + if (!ts->reported) + puts("ABORTED (execution failed -- not found?)"); + break; + case CHILDERR_STDERR: + if (!ts->reported) + puts("ABORTED (can't open /dev/null)"); + break; + default: + test_summarize(ts, WEXITSTATUS(ts->status)); + break; + } + return 0; + } else if (WIFSIGNALED(ts->status)) { + test_summarize(ts, -WTERMSIG(ts->status)); + ts->killed = 1; + return 0; + } else if (ts->plan != PLAN_FIRST && ts->plan != PLAN_FINAL) { + puts("ABORTED (no valid test plan)"); + ts->aborted = 1; + return 0; + } else { + test_summarize(ts, 0); + return (ts->failed == 0); + } +} + +static void +cond_fputs(const char *buffer, FILE *stream) +{ + if (!stream) { + return; + } + + fputs(buffer, stream); +} + +/* + * Runs a single test set, accumulating and then reporting the results. + * Returns true if the test set was successfully run and all tests passed, + * false otherwise. + */ +static int +test_run(struct testset *ts, FILE *logfile) +{ + pid_t testpid, child; + int outfd, status; + unsigned long i; + FILE *output; + char buffer[BUFSIZ]; + + /* Run the test program. */ + testpid = test_start(ts->path, &outfd); + output = fdopen(outfd, "r"); + if (!output) { + puts("ABORTED"); + fflush(stdout); + sysdie("fdopen failed"); + } + + /* Pass each line of output to test_checkline(). */ + while (!ts->aborted && fgets(buffer, sizeof(buffer), output)) { + cond_fputs(buffer, logfile); + test_checkline(buffer, ts); + } + if (ferror(output) || ts->plan == PLAN_INIT) + ts->aborted = 1; + test_backspace(ts); + + /* + * Consume the rest of the test output, close the output descriptor, + * retrieve the exit status, and pass that information to test_analyze() + * for eventual output. + */ + while (fgets(buffer, sizeof(buffer), output)) + ; + fclose(output); + child = waitpid(testpid, &ts->status, 0); + if (child == (pid_t) -1) { + if (!ts->reported) { + puts("ABORTED"); + fflush(stdout); + } + sysdie("waitpid for %u failed", (unsigned int) testpid); + } + if (ts->all_skipped) + ts->aborted = 0; + if (WEXITSTATUS(ts->status) > 0) + ts->failed++; + status = test_analyze(ts); + + /* Convert missing tests to failed tests. */ + for (i = 0; i < ts->count; i++) { + if (ts->results[i] == TEST_INVALID) { + ts->failed++; + ts->results[i] = TEST_FAIL; + status = 0; + } + } + return status; +} + +/* Summarize a list of test failures. */ +static void +test_fail_summary(const struct testlist *fails) +{ + struct testset *ts; + unsigned int chars; + unsigned long i, first, last, total; + + puts(header); + + /* Failed Set Fail/Total (%) Skip Stat Failing (25) + -------------------------- -------------- ---- ---- -------------- */ + for (; fails; fails = fails->next) { + ts = fails->ts; + total = ts->count - ts->skipped; + printf("%-26.26s %4lu/%-4lu %3.0f%% %4lu ", ts->file, ts->failed, + total, total ? (ts->failed * 100.0) / total : 0, + ts->skipped); + if (WIFEXITED(ts->status)) { + printf("%4d ", WEXITSTATUS(ts->status)); + } else if (ts->killed) { + printf("KILL "); + } else { + printf(" -- "); + } + if (ts->aborted) { + puts("aborted"); + continue; + } + chars = 0; + first = 0; + last = 0; + for (i = 0; i < ts->count; i++) { + if (ts->results[i] == TEST_FAIL) { + if (first != 0 && i == last) + last = i + 1; + else { + if (first != 0) + chars += test_print_range(first, last, chars, 19); + first = i + 1; + last = i + 1; + } + } + } + if (first != 0) + test_print_range(first, last, chars, 19); + putchar('\n'); + } +} + +/* + * Check whether a given file path is a valid test. Currently, this checks + * whether it is executable and is a regular file. Returns true or false. + */ +static int +is_valid_test(const char *path) +{ + struct stat st; + + if (access(path, X_OK) < 0) + return 0; + if (stat(path, &st) < 0) + return 0; + if (!S_ISREG(st.st_mode)) + return 0; + return 1; +} + +/* + * Given the name of a test, a pointer to the testset struct, and the source + * and build directories, find the test. We try first relative to the current + * directory, then in the build directory (if not NULL), then in the source + * directory. In each of those directories, we first try a "-t" extension and + * then a ".t" extension. When we find an executable program, we return the + * path to that program. If none of those paths are executable, just fill in + * the name of the test as is. + * + * The caller is responsible for freeing the path member of the testset + * struct. + */ +static char * +find_test(const char *name, const char *source, const char *build) +{ + char *path; + const char *bases[3], *suffix, *base; + unsigned int i, j; + const char *suffixes[3] = { "-t", ".t", "" }; + + /* Possible base directories. */ + bases[0] = "."; + bases[1] = build; + bases[2] = source; + + /* Try each suffix with each base. */ + for (i = 0; i < ARRAY_SIZE(suffixes); i++) { + suffix = suffixes[i]; + for (j = 0; j < ARRAY_SIZE(bases); j++) { + unsigned int path_len; + + base = bases[j]; + if (base == NULL) + continue; + path_len = strlen(base) + strlen(name) + strlen(suffix) + 2; + path = xmalloc(path_len); + snprintf(path, path_len, "%s/%s%s", base, name, suffix); + if (is_valid_test(path)) + return path; + free(path); + path = NULL; + } + } + if (path == NULL) + path = xstrdup(name); + return path; +} + +/* + * Read a list of tests from a file, returning the list of tests as a struct + * testlist. Reports an error to standard error and exits if the list of + * tests cannot be read. + */ +static struct testlist * +read_test_list(const char *filename) +{ + FILE *file; + unsigned int line; + size_t length; + char buffer[BUFSIZ]; + struct testlist *listhead, *current; + + /* Create the initial container list that will hold our results. */ + listhead = xmalloc(sizeof(struct testlist)); + listhead->ts = NULL; + listhead->next = NULL; + current = NULL; + + /* + * Open our file of tests to run and read it line by line, creating a new + * struct testlist and struct testset for each line. + */ + file = fopen(filename, "r"); + if (file == NULL) + sysdie("can't open %s", filename); + line = 0; + while (fgets(buffer, sizeof(buffer), file)) { + line++; + length = strlen(buffer) - 1; + if (buffer[length] != '\n') { + fprintf(stderr, "%s:%u: line too long\n", filename, line); + exit(1); + } + buffer[length] = '\0'; + if (current == NULL) + current = listhead; + else { + current->next = xmalloc(sizeof(struct testlist)); + current = current->next; + current->next = NULL; + } + current->ts = xcalloc(1, sizeof(struct testset)); + current->ts->plan = PLAN_INIT; + current->ts->file = xstrdup(buffer); + current->ts->reason = NULL; + } + fclose(file); + + /* Return the results. */ + return listhead; +} + +/* + * Build a list of tests from command line arguments. Takes the argv and argc + * representing the command line arguments and returns a newly allocated test + * list. The caller is responsible for freeing. + */ +static struct testlist * +build_test_list(char *argv[], int argc) +{ + int i; + struct testlist *listhead, *current; + + /* Create the initial container list that will hold our results. */ + listhead = xmalloc(sizeof(struct testlist)); + listhead->ts = NULL; + listhead->next = NULL; + current = NULL; + + /* Walk the list of arguments and create test sets for them. */ + for (i = 0; i < argc; i++) { + if (current == NULL) + current = listhead; + else { + current->next = xmalloc(sizeof(struct testlist)); + current = current->next; + current->next = NULL; + } + current->ts = xcalloc(1, sizeof(struct testset)); + current->ts->plan = PLAN_INIT; + current->ts->file = xstrdup(argv[i]); + current->ts->reason = NULL; + } + + /* Return the results. */ + return listhead; +} + +/* Free a struct testset. */ +static void +free_testset(struct testset *ts) +{ + free(ts->file); + free(ts->path); + free(ts->results); + if (ts->reason != NULL) + free(ts->reason); + free(ts); +} + +/* + * Run a batch of tests. Takes two additional parameters: the root of the + * source directory and the root of the build directory. Test programs will + * be first searched for in the current directory, then the build directory, + * then the source directory. Returns true iff all tests passed, and always + * frees the test list that's passed in. + */ +static int +test_batch(struct testlist *tests, const char *source, const char *build, + const char *logfile_name) +{ + size_t length; + unsigned int i; + unsigned int longest = 0; + unsigned int count = 0; + struct testset *ts; + struct timeval start, end; + struct rusage stats; + struct testlist *failhead = NULL; + struct testlist *failtail = NULL; + struct testlist *current, *next; + int succeeded; + FILE *logfile = NULL; + unsigned long total = 0; + unsigned long passed = 0; + unsigned long skipped = 0; + unsigned long failed = 0; + unsigned long aborted = 0; + unsigned long killed = 0; + + /* Walk the list of tests to find the longest name. */ + for (current = tests; current != NULL; current = current->next) { + length = strlen(current->ts->file); + if (length > longest) + longest = length; + } + + /* + * Add two to longest and round up to the nearest tab stop. This is how + * wide the column for printing the current test name will be. + */ + longest += 2; + if (longest % 8) + longest += 8 - (longest % 8); + + /* Start the wall clock timer. */ + gettimeofday(&start, NULL); + + /* Open the log (soft error). */ + if (logfile_name != NULL) { + logfile = fopen(logfile_name, "w+"); + if (!logfile) { + fprintf(stderr, "Could not open the log file.\n"); + } + } + + /* Now, plow through our tests again, running each one. */ + for (current = tests; current != NULL; current = current->next) { + ts = current->ts; + + /* Print out the name of the test file. */ + fputs(ts->file, stdout); + for (i = strlen(ts->file); i < longest; i++) + putchar('.'); + if (isatty(STDOUT_FILENO)) + fflush(stdout); + + /* Run the test. */ + ts->path = find_test(ts->file, source, build); + succeeded = test_run(ts, logfile); + fflush(stdout); + + /* Record cumulative statistics. */ + aborted += ts->aborted; + total += ts->count + ts->all_skipped; + passed += ts->passed; + skipped += ts->skipped + ts->all_skipped; + failed += ts->failed; + killed += ts->killed; + count++; + + /* If the test fails, we shuffle it over to the fail list. */ + if (!succeeded) { + if (failhead == NULL) { + failhead = xmalloc(sizeof(struct testset)); + failtail = failhead; + } else { + failtail->next = xmalloc(sizeof(struct testset)); + failtail = failtail->next; + } + failtail->ts = ts; + failtail->next = NULL; + } + } + total -= skipped; + + /* Close the log. */ + if (logfile) { + fclose(logfile); + } + + /* Stop the timer and get our child resource statistics. */ + gettimeofday(&end, NULL); + getrusage(RUSAGE_CHILDREN, &stats); + + /* Summarize the failures and free the failure list. */ + if (failhead != NULL) { + test_fail_summary(failhead); + while (failhead != NULL) { + next = failhead->next; + free(failhead); + failhead = next; + } + } + + /* Free the memory used by the test lists. */ + while (tests != NULL) { + next = tests->next; + free_testset(tests->ts); + free(tests); + tests = next; + } + + /* Print out the final test summary. */ + putchar('\n'); + if (killed != 0) { + printf("Killed %lu test set%s, passed %lu/%lu tests", + killed, killed == 1 ? "" : "s", passed, total); + } else if (aborted != 0) { + if (aborted == 1) + printf("Aborted %lu test set", aborted); + else + printf("Aborted %lu test sets", aborted); + printf(", passed %lu/%lu tests", passed, total); + } + else if (failed == 0) + fputs("All tests successful", stdout); + else + printf("Failed %lu/%lu tests, %.2f%% okay", failed, total, + (total - failed) * 100.0 / total); + if (skipped != 0) { + if (skipped == 1) + printf(", %lu test skipped", skipped); + else + printf(", %lu tests skipped", skipped); + } + puts("."); + printf("Files=%u, Tests=%lu", count, total); + printf(", %.2f seconds", tv_diff(&end, &start)); + printf(" (%.2f usr + %.2f sys = %.2f CPU)\n", + tv_seconds(&stats.ru_utime), tv_seconds(&stats.ru_stime), + tv_sum(&stats.ru_utime, &stats.ru_stime)); + return (failed == 0 && aborted == 0 && killed == 0); +} + +/* + * Run a single test case. This involves just running the test program after + * having done the environment setup and finding the test program. + */ +static void +test_single(const char *program, const char *source, const char *build) +{ + char *path; + + path = find_test(program, source, build); + if (execl(path, path, (char *) 0) == -1) + sysdie("cannot exec %s", path); +} + +/* + * Main routine. Set the SOURCE and BUILD environment variables and then, + * given a file listing tests, run each test listed. + */ +int +main(int argc, char *argv[]) +{ + int option; + int status = 0; + int single = 0; + char *source_env = NULL; + char *build_env = NULL; + const char *shortlist; + const char *list = NULL; + const char *source = SOURCE; + const char *build = BUILD; + const char *logfile = NULL; + struct testlist *tests; + + while ((option = getopt(argc, argv, "b:hl:os:L:")) != EOF) { + switch (option) { + case 'b': + build = optarg; + break; + case 'h': + printf(usage_message, argv[0], argv[0], argv[0], usage_extra); + exit(0); + break; + case 'l': + list = optarg; + break; + case 'o': + single = 1; + break; + case 's': + source = optarg; + break; + case 'L': + logfile = optarg; + break; + default: + exit(1); + } + } + argv += optind; + argc -= optind; + if ((list == NULL && argc < 1) || (list != NULL && argc > 0)) { + fprintf(stderr, usage_message, argv[0], argv[0], argv[0], usage_extra); + exit(1); + } + + /* Set SOURCE and BUILD environment variables. */ + if (source != NULL) { + unsigned int len = strlen("SOURCE=") + strlen(source) + 1; + source_env = xmalloc(len); + snprintf(source_env, len, "SOURCE=%s", source); + if (putenv(source_env) != 0) + sysdie("cannot set SOURCE in the environment"); + } + if (build != NULL) { + unsigned int len = strlen("BUILD=") + strlen(build) + 1; + build_env = xmalloc(len); + snprintf(build_env, len, "BUILD=%s", build); + if (putenv(build_env) != 0) + sysdie("cannot set BUILD in the environment"); + } + + /* Run the tests as instructed. */ + if (single) + test_single(argv[0], source, build); + else if (list != NULL) { + shortlist = strrchr(list, '/'); + if (shortlist == NULL) + shortlist = list; + else + shortlist++; + printf(banner, shortlist); + tests = read_test_list(list); + status = test_batch(tests, source, build, logfile) ? 0 : 1; + } else { + tests = build_test_list(argv, argc); + status = test_batch(tests, source, build, logfile) ? 0 : 1; + } + + /* For valgrind cleanliness, free all our memory. */ + if (source_env != NULL) { + putenv((char *) "SOURCE="); + free(source_env); + } + if (build_env != NULL) { + putenv((char *) "BUILD="); + free(build_env); + } + exit(status); +} diff --git a/tests/utils/test_lookup.c b/tests/utils/test_lookup.c new file mode 100644 index 0000000..ddb0f9d --- /dev/null +++ b/tests/utils/test_lookup.c @@ -0,0 +1,136 @@ +/* Copyright (C) 2016 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 <https://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <tap/basic.h> + +#include "libknot/error.h" +#include "utils/common/lookup.h" + +static void check_search_ok(lookup_t *l, const char *in, const char *out) +{ + diag("Search for '%s'", in); + int ret = lookup_search(l, in, strlen(in)); + is_int(KNOT_EOK, ret, "Check found"); + ok(strcmp(out, l->found.key) == 0, "Compare key"); + ok(strcmp(out, l->found.data) == 0, "Compare data"); + ok(l->iter.first_key == NULL, "Compare no first key"); + ok(l->iter.count == 1, "Compare 1 count"); +} + +static void check_search_multi(lookup_t *l, const char *in, const char *out, + const char *first, size_t count) +{ + diag("Search for '%s'", in); + int ret = lookup_search(l, in, strlen(in)); + is_int(KNOT_EFEWDATA, ret, "Check found multi"); + ok(strcmp(out, l->found.key) == 0, "Compare key"); + ok(l->found.data == NULL, "Compare no data"); + ok(strcmp(first, l->iter.first_key) == 0, "Compare first key"); + ok(l->iter.count == count, "Compare count"); +} + +static void check_search_none(lookup_t *l, const char *in) +{ + diag("Search for '%s'", in); + int ret = lookup_search(l, in, strlen(in)); + is_int(KNOT_ENOENT, ret, "Check not found"); + ok(l->found.key == NULL, "Check no key"); + ok(l->found.data == NULL, "Check no data"); +} + +static void init(lookup_t *l, const char **table) +{ + int ret = lookup_init(l); + is_int(KNOT_EOK, ret, "Init"); + + while (*table != NULL) { + ret = lookup_insert(l, *table, (void *)*table); + is_int(KNOT_EOK, ret, "Insert '%s'", *table); + table++; + } +} + +static void test_search_basic(void) +{ + const char* table[] = { + "aa", + "bb", + NULL + }; + + lookup_t l; + init(&l, table); + + check_search_ok(&l, "a", "aa"); + check_search_ok(&l, "aa", "aa"); + check_search_ok(&l, "b", "bb"); + check_search_ok(&l, "bb", "bb"); + + check_search_none(&l, "0"); + check_search_none(&l, "000"); + check_search_none(&l, "00000000000000000000000000000000000000000000"); + check_search_none(&l, "a0"); + check_search_none(&l, "ab"); + check_search_none(&l, "aaa"); + check_search_none(&l, "bbb"); + check_search_none(&l, "cc"); + check_search_none(&l, "ccc"); + check_search_none(&l, "cccccccccccccccccccccccccccccccccccccccccccc"); + + check_search_multi(&l, "", "", "aa", 2); + + lookup_deinit(&l); +} + +static void test_search_iter(void) +{ + const char* table[] = { + "0", + "ab", + "abc", + "abcd", + "abc-1", + "abc-99", + "z", + NULL + }; + + lookup_t l; + init(&l, table); + + check_search_multi(&l, "", "", "0", 7); + check_search_multi(&l, "a", "ab", "ab", 5); + check_search_multi(&l, "ab", "ab", "ab", 5); + check_search_multi(&l, "abc", "abc", "abc", 4); + check_search_multi(&l, "abc-", "abc-", "abc-1", 2); + + lookup_deinit(&l); +} + +int main(int argc, char *argv[]) +{ + plan_lazy(); + + diag("Search tests basic"); + test_search_basic(); + + diag("Search tests multi-result"); + test_search_iter(); + + return 0; +} |