diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:15:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:15:43 +0000 |
commit | f5f56e1a1c4d9e9496fcb9d81131066a964ccd23 (patch) | |
tree | 49e44c6f87febed37efb953ab5485aa49f6481a7 /src/lib/dns/tests | |
parent | Initial commit. (diff) | |
download | isc-kea-f5f56e1a1c4d9e9496fcb9d81131066a964ccd23.tar.xz isc-kea-f5f56e1a1c4d9e9496fcb9d81131066a964ccd23.zip |
Adding upstream version 2.4.1.upstream/2.4.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/dns/tests')
467 files changed, 29469 insertions, 0 deletions
diff --git a/src/lib/dns/tests/Makefile.am b/src/lib/dns/tests/Makefile.am new file mode 100644 index 0000000..c89c3db --- /dev/null +++ b/src/lib/dns/tests/Makefile.am @@ -0,0 +1,94 @@ +SUBDIRS = testdata . + +AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib +AM_CPPFLAGS += $(BOOST_INCLUDES) +AM_CPPFLAGS += -DTEST_DATA_SRCDIR=\"$(abs_top_srcdir)/src/lib/dns/tests/testdata\" +AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/dns/tests/testdata\" +AM_CXXFLAGS = $(KEA_CXXFLAGS) + +if USE_STATIC_LINK +AM_LDFLAGS = -static +endif + +CLEANFILES = *.gcno *.gcda + +TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND) + +TESTS = +if HAVE_GTEST +TESTS += run_unittests +run_unittests_SOURCES = unittest_util.h unittest_util.cc +run_unittests_SOURCES += dns_exceptions_unittest.cc +run_unittests_SOURCES += edns_unittest.cc +run_unittests_SOURCES += master_lexer_inputsource_unittest.cc +run_unittests_SOURCES += labelsequence_unittest.cc +run_unittests_SOURCES += messagerenderer_unittest.cc +run_unittests_SOURCES += master_lexer_token_unittest.cc +run_unittests_SOURCES += master_lexer_unittest.cc +run_unittests_SOURCES += master_loader_unittest.cc +run_unittests_SOURCES += master_lexer_state_unittest.cc +run_unittests_SOURCES += name_unittest.cc +run_unittests_SOURCES += nsec3hash_unittest.cc +run_unittests_SOURCES += rrclass_unittest.cc rrtype_unittest.cc +run_unittests_SOURCES += rrttl_unittest.cc +run_unittests_SOURCES += rrcollator_unittest.cc +run_unittests_SOURCES += opcode_unittest.cc +run_unittests_SOURCES += rcode_unittest.cc +run_unittests_SOURCES += rdata_unittest.h rdata_unittest.cc +run_unittests_SOURCES += rdatafields_unittest.cc +run_unittests_SOURCES += rdata_pimpl_holder_unittest.cc +run_unittests_SOURCES += rdata_char_string_unittest.cc +run_unittests_SOURCES += rdata_char_string_data_unittest.cc +run_unittests_SOURCES += rdata_in_a_unittest.cc rdata_in_aaaa_unittest.cc +run_unittests_SOURCES += rdata_ns_unittest.cc rdata_soa_unittest.cc +run_unittests_SOURCES += rdata_txt_like_unittest.cc +run_unittests_SOURCES += rdata_mx_unittest.cc +run_unittests_SOURCES += rdata_sshfp_unittest.cc +run_unittests_SOURCES += rdata_ptr_unittest.cc rdata_cname_unittest.cc +run_unittests_SOURCES += rdata_dname_unittest.cc +run_unittests_SOURCES += rdata_afsdb_unittest.cc +run_unittests_SOURCES += rdata_opt_unittest.cc +run_unittests_SOURCES += rdata_dhcid_unittest.cc +run_unittests_SOURCES += rdata_dnskey_unittest.cc +run_unittests_SOURCES += rdata_ds_like_unittest.cc +run_unittests_SOURCES += rdata_nsec_unittest.cc +run_unittests_SOURCES += rdata_nsec3_unittest.cc +run_unittests_SOURCES += rdata_nsecbitmap_unittest.cc +run_unittests_SOURCES += rdata_nsec3param_unittest.cc +run_unittests_SOURCES += rdata_nsec3param_like_unittest.cc +run_unittests_SOURCES += rdata_rrsig_unittest.cc +run_unittests_SOURCES += rdata_rp_unittest.cc +run_unittests_SOURCES += rdata_srv_unittest.cc +run_unittests_SOURCES += rdata_tlsa_unittest.cc +run_unittests_SOURCES += rdata_minfo_unittest.cc +run_unittests_SOURCES += rdata_tsig_unittest.cc +run_unittests_SOURCES += rdata_naptr_unittest.cc +run_unittests_SOURCES += rdata_hinfo_unittest.cc +run_unittests_SOURCES += rdata_caa_unittest.cc +run_unittests_SOURCES += rdata_tkey_unittest.cc +run_unittests_SOURCES += rrset_unittest.cc +run_unittests_SOURCES += qid_gen_unittest.cc +run_unittests_SOURCES += question_unittest.cc +run_unittests_SOURCES += rrparamregistry_unittest.cc +run_unittests_SOURCES += masterload_unittest.cc +run_unittests_SOURCES += message_unittest.cc +run_unittests_SOURCES += serial_unittest.cc +run_unittests_SOURCES += tsig_unittest.cc +run_unittests_SOURCES += tsigerror_unittest.cc +run_unittests_SOURCES += tsigkey_unittest.cc +run_unittests_SOURCES += tsigrecord_unittest.cc +run_unittests_SOURCES += master_loader_callbacks_test.cc +run_unittests_SOURCES += rrset_collection_unittest.cc +run_unittests_SOURCES += zone_checker_unittest.cc +run_unittests_SOURCES += run_unittests.cc +run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) +run_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS) +run_unittests_LDADD = $(top_builddir)/src/lib/dns/libkea-dns++.la +run_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la +run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la +run_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la +run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la +run_unittests_LDADD += $(CRYPTO_LIBS) $(GTEST_LDADD) +endif + +noinst_PROGRAMS = $(TESTS) diff --git a/src/lib/dns/tests/Makefile.in b/src/lib/dns/tests/Makefile.in new file mode 100644 index 0000000..59bb00f --- /dev/null +++ b/src/lib/dns/tests/Makefile.in @@ -0,0 +1,2357 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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@ +TESTS = $(am__EXEEXT_1) +@HAVE_GTEST_TRUE@am__append_1 = run_unittests +noinst_PROGRAMS = $(am__EXEEXT_2) +subdir = src/lib/dns/tests +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4macros/ax_boost_for_kea.m4 \ + $(top_srcdir)/m4macros/ax_cpp11.m4 \ + $(top_srcdir)/m4macros/ax_cpp20.m4 \ + $(top_srcdir)/m4macros/ax_crypto.m4 \ + $(top_srcdir)/m4macros/ax_find_library.m4 \ + $(top_srcdir)/m4macros/ax_gssapi.m4 \ + $(top_srcdir)/m4macros/ax_gtest.m4 \ + $(top_srcdir)/m4macros/ax_isc_rpath.m4 \ + $(top_srcdir)/m4macros/ax_netconf.m4 \ + $(top_srcdir)/m4macros/libtool.m4 \ + $(top_srcdir)/m4macros/ltoptions.m4 \ + $(top_srcdir)/m4macros/ltsugar.m4 \ + $(top_srcdir)/m4macros/ltversion.m4 \ + $(top_srcdir)/m4macros/lt~obsolete.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)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +@HAVE_GTEST_TRUE@am__EXEEXT_1 = run_unittests$(EXEEXT) +am__EXEEXT_2 = $(am__EXEEXT_1) +PROGRAMS = $(noinst_PROGRAMS) +am__run_unittests_SOURCES_DIST = unittest_util.h unittest_util.cc \ + dns_exceptions_unittest.cc edns_unittest.cc \ + master_lexer_inputsource_unittest.cc labelsequence_unittest.cc \ + messagerenderer_unittest.cc master_lexer_token_unittest.cc \ + master_lexer_unittest.cc master_loader_unittest.cc \ + master_lexer_state_unittest.cc name_unittest.cc \ + nsec3hash_unittest.cc rrclass_unittest.cc rrtype_unittest.cc \ + rrttl_unittest.cc rrcollator_unittest.cc opcode_unittest.cc \ + rcode_unittest.cc rdata_unittest.h rdata_unittest.cc \ + rdatafields_unittest.cc rdata_pimpl_holder_unittest.cc \ + rdata_char_string_unittest.cc \ + rdata_char_string_data_unittest.cc rdata_in_a_unittest.cc \ + rdata_in_aaaa_unittest.cc rdata_ns_unittest.cc \ + rdata_soa_unittest.cc rdata_txt_like_unittest.cc \ + rdata_mx_unittest.cc rdata_sshfp_unittest.cc \ + rdata_ptr_unittest.cc rdata_cname_unittest.cc \ + rdata_dname_unittest.cc rdata_afsdb_unittest.cc \ + rdata_opt_unittest.cc rdata_dhcid_unittest.cc \ + rdata_dnskey_unittest.cc rdata_ds_like_unittest.cc \ + rdata_nsec_unittest.cc rdata_nsec3_unittest.cc \ + rdata_nsecbitmap_unittest.cc rdata_nsec3param_unittest.cc \ + rdata_nsec3param_like_unittest.cc rdata_rrsig_unittest.cc \ + rdata_rp_unittest.cc rdata_srv_unittest.cc \ + rdata_tlsa_unittest.cc rdata_minfo_unittest.cc \ + rdata_tsig_unittest.cc rdata_naptr_unittest.cc \ + rdata_hinfo_unittest.cc rdata_caa_unittest.cc \ + rdata_tkey_unittest.cc rrset_unittest.cc qid_gen_unittest.cc \ + question_unittest.cc rrparamregistry_unittest.cc \ + masterload_unittest.cc message_unittest.cc serial_unittest.cc \ + tsig_unittest.cc tsigerror_unittest.cc tsigkey_unittest.cc \ + tsigrecord_unittest.cc master_loader_callbacks_test.cc \ + rrset_collection_unittest.cc zone_checker_unittest.cc \ + run_unittests.cc +@HAVE_GTEST_TRUE@am_run_unittests_OBJECTS = \ +@HAVE_GTEST_TRUE@ run_unittests-unittest_util.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-dns_exceptions_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-edns_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-master_lexer_inputsource_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-labelsequence_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-messagerenderer_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-master_lexer_token_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-master_lexer_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-master_loader_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-master_lexer_state_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-name_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-nsec3hash_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rrclass_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rrtype_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rrttl_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rrcollator_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-opcode_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rcode_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdatafields_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_pimpl_holder_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_char_string_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_char_string_data_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_in_a_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_in_aaaa_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_ns_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_soa_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_txt_like_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_mx_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_sshfp_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_ptr_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_cname_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_dname_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_afsdb_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_opt_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_dhcid_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_dnskey_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_ds_like_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_nsec_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_nsec3_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_nsecbitmap_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_nsec3param_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_nsec3param_like_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_rrsig_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_rp_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_srv_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_tlsa_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_minfo_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_tsig_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_naptr_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_hinfo_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_caa_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rdata_tkey_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rrset_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-qid_gen_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-question_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rrparamregistry_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-masterload_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-message_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-serial_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-tsig_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-tsigerror_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-tsigkey_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-tsigrecord_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-master_loader_callbacks_test.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-rrset_collection_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-zone_checker_unittest.$(OBJEXT) \ +@HAVE_GTEST_TRUE@ run_unittests-run_unittests.$(OBJEXT) +run_unittests_OBJECTS = $(am_run_unittests_OBJECTS) +am__DEPENDENCIES_1 = +@HAVE_GTEST_TRUE@run_unittests_DEPENDENCIES = \ +@HAVE_GTEST_TRUE@ $(top_builddir)/src/lib/dns/libkea-dns++.la \ +@HAVE_GTEST_TRUE@ $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la \ +@HAVE_GTEST_TRUE@ $(top_builddir)/src/lib/util/unittests/libutil_unittests.la \ +@HAVE_GTEST_TRUE@ $(top_builddir)/src/lib/util/libkea-util.la \ +@HAVE_GTEST_TRUE@ $(top_builddir)/src/lib/exceptions/libkea-exceptions.la \ +@HAVE_GTEST_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +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 = +run_unittests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(run_unittests_LDFLAGS) $(LDFLAGS) \ + -o $@ +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) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = \ + ./$(DEPDIR)/run_unittests-dns_exceptions_unittest.Po \ + ./$(DEPDIR)/run_unittests-edns_unittest.Po \ + ./$(DEPDIR)/run_unittests-labelsequence_unittest.Po \ + ./$(DEPDIR)/run_unittests-master_lexer_inputsource_unittest.Po \ + ./$(DEPDIR)/run_unittests-master_lexer_state_unittest.Po \ + ./$(DEPDIR)/run_unittests-master_lexer_token_unittest.Po \ + ./$(DEPDIR)/run_unittests-master_lexer_unittest.Po \ + ./$(DEPDIR)/run_unittests-master_loader_callbacks_test.Po \ + ./$(DEPDIR)/run_unittests-master_loader_unittest.Po \ + ./$(DEPDIR)/run_unittests-masterload_unittest.Po \ + ./$(DEPDIR)/run_unittests-message_unittest.Po \ + ./$(DEPDIR)/run_unittests-messagerenderer_unittest.Po \ + ./$(DEPDIR)/run_unittests-name_unittest.Po \ + ./$(DEPDIR)/run_unittests-nsec3hash_unittest.Po \ + ./$(DEPDIR)/run_unittests-opcode_unittest.Po \ + ./$(DEPDIR)/run_unittests-qid_gen_unittest.Po \ + ./$(DEPDIR)/run_unittests-question_unittest.Po \ + ./$(DEPDIR)/run_unittests-rcode_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_afsdb_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_caa_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_char_string_data_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_char_string_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_cname_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_dhcid_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_dname_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_dnskey_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_ds_like_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_hinfo_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_in_a_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_in_aaaa_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_minfo_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_mx_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_naptr_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_ns_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_nsec3_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_nsec3param_like_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_nsec3param_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_nsec_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_nsecbitmap_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_opt_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_pimpl_holder_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_ptr_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_rp_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_rrsig_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_soa_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_srv_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_sshfp_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_tkey_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_tlsa_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_tsig_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_txt_like_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdata_unittest.Po \ + ./$(DEPDIR)/run_unittests-rdatafields_unittest.Po \ + ./$(DEPDIR)/run_unittests-rrclass_unittest.Po \ + ./$(DEPDIR)/run_unittests-rrcollator_unittest.Po \ + ./$(DEPDIR)/run_unittests-rrparamregistry_unittest.Po \ + ./$(DEPDIR)/run_unittests-rrset_collection_unittest.Po \ + ./$(DEPDIR)/run_unittests-rrset_unittest.Po \ + ./$(DEPDIR)/run_unittests-rrttl_unittest.Po \ + ./$(DEPDIR)/run_unittests-rrtype_unittest.Po \ + ./$(DEPDIR)/run_unittests-run_unittests.Po \ + ./$(DEPDIR)/run_unittests-serial_unittest.Po \ + ./$(DEPDIR)/run_unittests-tsig_unittest.Po \ + ./$(DEPDIR)/run_unittests-tsigerror_unittest.Po \ + ./$(DEPDIR)/run_unittests-tsigkey_unittest.Po \ + ./$(DEPDIR)/run_unittests-tsigrecord_unittest.Po \ + ./$(DEPDIR)/run_unittests-unittest_util.Po \ + ./$(DEPDIR)/run_unittests-zone_checker_unittest.Po +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +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 = $(run_unittests_SOURCES) +DIST_SOURCES = $(am__run_unittests_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +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)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ASCIIDOC = @ASCIIDOC@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BOOST_INCLUDES = @BOOST_INCLUDES@ +BOOST_LIBS = @BOOST_LIBS@ +BOTAN_TOOL = @BOTAN_TOOL@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONTRIB_DIR = @CONTRIB_DIR@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTO_CFLAGS = @CRYPTO_CFLAGS@ +CRYPTO_INCLUDES = @CRYPTO_INCLUDES@ +CRYPTO_LDFLAGS = @CRYPTO_LDFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ +CRYPTO_PACKAGE = @CRYPTO_PACKAGE@ +CRYPTO_RPATH = @CRYPTO_RPATH@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISTCHECK_BOOST_CONFIGURE_FLAG = @DISTCHECK_BOOST_CONFIGURE_FLAG@ +DISTCHECK_CONTRIB_CONFIGURE_FLAG = @DISTCHECK_CONTRIB_CONFIGURE_FLAG@ +DISTCHECK_CRYPTO_CONFIGURE_FLAG = @DISTCHECK_CRYPTO_CONFIGURE_FLAG@ +DISTCHECK_GSSAPI_CONFIGURE_FLAG = @DISTCHECK_GSSAPI_CONFIGURE_FLAG@ +DISTCHECK_GTEST_CONFIGURE_FLAG = @DISTCHECK_GTEST_CONFIGURE_FLAG@ +DISTCHECK_KEA_SHELL_CONFIGURE_FLAG = @DISTCHECK_KEA_SHELL_CONFIGURE_FLAG@ +DISTCHECK_LIBYANGCPP_CONFIGURE_FLAG = @DISTCHECK_LIBYANGCPP_CONFIGURE_FLAG@ +DISTCHECK_LIBYANG_CONFIGURE_FLAG = @DISTCHECK_LIBYANG_CONFIGURE_FLAG@ +DISTCHECK_LOG4CPLUS_CONFIGURE_FLAG = @DISTCHECK_LOG4CPLUS_CONFIGURE_FLAG@ +DISTCHECK_MYSQL_CONFIGURE_FLAG = @DISTCHECK_MYSQL_CONFIGURE_FLAG@ +DISTCHECK_PERFDHCP_CONFIGURE_FLAG = @DISTCHECK_PERFDHCP_CONFIGURE_FLAG@ +DISTCHECK_PGSQL_CONFIGURE_FLAG = @DISTCHECK_PGSQL_CONFIGURE_FLAG@ +DISTCHECK_PREMIUM_CONFIGURE_FLAG = @DISTCHECK_PREMIUM_CONFIGURE_FLAG@ +DISTCHECK_SYSREPOCPP_CONFIGURE_FLAG = @DISTCHECK_SYSREPOCPP_CONFIGURE_FLAG@ +DISTCHECK_SYSREPO_CONFIGURE_FLAG = @DISTCHECK_SYSREPO_CONFIGURE_FLAG@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GREP = @GREP@ +GSSAPI_CFLAGS = @GSSAPI_CFLAGS@ +GSSAPI_LIBS = @GSSAPI_LIBS@ +GTEST_CONFIG = @GTEST_CONFIG@ +GTEST_INCLUDES = @GTEST_INCLUDES@ +GTEST_LDADD = @GTEST_LDADD@ +GTEST_LDFLAGS = @GTEST_LDFLAGS@ +GTEST_SOURCE = @GTEST_SOURCE@ +HAVE_NETCONF = @HAVE_NETCONF@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KEA_CXXFLAGS = @KEA_CXXFLAGS@ +KEA_SRCID = @KEA_SRCID@ +KRB5_CONFIG = @KRB5_CONFIG@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBYANGCPP_CPPFLAGS = @LIBYANGCPP_CPPFLAGS@ +LIBYANGCPP_INCLUDEDIR = @LIBYANGCPP_INCLUDEDIR@ +LIBYANGCPP_LIBS = @LIBYANGCPP_LIBS@ +LIBYANGCPP_PREFIX = @LIBYANGCPP_PREFIX@ +LIBYANGCPP_VERSION = @LIBYANGCPP_VERSION@ +LIBYANG_CPPFLAGS = @LIBYANG_CPPFLAGS@ +LIBYANG_INCLUDEDIR = @LIBYANG_INCLUDEDIR@ +LIBYANG_LIBS = @LIBYANG_LIBS@ +LIBYANG_PREFIX = @LIBYANG_PREFIX@ +LIBYANG_VERSION = @LIBYANG_VERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOG4CPLUS_INCLUDES = @LOG4CPLUS_INCLUDES@ +LOG4CPLUS_LIBS = @LOG4CPLUS_LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +MYSQL_LIBS = @MYSQL_LIBS@ +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@ +PACKAGE_VERSION_TYPE = @PACKAGE_VERSION_TYPE@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PGSQL_CPPFLAGS = @PGSQL_CPPFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PKGPYTHONDIR = @PKGPYTHONDIR@ +PKG_CONFIG = @PKG_CONFIG@ +PLANTUML = @PLANTUML@ +PREMIUM_DIR = @PREMIUM_DIR@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SEP = @SEP@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINXBUILD = @SPHINXBUILD@ +SRPD_PLUGINS_PATH = @SRPD_PLUGINS_PATH@ +SR_PLUGINS_PATH = @SR_PLUGINS_PATH@ +SR_REPO_PATH = @SR_REPO_PATH@ +STRIP = @STRIP@ +SYSREPOCPP_CPPFLAGS = @SYSREPOCPP_CPPFLAGS@ +SYSREPOCPP_INCLUDEDIR = @SYSREPOCPP_INCLUDEDIR@ +SYSREPOCPP_LIBS = @SYSREPOCPP_LIBS@ +SYSREPOCPP_PREFIX = @SYSREPOCPP_PREFIX@ +SYSREPOCPP_VERSION = @SYSREPOCPP_VERSION@ +SYSREPO_CPPFLAGS = @SYSREPO_CPPFLAGS@ +SYSREPO_INCLUDEDIR = @SYSREPO_INCLUDEDIR@ +SYSREPO_LIBS = @SYSREPO_LIBS@ +SYSREPO_PREFIX = @SYSREPO_PREFIX@ +SYSREPO_VERSION = @SYSREPO_VERSION@ +USE_LCOV = @USE_LCOV@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARNING_GCC_44_STRICT_ALIASING_CFLAG = @WARNING_GCC_44_STRICT_ALIASING_CFLAG@ +YACC = @YACC@ +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_CXX = @ac_ct_CXX@ +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@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = testdata . +AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib \ + $(BOOST_INCLUDES) \ + -DTEST_DATA_SRCDIR=\"$(abs_top_srcdir)/src/lib/dns/tests/testdata\" \ + -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/dns/tests/testdata\" +AM_CXXFLAGS = $(KEA_CXXFLAGS) +@USE_STATIC_LINK_TRUE@AM_LDFLAGS = -static +CLEANFILES = *.gcno *.gcda +TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND) +@HAVE_GTEST_TRUE@run_unittests_SOURCES = unittest_util.h \ +@HAVE_GTEST_TRUE@ unittest_util.cc dns_exceptions_unittest.cc \ +@HAVE_GTEST_TRUE@ edns_unittest.cc \ +@HAVE_GTEST_TRUE@ master_lexer_inputsource_unittest.cc \ +@HAVE_GTEST_TRUE@ labelsequence_unittest.cc \ +@HAVE_GTEST_TRUE@ messagerenderer_unittest.cc \ +@HAVE_GTEST_TRUE@ master_lexer_token_unittest.cc \ +@HAVE_GTEST_TRUE@ master_lexer_unittest.cc \ +@HAVE_GTEST_TRUE@ master_loader_unittest.cc \ +@HAVE_GTEST_TRUE@ master_lexer_state_unittest.cc \ +@HAVE_GTEST_TRUE@ name_unittest.cc nsec3hash_unittest.cc \ +@HAVE_GTEST_TRUE@ rrclass_unittest.cc rrtype_unittest.cc \ +@HAVE_GTEST_TRUE@ rrttl_unittest.cc rrcollator_unittest.cc \ +@HAVE_GTEST_TRUE@ opcode_unittest.cc rcode_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_unittest.h rdata_unittest.cc \ +@HAVE_GTEST_TRUE@ rdatafields_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_pimpl_holder_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_char_string_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_char_string_data_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_in_a_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_in_aaaa_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_ns_unittest.cc rdata_soa_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_txt_like_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_mx_unittest.cc rdata_sshfp_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_ptr_unittest.cc rdata_cname_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_dname_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_afsdb_unittest.cc rdata_opt_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_dhcid_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_dnskey_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_ds_like_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_nsec_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_nsec3_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_nsecbitmap_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_nsec3param_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_nsec3param_like_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_rrsig_unittest.cc rdata_rp_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_srv_unittest.cc rdata_tlsa_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_minfo_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_tsig_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_naptr_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_hinfo_unittest.cc rdata_caa_unittest.cc \ +@HAVE_GTEST_TRUE@ rdata_tkey_unittest.cc rrset_unittest.cc \ +@HAVE_GTEST_TRUE@ qid_gen_unittest.cc question_unittest.cc \ +@HAVE_GTEST_TRUE@ rrparamregistry_unittest.cc \ +@HAVE_GTEST_TRUE@ masterload_unittest.cc message_unittest.cc \ +@HAVE_GTEST_TRUE@ serial_unittest.cc tsig_unittest.cc \ +@HAVE_GTEST_TRUE@ tsigerror_unittest.cc tsigkey_unittest.cc \ +@HAVE_GTEST_TRUE@ tsigrecord_unittest.cc \ +@HAVE_GTEST_TRUE@ master_loader_callbacks_test.cc \ +@HAVE_GTEST_TRUE@ rrset_collection_unittest.cc \ +@HAVE_GTEST_TRUE@ zone_checker_unittest.cc run_unittests.cc +@HAVE_GTEST_TRUE@run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) +@HAVE_GTEST_TRUE@run_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS) +@HAVE_GTEST_TRUE@run_unittests_LDADD = \ +@HAVE_GTEST_TRUE@ $(top_builddir)/src/lib/dns/libkea-dns++.la \ +@HAVE_GTEST_TRUE@ $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la \ +@HAVE_GTEST_TRUE@ $(top_builddir)/src/lib/util/unittests/libutil_unittests.la \ +@HAVE_GTEST_TRUE@ $(top_builddir)/src/lib/util/libkea-util.la \ +@HAVE_GTEST_TRUE@ $(top_builddir)/src/lib/exceptions/libkea-exceptions.la \ +@HAVE_GTEST_TRUE@ $(CRYPTO_LIBS) $(GTEST_LDADD) +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .cc .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 src/lib/dns/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/lib/dns/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-noinstPROGRAMS: + @list='$(noinst_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 + +run_unittests$(EXEEXT): $(run_unittests_OBJECTS) $(run_unittests_DEPENDENCIES) $(EXTRA_run_unittests_DEPENDENCIES) + @rm -f run_unittests$(EXEEXT) + $(AM_V_CXXLD)$(run_unittests_LINK) $(run_unittests_OBJECTS) $(run_unittests_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-dns_exceptions_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-edns_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-labelsequence_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-master_lexer_inputsource_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-master_lexer_state_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-master_lexer_token_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-master_lexer_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-master_loader_callbacks_test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-master_loader_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-masterload_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-message_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-messagerenderer_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-name_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-nsec3hash_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-opcode_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-qid_gen_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-question_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rcode_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_afsdb_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_caa_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_char_string_data_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_char_string_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_cname_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_dhcid_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_dname_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_dnskey_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_ds_like_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_hinfo_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_in_a_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_in_aaaa_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_minfo_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_mx_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_naptr_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_ns_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_nsec3_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_nsec3param_like_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_nsec3param_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_nsec_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_nsecbitmap_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_opt_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_pimpl_holder_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_ptr_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_rp_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_rrsig_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_soa_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_srv_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_sshfp_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_tkey_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_tlsa_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_tsig_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_txt_like_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdata_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rdatafields_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rrclass_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rrcollator_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rrparamregistry_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rrset_collection_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rrset_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rrttl_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-rrtype_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-run_unittests.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-serial_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-tsig_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-tsigerror_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-tsigkey_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-tsigrecord_unittest.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-unittest_util.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/run_unittests-zone_checker_unittest.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cc.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cc.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cc.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +run_unittests-unittest_util.o: unittest_util.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-unittest_util.o -MD -MP -MF $(DEPDIR)/run_unittests-unittest_util.Tpo -c -o run_unittests-unittest_util.o `test -f 'unittest_util.cc' || echo '$(srcdir)/'`unittest_util.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-unittest_util.Tpo $(DEPDIR)/run_unittests-unittest_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unittest_util.cc' object='run_unittests-unittest_util.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-unittest_util.o `test -f 'unittest_util.cc' || echo '$(srcdir)/'`unittest_util.cc + +run_unittests-unittest_util.obj: unittest_util.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-unittest_util.obj -MD -MP -MF $(DEPDIR)/run_unittests-unittest_util.Tpo -c -o run_unittests-unittest_util.obj `if test -f 'unittest_util.cc'; then $(CYGPATH_W) 'unittest_util.cc'; else $(CYGPATH_W) '$(srcdir)/unittest_util.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-unittest_util.Tpo $(DEPDIR)/run_unittests-unittest_util.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='unittest_util.cc' object='run_unittests-unittest_util.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-unittest_util.obj `if test -f 'unittest_util.cc'; then $(CYGPATH_W) 'unittest_util.cc'; else $(CYGPATH_W) '$(srcdir)/unittest_util.cc'; fi` + +run_unittests-dns_exceptions_unittest.o: dns_exceptions_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-dns_exceptions_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-dns_exceptions_unittest.Tpo -c -o run_unittests-dns_exceptions_unittest.o `test -f 'dns_exceptions_unittest.cc' || echo '$(srcdir)/'`dns_exceptions_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-dns_exceptions_unittest.Tpo $(DEPDIR)/run_unittests-dns_exceptions_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dns_exceptions_unittest.cc' object='run_unittests-dns_exceptions_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-dns_exceptions_unittest.o `test -f 'dns_exceptions_unittest.cc' || echo '$(srcdir)/'`dns_exceptions_unittest.cc + +run_unittests-dns_exceptions_unittest.obj: dns_exceptions_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-dns_exceptions_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-dns_exceptions_unittest.Tpo -c -o run_unittests-dns_exceptions_unittest.obj `if test -f 'dns_exceptions_unittest.cc'; then $(CYGPATH_W) 'dns_exceptions_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/dns_exceptions_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-dns_exceptions_unittest.Tpo $(DEPDIR)/run_unittests-dns_exceptions_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='dns_exceptions_unittest.cc' object='run_unittests-dns_exceptions_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-dns_exceptions_unittest.obj `if test -f 'dns_exceptions_unittest.cc'; then $(CYGPATH_W) 'dns_exceptions_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/dns_exceptions_unittest.cc'; fi` + +run_unittests-edns_unittest.o: edns_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-edns_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-edns_unittest.Tpo -c -o run_unittests-edns_unittest.o `test -f 'edns_unittest.cc' || echo '$(srcdir)/'`edns_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-edns_unittest.Tpo $(DEPDIR)/run_unittests-edns_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='edns_unittest.cc' object='run_unittests-edns_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-edns_unittest.o `test -f 'edns_unittest.cc' || echo '$(srcdir)/'`edns_unittest.cc + +run_unittests-edns_unittest.obj: edns_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-edns_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-edns_unittest.Tpo -c -o run_unittests-edns_unittest.obj `if test -f 'edns_unittest.cc'; then $(CYGPATH_W) 'edns_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/edns_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-edns_unittest.Tpo $(DEPDIR)/run_unittests-edns_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='edns_unittest.cc' object='run_unittests-edns_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-edns_unittest.obj `if test -f 'edns_unittest.cc'; then $(CYGPATH_W) 'edns_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/edns_unittest.cc'; fi` + +run_unittests-master_lexer_inputsource_unittest.o: master_lexer_inputsource_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_lexer_inputsource_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-master_lexer_inputsource_unittest.Tpo -c -o run_unittests-master_lexer_inputsource_unittest.o `test -f 'master_lexer_inputsource_unittest.cc' || echo '$(srcdir)/'`master_lexer_inputsource_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_lexer_inputsource_unittest.Tpo $(DEPDIR)/run_unittests-master_lexer_inputsource_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_lexer_inputsource_unittest.cc' object='run_unittests-master_lexer_inputsource_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_lexer_inputsource_unittest.o `test -f 'master_lexer_inputsource_unittest.cc' || echo '$(srcdir)/'`master_lexer_inputsource_unittest.cc + +run_unittests-master_lexer_inputsource_unittest.obj: master_lexer_inputsource_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_lexer_inputsource_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-master_lexer_inputsource_unittest.Tpo -c -o run_unittests-master_lexer_inputsource_unittest.obj `if test -f 'master_lexer_inputsource_unittest.cc'; then $(CYGPATH_W) 'master_lexer_inputsource_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/master_lexer_inputsource_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_lexer_inputsource_unittest.Tpo $(DEPDIR)/run_unittests-master_lexer_inputsource_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_lexer_inputsource_unittest.cc' object='run_unittests-master_lexer_inputsource_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_lexer_inputsource_unittest.obj `if test -f 'master_lexer_inputsource_unittest.cc'; then $(CYGPATH_W) 'master_lexer_inputsource_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/master_lexer_inputsource_unittest.cc'; fi` + +run_unittests-labelsequence_unittest.o: labelsequence_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-labelsequence_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-labelsequence_unittest.Tpo -c -o run_unittests-labelsequence_unittest.o `test -f 'labelsequence_unittest.cc' || echo '$(srcdir)/'`labelsequence_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-labelsequence_unittest.Tpo $(DEPDIR)/run_unittests-labelsequence_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='labelsequence_unittest.cc' object='run_unittests-labelsequence_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-labelsequence_unittest.o `test -f 'labelsequence_unittest.cc' || echo '$(srcdir)/'`labelsequence_unittest.cc + +run_unittests-labelsequence_unittest.obj: labelsequence_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-labelsequence_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-labelsequence_unittest.Tpo -c -o run_unittests-labelsequence_unittest.obj `if test -f 'labelsequence_unittest.cc'; then $(CYGPATH_W) 'labelsequence_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/labelsequence_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-labelsequence_unittest.Tpo $(DEPDIR)/run_unittests-labelsequence_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='labelsequence_unittest.cc' object='run_unittests-labelsequence_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-labelsequence_unittest.obj `if test -f 'labelsequence_unittest.cc'; then $(CYGPATH_W) 'labelsequence_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/labelsequence_unittest.cc'; fi` + +run_unittests-messagerenderer_unittest.o: messagerenderer_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-messagerenderer_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-messagerenderer_unittest.Tpo -c -o run_unittests-messagerenderer_unittest.o `test -f 'messagerenderer_unittest.cc' || echo '$(srcdir)/'`messagerenderer_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-messagerenderer_unittest.Tpo $(DEPDIR)/run_unittests-messagerenderer_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='messagerenderer_unittest.cc' object='run_unittests-messagerenderer_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-messagerenderer_unittest.o `test -f 'messagerenderer_unittest.cc' || echo '$(srcdir)/'`messagerenderer_unittest.cc + +run_unittests-messagerenderer_unittest.obj: messagerenderer_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-messagerenderer_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-messagerenderer_unittest.Tpo -c -o run_unittests-messagerenderer_unittest.obj `if test -f 'messagerenderer_unittest.cc'; then $(CYGPATH_W) 'messagerenderer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/messagerenderer_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-messagerenderer_unittest.Tpo $(DEPDIR)/run_unittests-messagerenderer_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='messagerenderer_unittest.cc' object='run_unittests-messagerenderer_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-messagerenderer_unittest.obj `if test -f 'messagerenderer_unittest.cc'; then $(CYGPATH_W) 'messagerenderer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/messagerenderer_unittest.cc'; fi` + +run_unittests-master_lexer_token_unittest.o: master_lexer_token_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_lexer_token_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-master_lexer_token_unittest.Tpo -c -o run_unittests-master_lexer_token_unittest.o `test -f 'master_lexer_token_unittest.cc' || echo '$(srcdir)/'`master_lexer_token_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_lexer_token_unittest.Tpo $(DEPDIR)/run_unittests-master_lexer_token_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_lexer_token_unittest.cc' object='run_unittests-master_lexer_token_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_lexer_token_unittest.o `test -f 'master_lexer_token_unittest.cc' || echo '$(srcdir)/'`master_lexer_token_unittest.cc + +run_unittests-master_lexer_token_unittest.obj: master_lexer_token_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_lexer_token_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-master_lexer_token_unittest.Tpo -c -o run_unittests-master_lexer_token_unittest.obj `if test -f 'master_lexer_token_unittest.cc'; then $(CYGPATH_W) 'master_lexer_token_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/master_lexer_token_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_lexer_token_unittest.Tpo $(DEPDIR)/run_unittests-master_lexer_token_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_lexer_token_unittest.cc' object='run_unittests-master_lexer_token_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_lexer_token_unittest.obj `if test -f 'master_lexer_token_unittest.cc'; then $(CYGPATH_W) 'master_lexer_token_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/master_lexer_token_unittest.cc'; fi` + +run_unittests-master_lexer_unittest.o: master_lexer_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_lexer_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-master_lexer_unittest.Tpo -c -o run_unittests-master_lexer_unittest.o `test -f 'master_lexer_unittest.cc' || echo '$(srcdir)/'`master_lexer_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_lexer_unittest.Tpo $(DEPDIR)/run_unittests-master_lexer_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_lexer_unittest.cc' object='run_unittests-master_lexer_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_lexer_unittest.o `test -f 'master_lexer_unittest.cc' || echo '$(srcdir)/'`master_lexer_unittest.cc + +run_unittests-master_lexer_unittest.obj: master_lexer_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_lexer_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-master_lexer_unittest.Tpo -c -o run_unittests-master_lexer_unittest.obj `if test -f 'master_lexer_unittest.cc'; then $(CYGPATH_W) 'master_lexer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/master_lexer_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_lexer_unittest.Tpo $(DEPDIR)/run_unittests-master_lexer_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_lexer_unittest.cc' object='run_unittests-master_lexer_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_lexer_unittest.obj `if test -f 'master_lexer_unittest.cc'; then $(CYGPATH_W) 'master_lexer_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/master_lexer_unittest.cc'; fi` + +run_unittests-master_loader_unittest.o: master_loader_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_loader_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-master_loader_unittest.Tpo -c -o run_unittests-master_loader_unittest.o `test -f 'master_loader_unittest.cc' || echo '$(srcdir)/'`master_loader_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_loader_unittest.Tpo $(DEPDIR)/run_unittests-master_loader_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_loader_unittest.cc' object='run_unittests-master_loader_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_loader_unittest.o `test -f 'master_loader_unittest.cc' || echo '$(srcdir)/'`master_loader_unittest.cc + +run_unittests-master_loader_unittest.obj: master_loader_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_loader_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-master_loader_unittest.Tpo -c -o run_unittests-master_loader_unittest.obj `if test -f 'master_loader_unittest.cc'; then $(CYGPATH_W) 'master_loader_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/master_loader_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_loader_unittest.Tpo $(DEPDIR)/run_unittests-master_loader_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_loader_unittest.cc' object='run_unittests-master_loader_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_loader_unittest.obj `if test -f 'master_loader_unittest.cc'; then $(CYGPATH_W) 'master_loader_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/master_loader_unittest.cc'; fi` + +run_unittests-master_lexer_state_unittest.o: master_lexer_state_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_lexer_state_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-master_lexer_state_unittest.Tpo -c -o run_unittests-master_lexer_state_unittest.o `test -f 'master_lexer_state_unittest.cc' || echo '$(srcdir)/'`master_lexer_state_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_lexer_state_unittest.Tpo $(DEPDIR)/run_unittests-master_lexer_state_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_lexer_state_unittest.cc' object='run_unittests-master_lexer_state_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_lexer_state_unittest.o `test -f 'master_lexer_state_unittest.cc' || echo '$(srcdir)/'`master_lexer_state_unittest.cc + +run_unittests-master_lexer_state_unittest.obj: master_lexer_state_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_lexer_state_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-master_lexer_state_unittest.Tpo -c -o run_unittests-master_lexer_state_unittest.obj `if test -f 'master_lexer_state_unittest.cc'; then $(CYGPATH_W) 'master_lexer_state_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/master_lexer_state_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_lexer_state_unittest.Tpo $(DEPDIR)/run_unittests-master_lexer_state_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_lexer_state_unittest.cc' object='run_unittests-master_lexer_state_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_lexer_state_unittest.obj `if test -f 'master_lexer_state_unittest.cc'; then $(CYGPATH_W) 'master_lexer_state_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/master_lexer_state_unittest.cc'; fi` + +run_unittests-name_unittest.o: name_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-name_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-name_unittest.Tpo -c -o run_unittests-name_unittest.o `test -f 'name_unittest.cc' || echo '$(srcdir)/'`name_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-name_unittest.Tpo $(DEPDIR)/run_unittests-name_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='name_unittest.cc' object='run_unittests-name_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-name_unittest.o `test -f 'name_unittest.cc' || echo '$(srcdir)/'`name_unittest.cc + +run_unittests-name_unittest.obj: name_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-name_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-name_unittest.Tpo -c -o run_unittests-name_unittest.obj `if test -f 'name_unittest.cc'; then $(CYGPATH_W) 'name_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/name_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-name_unittest.Tpo $(DEPDIR)/run_unittests-name_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='name_unittest.cc' object='run_unittests-name_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-name_unittest.obj `if test -f 'name_unittest.cc'; then $(CYGPATH_W) 'name_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/name_unittest.cc'; fi` + +run_unittests-nsec3hash_unittest.o: nsec3hash_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-nsec3hash_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-nsec3hash_unittest.Tpo -c -o run_unittests-nsec3hash_unittest.o `test -f 'nsec3hash_unittest.cc' || echo '$(srcdir)/'`nsec3hash_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-nsec3hash_unittest.Tpo $(DEPDIR)/run_unittests-nsec3hash_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='nsec3hash_unittest.cc' object='run_unittests-nsec3hash_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-nsec3hash_unittest.o `test -f 'nsec3hash_unittest.cc' || echo '$(srcdir)/'`nsec3hash_unittest.cc + +run_unittests-nsec3hash_unittest.obj: nsec3hash_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-nsec3hash_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-nsec3hash_unittest.Tpo -c -o run_unittests-nsec3hash_unittest.obj `if test -f 'nsec3hash_unittest.cc'; then $(CYGPATH_W) 'nsec3hash_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/nsec3hash_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-nsec3hash_unittest.Tpo $(DEPDIR)/run_unittests-nsec3hash_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='nsec3hash_unittest.cc' object='run_unittests-nsec3hash_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-nsec3hash_unittest.obj `if test -f 'nsec3hash_unittest.cc'; then $(CYGPATH_W) 'nsec3hash_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/nsec3hash_unittest.cc'; fi` + +run_unittests-rrclass_unittest.o: rrclass_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrclass_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rrclass_unittest.Tpo -c -o run_unittests-rrclass_unittest.o `test -f 'rrclass_unittest.cc' || echo '$(srcdir)/'`rrclass_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrclass_unittest.Tpo $(DEPDIR)/run_unittests-rrclass_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrclass_unittest.cc' object='run_unittests-rrclass_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrclass_unittest.o `test -f 'rrclass_unittest.cc' || echo '$(srcdir)/'`rrclass_unittest.cc + +run_unittests-rrclass_unittest.obj: rrclass_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrclass_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rrclass_unittest.Tpo -c -o run_unittests-rrclass_unittest.obj `if test -f 'rrclass_unittest.cc'; then $(CYGPATH_W) 'rrclass_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrclass_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrclass_unittest.Tpo $(DEPDIR)/run_unittests-rrclass_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrclass_unittest.cc' object='run_unittests-rrclass_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrclass_unittest.obj `if test -f 'rrclass_unittest.cc'; then $(CYGPATH_W) 'rrclass_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrclass_unittest.cc'; fi` + +run_unittests-rrtype_unittest.o: rrtype_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrtype_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rrtype_unittest.Tpo -c -o run_unittests-rrtype_unittest.o `test -f 'rrtype_unittest.cc' || echo '$(srcdir)/'`rrtype_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrtype_unittest.Tpo $(DEPDIR)/run_unittests-rrtype_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrtype_unittest.cc' object='run_unittests-rrtype_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrtype_unittest.o `test -f 'rrtype_unittest.cc' || echo '$(srcdir)/'`rrtype_unittest.cc + +run_unittests-rrtype_unittest.obj: rrtype_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrtype_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rrtype_unittest.Tpo -c -o run_unittests-rrtype_unittest.obj `if test -f 'rrtype_unittest.cc'; then $(CYGPATH_W) 'rrtype_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrtype_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrtype_unittest.Tpo $(DEPDIR)/run_unittests-rrtype_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrtype_unittest.cc' object='run_unittests-rrtype_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrtype_unittest.obj `if test -f 'rrtype_unittest.cc'; then $(CYGPATH_W) 'rrtype_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrtype_unittest.cc'; fi` + +run_unittests-rrttl_unittest.o: rrttl_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrttl_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rrttl_unittest.Tpo -c -o run_unittests-rrttl_unittest.o `test -f 'rrttl_unittest.cc' || echo '$(srcdir)/'`rrttl_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrttl_unittest.Tpo $(DEPDIR)/run_unittests-rrttl_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrttl_unittest.cc' object='run_unittests-rrttl_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrttl_unittest.o `test -f 'rrttl_unittest.cc' || echo '$(srcdir)/'`rrttl_unittest.cc + +run_unittests-rrttl_unittest.obj: rrttl_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrttl_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rrttl_unittest.Tpo -c -o run_unittests-rrttl_unittest.obj `if test -f 'rrttl_unittest.cc'; then $(CYGPATH_W) 'rrttl_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrttl_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrttl_unittest.Tpo $(DEPDIR)/run_unittests-rrttl_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrttl_unittest.cc' object='run_unittests-rrttl_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrttl_unittest.obj `if test -f 'rrttl_unittest.cc'; then $(CYGPATH_W) 'rrttl_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrttl_unittest.cc'; fi` + +run_unittests-rrcollator_unittest.o: rrcollator_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrcollator_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rrcollator_unittest.Tpo -c -o run_unittests-rrcollator_unittest.o `test -f 'rrcollator_unittest.cc' || echo '$(srcdir)/'`rrcollator_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrcollator_unittest.Tpo $(DEPDIR)/run_unittests-rrcollator_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrcollator_unittest.cc' object='run_unittests-rrcollator_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrcollator_unittest.o `test -f 'rrcollator_unittest.cc' || echo '$(srcdir)/'`rrcollator_unittest.cc + +run_unittests-rrcollator_unittest.obj: rrcollator_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrcollator_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rrcollator_unittest.Tpo -c -o run_unittests-rrcollator_unittest.obj `if test -f 'rrcollator_unittest.cc'; then $(CYGPATH_W) 'rrcollator_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrcollator_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrcollator_unittest.Tpo $(DEPDIR)/run_unittests-rrcollator_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrcollator_unittest.cc' object='run_unittests-rrcollator_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrcollator_unittest.obj `if test -f 'rrcollator_unittest.cc'; then $(CYGPATH_W) 'rrcollator_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrcollator_unittest.cc'; fi` + +run_unittests-opcode_unittest.o: opcode_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-opcode_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-opcode_unittest.Tpo -c -o run_unittests-opcode_unittest.o `test -f 'opcode_unittest.cc' || echo '$(srcdir)/'`opcode_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-opcode_unittest.Tpo $(DEPDIR)/run_unittests-opcode_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opcode_unittest.cc' object='run_unittests-opcode_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-opcode_unittest.o `test -f 'opcode_unittest.cc' || echo '$(srcdir)/'`opcode_unittest.cc + +run_unittests-opcode_unittest.obj: opcode_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-opcode_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-opcode_unittest.Tpo -c -o run_unittests-opcode_unittest.obj `if test -f 'opcode_unittest.cc'; then $(CYGPATH_W) 'opcode_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/opcode_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-opcode_unittest.Tpo $(DEPDIR)/run_unittests-opcode_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='opcode_unittest.cc' object='run_unittests-opcode_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-opcode_unittest.obj `if test -f 'opcode_unittest.cc'; then $(CYGPATH_W) 'opcode_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/opcode_unittest.cc'; fi` + +run_unittests-rcode_unittest.o: rcode_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rcode_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rcode_unittest.Tpo -c -o run_unittests-rcode_unittest.o `test -f 'rcode_unittest.cc' || echo '$(srcdir)/'`rcode_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rcode_unittest.Tpo $(DEPDIR)/run_unittests-rcode_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rcode_unittest.cc' object='run_unittests-rcode_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rcode_unittest.o `test -f 'rcode_unittest.cc' || echo '$(srcdir)/'`rcode_unittest.cc + +run_unittests-rcode_unittest.obj: rcode_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rcode_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rcode_unittest.Tpo -c -o run_unittests-rcode_unittest.obj `if test -f 'rcode_unittest.cc'; then $(CYGPATH_W) 'rcode_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rcode_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rcode_unittest.Tpo $(DEPDIR)/run_unittests-rcode_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rcode_unittest.cc' object='run_unittests-rcode_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rcode_unittest.obj `if test -f 'rcode_unittest.cc'; then $(CYGPATH_W) 'rcode_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rcode_unittest.cc'; fi` + +run_unittests-rdata_unittest.o: rdata_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_unittest.Tpo -c -o run_unittests-rdata_unittest.o `test -f 'rdata_unittest.cc' || echo '$(srcdir)/'`rdata_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_unittest.Tpo $(DEPDIR)/run_unittests-rdata_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_unittest.cc' object='run_unittests-rdata_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_unittest.o `test -f 'rdata_unittest.cc' || echo '$(srcdir)/'`rdata_unittest.cc + +run_unittests-rdata_unittest.obj: rdata_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_unittest.Tpo -c -o run_unittests-rdata_unittest.obj `if test -f 'rdata_unittest.cc'; then $(CYGPATH_W) 'rdata_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_unittest.Tpo $(DEPDIR)/run_unittests-rdata_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_unittest.cc' object='run_unittests-rdata_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_unittest.obj `if test -f 'rdata_unittest.cc'; then $(CYGPATH_W) 'rdata_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_unittest.cc'; fi` + +run_unittests-rdatafields_unittest.o: rdatafields_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdatafields_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdatafields_unittest.Tpo -c -o run_unittests-rdatafields_unittest.o `test -f 'rdatafields_unittest.cc' || echo '$(srcdir)/'`rdatafields_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdatafields_unittest.Tpo $(DEPDIR)/run_unittests-rdatafields_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdatafields_unittest.cc' object='run_unittests-rdatafields_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdatafields_unittest.o `test -f 'rdatafields_unittest.cc' || echo '$(srcdir)/'`rdatafields_unittest.cc + +run_unittests-rdatafields_unittest.obj: rdatafields_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdatafields_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdatafields_unittest.Tpo -c -o run_unittests-rdatafields_unittest.obj `if test -f 'rdatafields_unittest.cc'; then $(CYGPATH_W) 'rdatafields_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdatafields_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdatafields_unittest.Tpo $(DEPDIR)/run_unittests-rdatafields_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdatafields_unittest.cc' object='run_unittests-rdatafields_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdatafields_unittest.obj `if test -f 'rdatafields_unittest.cc'; then $(CYGPATH_W) 'rdatafields_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdatafields_unittest.cc'; fi` + +run_unittests-rdata_pimpl_holder_unittest.o: rdata_pimpl_holder_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_pimpl_holder_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_pimpl_holder_unittest.Tpo -c -o run_unittests-rdata_pimpl_holder_unittest.o `test -f 'rdata_pimpl_holder_unittest.cc' || echo '$(srcdir)/'`rdata_pimpl_holder_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_pimpl_holder_unittest.Tpo $(DEPDIR)/run_unittests-rdata_pimpl_holder_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_pimpl_holder_unittest.cc' object='run_unittests-rdata_pimpl_holder_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_pimpl_holder_unittest.o `test -f 'rdata_pimpl_holder_unittest.cc' || echo '$(srcdir)/'`rdata_pimpl_holder_unittest.cc + +run_unittests-rdata_pimpl_holder_unittest.obj: rdata_pimpl_holder_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_pimpl_holder_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_pimpl_holder_unittest.Tpo -c -o run_unittests-rdata_pimpl_holder_unittest.obj `if test -f 'rdata_pimpl_holder_unittest.cc'; then $(CYGPATH_W) 'rdata_pimpl_holder_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_pimpl_holder_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_pimpl_holder_unittest.Tpo $(DEPDIR)/run_unittests-rdata_pimpl_holder_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_pimpl_holder_unittest.cc' object='run_unittests-rdata_pimpl_holder_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_pimpl_holder_unittest.obj `if test -f 'rdata_pimpl_holder_unittest.cc'; then $(CYGPATH_W) 'rdata_pimpl_holder_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_pimpl_holder_unittest.cc'; fi` + +run_unittests-rdata_char_string_unittest.o: rdata_char_string_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_char_string_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_char_string_unittest.Tpo -c -o run_unittests-rdata_char_string_unittest.o `test -f 'rdata_char_string_unittest.cc' || echo '$(srcdir)/'`rdata_char_string_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_char_string_unittest.Tpo $(DEPDIR)/run_unittests-rdata_char_string_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_char_string_unittest.cc' object='run_unittests-rdata_char_string_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_char_string_unittest.o `test -f 'rdata_char_string_unittest.cc' || echo '$(srcdir)/'`rdata_char_string_unittest.cc + +run_unittests-rdata_char_string_unittest.obj: rdata_char_string_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_char_string_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_char_string_unittest.Tpo -c -o run_unittests-rdata_char_string_unittest.obj `if test -f 'rdata_char_string_unittest.cc'; then $(CYGPATH_W) 'rdata_char_string_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_char_string_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_char_string_unittest.Tpo $(DEPDIR)/run_unittests-rdata_char_string_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_char_string_unittest.cc' object='run_unittests-rdata_char_string_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_char_string_unittest.obj `if test -f 'rdata_char_string_unittest.cc'; then $(CYGPATH_W) 'rdata_char_string_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_char_string_unittest.cc'; fi` + +run_unittests-rdata_char_string_data_unittest.o: rdata_char_string_data_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_char_string_data_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_char_string_data_unittest.Tpo -c -o run_unittests-rdata_char_string_data_unittest.o `test -f 'rdata_char_string_data_unittest.cc' || echo '$(srcdir)/'`rdata_char_string_data_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_char_string_data_unittest.Tpo $(DEPDIR)/run_unittests-rdata_char_string_data_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_char_string_data_unittest.cc' object='run_unittests-rdata_char_string_data_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_char_string_data_unittest.o `test -f 'rdata_char_string_data_unittest.cc' || echo '$(srcdir)/'`rdata_char_string_data_unittest.cc + +run_unittests-rdata_char_string_data_unittest.obj: rdata_char_string_data_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_char_string_data_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_char_string_data_unittest.Tpo -c -o run_unittests-rdata_char_string_data_unittest.obj `if test -f 'rdata_char_string_data_unittest.cc'; then $(CYGPATH_W) 'rdata_char_string_data_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_char_string_data_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_char_string_data_unittest.Tpo $(DEPDIR)/run_unittests-rdata_char_string_data_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_char_string_data_unittest.cc' object='run_unittests-rdata_char_string_data_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_char_string_data_unittest.obj `if test -f 'rdata_char_string_data_unittest.cc'; then $(CYGPATH_W) 'rdata_char_string_data_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_char_string_data_unittest.cc'; fi` + +run_unittests-rdata_in_a_unittest.o: rdata_in_a_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_in_a_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_in_a_unittest.Tpo -c -o run_unittests-rdata_in_a_unittest.o `test -f 'rdata_in_a_unittest.cc' || echo '$(srcdir)/'`rdata_in_a_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_in_a_unittest.Tpo $(DEPDIR)/run_unittests-rdata_in_a_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_in_a_unittest.cc' object='run_unittests-rdata_in_a_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_in_a_unittest.o `test -f 'rdata_in_a_unittest.cc' || echo '$(srcdir)/'`rdata_in_a_unittest.cc + +run_unittests-rdata_in_a_unittest.obj: rdata_in_a_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_in_a_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_in_a_unittest.Tpo -c -o run_unittests-rdata_in_a_unittest.obj `if test -f 'rdata_in_a_unittest.cc'; then $(CYGPATH_W) 'rdata_in_a_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_in_a_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_in_a_unittest.Tpo $(DEPDIR)/run_unittests-rdata_in_a_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_in_a_unittest.cc' object='run_unittests-rdata_in_a_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_in_a_unittest.obj `if test -f 'rdata_in_a_unittest.cc'; then $(CYGPATH_W) 'rdata_in_a_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_in_a_unittest.cc'; fi` + +run_unittests-rdata_in_aaaa_unittest.o: rdata_in_aaaa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_in_aaaa_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_in_aaaa_unittest.Tpo -c -o run_unittests-rdata_in_aaaa_unittest.o `test -f 'rdata_in_aaaa_unittest.cc' || echo '$(srcdir)/'`rdata_in_aaaa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_in_aaaa_unittest.Tpo $(DEPDIR)/run_unittests-rdata_in_aaaa_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_in_aaaa_unittest.cc' object='run_unittests-rdata_in_aaaa_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_in_aaaa_unittest.o `test -f 'rdata_in_aaaa_unittest.cc' || echo '$(srcdir)/'`rdata_in_aaaa_unittest.cc + +run_unittests-rdata_in_aaaa_unittest.obj: rdata_in_aaaa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_in_aaaa_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_in_aaaa_unittest.Tpo -c -o run_unittests-rdata_in_aaaa_unittest.obj `if test -f 'rdata_in_aaaa_unittest.cc'; then $(CYGPATH_W) 'rdata_in_aaaa_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_in_aaaa_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_in_aaaa_unittest.Tpo $(DEPDIR)/run_unittests-rdata_in_aaaa_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_in_aaaa_unittest.cc' object='run_unittests-rdata_in_aaaa_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_in_aaaa_unittest.obj `if test -f 'rdata_in_aaaa_unittest.cc'; then $(CYGPATH_W) 'rdata_in_aaaa_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_in_aaaa_unittest.cc'; fi` + +run_unittests-rdata_ns_unittest.o: rdata_ns_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_ns_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_ns_unittest.Tpo -c -o run_unittests-rdata_ns_unittest.o `test -f 'rdata_ns_unittest.cc' || echo '$(srcdir)/'`rdata_ns_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_ns_unittest.Tpo $(DEPDIR)/run_unittests-rdata_ns_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_ns_unittest.cc' object='run_unittests-rdata_ns_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_ns_unittest.o `test -f 'rdata_ns_unittest.cc' || echo '$(srcdir)/'`rdata_ns_unittest.cc + +run_unittests-rdata_ns_unittest.obj: rdata_ns_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_ns_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_ns_unittest.Tpo -c -o run_unittests-rdata_ns_unittest.obj `if test -f 'rdata_ns_unittest.cc'; then $(CYGPATH_W) 'rdata_ns_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_ns_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_ns_unittest.Tpo $(DEPDIR)/run_unittests-rdata_ns_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_ns_unittest.cc' object='run_unittests-rdata_ns_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_ns_unittest.obj `if test -f 'rdata_ns_unittest.cc'; then $(CYGPATH_W) 'rdata_ns_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_ns_unittest.cc'; fi` + +run_unittests-rdata_soa_unittest.o: rdata_soa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_soa_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_soa_unittest.Tpo -c -o run_unittests-rdata_soa_unittest.o `test -f 'rdata_soa_unittest.cc' || echo '$(srcdir)/'`rdata_soa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_soa_unittest.Tpo $(DEPDIR)/run_unittests-rdata_soa_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_soa_unittest.cc' object='run_unittests-rdata_soa_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_soa_unittest.o `test -f 'rdata_soa_unittest.cc' || echo '$(srcdir)/'`rdata_soa_unittest.cc + +run_unittests-rdata_soa_unittest.obj: rdata_soa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_soa_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_soa_unittest.Tpo -c -o run_unittests-rdata_soa_unittest.obj `if test -f 'rdata_soa_unittest.cc'; then $(CYGPATH_W) 'rdata_soa_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_soa_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_soa_unittest.Tpo $(DEPDIR)/run_unittests-rdata_soa_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_soa_unittest.cc' object='run_unittests-rdata_soa_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_soa_unittest.obj `if test -f 'rdata_soa_unittest.cc'; then $(CYGPATH_W) 'rdata_soa_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_soa_unittest.cc'; fi` + +run_unittests-rdata_txt_like_unittest.o: rdata_txt_like_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_txt_like_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_txt_like_unittest.Tpo -c -o run_unittests-rdata_txt_like_unittest.o `test -f 'rdata_txt_like_unittest.cc' || echo '$(srcdir)/'`rdata_txt_like_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_txt_like_unittest.Tpo $(DEPDIR)/run_unittests-rdata_txt_like_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_txt_like_unittest.cc' object='run_unittests-rdata_txt_like_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_txt_like_unittest.o `test -f 'rdata_txt_like_unittest.cc' || echo '$(srcdir)/'`rdata_txt_like_unittest.cc + +run_unittests-rdata_txt_like_unittest.obj: rdata_txt_like_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_txt_like_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_txt_like_unittest.Tpo -c -o run_unittests-rdata_txt_like_unittest.obj `if test -f 'rdata_txt_like_unittest.cc'; then $(CYGPATH_W) 'rdata_txt_like_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_txt_like_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_txt_like_unittest.Tpo $(DEPDIR)/run_unittests-rdata_txt_like_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_txt_like_unittest.cc' object='run_unittests-rdata_txt_like_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_txt_like_unittest.obj `if test -f 'rdata_txt_like_unittest.cc'; then $(CYGPATH_W) 'rdata_txt_like_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_txt_like_unittest.cc'; fi` + +run_unittests-rdata_mx_unittest.o: rdata_mx_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_mx_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_mx_unittest.Tpo -c -o run_unittests-rdata_mx_unittest.o `test -f 'rdata_mx_unittest.cc' || echo '$(srcdir)/'`rdata_mx_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_mx_unittest.Tpo $(DEPDIR)/run_unittests-rdata_mx_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_mx_unittest.cc' object='run_unittests-rdata_mx_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_mx_unittest.o `test -f 'rdata_mx_unittest.cc' || echo '$(srcdir)/'`rdata_mx_unittest.cc + +run_unittests-rdata_mx_unittest.obj: rdata_mx_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_mx_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_mx_unittest.Tpo -c -o run_unittests-rdata_mx_unittest.obj `if test -f 'rdata_mx_unittest.cc'; then $(CYGPATH_W) 'rdata_mx_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_mx_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_mx_unittest.Tpo $(DEPDIR)/run_unittests-rdata_mx_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_mx_unittest.cc' object='run_unittests-rdata_mx_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_mx_unittest.obj `if test -f 'rdata_mx_unittest.cc'; then $(CYGPATH_W) 'rdata_mx_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_mx_unittest.cc'; fi` + +run_unittests-rdata_sshfp_unittest.o: rdata_sshfp_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_sshfp_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_sshfp_unittest.Tpo -c -o run_unittests-rdata_sshfp_unittest.o `test -f 'rdata_sshfp_unittest.cc' || echo '$(srcdir)/'`rdata_sshfp_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_sshfp_unittest.Tpo $(DEPDIR)/run_unittests-rdata_sshfp_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_sshfp_unittest.cc' object='run_unittests-rdata_sshfp_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_sshfp_unittest.o `test -f 'rdata_sshfp_unittest.cc' || echo '$(srcdir)/'`rdata_sshfp_unittest.cc + +run_unittests-rdata_sshfp_unittest.obj: rdata_sshfp_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_sshfp_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_sshfp_unittest.Tpo -c -o run_unittests-rdata_sshfp_unittest.obj `if test -f 'rdata_sshfp_unittest.cc'; then $(CYGPATH_W) 'rdata_sshfp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_sshfp_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_sshfp_unittest.Tpo $(DEPDIR)/run_unittests-rdata_sshfp_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_sshfp_unittest.cc' object='run_unittests-rdata_sshfp_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_sshfp_unittest.obj `if test -f 'rdata_sshfp_unittest.cc'; then $(CYGPATH_W) 'rdata_sshfp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_sshfp_unittest.cc'; fi` + +run_unittests-rdata_ptr_unittest.o: rdata_ptr_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_ptr_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_ptr_unittest.Tpo -c -o run_unittests-rdata_ptr_unittest.o `test -f 'rdata_ptr_unittest.cc' || echo '$(srcdir)/'`rdata_ptr_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_ptr_unittest.Tpo $(DEPDIR)/run_unittests-rdata_ptr_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_ptr_unittest.cc' object='run_unittests-rdata_ptr_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_ptr_unittest.o `test -f 'rdata_ptr_unittest.cc' || echo '$(srcdir)/'`rdata_ptr_unittest.cc + +run_unittests-rdata_ptr_unittest.obj: rdata_ptr_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_ptr_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_ptr_unittest.Tpo -c -o run_unittests-rdata_ptr_unittest.obj `if test -f 'rdata_ptr_unittest.cc'; then $(CYGPATH_W) 'rdata_ptr_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_ptr_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_ptr_unittest.Tpo $(DEPDIR)/run_unittests-rdata_ptr_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_ptr_unittest.cc' object='run_unittests-rdata_ptr_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_ptr_unittest.obj `if test -f 'rdata_ptr_unittest.cc'; then $(CYGPATH_W) 'rdata_ptr_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_ptr_unittest.cc'; fi` + +run_unittests-rdata_cname_unittest.o: rdata_cname_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_cname_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_cname_unittest.Tpo -c -o run_unittests-rdata_cname_unittest.o `test -f 'rdata_cname_unittest.cc' || echo '$(srcdir)/'`rdata_cname_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_cname_unittest.Tpo $(DEPDIR)/run_unittests-rdata_cname_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_cname_unittest.cc' object='run_unittests-rdata_cname_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_cname_unittest.o `test -f 'rdata_cname_unittest.cc' || echo '$(srcdir)/'`rdata_cname_unittest.cc + +run_unittests-rdata_cname_unittest.obj: rdata_cname_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_cname_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_cname_unittest.Tpo -c -o run_unittests-rdata_cname_unittest.obj `if test -f 'rdata_cname_unittest.cc'; then $(CYGPATH_W) 'rdata_cname_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_cname_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_cname_unittest.Tpo $(DEPDIR)/run_unittests-rdata_cname_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_cname_unittest.cc' object='run_unittests-rdata_cname_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_cname_unittest.obj `if test -f 'rdata_cname_unittest.cc'; then $(CYGPATH_W) 'rdata_cname_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_cname_unittest.cc'; fi` + +run_unittests-rdata_dname_unittest.o: rdata_dname_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_dname_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_dname_unittest.Tpo -c -o run_unittests-rdata_dname_unittest.o `test -f 'rdata_dname_unittest.cc' || echo '$(srcdir)/'`rdata_dname_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_dname_unittest.Tpo $(DEPDIR)/run_unittests-rdata_dname_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_dname_unittest.cc' object='run_unittests-rdata_dname_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_dname_unittest.o `test -f 'rdata_dname_unittest.cc' || echo '$(srcdir)/'`rdata_dname_unittest.cc + +run_unittests-rdata_dname_unittest.obj: rdata_dname_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_dname_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_dname_unittest.Tpo -c -o run_unittests-rdata_dname_unittest.obj `if test -f 'rdata_dname_unittest.cc'; then $(CYGPATH_W) 'rdata_dname_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_dname_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_dname_unittest.Tpo $(DEPDIR)/run_unittests-rdata_dname_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_dname_unittest.cc' object='run_unittests-rdata_dname_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_dname_unittest.obj `if test -f 'rdata_dname_unittest.cc'; then $(CYGPATH_W) 'rdata_dname_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_dname_unittest.cc'; fi` + +run_unittests-rdata_afsdb_unittest.o: rdata_afsdb_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_afsdb_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_afsdb_unittest.Tpo -c -o run_unittests-rdata_afsdb_unittest.o `test -f 'rdata_afsdb_unittest.cc' || echo '$(srcdir)/'`rdata_afsdb_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_afsdb_unittest.Tpo $(DEPDIR)/run_unittests-rdata_afsdb_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_afsdb_unittest.cc' object='run_unittests-rdata_afsdb_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_afsdb_unittest.o `test -f 'rdata_afsdb_unittest.cc' || echo '$(srcdir)/'`rdata_afsdb_unittest.cc + +run_unittests-rdata_afsdb_unittest.obj: rdata_afsdb_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_afsdb_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_afsdb_unittest.Tpo -c -o run_unittests-rdata_afsdb_unittest.obj `if test -f 'rdata_afsdb_unittest.cc'; then $(CYGPATH_W) 'rdata_afsdb_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_afsdb_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_afsdb_unittest.Tpo $(DEPDIR)/run_unittests-rdata_afsdb_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_afsdb_unittest.cc' object='run_unittests-rdata_afsdb_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_afsdb_unittest.obj `if test -f 'rdata_afsdb_unittest.cc'; then $(CYGPATH_W) 'rdata_afsdb_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_afsdb_unittest.cc'; fi` + +run_unittests-rdata_opt_unittest.o: rdata_opt_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_opt_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_opt_unittest.Tpo -c -o run_unittests-rdata_opt_unittest.o `test -f 'rdata_opt_unittest.cc' || echo '$(srcdir)/'`rdata_opt_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_opt_unittest.Tpo $(DEPDIR)/run_unittests-rdata_opt_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_opt_unittest.cc' object='run_unittests-rdata_opt_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_opt_unittest.o `test -f 'rdata_opt_unittest.cc' || echo '$(srcdir)/'`rdata_opt_unittest.cc + +run_unittests-rdata_opt_unittest.obj: rdata_opt_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_opt_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_opt_unittest.Tpo -c -o run_unittests-rdata_opt_unittest.obj `if test -f 'rdata_opt_unittest.cc'; then $(CYGPATH_W) 'rdata_opt_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_opt_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_opt_unittest.Tpo $(DEPDIR)/run_unittests-rdata_opt_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_opt_unittest.cc' object='run_unittests-rdata_opt_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_opt_unittest.obj `if test -f 'rdata_opt_unittest.cc'; then $(CYGPATH_W) 'rdata_opt_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_opt_unittest.cc'; fi` + +run_unittests-rdata_dhcid_unittest.o: rdata_dhcid_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_dhcid_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_dhcid_unittest.Tpo -c -o run_unittests-rdata_dhcid_unittest.o `test -f 'rdata_dhcid_unittest.cc' || echo '$(srcdir)/'`rdata_dhcid_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_dhcid_unittest.Tpo $(DEPDIR)/run_unittests-rdata_dhcid_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_dhcid_unittest.cc' object='run_unittests-rdata_dhcid_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_dhcid_unittest.o `test -f 'rdata_dhcid_unittest.cc' || echo '$(srcdir)/'`rdata_dhcid_unittest.cc + +run_unittests-rdata_dhcid_unittest.obj: rdata_dhcid_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_dhcid_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_dhcid_unittest.Tpo -c -o run_unittests-rdata_dhcid_unittest.obj `if test -f 'rdata_dhcid_unittest.cc'; then $(CYGPATH_W) 'rdata_dhcid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_dhcid_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_dhcid_unittest.Tpo $(DEPDIR)/run_unittests-rdata_dhcid_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_dhcid_unittest.cc' object='run_unittests-rdata_dhcid_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_dhcid_unittest.obj `if test -f 'rdata_dhcid_unittest.cc'; then $(CYGPATH_W) 'rdata_dhcid_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_dhcid_unittest.cc'; fi` + +run_unittests-rdata_dnskey_unittest.o: rdata_dnskey_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_dnskey_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_dnskey_unittest.Tpo -c -o run_unittests-rdata_dnskey_unittest.o `test -f 'rdata_dnskey_unittest.cc' || echo '$(srcdir)/'`rdata_dnskey_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_dnskey_unittest.Tpo $(DEPDIR)/run_unittests-rdata_dnskey_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_dnskey_unittest.cc' object='run_unittests-rdata_dnskey_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_dnskey_unittest.o `test -f 'rdata_dnskey_unittest.cc' || echo '$(srcdir)/'`rdata_dnskey_unittest.cc + +run_unittests-rdata_dnskey_unittest.obj: rdata_dnskey_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_dnskey_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_dnskey_unittest.Tpo -c -o run_unittests-rdata_dnskey_unittest.obj `if test -f 'rdata_dnskey_unittest.cc'; then $(CYGPATH_W) 'rdata_dnskey_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_dnskey_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_dnskey_unittest.Tpo $(DEPDIR)/run_unittests-rdata_dnskey_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_dnskey_unittest.cc' object='run_unittests-rdata_dnskey_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_dnskey_unittest.obj `if test -f 'rdata_dnskey_unittest.cc'; then $(CYGPATH_W) 'rdata_dnskey_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_dnskey_unittest.cc'; fi` + +run_unittests-rdata_ds_like_unittest.o: rdata_ds_like_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_ds_like_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_ds_like_unittest.Tpo -c -o run_unittests-rdata_ds_like_unittest.o `test -f 'rdata_ds_like_unittest.cc' || echo '$(srcdir)/'`rdata_ds_like_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_ds_like_unittest.Tpo $(DEPDIR)/run_unittests-rdata_ds_like_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_ds_like_unittest.cc' object='run_unittests-rdata_ds_like_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_ds_like_unittest.o `test -f 'rdata_ds_like_unittest.cc' || echo '$(srcdir)/'`rdata_ds_like_unittest.cc + +run_unittests-rdata_ds_like_unittest.obj: rdata_ds_like_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_ds_like_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_ds_like_unittest.Tpo -c -o run_unittests-rdata_ds_like_unittest.obj `if test -f 'rdata_ds_like_unittest.cc'; then $(CYGPATH_W) 'rdata_ds_like_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_ds_like_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_ds_like_unittest.Tpo $(DEPDIR)/run_unittests-rdata_ds_like_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_ds_like_unittest.cc' object='run_unittests-rdata_ds_like_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_ds_like_unittest.obj `if test -f 'rdata_ds_like_unittest.cc'; then $(CYGPATH_W) 'rdata_ds_like_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_ds_like_unittest.cc'; fi` + +run_unittests-rdata_nsec_unittest.o: rdata_nsec_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_nsec_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_nsec_unittest.Tpo -c -o run_unittests-rdata_nsec_unittest.o `test -f 'rdata_nsec_unittest.cc' || echo '$(srcdir)/'`rdata_nsec_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_nsec_unittest.Tpo $(DEPDIR)/run_unittests-rdata_nsec_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_nsec_unittest.cc' object='run_unittests-rdata_nsec_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_nsec_unittest.o `test -f 'rdata_nsec_unittest.cc' || echo '$(srcdir)/'`rdata_nsec_unittest.cc + +run_unittests-rdata_nsec_unittest.obj: rdata_nsec_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_nsec_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_nsec_unittest.Tpo -c -o run_unittests-rdata_nsec_unittest.obj `if test -f 'rdata_nsec_unittest.cc'; then $(CYGPATH_W) 'rdata_nsec_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_nsec_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_nsec_unittest.Tpo $(DEPDIR)/run_unittests-rdata_nsec_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_nsec_unittest.cc' object='run_unittests-rdata_nsec_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_nsec_unittest.obj `if test -f 'rdata_nsec_unittest.cc'; then $(CYGPATH_W) 'rdata_nsec_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_nsec_unittest.cc'; fi` + +run_unittests-rdata_nsec3_unittest.o: rdata_nsec3_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_nsec3_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_nsec3_unittest.Tpo -c -o run_unittests-rdata_nsec3_unittest.o `test -f 'rdata_nsec3_unittest.cc' || echo '$(srcdir)/'`rdata_nsec3_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_nsec3_unittest.Tpo $(DEPDIR)/run_unittests-rdata_nsec3_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_nsec3_unittest.cc' object='run_unittests-rdata_nsec3_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_nsec3_unittest.o `test -f 'rdata_nsec3_unittest.cc' || echo '$(srcdir)/'`rdata_nsec3_unittest.cc + +run_unittests-rdata_nsec3_unittest.obj: rdata_nsec3_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_nsec3_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_nsec3_unittest.Tpo -c -o run_unittests-rdata_nsec3_unittest.obj `if test -f 'rdata_nsec3_unittest.cc'; then $(CYGPATH_W) 'rdata_nsec3_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_nsec3_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_nsec3_unittest.Tpo $(DEPDIR)/run_unittests-rdata_nsec3_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_nsec3_unittest.cc' object='run_unittests-rdata_nsec3_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_nsec3_unittest.obj `if test -f 'rdata_nsec3_unittest.cc'; then $(CYGPATH_W) 'rdata_nsec3_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_nsec3_unittest.cc'; fi` + +run_unittests-rdata_nsecbitmap_unittest.o: rdata_nsecbitmap_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_nsecbitmap_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_nsecbitmap_unittest.Tpo -c -o run_unittests-rdata_nsecbitmap_unittest.o `test -f 'rdata_nsecbitmap_unittest.cc' || echo '$(srcdir)/'`rdata_nsecbitmap_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_nsecbitmap_unittest.Tpo $(DEPDIR)/run_unittests-rdata_nsecbitmap_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_nsecbitmap_unittest.cc' object='run_unittests-rdata_nsecbitmap_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_nsecbitmap_unittest.o `test -f 'rdata_nsecbitmap_unittest.cc' || echo '$(srcdir)/'`rdata_nsecbitmap_unittest.cc + +run_unittests-rdata_nsecbitmap_unittest.obj: rdata_nsecbitmap_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_nsecbitmap_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_nsecbitmap_unittest.Tpo -c -o run_unittests-rdata_nsecbitmap_unittest.obj `if test -f 'rdata_nsecbitmap_unittest.cc'; then $(CYGPATH_W) 'rdata_nsecbitmap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_nsecbitmap_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_nsecbitmap_unittest.Tpo $(DEPDIR)/run_unittests-rdata_nsecbitmap_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_nsecbitmap_unittest.cc' object='run_unittests-rdata_nsecbitmap_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_nsecbitmap_unittest.obj `if test -f 'rdata_nsecbitmap_unittest.cc'; then $(CYGPATH_W) 'rdata_nsecbitmap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_nsecbitmap_unittest.cc'; fi` + +run_unittests-rdata_nsec3param_unittest.o: rdata_nsec3param_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_nsec3param_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_nsec3param_unittest.Tpo -c -o run_unittests-rdata_nsec3param_unittest.o `test -f 'rdata_nsec3param_unittest.cc' || echo '$(srcdir)/'`rdata_nsec3param_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_nsec3param_unittest.Tpo $(DEPDIR)/run_unittests-rdata_nsec3param_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_nsec3param_unittest.cc' object='run_unittests-rdata_nsec3param_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_nsec3param_unittest.o `test -f 'rdata_nsec3param_unittest.cc' || echo '$(srcdir)/'`rdata_nsec3param_unittest.cc + +run_unittests-rdata_nsec3param_unittest.obj: rdata_nsec3param_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_nsec3param_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_nsec3param_unittest.Tpo -c -o run_unittests-rdata_nsec3param_unittest.obj `if test -f 'rdata_nsec3param_unittest.cc'; then $(CYGPATH_W) 'rdata_nsec3param_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_nsec3param_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_nsec3param_unittest.Tpo $(DEPDIR)/run_unittests-rdata_nsec3param_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_nsec3param_unittest.cc' object='run_unittests-rdata_nsec3param_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_nsec3param_unittest.obj `if test -f 'rdata_nsec3param_unittest.cc'; then $(CYGPATH_W) 'rdata_nsec3param_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_nsec3param_unittest.cc'; fi` + +run_unittests-rdata_nsec3param_like_unittest.o: rdata_nsec3param_like_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_nsec3param_like_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_nsec3param_like_unittest.Tpo -c -o run_unittests-rdata_nsec3param_like_unittest.o `test -f 'rdata_nsec3param_like_unittest.cc' || echo '$(srcdir)/'`rdata_nsec3param_like_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_nsec3param_like_unittest.Tpo $(DEPDIR)/run_unittests-rdata_nsec3param_like_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_nsec3param_like_unittest.cc' object='run_unittests-rdata_nsec3param_like_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_nsec3param_like_unittest.o `test -f 'rdata_nsec3param_like_unittest.cc' || echo '$(srcdir)/'`rdata_nsec3param_like_unittest.cc + +run_unittests-rdata_nsec3param_like_unittest.obj: rdata_nsec3param_like_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_nsec3param_like_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_nsec3param_like_unittest.Tpo -c -o run_unittests-rdata_nsec3param_like_unittest.obj `if test -f 'rdata_nsec3param_like_unittest.cc'; then $(CYGPATH_W) 'rdata_nsec3param_like_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_nsec3param_like_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_nsec3param_like_unittest.Tpo $(DEPDIR)/run_unittests-rdata_nsec3param_like_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_nsec3param_like_unittest.cc' object='run_unittests-rdata_nsec3param_like_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_nsec3param_like_unittest.obj `if test -f 'rdata_nsec3param_like_unittest.cc'; then $(CYGPATH_W) 'rdata_nsec3param_like_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_nsec3param_like_unittest.cc'; fi` + +run_unittests-rdata_rrsig_unittest.o: rdata_rrsig_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_rrsig_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_rrsig_unittest.Tpo -c -o run_unittests-rdata_rrsig_unittest.o `test -f 'rdata_rrsig_unittest.cc' || echo '$(srcdir)/'`rdata_rrsig_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_rrsig_unittest.Tpo $(DEPDIR)/run_unittests-rdata_rrsig_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_rrsig_unittest.cc' object='run_unittests-rdata_rrsig_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_rrsig_unittest.o `test -f 'rdata_rrsig_unittest.cc' || echo '$(srcdir)/'`rdata_rrsig_unittest.cc + +run_unittests-rdata_rrsig_unittest.obj: rdata_rrsig_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_rrsig_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_rrsig_unittest.Tpo -c -o run_unittests-rdata_rrsig_unittest.obj `if test -f 'rdata_rrsig_unittest.cc'; then $(CYGPATH_W) 'rdata_rrsig_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_rrsig_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_rrsig_unittest.Tpo $(DEPDIR)/run_unittests-rdata_rrsig_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_rrsig_unittest.cc' object='run_unittests-rdata_rrsig_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_rrsig_unittest.obj `if test -f 'rdata_rrsig_unittest.cc'; then $(CYGPATH_W) 'rdata_rrsig_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_rrsig_unittest.cc'; fi` + +run_unittests-rdata_rp_unittest.o: rdata_rp_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_rp_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_rp_unittest.Tpo -c -o run_unittests-rdata_rp_unittest.o `test -f 'rdata_rp_unittest.cc' || echo '$(srcdir)/'`rdata_rp_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_rp_unittest.Tpo $(DEPDIR)/run_unittests-rdata_rp_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_rp_unittest.cc' object='run_unittests-rdata_rp_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_rp_unittest.o `test -f 'rdata_rp_unittest.cc' || echo '$(srcdir)/'`rdata_rp_unittest.cc + +run_unittests-rdata_rp_unittest.obj: rdata_rp_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_rp_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_rp_unittest.Tpo -c -o run_unittests-rdata_rp_unittest.obj `if test -f 'rdata_rp_unittest.cc'; then $(CYGPATH_W) 'rdata_rp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_rp_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_rp_unittest.Tpo $(DEPDIR)/run_unittests-rdata_rp_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_rp_unittest.cc' object='run_unittests-rdata_rp_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_rp_unittest.obj `if test -f 'rdata_rp_unittest.cc'; then $(CYGPATH_W) 'rdata_rp_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_rp_unittest.cc'; fi` + +run_unittests-rdata_srv_unittest.o: rdata_srv_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_srv_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_srv_unittest.Tpo -c -o run_unittests-rdata_srv_unittest.o `test -f 'rdata_srv_unittest.cc' || echo '$(srcdir)/'`rdata_srv_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_srv_unittest.Tpo $(DEPDIR)/run_unittests-rdata_srv_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_srv_unittest.cc' object='run_unittests-rdata_srv_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_srv_unittest.o `test -f 'rdata_srv_unittest.cc' || echo '$(srcdir)/'`rdata_srv_unittest.cc + +run_unittests-rdata_srv_unittest.obj: rdata_srv_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_srv_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_srv_unittest.Tpo -c -o run_unittests-rdata_srv_unittest.obj `if test -f 'rdata_srv_unittest.cc'; then $(CYGPATH_W) 'rdata_srv_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_srv_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_srv_unittest.Tpo $(DEPDIR)/run_unittests-rdata_srv_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_srv_unittest.cc' object='run_unittests-rdata_srv_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_srv_unittest.obj `if test -f 'rdata_srv_unittest.cc'; then $(CYGPATH_W) 'rdata_srv_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_srv_unittest.cc'; fi` + +run_unittests-rdata_tlsa_unittest.o: rdata_tlsa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_tlsa_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_tlsa_unittest.Tpo -c -o run_unittests-rdata_tlsa_unittest.o `test -f 'rdata_tlsa_unittest.cc' || echo '$(srcdir)/'`rdata_tlsa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_tlsa_unittest.Tpo $(DEPDIR)/run_unittests-rdata_tlsa_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_tlsa_unittest.cc' object='run_unittests-rdata_tlsa_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_tlsa_unittest.o `test -f 'rdata_tlsa_unittest.cc' || echo '$(srcdir)/'`rdata_tlsa_unittest.cc + +run_unittests-rdata_tlsa_unittest.obj: rdata_tlsa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_tlsa_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_tlsa_unittest.Tpo -c -o run_unittests-rdata_tlsa_unittest.obj `if test -f 'rdata_tlsa_unittest.cc'; then $(CYGPATH_W) 'rdata_tlsa_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_tlsa_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_tlsa_unittest.Tpo $(DEPDIR)/run_unittests-rdata_tlsa_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_tlsa_unittest.cc' object='run_unittests-rdata_tlsa_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_tlsa_unittest.obj `if test -f 'rdata_tlsa_unittest.cc'; then $(CYGPATH_W) 'rdata_tlsa_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_tlsa_unittest.cc'; fi` + +run_unittests-rdata_minfo_unittest.o: rdata_minfo_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_minfo_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_minfo_unittest.Tpo -c -o run_unittests-rdata_minfo_unittest.o `test -f 'rdata_minfo_unittest.cc' || echo '$(srcdir)/'`rdata_minfo_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_minfo_unittest.Tpo $(DEPDIR)/run_unittests-rdata_minfo_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_minfo_unittest.cc' object='run_unittests-rdata_minfo_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_minfo_unittest.o `test -f 'rdata_minfo_unittest.cc' || echo '$(srcdir)/'`rdata_minfo_unittest.cc + +run_unittests-rdata_minfo_unittest.obj: rdata_minfo_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_minfo_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_minfo_unittest.Tpo -c -o run_unittests-rdata_minfo_unittest.obj `if test -f 'rdata_minfo_unittest.cc'; then $(CYGPATH_W) 'rdata_minfo_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_minfo_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_minfo_unittest.Tpo $(DEPDIR)/run_unittests-rdata_minfo_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_minfo_unittest.cc' object='run_unittests-rdata_minfo_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_minfo_unittest.obj `if test -f 'rdata_minfo_unittest.cc'; then $(CYGPATH_W) 'rdata_minfo_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_minfo_unittest.cc'; fi` + +run_unittests-rdata_tsig_unittest.o: rdata_tsig_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_tsig_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_tsig_unittest.Tpo -c -o run_unittests-rdata_tsig_unittest.o `test -f 'rdata_tsig_unittest.cc' || echo '$(srcdir)/'`rdata_tsig_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_tsig_unittest.Tpo $(DEPDIR)/run_unittests-rdata_tsig_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_tsig_unittest.cc' object='run_unittests-rdata_tsig_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_tsig_unittest.o `test -f 'rdata_tsig_unittest.cc' || echo '$(srcdir)/'`rdata_tsig_unittest.cc + +run_unittests-rdata_tsig_unittest.obj: rdata_tsig_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_tsig_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_tsig_unittest.Tpo -c -o run_unittests-rdata_tsig_unittest.obj `if test -f 'rdata_tsig_unittest.cc'; then $(CYGPATH_W) 'rdata_tsig_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_tsig_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_tsig_unittest.Tpo $(DEPDIR)/run_unittests-rdata_tsig_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_tsig_unittest.cc' object='run_unittests-rdata_tsig_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_tsig_unittest.obj `if test -f 'rdata_tsig_unittest.cc'; then $(CYGPATH_W) 'rdata_tsig_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_tsig_unittest.cc'; fi` + +run_unittests-rdata_naptr_unittest.o: rdata_naptr_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_naptr_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_naptr_unittest.Tpo -c -o run_unittests-rdata_naptr_unittest.o `test -f 'rdata_naptr_unittest.cc' || echo '$(srcdir)/'`rdata_naptr_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_naptr_unittest.Tpo $(DEPDIR)/run_unittests-rdata_naptr_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_naptr_unittest.cc' object='run_unittests-rdata_naptr_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_naptr_unittest.o `test -f 'rdata_naptr_unittest.cc' || echo '$(srcdir)/'`rdata_naptr_unittest.cc + +run_unittests-rdata_naptr_unittest.obj: rdata_naptr_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_naptr_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_naptr_unittest.Tpo -c -o run_unittests-rdata_naptr_unittest.obj `if test -f 'rdata_naptr_unittest.cc'; then $(CYGPATH_W) 'rdata_naptr_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_naptr_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_naptr_unittest.Tpo $(DEPDIR)/run_unittests-rdata_naptr_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_naptr_unittest.cc' object='run_unittests-rdata_naptr_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_naptr_unittest.obj `if test -f 'rdata_naptr_unittest.cc'; then $(CYGPATH_W) 'rdata_naptr_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_naptr_unittest.cc'; fi` + +run_unittests-rdata_hinfo_unittest.o: rdata_hinfo_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_hinfo_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_hinfo_unittest.Tpo -c -o run_unittests-rdata_hinfo_unittest.o `test -f 'rdata_hinfo_unittest.cc' || echo '$(srcdir)/'`rdata_hinfo_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_hinfo_unittest.Tpo $(DEPDIR)/run_unittests-rdata_hinfo_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_hinfo_unittest.cc' object='run_unittests-rdata_hinfo_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_hinfo_unittest.o `test -f 'rdata_hinfo_unittest.cc' || echo '$(srcdir)/'`rdata_hinfo_unittest.cc + +run_unittests-rdata_hinfo_unittest.obj: rdata_hinfo_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_hinfo_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_hinfo_unittest.Tpo -c -o run_unittests-rdata_hinfo_unittest.obj `if test -f 'rdata_hinfo_unittest.cc'; then $(CYGPATH_W) 'rdata_hinfo_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_hinfo_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_hinfo_unittest.Tpo $(DEPDIR)/run_unittests-rdata_hinfo_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_hinfo_unittest.cc' object='run_unittests-rdata_hinfo_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_hinfo_unittest.obj `if test -f 'rdata_hinfo_unittest.cc'; then $(CYGPATH_W) 'rdata_hinfo_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_hinfo_unittest.cc'; fi` + +run_unittests-rdata_caa_unittest.o: rdata_caa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_caa_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_caa_unittest.Tpo -c -o run_unittests-rdata_caa_unittest.o `test -f 'rdata_caa_unittest.cc' || echo '$(srcdir)/'`rdata_caa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_caa_unittest.Tpo $(DEPDIR)/run_unittests-rdata_caa_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_caa_unittest.cc' object='run_unittests-rdata_caa_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_caa_unittest.o `test -f 'rdata_caa_unittest.cc' || echo '$(srcdir)/'`rdata_caa_unittest.cc + +run_unittests-rdata_caa_unittest.obj: rdata_caa_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_caa_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_caa_unittest.Tpo -c -o run_unittests-rdata_caa_unittest.obj `if test -f 'rdata_caa_unittest.cc'; then $(CYGPATH_W) 'rdata_caa_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_caa_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_caa_unittest.Tpo $(DEPDIR)/run_unittests-rdata_caa_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_caa_unittest.cc' object='run_unittests-rdata_caa_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_caa_unittest.obj `if test -f 'rdata_caa_unittest.cc'; then $(CYGPATH_W) 'rdata_caa_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_caa_unittest.cc'; fi` + +run_unittests-rdata_tkey_unittest.o: rdata_tkey_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_tkey_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rdata_tkey_unittest.Tpo -c -o run_unittests-rdata_tkey_unittest.o `test -f 'rdata_tkey_unittest.cc' || echo '$(srcdir)/'`rdata_tkey_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_tkey_unittest.Tpo $(DEPDIR)/run_unittests-rdata_tkey_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_tkey_unittest.cc' object='run_unittests-rdata_tkey_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_tkey_unittest.o `test -f 'rdata_tkey_unittest.cc' || echo '$(srcdir)/'`rdata_tkey_unittest.cc + +run_unittests-rdata_tkey_unittest.obj: rdata_tkey_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rdata_tkey_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rdata_tkey_unittest.Tpo -c -o run_unittests-rdata_tkey_unittest.obj `if test -f 'rdata_tkey_unittest.cc'; then $(CYGPATH_W) 'rdata_tkey_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_tkey_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rdata_tkey_unittest.Tpo $(DEPDIR)/run_unittests-rdata_tkey_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rdata_tkey_unittest.cc' object='run_unittests-rdata_tkey_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rdata_tkey_unittest.obj `if test -f 'rdata_tkey_unittest.cc'; then $(CYGPATH_W) 'rdata_tkey_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rdata_tkey_unittest.cc'; fi` + +run_unittests-rrset_unittest.o: rrset_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrset_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rrset_unittest.Tpo -c -o run_unittests-rrset_unittest.o `test -f 'rrset_unittest.cc' || echo '$(srcdir)/'`rrset_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrset_unittest.Tpo $(DEPDIR)/run_unittests-rrset_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrset_unittest.cc' object='run_unittests-rrset_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrset_unittest.o `test -f 'rrset_unittest.cc' || echo '$(srcdir)/'`rrset_unittest.cc + +run_unittests-rrset_unittest.obj: rrset_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrset_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rrset_unittest.Tpo -c -o run_unittests-rrset_unittest.obj `if test -f 'rrset_unittest.cc'; then $(CYGPATH_W) 'rrset_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrset_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrset_unittest.Tpo $(DEPDIR)/run_unittests-rrset_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrset_unittest.cc' object='run_unittests-rrset_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrset_unittest.obj `if test -f 'rrset_unittest.cc'; then $(CYGPATH_W) 'rrset_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrset_unittest.cc'; fi` + +run_unittests-qid_gen_unittest.o: qid_gen_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-qid_gen_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-qid_gen_unittest.Tpo -c -o run_unittests-qid_gen_unittest.o `test -f 'qid_gen_unittest.cc' || echo '$(srcdir)/'`qid_gen_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-qid_gen_unittest.Tpo $(DEPDIR)/run_unittests-qid_gen_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='qid_gen_unittest.cc' object='run_unittests-qid_gen_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-qid_gen_unittest.o `test -f 'qid_gen_unittest.cc' || echo '$(srcdir)/'`qid_gen_unittest.cc + +run_unittests-qid_gen_unittest.obj: qid_gen_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-qid_gen_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-qid_gen_unittest.Tpo -c -o run_unittests-qid_gen_unittest.obj `if test -f 'qid_gen_unittest.cc'; then $(CYGPATH_W) 'qid_gen_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/qid_gen_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-qid_gen_unittest.Tpo $(DEPDIR)/run_unittests-qid_gen_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='qid_gen_unittest.cc' object='run_unittests-qid_gen_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-qid_gen_unittest.obj `if test -f 'qid_gen_unittest.cc'; then $(CYGPATH_W) 'qid_gen_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/qid_gen_unittest.cc'; fi` + +run_unittests-question_unittest.o: question_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-question_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-question_unittest.Tpo -c -o run_unittests-question_unittest.o `test -f 'question_unittest.cc' || echo '$(srcdir)/'`question_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-question_unittest.Tpo $(DEPDIR)/run_unittests-question_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='question_unittest.cc' object='run_unittests-question_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-question_unittest.o `test -f 'question_unittest.cc' || echo '$(srcdir)/'`question_unittest.cc + +run_unittests-question_unittest.obj: question_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-question_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-question_unittest.Tpo -c -o run_unittests-question_unittest.obj `if test -f 'question_unittest.cc'; then $(CYGPATH_W) 'question_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/question_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-question_unittest.Tpo $(DEPDIR)/run_unittests-question_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='question_unittest.cc' object='run_unittests-question_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-question_unittest.obj `if test -f 'question_unittest.cc'; then $(CYGPATH_W) 'question_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/question_unittest.cc'; fi` + +run_unittests-rrparamregistry_unittest.o: rrparamregistry_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrparamregistry_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rrparamregistry_unittest.Tpo -c -o run_unittests-rrparamregistry_unittest.o `test -f 'rrparamregistry_unittest.cc' || echo '$(srcdir)/'`rrparamregistry_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrparamregistry_unittest.Tpo $(DEPDIR)/run_unittests-rrparamregistry_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrparamregistry_unittest.cc' object='run_unittests-rrparamregistry_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrparamregistry_unittest.o `test -f 'rrparamregistry_unittest.cc' || echo '$(srcdir)/'`rrparamregistry_unittest.cc + +run_unittests-rrparamregistry_unittest.obj: rrparamregistry_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrparamregistry_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rrparamregistry_unittest.Tpo -c -o run_unittests-rrparamregistry_unittest.obj `if test -f 'rrparamregistry_unittest.cc'; then $(CYGPATH_W) 'rrparamregistry_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrparamregistry_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrparamregistry_unittest.Tpo $(DEPDIR)/run_unittests-rrparamregistry_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrparamregistry_unittest.cc' object='run_unittests-rrparamregistry_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrparamregistry_unittest.obj `if test -f 'rrparamregistry_unittest.cc'; then $(CYGPATH_W) 'rrparamregistry_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrparamregistry_unittest.cc'; fi` + +run_unittests-masterload_unittest.o: masterload_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-masterload_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-masterload_unittest.Tpo -c -o run_unittests-masterload_unittest.o `test -f 'masterload_unittest.cc' || echo '$(srcdir)/'`masterload_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-masterload_unittest.Tpo $(DEPDIR)/run_unittests-masterload_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='masterload_unittest.cc' object='run_unittests-masterload_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-masterload_unittest.o `test -f 'masterload_unittest.cc' || echo '$(srcdir)/'`masterload_unittest.cc + +run_unittests-masterload_unittest.obj: masterload_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-masterload_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-masterload_unittest.Tpo -c -o run_unittests-masterload_unittest.obj `if test -f 'masterload_unittest.cc'; then $(CYGPATH_W) 'masterload_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/masterload_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-masterload_unittest.Tpo $(DEPDIR)/run_unittests-masterload_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='masterload_unittest.cc' object='run_unittests-masterload_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-masterload_unittest.obj `if test -f 'masterload_unittest.cc'; then $(CYGPATH_W) 'masterload_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/masterload_unittest.cc'; fi` + +run_unittests-message_unittest.o: message_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-message_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-message_unittest.Tpo -c -o run_unittests-message_unittest.o `test -f 'message_unittest.cc' || echo '$(srcdir)/'`message_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-message_unittest.Tpo $(DEPDIR)/run_unittests-message_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='message_unittest.cc' object='run_unittests-message_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-message_unittest.o `test -f 'message_unittest.cc' || echo '$(srcdir)/'`message_unittest.cc + +run_unittests-message_unittest.obj: message_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-message_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-message_unittest.Tpo -c -o run_unittests-message_unittest.obj `if test -f 'message_unittest.cc'; then $(CYGPATH_W) 'message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/message_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-message_unittest.Tpo $(DEPDIR)/run_unittests-message_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='message_unittest.cc' object='run_unittests-message_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-message_unittest.obj `if test -f 'message_unittest.cc'; then $(CYGPATH_W) 'message_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/message_unittest.cc'; fi` + +run_unittests-serial_unittest.o: serial_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-serial_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-serial_unittest.Tpo -c -o run_unittests-serial_unittest.o `test -f 'serial_unittest.cc' || echo '$(srcdir)/'`serial_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-serial_unittest.Tpo $(DEPDIR)/run_unittests-serial_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='serial_unittest.cc' object='run_unittests-serial_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-serial_unittest.o `test -f 'serial_unittest.cc' || echo '$(srcdir)/'`serial_unittest.cc + +run_unittests-serial_unittest.obj: serial_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-serial_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-serial_unittest.Tpo -c -o run_unittests-serial_unittest.obj `if test -f 'serial_unittest.cc'; then $(CYGPATH_W) 'serial_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/serial_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-serial_unittest.Tpo $(DEPDIR)/run_unittests-serial_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='serial_unittest.cc' object='run_unittests-serial_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-serial_unittest.obj `if test -f 'serial_unittest.cc'; then $(CYGPATH_W) 'serial_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/serial_unittest.cc'; fi` + +run_unittests-tsig_unittest.o: tsig_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-tsig_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-tsig_unittest.Tpo -c -o run_unittests-tsig_unittest.o `test -f 'tsig_unittest.cc' || echo '$(srcdir)/'`tsig_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-tsig_unittest.Tpo $(DEPDIR)/run_unittests-tsig_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tsig_unittest.cc' object='run_unittests-tsig_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-tsig_unittest.o `test -f 'tsig_unittest.cc' || echo '$(srcdir)/'`tsig_unittest.cc + +run_unittests-tsig_unittest.obj: tsig_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-tsig_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-tsig_unittest.Tpo -c -o run_unittests-tsig_unittest.obj `if test -f 'tsig_unittest.cc'; then $(CYGPATH_W) 'tsig_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/tsig_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-tsig_unittest.Tpo $(DEPDIR)/run_unittests-tsig_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tsig_unittest.cc' object='run_unittests-tsig_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-tsig_unittest.obj `if test -f 'tsig_unittest.cc'; then $(CYGPATH_W) 'tsig_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/tsig_unittest.cc'; fi` + +run_unittests-tsigerror_unittest.o: tsigerror_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-tsigerror_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-tsigerror_unittest.Tpo -c -o run_unittests-tsigerror_unittest.o `test -f 'tsigerror_unittest.cc' || echo '$(srcdir)/'`tsigerror_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-tsigerror_unittest.Tpo $(DEPDIR)/run_unittests-tsigerror_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tsigerror_unittest.cc' object='run_unittests-tsigerror_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-tsigerror_unittest.o `test -f 'tsigerror_unittest.cc' || echo '$(srcdir)/'`tsigerror_unittest.cc + +run_unittests-tsigerror_unittest.obj: tsigerror_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-tsigerror_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-tsigerror_unittest.Tpo -c -o run_unittests-tsigerror_unittest.obj `if test -f 'tsigerror_unittest.cc'; then $(CYGPATH_W) 'tsigerror_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/tsigerror_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-tsigerror_unittest.Tpo $(DEPDIR)/run_unittests-tsigerror_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tsigerror_unittest.cc' object='run_unittests-tsigerror_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-tsigerror_unittest.obj `if test -f 'tsigerror_unittest.cc'; then $(CYGPATH_W) 'tsigerror_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/tsigerror_unittest.cc'; fi` + +run_unittests-tsigkey_unittest.o: tsigkey_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-tsigkey_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-tsigkey_unittest.Tpo -c -o run_unittests-tsigkey_unittest.o `test -f 'tsigkey_unittest.cc' || echo '$(srcdir)/'`tsigkey_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-tsigkey_unittest.Tpo $(DEPDIR)/run_unittests-tsigkey_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tsigkey_unittest.cc' object='run_unittests-tsigkey_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-tsigkey_unittest.o `test -f 'tsigkey_unittest.cc' || echo '$(srcdir)/'`tsigkey_unittest.cc + +run_unittests-tsigkey_unittest.obj: tsigkey_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-tsigkey_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-tsigkey_unittest.Tpo -c -o run_unittests-tsigkey_unittest.obj `if test -f 'tsigkey_unittest.cc'; then $(CYGPATH_W) 'tsigkey_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/tsigkey_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-tsigkey_unittest.Tpo $(DEPDIR)/run_unittests-tsigkey_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tsigkey_unittest.cc' object='run_unittests-tsigkey_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-tsigkey_unittest.obj `if test -f 'tsigkey_unittest.cc'; then $(CYGPATH_W) 'tsigkey_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/tsigkey_unittest.cc'; fi` + +run_unittests-tsigrecord_unittest.o: tsigrecord_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-tsigrecord_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-tsigrecord_unittest.Tpo -c -o run_unittests-tsigrecord_unittest.o `test -f 'tsigrecord_unittest.cc' || echo '$(srcdir)/'`tsigrecord_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-tsigrecord_unittest.Tpo $(DEPDIR)/run_unittests-tsigrecord_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tsigrecord_unittest.cc' object='run_unittests-tsigrecord_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-tsigrecord_unittest.o `test -f 'tsigrecord_unittest.cc' || echo '$(srcdir)/'`tsigrecord_unittest.cc + +run_unittests-tsigrecord_unittest.obj: tsigrecord_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-tsigrecord_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-tsigrecord_unittest.Tpo -c -o run_unittests-tsigrecord_unittest.obj `if test -f 'tsigrecord_unittest.cc'; then $(CYGPATH_W) 'tsigrecord_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/tsigrecord_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-tsigrecord_unittest.Tpo $(DEPDIR)/run_unittests-tsigrecord_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='tsigrecord_unittest.cc' object='run_unittests-tsigrecord_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-tsigrecord_unittest.obj `if test -f 'tsigrecord_unittest.cc'; then $(CYGPATH_W) 'tsigrecord_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/tsigrecord_unittest.cc'; fi` + +run_unittests-master_loader_callbacks_test.o: master_loader_callbacks_test.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_loader_callbacks_test.o -MD -MP -MF $(DEPDIR)/run_unittests-master_loader_callbacks_test.Tpo -c -o run_unittests-master_loader_callbacks_test.o `test -f 'master_loader_callbacks_test.cc' || echo '$(srcdir)/'`master_loader_callbacks_test.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_loader_callbacks_test.Tpo $(DEPDIR)/run_unittests-master_loader_callbacks_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_loader_callbacks_test.cc' object='run_unittests-master_loader_callbacks_test.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_loader_callbacks_test.o `test -f 'master_loader_callbacks_test.cc' || echo '$(srcdir)/'`master_loader_callbacks_test.cc + +run_unittests-master_loader_callbacks_test.obj: master_loader_callbacks_test.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-master_loader_callbacks_test.obj -MD -MP -MF $(DEPDIR)/run_unittests-master_loader_callbacks_test.Tpo -c -o run_unittests-master_loader_callbacks_test.obj `if test -f 'master_loader_callbacks_test.cc'; then $(CYGPATH_W) 'master_loader_callbacks_test.cc'; else $(CYGPATH_W) '$(srcdir)/master_loader_callbacks_test.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-master_loader_callbacks_test.Tpo $(DEPDIR)/run_unittests-master_loader_callbacks_test.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='master_loader_callbacks_test.cc' object='run_unittests-master_loader_callbacks_test.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-master_loader_callbacks_test.obj `if test -f 'master_loader_callbacks_test.cc'; then $(CYGPATH_W) 'master_loader_callbacks_test.cc'; else $(CYGPATH_W) '$(srcdir)/master_loader_callbacks_test.cc'; fi` + +run_unittests-rrset_collection_unittest.o: rrset_collection_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrset_collection_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-rrset_collection_unittest.Tpo -c -o run_unittests-rrset_collection_unittest.o `test -f 'rrset_collection_unittest.cc' || echo '$(srcdir)/'`rrset_collection_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrset_collection_unittest.Tpo $(DEPDIR)/run_unittests-rrset_collection_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrset_collection_unittest.cc' object='run_unittests-rrset_collection_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrset_collection_unittest.o `test -f 'rrset_collection_unittest.cc' || echo '$(srcdir)/'`rrset_collection_unittest.cc + +run_unittests-rrset_collection_unittest.obj: rrset_collection_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-rrset_collection_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-rrset_collection_unittest.Tpo -c -o run_unittests-rrset_collection_unittest.obj `if test -f 'rrset_collection_unittest.cc'; then $(CYGPATH_W) 'rrset_collection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrset_collection_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-rrset_collection_unittest.Tpo $(DEPDIR)/run_unittests-rrset_collection_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='rrset_collection_unittest.cc' object='run_unittests-rrset_collection_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-rrset_collection_unittest.obj `if test -f 'rrset_collection_unittest.cc'; then $(CYGPATH_W) 'rrset_collection_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/rrset_collection_unittest.cc'; fi` + +run_unittests-zone_checker_unittest.o: zone_checker_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-zone_checker_unittest.o -MD -MP -MF $(DEPDIR)/run_unittests-zone_checker_unittest.Tpo -c -o run_unittests-zone_checker_unittest.o `test -f 'zone_checker_unittest.cc' || echo '$(srcdir)/'`zone_checker_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-zone_checker_unittest.Tpo $(DEPDIR)/run_unittests-zone_checker_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='zone_checker_unittest.cc' object='run_unittests-zone_checker_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-zone_checker_unittest.o `test -f 'zone_checker_unittest.cc' || echo '$(srcdir)/'`zone_checker_unittest.cc + +run_unittests-zone_checker_unittest.obj: zone_checker_unittest.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-zone_checker_unittest.obj -MD -MP -MF $(DEPDIR)/run_unittests-zone_checker_unittest.Tpo -c -o run_unittests-zone_checker_unittest.obj `if test -f 'zone_checker_unittest.cc'; then $(CYGPATH_W) 'zone_checker_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/zone_checker_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-zone_checker_unittest.Tpo $(DEPDIR)/run_unittests-zone_checker_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='zone_checker_unittest.cc' object='run_unittests-zone_checker_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-zone_checker_unittest.obj `if test -f 'zone_checker_unittest.cc'; then $(CYGPATH_W) 'zone_checker_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/zone_checker_unittest.cc'; fi` + +run_unittests-run_unittests.o: run_unittests.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-run_unittests.o -MD -MP -MF $(DEPDIR)/run_unittests-run_unittests.Tpo -c -o run_unittests-run_unittests.o `test -f 'run_unittests.cc' || echo '$(srcdir)/'`run_unittests.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-run_unittests.Tpo $(DEPDIR)/run_unittests-run_unittests.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='run_unittests.cc' object='run_unittests-run_unittests.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-run_unittests.o `test -f 'run_unittests.cc' || echo '$(srcdir)/'`run_unittests.cc + +run_unittests-run_unittests.obj: run_unittests.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT run_unittests-run_unittests.obj -MD -MP -MF $(DEPDIR)/run_unittests-run_unittests.Tpo -c -o run_unittests-run_unittests.obj `if test -f 'run_unittests.cc'; then $(CYGPATH_W) 'run_unittests.cc'; else $(CYGPATH_W) '$(srcdir)/run_unittests.cc'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/run_unittests-run_unittests.Tpo $(DEPDIR)/run_unittests-run_unittests.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='run_unittests.cc' object='run_unittests-run_unittests.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(run_unittests_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o run_unittests-run_unittests.obj `if test -f 'run_unittests.cc'; then $(CYGPATH_W) 'run_unittests.cc'; else $(CYGPATH_W) '$(srcdir)/run_unittests.cc'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(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-recursive + +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-recursive + +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 + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +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 + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-recursive +all-am: Makefile $(PROGRAMS) +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +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) + +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-recursive + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/run_unittests-dns_exceptions_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-edns_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-labelsequence_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-master_lexer_inputsource_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-master_lexer_state_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-master_lexer_token_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-master_lexer_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-master_loader_callbacks_test.Po + -rm -f ./$(DEPDIR)/run_unittests-master_loader_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-masterload_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-message_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-messagerenderer_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-name_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-nsec3hash_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-opcode_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-qid_gen_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-question_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rcode_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_afsdb_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_caa_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_char_string_data_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_char_string_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_cname_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_dhcid_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_dname_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_dnskey_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_ds_like_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_hinfo_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_in_a_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_in_aaaa_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_minfo_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_mx_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_naptr_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_ns_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_nsec3_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_nsec3param_like_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_nsec3param_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_nsec_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_nsecbitmap_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_opt_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_pimpl_holder_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_ptr_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_rp_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_rrsig_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_soa_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_srv_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_sshfp_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_tkey_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_tlsa_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_tsig_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_txt_like_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdatafields_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrclass_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrcollator_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrparamregistry_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrset_collection_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrset_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrttl_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrtype_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-run_unittests.Po + -rm -f ./$(DEPDIR)/run_unittests-serial_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-tsig_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-tsigerror_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-tsigkey_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-tsigrecord_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-unittest_util.Po + -rm -f ./$(DEPDIR)/run_unittests-zone_checker_unittest.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/run_unittests-dns_exceptions_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-edns_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-labelsequence_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-master_lexer_inputsource_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-master_lexer_state_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-master_lexer_token_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-master_lexer_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-master_loader_callbacks_test.Po + -rm -f ./$(DEPDIR)/run_unittests-master_loader_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-masterload_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-message_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-messagerenderer_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-name_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-nsec3hash_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-opcode_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-qid_gen_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-question_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rcode_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_afsdb_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_caa_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_char_string_data_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_char_string_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_cname_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_dhcid_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_dname_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_dnskey_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_ds_like_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_hinfo_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_in_a_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_in_aaaa_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_minfo_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_mx_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_naptr_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_ns_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_nsec3_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_nsec3param_like_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_nsec3param_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_nsec_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_nsecbitmap_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_opt_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_pimpl_holder_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_ptr_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_rp_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_rrsig_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_soa_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_srv_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_sshfp_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_tkey_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_tlsa_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_tsig_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_txt_like_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdata_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rdatafields_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrclass_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrcollator_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrparamregistry_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrset_collection_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrset_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrttl_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-rrtype_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-run_unittests.Po + -rm -f ./$(DEPDIR)/run_unittests-serial_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-tsig_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-tsigerror_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-tsigkey_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-tsigrecord_unittest.Po + -rm -f ./$(DEPDIR)/run_unittests-unittest_util.Po + -rm -f ./$(DEPDIR)/run_unittests-zone_checker_unittest.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) check-am install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-TESTS check-am clean clean-generic \ + clean-libtool clean-noinstPROGRAMS 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 installdirs-am 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 + + +# 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/src/lib/dns/tests/dns_exceptions_unittest.cc b/src/lib/dns/tests/dns_exceptions_unittest.cc new file mode 100644 index 0000000..a8d2590 --- /dev/null +++ b/src/lib/dns/tests/dns_exceptions_unittest.cc @@ -0,0 +1,65 @@ +// Copyright (C) 2014-2015,2017 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/exceptions.h> + +#include <gtest/gtest.h> + +namespace { // begin unnamed namespace + +TEST(DNSExceptionsTest, checkExceptionsHierarchy) { + EXPECT_NO_THROW({ + const isc::dns::Exception exception("", 0, ""); + const isc::Exception& exception_cast = + dynamic_cast<const isc::Exception&>(exception); + // to avoid compiler warning + exception_cast.what(); + }); + + EXPECT_NO_THROW({ + const isc::dns::DNSTextError exception("", 0, ""); + const isc::dns::Exception& exception_cast = + dynamic_cast<const isc::dns::Exception&>(exception); + // to avoid compiler warning + exception_cast.what(); + }); + + EXPECT_NO_THROW({ + const isc::dns::NameParserException exception("", 0, ""); + const isc::dns::DNSTextError& exception_cast = + dynamic_cast<const isc::dns::DNSTextError&>(exception); + // to avoid compiler warning + exception_cast.what(); + }); + + EXPECT_NO_THROW({ + const isc::dns::DNSMessageFORMERR exception("", 0, ""); + const isc::dns::DNSProtocolError& exception_cast = + dynamic_cast<const isc::dns::DNSProtocolError&>(exception); + const isc::dns::Exception& exception_cast2 = + dynamic_cast<const isc::dns::Exception&>(exception); + // to avoid compiler warning + exception_cast.getRcode(); + exception_cast.what(); + exception_cast2.what(); + }); + + EXPECT_NO_THROW({ + const isc::dns::DNSMessageBADVERS exception("", 0, ""); + const isc::dns::DNSProtocolError& exception_cast = + dynamic_cast<const isc::dns::DNSProtocolError&>(exception); + const isc::dns::Exception& exception_cast2 = + dynamic_cast<const isc::dns::Exception&>(exception); + // to avoid compiler warning + exception_cast.getRcode(); + exception_cast.what(); + exception_cast2.what(); + }); +} + +} // end unnamed namespace diff --git a/src/lib/dns/tests/edns_unittest.cc b/src/lib/dns/tests/edns_unittest.cc new file mode 100644 index 0000000..dfc68cc --- /dev/null +++ b/src/lib/dns/tests/edns_unittest.cc @@ -0,0 +1,258 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <sstream> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <dns/edns.h> +#include <dns/exceptions.h> +#include <dns/message.h> +#include <dns/messagerenderer.h> +#include <dns/name.h> +#include <dns/rcode.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrttl.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +const uint8_t EDNS::SUPPORTED_VERSION; + +namespace { +class EDNSTest : public ::testing::Test { +protected: + EDNSTest() : rrtype(RRType::OPT()), buffer(NULL, 0), obuffer(0), rcode(0) { + opt_rdata = ConstRdataPtr(new generic::OPT()); + edns_base.setUDPSize(4096); + } + RRType rrtype; + EDNS edns_base; + ConstEDNSPtr edns; + InputBuffer buffer; + OutputBuffer obuffer; + MessageRenderer renderer; + ConstRdataPtr opt_rdata; + Rcode rcode; + vector<unsigned char> wiredata; +}; + +// RRClass of EDNS OPT means UDP buffer size +const RRClass rrclass(4096); +// RRTTL of EDNS OPT encodes extended-rcode, version, and DO bit +const RRTTL rrttl_do_on(0x00008000); // DO=on +const RRTTL rrttl_do_off(0); // DO=off +const RRTTL rrttl_badver(0x00018000); // version=1, DO=on + +TEST_F(EDNSTest, badVerConstruct) { + EXPECT_THROW(EDNS(1), isc::InvalidParameter); +} + +TEST_F(EDNSTest, DNSSECDOBit) { + // tests for EDNS from RR + + // DO bit is on, so DNSSEC should be considered to be supported. + EXPECT_TRUE(EDNS(Name::ROOT_NAME(), rrclass, rrtype, + rrttl_do_on, *opt_rdata).getDNSSECAwareness()); + + // DO bit is off. DNSSEC should be considered to be unsupported. + EXPECT_FALSE(EDNS(Name::ROOT_NAME(), rrclass, rrtype, + rrttl_do_off, *opt_rdata).getDNSSECAwareness()); + + // tests for EDNS constructed by hand + EXPECT_FALSE(edns_base.getDNSSECAwareness()); // false by default + edns_base.setDNSSECAwareness(true); // enable by hand + EXPECT_TRUE(edns_base.getDNSSECAwareness()); + edns_base.setDNSSECAwareness(false); // disable by hand + EXPECT_FALSE(edns_base.getDNSSECAwareness()); +} + +TEST_F(EDNSTest, UDPSize) { + EXPECT_EQ(4096, EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_on, + *opt_rdata).getUDPSize()); + + // EDNS UDP size smaller than the traditional max, 512. Unusual, but + // not prohibited. + edns_base.setUDPSize(511); + EXPECT_EQ(511, edns_base.getUDPSize()); + + // Even 0 is okay. + edns_base.setUDPSize(0); + EXPECT_EQ(0, edns_base.getUDPSize()); + + // Possible max value is also okay, although the higher layer app may + // adjust it to a reasonably lower value + edns_base.setUDPSize(65535); + EXPECT_EQ(65535, edns_base.getUDPSize()); +} + +TEST_F(EDNSTest, getVersion) { + // Constructed by hand + EXPECT_EQ(EDNS::SUPPORTED_VERSION, EDNS().getVersion()); + + // From RR + EXPECT_EQ(EDNS::SUPPORTED_VERSION, + EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_on, + *opt_rdata).getVersion()); +} + +TEST_F(EDNSTest, BadWireData) { + // Incompatible RR type + EXPECT_THROW(EDNS(Name::ROOT_NAME(), rrclass, RRType::A(), + rrttl_do_on, *opt_rdata), isc::InvalidParameter); + + // OPT RR of a non root name + EXPECT_THROW(EDNS(Name("example.com"), rrclass, rrtype, + rrttl_do_on, *opt_rdata), DNSMessageFORMERR); + + // Unsupported Version + EXPECT_THROW(EDNS(Name::ROOT_NAME(), rrclass, rrtype, + rrttl_badver, *opt_rdata), DNSMessageBADVERS); +} + +TEST_F(EDNSTest, toText) { + // Typical case, disabling DNSSEC + EXPECT_EQ("; EDNS: version: 0, flags:; udp: 4096\n", + EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_off, + *opt_rdata).toText()); + + // Typical case, enabling DNSSEC + EXPECT_EQ("; EDNS: version: 0, flags: do; udp: 4096\n", + EDNS(Name::ROOT_NAME(), rrclass, rrtype, rrttl_do_on, + *opt_rdata).toText()); + + // Non-0 extended Rcode: ignored in the toText() output. + EXPECT_EQ("; EDNS: version: 0, flags: do; udp: 4096\n", + EDNS(Name::ROOT_NAME(), rrclass, rrtype, + RRTTL(0x01008000), *opt_rdata).toText()); + + // Unknown flag: ignored in the toText() output. + EXPECT_EQ("; EDNS: version: 0, flags: do; udp: 4096\n", + EDNS(Name::ROOT_NAME(), rrclass, rrtype, + RRTTL(0x00008001), *opt_rdata).toText()); +} + +TEST_F(EDNSTest, toWireRenderer) { + // Typical case, (explicitly) disabling DNSSEC + edns_base.setDNSSECAwareness(false); + EXPECT_EQ(1, edns_base.toWire(renderer, + Rcode::NOERROR().getExtendedCode())); + UnitTestUtil::readWireData("edns_toWire1.wire", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + renderer.getData(), renderer.getLength()); + + // Typical case, enabling DNSSEC + renderer.clear(); + wiredata.clear(); + edns_base.setDNSSECAwareness(true); + EXPECT_EQ(1, edns_base.toWire(renderer, + Rcode::NOERROR().getExtendedCode())); + UnitTestUtil::readWireData("edns_toWire2.wire", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + renderer.getData(), renderer.getLength()); + + // Non-0 extended Rcode + renderer.clear(); + wiredata.clear(); + edns_base.setDNSSECAwareness(true); + EXPECT_EQ(1, edns_base.toWire(renderer, + Rcode::BADVERS().getExtendedCode())); + UnitTestUtil::readWireData("edns_toWire3.wire", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + renderer.getData(), renderer.getLength()); + + // Uncommon UDP buffer size + renderer.clear(); + wiredata.clear(); + edns_base.setDNSSECAwareness(true); + edns_base.setUDPSize(511); + EXPECT_EQ(1, edns_base.toWire(renderer, + Rcode::NOERROR().getExtendedCode())); + UnitTestUtil::readWireData("edns_toWire4.wire", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + renderer.getData(), renderer.getLength()); + + // From RR with unknown flag. If used for toWire(), the unknown flag + // should disappear. + renderer.clear(); + wiredata.clear(); + EXPECT_EQ(1, EDNS(Name::ROOT_NAME(), rrclass, rrtype, RRTTL(0x00008001), + *opt_rdata).toWire(renderer, + Rcode::NOERROR().getExtendedCode())); + UnitTestUtil::readWireData("edns_toWire2.wire", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + renderer.getData(), renderer.getLength()); + + // If the available length in the renderer is not sufficient for the OPT + // RR, it shouldn't be inserted. + renderer.clear(); + renderer.setLengthLimit(10); // 10 = minimum length of OPT RR - 1 + edns_base.setDNSSECAwareness(true); + edns_base.setUDPSize(4096); + EXPECT_EQ(0, edns_base.toWire(renderer, + Rcode::NOERROR().getExtendedCode())); + // renderer should be intact + EXPECT_EQ(0, renderer.getLength()); +} + +TEST_F(EDNSTest, toWireBuffer) { + // "to renderer" and "to buffer" should generally produce the same result. + // for simplicity we only check one typical case to confirm that. + EXPECT_EQ(1, edns_base.toWire(obuffer, + Rcode::NOERROR().getExtendedCode())); + UnitTestUtil::readWireData("edns_toWire1.wire", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(EDNSTest, createFromRR) { + uint8_t extended_rcode; + + // normal case + edns = ConstEDNSPtr(createEDNSFromRR(Name::ROOT_NAME(), rrclass, rrtype, + rrttl_do_on, *opt_rdata, + extended_rcode)); + EXPECT_EQ(EDNS::SUPPORTED_VERSION, edns->getVersion()); + EXPECT_TRUE(edns->getDNSSECAwareness()); + EXPECT_EQ(4096, edns->getUDPSize()); + EXPECT_EQ(0, static_cast<int>(extended_rcode)); + + // non-0 extended rcode + extended_rcode = 0; + ConstEDNSPtr(createEDNSFromRR(Name::ROOT_NAME(), rrclass, rrtype, + RRTTL(0x01008000), *opt_rdata, + extended_rcode)); + EXPECT_EQ(1, static_cast<int>(extended_rcode)); + + // creation triggers an exception. extended_rcode must be intact. + extended_rcode = 0; + EXPECT_THROW(createEDNSFromRR(Name::ROOT_NAME(), rrclass, rrtype, + rrttl_badver, *opt_rdata, extended_rcode), + DNSMessageBADVERS); + EXPECT_EQ(0, static_cast<int>(extended_rcode)); +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST_F(EDNSTest, LeftShiftOperator) { + ostringstream oss; + oss << edns_base; + EXPECT_EQ(edns_base.toText(), oss.str()); +} +} diff --git a/src/lib/dns/tests/labelsequence_unittest.cc b/src/lib/dns/tests/labelsequence_unittest.cc new file mode 100644 index 0000000..15650fa --- /dev/null +++ b/src/lib/dns/tests/labelsequence_unittest.cc @@ -0,0 +1,1243 @@ +// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> + +#include <dns/labelsequence.h> +#include <dns/name.h> +#include <exceptions/exceptions.h> + +#include <gtest/gtest.h> + +#include <boost/functional/hash.hpp> + +#include <string> +#include <vector> +#include <utility> +#include <set> + +using namespace isc::dns; +using namespace std; + +// XXX: this is defined as class static constants, but some compilers +// seemingly cannot find the symbols when used in the EXPECT_xxx macros. +const size_t LabelSequence::MAX_SERIALIZED_LENGTH; + +namespace { + +// Common check that two labelsequences are equal +void check_equal(const LabelSequence& ls1, const LabelSequence& ls2) { + NameComparisonResult result = ls1.compare(ls2); + EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL, + result.getRelation()) << ls1.toText() << " != " << ls2.toText(); + EXPECT_EQ(0, result.getOrder()) << ls1.toText() << " != " << ls2.toText(); + EXPECT_EQ(ls1.getLabelCount(), result.getCommonLabels()); +} + +// Common check for general comparison of two labelsequences +void check_compare(const LabelSequence& ls1, const LabelSequence& ls2, + isc::dns::NameComparisonResult::NameRelation relation, + size_t common_labels, bool check_order, int order=0) { + NameComparisonResult result = ls1.compare(ls2); + EXPECT_EQ(relation, result.getRelation()); + EXPECT_EQ(common_labels, result.getCommonLabels()); + if (check_order) { + EXPECT_EQ(order, result.getOrder()); + } +} + +class LabelSequenceTest : public ::testing::Test { +public: + LabelSequenceTest() : n1("example.org"), n2("example.com"), + n3("example.org"), n4("foo.bar.test.example"), + n5("example.ORG"), n6("ExAmPlE.org"), + n7("."), n8("foo.example.org.bar"), + n9("\\000xample.org"), + n10("\\000xample.org"), + n11("\\000xample.com"), + n12("\\000xamplE.com"), + n_maxlabel("0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6"), + ls1(n1), ls2(n2), ls3(n3), ls4(n4), ls5(n5), + ls6(n6), ls7(n7), ls8(n8), + ls9(n9), ls10(n10), ls11(n11), ls12(n12) + {}; + // Need to keep names in scope for at least the lifetime of + // the labelsequences + Name n1, n2, n3, n4, n5, n6, n7, n8; + Name n9, n10, n11, n12; + const Name n_maxlabel; + + LabelSequence ls1, ls2, ls3, ls4, ls5, ls6, ls7, ls8; + LabelSequence ls9, ls10, ls11, ls12; +}; + +// Check the assignment operator. +TEST_F(LabelSequenceTest, assign) { + // Create the label sequence with example.org (n1 name). + LabelSequence ls(n1); + EXPECT_TRUE(ls == ls1); + + // Assign the label sequence to example.com (n2 name). + ls = ls2; + EXPECT_FALSE(ls == ls1); + EXPECT_TRUE(ls == ls2); +} + +// Basic equality tests +TEST_F(LabelSequenceTest, equals_sensitive) { + EXPECT_TRUE(ls1.equals(ls1, true)); + EXPECT_FALSE(ls1.equals(ls2, true)); + EXPECT_TRUE(ls1.equals(ls3, true)); + EXPECT_FALSE(ls1.equals(ls4, true)); + EXPECT_FALSE(ls1.equals(ls5, true)); + EXPECT_FALSE(ls1.equals(ls6, true)); + EXPECT_FALSE(ls1.equals(ls7, true)); + EXPECT_FALSE(ls1.equals(ls8, true)); + + EXPECT_FALSE(ls2.equals(ls1, true)); + EXPECT_TRUE(ls2.equals(ls2, true)); + EXPECT_FALSE(ls2.equals(ls3, true)); + EXPECT_FALSE(ls2.equals(ls4, true)); + EXPECT_FALSE(ls2.equals(ls5, true)); + EXPECT_FALSE(ls2.equals(ls6, true)); + EXPECT_FALSE(ls2.equals(ls7, true)); + EXPECT_FALSE(ls2.equals(ls8, true)); + + EXPECT_FALSE(ls4.equals(ls1, true)); + EXPECT_FALSE(ls4.equals(ls2, true)); + EXPECT_FALSE(ls4.equals(ls3, true)); + EXPECT_TRUE(ls4.equals(ls4, true)); + EXPECT_FALSE(ls4.equals(ls5, true)); + EXPECT_FALSE(ls4.equals(ls6, true)); + EXPECT_FALSE(ls4.equals(ls7, true)); + EXPECT_FALSE(ls4.equals(ls8, true)); + + EXPECT_FALSE(ls5.equals(ls1, true)); + EXPECT_FALSE(ls5.equals(ls2, true)); + EXPECT_FALSE(ls5.equals(ls3, true)); + EXPECT_FALSE(ls5.equals(ls4, true)); + EXPECT_TRUE(ls5.equals(ls5, true)); + EXPECT_FALSE(ls5.equals(ls6, true)); + EXPECT_FALSE(ls5.equals(ls7, true)); + EXPECT_FALSE(ls5.equals(ls8, true)); + + EXPECT_TRUE(ls9.equals(ls10, true)); + EXPECT_FALSE(ls9.equals(ls11, true)); + EXPECT_FALSE(ls9.equals(ls12, true)); + EXPECT_FALSE(ls11.equals(ls12, true)); +} + +TEST_F(LabelSequenceTest, equals_insensitive) { + EXPECT_TRUE(ls1.equals(ls1)); + EXPECT_FALSE(ls1.equals(ls2)); + EXPECT_TRUE(ls1.equals(ls3)); + EXPECT_FALSE(ls1.equals(ls4)); + EXPECT_TRUE(ls1.equals(ls5)); + EXPECT_TRUE(ls1.equals(ls6)); + EXPECT_FALSE(ls1.equals(ls7)); + + EXPECT_FALSE(ls2.equals(ls1)); + EXPECT_TRUE(ls2.equals(ls2)); + EXPECT_FALSE(ls2.equals(ls3)); + EXPECT_FALSE(ls2.equals(ls4)); + EXPECT_FALSE(ls2.equals(ls5)); + EXPECT_FALSE(ls2.equals(ls6)); + EXPECT_FALSE(ls2.equals(ls7)); + + EXPECT_TRUE(ls3.equals(ls1)); + EXPECT_FALSE(ls3.equals(ls2)); + EXPECT_TRUE(ls3.equals(ls3)); + EXPECT_FALSE(ls3.equals(ls4)); + EXPECT_TRUE(ls3.equals(ls5)); + EXPECT_TRUE(ls3.equals(ls6)); + EXPECT_FALSE(ls3.equals(ls7)); + + EXPECT_FALSE(ls4.equals(ls1)); + EXPECT_FALSE(ls4.equals(ls2)); + EXPECT_FALSE(ls4.equals(ls3)); + EXPECT_TRUE(ls4.equals(ls4)); + EXPECT_FALSE(ls4.equals(ls5)); + EXPECT_FALSE(ls4.equals(ls6)); + EXPECT_FALSE(ls4.equals(ls7)); + + EXPECT_TRUE(ls5.equals(ls1)); + EXPECT_FALSE(ls5.equals(ls2)); + EXPECT_TRUE(ls5.equals(ls3)); + EXPECT_FALSE(ls5.equals(ls4)); + EXPECT_TRUE(ls5.equals(ls5)); + EXPECT_TRUE(ls5.equals(ls6)); + EXPECT_FALSE(ls5.equals(ls7)); + + EXPECT_TRUE(ls9.equals(ls10)); + EXPECT_FALSE(ls9.equals(ls11)); + EXPECT_FALSE(ls9.equals(ls12)); + EXPECT_TRUE(ls11.equals(ls12)); +} + +// operator==(). This is mostly trivial wrapper, so it should suffice to +// check some basic cases. +TEST_F(LabelSequenceTest, operatorEqual) { + // cppcheck-suppress duplicateExpression + EXPECT_TRUE(ls1 == ls1); // self equivalence + EXPECT_TRUE(ls1 == LabelSequence(n1)); // equivalent two different objects + EXPECT_FALSE(ls1 == ls2); // non equivalent objects + EXPECT_TRUE(ls1 == ls5); // it's always case insensitive +} + +// Compare tests +TEST_F(LabelSequenceTest, compare) { + // "example.org." and "example.org.", case sensitive + NameComparisonResult result = ls1.compare(ls3, true); + EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL, + result.getRelation()); + EXPECT_EQ(0, result.getOrder()); + EXPECT_EQ(3, result.getCommonLabels()); + + // "example.org." and "example.ORG.", case sensitive + result = ls3.compare(ls5, true); + EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR, + result.getRelation()); + EXPECT_LT(0, result.getOrder()); + EXPECT_EQ(1, result.getCommonLabels()); + + // "example.org." and "example.ORG.", case in-sensitive + result = ls3.compare(ls5); + EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL, + result.getRelation()); + EXPECT_EQ(0, result.getOrder()); + EXPECT_EQ(3, result.getCommonLabels()); + + Name na("a.example.org"); + Name nb("b.example.org"); + LabelSequence lsa(na); + LabelSequence lsb(nb); + + // "a.example.org." and "b.example.org.", case in-sensitive + result = lsa.compare(lsb); + EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR, + result.getRelation()); + EXPECT_GT(0, result.getOrder()); + EXPECT_EQ(3, result.getCommonLabels()); + + // "example.org." and "b.example.org.", case in-sensitive + lsa.stripLeft(1); + result = lsa.compare(lsb); + EXPECT_EQ(isc::dns::NameComparisonResult::SUPERDOMAIN, + result.getRelation()); + EXPECT_GT(0, result.getOrder()); + EXPECT_EQ(3, result.getCommonLabels()); + + Name nc("g.f.e.d.c.example.org"); + LabelSequence lsc(nc); + + // "g.f.e.d.c.example.org." and "b.example.org" (not absolute), case + // in-sensitive; the absolute one is always smaller. + lsb.stripRight(1); + result = lsc.compare(lsb); + EXPECT_EQ(isc::dns::NameComparisonResult::NONE, result.getRelation()); + EXPECT_GT(0, result.getOrder()); + EXPECT_EQ(0, result.getCommonLabels()); + + // "g.f.e.d.c.example.org." and "example.org.", case in-sensitive + result = lsc.compare(ls1); + EXPECT_EQ(isc::dns::NameComparisonResult::SUBDOMAIN, + result.getRelation()); + EXPECT_LT(0, result.getOrder()); + EXPECT_EQ(3, result.getCommonLabels()); + + // "e.d.c.example.org." and "example.org.", case in-sensitive + lsc.stripLeft(2); + result = lsc.compare(ls1); + EXPECT_EQ(isc::dns::NameComparisonResult::SUBDOMAIN, + result.getRelation()); + EXPECT_LT(0, result.getOrder()); + EXPECT_EQ(3, result.getCommonLabels()); + + // "example.org." and "example.org.", case in-sensitive + lsc.stripLeft(3); + result = lsc.compare(ls1); + EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL, + result.getRelation()); + EXPECT_EQ(0, result.getOrder()); + EXPECT_EQ(3, result.getCommonLabels()); + + // "." and "example.org.", case in-sensitive + lsc.stripLeft(2); + result = lsc.compare(ls1); + EXPECT_EQ(isc::dns::NameComparisonResult::SUPERDOMAIN, + result.getRelation()); + EXPECT_GT(0, result.getOrder()); + EXPECT_EQ(1, result.getCommonLabels()); + + Name nd("a.b.c.isc.example.org"); + LabelSequence lsd(nd); + Name ne("w.x.y.isc.EXAMPLE.org"); + LabelSequence lse(ne); + + // "a.b.c.isc.example.org." and "w.x.y.isc.EXAMPLE.org.", + // case sensitive + result = lsd.compare(lse, true); + EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR, + result.getRelation()); + EXPECT_LT(0, result.getOrder()); + EXPECT_EQ(2, result.getCommonLabels()); + + // "a.b.c.isc.example.org." and "w.x.y.isc.EXAMPLE.org.", + // case in-sensitive + result = lsd.compare(lse); + EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR, + result.getRelation()); + EXPECT_GT(0, result.getOrder()); + EXPECT_EQ(4, result.getCommonLabels()); + + // "isc.example.org." and "isc.EXAMPLE.org.", case sensitive + lsd.stripLeft(3); + lse.stripLeft(3); + result = lsd.compare(lse, true); + EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR, + result.getRelation()); + EXPECT_LT(0, result.getOrder()); + EXPECT_EQ(2, result.getCommonLabels()); + + // "isc.example.org." and "isc.EXAMPLE.org.", case in-sensitive + result = lsd.compare(lse); + EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL, + result.getRelation()); + EXPECT_EQ(0, result.getOrder()); + EXPECT_EQ(4, result.getCommonLabels()); + + Name nf("a.b.c.isc.example.org"); + LabelSequence lsf(nf); + Name ng("w.x.y.isc.EXAMPLE.org"); + LabelSequence lsg(ng); + + // lsf: "a.b.c.isc.example.org." + // lsg: "w.x.y.isc.EXAMPLE.org" (not absolute), case in-sensitive. + // the absolute one is always smaller. + lsg.stripRight(1); + result = lsg.compare(lsf); // lsg > lsf + EXPECT_EQ(isc::dns::NameComparisonResult::NONE, result.getRelation()); + EXPECT_LT(0, result.getOrder()); + EXPECT_EQ(0, result.getCommonLabels()); + + // "a.b.c.isc.example.org" (not absolute) and + // "w.x.y.isc.EXAMPLE.org" (not absolute), case in-sensitive + lsf.stripRight(1); + result = lsg.compare(lsf); + EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR, + result.getRelation()); + EXPECT_LT(0, result.getOrder()); + EXPECT_EQ(3, result.getCommonLabels()); + + // "a.b.c.isc.example" (not absolute) and + // "w.x.y.isc.EXAMPLE" (not absolute), case in-sensitive + lsf.stripRight(1); + lsg.stripRight(1); + result = lsg.compare(lsf); + EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR, + result.getRelation()); + EXPECT_LT(0, result.getOrder()); + EXPECT_EQ(2, result.getCommonLabels()); + + // lsf: "a.b.c" (not absolute) and + // lsg: "w.x.y" (not absolute), case in-sensitive; a.b.c < w.x.y; + // no common labels. + lsf.stripRight(2); + lsg.stripRight(2); + result = lsf.compare(lsg); + EXPECT_EQ(isc::dns::NameComparisonResult::NONE, result.getRelation()); + EXPECT_GT(0, result.getOrder()); + EXPECT_EQ(0, result.getCommonLabels()); + + // lsf2: a.b.cc (not absolute); a.b.c < a.b.cc, no common labels. + const Name nf2("a.b.cc"); + LabelSequence lsf2(nf2); + lsf2.stripRight(1); + result = lsf.compare(lsf2); + EXPECT_EQ(isc::dns::NameComparisonResult::NONE, result.getRelation()); + EXPECT_GT(0, result.getOrder()); + EXPECT_EQ(0, result.getCommonLabels()); + + Name nh("aexample.org"); + LabelSequence lsh(nh); + Name ni("bexample.org"); + LabelSequence lsi(ni); + + // "aexample.org" (not absolute) and + // "bexample.org" (not absolute), case in-sensitive + lsh.stripRight(1); + lsi.stripRight(1); + result = lsh.compare(lsi); + EXPECT_EQ(isc::dns::NameComparisonResult::COMMONANCESTOR, + result.getRelation()); + EXPECT_GT(0, result.getOrder()); + EXPECT_EQ(1, result.getCommonLabels()); + + // "aexample" (not absolute) and + // "bexample" (not absolute), case in-sensitive; + // aexample < bexample; no common labels. + lsh.stripRight(1); + lsi.stripRight(1); + result = lsh.compare(lsi); + EXPECT_EQ(isc::dns::NameComparisonResult::NONE, result.getRelation()); + EXPECT_GT(0, result.getOrder()); + EXPECT_EQ(0, result.getCommonLabels()); + + Name nj("example.org"); + LabelSequence lsj(nj); + Name nk("example.org"); + LabelSequence lsk(nk); + + // "example.org" (not absolute) and + // "example.org" (not absolute), case in-sensitive + lsj.stripRight(1); + lsk.stripRight(1); + result = lsj.compare(lsk); + EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL, + result.getRelation()); + EXPECT_EQ(0, result.getOrder()); + EXPECT_EQ(2, result.getCommonLabels()); + + // "example" (not absolute) and + // "example" (not absolute), case in-sensitive + lsj.stripRight(1); + lsk.stripRight(1); + result = lsj.compare(lsk); + EXPECT_EQ(isc::dns::NameComparisonResult::EQUAL, + result.getRelation()); + EXPECT_EQ(0, result.getOrder()); + EXPECT_EQ(1, result.getCommonLabels()); +} + +void +getDataCheck(const uint8_t* expected_data, size_t expected_len, + const LabelSequence& ls) +{ + size_t len; + const uint8_t* data = ls.getData(&len); + ASSERT_EQ(expected_len, len) << "Expected data: " << expected_data << + ", label sequence: " << ls; + EXPECT_EQ(expected_len, ls.getDataLength()) << + "Expected data: " << expected_data << + ", label sequence: " << ls; + for (size_t i = 0; i < len; ++i) { + EXPECT_EQ(expected_data[i], data[i]) << + "Difference at pos " << i << ": Expected data: " << expected_data << + ", label sequence: " << ls; + } +} + +// Convenient data converter for expected data. Label data must be of +// uint8_t*, while it's convenient if we can specify some test data in +// plain string (which is of char*). This wrapper converts the latter to +// the former in a safer way. +void +getDataCheck(const char* expected_char_data, size_t expected_len, + const LabelSequence& ls) +{ + const vector<uint8_t> expected_data(expected_char_data, + expected_char_data + expected_len); + getDataCheck(&expected_data[0], expected_len, ls); +} + +TEST_F(LabelSequenceTest, getData) { + getDataCheck("\007example\003org\000", 13, ls1); + getDataCheck("\007example\003com\000", 13, ls2); + getDataCheck("\007example\003org\000", 13, ls3); + getDataCheck("\003foo\003bar\004test\007example\000", 22, ls4); + getDataCheck("\007example\003ORG\000", 13, ls5); + getDataCheck("\007ExAmPlE\003org\000", 13, ls6); + getDataCheck("\000", 1, ls7); +}; + +TEST_F(LabelSequenceTest, stripLeft) { + EXPECT_TRUE(ls1.equals(ls3)); + ls1.stripLeft(0); + getDataCheck("\007example\003org\000", 13, ls1); + EXPECT_TRUE(ls1.equals(ls3)); + ls1.stripLeft(1); + getDataCheck("\003org\000", 5, ls1); + EXPECT_FALSE(ls1.equals(ls3)); + ls1.stripLeft(1); + getDataCheck("\000", 1, ls1); + EXPECT_TRUE(ls1.equals(ls7)); + + ls2.stripLeft(2); + getDataCheck("\000", 1, ls2); + EXPECT_TRUE(ls2.equals(ls7)); +} + +TEST_F(LabelSequenceTest, stripRight) { + EXPECT_TRUE(ls1.equals(ls3)); + ls1.stripRight(1); + getDataCheck("\007example\003org", 12, ls1); + EXPECT_FALSE(ls1.equals(ls3)); + ls1.stripRight(1); + getDataCheck("\007example", 8, ls1); + EXPECT_FALSE(ls1.equals(ls3)); + + ASSERT_FALSE(ls1.equals(ls2)); + ls2.stripRight(2); + getDataCheck("\007example", 8, ls2); + EXPECT_TRUE(ls1.equals(ls2)); +} + +TEST_F(LabelSequenceTest, stripOutOfRange) { + EXPECT_THROW(ls1.stripLeft(100), isc::OutOfRange); + EXPECT_THROW(ls1.stripLeft(5), isc::OutOfRange); + EXPECT_THROW(ls1.stripLeft(4), isc::OutOfRange); + EXPECT_THROW(ls1.stripLeft(3), isc::OutOfRange); + getDataCheck("\007example\003org\000", 13, ls1); + + EXPECT_THROW(ls1.stripRight(100), isc::OutOfRange); + EXPECT_THROW(ls1.stripRight(5), isc::OutOfRange); + EXPECT_THROW(ls1.stripRight(4), isc::OutOfRange); + EXPECT_THROW(ls1.stripRight(3), isc::OutOfRange); + getDataCheck("\007example\003org\000", 13, ls1); +} + +TEST_F(LabelSequenceTest, getLabelCount) { + EXPECT_EQ(3, ls1.getLabelCount()); + ls1.stripLeft(0); + EXPECT_EQ(3, ls1.getLabelCount()); + ls1.stripLeft(1); + EXPECT_EQ(2, ls1.getLabelCount()); + ls1.stripLeft(1); + EXPECT_EQ(1, ls1.getLabelCount()); + + EXPECT_EQ(3, ls2.getLabelCount()); + ls2.stripRight(1); + EXPECT_EQ(2, ls2.getLabelCount()); + ls2.stripRight(1); + EXPECT_EQ(1, ls2.getLabelCount()); + + EXPECT_EQ(3, ls3.getLabelCount()); + ls3.stripRight(2); + EXPECT_EQ(1, ls3.getLabelCount()); + + EXPECT_EQ(5, ls4.getLabelCount()); + ls4.stripRight(3); + EXPECT_EQ(2, ls4.getLabelCount()); + + EXPECT_EQ(3, ls5.getLabelCount()); + ls5.stripLeft(2); + EXPECT_EQ(1, ls5.getLabelCount()); +} + +TEST_F(LabelSequenceTest, comparePart) { + EXPECT_FALSE(ls1.equals(ls8)); + + // strip root label from example.org. + ls1.stripRight(1); + // strip foo from foo.example.org.bar. + ls8.stripLeft(1); + // strip bar. (i.e. bar and root) too + ls8.stripRight(2); + + EXPECT_TRUE(ls1.equals(ls8)); + + // Data comparison + size_t len; + const uint8_t* data = ls1.getData(&len); + getDataCheck(data, len, ls8); +} + +TEST_F(LabelSequenceTest, isAbsolute) { + ASSERT_TRUE(ls1.isAbsolute()); + + ls1.stripLeft(1); + ASSERT_TRUE(ls1.isAbsolute()); + ls1.stripRight(1); + ASSERT_FALSE(ls1.isAbsolute()); + + ASSERT_TRUE(ls2.isAbsolute()); + ls2.stripRight(1); + ASSERT_FALSE(ls2.isAbsolute()); + + ASSERT_TRUE(ls3.isAbsolute()); + ls3.stripLeft(2); + ASSERT_TRUE(ls3.isAbsolute()); +} + +TEST_F(LabelSequenceTest, toText) { + EXPECT_EQ(".", ls7.toText()); + + EXPECT_EQ("example.org.", ls1.toText()); + ls1.stripLeft(1); + EXPECT_EQ("org.", ls1.toText()); + ls1.stripLeft(1); + EXPECT_EQ(".", ls1.toText()); + + EXPECT_EQ("example.com.", ls2.toText()); + ls2.stripRight(1); + EXPECT_EQ("example.com", ls2.toText()); + ls2.stripRight(1); + EXPECT_EQ("example", ls2.toText()); + + EXPECT_EQ("foo.example.org.bar.", ls8.toText()); + ls8.stripRight(2); + EXPECT_EQ("foo.example.org", ls8.toText()); + + EXPECT_EQ(".", ls7.toText()); + EXPECT_THROW(ls7.stripLeft(1), isc::OutOfRange); + + Name n_long1("012345678901234567890123456789" + "012345678901234567890123456789012." + "012345678901234567890123456789" + "012345678901234567890123456789012." + "012345678901234567890123456789" + "012345678901234567890123456789012." + "012345678901234567890123456789" + "0123456789012345678901234567890"); + LabelSequence ls_long1(n_long1); + + EXPECT_EQ("012345678901234567890123456789" + "012345678901234567890123456789012." + "012345678901234567890123456789" + "012345678901234567890123456789012." + "012345678901234567890123456789" + "012345678901234567890123456789012." + "012345678901234567890123456789" + "0123456789012345678901234567890.", ls_long1.toText()); + ls_long1.stripRight(1); + EXPECT_EQ("012345678901234567890123456789" + "012345678901234567890123456789012." + "012345678901234567890123456789" + "012345678901234567890123456789012." + "012345678901234567890123456789" + "012345678901234567890123456789012." + "012345678901234567890123456789" + "0123456789012345678901234567890", ls_long1.toText()); + + LabelSequence ls_long2(n_maxlabel); + + EXPECT_EQ("0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.", ls_long2.toText()); + ls_long2.stripRight(1); + EXPECT_EQ("0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." + "0.1.2.3.4.5.6", ls_long2.toText()); + ls_long2.stripRight(125); + EXPECT_EQ("0.1", ls_long2.toText()); +} + +// The following verifies that toRawText() returns a string +// actual characters in place of escape sequences. We do not +// bother with an exhaustive set of tests here as this is +// not a primary use case. +TEST_F(LabelSequenceTest, toRawText) { + Name n("a bc.$exa(m)ple.@org"); + LabelSequence l(n); + EXPECT_EQ("a bc.$exa(m)ple.@org", l.toRawText(true)); + EXPECT_EQ("a bc.$exa(m)ple.@org.", l.toRawText(false)); + + // toRawText is not supposed to do any sanity checks. + // Let's try with a very weird name. + Name n2("xtra\tchars\n.in.name"); + LabelSequence l2(n2); + EXPECT_EQ("xtra\tchars\n.in.name.", l2.toRawText(false)); +} + +// The following are test data used in the getHash test below. Normally +// we use example/documentation domain names for testing, but in this case +// we'd specifically like to use more realistic data, and are intentionally +// using real-world samples: They are the NS names of root and some top level +// domains as of this test. +const char* const root_servers[] = { + "a.root-servers.net", "b.root-servers.net", "c.root-servers.net", + "d.root-servers.net", "e.root-servers.net", "f.root-servers.net", + "g.root-servers.net", "h.root-servers.net", "i.root-servers.net", + "j.root-servers.net", "k.root-servers.net", "l.root-servers.net", + "m.root-servers.net", NULL +}; + +const char* const jp_servers[] = { + "a.dns.jp", "b.dns.jp", "c.dns.jp", "d.dns.jp", "e.dns.jp", + "f.dns.jp", "g.dns.jp", NULL +}; +const char* const cn_servers[] = { + "a.dns.cn", "b.dns.cn", "c.dns.cn", "d.dns.cn", "e.dns.cn", + "ns.cernet.net", NULL +}; +const char* const ca_servers[] = { + "k.ca-servers.ca", "e.ca-servers.ca", "a.ca-servers.ca", "z.ca-servers.ca", + "tld.isc-sns.net", "c.ca-servers.ca", "j.ca-servers.ca", "l.ca-servers.ca", + "sns-pb.isc.org", "f.ca-servers.ca", NULL +}; + +// A helper function used in the getHash test below. +void +hashDistributionCheck(const char* const* servers) { + const size_t BUCKETS = 64; // constant used in the MessageRenderer + set<Name> names; + vector<size_t> hash_counts(BUCKETS); + + // Store all test names and their super domain names (excluding the + // "root" label) in the set, calculates their hash values, and increments + // the counter for the corresponding hash "bucket". + for (size_t i = 0; servers[i] != NULL; ++i) { + const Name name(servers[i]); + for (size_t l = 0; l < name.getLabelCount() - 1; ++l) { + pair<set<Name>::const_iterator, bool> ret = + names.insert(name.split(l)); + if (ret.second) { + hash_counts[LabelSequence((*ret.first)).getHash(false) % + BUCKETS]++; + } + } + } + + // See how many conflicts we have in the buckets. For the testing purpose + // we expect there's at most 2 conflicts in each set, which is an + // arbitrary choice (it should happen to succeed with the hash function + // and data we are using; if it's not the case, maybe with an update to + // the hash implementation, we should revise the test). + for (size_t i = 0; i < BUCKETS; ++i) { + EXPECT_GE(3, hash_counts[i]); + } +} + +TEST_F(LabelSequenceTest, getHash) { + // Trivial case. The same sequence should have the same hash. + EXPECT_EQ(ls1.getHash(true), ls1.getHash(true)); + + // Check the case-insensitive mode behavior. + EXPECT_EQ(ls1.getHash(false), ls5.getHash(false)); + + // Check that the distribution of hash values is "not too bad" (such as + // everything has the same hash value due to a stupid bug). It's + // difficult to check such things reliably. We do some ad hoc tests here. + hashDistributionCheck(root_servers); + hashDistributionCheck(jp_servers); + hashDistributionCheck(cn_servers); + hashDistributionCheck(ca_servers); +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST_F(LabelSequenceTest, LeftShiftOperator) { + ostringstream oss; + oss << ls1; + EXPECT_EQ(ls1.toText(), oss.str()); +} + +TEST_F(LabelSequenceTest, serialize) { + // placeholder for serialized data. We use a sufficiently large space + // for testing the overwrapping cases below. + uint8_t labels_buf[LabelSequence::MAX_SERIALIZED_LENGTH * 3]; + + // vector to store expected and actual data + vector<LabelSequence> actual_labelseqs; + typedef pair<size_t, const uint8_t*> DataPair; + vector<DataPair> expected; + + // An absolute sequence directly constructed from a valid name. + // labels = 3, offset sequence = 0, 8, 12, data = "example.com." + actual_labelseqs.push_back(ls1); + const uint8_t expected_data1[] = { + 3, 0, 8, 12, 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', + 3, 'o', 'r', 'g', 0 }; + expected.push_back(DataPair(sizeof(expected_data1), expected_data1)); + + // Strip the original one from right. + // labels = 2, offset sequence = 0, 8, data = "example.com" (non absolute) + LabelSequence ls_rstripped = ls1; + ls_rstripped.stripRight(1); + actual_labelseqs.push_back(ls_rstripped); + const uint8_t expected_data2[] = { + 2, 0, 8, 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', + 3, 'o', 'r', 'g'}; + expected.push_back(DataPair(sizeof(expected_data2), expected_data2)); + + // Strip the original one from left. + // labels = 2, offset sequence = 0, 4, data = "com." + // Note that offsets are adjusted so that they begin with 0. + LabelSequence ls_lstripped = ls1; + ls_lstripped.stripLeft(1); + actual_labelseqs.push_back(ls_lstripped); + const uint8_t expected_data3[] = { 2, 0, 4, 3, 'o', 'r', 'g', 0 }; + expected.push_back(DataPair(sizeof(expected_data3), expected_data3)); + + // Root label. + LabelSequence ls_root(Name::ROOT_NAME()); + actual_labelseqs.push_back(ls_root); + const uint8_t expected_data4[] = { 1, 0, 0 }; + expected.push_back(DataPair(sizeof(expected_data4), expected_data4)); + + // Non absolute single-label. + LabelSequence ls_single = ls_rstripped; + ls_single.stripRight(1); + actual_labelseqs.push_back(ls_single); + const uint8_t expected_data5[] = { + 1, 0, 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e' }; + expected.push_back(DataPair(sizeof(expected_data5), expected_data5)); + + // Labels containing a longest possible label + const Name name_longlabel(std::string(63, 'x')); // 63 'x's + LabelSequence ls_longlabel(name_longlabel); + actual_labelseqs.push_back(ls_longlabel); + vector<uint8_t> expected_data6; + expected_data6.push_back(2); // 2 labels + expected_data6.push_back(0); // 1st offset + expected_data6.push_back(64); // 2nd offset + expected_data6.push_back(63); // 1st label length + expected_data6.insert(expected_data6.end(), 63, 'x'); // 1st label: 63 'x's + expected_data6.push_back(0); // 2nd label: trailing 0 + expected.push_back(DataPair(expected_data6.size(), &expected_data6[0])); + + // Max number of labels and longest possible name + EXPECT_EQ(Name::MAX_WIRE, n_maxlabel.getLength()); + LabelSequence ls_maxlabel(n_maxlabel); + actual_labelseqs.push_back(ls_maxlabel); + vector<uint8_t> expected_data7; + expected_data7.push_back(Name::MAX_LABELS); // number of labels + for (size_t i = 0; i < Name::MAX_LABELS; ++i) { + expected_data7.push_back(i * 2); // each label has length and 1 byte + } + // Copy wire data of the name + isc::util::OutputBuffer ob(0); + n_maxlabel.toWire(ob); + expected_data7.insert(expected_data7.end(), + static_cast<const uint8_t*>(ob.getData()), + static_cast<const uint8_t*>(ob.getData()) + + ob.getLength()); + expected.push_back(DataPair(expected_data7.size(), &expected_data7[0])); + + // For each data set, serialize the labels and compare the data to the + // expected one. + vector<DataPair>::const_iterator it = expected.begin(); + vector<LabelSequence>::const_iterator itl = actual_labelseqs.begin(); + for (; it != expected.end(); ++it, ++itl) { + SCOPED_TRACE(itl->toText()); + + const size_t serialized_len = itl->getSerializedLength(); + + ASSERT_GE(LabelSequence::MAX_SERIALIZED_LENGTH, serialized_len); + itl->serialize(labels_buf, serialized_len); + EXPECT_EQ(it->first, serialized_len); + EXPECT_EQ(0, memcmp(it->second, labels_buf, serialized_len)); + + EXPECT_EQ(NameComparisonResult::EQUAL, + LabelSequence(labels_buf).compare(*itl).getRelation()); + + // Shift the data to the middle of the buffer for overwrap check + uint8_t* const bp = labels_buf; + std::memcpy(bp + serialized_len, bp, serialized_len); + // Memory layout is now as follows: + // <- ser_len -> <- ser_len ------> + // bp bp+ser_len bp+(ser_len*2) + // olen,odata,ndata + + // end of buffer would be the first byte of offsets: invalid. + EXPECT_THROW(LabelSequence(bp + serialized_len). + serialize(bp + 2, serialized_len), + isc::BadValue); + // begin of buffer would be the last byte of ndata: invalid. + EXPECT_THROW(LabelSequence(bp + serialized_len). + serialize(bp + (2 * serialized_len) - 1, serialized_len), + isc::BadValue); + // A boundary safe case: buffer is placed after the sequence data. + // should cause no disruption. + LabelSequence(bp + serialized_len). + serialize(bp + 2 * serialized_len, serialized_len); + // A boundary safe case: buffer is placed before the sequence data + // should cause no disruption. (but the original serialized data will + // be overridden, so it can't be used any more) + LabelSequence(bp + serialized_len). + serialize(bp + 1, serialized_len); + } + + EXPECT_THROW(ls1.serialize(labels_buf, ls1.getSerializedLength() - 1), + isc::BadValue); +} + +#ifdef ENABLE_DEBUG + +// These checks are enabled only in debug mode in the LabelSequence +// class. +TEST_F(LabelSequenceTest, badDeserialize) { + EXPECT_THROW(LabelSequence(NULL), isc::BadValue); + const uint8_t zero_offsets[] = { 0 }; + EXPECT_THROW(LabelSequence ls(zero_offsets), isc::BadValue); + const uint8_t toomany_offsets[] = { Name::MAX_LABELS + 1 }; + EXPECT_THROW(LabelSequence ls(toomany_offsets), isc::BadValue); + + // (second) offset does not match actual label length + const uint8_t offsets_wrongoffset[] = { 2, 0, 64, 1 }; + EXPECT_THROW(LabelSequence ls(offsets_wrongoffset), isc::BadValue); + + // offset matches, but exceeds MAX_LABEL_LEN + const uint8_t offsets_toolonglabel[] = { 2, 0, 64, 64 }; + EXPECT_THROW(LabelSequence ls(offsets_toolonglabel), isc::BadValue); + + // Inconsistent data: an offset is lower than the previous offset + const uint8_t offsets_lower[] = { 3, // # of offsets + 0, 2, 1, // offsets + 1, 'a', 1, 'b', 0}; + EXPECT_THROW(LabelSequence ls(offsets_lower), isc::BadValue); + + // Inconsistent data: an offset is equal to the previous offset + const uint8_t offsets_noincrease[] = { 2, 0, 0, 0, 0 }; + EXPECT_THROW(LabelSequence ls(offsets_noincrease), isc::BadValue); +} + +#endif + +namespace { + +// Helper function; repeatedly calls +// - Initially, all three labelsequences should be the same +// - repeatedly performs: +// - checks all three are equal +// - stripLeft on ls1 +// - checks ls1 and ls2 are different, and ls2 and ls3 are equal +// - stripLeft on ls2 +// - checks ls1 and ls2 are equal, and ls2 and ls3 are different +// - stripLeft on ls3 +// +// (this test makes sure the stripLeft of one has no effect on the other +// two, and that the strip properties hold regardless of how they were +// constructed) +// +void stripLeftCheck(LabelSequence ls1, LabelSequence ls2, LabelSequence ls3) { + ASSERT_LT(1, ls1.getLabelCount()); + while (ls1.getLabelCount() > 1) { + check_equal(ls1, ls2); + check_equal(ls2, ls3); + + ls1.stripLeft(1); + check_compare(ls1, ls2, isc::dns::NameComparisonResult::SUPERDOMAIN, + ls1.getLabelCount(), true, -1); + check_equal(ls2, ls3); + + ls2.stripLeft(1); + check_equal(ls1, ls2); + check_compare(ls2, ls3, isc::dns::NameComparisonResult::SUPERDOMAIN, + ls1.getLabelCount(), true, -1); + + ls3.stripLeft(1); + } +} + +// Similar to stripLeftCheck, but using stripRight() +void stripRightCheck(LabelSequence ls1, LabelSequence ls2, LabelSequence ls3) { + ASSERT_LT(1, ls1.getLabelCount()); + while (ls1.getLabelCount() > 1) { + check_equal(ls1, ls2); + check_equal(ls2, ls3); + + ls1.stripRight(1); + check_compare(ls1, ls2, isc::dns::NameComparisonResult::NONE, 0, + false); + check_equal(ls2, ls3); + + ls2.stripRight(1); + check_equal(ls1, ls2); + check_compare(ls2, ls3, isc::dns::NameComparisonResult::NONE, 0, + false); + + ls3.stripRight(1); + } +} + +} // end anonymous namespace + +class ExtendableLabelSequenceTest : public ::testing::Test { +public: + ExtendableLabelSequenceTest() : bar("bar."), + example_org("example.org"), + foo("foo."), + foo_bar("foo.bar."), + foo_bar_example_org("foo.bar.example.org."), + foo_bar_foo_bar("foo.bar.foo.bar."), + foo_example("foo.example."), + org("org") + { + // explicitly set to non-zero data, to make sure + // we don't try to use data we don't set + memset(buf, 0xff, LabelSequence::MAX_SERIALIZED_LENGTH); + } + + Name bar; + Name example_org; + Name foo; + Name foo_bar; + Name foo_bar_example_org; + Name foo_bar_foo_bar; + Name foo_example; + Name org; + + uint8_t buf[LabelSequence::MAX_SERIALIZED_LENGTH]; +}; + +// Test that 'extendable' labelsequences behave correctly when using +// stripLeft() and stripRight() +TEST_F(ExtendableLabelSequenceTest, extendableLabelSequence) { + LabelSequence ls1(example_org); + LabelSequence ls2(example_org); + + LabelSequence els(ls1, buf); + // ls1 is absolute, so els should be too + EXPECT_TRUE(els.isAbsolute()); + check_equal(ls1, els); + + ASSERT_EQ(ls1.getDataLength(), els.getDataLength()); + stripLeftCheck(ls1, els, ls2); + stripRightCheck(ls1, els, ls2); + + // Creating an extendable labelsequence from a non-absolute + // label sequence should result in a non-absolute label sequence + ls1.stripRight(1); + els = LabelSequence(ls1, buf); + EXPECT_FALSE(els.isAbsolute()); + check_equal(ls1, els); + + // and extending with the root label should make it absolute again + els.extend(LabelSequence(Name(".")), buf); + EXPECT_TRUE(els.isAbsolute()); + check_equal(ls2, els); +} + +// Test that 'extendable' LabelSequences behave correctly when initialized +// with a stripped source LabelSequence +TEST_F(ExtendableLabelSequenceTest, extendableLabelSequenceLeftStrippedSource) { + LabelSequence ls1(foo_bar_example_org); + LabelSequence ls2(foo_bar_example_org); + + while (ls1.getLabelCount() > 2) { + ls1.stripLeft(1); + ls2.stripLeft(1); + + LabelSequence els(ls1, buf); + + ASSERT_EQ(ls1.getDataLength(), els.getDataLength()); + stripLeftCheck(ls1, els, ls2); + stripRightCheck(ls1, els, ls2); + } +} + +TEST_F(ExtendableLabelSequenceTest, extendableLabelSequenceRightStrippedSource) { + LabelSequence ls1(foo_bar_example_org); + LabelSequence ls2(foo_bar_example_org); + + while (ls1.getLabelCount() > 2) { + ls1.stripRight(1); + ls2.stripRight(1); + + LabelSequence els(ls1, buf); + + ASSERT_EQ(ls1.getDataLength(), els.getDataLength()); + stripLeftCheck(ls1, els, ls2); + stripRightCheck(ls1, els, ls2); + } +} + +// Check some basic 'extend' functionality +TEST_F(ExtendableLabelSequenceTest, extend) { + LabelSequence ls1(foo_bar); + LabelSequence ls2(foo); + LabelSequence ls3(bar); + LabelSequence ls4(foo_bar); + + LabelSequence els(ls2, buf); + + check_compare(ls1, els, isc::dns::NameComparisonResult::COMMONANCESTOR, 1, + true, -4); + els.extend(ls3, buf); + EXPECT_TRUE(els.isAbsolute()); + + check_equal(ls1, els); + stripLeftCheck(ls1, els, ls4); + stripRightCheck(ls1, els, ls4); + + // strip, then extend again + els.stripRight(2); // (2, 1 for root label, 1 for last label) + els.extend(ls3, buf); + EXPECT_TRUE(els.isAbsolute()); + check_equal(ls1, els); + + // Extending again should make it different + els.extend(ls3, buf); + EXPECT_TRUE(els.isAbsolute()); + check_compare(ls1, els, isc::dns::NameComparisonResult::COMMONANCESTOR, 2, + true, 4); + + // Extending with a non-absolute name should make it non-absolute as well + ls3.stripRight(1); + els.extend(ls3, buf); + EXPECT_FALSE(els.isAbsolute()); + + Name check_name("foo.bar.bar.bar"); + LabelSequence check_ls(check_name); + check_ls.stripRight(1); + check_equal(check_ls, els); + + // And try extending when both are not absolute + els.stripRight(3); + ls1.stripRight(1); + EXPECT_FALSE(els.isAbsolute()); + els.extend(ls3, buf); + EXPECT_FALSE(els.isAbsolute()); + check_equal(ls1, els); + + // Extending non-absolute with absolute should make it absolute again + EXPECT_FALSE(els.isAbsolute()); + els.extend(LabelSequence(Name("absolute.")), buf); + EXPECT_TRUE(els.isAbsolute()); + check_equal(LabelSequence(Name("foo.bar.absolute")), els); +} + +TEST_F(ExtendableLabelSequenceTest, extendLeftStripped) { + LabelSequence ls1(foo_example); + LabelSequence ls2(example_org); + LabelSequence ls3(org); + + LabelSequence els(ls1, buf); + + els.stripLeft(1); + els.extend(ls3, buf); + EXPECT_TRUE(els.isAbsolute()); + check_equal(ls2, els); +} + +// Check that when extending with itself, it does not cause horrible failures +TEST_F(ExtendableLabelSequenceTest, extendWithItself) { + LabelSequence ls1(foo_bar); + LabelSequence ls2(foo_bar_foo_bar); + + LabelSequence els(ls1, buf); + + els.extend(els, buf); + EXPECT_TRUE(els.isAbsolute()); + check_equal(ls2, els); + + // Also try for non-absolute names + ls2.stripRight(1); + els = LabelSequence(ls1, buf); + els.stripRight(1); + els.extend(els, buf); + EXPECT_FALSE(els.isAbsolute()); + check_equal(ls2, els); + + // Once more, now start out with non-absolute labelsequence + ls1.stripRight(1); + els = LabelSequence(ls1, buf); + els.extend(els, buf); + EXPECT_FALSE(els.isAbsolute()); + check_equal(ls2, els); +} + +// Test that 'extending' with just a root label is a no-op, iff the original +// was already absolute +TEST_F(ExtendableLabelSequenceTest, extendWithRoot) { + LabelSequence ls1(example_org); + + LabelSequence els(LabelSequence(ls1, buf)); + check_equal(ls1, els); + els.extend(LabelSequence(Name(".")), buf); + EXPECT_TRUE(els.isAbsolute()); + check_equal(ls1, els); + + // but not if the original was not absolute (it will be equal to + // the original labelsequence used above, but not the one it was based + // on). + LabelSequence ls2(example_org); + ls2.stripRight(1); + els = LabelSequence(ls2, buf); + EXPECT_FALSE(els.isAbsolute()); + els.extend(LabelSequence(Name(".")), buf); + EXPECT_TRUE(els.isAbsolute()); + check_equal(ls1, els); + check_compare(ls2, els, isc::dns::NameComparisonResult::NONE, 0, true, 3); +} + +// Check possible failure modes of extend() +TEST_F(ExtendableLabelSequenceTest, extendBadData) { + LabelSequence ls1(example_org); + + LabelSequence els(ls1, buf); + + // try use with unrelated labelsequence + EXPECT_THROW(ls1.extend(ls1, buf), isc::BadValue); + + // Create a long name, but so that we can still extend once + Name longlabel("1234567890123456789012345678901234567890" + "12345678901234567890"); + LabelSequence long_ls(longlabel); + els = LabelSequence(long_ls, buf); + els.extend(els, buf); + els.extend(long_ls, buf); + els.extend(long_ls, buf); + ASSERT_EQ(245, els.getDataLength()); + // Extending once more with 10 bytes should still work + els.extend(LabelSequence(Name("123456789")), buf); + EXPECT_TRUE(els.isAbsolute()); + + // Extended label sequence should now look like + const Name full_name( + "123456789012345678901234567890123456789012345678901234567890." + "123456789012345678901234567890123456789012345678901234567890." + "123456789012345678901234567890123456789012345678901234567890." + "123456789012345678901234567890123456789012345678901234567890." + "123456789."); + const LabelSequence full_ls(full_name); + check_equal(full_ls, els); + + // But now, even the shortest extension should fail + EXPECT_THROW(els.extend(LabelSequence(Name("1")), buf), isc::BadValue); + + // Check it hasn't been changed + EXPECT_TRUE(els.isAbsolute()); + check_equal(full_ls, els); + + // Also check that extending past MAX_LABELS is not possible + Name shortname("1."); + LabelSequence short_ls(shortname); + els = LabelSequence(short_ls, buf); + for (size_t i=0; i < 126; ++i) { + els.extend(short_ls, buf); + } + + // Should now look like this + const Name full_name2( + "1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1." + "1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1." + "1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1." + "1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1." + "1.1.1.1.1.1.1."); + const LabelSequence full_ls2(full_name2); + EXPECT_TRUE(els.isAbsolute()); + check_equal(full_ls2, els); + + EXPECT_THROW(els.extend(short_ls, buf), isc::BadValue); + + EXPECT_TRUE(els.isAbsolute()); + check_equal(full_ls2, els); +} + +// Check the static fixed 'wildcard' LabelSequence +TEST(WildCardLabelSequence, wildcard) { + ASSERT_FALSE(LabelSequence::WILDCARD().isAbsolute()); + ASSERT_EQ("*", LabelSequence::WILDCARD().toText()); +} + +} diff --git a/src/lib/dns/tests/master_lexer_inputsource_unittest.cc b/src/lib/dns/tests/master_lexer_inputsource_unittest.cc new file mode 100644 index 0000000..c5f618a --- /dev/null +++ b/src/lib/dns/tests/master_lexer_inputsource_unittest.cc @@ -0,0 +1,368 @@ +// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/master_lexer_inputsource.h> +#include <dns/master_lexer.h> +#include <exceptions/exceptions.h> + +#include <gtest/gtest.h> + +#include <iostream> +#include <sstream> +#include <string> + +#include <string.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::dns::master_lexer_internal; + +namespace { + +const char* const test_input = + "Line1 to scan.\nLine2 to scan.\nLine3 to scan.\n"; + +class InputSourceTest : public ::testing::Test { +protected: + InputSourceTest() : + str_(test_input), + str_length_(strlen(str_)), + iss_(str_), + source_(iss_) + {} + + const char* str_; + const size_t str_length_; + stringstream iss_; + InputSource source_; +}; + +// Test the default return values set during InputSource construction. +TEST_F(InputSourceTest, defaults) { + EXPECT_EQ(1, source_.getCurrentLine()); + EXPECT_FALSE(source_.atEOF()); +} + +// getName() on file and stream sources +TEST_F(InputSourceTest, getName) { + EXPECT_EQ(0, source_.getName().find("stream-")); + + // Use some file; doesn't really matter what. + InputSource source2(TEST_DATA_SRCDIR "/masterload.txt"); + EXPECT_EQ(TEST_DATA_SRCDIR "/masterload.txt", source2.getName()); +} + +TEST_F(InputSourceTest, nonExistentFile) { + EXPECT_THROW({ + InputSource source(TEST_DATA_SRCDIR "/does-not-exist"); + }, InputSource::OpenError); +} + +// getChar() should return characters from the input stream in +// sequence. ungetChar() should skip backwards. +void +checkGetAndUngetChar(InputSource& source, + const char* str, const size_t str_length) +{ + for (size_t i = 0; i < str_length; ++i) { + EXPECT_EQ(str[i], source.getChar()); + EXPECT_EQ(i + 1, source.getPosition()); + EXPECT_FALSE(source.atEOF()); + } + + // At this point, we still have not reached EOF. + EXPECT_FALSE(source.atEOF()); + + // This should cause EOF to be set. + EXPECT_EQ(InputSource::END_OF_STREAM, source.getChar()); + + // Now, EOF should be set. + EXPECT_TRUE(source.atEOF()); + + // It doesn't increase the position count. + EXPECT_EQ(str_length, source.getPosition()); + EXPECT_EQ(str_length, source.getSize()); // this should be == getSize(). + + // Now, let's go backwards. This should cause the EOF to be set to + // false. + source.ungetChar(); + + // Now, EOF should be false. + EXPECT_FALSE(source.atEOF()); + + // But the position shouldn't change. + EXPECT_EQ(str_length, source.getPosition()); + + // This should cause EOF to be set again. + EXPECT_EQ(InputSource::END_OF_STREAM, source.getChar()); + + // Now, EOF should be set. + EXPECT_TRUE(source.atEOF()); + + // Now, let's go backwards in a loop. Start by skipping the EOF. + source.ungetChar(); + + for (size_t i = 0; i < str_length; ++i) { + const size_t index = str_length - 1 - i; + // Skip one character. + source.ungetChar(); + EXPECT_EQ(str[index], source.getChar()); + EXPECT_EQ(index + 1, source.getPosition()); + // Skip the character we received again. + source.ungetChar(); + } + + // Skipping past the start of buffer should throw. + EXPECT_THROW(source.ungetChar(), InputSource::UngetBeforeBeginning); +} + +TEST_F(InputSourceTest, stream) { + checkGetAndUngetChar(source_, str_, str_length_); +} + +TEST_F(InputSourceTest, file) { + std::ifstream fs(TEST_DATA_SRCDIR "/masterload.txt"); + const std::string str((std::istreambuf_iterator<char>(fs)), + std::istreambuf_iterator<char>()); + fs.close(); + + InputSource source(TEST_DATA_SRCDIR "/masterload.txt"); + checkGetAndUngetChar(source, str.c_str(), str.size()); +} + +// ungetAll() should skip back to the place where the InputSource +// started at construction, or the last saved start of line. +TEST_F(InputSourceTest, ungetAll) { + while (!source_.atEOF()) { + source_.getChar(); + } + + // Now, we are at EOF. + EXPECT_TRUE(source_.atEOF()); + EXPECT_EQ(4, source_.getCurrentLine()); + + source_.ungetAll(); + + // Now we are back to where we started. + EXPECT_EQ(1, source_.getCurrentLine()); + EXPECT_FALSE(source_.atEOF()); + EXPECT_EQ(0, source_.getPosition()); +} + +TEST_F(InputSourceTest, compact) { + // Compact at the start + source_.compact(); + + // Ungetting here must throw. + EXPECT_THROW(source_.ungetChar(), InputSource::UngetBeforeBeginning); + + for (size_t i = 0; i < str_length_; ++i) { + EXPECT_EQ(str_[i], source_.getChar()); + EXPECT_FALSE(source_.atEOF()); + } + + // At this point, we still have not reached EOF. + EXPECT_FALSE(source_.atEOF()); + + // This should cause EOF to be set. + EXPECT_EQ(InputSource::END_OF_STREAM, source_.getChar()); + + // Now, EOF should be set. + EXPECT_TRUE(source_.atEOF()); + EXPECT_EQ(4, source_.getCurrentLine()); + + // Compact again + source_.compact(); + + // We are still at EOF. + EXPECT_TRUE(source_.atEOF()); + EXPECT_EQ(4, source_.getCurrentLine()); + + // compact shouldn't change the position count. + EXPECT_EQ(source_.getSize(), source_.getPosition()); + + // Skip the EOF. + source_.ungetChar(); + + // Ungetting here must throw. + EXPECT_THROW(source_.ungetChar(), InputSource::UngetBeforeBeginning); + + EXPECT_EQ(InputSource::END_OF_STREAM, source_.getChar()); + EXPECT_TRUE(source_.atEOF()); +} + +TEST_F(InputSourceTest, markDuring) { + // First, skip to line 2. + while (!source_.atEOF() && + (source_.getCurrentLine() != 2)) { + source_.getChar(); + } + EXPECT_FALSE(source_.atEOF()); + EXPECT_EQ(2, source_.getCurrentLine()); + + // Now, unget a couple of characters. This should cause the + // buffer_pos_ to be not equal to the size of the buffer. + source_.ungetChar(); + source_.ungetChar(); + + // Now "mark" the source, meaning that we save line number and also + // compact the internal buffer at this stage. + source_.mark(); + + // Ungetting here must throw. + EXPECT_THROW(source_.ungetChar(), InputSource::UngetBeforeBeginning); + + for (size_t i = 13; i < str_length_; ++i) { + EXPECT_EQ(str_[i], source_.getChar()); + EXPECT_FALSE(source_.atEOF()); + } + + // At this point, we still have not reached EOF. + EXPECT_FALSE(source_.atEOF()); + + // This should cause EOF to be set. + EXPECT_EQ(InputSource::END_OF_STREAM, source_.getChar()); + + // Now, EOF should be set. + EXPECT_TRUE(source_.atEOF()); + + // Now, ungetAll() and check where it goes back. + source_.ungetAll(); + + // Ungetting here must throw. + EXPECT_THROW(source_.ungetChar(), InputSource::UngetBeforeBeginning); + + for (size_t i = 13; i < str_length_; ++i) { + EXPECT_EQ(str_[i], source_.getChar()); + EXPECT_FALSE(source_.atEOF()); + } + + // At this point, we still have not reached EOF. + EXPECT_FALSE(source_.atEOF()); + + // This should cause EOF to be set. + EXPECT_EQ(InputSource::END_OF_STREAM, source_.getChar()); + + // Now, EOF should be set. + EXPECT_TRUE(source_.atEOF()); +} + +// Test line counters. +TEST_F(InputSourceTest, lines) { + size_t line = 1; + while (!source_.atEOF()) { + if (source_.getChar() == '\n') { + ++line; + } + EXPECT_EQ(line, source_.getCurrentLine()); + } + + // Now, we are at EOF. + EXPECT_TRUE(source_.atEOF()); + EXPECT_EQ(4, source_.getCurrentLine()); + + // Go backwards 2 characters, skipping the last EOF and '\n'. + source_.ungetChar(); + source_.ungetChar(); + + EXPECT_FALSE(source_.atEOF()); + EXPECT_EQ(3, source_.getCurrentLine()); + + source_.ungetAll(); + + // Now we are back to where we started. + EXPECT_EQ(1, source_.getCurrentLine()); + EXPECT_FALSE(source_.atEOF()); + + // Now check that line numbers are decremented properly (as much as + // possible using the available API). + while (!source_.atEOF()) { + source_.getChar(); + } + line = source_.getCurrentLine(); + + // Now, we are at EOF. + EXPECT_TRUE(source_.atEOF()); + EXPECT_EQ(4, line); + + EXPECT_THROW({ + while (true) { + source_.ungetChar(); + EXPECT_TRUE(((line == source_.getCurrentLine()) || + ((line - 1) == source_.getCurrentLine()))); + line = source_.getCurrentLine(); + } + }, InputSource::UngetBeforeBeginning); + + // Now we are back to where we started. + EXPECT_EQ(1, source_.getCurrentLine()); +} + +// ungetAll() after saveLine() should skip back to the last-saved place. +TEST_F(InputSourceTest, saveLine) { + // First, skip to line 2. + while (!source_.atEOF() && + (source_.getCurrentLine() != 2)) { + source_.getChar(); + } + EXPECT_FALSE(source_.atEOF()); + EXPECT_EQ(2, source_.getCurrentLine()); + + // Now, save the line. + source_.saveLine(); + + // Now, go to EOF + while (!source_.atEOF()) { + source_.getChar(); + } + + // Now, we are at EOF. + EXPECT_TRUE(source_.atEOF()); + EXPECT_EQ(4, source_.getCurrentLine()); + + // Now, ungetAll() and check where it goes back. + source_.ungetAll(); + + // Now we are back to where we last-saved. + EXPECT_EQ(2, source_.getCurrentLine()); + EXPECT_FALSE(source_.atEOF()); +} + +TEST_F(InputSourceTest, getSize) { + // A simple case using string stream + EXPECT_EQ(strlen(test_input), source_.getSize()); + + // Check it works with an empty input + istringstream iss(""); + EXPECT_EQ(0, InputSource(iss).getSize()); + + // Pretend there's an error in seeking in the stream. It will be + // considered a seek specific error, and getSize() returns "unknown". + iss.setstate(std::ios_base::failbit); + EXPECT_EQ(MasterLexer::SOURCE_SIZE_UNKNOWN, InputSource(iss).getSize()); + // The fail bit should have been cleared. + EXPECT_FALSE(iss.fail()); + + // Pretend there's a *critical* error in the stream. The constructor will + // throw in the attempt of getting the input size. + iss.setstate(std::ios_base::badbit); + EXPECT_THROW(InputSource isrc(iss), InputSource::OpenError); + + // Check with input source from file name. We hardcode the file size + // for simplicity. It won't change too often. + EXPECT_EQ(143, InputSource(TEST_DATA_SRCDIR "/masterload.txt").getSize()); +} + +TEST_F(InputSourceTest, getPosition) { + // Initially the position is set to 0. Other cases are tested in tests + // for get and unget. + EXPECT_EQ(0, source_.getPosition()); + EXPECT_EQ(0, InputSource(TEST_DATA_SRCDIR "/masterload.txt").getPosition()); +} + +} // end namespace diff --git a/src/lib/dns/tests/master_lexer_state_unittest.cc b/src/lib/dns/tests/master_lexer_state_unittest.cc new file mode 100644 index 0000000..e810136 --- /dev/null +++ b/src/lib/dns/tests/master_lexer_state_unittest.cc @@ -0,0 +1,607 @@ +// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/master_lexer.h> +#include <dns/master_lexer_inputsource.h> +#include <dns/master_lexer_state.h> + +#include <gtest/gtest.h> + +#include <sstream> + +using namespace isc::dns; +using namespace master_lexer_internal; + +namespace { +typedef MasterToken Token; // shortcut + +class MasterLexerStateTest : public ::testing::Test { +protected: + MasterLexerStateTest() : common_options(MasterLexer::INITIAL_WS), + s_null(NULL), + s_crlf(State::getInstance(State::CRLF)), + s_string(State::getInstance(State::String)), + s_qstring(State::getInstance(State::QString)), + s_number(State::getInstance(State::Number)), + options(MasterLexer::NONE), + orig_options(options) + {} + + // Specify INITIAL_WS as common initial options. + const MasterLexer::Options common_options; + MasterLexer lexer; + const State* const s_null; + const State& s_crlf; + const State& s_string; + const State& s_qstring; + const State& s_number; + std::stringstream ss; + MasterLexer::Options options, orig_options; +}; + +// Common check for the end-of-file condition. +// Token is set to END_OF_FILE, and the lexer was NOT last eol state. +// Passed state can be any valid one; they are stateless, just providing the +// interface for inspection. +void +eofCheck(const State& state, MasterLexer& lexer) { + EXPECT_EQ(Token::END_OF_FILE, state.getToken(lexer).getType()); + EXPECT_FALSE(state.wasLastEOL(lexer)); +} + +TEST_F(MasterLexerStateTest, startAndEnd) { + // A simple case: the input is empty, so we begin with start and + // are immediately done. + lexer.pushSource(ss); + EXPECT_EQ(s_null, State::start(lexer, common_options)); + eofCheck(s_crlf, lexer); +} + +TEST_F(MasterLexerStateTest, startToEOL) { + ss << "\n"; + lexer.pushSource(ss); + + EXPECT_EQ(s_null, State::start(lexer, common_options)); + EXPECT_TRUE(s_crlf.wasLastEOL(lexer)); + EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType()); + + // The next lexer session will reach EOF. Same eof check should pass. + EXPECT_EQ(s_null, State::start(lexer, common_options)); + eofCheck(s_crlf, lexer); +} + +TEST_F(MasterLexerStateTest, space) { + // repeat '\t\n' twice (see below), then space after EOL + ss << " \t\n\t\n "; + lexer.pushSource(ss); + + // by default space characters and tabs will be ignored. We check this + // twice; at the second iteration, it's a white space at the beginning + // of line, but since we don't specify INITIAL_WS option, it's treated as + // normal space and ignored. + for (size_t i = 0; i < 2; ++i) { + EXPECT_EQ(s_null, State::start(lexer, MasterLexer::NONE)); + EXPECT_TRUE(s_crlf.wasLastEOL(lexer)); + EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType()); + } + + // Now we specify the INITIAL_WS option. It will be recognized and the + // corresponding token will be returned. + EXPECT_EQ(s_null, State::start(lexer, MasterLexer::INITIAL_WS)); + EXPECT_FALSE(s_crlf.wasLastEOL(lexer)); + EXPECT_EQ(Token::INITIAL_WS, s_crlf.getToken(lexer).getType()); +} + +TEST_F(MasterLexerStateTest, parentheses) { + ss << "\n(\na\n )\n "; // 1st \n is to check if 'was EOL' is set to false + lexer.pushSource(ss); + + EXPECT_EQ(s_null, State::start(lexer, common_options)); // handle \n + + // Now handle '('. It skips \n and recognize 'a' as string + EXPECT_EQ(0, s_crlf.getParenCount(lexer)); // check pre condition + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + EXPECT_EQ(1, s_crlf.getParenCount(lexer)); // check post condition + EXPECT_FALSE(s_crlf.wasLastEOL(lexer)); + + // skip 'a' + s_string.handle(lexer); + + // Then handle ')'. '\n' before ')' isn't recognized because + // it's canceled due to the '('. Likewise, the space after the '\n' + // shouldn't be recognized but should be just ignored. + EXPECT_EQ(s_null, State::start(lexer, common_options)); + EXPECT_EQ(0, s_crlf.getParenCount(lexer)); + + // Now, temporarily disabled options are restored: Both EOL and the + // initial WS are recognized + EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType()); + EXPECT_EQ(s_null, State::start(lexer, common_options)); + EXPECT_EQ(Token::INITIAL_WS, s_crlf.getToken(lexer).getType()); +} + +TEST_F(MasterLexerStateTest, nestedParentheses) { + // This is an unusual, but allowed (in this implementation) case. + ss << "(a(b)\n c)\n "; + lexer.pushSource(ss); + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); // consume '(' + s_string.handle(lexer); // consume 'a' + EXPECT_EQ(&s_string, State::start(lexer, common_options)); // consume '(' + s_string.handle(lexer); // consume 'b' + EXPECT_EQ(2, s_crlf.getParenCount(lexer)); // now the count is 2 + + // Close the inner most parentheses. count will be decreased, but option + // shouldn't be restored yet, so the intermediate EOL or initial WS won't + // be recognized. + EXPECT_EQ(&s_string, State::start(lexer, common_options)); // consume ')' + s_string.handle(lexer); // consume 'c' + EXPECT_EQ(1, s_crlf.getParenCount(lexer)); + + // Close the outermost parentheses. count will be reset to 0, and original + // options are restored. + EXPECT_EQ(s_null, State::start(lexer, common_options)); + + // Now, temporarily disabled options are restored: Both EOL and the + // initial WS are recognized + EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType()); + EXPECT_EQ(s_null, State::start(lexer, common_options)); + EXPECT_EQ(Token::INITIAL_WS, s_crlf.getToken(lexer).getType()); +} + +TEST_F(MasterLexerStateTest, unbalancedParentheses) { + // Only closing paren is provided. We prepend a \n to check if it's + // correctly canceled after detecting the error. + ss << "\n)"; + ss << "(a"; + lexer.pushSource(ss); + + EXPECT_EQ(s_null, State::start(lexer, common_options)); // consume '\n' + EXPECT_TRUE(s_crlf.wasLastEOL(lexer)); // this \n was remembered + + // Now checking ')'. The result should be error, count shouldn't be + // changed. "last EOL" should be canceled. + EXPECT_EQ(0, s_crlf.getParenCount(lexer)); + EXPECT_EQ(s_null, State::start(lexer, common_options)); + EXPECT_EQ(0, s_crlf.getParenCount(lexer)); + ASSERT_EQ(Token::ERROR, s_crlf.getToken(lexer).getType()); + EXPECT_EQ(Token::UNBALANCED_PAREN, s_crlf.getToken(lexer).getErrorCode()); + EXPECT_FALSE(s_crlf.wasLastEOL(lexer)); + + // Reach EOF with a dangling open parenthesis. + EXPECT_EQ(&s_string, State::start(lexer, common_options)); // consume '(' + s_string.handle(lexer); // consume 'a' + EXPECT_EQ(1, s_crlf.getParenCount(lexer)); + EXPECT_EQ(s_null, State::start(lexer, common_options)); // reach EOF + ASSERT_EQ(Token::ERROR, s_crlf.getToken(lexer).getType()); + EXPECT_EQ(Token::UNBALANCED_PAREN, s_crlf.getToken(lexer).getErrorCode()); + EXPECT_EQ(0, s_crlf.getParenCount(lexer)); // should be reset to 0 +} + +TEST_F(MasterLexerStateTest, startToComment) { + // Begin with 'start', detect space, then encounter a comment. Skip + // the rest of the line, and recognize the new line. Note that the + // second ';' is simply ignored. + ss << " ;a;\n"; + ss << ";a;"; // Likewise, but the comment ends with EOF. + lexer.pushSource(ss); + + // Initial whitespace (asked for in common_options) + EXPECT_EQ(s_null, State::start(lexer, common_options)); + EXPECT_EQ(Token::INITIAL_WS, s_crlf.getToken(lexer).getType()); + // Comment ending with EOL + EXPECT_EQ(s_null, State::start(lexer, common_options)); + EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType()); + + // Comment ending with EOF + EXPECT_EQ(s_null, State::start(lexer, common_options)); + EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType()); +} + +TEST_F(MasterLexerStateTest, commentAfterParen) { + // comment after an opening parenthesis. The code that is tested by + // other tests should also ensure that it works correctly, but we + // check it explicitly. + ss << "( ;this is a comment\na)\n"; + lexer.pushSource(ss); + + // consume '(', skip comments, consume 'a', then consume ')' + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); + EXPECT_EQ(s_null, State::start(lexer, common_options)); + EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType()); +} + +TEST_F(MasterLexerStateTest, crlf) { + ss << "\r\n"; // case 1 + ss << "\r "; // case 2 + ss << "\r;comment\na"; // case 3 + ss << "\r"; // case 4 + lexer.pushSource(ss); + + // 1. A sequence of \r, \n is recognized as a single 'end-of-line' + EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // recognize '\r' + s_crlf.handle(lexer); // recognize '\n' + EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType()); + EXPECT_TRUE(s_crlf.wasLastEOL(lexer)); + + // 2. Single '\r' (not followed by \n) is recognized as a single + // 'end-of-line'. then there will be "initial WS" + EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // recognize '\r' + // see ' ', "unget" it + s_crlf.handle(lexer); + EXPECT_EQ(s_null, State::start(lexer, common_options)); // recognize ' ' + EXPECT_EQ(Token::INITIAL_WS, s_crlf.getToken(lexer).getType()); + + // 3. comment between \r and \n + EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // recognize '\r' + // skip comments, recognize '\n' + s_crlf.handle(lexer); + EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType()); + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // skip 'a' + + // 4. \r then EOF + EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // recognize '\r' + // see EOF, then "unget" it + s_crlf.handle(lexer); + EXPECT_EQ(s_null, State::start(lexer, common_options)); // recognize EOF + EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType()); +} + +// Commonly used check for string related test cases, checking if the given +// token has expected values. +void +stringTokenCheck(const std::string& expected, const MasterToken& token, + bool quoted = false) +{ + EXPECT_EQ(quoted ? Token::QSTRING : Token::STRING, token.getType()); + EXPECT_EQ(expected, token.getString()); + const std::string actual(token.getStringRegion().beg, + token.getStringRegion().beg + + token.getStringRegion().len); + EXPECT_EQ(expected, actual); + + // There should be "hidden" nul-terminator after the string data. + ASSERT_NE(static_cast<const char*>(NULL), token.getStringRegion().beg); + EXPECT_EQ(0, *(token.getStringRegion().beg + token.getStringRegion().len)); +} + +TEST_F(MasterLexerStateTest, string) { + // Check with simple strings followed by separate characters + ss << "followed-by-EOL\n"; + ss << "followed-by-CR\r"; + ss << "followed-by-space "; + ss << "followed-by-tab\t"; + ss << "followed-by-comment;this is comment and ignored\n"; + ss << "followed-by-paren(closing)"; + ss << "followed-by-EOF"; + lexer.pushSource(ss); + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see \n + EXPECT_FALSE(s_string.wasLastEOL(lexer)); + stringTokenCheck("followed-by-EOL", s_string.getToken(lexer)); + EXPECT_EQ(s_null, State::start(lexer, common_options)); // skip \n + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see \r + stringTokenCheck("followed-by-CR", s_string.getToken(lexer)); + EXPECT_EQ(&s_crlf, State::start(lexer, common_options)); // handle \r... + s_crlf.handle(lexer); // ...and skip it + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see ' ' + stringTokenCheck("followed-by-space", s_string.getToken(lexer)); + + // skip ' ', then recognize the next string + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see \t + stringTokenCheck("followed-by-tab", s_string.getToken(lexer)); + + // skip \t, then recognize the next string + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see comment + stringTokenCheck("followed-by-comment", s_string.getToken(lexer)); + EXPECT_EQ(s_null, State::start(lexer, common_options)); // skip \n after it + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see '(' + stringTokenCheck("followed-by-paren", s_string.getToken(lexer)); + EXPECT_EQ(&s_string, State::start(lexer, common_options)); // str in () + s_string.handle(lexer); // recognize the str, see ')' + stringTokenCheck("closing", s_string.getToken(lexer)); + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see EOF + stringTokenCheck("followed-by-EOF", s_string.getToken(lexer)); +} + +TEST_F(MasterLexerStateTest, stringEscape) { + // some of the separate characters should be considered part of the + // string if escaped. + ss << "escaped\\ space "; + ss << "escaped\\\ttab "; + ss << "escaped\\(paren "; + ss << "escaped\\)close "; + ss << "escaped\\;comment "; + ss << "escaped\\\\ backslash "; // second '\' shouldn't escape ' ' + lexer.pushSource(ss); + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("escaped\\ space", s_string.getToken(lexer)); + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("escaped\\\ttab", s_string.getToken(lexer)); + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("escaped\\(paren", s_string.getToken(lexer)); + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("escaped\\)close", s_string.getToken(lexer)); + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("escaped\\;comment", s_string.getToken(lexer)); + + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see ' ' in mid + stringTokenCheck("escaped\\\\", s_string.getToken(lexer)); + + // Confirm the word that follows the escaped '\' is correctly recognized. + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("backslash", s_string.getToken(lexer)); +} + +TEST_F(MasterLexerStateTest, quotedString) { + ss << "\"ignore-quotes\"\n"; + ss << "\"quoted string\" "; // space is part of the qstring + ss << "\"\" "; // empty quoted string + // also check other separator characters. note that \r doesn't cause + // UNBALANCED_QUOTES. Not sure if it's intentional, but that's how the + // BIND 9 version works, so we follow it (it should be too minor to matter + // in practice anyway) + ss << "\"quoted()\t\rstring\" "; + ss << "\"escape\\ in quote\" "; + ss << "\"escaped\\\"\" "; + ss << "\"escaped backslash\\\\\" "; + ss << "\"no;comment\""; + lexer.pushSource(ss); + + // by default, '"' is unexpected (when QSTRING is not specified), + // and it returns MasterToken::UNEXPECTED_QUOTES. + EXPECT_EQ(s_null, State::start(lexer, common_options)); + EXPECT_EQ(Token::UNEXPECTED_QUOTES, s_string.getToken(lexer).getErrorCode()); + // Read it as a QSTRING. + s_qstring.handle(lexer); // recognize quoted str, see \n + stringTokenCheck("ignore-quotes", s_qstring.getToken(lexer), true); + EXPECT_EQ(s_null, State::start(lexer, common_options)); // skip \n after it + EXPECT_TRUE(s_string.wasLastEOL(lexer)); + + // If QSTRING is specified in option, '"' is regarded as a beginning of + // a quoted string. + const MasterLexer::Options options = common_options | MasterLexer::QSTRING; + EXPECT_EQ(&s_qstring, State::start(lexer, options)); + EXPECT_FALSE(s_string.wasLastEOL(lexer)); // EOL is canceled due to '"' + s_qstring.handle(lexer); + stringTokenCheck("quoted string", s_string.getToken(lexer), true); + + // Empty string is okay as qstring + EXPECT_EQ(&s_qstring, State::start(lexer, options)); + s_qstring.handle(lexer); + stringTokenCheck("", s_string.getToken(lexer), true); + + // Also checks other separator characters within a qstring + EXPECT_EQ(&s_qstring, State::start(lexer, options)); + s_qstring.handle(lexer); + stringTokenCheck("quoted()\t\rstring", s_string.getToken(lexer), true); + + // escape character mostly doesn't have any effect in the qstring + // processing + EXPECT_EQ(&s_qstring, State::start(lexer, options)); + s_qstring.handle(lexer); + stringTokenCheck("escape\\ in quote", s_string.getToken(lexer), true); + + // The only exception is the quotation mark itself. Note that the escape + // only works on the quotation mark immediately after it. + EXPECT_EQ(&s_qstring, State::start(lexer, options)); + s_qstring.handle(lexer); + stringTokenCheck("escaped\"", s_string.getToken(lexer), true); + + // quoted '\' then '"'. Unlike the previous case '"' shouldn't be + // escaped. + EXPECT_EQ(&s_qstring, State::start(lexer, options)); + s_qstring.handle(lexer); + stringTokenCheck("escaped backslash\\\\", s_string.getToken(lexer), true); + + // ';' has no meaning in a quoted string (not indicating a comment) + EXPECT_EQ(&s_qstring, State::start(lexer, options)); + s_qstring.handle(lexer); + stringTokenCheck("no;comment", s_string.getToken(lexer), true); +} + +TEST_F(MasterLexerStateTest, brokenQuotedString) { + ss << "\"unbalanced-quote\n"; + ss << "\"quoted\\\n\" "; + ss << "\"unclosed quote and EOF"; + lexer.pushSource(ss); + + // EOL is encountered without closing the quote + const MasterLexer::Options options = common_options | MasterLexer::QSTRING; + EXPECT_EQ(&s_qstring, State::start(lexer, options)); + s_qstring.handle(lexer); + ASSERT_EQ(Token::ERROR, s_qstring.getToken(lexer).getType()); + EXPECT_EQ(Token::UNBALANCED_QUOTES, + s_qstring.getToken(lexer).getErrorCode()); + // We can resume after the error from the '\n' + EXPECT_EQ(s_null, State::start(lexer, options)); + EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType()); + + // \n is okay in a quoted string if escaped + EXPECT_EQ(&s_qstring, State::start(lexer, options)); + s_qstring.handle(lexer); + stringTokenCheck("quoted\\\n", s_string.getToken(lexer), true); + + // EOF is encountered without closing the quote + EXPECT_EQ(&s_qstring, State::start(lexer, options)); + s_qstring.handle(lexer); + ASSERT_EQ(Token::ERROR, s_qstring.getToken(lexer).getType()); + EXPECT_EQ(Token::UNEXPECTED_END, s_qstring.getToken(lexer).getErrorCode()); + // If we continue we'll simply see the EOF + EXPECT_EQ(s_null, State::start(lexer, options)); + EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType()); +} + +TEST_F(MasterLexerStateTest, basicNumbers) { + ss << "0 "; + ss << "1 "; + ss << "12345 "; + ss << "4294967295 "; // 2^32-1 + ss << "4294967296 "; // Out of range + ss << "340282366920938463463374607431768211456 "; + // Very much out of range (2^128) + ss << "005 "; // Leading zeroes are ignored + ss << "42;asdf\n"; // Number with comment + ss << "37"; // Simple number again, here to make + // sure none of the above messed up + // the tokenizer + lexer.pushSource(ss); + + // Ask the lexer to recognize numbers as well + const MasterLexer::Options options = common_options | MasterLexer::NUMBER; + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + EXPECT_EQ(0, s_number.getToken(lexer).getNumber()); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + EXPECT_EQ(1, s_number.getToken(lexer).getNumber()); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + EXPECT_EQ(12345, s_number.getToken(lexer).getNumber()); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + EXPECT_EQ(4294967295u, s_number.getToken(lexer).getNumber()); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + EXPECT_EQ(Token::NUMBER_OUT_OF_RANGE, + s_number.getToken(lexer).getErrorCode()); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + EXPECT_EQ(Token::NUMBER_OUT_OF_RANGE, + s_number.getToken(lexer).getErrorCode()); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + EXPECT_EQ(5, s_number.getToken(lexer).getNumber()); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + EXPECT_EQ(42, s_number.getToken(lexer).getNumber()); + + EXPECT_EQ(s_null, State::start(lexer, options)); + EXPECT_TRUE(s_crlf.wasLastEOL(lexer)); + EXPECT_EQ(Token::END_OF_LINE, s_crlf.getToken(lexer).getType()); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + EXPECT_EQ(37, s_number.getToken(lexer).getNumber()); + + // If we continue we'll simply see the EOF + EXPECT_EQ(s_null, State::start(lexer, options)); + EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType()); +} + +// Test tokens that look like (or start out as) numbers, +// but turn out to be strings. Tests include escaped characters. +TEST_F(MasterLexerStateTest, stringNumbers) { + ss << "123 "; // Should be read as a string if the + // NUMBER option is not given + ss << "-1 "; // Negative numbers are interpreted + // as strings (unsigned integers only) + ss << "123abc456 "; // 'Numbers' containing non-digits should + // be interpreted as strings + ss << "123\\456 "; // Numbers containing escaped digits are + // interpreted as strings + ss << "3scaped\\ space "; + ss << "3scaped\\\ttab "; + ss << "3scaped\\(paren "; + ss << "3scaped\\)close "; + ss << "3scaped\\;comment "; + ss << "3scaped\\\\ 8ackslash "; // second '\' shouldn't escape ' ' + + lexer.pushSource(ss); + + // Note that common_options does not include MasterLexer::NUMBER, + // so the token should be recognized as a string + EXPECT_EQ(&s_string, State::start(lexer, common_options)); + s_string.handle(lexer); + stringTokenCheck("123", s_string.getToken(lexer), false); + + // Ask the lexer to recognize numbers as well + const MasterLexer::Options options = common_options | MasterLexer::NUMBER; + + EXPECT_EQ(&s_string, State::start(lexer, options)); + s_string.handle(lexer); + stringTokenCheck("-1", s_string.getToken(lexer), false); + + // Starts out as a number, but ends up being a string + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + stringTokenCheck("123abc456", s_number.getToken(lexer), false); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); + stringTokenCheck("123\\456", s_number.getToken(lexer), false); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("3scaped\\ space", s_number.getToken(lexer)); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("3scaped\\\ttab", s_number.getToken(lexer)); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("3scaped\\(paren", s_number.getToken(lexer)); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("3scaped\\)close", s_number.getToken(lexer)); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("3scaped\\;comment", s_number.getToken(lexer)); + + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); // recognize str, see ' ' in mid + stringTokenCheck("3scaped\\\\", s_number.getToken(lexer)); + + // Confirm the word that follows the escaped '\' is correctly recognized. + EXPECT_EQ(&s_number, State::start(lexer, options)); + s_number.handle(lexer); // recognize str, see ' ' at end + stringTokenCheck("8ackslash", s_number.getToken(lexer)); + + // If we continue we'll simply see the EOF + EXPECT_EQ(s_null, State::start(lexer, options)); + EXPECT_EQ(Token::END_OF_FILE, s_crlf.getToken(lexer).getType()); +} + +} // end anonymous namespace + diff --git a/src/lib/dns/tests/master_lexer_token_unittest.cc b/src/lib/dns/tests/master_lexer_token_unittest.cc new file mode 100644 index 0000000..2167a9f --- /dev/null +++ b/src/lib/dns/tests/master_lexer_token_unittest.cc @@ -0,0 +1,162 @@ +// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <exceptions/exceptions.h> + +#include <dns/master_lexer.h> + +#include <gtest/gtest.h> + +#include <string> + +using namespace isc::dns; + +namespace { + +const char TEST_STRING[] = "string token"; +// This excludes the ending \0 character +const size_t TEST_STRING_LEN = sizeof(TEST_STRING) - 1; + +class MasterLexerTokenTest : public ::testing::Test { +protected: + MasterLexerTokenTest() : + token_eof(MasterToken::END_OF_FILE), + token_str(TEST_STRING, TEST_STRING_LEN), + token_num(42), + token_err(MasterToken::UNEXPECTED_END) + {} + + const MasterToken token_eof; // an example of non-value type token + const MasterToken token_str; + const MasterToken token_num; + const MasterToken token_err; +}; + + +TEST_F(MasterLexerTokenTest, strings) { + // basic construction and getter checks + EXPECT_EQ(MasterToken::STRING, token_str.getType()); + EXPECT_EQ(std::string("string token"), token_str.getString()); + std::string strval = "dummy"; // this should be replaced + token_str.getString(strval); + EXPECT_EQ(std::string("string token"), strval); + const MasterToken::StringRegion str_region = + token_str.getStringRegion(); + EXPECT_EQ(TEST_STRING, str_region.beg); + EXPECT_EQ(TEST_STRING_LEN, str_region.len); + + // Even if the stored string contains a nul character (in this case, + // it happens to be at the end of the string, but could be in the middle), + // getString() should return a string object containing the nul. + std::string expected_str("string token"); + expected_str.push_back('\0'); + EXPECT_EQ(expected_str, + MasterToken(TEST_STRING, TEST_STRING_LEN + 1).getString()); + MasterToken(TEST_STRING, TEST_STRING_LEN + 1).getString(strval); + EXPECT_EQ(expected_str, strval); + + // Construct type of qstring + EXPECT_EQ(MasterToken::QSTRING, + MasterToken(TEST_STRING, sizeof(TEST_STRING), true). + getType()); + // if we explicitly set 'quoted' to false, it should be normal string + EXPECT_EQ(MasterToken::STRING, + MasterToken(TEST_STRING, sizeof(TEST_STRING), false). + getType()); + + // getString/StringRegion() aren't allowed for non string(-variant) types + EXPECT_THROW(token_eof.getString(), isc::InvalidOperation); + EXPECT_THROW(token_eof.getString(strval), isc::InvalidOperation); + EXPECT_THROW(token_num.getString(), isc::InvalidOperation); + EXPECT_THROW(token_num.getString(strval), isc::InvalidOperation); + EXPECT_THROW(token_eof.getStringRegion(), isc::InvalidOperation); + EXPECT_THROW(token_num.getStringRegion(), isc::InvalidOperation); +} + +TEST_F(MasterLexerTokenTest, numbers) { + EXPECT_EQ(42, token_num.getNumber()); + EXPECT_EQ(MasterToken::NUMBER, token_num.getType()); + + // It's copyable and assignable. + MasterToken token(token_num); + EXPECT_EQ(42, token.getNumber()); + EXPECT_EQ(MasterToken::NUMBER, token.getType()); + + token = token_num; + EXPECT_EQ(42, token.getNumber()); + EXPECT_EQ(MasterToken::NUMBER, token.getType()); + + // it's okay to replace it with a different type of token + token = token_eof; + EXPECT_EQ(MasterToken::END_OF_FILE, token.getType()); + + // Possible max value + token = MasterToken(0xffffffff); + EXPECT_EQ(4294967295u, token.getNumber()); + + // getNumber() isn't allowed for non number types + EXPECT_THROW(token_eof.getNumber(), isc::InvalidOperation); + EXPECT_THROW(token_str.getNumber(), isc::InvalidOperation); +} + +TEST_F(MasterLexerTokenTest, novalues) { + // Just checking we can construct them and getType() returns correct value. + EXPECT_EQ(MasterToken::END_OF_FILE, token_eof.getType()); + EXPECT_EQ(MasterToken::END_OF_LINE, + MasterToken(MasterToken::END_OF_LINE).getType()); + EXPECT_EQ(MasterToken::INITIAL_WS, + MasterToken(MasterToken::INITIAL_WS).getType()); + + // Special types of tokens cannot have value-based types + EXPECT_THROW(MasterToken t(MasterToken::STRING), isc::InvalidParameter); + EXPECT_THROW(MasterToken t(MasterToken::QSTRING), isc::InvalidParameter); + EXPECT_THROW(MasterToken t(MasterToken::NUMBER), isc::InvalidParameter); + EXPECT_THROW(MasterToken t(MasterToken::ERROR), isc::InvalidParameter); +} + +TEST_F(MasterLexerTokenTest, errors) { + EXPECT_EQ(MasterToken::ERROR, token_err.getType()); + EXPECT_EQ(MasterToken::UNEXPECTED_END, token_err.getErrorCode()); + EXPECT_EQ("unexpected end of input", token_err.getErrorText()); + EXPECT_EQ("lexer not started", MasterToken(MasterToken::NOT_STARTED). + getErrorText()); + EXPECT_EQ("unbalanced parentheses", + MasterToken(MasterToken::UNBALANCED_PAREN). + getErrorText()); + EXPECT_EQ("unbalanced quotes", MasterToken(MasterToken::UNBALANCED_QUOTES). + getErrorText()); + EXPECT_EQ("no token produced", MasterToken(MasterToken::NO_TOKEN_PRODUCED). + getErrorText()); + EXPECT_EQ("number out of range", + MasterToken(MasterToken::NUMBER_OUT_OF_RANGE). + getErrorText()); + EXPECT_EQ("not a valid number", + MasterToken(MasterToken::BAD_NUMBER).getErrorText()); + EXPECT_EQ("unexpected quotes", + MasterToken(MasterToken::UNEXPECTED_QUOTES).getErrorText()); + + // getErrorCode/Text() isn't allowed for non number types + EXPECT_THROW(token_num.getErrorCode(), isc::InvalidOperation); + EXPECT_THROW(token_num.getErrorText(), isc::InvalidOperation); + + // Only the pre-defined error code is accepted. Hardcoding '8' (max code + // + 1) is intentional; it'd be actually better if we notice it when we + // update the enum list (which shouldn't happen too often). + // + // Note: if you fix this testcase, you probably want to update the + // getErrorText() tests above too. + EXPECT_THROW(MasterToken(MasterToken::ErrorCode(8)), + isc::InvalidParameter); + + // Check the coexistence of "from number" and "from error-code" + // constructors won't cause confusion. + EXPECT_EQ(MasterToken::NUMBER, + MasterToken(static_cast<uint32_t>(MasterToken::NOT_STARTED)). + getType()); +} +} diff --git a/src/lib/dns/tests/master_lexer_unittest.cc b/src/lib/dns/tests/master_lexer_unittest.cc new file mode 100644 index 0000000..7bebb48 --- /dev/null +++ b/src/lib/dns/tests/master_lexer_unittest.cc @@ -0,0 +1,521 @@ +// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <exceptions/exceptions.h> + +#include <dns/master_lexer.h> +#include <dns/master_lexer_state.h> + +#include <gtest/gtest.h> + +#include <boost/lexical_cast.hpp> +#include <boost/scoped_ptr.hpp> + +#include <string> +#include <sstream> + +using namespace isc::dns; +using std::string; +using std::stringstream; +using boost::lexical_cast; +using boost::scoped_ptr; +using master_lexer_internal::State; + +namespace { + +class MasterLexerTest : public ::testing::Test { +protected: + MasterLexerTest() : + expected_stream_name("stream-" + lexical_cast<string>(&ss)) + {} + + MasterLexer lexer; + stringstream ss; + const string expected_stream_name; +}; + +// Commonly used check case where the input sources stack is empty. +void +checkEmptySource(const MasterLexer& lexer) { + EXPECT_TRUE(lexer.getSourceName().empty()); + EXPECT_EQ(0, lexer.getSourceLine()); + EXPECT_EQ(0, lexer.getPosition()); +} + +TEST_F(MasterLexerTest, preOpen) { + // Initially sources stack is empty. + checkEmptySource(lexer); +} + +TEST_F(MasterLexerTest, pushStream) { + EXPECT_EQ(0, lexer.getSourceCount()); + ss << "test"; + lexer.pushSource(ss); + EXPECT_EQ(expected_stream_name, lexer.getSourceName()); + EXPECT_EQ(1, lexer.getSourceCount()); + EXPECT_EQ(4, lexer.getTotalSourceSize()); // 4 = len("test") + + // From the point of view of this test, we only have to check (though + // indirectly) getSourceLine calls InputSource::getCurrentLine. It should + // return 1 initially. + EXPECT_EQ(1, lexer.getSourceLine()); + + // By popping it the stack will be empty again. + lexer.popSource(); + EXPECT_EQ(0, lexer.getSourceCount()); + checkEmptySource(lexer); + EXPECT_EQ(4, lexer.getTotalSourceSize()); // this shouldn't change +} + +TEST_F(MasterLexerTest, pushStreamFail) { + // Pretend a "bad" thing happened in the stream. This will make the + // initialization throw an exception. + ss << "test"; + ss.setstate(std::ios_base::badbit); + + EXPECT_THROW(lexer.pushSource(ss), isc::Unexpected); +} + +TEST_F(MasterLexerTest, pushFile) { + // We use zone file (-like) data, but in this test that actually doesn't + // matter. + EXPECT_EQ(0, lexer.getSourceCount()); + EXPECT_TRUE(lexer.pushSource(TEST_DATA_SRCDIR "/masterload.txt")); + EXPECT_EQ(1, lexer.getSourceCount()); + EXPECT_EQ(TEST_DATA_SRCDIR "/masterload.txt", lexer.getSourceName()); + EXPECT_EQ(1, lexer.getSourceLine()); + + // 143 = size of the test zone file. hardcode it assuming it won't change + // too often. + EXPECT_EQ(143, lexer.getTotalSourceSize()); + + lexer.popSource(); + checkEmptySource(lexer); + EXPECT_EQ(0, lexer.getSourceCount()); + EXPECT_EQ(143, lexer.getTotalSourceSize()); // this shouldn't change + + // If we give a non NULL string pointer, its content will be intact + // if pushSource succeeds. + std::string error_txt = "dummy"; + EXPECT_TRUE(lexer.pushSource(TEST_DATA_SRCDIR "/masterload.txt", + &error_txt)); + EXPECT_EQ("dummy", error_txt); +} + +TEST_F(MasterLexerTest, pushBadFileName) { + EXPECT_THROW(lexer.pushSource(NULL), isc::InvalidParameter); +} + +TEST_F(MasterLexerTest, pushFileFail) { + // The file to be pushed doesn't exist. pushSource() fails and + // some non empty error string should be set. + std::string error_txt; + EXPECT_TRUE(error_txt.empty()); + EXPECT_FALSE(lexer.pushSource("no-such-file", &error_txt)); + EXPECT_FALSE(error_txt.empty()); + + // It's safe to pass NULL error_txt (either explicitly or implicitly as + // the default) + EXPECT_FALSE(lexer.pushSource("no-such-file", NULL)); + EXPECT_FALSE(lexer.pushSource("no-such-file")); +} + +TEST_F(MasterLexerTest, nestedPush) { + const string test_txt = "test"; + ss << test_txt; + lexer.pushSource(ss); + + EXPECT_EQ(test_txt.size(), lexer.getTotalSourceSize()); + EXPECT_EQ(0, lexer.getPosition()); + + EXPECT_EQ(expected_stream_name, lexer.getSourceName()); + + // Read the string; getPosition() should reflect that. + EXPECT_EQ(MasterToken::STRING, lexer.getNextToken().getType()); + EXPECT_EQ(test_txt.size(), lexer.getPosition()); + + // We can push another source without popping the previous one. + lexer.pushSource(TEST_DATA_SRCDIR "/masterload.txt"); + EXPECT_EQ(TEST_DATA_SRCDIR "/masterload.txt", lexer.getSourceName()); + EXPECT_EQ(143 + test_txt.size(), + lexer.getTotalSourceSize()); // see above for magic nums + + // the next token should be the EOL (skipping a comment line), its + // position in the file is 35 (hardcoded). + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); + EXPECT_EQ(test_txt.size() + 35, lexer.getPosition()); + + // popSource() works on the "topmost" (last-pushed) source + lexer.popSource(); + EXPECT_EQ(expected_stream_name, lexer.getSourceName()); + + // pop shouldn't change the total size and the current position + EXPECT_EQ(143 + test_txt.size(), lexer.getTotalSourceSize()); + EXPECT_EQ(test_txt.size() + 35, lexer.getPosition()); + + lexer.popSource(); + EXPECT_TRUE(lexer.getSourceName().empty()); + + // size and position still shouldn't change + EXPECT_EQ(143 + test_txt.size(), lexer.getTotalSourceSize()); + EXPECT_EQ(test_txt.size() + 35, lexer.getPosition()); +} + +TEST_F(MasterLexerTest, unknownSourceSize) { + // Similar to the previous case, but the size of the second source + // will be considered "unknown" (by emulating an error). + ss << "test"; + lexer.pushSource(ss); + EXPECT_EQ(4, lexer.getTotalSourceSize()); + + stringstream ss2; + ss2.setstate(std::ios_base::failbit); // this will make the size unknown + lexer.pushSource(ss2); + // Then the total size is also unknown. + EXPECT_EQ(MasterLexer::SOURCE_SIZE_UNKNOWN, lexer.getTotalSourceSize()); + + // Even if we pop that source, the size is still unknown. + lexer.popSource(); + EXPECT_EQ(MasterLexer::SOURCE_SIZE_UNKNOWN, lexer.getTotalSourceSize()); +} + +TEST_F(MasterLexerTest, invalidPop) { + // popSource() cannot be called if the sources stack is empty. + EXPECT_THROW(lexer.popSource(), isc::InvalidOperation); +} + +// Test it is not possible to get token when no source is available. +TEST_F(MasterLexerTest, noSource) { + EXPECT_THROW(lexer.getNextToken(), isc::InvalidOperation); +} + +// Test getting some tokens. It also check basic behavior of getPosition(). +TEST_F(MasterLexerTest, getNextToken) { + ss << "\n \n\"STRING\"\n"; + lexer.pushSource(ss); + + // First, the newline should get out. + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); + EXPECT_EQ(1, lexer.getPosition()); + // Then the whitespace, if we specify the option. + EXPECT_EQ(MasterToken::INITIAL_WS, + lexer.getNextToken(MasterLexer::INITIAL_WS).getType()); + EXPECT_EQ(2, lexer.getPosition()); + // The newline + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); + EXPECT_EQ(5, lexer.getPosition()); // 1st \n + 3 spaces, then 2nd \n + // The (quoted) string + EXPECT_EQ(MasterToken::QSTRING, + lexer.getNextToken(MasterLexer::QSTRING).getType()); + EXPECT_EQ(5 + 8, lexer.getPosition()); // 8 = len("STRING') + quotes + + // And the end of line and file + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); + EXPECT_EQ(5 + 8 + 1, lexer.getPosition()); // previous + 3rd \n + EXPECT_EQ(MasterToken::END_OF_FILE, lexer.getNextToken().getType()); + EXPECT_EQ(5 + 8 + 1, lexer.getPosition()); // position doesn't change +} + +// Test we correctly find end of file. +TEST_F(MasterLexerTest, eof) { + // Let the ss empty. + lexer.pushSource(ss); + + // The first one is found to be EOF + EXPECT_EQ(MasterToken::END_OF_FILE, lexer.getNextToken().getType()); + // And it stays on EOF for any following attempts + EXPECT_EQ(MasterToken::END_OF_FILE, lexer.getNextToken().getType()); + // And we can step back one token, but that is the EOF too. + lexer.ungetToken(); + EXPECT_EQ(MasterToken::END_OF_FILE, lexer.getNextToken().getType()); +} + +// Check we properly return error when there's an opened parentheses and no +// closing one +TEST_F(MasterLexerTest, getUnbalancedParen) { + ss << "(string"; + lexer.pushSource(ss); + + // The string gets out first + EXPECT_EQ(MasterToken::STRING, lexer.getNextToken().getType()); + // Then an unbalanced parenthesis + EXPECT_EQ(MasterToken::UNBALANCED_PAREN, + lexer.getNextToken().getErrorCode()); + // And then EOF + EXPECT_EQ(MasterToken::END_OF_FILE, lexer.getNextToken().getType()); +} + +// Check we properly return error when there's an opened quoted string and no +// closing one +TEST_F(MasterLexerTest, getUnbalancedString) { + ss << "\"string"; + lexer.pushSource(ss); + + // Then an unbalanced qstring (reported as an unexpected end) + EXPECT_EQ(MasterToken::UNEXPECTED_END, + lexer.getNextToken(MasterLexer::QSTRING).getErrorCode()); + // And then EOF + EXPECT_EQ(MasterToken::END_OF_FILE, lexer.getNextToken().getType()); +} + +// Test ungetting tokens works. Also check getPosition() is adjusted +TEST_F(MasterLexerTest, ungetToken) { + ss << "\n (\"string\"\n) more"; + lexer.pushSource(ss); + + // Try getting the newline + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); + EXPECT_EQ(1, lexer.getPosition()); + // Return it and get again + lexer.ungetToken(); + EXPECT_EQ(0, lexer.getPosition()); + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); + EXPECT_EQ(1, lexer.getPosition()); + // Get the string and return it back + EXPECT_EQ(MasterToken::QSTRING, + lexer.getNextToken(MasterLexer::QSTRING).getType()); + EXPECT_EQ(string("\n (\"string\"").size(), lexer.getPosition()); + lexer.ungetToken(); + EXPECT_EQ(1, lexer.getPosition()); // back to just after 1st \n + // But if we change the options, it honors them + EXPECT_EQ(MasterToken::INITIAL_WS, + lexer.getNextToken(MasterLexer::QSTRING | + MasterLexer::INITIAL_WS).getType()); + // Get to the "more" string + EXPECT_EQ(MasterToken::QSTRING, + lexer.getNextToken(MasterLexer::QSTRING).getType()); + EXPECT_EQ(MasterToken::STRING, + lexer.getNextToken(MasterLexer::QSTRING).getType()); + // Return it back. It should get inside the parentheses. + // Upon next attempt to get it again, the newline inside the parentheses + // should be still ignored. + lexer.ungetToken(); + EXPECT_EQ(MasterToken::STRING, + lexer.getNextToken(MasterLexer::QSTRING).getType()); +} + +// Check ungetting token without overriding the start method. We also +// check it works well with changing options between the calls. +TEST_F(MasterLexerTest, ungetRealOptions) { + ss << " \n"; + lexer.pushSource(ss); + + // If we call it the usual way, it skips up to the newline and returns + // it + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); + + // Now we return it. If we call it again, but with different options, + // we get the initial whitespace. + lexer.ungetToken(); + EXPECT_EQ(MasterToken::INITIAL_WS, + lexer.getNextToken(MasterLexer::INITIAL_WS).getType()); +} + +// Check the initial whitespace is found even in the first line of included +// file. It also confirms getPosition() works for multiple sources, each +// of which is partially parsed. +TEST_F(MasterLexerTest, includeAndInitialWS) { + ss << " \n"; + lexer.pushSource(ss); + + stringstream ss2; + ss2 << " \n"; + + EXPECT_EQ(MasterToken::INITIAL_WS, + lexer.getNextToken(MasterLexer::INITIAL_WS).getType()); + EXPECT_EQ(1, lexer.getPosition()); + lexer.pushSource(ss2); + EXPECT_EQ(MasterToken::INITIAL_WS, + lexer.getNextToken(MasterLexer::INITIAL_WS).getType()); + EXPECT_EQ(2, lexer.getPosition()); // should be sum of pushed positions. +} + +// Test only one token can be ungotten +TEST_F(MasterLexerTest, ungetTwice) { + ss << "\n"; + lexer.pushSource(ss); + + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); + // Unget the token. It can be done once + lexer.ungetToken(); + // But not twice + EXPECT_THROW(lexer.ungetToken(), isc::InvalidOperation); +} + +// Test we can't unget a token before we get one +TEST_F(MasterLexerTest, ungetBeforeGet) { + lexer.pushSource(ss); // Just to eliminate the missing source problem + EXPECT_THROW(lexer.ungetToken(), isc::InvalidOperation); +} + +// Test we can't unget a token after a source switch, even when we got +// something before. +TEST_F(MasterLexerTest, ungetAfterSwitch) { + ss << "\n\n"; + lexer.pushSource(ss); + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); + // Switch the source + std::stringstream ss2; + ss2 << "\n\n"; + lexer.pushSource(ss2); + EXPECT_THROW(lexer.ungetToken(), isc::InvalidOperation); + // We can get from the new source + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); + // And when we drop the current source, we can't unget again + lexer.popSource(); + EXPECT_THROW(lexer.ungetToken(), isc::InvalidOperation); +} + +// Common checks for the case when getNextToken() should result in LexerError +void +lexerErrorCheck(MasterLexer& lexer, MasterToken::Type expect, + MasterToken::ErrorCode expected_error) +{ + bool thrown = false; + try { + lexer.getNextToken(expect); + } catch (const MasterLexer::LexerError& error) { + EXPECT_EQ(expected_error, error.token_.getErrorCode()); + thrown = true; + } + EXPECT_TRUE(thrown); +} + +// Common checks regarding expected/unexpected end-of-line +// +// The 'lexer' should be at a position before two consecutive '\n's. +// The first one will be recognized, and the second one will be considered an +// unexpected token. Then this helper consumes the second '\n', so the caller +// can continue the test after these '\n's. +void +eolCheck(MasterLexer& lexer, MasterToken::Type expect) { + // If EOL is found and eol_ok is true, we get it. + EXPECT_EQ(MasterToken::END_OF_LINE, + lexer.getNextToken(expect, true).getType()); + // We'll see the second '\n'; by default it will fail. + EXPECT_THROW(lexer.getNextToken(expect), MasterLexer::LexerError); + // Same if eol_ok is explicitly set to false. This also checks the + // offending '\n' was "ungotten". + EXPECT_THROW(lexer.getNextToken(expect, false), MasterLexer::LexerError); + + // And also check the error token set in the exception object. + lexerErrorCheck(lexer, expect, MasterToken::UNEXPECTED_END); + + // Then skip the 2nd '\n' + EXPECT_EQ(MasterToken::END_OF_LINE, lexer.getNextToken().getType()); +} + +// Common checks regarding expected/unexpected end-of-file +// +// The 'lexer' should be at a position just before an end-of-file. +void +eofCheck(MasterLexer& lexer, MasterToken::Type expect) { + EXPECT_EQ(MasterToken::END_OF_FILE, + lexer.getNextToken(expect, true).getType()); + EXPECT_THROW(lexer.getNextToken(expect), MasterLexer::LexerError); + EXPECT_THROW(lexer.getNextToken(expect, false), MasterLexer::LexerError); +} + +TEST_F(MasterLexerTest, getNextTokenString) { + ss << "normal-string\n"; + ss << "\n"; + ss << "another-string"; + lexer.pushSource(ss); + + // Normal successful case: Expecting a string and get one. + EXPECT_EQ("normal-string", + lexer.getNextToken(MasterToken::STRING).getString()); + eolCheck(lexer, MasterToken::STRING); + + // Same set of tests but for end-of-file + EXPECT_EQ("another-string", + lexer.getNextToken(MasterToken::STRING, true).getString()); + eofCheck(lexer, MasterToken::STRING); +} + +TEST_F(MasterLexerTest, getNextTokenQString) { + ss << "\"quoted-string\"\n"; + ss << "\n"; + ss << "normal-string"; + lexer.pushSource(ss); + + // Expecting a quoted string and get one. + EXPECT_EQ("quoted-string", + lexer.getNextToken(MasterToken::QSTRING).getString()); + eolCheck(lexer, MasterToken::QSTRING); + + // Expecting a quoted string but see a normal string. It's okay. + EXPECT_EQ("normal-string", + lexer.getNextToken(MasterToken::QSTRING).getString()); + eofCheck(lexer, MasterToken::QSTRING); +} + +TEST_F(MasterLexerTest, getNextTokenNumber) { + ss << "3600\n"; + ss << "\n"; + ss << "4294967296 "; // =2^32, out of range + ss << "not-a-number "; + ss << "123abc "; // starting with digits, but resulting in a string + ss << "86400"; + lexer.pushSource(ss); + + // Expecting a number string and get one. + EXPECT_EQ(3600, + lexer.getNextToken(MasterToken::NUMBER).getNumber()); + eolCheck(lexer, MasterToken::NUMBER); + + // Expecting a number, but it's too big for uint32. + lexerErrorCheck(lexer, MasterToken::NUMBER, + MasterToken::NUMBER_OUT_OF_RANGE); + // The token should have been "ungotten". Re-read and skip it. + EXPECT_EQ(MasterToken::STRING, lexer.getNextToken().getType()); + + // Expecting a number, but see a string. + lexerErrorCheck(lexer, MasterToken::NUMBER, MasterToken::BAD_NUMBER); + // The unexpected string should have been "ungotten". Re-read and skip it. + EXPECT_EQ(MasterToken::STRING, lexer.getNextToken().getType()); + + // Expecting a number, but see a string. + lexerErrorCheck(lexer, MasterToken::NUMBER, MasterToken::BAD_NUMBER); + // The unexpected string should have been "ungotten". Re-read and skip it. + EXPECT_EQ(MasterToken::STRING, lexer.getNextToken().getType()); + + // Unless we specify NUMBER, decimal number string should be recognized + // as a string. + EXPECT_EQ("86400", + lexer.getNextToken(MasterToken::STRING).getString()); + eofCheck(lexer, MasterToken::NUMBER); +} + +TEST_F(MasterLexerTest, getNextTokenErrors) { + // Check miscellaneous error cases + + ss << ") "; // unbalanced parenthesis + ss << "string-after-error "; + lexer.pushSource(ss); + + // Only string/qstring/number can be "expected". + EXPECT_THROW(lexer.getNextToken(MasterToken::END_OF_LINE), + isc::InvalidParameter); + EXPECT_THROW(lexer.getNextToken(MasterToken::END_OF_FILE), + isc::InvalidParameter); + EXPECT_THROW(lexer.getNextToken(MasterToken::INITIAL_WS), + isc::InvalidParameter); + EXPECT_THROW(lexer.getNextToken(MasterToken::ERROR), + isc::InvalidParameter); + + // If it encounters a syntax error, it results in LexerError exception. + lexerErrorCheck(lexer, MasterToken::STRING, MasterToken::UNBALANCED_PAREN); + + // Unlike the NUMBER_OUT_OF_RANGE case, the error part has been skipped + // within getNextToken(). We should be able to get the next token. + EXPECT_EQ("string-after-error", + lexer.getNextToken(MasterToken::STRING).getString()); +} + +} diff --git a/src/lib/dns/tests/master_loader_callbacks_test.cc b/src/lib/dns/tests/master_loader_callbacks_test.cc new file mode 100644 index 0000000..9d23802 --- /dev/null +++ b/src/lib/dns/tests/master_loader_callbacks_test.cc @@ -0,0 +1,79 @@ +// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/master_loader_callbacks.h> +#include <dns/rrset.h> +#include <dns/name.h> +#include <dns/rrttl.h> +#include <dns/rrclass.h> + +#include <exceptions/exceptions.h> + +#include <gtest/gtest.h> +#include <functional> + +namespace { + +using std::string; +using namespace isc::dns; +namespace ph = std::placeholders; + +class MasterLoaderCallbacksTest : public ::testing::Test { +protected: + MasterLoaderCallbacksTest() : + last_was_error_(false), // Not needed, but then cppcheck complains + issue_called_(false), + rrset_(new RRset(Name("example.org"), RRClass::IN(), RRType::A(), + RRTTL(3600))), + error_(std::bind(&MasterLoaderCallbacksTest::checkCallback, this, + true, ph::_1, ph::_2, ph::_3)), + warning_(std::bind(&MasterLoaderCallbacksTest::checkCallback, this, + false, ph::_1, ph::_2, ph::_3)), + callbacks_(error_, warning_) + {} + + void checkCallback(bool error, const string& source, size_t line, + const string& reason) + { + issue_called_ = true; + last_was_error_ = error; + EXPECT_EQ("source", source); + EXPECT_EQ(1, line); + EXPECT_EQ("reason", reason); + } + bool last_was_error_; + bool issue_called_; + const RRsetPtr rrset_; + const MasterLoaderCallbacks::IssueCallback error_, warning_; + MasterLoaderCallbacks callbacks_; +}; + +// Check the constructor rejects empty callbacks, but accepts non-empty ones +TEST_F(MasterLoaderCallbacksTest, constructor) { + EXPECT_THROW(MasterLoaderCallbacks(MasterLoaderCallbacks::IssueCallback(), + warning_), isc::InvalidParameter); + EXPECT_THROW(MasterLoaderCallbacks(error_, + MasterLoaderCallbacks::IssueCallback()), + isc::InvalidParameter); + EXPECT_NO_THROW(MasterLoaderCallbacks(error_, warning_)); +} + +// Call the issue callbacks +TEST_F(MasterLoaderCallbacksTest, issueCall) { + callbacks_.error("source", 1, "reason"); + EXPECT_TRUE(last_was_error_); + EXPECT_TRUE(issue_called_); + + issue_called_ = false; + + callbacks_.warning("source", 1, "reason"); + EXPECT_FALSE(last_was_error_); + EXPECT_TRUE(issue_called_); +} + +} diff --git a/src/lib/dns/tests/master_loader_unittest.cc b/src/lib/dns/tests/master_loader_unittest.cc new file mode 100644 index 0000000..74300d3 --- /dev/null +++ b/src/lib/dns/tests/master_loader_unittest.cc @@ -0,0 +1,1445 @@ +// Copyright (C) 2012-2021 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/master_loader_callbacks.h> +#include <dns/master_loader.h> +#include <dns/rrtype.h> +#include <dns/rrset.h> +#include <dns/rrclass.h> +#include <dns/rrttl.h> +#include <dns/name.h> +#include <dns/rdata.h> + +#include <gtest/gtest.h> + +#include <boost/lexical_cast.hpp> +#include <boost/scoped_ptr.hpp> + +#include <functional> +#include <string> +#include <vector> +#include <list> +#include <sstream> + +using namespace isc::dns; +using std::vector; +using std::string; +using std::list; +using std::stringstream; +using std::endl; +using boost::lexical_cast; +namespace ph = std::placeholders; + +namespace { +class MasterLoaderTest : public ::testing::Test { +public: + MasterLoaderTest() : + callbacks_(std::bind(&MasterLoaderTest::callback, this, + &errors_, ph::_1, ph::_2, ph::_3), + std::bind(&MasterLoaderTest::callback, this, + &warnings_, ph::_1, ph::_2, ph::_3)) + {} + + void TearDown() { + // Check there are no more RRs we didn't expect + EXPECT_TRUE(rrsets_.empty()); + } + + /// Concatenate file, line, and reason, and add it to either errors + /// or warnings + void callback(vector<string>* target, const std::string& file, size_t line, + const std::string& reason) + { + std::stringstream ss; + ss << reason << " [" << file << ":" << line << "]"; + target->push_back(ss.str()); + } + + void addRRset(const Name& name, const RRClass& rrclass, + const RRType& rrtype, const RRTTL& rrttl, + const rdata::RdataPtr& data) { + const RRsetPtr rrset(new BasicRRset(name, rrclass, rrtype, rrttl)); + rrset->addRdata(data); + rrsets_.push_back(rrset); + } + + void setLoader(const char* file, const Name& origin, + const RRClass& rrclass, const MasterLoader::Options options) + { + loader_.reset(new MasterLoader(file, origin, rrclass, callbacks_, + std::bind(&MasterLoaderTest::addRRset, + this, ph::_1, ph::_2, ph::_3, + ph::_4, ph::_5), + options)); + } + + void setLoader(std::istream& stream, const Name& origin, + const RRClass& rrclass, const MasterLoader::Options options) + { + loader_.reset(new MasterLoader(stream, origin, rrclass, callbacks_, + std::bind(&MasterLoaderTest::addRRset, + this, ph::_1, ph::_2, ph::_3, + ph::_4, ph::_5), + options)); + } + + static string prepareZone(const string& line, bool include_last) { + string result; + result += "example.org. 3600 IN SOA ns1.example.org. " + "admin.example.org. 1234 3600 1800 2419200 7200\n"; + result += line; + if (include_last) { + result += "\n"; + result += "correct 3600 IN A 192.0.2.2\n"; + } + return (result); + } + + void clear() { + warnings_.clear(); + errors_.clear(); + rrsets_.clear(); + } + + // Check the next RR in the ones produced by the loader + // Other than passed arguments are checked to be the default for the tests + void checkRR(const string& name, const RRType& type, const string& data, + const RRTTL& rrttl = RRTTL(3600)) { + ASSERT_FALSE(rrsets_.empty()); + RRsetPtr current = rrsets_.front(); + rrsets_.pop_front(); + + EXPECT_EQ(Name(name), current->getName()); + EXPECT_EQ(type, current->getType()); + EXPECT_EQ(RRClass::IN(), current->getClass()); + EXPECT_EQ(rrttl, current->getTTL()); + ASSERT_EQ(1, current->getRdataCount()); + EXPECT_EQ(0, isc::dns::rdata::createRdata(type, RRClass::IN(), data)-> + compare(current->getRdataIterator()->getCurrent())) + << data << " vs. " + << current->getRdataIterator()->getCurrent().toText(); + } + + void checkBasicRRs() { + checkRR("example.org", RRType::SOA(), + "ns1.example.org. admin.example.org. " + "1234 3600 1800 2419200 7200"); + checkRR("example.org", RRType::NS(), "ns1.example.org."); + checkRR("www.example.org", RRType::A(), "192.0.2.1"); + checkRR("www.example.org", RRType::AAAA(), "2001:db8::1"); + } + + void checkARR(const string& name) { + checkRR(name, RRType::A(), "192.0.2.1"); + } + + MasterLoaderCallbacks callbacks_; + boost::scoped_ptr<MasterLoader> loader_; + vector<string> errors_; + vector<string> warnings_; + list<RRsetPtr> rrsets_; +}; + +// Test simple loading. The zone file contains no tricky things, and nothing is +// omitted. No RRset contains more than one RR Also no errors or warnings. +TEST_F(MasterLoaderTest, basicLoad) { + setLoader(TEST_DATA_SRCDIR "/example.org", Name("example.org."), + RRClass::IN(), MasterLoader::MANY_ERRORS); + + EXPECT_FALSE(loader_->loadedSuccessfully()); + + // The following three should be set to 0 initially in case the loader + // is constructed from a file name. + EXPECT_EQ(0, loader_->getSize()); + EXPECT_EQ(0, loader_->getPosition()); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + + EXPECT_TRUE(errors_.empty()); + EXPECT_TRUE(warnings_.empty()); + + // Hardcode expected values taken from the test data file, assuming it + // won't change too often. + EXPECT_EQ(550, loader_->getSize()); + EXPECT_EQ(550, loader_->getPosition()); + + checkBasicRRs(); +} + +// Test the $INCLUDE directive +TEST_F(MasterLoaderTest, include) { + // Test various cases of include + const char* includes[] = { + "$include", + "$INCLUDE", + "$Include", + "$InCluDe", + "\"$INCLUDE\"", + NULL + }; + for (const char** include = includes; *include != NULL; ++include) { + SCOPED_TRACE(*include); + + clear(); + // Prepare input source that has the include and some more data + // below (to see it returns back to the original source). + const string include_str = string(*include) + " " + + TEST_DATA_SRCDIR + "/example.org\nwww 3600 IN AAAA 2001:db8::1\n"; + stringstream ss(include_str); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + EXPECT_TRUE(warnings_.empty()); + + checkBasicRRs(); + checkRR("www.example.org", RRType::AAAA(), "2001:db8::1"); + } +} + +TEST_F(MasterLoaderTest, includeAndIncremental) { + // Check getSize() and getPosition() are adjusted before and after + // $INCLUDE. + const string first_rr = "before.example.org. 0 A 192.0.2.1\n"; + const string include_str = "$INCLUDE " TEST_DATA_SRCDIR "/example.org"; + const string zone_data = first_rr + include_str + "\n" + + "www 3600 IN AAAA 2001:db8::1\n"; + stringstream ss(zone_data); + setLoader(ss, Name("example.org."), RRClass::IN(), MasterLoader::DEFAULT); + + // On construction, getSize() returns the size of the data (exclude the + // the file to be included); position is set to 0. + EXPECT_EQ(zone_data.size(), loader_->getSize()); + EXPECT_EQ(0, loader_->getPosition()); + + // Read the first RR. getSize() doesn't change; position should be + // at the end of the first line. + loader_->loadIncremental(1); + EXPECT_EQ(zone_data.size(), loader_->getSize()); + EXPECT_EQ(first_rr.size(), loader_->getPosition()); + + // Read next 4. It includes $INCLUDE processing. Magic number of 550 + // is the size of the test zone file (see above); 507 is the position in + // the file at the end of 4th RR (due to extra comments it's smaller than + // the file size). + loader_->loadIncremental(4); + EXPECT_EQ(zone_data.size() + 550, loader_->getSize()); + EXPECT_EQ(first_rr.size() + include_str.size() + 507, + loader_->getPosition()); + + // Read the last one. At this point getSize and getPosition return + // the same value, indicating progress of 100%. + loader_->loadIncremental(1); + EXPECT_EQ(zone_data.size() + 550, loader_->getSize()); + EXPECT_EQ(zone_data.size() + 550, loader_->getPosition()); + + // we were not interested in checking RRs in this test. clear them to + // not confuse TearDown(). + rrsets_.clear(); +} + +// A commonly used helper to check callback message. +void +checkCallbackMessage(const string& actual_msg, const string& expected_msg, + size_t expected_line) { + // The actual message should begin with the expected message. + EXPECT_EQ(0, actual_msg.find(expected_msg)) << "actual message: " << + actual_msg << " expected: " << + expected_msg; + + // and it should end with "...:<line_num>]" + const string line_desc = ":" + lexical_cast<string>(expected_line) + "]"; + EXPECT_EQ(actual_msg.size() - line_desc.size(), + actual_msg.find(line_desc)) << "Expected on line " << + expected_line; +} + +TEST_F(MasterLoaderTest, origin) { + // Various forms of the directive + const char* origins[] = { + "$origin", + "$ORIGIN", + "$Origin", + "$OrigiN", + "\"$ORIGIN\"", + NULL + }; + for (const char** origin = origins; *origin != NULL; ++origin) { + SCOPED_TRACE(*origin); + + clear(); + const string directive = *origin; + const string input = + "@ 1H IN A 192.0.2.1\n" + + directive + " sub.example.org.\n" + "\"www\" 1H IN A 192.0.2.1\n" + + // Relative name in the origin + directive + " relative\n" + "@ 1H IN A 192.0.2.1\n" + // Origin is _not_ used here (absolute name) + "noorigin.example.org. 60M IN A 192.0.2.1\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + // There's a relative origin in it, we warn about that. + EXPECT_EQ(1, warnings_.size()); + checkCallbackMessage(warnings_.at(0), + "The new origin is relative, did you really mean " + "relative.sub.example.org.?", 4); + + checkARR("example.org"); + checkARR("www.sub.example.org"); + checkARR("relative.sub.example.org"); + checkARR("noorigin.example.org"); + } +} + +TEST_F(MasterLoaderTest, generate) { + // Various forms of the directive + const char* generates[] = { + "$generate", + "$GENERATE", + "$Generate", + "$GeneratE", + "\"$GENERATE\"", + NULL + }; + for (const char** generate = generates; *generate != NULL; ++generate) { + SCOPED_TRACE(*generate); + + clear(); + const string directive = *generate; + const string input = + "$ORIGIN example.org.\n" + "before.example.org. 3600 IN A 192.0.2.0\n" + + directive + " 3-5 host$ A 192.0.2.$\n" + + "after.example.org. 3600 IN A 192.0.2.255\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + // The "before" and "after" scaffolding below checks that no + // extra records are added by $GENERATE outside the requested + // range. + checkRR("before.example.org", RRType::A(), "192.0.2.0"); + checkRR("host3.example.org", RRType::A(), "192.0.2.3"); + checkRR("host4.example.org", RRType::A(), "192.0.2.4"); + checkRR("host5.example.org", RRType::A(), "192.0.2.5"); + checkRR("after.example.org", RRType::A(), "192.0.2.255"); + } +} + +TEST_F(MasterLoaderTest, generateRelativeLHS) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 1-2 @ 3600 NS ns$.example.org.\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + checkRR("example.org", RRType::NS(), "ns1.example.org."); + checkRR("example.org", RRType::NS(), "ns2.example.org."); +} + +TEST_F(MasterLoaderTest, generateInFront) { + // $ is in the front + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 9-10 $host 3600 TXT \"$ pomegranate\"\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + checkRR("9host.example.org", RRType::TXT(), "9 pomegranate"); + checkRR("10host.example.org", RRType::TXT(), "10 pomegranate"); +} + +TEST_F(MasterLoaderTest, generateInMiddle) { + // $ is in the middle + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 9-10 num$-host 3600 TXT \"This is $ pomegranate\"\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + checkRR("num9-host.example.org", RRType::TXT(), "This is 9 pomegranate"); + checkRR("num10-host.example.org", RRType::TXT(), "This is 10 pomegranate"); +} + +TEST_F(MasterLoaderTest, generateAtEnd) { + // $ is at the end + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 9-10 num$-host 3600 TXT Pomegranate$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + checkRR("num9-host.example.org", RRType::TXT(), "Pomegranate9"); + checkRR("num10-host.example.org", RRType::TXT(), "Pomegranate10"); +} + +TEST_F(MasterLoaderTest, generateStripsQuotes) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 1-2 @ 3600 MX \"$ mx$.example.org.\"\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + checkRR("example.org", RRType::MX(), "1 mx1.example.org."); + checkRR("example.org", RRType::MX(), "2 mx2.example.org."); +} + +TEST_F(MasterLoaderTest, generateWithDoublePlaceholder) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 9-10 host$ 3600 TXT \"This is $$ pomegranate\"\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + checkRR("host9.example.org", RRType::TXT(), "This is $ pomegranate"); + checkRR("host10.example.org", RRType::TXT(), "This is $ pomegranate"); +} + +TEST_F(MasterLoaderTest, generateWithEscape) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 9-10 host$ 3600 TXT \"This is \\$\\pomegranate\"\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + checkRR("host9.example.org", RRType::TXT(), "This is \\$\\pomegranate"); + checkRR("host10.example.org", RRType::TXT(), "This is \\$\\pomegranate"); +} + +TEST_F(MasterLoaderTest, generateWithParams) { + const string input = + "$ORIGIN example.org.\n" + "$TTL 3600\n" + "$GENERATE 2-3 host$ A 192.0.2.$\n" + "$GENERATE 5-6 host$ 3600 A 192.0.2.$\n" + "$GENERATE 8-9 host$ IN A 192.0.2.$\n" + "$GENERATE 11-12 host$ IN 3600 A 192.0.2.$\n" + "$GENERATE 14-15 host$ 3600 IN A 192.0.2.$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + checkRR("host2.example.org", RRType::A(), "192.0.2.2"); + checkRR("host3.example.org", RRType::A(), "192.0.2.3"); + + checkRR("host5.example.org", RRType::A(), "192.0.2.5"); + checkRR("host6.example.org", RRType::A(), "192.0.2.6"); + + checkRR("host8.example.org", RRType::A(), "192.0.2.8"); + checkRR("host9.example.org", RRType::A(), "192.0.2.9"); + + checkRR("host11.example.org", RRType::A(), "192.0.2.11"); + checkRR("host12.example.org", RRType::A(), "192.0.2.12"); + + checkRR("host14.example.org", RRType::A(), "192.0.2.14"); + checkRR("host15.example.org", RRType::A(), "192.0.2.15"); +} + +TEST_F(MasterLoaderTest, generateWithStep) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 2-9/2 host$ 3600 A 192.0.2.$\n" + "$GENERATE 12-21/3 host$ 3600 A 192.0.2.$\n" + "$GENERATE 30-31/1 host$ 3600 A 192.0.2.$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + checkRR("host2.example.org", RRType::A(), "192.0.2.2"); + checkRR("host4.example.org", RRType::A(), "192.0.2.4"); + checkRR("host6.example.org", RRType::A(), "192.0.2.6"); + checkRR("host8.example.org", RRType::A(), "192.0.2.8"); + + checkRR("host12.example.org", RRType::A(), "192.0.2.12"); + checkRR("host15.example.org", RRType::A(), "192.0.2.15"); + checkRR("host18.example.org", RRType::A(), "192.0.2.18"); + checkRR("host21.example.org", RRType::A(), "192.0.2.21"); + + checkRR("host30.example.org", RRType::A(), "192.0.2.30"); + checkRR("host31.example.org", RRType::A(), "192.0.2.31"); +} + +TEST_F(MasterLoaderTest, generateWithModifiers) { + const string input = + "$ORIGIN example.org.\n" + "$TTL 3600\n" + + // Use a positive delta of 1 in the LHS and a negative delta of + // -1 in the RHS + "$GENERATE 2-9/2 host${1} A 192.0.2.${-1}\n" + + "$GENERATE 10-12 host${0,4} A 192.0.2.$\n" + "$GENERATE 14-15 host${0,4,d} A 192.0.2.$\n" + + // Names are case-insensitive, so we use TXT's RDATA to check + // case with hex representation. + "$GENERATE 30-31 host$ TXT \"Value ${0,4,x}\"\n" + "$GENERATE 42-43 host$ TXT \"Value ${0,4,X}\"\n" + + // Octal does not use any alphabets + "$GENERATE 45-46 host${0,4,o} A 192.0.2.$\n" + + // Here, the LHS has a trailing dot (which would result in an + // out-of-zone name), but that should be handled as a relative + // name. + "$GENERATE 90-92 ${0,8,n} A 192.0.2.$\n" + + // Here, the LHS has no trailing dot, and results in the same + // number of labels as width=8 above. + "$GENERATE 94-96 ${0,7,n} A 192.0.2.$\n" + + // Names are case-insensitive, so we use TXT's RDATA to check + // case with nibble representation. + "$GENERATE 106-107 host$ TXT \"Value ${0,9,n}\"\n" + "$GENERATE 109-110 host$ TXT \"Value ${0,9,N}\"\n" + + // Junk type will not parse and 'd' is assumed. No error is + // generated (this is to match BIND 9 behavior). + "$GENERATE 200-201 host${0,4,j} A 192.0.2.$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + + checkRR("host3.example.org", RRType::A(), "192.0.2.1"); + checkRR("host5.example.org", RRType::A(), "192.0.2.3"); + checkRR("host7.example.org", RRType::A(), "192.0.2.5"); + checkRR("host9.example.org", RRType::A(), "192.0.2.7"); + + checkRR("host0010.example.org", RRType::A(), "192.0.2.10"); + checkRR("host0011.example.org", RRType::A(), "192.0.2.11"); + checkRR("host0012.example.org", RRType::A(), "192.0.2.12"); + + checkRR("host0014.example.org", RRType::A(), "192.0.2.14"); + checkRR("host0015.example.org", RRType::A(), "192.0.2.15"); + + checkRR("host30.example.org", RRType::TXT(), "Value 001e"); + checkRR("host31.example.org", RRType::TXT(), "Value 001f"); + + checkRR("host42.example.org", RRType::TXT(), "Value 002A"); + checkRR("host43.example.org", RRType::TXT(), "Value 002B"); + + checkRR("host0055.example.org", RRType::A(), "192.0.2.45"); + checkRR("host0056.example.org", RRType::A(), "192.0.2.46"); + + checkRR("a.5.0.0.example.org", RRType::A(), "192.0.2.90"); + checkRR("b.5.0.0.example.org", RRType::A(), "192.0.2.91"); + checkRR("c.5.0.0.example.org", RRType::A(), "192.0.2.92"); + + checkRR("e.5.0.0.example.org", RRType::A(), "192.0.2.94"); + checkRR("f.5.0.0.example.org", RRType::A(), "192.0.2.95"); + checkRR("0.6.0.0.example.org", RRType::A(), "192.0.2.96"); + + checkRR("host106.example.org", RRType::TXT(), "Value a.6.0.0.0"); + checkRR("host107.example.org", RRType::TXT(), "Value b.6.0.0.0"); + checkRR("host109.example.org", RRType::TXT(), "Value D.6.0.0.0"); + checkRR("host110.example.org", RRType::TXT(), "Value E.6.0.0.0"); + + checkRR("host0200.example.org", RRType::A(), "192.0.2.200"); + checkRR("host0201.example.org", RRType::A(), "192.0.2.201"); +} + +TEST_F(MasterLoaderTest, generateWithNoModifiers) { + const string input = + "$ORIGIN example.org.\n" + "$TTL 3600\n" + "$GENERATE 10-12 host${} A 192.0.2.$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + ASSERT_EQ(2, errors_.size()); // For the broken GENERATE + EXPECT_TRUE(warnings_.empty()); + + checkCallbackMessage(errors_.at(0), + "Invalid $GENERATE format modifiers", 3); + checkCallbackMessage(errors_.at(1), + "$GENERATE error", 3); +} + +TEST_F(MasterLoaderTest, generateWithBadModifiers) { + const string input = + "$ORIGIN example.org.\n" + "$TTL 3600\n" + "$GENERATE 10-12 host${GARBAGE} A 192.0.2.$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + ASSERT_EQ(2, errors_.size()); // For the broken GENERATE + EXPECT_TRUE(warnings_.empty()); + + checkCallbackMessage(errors_.at(0), + "Invalid $GENERATE format modifiers", 3); + checkCallbackMessage(errors_.at(1), + "$GENERATE error", 3); +} + +TEST_F(MasterLoaderTest, generateMissingRange) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); // For the broken GENERATE + EXPECT_TRUE(warnings_.empty()); + + checkCallbackMessage(errors_.at(0), + "unexpected end of input", 2); +} + +TEST_F(MasterLoaderTest, generateMissingLHS) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 2-4\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); // For the broken GENERATE + EXPECT_TRUE(warnings_.empty()); + + checkCallbackMessage(errors_.at(0), + "unexpected end of input", 2); +} + +TEST_F(MasterLoaderTest, generateMissingType) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 2-4 host$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); // For the broken GENERATE + EXPECT_TRUE(warnings_.empty()); + + checkCallbackMessage(errors_.at(0), + "unexpected end of input", 2); +} + +TEST_F(MasterLoaderTest, generateMissingRHS) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 2-4 host$ A\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); // For the broken GENERATE + EXPECT_TRUE(warnings_.empty()); + + checkCallbackMessage(errors_.at(0), + "unexpected end of input", 2); +} + +TEST_F(MasterLoaderTest, generateWithBadRangeSyntax) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE ABCD host$ 3600 A 192.0.2.$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); // For the broken GENERATE + EXPECT_TRUE(warnings_.empty()); + + checkCallbackMessage(errors_.at(0), + "$GENERATE: invalid range: ABCD", 2); +} + +TEST_F(MasterLoaderTest, generateWithInvalidRange) { + // start > stop + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 2-1 host$ 3600 A 192.0.2.$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); // For the broken GENERATE + EXPECT_TRUE(warnings_.empty()); + + checkCallbackMessage(errors_.at(0), + "$GENERATE: invalid range: 2-1", 2); +} + +TEST_F(MasterLoaderTest, generateWithInvalidClass) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 1-2 host$ 3600 CH A 192.0.2.$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); // For the broken GENERATE + EXPECT_TRUE(warnings_.empty()); + + checkCallbackMessage(errors_.at(0), + "Class mismatch: CH vs. IN", 2); +} + +TEST_F(MasterLoaderTest, generateWithNoAvailableTTL) { + const string input = + "$ORIGIN example.org.\n" + "$GENERATE 1-2 host$ A 192.0.2.$\n"; + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); // For the broken GENERATE + EXPECT_TRUE(warnings_.empty()); + + checkCallbackMessage(errors_.at(0), + "no TTL specified; load rejected", 2); +} + +// Test the source is correctly popped even after error +TEST_F(MasterLoaderTest, popAfterError) { + const string include_str = "$include " TEST_DATA_SRCDIR + "/broken.zone\nwww 3600 IN AAAA 2001:db8::1\n"; + stringstream ss(include_str); + // We perform the test with MANY_ERRORS, we want to see what happens + // after the error. + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); // For the broken RR + EXPECT_EQ(1, warnings_.size()); // For missing EOLN + + // The included file doesn't contain anything usable, but the + // line after the include should be there. + checkRR("www.example.org", RRType::AAAA(), "2001:db8::1"); +} + +// Check it works the same when created based on a stream, not filename +TEST_F(MasterLoaderTest, streamConstructor) { + const string zone_data(prepareZone("", true)); + stringstream zone_stream(zone_data); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + EXPECT_FALSE(loader_->loadedSuccessfully()); + + // Unlike the basicLoad test, if we construct the loader from a stream + // getSize() returns the data size in the stream immediately after the + // construction. + EXPECT_EQ(zone_data.size(), loader_->getSize()); + EXPECT_EQ(0, loader_->getPosition()); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + + EXPECT_TRUE(errors_.empty()); + EXPECT_TRUE(warnings_.empty()); + checkRR("example.org", RRType::SOA(), "ns1.example.org. " + "admin.example.org. 1234 3600 1800 2419200 7200"); + checkRR("correct.example.org", RRType::A(), "192.0.2.2"); + + // On completion of the load, both getSize() and getPosition() return the + // size of the data. + EXPECT_EQ(zone_data.size(), loader_->getSize()); + EXPECT_EQ(zone_data.size(), loader_->getPosition()); +} + +// Try loading data incrementally. +TEST_F(MasterLoaderTest, incrementalLoad) { + setLoader(TEST_DATA_SRCDIR "/example.org", Name("example.org."), + RRClass::IN(), MasterLoader::MANY_ERRORS); + + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_FALSE(loader_->loadIncremental(2)); + EXPECT_FALSE(loader_->loadedSuccessfully()); + + EXPECT_TRUE(errors_.empty()); + EXPECT_TRUE(warnings_.empty()); + + checkRR("example.org", RRType::SOA(), + "ns1.example.org. admin.example.org. " + "1234 3600 1800 2419200 7200"); + checkRR("example.org", RRType::NS(), "ns1.example.org."); + + // The third one is not loaded yet + EXPECT_TRUE(rrsets_.empty()); + + // Load the rest. + EXPECT_TRUE(loader_->loadIncremental(20)); + EXPECT_TRUE(loader_->loadedSuccessfully()); + + EXPECT_TRUE(errors_.empty()); + EXPECT_TRUE(warnings_.empty()); + + checkRR("www.example.org", RRType::A(), "192.0.2.1"); + checkRR("www.example.org", RRType::AAAA(), "2001:db8::1"); +} + +// Try loading from file that doesn't exist. There should be single error +// saying so. +TEST_F(MasterLoaderTest, invalidFile) { + setLoader("This file doesn't exist at all", + Name("example.org."), RRClass::IN(), MasterLoader::MANY_ERRORS); + + // Nothing yet. The loader is dormant until invoked. + // Is it really what we want? + EXPECT_TRUE(errors_.empty()); + + loader_->load(); + + EXPECT_TRUE(warnings_.empty()); + EXPECT_TRUE(rrsets_.empty()); + ASSERT_EQ(1, errors_.size()); + EXPECT_EQ(0, errors_[0].find("Error opening the input source file: ")) << + "Different error: " << errors_[0]; +} + +struct ErrorCase { + const char* const line; // The broken line in master file + const char* const reason; // If non NULL, the reason string + const char* const problem; // Description of the problem for SCOPED_TRACE +} const error_cases[] = { + { "www... 3600 IN A 192.0.2.1", NULL, "Invalid name" }, + { "www FORTNIGHT IN A 192.0.2.1", NULL, "Invalid TTL" }, + { "www 3600 XX A 192.0.2.1", NULL, "Invalid class" }, + { "www 3600 IN A bad_ip", NULL, "Invalid Rdata" }, + + // Parameter ordering errors + { "www IN A 3600 192.168.2.7", + "createRdata from text failed: Bad IN/A RDATA text: '3600'", + "Incorrect order of class, TTL and type" }, + { "www A IN 3600 192.168.2.8", + "createRdata from text failed: Bad IN/A RDATA text: 'IN'", + "Incorrect order of class, TTL and type" }, + { "www 3600 A IN 192.168.2.7", + "createRdata from text failed: Bad IN/A RDATA text: 'IN'", + "Incorrect order of class, TTL and type" }, + { "www A 3600 IN 192.168.2.8", + "createRdata from text failed: Bad IN/A RDATA text: '3600'", + "Incorrect order of class, TTL and type" }, + + // Missing type and Rdata + { "www", "unexpected end of input", "Missing type and Rdata" }, + { "www 3600", "unexpected end of input", "Missing type and Rdata" }, + { "www IN", "unexpected end of input", "Missing type and Rdata" }, + { "www 3600 IN", "unexpected end of input", "Missing type and Rdata" }, + { "www IN 3600", "unexpected end of input", "Missing type and Rdata" }, + + // Missing Rdata + { "www A", + "createRdata from text failed: unexpected end of input", + "Missing Rdata" }, + { "www 3600 A", + "createRdata from text failed: unexpected end of input", + "Missing Rdata" }, + { "www IN A", + "createRdata from text failed: unexpected end of input", + "Missing Rdata" }, + { "www 3600 IN A", + "createRdata from text failed: unexpected end of input", + "Missing Rdata" }, + { "www IN 3600 A", + "createRdata from text failed: unexpected end of input", + "Missing Rdata" }, + + { "www 3600 IN", NULL, "Unexpected EOLN" }, + { "www 3600 CH TXT nothing", "Class mismatch: CH vs. IN", + "Class mismatch" }, + { "www \"3600\" IN A 192.0.2.1", NULL, "Quoted TTL" }, + { "www 3600 \"IN\" A 192.0.2.1", NULL, "Quoted class" }, + { "www 3600 IN \"A\" 192.0.2.1", NULL, "Quoted type" }, + { "unbalanced)paren 3600 IN A 192.0.2.1", NULL, "Token error 1" }, + { "www 3600 unbalanced)paren A 192.0.2.1", NULL, + "Token error 2" }, + // Check the unknown directive. The rest looks like ordinary RR, + // so we see the $ is actually special. + { "$UNKNOWN 3600 IN A 192.0.2.1", NULL, "Unknown $ directive" }, + { "$INCLUD " TEST_DATA_SRCDIR "/example.org", "Unknown directive 'INCLUD'", + "Include too short" }, + { "$INCLUDES " TEST_DATA_SRCDIR "/example.org", + "Unknown directive 'INCLUDES'", "Include too long" }, + { "$INCLUDE", "unexpected end of input", "Missing include path" }, + // The following two error messages are system dependent, omitting + { "$INCLUDE /file/not/found", NULL, "Include file not found" }, + { "$INCLUDE /file/not/found example.org. and here goes bunch of garbage", + NULL, "Include file not found and garbage at the end of line" }, + { "$ORIGIN", "unexpected end of input", "Missing origin name" }, + { "$ORIGIN invalid...name", "duplicate period in invalid...name", + "Invalid name for origin" }, + { "$ORIGIN )brokentoken", "unbalanced parentheses", + "Broken token in origin" }, + { "$ORIGIN example.org. garbage", "Extra tokens at the end of line", + "Garbage after origin" }, + { "$ORIGI name.", "Unknown directive 'ORIGI'", "$ORIGIN too short" }, + { "$ORIGINAL name.", "Unknown directive 'ORIGINAL'", "$ORIGIN too long" }, + { "$TTL 100 extra-garbage", "Extra tokens at the end of line", + "$TTL with extra token" }, + { "$TTL", "unexpected end of input", "missing TTL" }, + { "$TTL No-ttl", "Unknown unit used: N in: No-ttl", "bad TTL" }, + { "$TTL \"100\"", "unexpected quotes", "bad TTL, quoted" }, + { "$TT 100", "Unknown directive 'TT'", "bad directive, too short" }, + { "$TTLLIKE 100", "Unknown directive 'TTLLIKE'", "bad directive, extra" }, + { NULL, NULL, NULL } +}; + +// Test a broken zone is handled properly. We test several problems, +// both in strict and lenient mode. +TEST_F(MasterLoaderTest, brokenZone) { + for (const ErrorCase* ec = error_cases; ec->line != NULL; ++ec) { + SCOPED_TRACE(ec->problem); + const string zone(prepareZone(ec->line, true)); + + { + SCOPED_TRACE("Strict mode"); + clear(); + stringstream zone_stream(zone); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::DEFAULT); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_THROW(loader_->load(), MasterLoaderError); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); + if (ec->reason != NULL) { + checkCallbackMessage(errors_.at(0), ec->reason, 2); + } + EXPECT_TRUE(warnings_.empty()); + + checkRR("example.org", RRType::SOA(), "ns1.example.org. " + "admin.example.org. 1234 3600 1800 2419200 7200"); + // In the strict mode, it is aborted. The last RR is not + // even attempted. + EXPECT_TRUE(rrsets_.empty()); + } + + { + SCOPED_TRACE("Lenient mode"); + clear(); + stringstream zone_stream(zone); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_NO_THROW(loader_->load()); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); + EXPECT_TRUE(warnings_.empty()); + checkRR("example.org", RRType::SOA(), "ns1.example.org. " + "admin.example.org. 1234 3600 1800 2419200 7200"); + // This one is below the error one. + checkRR("correct.example.org", RRType::A(), "192.0.2.2"); + EXPECT_TRUE(rrsets_.empty()); + } + + { + SCOPED_TRACE("Error at EOF"); + // This case is interesting only in the lenient mode. + clear(); + const string zoneEOF(prepareZone(ec->line, false)); + stringstream zone_stream(zoneEOF); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_NO_THROW(loader_->load()); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()) << errors_[0] << "\n" << errors_[1]; + // The unexpected EOF warning + EXPECT_EQ(1, warnings_.size()); + checkRR("example.org", RRType::SOA(), "ns1.example.org. " + "admin.example.org. 1234 3600 1800 2419200 7200"); + EXPECT_TRUE(rrsets_.empty()); + } + } +} + +// Check that a garbage after the include generates an error, but not fatal +// one (in lenient mode) and we can recover. +TEST_F(MasterLoaderTest, includeWithGarbage) { + // Include an origin (example.org) because we expect it to be handled + // soon and we don't want it to break here. + const string include_str("$INCLUDE " TEST_DATA_SRCDIR + "/example.org example.org. bunch of other stuff\n" + "www 3600 IN AAAA 2001:db8::1\n"); + stringstream zone_stream(include_str); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + EXPECT_NO_THROW(loader_->load()); + EXPECT_FALSE(loader_->loadedSuccessfully()); + ASSERT_EQ(1, errors_.size()); + checkCallbackMessage(errors_.at(0), "Extra tokens at the end of line", 1); + // It says something about extra tokens at the end + EXPECT_NE(string::npos, errors_[0].find("Extra")); + EXPECT_TRUE(warnings_.empty()); + checkBasicRRs(); + checkRR("www.example.org", RRType::AAAA(), "2001:db8::1"); +} + +// Check we error about garbage at the end of $ORIGIN line (but the line +// works). +TEST_F(MasterLoaderTest, originWithGarbage) { + const string origin_str = "$ORIGIN www.example.org. More garbage here\n" + "@ 1H IN A 192.0.2.1\n"; + stringstream ss(origin_str); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + EXPECT_NO_THROW(loader_->load()); + EXPECT_FALSE(loader_->loadedSuccessfully()); + ASSERT_EQ(1, errors_.size()); + checkCallbackMessage(errors_.at(0), "Extra tokens at the end of line", 1); + EXPECT_TRUE(warnings_.empty()); + checkARR("www.example.org"); +} + +// Test we can pass both file to include and the origin to switch +TEST_F(MasterLoaderTest, includeAndOrigin) { + // First, switch origin to something else, so we can check it is + // switched back. + const string include_string = "$ORIGIN www.example.org.\n" + "@ 1H IN A 192.0.2.1\n" + // Then include the file with data and switch origin back + "$INCLUDE " TEST_DATA_SRCDIR "/example.org example.org.\n" + // Another RR to see we fall back to the previous origin. + "www 1H IN A 192.0.2.1\n"; + stringstream ss(include_string); + setLoader(ss, Name("example.org"), RRClass::IN(), + MasterLoader::MANY_ERRORS); + // Successfully load the data + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + EXPECT_TRUE(warnings_.empty()); + // And check it's the correct data + checkARR("www.example.org"); + checkBasicRRs(); + checkARR("www.www.example.org"); +} + +// Like above, but the origin after include is bogus. The whole line should +// be rejected. +TEST_F(MasterLoaderTest, includeAndBadOrigin) { + const string include_string = + "$INCLUDE " TEST_DATA_SRCDIR "/example.org example..org.\n" + // Another RR to see the switch survives after we exit include + "www 1H IN A 192.0.2.1\n"; + stringstream ss(include_string); + setLoader(ss, Name("example.org"), RRClass::IN(), + MasterLoader::MANY_ERRORS); + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); + checkCallbackMessage(errors_.at(0), "duplicate period in example..org.", + 1); + EXPECT_TRUE(warnings_.empty()); + // And check it's the correct data + checkARR("www.example.org"); +} + +// Check the origin doesn't get outside of the included file. +TEST_F(MasterLoaderTest, includeOriginRestore) { + const string include_string = + "$INCLUDE " TEST_DATA_SRCDIR "/origincheck.txt\n" + "@ 1H IN A 192.0.2.1\n"; + stringstream ss(include_string); + setLoader(ss, Name("example.org"), RRClass::IN(), + MasterLoader::MANY_ERRORS); + // Successfully load the data + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + EXPECT_TRUE(warnings_.empty()); + // And check it's the correct data + checkARR("www.example.org"); + checkARR("example.org"); +} + +// Check we restore the last name for initial whitespace when returning from +// include. But we do produce a warning if there's one just ofter the include. +TEST_F(MasterLoaderTest, includeAndInitialWS) { + const string include_string = "xyz 1H IN A 192.0.2.1\n" + "$INCLUDE " TEST_DATA_SRCDIR "/example.org\n" + " 1H IN A 192.0.2.1\n"; + stringstream ss(include_string); + setLoader(ss, Name("example.org"), RRClass::IN(), + MasterLoader::MANY_ERRORS); + // Successfully load the data + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + EXPECT_EQ(1, warnings_.size()); + checkCallbackMessage(warnings_.at(0), + "Owner name omitted around $INCLUDE, the result might " + "not be as expected", 3); + checkARR("xyz.example.org"); + checkBasicRRs(); + checkARR("xyz.example.org"); +} + +// Test for "$TTL" +TEST_F(MasterLoaderTest, ttlDirective) { + stringstream zone_stream; + + // Set the default TTL with $TTL followed by an RR omitting the TTL + zone_stream << "$TTL 1800\nexample.org. IN A 192.0.2.1\n"; + // $TTL can be quoted. Also testing the case of $TTL being changed. + zone_stream << "\"$TTL\" 100\na.example.org. IN A 192.0.2.2\n"; + // Extended TTL form is accepted. + zone_stream << "$TTL 1H\nb.example.org. IN A 192.0.2.3\n"; + // Matching is case insensitive. + zone_stream << "$tTl 360\nc.example.org. IN A 192.0.2.4\n"; + // Maximum allowable TTL + zone_stream << "$TTL 2147483647\nd.example.org. IN A 192.0.2.5\n"; + + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::DEFAULT); + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + checkRR("example.org", RRType::A(), "192.0.2.1", RRTTL(1800)); + checkRR("a.example.org", RRType::A(), "192.0.2.2", RRTTL(100)); + checkRR("b.example.org", RRType::A(), "192.0.2.3", RRTTL(3600)); + checkRR("c.example.org", RRType::A(), "192.0.2.4", RRTTL(360)); + checkRR("d.example.org", RRType::A(), "192.0.2.5", RRTTL(2147483647)); +} + +TEST_F(MasterLoaderTest, ttlFromSOA) { + // No $TTL, and the SOA doesn't have an explicit TTL field. Its minimum + // TTL field will be used as the RR's TTL, and it'll be used as the + // default TTL for others. + stringstream zone_stream("example.org. IN SOA . . 0 0 0 0 1800\n" + "a.example.org. IN A 192.0.2.1\n"); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::DEFAULT); + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + checkRR("example.org", RRType::SOA(), ". . 0 0 0 0 1800", RRTTL(1800)); + checkRR("a.example.org", RRType::A(), "192.0.2.1", RRTTL(1800)); + + // The use of SOA minimum TTL should have caused a warning. + EXPECT_EQ(1, warnings_.size()); + checkCallbackMessage(warnings_.at(0), + "no TTL specified; using SOA MINTTL instead", 1); +} + +TEST_F(MasterLoaderTest, ttlFromPrevious) { + // No available default TTL. 2nd and 3rd RR will use the TTL of the + // 1st RR. This will result in a warning, but only for the first time. + stringstream zone_stream("a.example.org. 1800 IN A 192.0.2.1\n" + "b.example.org. IN A 192.0.2.2\n" + "c.example.org. IN A 192.0.2.3\n"); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::DEFAULT); + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + checkRR("a.example.org", RRType::A(), "192.0.2.1", RRTTL(1800)); + checkRR("b.example.org", RRType::A(), "192.0.2.2", RRTTL(1800)); + checkRR("c.example.org", RRType::A(), "192.0.2.3", RRTTL(1800)); + + EXPECT_EQ(1, warnings_.size()); + checkCallbackMessage(warnings_.at(0), "using RFC1035 TTL semantics", 2); +} + +TEST_F(MasterLoaderTest, RRParamsOrdering) { + // We test the order and existence of TTL, class and type. See + // MasterLoader::MasterLoaderImpl::parseRRParams() for ordering. + + stringstream zone_stream; + // <TTL> <class> <type> <RDATA> + zone_stream << "a.example.org. 1800 IN A 192.0.2.1\n"; + // <type> <RDATA> + zone_stream << "b.example.org. A 192.0.2.2\n"; + // <class> <TTL> <type> <RDATA> + zone_stream << "c.example.org. IN 3600 A 192.0.2.3\n"; + // <TTL> <type> <RDATA> + zone_stream << "d.example.org. 7200 A 192.0.2.4\n"; + // <class> <type> <RDATA> + zone_stream << "e.example.org. IN A 192.0.2.5\n"; + + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::DEFAULT); + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + checkRR("a.example.org", RRType::A(), "192.0.2.1", RRTTL(1800)); + checkRR("b.example.org", RRType::A(), "192.0.2.2", RRTTL(1800)); + checkRR("c.example.org", RRType::A(), "192.0.2.3", RRTTL(3600)); + checkRR("d.example.org", RRType::A(), "192.0.2.4", RRTTL(7200)); + checkRR("e.example.org", RRType::A(), "192.0.2.5", RRTTL(7200)); + + EXPECT_EQ(1, warnings_.size()); + checkCallbackMessage(warnings_.at(0), "using RFC1035 TTL semantics", 2); +} + +TEST_F(MasterLoaderTest, ttlFromPreviousSOA) { + // Mixture of the previous two cases: SOA has explicit TTL, followed by + // an RR without an explicit TTL. In this case the minimum TTL won't be + // recognized as the "default TTL". + stringstream zone_stream("example.org. 100 IN SOA . . 0 0 0 0 1800\n" + "a.example.org. IN A 192.0.2.1\n"); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::DEFAULT); + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + + checkRR("example.org", RRType::SOA(), ". . 0 0 0 0 1800", RRTTL(100)); + checkRR("a.example.org", RRType::A(), "192.0.2.1", RRTTL(100)); + + EXPECT_EQ(1, warnings_.size()); + checkCallbackMessage(warnings_.at(0), "using RFC1035 TTL semantics", 2); +} + +TEST_F(MasterLoaderTest, ttlUnknown) { + // No available TTL is known for the first RR. + stringstream zone_stream("a.example.org. IN A 192.0.2.1\n"); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::DEFAULT); + EXPECT_THROW(loader_->load(), MasterLoaderError); +} + +TEST_F(MasterLoaderTest, ttlUnknownAndContinue) { + stringstream zone_stream("a.example.org. IN A 192.0.2.1\n" + "b.example.org. 1800 IN A 192.0.2.2\n"); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + checkRR("b.example.org", RRType::A(), "192.0.2.2", RRTTL(1800)); + + EXPECT_TRUE(warnings_.empty()); + EXPECT_EQ(1, errors_.size()); + checkCallbackMessage(errors_.at(0), "no TTL specified; load rejected", 1); +} + +TEST_F(MasterLoaderTest, ttlUnknownAndEOF) { + // Similar to the previous case, but the input will be abruptly terminated + // after the offending RR. This will cause an additional warning. + stringstream zone_stream("a.example.org. IN A 192.0.2.1"); + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_TRUE(rrsets_.empty()); + + EXPECT_EQ(1, errors_.size()); + checkCallbackMessage(errors_.at(0), "no TTL specified; load rejected", 1); + + // RDATA implementation can complain about it, too. To be independent of + // its details, we focus on the very last warning. + EXPECT_FALSE(warnings_.empty()); + checkCallbackMessage(*warnings_.rbegin(), "File does not end with newline", + 1); +} + +TEST_F(MasterLoaderTest, ttlOverflow) { + stringstream zone_stream; + zone_stream << "example.org. IN SOA . . 0 0 0 0 2147483648\n"; + zone_stream << "$TTL 3600\n"; // reset to an in-range value + zone_stream << "$TTL 2147483649\n"; + zone_stream << "a.example.org. IN A 192.0.2.1\n"; + zone_stream << "$TTL 3600\n"; // reset to an in-range value + zone_stream << "b.example.org. 2147483650 IN A 192.0.2.2\n"; + setLoader(zone_stream, Name("example.org."), RRClass::IN(), + MasterLoader::DEFAULT); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_EQ(3, rrsets_.size()); + + checkRR("example.org", RRType::SOA(), ". . 0 0 0 0 2147483648", RRTTL(0)); + checkRR("a.example.org", RRType::A(), "192.0.2.1", RRTTL(0)); + checkRR("b.example.org", RRType::A(), "192.0.2.2", RRTTL(0)); + + EXPECT_EQ(4, warnings_.size()); + checkCallbackMessage(warnings_.at(1), + "TTL 2147483648 > MAXTTL, setting to 0 per RFC2181", + 1); + checkCallbackMessage(warnings_.at(2), + "TTL 2147483649 > MAXTTL, setting to 0 per RFC2181", + 3); + checkCallbackMessage(warnings_.at(3), + "TTL 2147483650 > MAXTTL, setting to 0 per RFC2181", + 6); +} + +// Test the constructor rejects empty add callback. +TEST_F(MasterLoaderTest, emptyCallback) { + EXPECT_THROW(MasterLoader(TEST_DATA_SRCDIR "/example.org", + Name("example.org"), RRClass::IN(), callbacks_, + AddRRCallback()), isc::InvalidParameter); + // And the same with the second constructor + stringstream ss(""); + EXPECT_THROW(MasterLoader(ss, Name("example.org"), RRClass::IN(), + callbacks_, AddRRCallback()), + isc::InvalidParameter); +} + +// Check it throws when we try to load after loading was complete. +TEST_F(MasterLoaderTest, loadTwice) { + setLoader(TEST_DATA_SRCDIR "/example.org", Name("example.org."), + RRClass::IN(), MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_THROW(loader_->load(), isc::InvalidOperation); + // Don't check them, they are not interesting, so suppress the error + // at TearDown + rrsets_.clear(); +} + +// Load 0 items should be rejected +TEST_F(MasterLoaderTest, loadZero) { + setLoader(TEST_DATA_SRCDIR "/example.org", Name("example.org."), + RRClass::IN(), MasterLoader::MANY_ERRORS); + EXPECT_THROW(loader_->loadIncremental(0), isc::InvalidParameter); +} + +// Test there's a warning when the file terminates without end of +// line. +TEST_F(MasterLoaderTest, noEOLN) { + // No \n at the end + const string input("example.org. 3600 IN SOA ns1.example.org. " + "admin.example.org. 1234 3600 1800 2419200 7200"); + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + // There should be one warning about the EOLN + EXPECT_EQ(1, warnings_.size()); + checkRR("example.org", RRType::SOA(), "ns1.example.org. " + "admin.example.org. 1234 3600 1800 2419200 7200"); +} + +// Test it rejects when we don't have the previous name to use in place of +// initial whitespace +TEST_F(MasterLoaderTest, noPreviousName) { + const string input(" 1H IN A 192.0.2.1\n"); + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + loader_->load(); + EXPECT_FALSE(loader_->loadedSuccessfully()); + EXPECT_EQ(1, errors_.size()); + checkCallbackMessage(errors_.at(0), "No previous name to use in place of " + "initial whitespace", 1); + EXPECT_TRUE(warnings_.empty()); +} + +// Check we warn if the first RR in an included file has omitted name +TEST_F(MasterLoaderTest, previousInInclude) { + const string input("www 1H IN A 192.0.2.1\n" + "$INCLUDE " TEST_DATA_SRCDIR "/omitcheck.txt\n"); + stringstream ss(input); + setLoader(ss, Name("example.org"), RRClass::IN(), + MasterLoader::MANY_ERRORS); + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + // There should be one warning about the EOLN + EXPECT_EQ(1, warnings_.size()); + checkCallbackMessage(warnings_.at(0), "Owner name omitted around " + "$INCLUDE, the result might not be as expected", 1); + checkARR("www.example.org"); + checkARR("www.example.org"); +} + +TEST_F(MasterLoaderTest, numericOwnerName) { + const string input("$ORIGIN example.org.\n" + "1 3600 IN A 192.0.2.1\n"); + stringstream ss(input); + setLoader(ss, Name("example.org."), RRClass::IN(), + MasterLoader::MANY_ERRORS); + + loader_->load(); + EXPECT_TRUE(loader_->loadedSuccessfully()); + EXPECT_TRUE(errors_.empty()); + EXPECT_TRUE(warnings_.empty()); + + checkRR("1.example.org", RRType::A(), "192.0.2.1"); +} + +} diff --git a/src/lib/dns/tests/masterload_unittest.cc b/src/lib/dns/tests/masterload_unittest.cc new file mode 100644 index 0000000..e412de0 --- /dev/null +++ b/src/lib/dns/tests/masterload_unittest.cc @@ -0,0 +1,397 @@ +// Copyright (C) 2010-2022 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <functional> +#include <ios> +#include <fstream> +#include <sstream> +#include <string> +#include <vector> + +#include <gtest/gtest.h> + +#include <dns/masterload.h> +#include <dns/name.h> +#include <dns/rdata.h> +#include <dns/rrclass.h> +#include <dns/rrset.h> + +using namespace std; +using namespace isc::dns; +namespace ph = std::placeholders; + +namespace { +// A callback functor for masterLoad() commonly used for the following tests. +class TestCallback { +public: + TestCallback(vector<ConstRRsetPtr>& rrsets) : rrsets_(rrsets) {} + void operator()(ConstRRsetPtr rrset) { + rrsets_.push_back(rrset); + } +private: + vector<ConstRRsetPtr>& rrsets_; +}; + +// A function version of TestCallback. +void +testCallback(ConstRRsetPtr rrset, vector<ConstRRsetPtr>* rrsets) { + rrsets->push_back(rrset); +} + +class MasterLoadTest : public ::testing::Test { +protected: + MasterLoadTest() : origin("example.com"), zclass(RRClass::IN()), + callback(results) {} +public: + void rrsetCallback(ConstRRsetPtr rrset) { + results.push_back(rrset); + } +protected: + Name origin; + RRClass zclass; + stringstream rr_stream; + vector<ConstRRsetPtr> results; + TestCallback callback; +}; + +// Commonly used test RRs +const char* const txt_rr = "example.com. 3600 IN TXT \"test data\"\n"; +const char* const a_rr1 = "www.example.com. 60 IN A 192.0.2.1\n"; +const char* const a_rr2 = "www.example.com. 60 IN A 192.0.2.2\n"; +const char* const a_rr3 = "ftp.example.com. 60 IN A 192.0.2.3\n"; +// multi-field RR case +const char* const soa_rr = "example.com. 7200 IN SOA . . 0 0 0 0 0\n"; +// A couple of RRSIGs, different type covered +const char* const rrsig_rr1 = + "www.example.com. 60 IN RRSIG A 5 3 3600 20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE\n"; +const char* const rrsig_rr2 = + "www.example.com. 60 IN RRSIG AAAA 5 3 3600 20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE\n"; + +// Commonly used for some tests to check the constructed RR content. +const char* const dnskey_rdata = + "256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH " + "zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE=\n"; + +TEST_F(MasterLoadTest, loadRRs) { + // a simple case: loading 3 RRs, each consists of a single RRset. + rr_stream << txt_rr << a_rr1 << soa_rr; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(3, results.size()); + EXPECT_EQ(txt_rr, results[0]->toText()); + EXPECT_EQ(a_rr1, results[1]->toText()); + EXPECT_EQ(soa_rr, results[2]->toText()); +} + +TEST_F(MasterLoadTest, loadWithFunctionCallback) { + // The same test as loadRRs but using a normal function (not a functor + // object) + rr_stream << txt_rr << a_rr1 << soa_rr; + masterLoad(rr_stream, origin, zclass, + std::bind(&testCallback, ph::_1, &results)); + ASSERT_EQ(3, results.size()); + EXPECT_EQ(txt_rr, results[0]->toText()); + EXPECT_EQ(a_rr1, results[1]->toText()); + EXPECT_EQ(soa_rr, results[2]->toText()); +} + +TEST_F(MasterLoadTest, loadWithMemFunctionCallback) { + // The same test as loadRRs but using a class member function (with a + // help of std.bind) + rr_stream << txt_rr << a_rr1 << soa_rr; + masterLoad(rr_stream, origin, zclass, + std::bind(&MasterLoadTest::rrsetCallback, this, ph::_1)); + ASSERT_EQ(3, results.size()); + EXPECT_EQ(txt_rr, results[0]->toText()); + EXPECT_EQ(a_rr1, results[1]->toText()); + EXPECT_EQ(soa_rr, results[2]->toText()); +} + +TEST_F(MasterLoadTest, loadComments) { + rr_stream << ";; comment line, should be skipped\n" + << "\n" // blank line (should be skipped) + << txt_rr; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(1, results.size()); + EXPECT_EQ(txt_rr, results[0]->toText()); +} + +TEST_F(MasterLoadTest, loadRRset) { + // load an RRset containing two RRs + rr_stream << a_rr1 << a_rr2; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(1, results.size()); + EXPECT_EQ(string(a_rr1) + string(a_rr2), results[0]->toText()); +} + +TEST_F(MasterLoadTest, loadRRsetsOfSameType) { + // load two RRsets with the same RR type and different owner names. + // the loader must distinguish them as separate RRsets. + rr_stream << a_rr1 << a_rr3; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(2, results.size()); + EXPECT_EQ(a_rr1, results[0]->toText()); + EXPECT_EQ(a_rr3, results[1]->toText()); +} + +TEST_F(MasterLoadTest, loadRRsetsInterleaved) { + // two RRs that belongs to the same RRset (rr1 and rr2) are interleaved + // by another. This is an unexpected case for this loader, but it's + // not considered an error. The loader will simply treat them separate + // RRsets. + rr_stream << a_rr1 << a_rr3 << a_rr2; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(3, results.size()); + EXPECT_EQ(a_rr1, results[0]->toText()); + EXPECT_EQ(a_rr3, results[1]->toText()); + EXPECT_EQ(a_rr2, results[2]->toText()); +} + +TEST_F(MasterLoadTest, loadRRsigs) { + // RRSIGs of different types covered should be separated + rr_stream << rrsig_rr1 << rrsig_rr2; + masterLoad(rr_stream, origin, zclass, callback); + EXPECT_EQ(2, results.size()); +} + +// This test was disabled by #2387, because the test data has trailing +// comments and it (eventually) uses the string RDATA constructor which +// doesn't support them. This test should be fixed and re-enabled by +// #2381, or deleted. +TEST_F(MasterLoadTest, DISABLED_loadRRWithComment) { + // Comment at the end of line should be ignored and the RR should be + // accepted. + rr_stream << "example.com. 3600 IN DNSKEY\t256 3 7 " + "AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH " + "zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE= ; key id = 40430\n"; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(1, results.size()); + EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare( + *rdata::createRdata(RRType::DNSKEY(), zclass, + dnskey_rdata))); +} + +// This test was disabled by #2387, because the test data has trailing +// comments and it (eventually) uses the string RDATA constructor which +// doesn't support them. This test should be fixed and re-enabled by +// #2381, or deleted. +TEST_F(MasterLoadTest, DISABLED_loadRRWithCommentNoSpace) { + // Similar to the previous one, but there's no space before comments. + // It should still work. + rr_stream << "example.com. 3600 IN DNSKEY\t256 3 7 " + "AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH " + "zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE=; key id = 40430\n"; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(1, results.size()); + EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare( + *rdata::createRdata(RRType::DNSKEY(), zclass, + dnskey_rdata))); +} + +// This test was disabled by #2387, because the test data has trailing +// comments and it (eventually) uses the string RDATA constructor which +// doesn't support them. This test should be fixed and re-enabled by +// #2381, or deleted. +TEST_F(MasterLoadTest, DISABLED_loadRRWithCommentEmptyComment) { + // Similar to the previous one, but there's no data after the ; + // It should still work. + rr_stream << "example.com. 3600 IN DNSKEY\t256 3 7 " + "AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH " + "zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE= ;\n"; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(1, results.size()); + EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare( + *rdata::createRdata(RRType::DNSKEY(), zclass, + dnskey_rdata))); +} + +// This test was disabled by #2387, because the test data has trailing +// comments and it (eventually) uses the string RDATA constructor which +// doesn't support them. This test should be fixed and re-enabled by +// #2381, or deleted. +TEST_F(MasterLoadTest, DISABLED_loadRRWithCommentEmptyCommentNoSpace) { + // Similar to the previous one, but there's no space before or after ; + // It should still work. + rr_stream << "example.com. 3600 IN DNSKEY\t256 3 7 " + "AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LUsAD0QPWU+wzt89epO6tH " + "zkMBVDkC7qphQO2hTY4hHn9npWFRw5BYubE=;\n"; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(1, results.size()); + EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare( + *rdata::createRdata(RRType::DNSKEY(), zclass, + dnskey_rdata))); +} + +TEST_F(MasterLoadTest, loadRRWithEOLWhitespace) { + // Test with whitespace after rdata + // It should still work. + rr_stream << "example.com. 3600 IN NSEC3PARAM 1 0 1 beef \n"; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(1, results.size()); + EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare( + *rdata::createRdata(RRType::NSEC3PARAM(), zclass, + "1 0 1 beef"))); +} + +TEST_F(MasterLoadTest, loadRRWithEOLWhitespaceTab) { + // Similar to the previous one, tab instead of space. + // It should still work. + rr_stream << "example.com. 3600 IN NSEC3PARAM 1 0 1 beef\t\n"; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(1, results.size()); + EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare( + *rdata::createRdata(RRType::NSEC3PARAM(), zclass, + "1 0 1 beef"))); +} + +TEST_F(MasterLoadTest, loadRRNoComment) { + // A semicolon in a character-string shouldn't confuse the parser. + rr_stream << "example.com. 3600 IN TXT \"aaa;bbb\"\n"; + masterLoad(rr_stream, origin, zclass, callback); + EXPECT_EQ(1, results.size()); + EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare( + *rdata::createRdata(RRType::TXT(), zclass, + "\"aaa;bbb\""))); +} + +TEST_F(MasterLoadTest, nonAbsoluteOwner) { + // If the owner name is not absolute, the zone origin is assumed to be + // its origin. + rr_stream << "example.com 3600 IN A 192.0.2.1"; + masterLoad(rr_stream, origin, zclass, callback); + EXPECT_EQ(1, results.size()); + EXPECT_EQ(results[0]->getName(), Name("example.com.example.com")); +} + +TEST_F(MasterLoadTest, loadRREmptyAndComment) { + // There's no RDATA (invalid in this case) but a comment. This position + // shouldn't cause any disruption and should be treated as a normal error. + rr_stream << "example.com. 3600 IN A ;\n"; + EXPECT_THROW(masterLoad(rr_stream, origin, zclass, callback), + MasterLoadError); +} + +TEST_F(MasterLoadTest, loadWithNoEOF) { + // the input stream doesn't end with a new line (and the following blank + // line). It should be accepted. + string rr_string(a_rr1); + rr_string.erase(rr_string.end() - 1); + rr_stream << rr_string; + masterLoad(rr_stream, origin, zclass, callback); + ASSERT_EQ(1, results.size()); + EXPECT_EQ(a_rr1, results[0]->toText()); +} + +TEST_F(MasterLoadTest, loadEmpty) { + // an unusual case: empty input. load must succeed with an empty result. + masterLoad(rr_stream, origin, zclass, callback); + EXPECT_EQ(0, results.size()); +} + +TEST_F(MasterLoadTest, loadWithBeginningSpace) { + rr_stream << " " << a_rr1; + EXPECT_THROW(masterLoad(rr_stream, origin, zclass, callback), + MasterLoadError); +} + +TEST_F(MasterLoadTest, loadWithBeginningTab) { + rr_stream << "\t" << a_rr1; + EXPECT_THROW(masterLoad(rr_stream, origin, zclass, callback), + MasterLoadError); +} + +TEST_F(MasterLoadTest, loadInvalidRRClass) { + rr_stream << "example.com. 3600 CH TXT \"test text\""; + EXPECT_THROW(masterLoad(rr_stream, origin, zclass, callback), + MasterLoadError); +} + +TEST_F(MasterLoadTest, loadOutOfZoneData) { + rr_stream << "example.org. 3600 IN A 192.0.2.255"; + EXPECT_THROW(masterLoad(rr_stream, origin, zclass, callback), + MasterLoadError); +} + +TEST_F(MasterLoadTest, loadNonAtopSOA) { + // SOA's owner name must be zone's origin. + rr_stream << "soa.example.com. 3600 IN SOA . . 0 0 0 0 0"; + EXPECT_THROW(masterLoad(rr_stream, origin, zclass, callback), + MasterLoadError); +} + +// Load TTL with units +TEST_F(MasterLoadTest, loadUnitTTL) { + stringstream rr_stream2("example.com. 1D IN A 192.0.2.1"); + masterLoad(rr_stream2, origin, zclass, callback); + EXPECT_EQ(1, results.size()); + EXPECT_EQ(0, results[0]->getRdataIterator()->getCurrent().compare( + *rdata::createRdata(RRType::A(), zclass, "192.0.2.1"))); +} + +TEST_F(MasterLoadTest, loadBadRRText) { + rr_stream << "example..com. 3600 IN A 192.0.2.1"; // bad owner name + EXPECT_THROW(masterLoad(rr_stream, origin, zclass, callback), + MasterLoadError); + + // bad RR class text + stringstream rr_stream3("example.com. 3600 BAD A 192.0.2.1"); + EXPECT_THROW(masterLoad(rr_stream3, origin, zclass, callback), + MasterLoadError); + + // bad RR type text + stringstream rr_stream4("example.com. 3600 IN BAD 192.0.2.1"); + EXPECT_THROW(masterLoad(rr_stream4, origin, zclass, callback), + MasterLoadError); + + // bad RDATA text + stringstream rr_stream5("example.com. 3600 IN A 2001:db8::1"); + EXPECT_THROW(masterLoad(rr_stream5, origin, zclass, callback), + MasterLoadError); + + // incomplete RR text + stringstream rr_stream6("example.com. 3600 IN A"); + EXPECT_THROW(masterLoad(rr_stream6, origin, zclass, callback), + MasterLoadError); +} + +// This is a helper callback to test the case the input stream becomes bad +// in the middle of processing. +class StreamInvalidator { +public: + StreamInvalidator(stringstream& ss) : ss_(ss) {} + void operator()(ConstRRsetPtr) { + ss_.setstate(ios::badbit); + } +private: + stringstream& ss_; +}; + +TEST_F(MasterLoadTest, loadBadStream) { + rr_stream << txt_rr << a_rr1; + StreamInvalidator invalidator(rr_stream); + EXPECT_THROW(masterLoad(rr_stream, origin, zclass, invalidator), + MasterLoadError); +} + +TEST_F(MasterLoadTest, loadFromFile) { + // The main parser is shared with the stream version, so we simply test + // file I/O specific parts. + masterLoad(TEST_DATA_SRCDIR "/masterload.txt", origin, zclass, callback); + ASSERT_EQ(2, results.size()); + EXPECT_EQ(txt_rr, results[0]->toText()); + EXPECT_EQ(string(a_rr1) + string(a_rr2), results[1]->toText()); + + // NULL file name. Should result in exception. + EXPECT_THROW(masterLoad(NULL, origin, zclass, callback), MasterLoadError); + + // Non existent file name. Ditto. + EXPECT_THROW(masterLoad(TEST_DATA_BUILDDIR "/nonexistent.txt", origin, + zclass, callback), MasterLoadError); +} +} // end namespace diff --git a/src/lib/dns/tests/message_unittest.cc b/src/lib/dns/tests/message_unittest.cc new file mode 100644 index 0000000..8b6832b --- /dev/null +++ b/src/lib/dns/tests/message_unittest.cc @@ -0,0 +1,1162 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <fstream> + +#include <boost/scoped_ptr.hpp> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <util/time_utilities.h> + +#include <util/unittests/testdata.h> +#include <util/unittests/textdata.h> + +#include <dns/edns.h> +#include <dns/exceptions.h> +#include <dns/message.h> +#include <dns/messagerenderer.h> +#include <dns/question.h> +#include <dns/opcode.h> +#include <dns/rcode.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrttl.h> +#include <dns/rrtype.h> +#include <dns/tsig.h> +#include <dns/tsigkey.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +// +// Note: we need more tests, including: +// parsing malformed headers +// more complete tests about parsing/rendering header flags, opcode, rcode, etc. +// tests for adding RRsets +// tests for RRset/Question iterators +// But, we'll ship with the current set of tests for now, partly because many +// of the above are covered as part of other tests, and partly due to time +// limitation. We also expect to revisit the fundamental design of the Message +// class, at which point we'll also revise the tests including more cases. +// + +const uint16_t Message::DEFAULT_MAX_UDPSIZE; + +namespace isc { +namespace util { +namespace detail { +extern int64_t (*gettimeFunction)(); +} +} +} + +// XXX: this is defined as class static constants, but some compilers +// seemingly cannot find the symbol when used in the EXPECT_xxx macros. +const uint16_t TSIGContext::DEFAULT_FUDGE; + +namespace { +class MessageTest : public ::testing::Test { +protected: + MessageTest() : test_name("test.example.com"), obuffer(0), + message_parse(Message::PARSE), + message_render(Message::RENDER), + bogus_section(static_cast<Message::Section>( + Message::SECTION_ADDITIONAL + 1)), + tsig_ctx(TSIGKey("www.example.com:" + "SFuWd/q99SzF8Yzd1QbB9g==")) + { + rrset_a = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::A(), RRTTL(3600))); + rrset_a->addRdata(in::A("192.0.2.1")); + rrset_a->addRdata(in::A("192.0.2.2")); + + rrset_aaaa = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::AAAA(), RRTTL(3600))); + rrset_aaaa->addRdata(in::AAAA("2001:db8::1234")); + + rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::RRSIG(), RRTTL(3600))); + rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 " + "20100220084538 1 example.com. " + "FAKEFAKEFAKEFAKE")); + rrset_aaaa->addRRsig(rrset_rrsig); + } + + static Question factoryFromFile(const char* datafile); + const Name test_name; + OutputBuffer obuffer; + MessageRenderer renderer; + Message message_parse; + Message message_render; + const Message::Section bogus_section; + RRsetPtr rrset_a; // A RRset with two RDATAs + RRsetPtr rrset_aaaa; // AAAA RRset with one RDATA with RRSIG + RRsetPtr rrset_rrsig; // RRSIG for the AAAA RRset + TSIGContext tsig_ctx; + vector<unsigned char> received_data; + vector<unsigned char> expected_data; + + void factoryFromFile(Message& message, const char* datafile, + Message::ParseOptions options = + Message::PARSE_DEFAULT); +}; + +void +MessageTest::factoryFromFile(Message& message, const char* datafile, + Message::ParseOptions options) +{ + received_data.clear(); + UnitTestUtil::readWireData(datafile, received_data); + + InputBuffer buffer(&received_data[0], received_data.size()); + message.fromWire(buffer, options); +} + +TEST_F(MessageTest, headerFlag) { + // by default no flag is set + EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_QR)); + EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_AA)); + EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_TC)); + EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_RD)); + EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_RA)); + EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_AD)); + EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_CD)); + + // set operation: by default it will be on + message_render.setHeaderFlag(Message::HEADERFLAG_QR); + EXPECT_TRUE(message_render.getHeaderFlag(Message::HEADERFLAG_QR)); + + // it can be set to on explicitly, too + message_render.setHeaderFlag(Message::HEADERFLAG_AA, true); + EXPECT_TRUE(message_render.getHeaderFlag(Message::HEADERFLAG_AA)); + + // the bit can also be cleared + message_render.setHeaderFlag(Message::HEADERFLAG_AA, false); + EXPECT_FALSE(message_render.getHeaderFlag(Message::HEADERFLAG_AA)); + + // Invalid flag values + EXPECT_THROW(message_render.setHeaderFlag( + static_cast<Message::HeaderFlag>(0)), InvalidParameter); + EXPECT_THROW(message_render.setHeaderFlag( + static_cast<Message::HeaderFlag>(0x7000)), + InvalidParameter); + EXPECT_THROW(message_render.setHeaderFlag( + static_cast<Message::HeaderFlag>(0x0800)), + InvalidParameter); + EXPECT_THROW(message_render.setHeaderFlag( + static_cast<Message::HeaderFlag>(0x0040)), + InvalidParameter); + EXPECT_THROW(message_render.setHeaderFlag( + static_cast<Message::HeaderFlag>(0x10000)), + InvalidParameter); + EXPECT_THROW(message_render.setHeaderFlag( + static_cast<Message::HeaderFlag>(0x80000000)), + InvalidParameter); + + // set operation isn't allowed in the parse mode. + EXPECT_THROW(message_parse.setHeaderFlag(Message::HEADERFLAG_QR), + InvalidMessageOperation); +} +TEST_F(MessageTest, getEDNS) { + EXPECT_FALSE(message_parse.getEDNS()); // by default EDNS isn't set + + factoryFromFile(message_parse, "message_fromWire10.wire"); + EXPECT_TRUE(message_parse.getEDNS()); + EXPECT_EQ(0, message_parse.getEDNS()->getVersion()); + EXPECT_EQ(4096, message_parse.getEDNS()->getUDPSize()); + EXPECT_TRUE(message_parse.getEDNS()->getDNSSECAwareness()); +} + +TEST_F(MessageTest, setEDNS) { + // setEDNS() isn't allowed in the parse mode + EXPECT_THROW(message_parse.setEDNS(EDNSPtr(new EDNS())), + InvalidMessageOperation); + + EDNSPtr edns = EDNSPtr(new EDNS()); + message_render.setEDNS(edns); + EXPECT_EQ(edns, message_render.getEDNS()); +} + +TEST_F(MessageTest, fromWireWithTSIG) { + // Initially there should be no TSIG + EXPECT_EQ(static_cast<void*>(NULL), message_parse.getTSIGRecord()); + + // getTSIGRecord() is only valid in the parse mode. + EXPECT_THROW(message_render.getTSIGRecord(), InvalidMessageOperation); + + factoryFromFile(message_parse, "message_toWire2.wire"); + const uint8_t expected_mac[] = { + 0x22, 0x70, 0x26, 0xad, 0x29, 0x7b, 0xee, 0xe7, + 0x21, 0xce, 0x6c, 0x6f, 0xff, 0x1e, 0x9e, 0xf3 + }; + const TSIGRecord* tsig_rr = message_parse.getTSIGRecord(); + ASSERT_NE(static_cast<void*>(NULL), tsig_rr); + EXPECT_EQ(Name("www.example.com"), tsig_rr->getName()); + EXPECT_EQ(85, tsig_rr->getLength()); // see TSIGRecordTest.getLength + EXPECT_EQ(TSIGKey::HMACMD5_NAME(), tsig_rr->getRdata().getAlgorithm()); + EXPECT_EQ(0x4da8877a, tsig_rr->getRdata().getTimeSigned()); + EXPECT_EQ(TSIGContext::DEFAULT_FUDGE, tsig_rr->getRdata().getFudge()); + matchWireData(expected_mac, sizeof(expected_mac), + tsig_rr->getRdata().getMAC(), + tsig_rr->getRdata().getMACSize()); + EXPECT_EQ(0, tsig_rr->getRdata().getError()); + EXPECT_EQ(0, tsig_rr->getRdata().getOtherLen()); + EXPECT_EQ(static_cast<void*>(NULL), tsig_rr->getRdata().getOtherData()); + + // If we clear the message for reuse, the recorded TSIG will be cleared. + message_parse.clear(Message::PARSE); + EXPECT_EQ(static_cast<void*>(NULL), message_parse.getTSIGRecord()); +} + +TEST_F(MessageTest, fromWireWithTSIGCompressed) { + // Mostly same as fromWireWithTSIG, but the TSIG owner name is compressed. + factoryFromFile(message_parse, "message_fromWire12.wire"); + const TSIGRecord* tsig_rr = message_parse.getTSIGRecord(); + ASSERT_NE(static_cast<void*>(NULL), tsig_rr); + EXPECT_EQ(Name("www.example.com"), tsig_rr->getName()); + // len(www.example.com) = 17, but when fully compressed, the length is + // 2 bytes. So the length of the record should be 15 bytes shorter. + EXPECT_EQ(70, tsig_rr->getLength()); +} + +TEST_F(MessageTest, fromWireWithBadTSIG) { + // Multiple TSIG RRs + EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire13.wire"), + DNSMessageFORMERR); + message_parse.clear(Message::PARSE); + + // TSIG in the answer section (must be in additional) + EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire14.wire"), + DNSMessageFORMERR); + message_parse.clear(Message::PARSE); + + // TSIG is not the last record. + EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire15.wire"), + DNSMessageFORMERR); + message_parse.clear(Message::PARSE); + + // Unexpected RR Class (this will fail in constructing TSIGRecord) + EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire16.wire"), + DNSMessageFORMERR); +} + +TEST_F(MessageTest, getRRCount) { + // by default all counters should be 0 + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_QUESTION)); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ANSWER)); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY)); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL)); + + message_render.addQuestion(Question(Name("test.example.com"), + RRClass::IN(), RRType::A())); + EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION)); + + // rrset_a contains two RRs + message_render.addRRset(Message::SECTION_ANSWER, rrset_a); + EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER)); + + // parse a message containing a Question and EDNS OPT RR. + // OPT shouldn't be counted as normal RR, so result of getRRCount + // shouldn't change. + factoryFromFile(message_parse, "message_fromWire11.wire"); + EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION)); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL)); + + // out-of-band section ID + EXPECT_THROW(message_parse.getRRCount(bogus_section), OutOfRange); +} + +TEST_F(MessageTest, addRRset) { + // initially, we have 0 + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ANSWER)); + + // add two A RRs (unsigned) + message_render.addRRset(Message::SECTION_ANSWER, rrset_a); + EXPECT_EQ(rrset_a, + *message_render.beginSection(Message::SECTION_ANSWER)); + EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER)); + + message_render.clear(Message::RENDER); + + // add one AAAA RR (signed) + message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa); + EXPECT_EQ(rrset_aaaa, + *message_render.beginSection(Message::SECTION_ANSWER)); + EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER)); +} + +TEST_F(MessageTest, badAddRRset) { + // addRRset() isn't allowed in the parse mode. + EXPECT_THROW(message_parse.addRRset(Message::SECTION_ANSWER, + rrset_a), InvalidMessageOperation); + // out-of-band section ID + EXPECT_THROW(message_render.addRRset(bogus_section, rrset_a), OutOfRange); + + // NULL RRset + EXPECT_THROW(message_render.addRRset(Message::SECTION_ANSWER, RRsetPtr()), + InvalidParameter); +} + +TEST_F(MessageTest, hasRRset) { + message_render.addRRset(Message::SECTION_ANSWER, rrset_a); + EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::A())); + // section doesn't match + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name, + RRClass::IN(), RRType::A())); + // name doesn't match + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, + Name("nomatch.example"), + RRClass::IN(), RRType::A())); + // RR class doesn't match + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::CH(), RRType::A())); + // RR type doesn't match + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::AAAA())); + + // out-of-band section ID + EXPECT_THROW(message_render.hasRRset(bogus_section, test_name, + RRClass::IN(), RRType::A()), + OutOfRange); + + // Repeat the checks having created an RRset of the appropriate type. + + RRsetPtr rrs1(new RRset(test_name, RRClass::IN(), RRType::A(), RRTTL(60))); + EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, rrs1)); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ADDITIONAL, rrs1)); + + RRsetPtr rrs2(new RRset(Name("nomatch.example"), RRClass::IN(), RRType::A(), + RRTTL(5))); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, rrs2)); + + RRsetPtr rrs3(new RRset(test_name, RRClass::CH(), RRType::A(), RRTTL(60))); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, rrs3)); + + RRsetPtr rrs4(new RRset(test_name, RRClass::IN(), RRType::AAAA(), RRTTL(5))); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, rrs4)); + + RRsetPtr rrs5(new RRset(test_name, RRClass::IN(), RRType::AAAA(), RRTTL(5))); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, rrs4)); + + EXPECT_THROW(message_render.hasRRset(bogus_section, rrs1), OutOfRange); +} + +TEST_F(MessageTest, removeRRset) { + message_render.addRRset(Message::SECTION_ANSWER, rrset_a); + message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa); + EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::A())); + EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::AAAA())); + EXPECT_EQ(4, message_render.getRRCount(Message::SECTION_ANSWER)); + + // Locate the AAAA RRset and remove it and any associated RRSIGs + RRsetIterator i = message_render.beginSection(Message::SECTION_ANSWER); + if ((*i)->getType() == RRType::A()) { + ++i; + } + EXPECT_EQ(RRType::AAAA(), (*i)->getType()); + message_render.removeRRset(Message::SECTION_ANSWER, i); + + EXPECT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::A())); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::AAAA())); + EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER)); +} + +TEST_F(MessageTest, clearQuestionSection) { + QuestionPtr q(new Question(Name("www.example.com"), RRClass::IN(), + RRType::A())); + message_render.addQuestion(q); + ASSERT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION)); + + message_render.clearSection(Message::SECTION_QUESTION); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_QUESTION)); + EXPECT_TRUE(message_render.beginQuestion() == + message_render.endQuestion()); +} + + +TEST_F(MessageTest, clearAnswerSection) { + // Add two RRsets, check they are present, clear the section, + // check if they are gone. + message_render.addRRset(Message::SECTION_ANSWER, rrset_a); + message_render.addRRset(Message::SECTION_ANSWER, rrset_aaaa); + ASSERT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::A())); + ASSERT_TRUE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::AAAA())); + ASSERT_EQ(4, message_render.getRRCount(Message::SECTION_ANSWER)); + + message_render.clearSection(Message::SECTION_ANSWER); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::A())); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::AAAA())); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ANSWER)); +} + +TEST_F(MessageTest, clearAuthoritySection) { + // Add two RRsets, check they are present, clear the section, + // check if they are gone. + message_render.addRRset(Message::SECTION_AUTHORITY, rrset_a); + message_render.addRRset(Message::SECTION_AUTHORITY, rrset_aaaa); + ASSERT_TRUE(message_render.hasRRset(Message::SECTION_AUTHORITY, test_name, + RRClass::IN(), RRType::A())); + ASSERT_TRUE(message_render.hasRRset(Message::SECTION_AUTHORITY, test_name, + RRClass::IN(), RRType::AAAA())); + ASSERT_EQ(4, message_render.getRRCount(Message::SECTION_AUTHORITY)); + + message_render.clearSection(Message::SECTION_AUTHORITY); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_AUTHORITY, test_name, + RRClass::IN(), RRType::A())); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_AUTHORITY, test_name, + RRClass::IN(), RRType::AAAA())); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY)); +} + +TEST_F(MessageTest, clearAdditionalSection) { + // Add two RRsets, check they are present, clear the section, + // check if they are gone. + message_render.addRRset(Message::SECTION_ADDITIONAL, rrset_a); + message_render.addRRset(Message::SECTION_ADDITIONAL, rrset_aaaa); + ASSERT_TRUE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name, + RRClass::IN(), RRType::A())); + ASSERT_TRUE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name, + RRClass::IN(), RRType::AAAA())); + ASSERT_EQ(4, message_render.getRRCount(Message::SECTION_ADDITIONAL)); + + message_render.clearSection(Message::SECTION_ADDITIONAL); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name, + RRClass::IN(), RRType::A())); + EXPECT_FALSE(message_render.hasRRset(Message::SECTION_ADDITIONAL, test_name, + RRClass::IN(), RRType::AAAA())); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL)); +} + +TEST_F(MessageTest, badClearSection) { + // attempt of clearing a message in the parse mode. + EXPECT_THROW(message_parse.clearSection(Message::SECTION_QUESTION), + InvalidMessageOperation); + // attempt of clearing out-of-range section + EXPECT_THROW(message_render.clearSection(bogus_section), OutOfRange); +} + +TEST_F(MessageTest, badBeginSection) { + // valid cases are tested via other tests + EXPECT_THROW(message_render.beginSection(Message::SECTION_QUESTION), + InvalidMessageSection); + EXPECT_THROW(message_render.beginSection(bogus_section), OutOfRange); +} + +TEST_F(MessageTest, badEndSection) { + // valid cases are tested via other tests + EXPECT_THROW(message_render.endSection(Message::SECTION_QUESTION), + InvalidMessageSection); + EXPECT_THROW(message_render.endSection(bogus_section), OutOfRange); +} + +TEST_F(MessageTest, appendSection) { + Message target(Message::RENDER); + + // Section check + EXPECT_THROW(target.appendSection(bogus_section, message_render), + OutOfRange); + + // Make sure nothing is copied if there is nothing to copy + target.appendSection(Message::SECTION_QUESTION, message_render); + EXPECT_EQ(0, target.getRRCount(Message::SECTION_QUESTION)); + target.appendSection(Message::SECTION_ANSWER, message_render); + EXPECT_EQ(0, target.getRRCount(Message::SECTION_ANSWER)); + target.appendSection(Message::SECTION_AUTHORITY, message_render); + EXPECT_EQ(0, target.getRRCount(Message::SECTION_AUTHORITY)); + target.appendSection(Message::SECTION_ADDITIONAL, message_render); + EXPECT_EQ(0, target.getRRCount(Message::SECTION_ADDITIONAL)); + + // Now add some data, copy again, and see if it got added + message_render.addQuestion(Question(Name("test.example.com"), + RRClass::IN(), RRType::A())); + message_render.addRRset(Message::SECTION_ANSWER, rrset_a); + message_render.addRRset(Message::SECTION_AUTHORITY, rrset_a); + message_render.addRRset(Message::SECTION_ADDITIONAL, rrset_a); + message_render.addRRset(Message::SECTION_ADDITIONAL, rrset_aaaa); + + target.appendSection(Message::SECTION_QUESTION, message_render); + EXPECT_EQ(1, target.getRRCount(Message::SECTION_QUESTION)); + + target.appendSection(Message::SECTION_ANSWER, message_render); + EXPECT_EQ(2, target.getRRCount(Message::SECTION_ANSWER)); + EXPECT_TRUE(target.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::A())); + + target.appendSection(Message::SECTION_AUTHORITY, message_render); + EXPECT_EQ(2, target.getRRCount(Message::SECTION_AUTHORITY)); + EXPECT_TRUE(target.hasRRset(Message::SECTION_AUTHORITY, test_name, + RRClass::IN(), RRType::A())); + + target.appendSection(Message::SECTION_ADDITIONAL, message_render); + EXPECT_EQ(4, target.getRRCount(Message::SECTION_ADDITIONAL)); + EXPECT_TRUE(target.hasRRset(Message::SECTION_ADDITIONAL, test_name, + RRClass::IN(), RRType::A())); + EXPECT_TRUE(target.hasRRset(Message::SECTION_ADDITIONAL, test_name, + RRClass::IN(), RRType::AAAA())); + + // One more test, test to see if the section gets added, not replaced + Message source2(Message::RENDER); + source2.addRRset(Message::SECTION_ANSWER, rrset_aaaa); + target.appendSection(Message::SECTION_ANSWER, source2); + EXPECT_EQ(4, target.getRRCount(Message::SECTION_ANSWER)); + EXPECT_TRUE(target.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::A())); + EXPECT_TRUE(target.hasRRset(Message::SECTION_ANSWER, test_name, + RRClass::IN(), RRType::AAAA())); + +} + +TEST_F(MessageTest, parseHeader) { + received_data.clear(); + UnitTestUtil::readWireData("message_fromWire1", received_data); + + // parseHeader() isn't allowed in the render mode. + InputBuffer buffer(&received_data[0], received_data.size()); + EXPECT_THROW(message_render.parseHeader(buffer), InvalidMessageOperation); + + message_parse.parseHeader(buffer); + EXPECT_EQ(0x1035, message_parse.getQid()); + EXPECT_EQ(Opcode::QUERY(), message_parse.getOpcode()); + EXPECT_EQ(Rcode::NOERROR(), message_parse.getRcode()); + EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_QR)); + EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_AA)); + EXPECT_FALSE(message_parse.getHeaderFlag(Message::HEADERFLAG_TC)); + EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_RD)); + EXPECT_FALSE(message_parse.getHeaderFlag(Message::HEADERFLAG_RA)); + EXPECT_FALSE(message_parse.getHeaderFlag(Message::HEADERFLAG_AD)); + EXPECT_FALSE(message_parse.getHeaderFlag(Message::HEADERFLAG_CD)); + EXPECT_EQ(1, message_parse.getRRCount(Message::SECTION_QUESTION)); + EXPECT_EQ(2, message_parse.getRRCount(Message::SECTION_ANSWER)); + EXPECT_EQ(0, message_parse.getRRCount(Message::SECTION_AUTHORITY)); + EXPECT_EQ(0, message_parse.getRRCount(Message::SECTION_ADDITIONAL)); + + // Only the header part should have been examined. + EXPECT_EQ(12, buffer.getPosition()); // 12 = size of the header section + EXPECT_TRUE(message_parse.beginQuestion() == message_parse.endQuestion()); + EXPECT_TRUE(message_parse.beginSection(Message::SECTION_ANSWER) == + message_parse.endSection(Message::SECTION_ANSWER)); + EXPECT_TRUE(message_parse.beginSection(Message::SECTION_AUTHORITY) == + message_parse.endSection(Message::SECTION_AUTHORITY)); + EXPECT_TRUE(message_parse.beginSection(Message::SECTION_ADDITIONAL) == + message_parse.endSection(Message::SECTION_ADDITIONAL)); +} + +void +checkMessageFromWire(const Message& message_parse, + const Name& test_name) +{ + EXPECT_EQ(0x1035, message_parse.getQid()); + EXPECT_EQ(Opcode::QUERY(), message_parse.getOpcode()); + EXPECT_EQ(Rcode::NOERROR(), message_parse.getRcode()); + EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_QR)); + EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_RD)); + EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_AA)); + + QuestionPtr q = *message_parse.beginQuestion(); + EXPECT_EQ(test_name, q->getName()); + EXPECT_EQ(RRType::A(), q->getType()); + EXPECT_EQ(RRClass::IN(), q->getClass()); + EXPECT_EQ(1, message_parse.getRRCount(Message::SECTION_QUESTION)); + EXPECT_EQ(2, message_parse.getRRCount(Message::SECTION_ANSWER)); + EXPECT_EQ(0, message_parse.getRRCount(Message::SECTION_AUTHORITY)); + EXPECT_EQ(0, message_parse.getRRCount(Message::SECTION_ADDITIONAL)); + + RRsetPtr rrset = *message_parse.beginSection(Message::SECTION_ANSWER); + EXPECT_EQ(test_name, rrset->getName()); + EXPECT_EQ(RRType::A(), rrset->getType()); + EXPECT_EQ(RRClass::IN(), rrset->getClass()); + // TTL should be 3600, even though that of the 2nd RR is 7200 + EXPECT_EQ(RRTTL(3600), rrset->getTTL()); + RdataIteratorPtr it = rrset->getRdataIterator(); + EXPECT_EQ("192.0.2.1", it->getCurrent().toText()); + it->next(); + EXPECT_EQ("192.0.2.2", it->getCurrent().toText()); + it->next(); + EXPECT_TRUE(it->isLast()); +} + + +TEST_F(MessageTest, fromWire) { + // fromWire() isn't allowed in the render mode. + EXPECT_THROW(factoryFromFile(message_render, "message_fromWire1"), + InvalidMessageOperation); + + factoryFromFile(message_parse, "message_fromWire1"); + checkMessageFromWire(message_parse, test_name); +} + +TEST_F(MessageTest, fromWireMultiple) { + // Parse from wire multiple times. + factoryFromFile(message_parse, "message_fromWire1"); + factoryFromFile(message_parse, "message_fromWire1"); + factoryFromFile(message_parse, "message_fromWire1"); + factoryFromFile(message_parse, "message_fromWire1"); + checkMessageFromWire(message_parse, test_name); + + // Calling parseHeader() directly before fromWire() should not cause + // any problems. + received_data.clear(); + UnitTestUtil::readWireData("message_fromWire1", received_data); + + InputBuffer buffer(&received_data[0], received_data.size()); + message_parse.parseHeader(buffer); + message_parse.fromWire(buffer); + message_parse.parseHeader(buffer); + message_parse.fromWire(buffer); + checkMessageFromWire(message_parse, test_name); +} + +TEST_F(MessageTest, fromWireShortBuffer) { + // We trim a valid message (ending with an SOA RR) for one byte. + // fromWire() should throw an exception while parsing the trimmed RR. + UnitTestUtil::readWireData("message_fromWire22.wire", received_data); + InputBuffer buffer(&received_data[0], received_data.size() - 1); + EXPECT_THROW(message_parse.fromWire(buffer), InvalidBufferPosition); +} + +TEST_F(MessageTest, fromWireCombineRRs) { + // This message contains 3 RRs in the answer section in the order of + // A, AAAA, A types. fromWire() should combine the two A RRs into a + // single RRset by default. + factoryFromFile(message_parse, "message_fromWire19.wire"); + + RRsetIterator it = message_parse.beginSection(Message::SECTION_ANSWER); + RRsetIterator it_end = message_parse.endSection(Message::SECTION_ANSWER); + ASSERT_TRUE(it != it_end); + EXPECT_EQ(RRType::A(), (*it)->getType()); + EXPECT_EQ(2, (*it)->getRdataCount()); + + ++it; + ASSERT_TRUE(it != it_end); + EXPECT_EQ(RRType::AAAA(), (*it)->getType()); + EXPECT_EQ(1, (*it)->getRdataCount()); +} + +// A helper function for a test pattern commonly used in several tests below. +void +preserveRRCheck(const Message& message, Message::Section section) { + RRsetIterator it = message.beginSection(section); + RRsetIterator it_end = message.endSection(section); + ASSERT_TRUE(it != it_end); + EXPECT_EQ(RRType::A(), (*it)->getType()); + EXPECT_EQ(1, (*it)->getRdataCount()); + EXPECT_EQ("192.0.2.1", (*it)->getRdataIterator()->getCurrent().toText()); + + ++it; + ASSERT_TRUE(it != it_end); + EXPECT_EQ(RRType::AAAA(), (*it)->getType()); + EXPECT_EQ(1, (*it)->getRdataCount()); + EXPECT_EQ("2001:db8::1", (*it)->getRdataIterator()->getCurrent().toText()); + + ++it; + ASSERT_TRUE(it != it_end); + EXPECT_EQ(RRType::A(), (*it)->getType()); + EXPECT_EQ(1, (*it)->getRdataCount()); + EXPECT_EQ("192.0.2.2", (*it)->getRdataIterator()->getCurrent().toText()); +} + +TEST_F(MessageTest, fromWirePreserveAnswer) { + // Using the same data as the previous test, but specify the PRESERVE_ORDER + // option. The received order of RRs should be preserved, and each RR + // should be stored in a single RRset. + factoryFromFile(message_parse, "message_fromWire19.wire", + Message::PRESERVE_ORDER); + { + SCOPED_TRACE("preserve answer RRs"); + preserveRRCheck(message_parse, Message::SECTION_ANSWER); + } +} + +TEST_F(MessageTest, fromWirePreserveAuthority) { + // Same for the previous test, but for the authority section. + factoryFromFile(message_parse, "message_fromWire20.wire", + Message::PRESERVE_ORDER); + { + SCOPED_TRACE("preserve authority RRs"); + preserveRRCheck(message_parse, Message::SECTION_AUTHORITY); + } +} + +TEST_F(MessageTest, fromWirePreserveAdditional) { + // Same for the previous test, but for the additional section. + factoryFromFile(message_parse, "message_fromWire21.wire", + Message::PRESERVE_ORDER); + { + SCOPED_TRACE("preserve additional RRs"); + preserveRRCheck(message_parse, Message::SECTION_ADDITIONAL); + } +} + +TEST_F(MessageTest, EDNS0ExtRcode) { + // Extended Rcode = BADVERS + factoryFromFile(message_parse, "message_fromWire10.wire"); + EXPECT_EQ(Rcode::BADVERS(), message_parse.getRcode()); + + // Maximum extended Rcode + message_parse.clear(Message::PARSE); + factoryFromFile(message_parse, "message_fromWire11.wire"); + EXPECT_EQ(0xfff, message_parse.getRcode().getCode()); +} + +TEST_F(MessageTest, BadEDNS0) { + // OPT RR in the answer section + EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire4"), + DNSMessageFORMERR); + // multiple OPT RRs (in the additional section) + message_parse.clear(Message::PARSE); + EXPECT_THROW(factoryFromFile(message_parse, "message_fromWire5"), + DNSMessageFORMERR); +} + +TEST_F(MessageTest, toWire) { + message_render.setQid(0x1035); + message_render.setOpcode(Opcode::QUERY()); + message_render.setRcode(Rcode::NOERROR()); + message_render.setHeaderFlag(Message::HEADERFLAG_QR, true); + message_render.setHeaderFlag(Message::HEADERFLAG_RD, true); + message_render.setHeaderFlag(Message::HEADERFLAG_AA, true); + message_render.addQuestion(Question(Name("test.example.com"), RRClass::IN(), + RRType::A())); + message_render.addRRset(Message::SECTION_ANSWER, rrset_a); + + EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION)); + EXPECT_EQ(2, message_render.getRRCount(Message::SECTION_ANSWER)); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY)); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL)); + + message_render.toWire(renderer); + vector<unsigned char> data; + UnitTestUtil::readWireData("message_toWire1", data); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageTest, toWireSigned) { + message_render.setQid(0x75c1); + message_render.setOpcode(Opcode::QUERY()); + message_render.setRcode(Rcode::NOERROR()); + message_render.setHeaderFlag(Message::HEADERFLAG_QR, true); + message_render.setHeaderFlag(Message::HEADERFLAG_RD, true); + message_render.setHeaderFlag(Message::HEADERFLAG_AA, true); + message_render.addQuestion(Question(Name("test.example.com"), RRClass::IN(), + RRType::A())); + + rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::RRSIG(), RRTTL(3600))); + // one signature algorithm (5 = RSA/SHA-1) + rrset_rrsig->addRdata(generic::RRSIG("A 5 3 3600 " + "20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE")); + // another signature algorithm (3 = DSA/SHA-1) + rrset_rrsig->addRdata(generic::RRSIG("A 3 3 3600 " + "20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE")); + rrset_a->addRRsig(rrset_rrsig); + EXPECT_EQ(2, rrset_a->getRRsigDataCount()); + + message_render.addRRset(Message::SECTION_ANSWER, rrset_a); + + EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION)); + EXPECT_EQ(4, message_render.getRRCount(Message::SECTION_ANSWER)); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY)); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL)); + + message_render.toWire(renderer); + vector<unsigned char> data; + UnitTestUtil::readWireData("message_toWire6", data); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageTest, toWireSignedAndTruncated) { + message_render.setQid(0x75c1); + message_render.setOpcode(Opcode::QUERY()); + message_render.setRcode(Rcode::NOERROR()); + message_render.setHeaderFlag(Message::HEADERFLAG_QR, true); + message_render.setHeaderFlag(Message::HEADERFLAG_RD, true); + message_render.setHeaderFlag(Message::HEADERFLAG_AA, true); + message_render.addQuestion(Question(Name("test.example.com"), RRClass::IN(), + RRType::TXT())); + + RRsetPtr rrset_txt = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::TXT(), RRTTL(3600))); + rrset_txt->addRdata(generic::TXT(string(255, 'a'))); + rrset_txt->addRdata(generic::TXT(string(255, 'b'))); + rrset_txt->addRdata(generic::TXT(string(255, 'c'))); + rrset_txt->addRdata(generic::TXT(string(255, 'd'))); + rrset_txt->addRdata(generic::TXT(string(255, 'e'))); + rrset_txt->addRdata(generic::TXT(string(255, 'f'))); + rrset_txt->addRdata(generic::TXT(string(255, 'g'))); + rrset_txt->addRdata(generic::TXT(string(255, 'h'))); + + rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::RRSIG(), RRTTL(3600))); + // one signature algorithm (5 = RSA/SHA-1) + rrset_rrsig->addRdata(generic::RRSIG("TXT 5 3 3600 " + "20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE")); + rrset_txt->addRRsig(rrset_rrsig); + EXPECT_EQ(1, rrset_txt->getRRsigDataCount()); + + message_render.addRRset(Message::SECTION_ANSWER, rrset_txt); + + EXPECT_EQ(1, message_render.getRRCount(Message::SECTION_QUESTION)); + EXPECT_EQ(9, message_render.getRRCount(Message::SECTION_ANSWER)); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_AUTHORITY)); + EXPECT_EQ(0, message_render.getRRCount(Message::SECTION_ADDITIONAL)); + + message_render.toWire(renderer); + vector<unsigned char> data; + UnitTestUtil::readWireData("message_toWire7", data); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageTest, toWireInParseMode) { + // toWire() isn't allowed in the parse mode. + EXPECT_THROW(message_parse.toWire(renderer), InvalidMessageOperation); +} + +// See dnssectime_unittest.cc +template <int64_t NOW> +int64_t +testGetTime() { + return (NOW); +} + +// bit-wise constant flags to configure DNS header flags for test +// messages. +const unsigned int QR_FLAG = 0x1; +const unsigned int AA_FLAG = 0x2; +const unsigned int RD_FLAG = 0x4; + +void +commonTSIGToWireCheck(Message& message, MessageRenderer& renderer, + TSIGContext& tsig_ctx, const char* const expected_file, + unsigned int message_flags = RD_FLAG, + RRType qtype = RRType::A(), + const vector<const char*>* answer_data = NULL) +{ + message.setOpcode(Opcode::QUERY()); + message.setRcode(Rcode::NOERROR()); + if ((message_flags & QR_FLAG) != 0) { + message.setHeaderFlag(Message::HEADERFLAG_QR); + } + if ((message_flags & AA_FLAG) != 0) { + message.setHeaderFlag(Message::HEADERFLAG_AA); + } + if ((message_flags & RD_FLAG) != 0) { + message.setHeaderFlag(Message::HEADERFLAG_RD); + } + message.addQuestion(Question(Name("www.example.com"), RRClass::IN(), + qtype)); + + if (answer_data != NULL) { + RRsetPtr ans_rrset(new RRset(Name("www.example.com"), RRClass::IN(), + qtype, RRTTL(86400))); + for (vector<const char*>::const_iterator it = answer_data->begin(); + it != answer_data->end(); + ++it) { + ans_rrset->addRdata(createRdata(qtype, RRClass::IN(), *it)); + } + message.addRRset(Message::SECTION_ANSWER, ans_rrset); + } + + message.toWire(renderer, &tsig_ctx); + vector<unsigned char> expected_data; + UnitTestUtil::readWireData(expected_file, expected_data); + matchWireData(&expected_data[0], expected_data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageTest, toWireWithTSIG) { + // Rendering a message with TSIG. Various special cases specific to + // TSIG are tested in the tsig tests. We only check the message contains + // a TSIG at the end and the ARCOUNT of the header is updated. + + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + message_render.setQid(0x2d65); + + { + SCOPED_TRACE("Message sign with TSIG"); + commonTSIGToWireCheck(message_render, renderer, tsig_ctx, + "message_toWire2.wire"); + } +} + +TEST_F(MessageTest, toWireWithEDNSAndTSIG) { + // Similar to the previous test, but with an EDNS before TSIG. + // The wire data check will confirm the ordering. + isc::util::detail::gettimeFunction = testGetTime<0x4db60d1f>; + + message_render.setQid(0x6cd); + + EDNSPtr edns(new EDNS()); + edns->setUDPSize(4096); + message_render.setEDNS(edns); + + { + SCOPED_TRACE("Message sign with TSIG and EDNS"); + commonTSIGToWireCheck(message_render, renderer, tsig_ctx, + "message_toWire3.wire"); + } +} + +// Some of the following tests involve truncation. We use the query name +// "www.example.com" and some TXT question/answers. The length of the +// header and question will be 33 bytes. If we also try to include a +// TSIG of the same key name (not compressed) with HMAC-MD5, the TSIG RR +// will be 85 bytes. + +// A long TXT RDATA. With a fully compressed owner name, the corresponding +// RR will be 268 bytes. +const char* const long_txt1 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde"; + +// With a fully compressed owner name, the corresponding RR will be 212 bytes. +// It should result in truncation even without TSIG (33 + 268 + 212 = 513) +const char* const long_txt2 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456"; + +// With a fully compressed owner name, the corresponding RR will be 127 bytes. +// So, it can fit in the standard 512 bytes with txt1 and without TSIG, but +// adding a TSIG would result in truncation (33 + 268 + 127 + 85 = 513) +const char* const long_txt3 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01"; + +// This is 1 byte shorter than txt3, which will result in a possible longest +// message containing answer RRs and TSIG. +const char* const long_txt4 = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0"; + +// Example output generated by +// "dig -y www.example.com:SFuWd/q99SzF8Yzd1QbB9g== www.example.com txt +// QID: 0x22c2 +// Time Signed: 0x00004e179212 +TEST_F(MessageTest, toWireTSIGTruncation) { + isc::util::detail::gettimeFunction = testGetTime<0x4e179212>; + + // Verify a validly signed query so that we can use the TSIG context + + factoryFromFile(message_parse, "message_fromWire17.wire"); + EXPECT_EQ(TSIGError::NOERROR(), + tsig_ctx.verify(message_parse.getTSIGRecord(), + &received_data[0], received_data.size())); + + message_render.setQid(0x22c2); + vector<const char*> answer_data; + answer_data.push_back(long_txt1); + answer_data.push_back(long_txt2); + { + SCOPED_TRACE("Message sign with TSIG and TC bit on"); + commonTSIGToWireCheck(message_render, renderer, tsig_ctx, + "message_toWire4.wire", + QR_FLAG|AA_FLAG|RD_FLAG, + RRType::TXT(), &answer_data); + } +} + +TEST_F(MessageTest, toWireTSIGTruncation2) { + // Similar to the previous test, but without TSIG it wouldn't cause + // truncation. + isc::util::detail::gettimeFunction = testGetTime<0x4e179212>; + factoryFromFile(message_parse, "message_fromWire17.wire"); + EXPECT_EQ(TSIGError::NOERROR(), + tsig_ctx.verify(message_parse.getTSIGRecord(), + &received_data[0], received_data.size())); + + message_render.setQid(0x22c2); + vector<const char*> answer_data; + answer_data.push_back(long_txt1); + answer_data.push_back(long_txt3); + { + SCOPED_TRACE("Message sign with TSIG and TC bit on (2)"); + commonTSIGToWireCheck(message_render, renderer, tsig_ctx, + "message_toWire4.wire", + QR_FLAG|AA_FLAG|RD_FLAG, + RRType::TXT(), &answer_data); + } +} + +TEST_F(MessageTest, toWireTSIGTruncation3) { + // Similar to previous ones, but truncation occurs due to too many + // Questions (very unusual, but not necessarily illegal). + + // We are going to create a message starting with a standard + // header (12 bytes) and multiple questions in the Question + // section of the same owner name (changing the RRType, just so + // that it would be the form that would be accepted by the BIND 9 + // parser). The first Question is 21 bytes in length, and the subsequent + // ones are 6 bytes. We'll also use a TSIG whose size is 85 bytes. + // Up to 66 questions can fit in the standard 512-byte buffer + // (12 + 21 + 6 * 65 + 85 = 508). If we try to add one more it would + // result in truncation. + message_render.setOpcode(Opcode::QUERY()); + message_render.setRcode(Rcode::NOERROR()); + for (int i = 1; i <= 67; ++i) { + message_render.addQuestion(Question(Name("www.example.com"), + RRClass::IN(), RRType(i))); + } + message_render.toWire(renderer, &tsig_ctx); + + // Check the rendered data by parsing it. We only check it has the + // TC bit on, has the correct number of questions, and has a TSIG RR. + // Checking the signature wouldn't be necessary for this rare case + // scenario. + InputBuffer buffer(renderer.getData(), renderer.getLength()); + message_parse.fromWire(buffer); + EXPECT_TRUE(message_parse.getHeaderFlag(Message::HEADERFLAG_TC)); + // Note that the number of questions are 66, not 67 as we tried to add. + EXPECT_EQ(66, message_parse.getRRCount(Message::SECTION_QUESTION)); + EXPECT_TRUE(message_parse.getTSIGRecord() != NULL); +} + +TEST_F(MessageTest, toWireTSIGNoTruncation) { + // A boundary case that shouldn't cause truncation: the resulting + // response message with a TSIG will be 512 bytes long. + isc::util::detail::gettimeFunction = testGetTime<0x4e17b38d>; + factoryFromFile(message_parse, "message_fromWire18.wire"); + EXPECT_EQ(TSIGError::NOERROR(), + tsig_ctx.verify(message_parse.getTSIGRecord(), + &received_data[0], received_data.size())); + + message_render.setQid(0xd6e2); + vector<const char*> answer_data; + answer_data.push_back(long_txt1); + answer_data.push_back(long_txt4); + { + SCOPED_TRACE("Message sign with TSIG, no truncation"); + commonTSIGToWireCheck(message_render, renderer, tsig_ctx, + "message_toWire5.wire", + QR_FLAG|AA_FLAG|RD_FLAG, + RRType::TXT(), &answer_data); + } +} + +// This is a buggy renderer for testing. It behaves like the straightforward +// MessageRenderer, but once it has some data, its setLengthLimit() ignores +// the given parameter and resets the limit to the current length, making +// subsequent insertion result in truncation, which would make TSIG RR +// rendering fail unexpectedly in the test that follows. +class BadRenderer : public MessageRenderer { +public: + virtual void setLengthLimit(size_t len) { + if (getLength() > 0) { + MessageRenderer::setLengthLimit(getLength()); + } else { + MessageRenderer::setLengthLimit(len); + } + } +}; + +TEST_F(MessageTest, toWireTSIGLengthErrors) { + // specify an unusual short limit that wouldn't be able to hold + // the TSIG. + renderer.setLengthLimit(tsig_ctx.getTSIGLength() - 1); + // Use commonTSIGToWireCheck() only to call toWire() with otherwise valid + // conditions. The checks inside it don't matter because we expect an + // exception before any of the checks. + EXPECT_THROW(commonTSIGToWireCheck(message_render, renderer, tsig_ctx, + "message_toWire2.wire"), + InvalidParameter); + + // This one is large enough for TSIG, but the remaining limit isn't + // even enough for the Header section. + renderer.clear(); + message_render.clear(Message::RENDER); + renderer.setLengthLimit(tsig_ctx.getTSIGLength() + 1); + EXPECT_THROW(commonTSIGToWireCheck(message_render, renderer, tsig_ctx, + "message_toWire2.wire"), + InvalidParameter); + + // Trying to render a message with TSIG using a buggy renderer. + BadRenderer bad_renderer; + bad_renderer.setLengthLimit(512); + message_render.clear(Message::RENDER); + EXPECT_THROW(commonTSIGToWireCheck(message_render, bad_renderer, tsig_ctx, + "message_toWire2.wire"), + Unexpected); +} + +TEST_F(MessageTest, toWireWithoutOpcode) { + message_render.setRcode(Rcode::NOERROR()); + EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation); +} + +TEST_F(MessageTest, toWireWithoutRcode) { + message_render.setOpcode(Opcode::QUERY()); + EXPECT_THROW(message_render.toWire(renderer), InvalidMessageOperation); +} + +TEST_F(MessageTest, toText) { + // Check toText() output for a typical DNS response with records in + // all sections + + factoryFromFile(message_parse, "message_toText1.wire"); + { + SCOPED_TRACE("Message toText test (basic case)"); + ifstream ifs; + unittests::openTestData("message_toText1.txt", ifs); + unittests::matchTextData(ifs, message_parse.toText()); + } + + // Another example with EDNS. The expected data was slightly modified + // from the dig output (other than replacing tabs with a space): adding + // a newline after the "OPT PSEUDOSECTION". This is an intentional change + // in our version for better readability. + message_parse.clear(Message::PARSE); + factoryFromFile(message_parse, "message_toText2.wire"); + { + SCOPED_TRACE("Message toText test with EDNS"); + ifstream ifs; + unittests::openTestData("message_toText2.txt", ifs); + unittests::matchTextData(ifs, message_parse.toText()); + } + + // Another example with TSIG. The expected data was slightly modified + // from the dig output (other than replacing tabs with a space): removing + // a redundant white space at the end of TSIG RDATA. We'd rather consider + // it a dig's defect than a feature. + message_parse.clear(Message::PARSE); + factoryFromFile(message_parse, "message_toText3.wire"); + { + SCOPED_TRACE("Message toText test with TSIG"); + ifstream ifs; + unittests::openTestData("message_toText3.txt", ifs); + unittests::matchTextData(ifs, message_parse.toText()); + } +} + +TEST_F(MessageTest, toTextWithoutOpcode) { + message_render.setRcode(Rcode::NOERROR()); + EXPECT_THROW(message_render.toText(), InvalidMessageOperation); +} + +TEST_F(MessageTest, toTextWithoutRcode) { + message_render.setOpcode(Opcode::QUERY()); + EXPECT_THROW(message_render.toText(), InvalidMessageOperation); +} +} diff --git a/src/lib/dns/tests/messagerenderer_unittest.cc b/src/lib/dns/tests/messagerenderer_unittest.cc new file mode 100644 index 0000000..c3a53eb --- /dev/null +++ b/src/lib/dns/tests/messagerenderer_unittest.cc @@ -0,0 +1,292 @@ +// Copyright (C) 2009-2017 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <exceptions/exceptions.h> +#include <util/buffer.h> +#include <dns/name.h> +#include <dns/labelsequence.h> +#include <dns/messagerenderer.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +#include <gtest/gtest.h> + +#include <boost/lexical_cast.hpp> + +#include <string> +#include <vector> + +using isc::UnitTestUtil; +using isc::dns::Name; +using isc::dns::LabelSequence; +using isc::dns::MessageRenderer; +using isc::util::OutputBuffer; +using boost::lexical_cast; +using isc::util::unittests::matchWireData; + +namespace { +class MessageRendererTest : public ::testing::Test { +protected: + MessageRendererTest() : expected_size(0) { + data16 = (2 << 8) | 3; + data32 = (4 << 24) | (5 << 16) | (6 << 8) | 7; + } + size_t expected_size; + uint16_t data16; + uint32_t data32; + MessageRenderer renderer; + std::vector<unsigned char> data; + static const uint8_t testdata[5]; +}; + +const uint8_t MessageRendererTest::testdata[5] = {1, 2, 3, 4, 5}; + +// The test cases are borrowed from those for the OutputBuffer class. +TEST_F(MessageRendererTest, writeInteger) { + renderer.writeUint16(data16); + expected_size += sizeof(data16); + + matchWireData(&testdata[1], sizeof(data16), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageRendererTest, writeName) { + UnitTestUtil::readWireData("name_toWire1", data); + renderer.writeName(Name("a.example.com.")); + renderer.writeName(Name("b.example.com.")); + renderer.writeName(Name("a.example.org.")); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageRendererTest, writeNameInLargeBuffer) { + size_t offset = 0x3fff; + renderer.skip(offset); + + UnitTestUtil::readWireData("name_toWire2", data); + renderer.writeName(Name("a.example.com.")); + renderer.writeName(Name("a.example.com.")); + renderer.writeName(Name("b.example.com.")); + matchWireData(&data[0], data.size(), + static_cast<const uint8_t*>(renderer.getData()) + offset, + renderer.getLength() - offset); +} + +TEST_F(MessageRendererTest, writeNameWithUncompressed) { + UnitTestUtil::readWireData("name_toWire3", data); + renderer.writeName(Name("a.example.com.")); + renderer.writeName(Name("b.example.com."), false); + renderer.writeName(Name("b.example.com.")); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageRendererTest, writeNamePointerChain) { + UnitTestUtil::readWireData("name_toWire4", data); + renderer.writeName(Name("a.example.com.")); + renderer.writeName(Name("b.example.com.")); + renderer.writeName(Name("b.example.com.")); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageRendererTest, compressMode) { + // By default the render performs case insensitive compression. + EXPECT_EQ(MessageRenderer::CASE_INSENSITIVE, renderer.getCompressMode()); + + // The mode can be explicitly changed. + renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE); + EXPECT_EQ(MessageRenderer::CASE_SENSITIVE, renderer.getCompressMode()); + renderer.setCompressMode(MessageRenderer::CASE_INSENSITIVE); + EXPECT_EQ(MessageRenderer::CASE_INSENSITIVE, renderer.getCompressMode()); + + // The clear() method resets the mode to the default. + renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE); + renderer.clear(); + EXPECT_EQ(MessageRenderer::CASE_INSENSITIVE, renderer.getCompressMode()); +} + +TEST_F(MessageRendererTest, writeNameCaseCompress) { + // By default MessageRenderer performs case insensitive compression. + + UnitTestUtil::readWireData("name_toWire1", data); + renderer.writeName(Name("a.example.com.")); + // this should match the first name in terms of compression: + renderer.writeName(Name("b.exAmple.CoM.")); + renderer.writeName(Name("a.example.org.")); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageRendererTest, writeNameCaseSensitiveCompress) { + // name compression in case sensitive manner. See the data file + // description for details. + renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE); + UnitTestUtil::readWireData("name_toWire5.wire", data); + renderer.writeName(Name("a.example.com.")); + renderer.writeName(Name("b.eXample.com.")); + renderer.writeName(Name("c.eXample.com.")); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageRendererTest, writeNameMixedCaseCompress) { + renderer.setCompressMode(MessageRenderer::CASE_SENSITIVE); + UnitTestUtil::readWireData("name_toWire6.wire", data); + renderer.writeName(Name("a.example.com.")); + renderer.writeName(Name("b.eXample.com.")); + + // Change the compression mode in the middle of rendering. This is not + // allowed in this implementation. + EXPECT_THROW(renderer.setCompressMode(MessageRenderer::CASE_INSENSITIVE), + isc::InvalidParameter); + + // Once the renderer is cleared, it's okay again. + renderer.clear(); + EXPECT_NO_THROW(renderer.setCompressMode( + MessageRenderer::CASE_INSENSITIVE)); +} + +TEST_F(MessageRendererTest, writeRootName) { + // root name is special: it never causes compression or can (reasonably) + // be a compression pointer. So it makes sense to check this case + // explicitly. + Name example_name = Name("www.example.com"); + + OutputBuffer expected(0); + expected.writeUint8(0); // root name + example_name.toWire(expected); + + renderer.writeName(Name(".")); + renderer.writeName(example_name); + matchWireData(static_cast<const uint8_t*>(expected.getData()), + expected.getLength(), + static_cast<const uint8_t*>(renderer.getData()), + renderer.getLength()); +} + +TEST_F(MessageRendererTest, writeNameLabelSequence1) { + UnitTestUtil::readWireData("name_toWire7", data); + + Name n1("a.example.com"); + LabelSequence ls1(n1); + + // a.example.com. + renderer.writeName(ls1); + + ls1.stripLeft(1); + + // example.com. + renderer.writeName(ls1); + + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageRendererTest, writeNameLabelSequence2) { + UnitTestUtil::readWireData("name_toWire8", data); + + Name n1("a.example.com"); + LabelSequence ls1(n1); + + ls1.stripRight(1); + + // a.example.com (without root .) + renderer.writeName(ls1); + + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageRendererTest, writeNameLabelSequence3) { + UnitTestUtil::readWireData("name_toWire9", data); + + Name n1("a.example.com"); + LabelSequence ls1(n1); + + // a.example.com. + renderer.writeName(ls1); + + ls1.stripRight(1); + + // a.example.com (without root .) + renderer.writeName(ls1); + + ls1.stripRight(1); + + // a.example + renderer.writeName(ls1); + + ls1.stripLeft(1); + + // example + renderer.writeName(ls1); + + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(MessageRendererTest, setBuffer) { + OutputBuffer new_buffer(0); + renderer.setBuffer(&new_buffer); + EXPECT_EQ(0, new_buffer.getLength()); // the buffer should be still empty + renderer.writeUint32(42); + EXPECT_EQ(sizeof(uint32_t), new_buffer.getLength()); + EXPECT_EQ(sizeof(uint32_t), renderer.getLength()); + + // Change some other internal state for the reset test below. + EXPECT_EQ(512, renderer.getLengthLimit()); + renderer.setLengthLimit(4096); + EXPECT_EQ(4096, renderer.getLengthLimit()); + + // Reset the buffer to the default again. Other internal states and + // resources should be cleared. The used buffer should be intact. + renderer.setBuffer(NULL); + EXPECT_EQ(sizeof(uint32_t), new_buffer.getLength()); + EXPECT_EQ(0, renderer.getLength()); + EXPECT_EQ(512, renderer.getLengthLimit()); +} + +TEST_F(MessageRendererTest, setBufferErrors) { + OutputBuffer new_buffer(0); + + // Buffer cannot be reset when the renderer is in use. + renderer.writeUint32(10); + EXPECT_THROW(renderer.setBuffer(&new_buffer), isc::InvalidParameter); + + renderer.clear(); + renderer.setBuffer(&new_buffer); + renderer.writeUint32(10); + EXPECT_THROW(renderer.setBuffer(&new_buffer), isc::InvalidParameter); + + // Resetting the buffer isn't allowed for the default buffer. + renderer.setBuffer(NULL); + EXPECT_THROW(renderer.setBuffer(NULL), isc::InvalidParameter); + + // It's okay to reset a temporary buffer without using it. + renderer.setBuffer(&new_buffer); + EXPECT_NO_THROW(renderer.setBuffer(NULL)); +} + +TEST_F(MessageRendererTest, manyRRs) { + // Render a large number of names, and the confirm the resulting wire + // data store the expected names in the correct order (1000 is an + // arbitrary choice). + for (size_t i = 0; i < 1000; ++i) { + renderer.writeName(Name(lexical_cast<std::string>(i) + ".example")); + } + isc::util::InputBuffer b(renderer.getData(), renderer.getLength()); + for (size_t i = 0; i < 1000; ++i) { + EXPECT_EQ(Name(lexical_cast<std::string>(i) + ".example"), Name(b)); + } + // This will trigger trimming excessive hash items. It shouldn't cause + // any disruption. + EXPECT_NO_THROW(renderer.clear()); +} +} diff --git a/src/lib/dns/tests/name_unittest.cc b/src/lib/dns/tests/name_unittest.cc new file mode 100644 index 0000000..caf1f12 --- /dev/null +++ b/src/lib/dns/tests/name_unittest.cc @@ -0,0 +1,797 @@ +// Copyright (C) 2009-2019 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <vector> +#include <string> +#include <sstream> +#include <iomanip> +#include <limits> +#include <stdexcept> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/name.h> +#include <dns/messagerenderer.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +#include <gtest/gtest.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using isc::util::unittests::matchWireData; + +// +// XXX: these are defined as class static constants, but some compilers +// seemingly cannot find the symbols when used in the EXPECT_xxx macros. +// +const size_t Name::MAX_WIRE; +const size_t Name::MAX_LABELS; + +// This is a name of maximum allowed number of labels +const char* max_labels_str = "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 40 + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 80 + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 120 + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 160 + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 200 + "0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9." // 240 + "0.1.2.3.4.5.6"; +// This is a name of maximum allowed length +const char* max_len_str = "123456789.123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789.123456789." + "123"; + +namespace { +class NameTest : public ::testing::Test { +protected: + NameTest() : example_name("www.example.com"), + example_name_upper("WWW.EXAMPLE.COM"), + small_name("aaa.example.com"), + large_name("zzz.example.com"), + origin_name("example.com."), + origin_name_upper("EXAMPLE.COM"), + buffer_actual(0), buffer_expected(0) + {} + + const Name example_name; + Name example_name_upper; // this will be modified and cannot be const + const Name small_name; + const Name large_name; + const Name origin_name; + const Name origin_name_upper; + OutputBuffer buffer_actual, buffer_expected; + + // + // helper methods + // + static Name nameFactoryFromWire(const char* datafile, size_t position, + bool downcase = false); + // construct a name including all non-upper-case-alphabet characters. + static Name nameFactoryLowerCase(); + void compareInWireFormat(const Name& name_actual, + const Name& name_expected); +}; + +const Name downcased_global("\\255.EXAMPLE.COM", true); + +Name +NameTest::nameFactoryFromWire(const char* datafile, size_t position, + bool downcase) +{ + vector<unsigned char> data; + UnitTestUtil::readWireData(datafile, data); + + InputBuffer buffer(&data[0], data.size()); + buffer.setPosition(position); + + return (Name(buffer, downcase)); +} + +Name +NameTest::nameFactoryLowerCase() { + string lowercase_namestr; + lowercase_namestr.reserve(Name::MAX_WIRE); + + unsigned int ch = 0; + unsigned int labelcount = 0; + do { + if (ch < 'A' || ch > 'Z') { + ostringstream ss; + ss.setf(ios_base::right, ios_base::adjustfield); + ss.width(3); + ss << setfill('0') << ch; + lowercase_namestr += '\\' + ss.str(); + + if (++labelcount == Name::MAX_LABELLEN) { + lowercase_namestr.push_back('.'); + labelcount = 0; + } + } + } while (++ch <= Name::MAX_WIRE); + + return (Name(lowercase_namestr)); +} + +void +NameTest::compareInWireFormat(const Name& name_actual, + const Name& name_expected) +{ + buffer_actual.clear(); + buffer_expected.clear(); + + name_actual.toWire(buffer_actual); + name_expected.toWire(buffer_expected); + + matchWireData(buffer_expected.getData(), buffer_expected.getLength(), + buffer_actual.getData(), buffer_actual.getLength()); +} + +TEST_F(NameTest, nonlocalObject) { + // A previous version of code relied on a non local static object for + // name construction, so a non local static Name object defined outside + // the name module might not be initialized correctly. This test detects + // that kind of bug. + EXPECT_EQ("\\255.example.com.", downcased_global.toText()); +} + +template <typename ExceptionType> +void +checkBadTextName(const string& txt) { + // Check it results in the specified type of exception as well as + // NameParserException. + EXPECT_THROW(Name(txt, false), ExceptionType); + EXPECT_THROW(Name(txt, false), NameParserException); + // The same is thrown when constructing by the master-file constructor + EXPECT_THROW(Name(txt.c_str(), txt.length(), &Name::ROOT_NAME()), + ExceptionType); + EXPECT_THROW(Name(txt.c_str(), txt.length(), &Name::ROOT_NAME()), + NameParserException); +} + +TEST_F(NameTest, checkExceptionsHierarchy) { + EXPECT_NO_THROW({ + const isc::dns::EmptyLabel exception("", 0, ""); + const isc::dns::NameParserException& exception_cast = + dynamic_cast<const isc::dns::NameParserException&>(exception); + // to avoid compiler warning + exception_cast.what(); + }); + + EXPECT_NO_THROW({ + const isc::dns::TooLongName exception("", 0, ""); + const isc::dns::NameParserException& exception_cast = + dynamic_cast<const isc::dns::NameParserException&>(exception); + // to avoid compiler warning + exception_cast.what(); + }); + + EXPECT_NO_THROW({ + const isc::dns::TooLongLabel exception("", 0, ""); + const isc::dns::NameParserException& exception_cast = + dynamic_cast<const isc::dns::NameParserException&>(exception); + // to avoid compiler warning + exception_cast.what(); + }); + + EXPECT_NO_THROW({ + const isc::dns::BadLabelType exception("", 0, ""); + const isc::dns::NameParserException& exception_cast = + dynamic_cast<const isc::dns::NameParserException&>(exception); + // to avoid compiler warning + exception_cast.what(); + }); + + EXPECT_NO_THROW({ + const isc::dns::BadEscape exception("", 0, ""); + const isc::dns::NameParserException& exception_cast = + dynamic_cast<const isc::dns::NameParserException&>(exception); + // to avoid compiler warning + exception_cast.what(); + }); + + EXPECT_NO_THROW({ + const isc::dns::IncompleteName exception("", 0, ""); + const isc::dns::NameParserException& exception_cast = + dynamic_cast<const isc::dns::NameParserException&>(exception); + // to avoid compiler warning + exception_cast.what(); + }); + + EXPECT_NO_THROW({ + const isc::dns::MissingNameOrigin exception("", 0, ""); + const isc::dns::NameParserException& exception_cast = + dynamic_cast<const isc::dns::NameParserException&>(exception); + // to avoid compiler warning + exception_cast.what(); + }); +} + +TEST_F(NameTest, fromText) { + vector<string> strnames; + strnames.push_back("www.example.com"); + strnames.push_back("www.example.com."); // with a trailing dot + strnames.push_back("wWw.exAmpLe.com"); // mixed cases + strnames.push_back("\\wWw.exAmpLe.com"); // escape with a backslash + // decimal representation for "WWW" + strnames.push_back("\\087\\087\\087.example.com"); + + vector<string>::const_iterator it; + for (it = strnames.begin(); it != strnames.end(); ++it) { + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name, Name(*it)); + } + + // root names + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, Name("@"), Name(".")); + + // downcase + EXPECT_EQ(Name("Www.eXample.coM", true).toText(), example_name.toText()); + + // + // Tests for bogus names. These should trigger exceptions. + // + // empty label cannot be followed by another label + checkBadTextName<EmptyLabel>(".a"); + // duplicate period + checkBadTextName<EmptyLabel>("a.."); + // label length must be < 64 + checkBadTextName<TooLongLabel>("012345678901234567890123456789" + "012345678901234567890123456789" + "0123"); + // now-unsupported bitstring labels + checkBadTextName<BadLabelType>("\\[b11010000011101]"); + // label length must be < 64 + checkBadTextName<TooLongLabel>("012345678901234567890123456789" + "012345678901234567890123456789" + "012\\x"); + // but okay as long as resulting len < 64 even if the original string is + // "too long" + EXPECT_NO_THROW(Name("012345678901234567890123456789" + "012345678901234567890123456789" + "01\\x")); + // incomplete \DDD pattern (exactly 3 D's must appear) + checkBadTextName<BadEscape>("\\12abc"); + // \DDD must not exceed 255 + checkBadTextName<BadEscape>("\\256"); + // Same tests for \111 as for \\x above + checkBadTextName<TooLongLabel>("012345678901234567890123456789" + "012345678901234567890123456789" + "012\\111"); + EXPECT_NO_THROW(Name("012345678901234567890123456789" + "012345678901234567890123456789" + "01\\111")); + // A domain name must be 255 octets or less + checkBadTextName<TooLongName>("123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789." + "123456789.1234"); + // This is a possible longest name and should be accepted + EXPECT_NO_THROW(Name(string(max_len_str))); + // \DDD must consist of 3 digits. + checkBadTextName<IncompleteName>("\\12"); + + // a name with the max number of labels. should be constructed without + // an error, and its length should be the max value. + Name maxlabels = Name(string(max_labels_str)); + EXPECT_EQ(Name::MAX_LABELS, maxlabels.getLabelCount()); +} + +// The following test uses a name data that was produced by +// fuzz testing and causes an unexpected condition in stringParser. +// Formerly this condition was trapped by an assert, but for +// robustness it has been replaced by a throw. +TEST_F(NameTest, unexpectedParseError) { + std::vector<uint8_t> badname { + 0xff,0xff,0x7f,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00, + 0x00,0x00,0x04,0x63,0x82,0x53,0x63,0x35,0x01,0x01,0x3d,0x07,0x01,0x00,0x00,0x00, + 0x00,0x00,0x00,0x19,0x0c,0x4e,0x01,0x00,0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x35,0x01,0x05,0x3a,0x04,0x00,0x00,0x07,0x08,0x3b,0x04,0x00, + 0x00,0x2e,0x3b,0x04,0x00,0x19,0x2e,0x00,0x00,0x00,0x0a,0x00,0x12,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x0b,0x82,0x01,0xfc,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x35,0x01,0x05,0x3a,0x04,0x00,0x00,0x07,0x08,0x3b,0x04, + 0x00,0x00,0x2e,0x3b,0x04,0x00,0x19,0x2e,0x56,0x00,0x00,0x0a,0x00,0x12,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x0b,0x82,0x01,0xfc,0x42,0x00,0x00,0x00,0x00,0x19,0x0c, + 0x4e,0x01,0x05,0x3a,0x04,0xde,0x00,0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x35,0x01,0x05,0x3a,0x07,0x08,0x3b,0x04,0x00,0x00,0x2e,0x3b,0x04, + 0x00,0x19,0x2e,0x56,0x40,0x00,0x00,0x00,0x00,0x00,0x0a,0x00,0x12,0x00,0x00,0x00, + 0x00,0x00,0x19,0x00,0x0b,0x82,0x01,0xfc,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x35,0x01,0x05,0xff,0xff,0x05,0x00,0x07,0x08,0x3b,0x04, + 0x00,0x00,0x2e,0x3b + }; + + std::string badnamestr(badname.begin(), badname.end()); + EXPECT_THROW(Name(badnamestr, false), Unexpected); +} + +// on the rest while we prepare it. +// Check the @ syntax is accepted and it just copies the origin. +TEST_F(NameTest, copyOrigin) { + EXPECT_EQ(origin_name, Name("@", 1, &origin_name)); + // The downcase works on the origin too. But only when we provide it. + EXPECT_EQ(origin_name, Name("@", 1, &origin_name_upper, true)); + EXPECT_EQ(origin_name_upper, Name("@", 1, &origin_name_upper, true)); + // If we don't provide the origin, it throws + EXPECT_THROW(Name("@", 1, NULL), MissingNameOrigin); +} + +// Test the master-file constructor does not append the origin when the +// provided name is absolute +TEST_F(NameTest, dontAppendOrigin) { + EXPECT_EQ(example_name, Name("www.example.com.", 16, &origin_name)); + // The downcase works (only if provided, though) + EXPECT_EQ(example_name, Name("WWW.EXAMPLE.COM.", 16, &origin_name, true)); + EXPECT_EQ(example_name_upper, Name("WWW.EXAMPLE.COM.", 16, &origin_name)); + // And it does not require the origin to be provided + EXPECT_NO_THROW(Name("www.example.com.", 16, NULL)); +} + +// Test the master-file constructor properly appends the origin when +// the provided name is relative. +TEST_F(NameTest, appendOrigin) { + EXPECT_EQ(example_name, Name("www", 3, &origin_name)); + // Check the downcase works (if provided) + EXPECT_EQ(example_name, Name("WWW", 3, &origin_name, true)); + EXPECT_EQ(example_name, Name("WWW", 3, &origin_name_upper, true)); + EXPECT_EQ(example_name_upper, Name("WWW", 3, &origin_name_upper)); + // Check we can prepend more than one label + EXPECT_EQ(Name("a.b.c.d.example.com."), Name("a.b.c.d", 7, &origin_name)); + // When the name is relative, we throw. + EXPECT_THROW(Name("www", 3, NULL), MissingNameOrigin); +} + +// When we don't provide the data, it throws +TEST_F(NameTest, noDataProvided) { + EXPECT_THROW(Name(NULL, 10, NULL), isc::InvalidParameter); + EXPECT_THROW(Name(NULL, 10, &origin_name), isc::InvalidParameter); + EXPECT_THROW(Name("www", 0, NULL), isc::InvalidParameter); + EXPECT_THROW(Name("www", 0, &origin_name), isc::InvalidParameter); +} + +// When we combine the first part and the origin together, the resulting name +// is too long. It should throw. Other test checks this is valid when alone +// (without the origin appended). +TEST_F(NameTest, combinedTooLong) { + EXPECT_THROW(Name(max_len_str, strlen(max_len_str), &origin_name), + TooLongName); + EXPECT_THROW(Name(max_labels_str, strlen(max_labels_str), &origin_name), + TooLongName); + // Appending the root should be OK + EXPECT_NO_THROW(Name(max_len_str, strlen(max_len_str), + &Name::ROOT_NAME())); + EXPECT_NO_THROW(Name(max_labels_str, strlen(max_labels_str), + &Name::ROOT_NAME())); +} + +// Test the handling of @ in the name. If it is alone, it is the origin (when +// it exists) or the root. If it is somewhere else, it has no special meaning. +TEST_F(NameTest, atSign) { + // If it is alone, it is the origin + EXPECT_EQ(origin_name, Name("@", 1, &origin_name)); + EXPECT_THROW(Name("@", 1, NULL), MissingNameOrigin); + EXPECT_EQ(Name::ROOT_NAME(), Name("@")); + + // It is not alone. It is taken verbatim. We check the name converted + // back to the textual form, since checking it against other name object + // may be wrong -- if we create it wrong the same way as the tested + // object. + EXPECT_EQ("\\@.", Name("@.").toText()); + EXPECT_EQ("\\@.", Name("@.", 2, NULL).toText()); + EXPECT_EQ("\\@something.", Name("@something").toText()); + EXPECT_EQ("something\\@.", Name("something@").toText()); + EXPECT_EQ("\\@x.example.com.", Name("@x", 2, &origin_name).toText()); + EXPECT_EQ("x\\@.example.com.", Name("x@", 2, &origin_name).toText()); + + // An escaped at-sign isn't active + EXPECT_EQ("\\@.", Name("\\@").toText()); + EXPECT_EQ("\\@.example.com.", Name("\\@", 2, &origin_name).toText()); +} + +TEST_F(NameTest, fromWire) { + // + // test cases derived from BIND9 tests. + // + // normal case with a compression pointer + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, + nameFactoryFromWire("name_fromWire1", 25), + Name("vix.com")); + // bogus label character (looks like a local compression pointer) + EXPECT_THROW(nameFactoryFromWire("name_fromWire2", 25), DNSMessageFORMERR); + // a bad compression pointer (too big) + EXPECT_THROW(nameFactoryFromWire("name_fromWire3_1", 25), + DNSMessageFORMERR); + // forward reference + EXPECT_THROW(nameFactoryFromWire("name_fromWire3_2", 25), + DNSMessageFORMERR); + // invalid name length + EXPECT_THROW(nameFactoryFromWire("name_fromWire4", 550), DNSMessageFORMERR); + + // skip test for from Wire5. It's for disabling decompression, but our + // implementation always allows it. + + // bad pointer (too big) + EXPECT_THROW(nameFactoryFromWire("name_fromWire6", 25), DNSMessageFORMERR); + // input ends unexpectedly + EXPECT_THROW(nameFactoryFromWire("name_fromWire7", 25), DNSMessageFORMERR); + // many hops of compression but valid. should succeed. + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, + nameFactoryFromWire("name_fromWire8", 383), + Name("vix.com")); + + // + // Additional test cases + // + + // large names, a long but valid one, and invalid (too long) one. + EXPECT_EQ(Name::MAX_WIRE, + nameFactoryFromWire("name_fromWire9", 0).getLength()); + EXPECT_THROW(nameFactoryFromWire("name_fromWire10", 0).getLength(), + DNSMessageFORMERR); + + // A name with possible maximum number of labels; awkward but valid + EXPECT_EQ(nameFactoryFromWire("name_fromWire11", 0).getLabelCount(), + Name::MAX_LABELS); + + // Wire format including an invalid label length + EXPECT_THROW(nameFactoryFromWire("name_fromWire12", 0), DNSMessageFORMERR); + + // converting upper-case letters to down-case + EXPECT_EQ("vix.com.", + nameFactoryFromWire("name_fromWire1", 25, true).toText()); + EXPECT_EQ(3, nameFactoryFromWire("name_fromWire1", 25).getLabelCount()); +} + +TEST_F(NameTest, copyConstruct) { + Name copy(example_name); + EXPECT_EQ(copy, example_name); + + // Check the copied data is valid even after the original is deleted + Name* copy2 = new Name(example_name); + Name copy3(*copy2); + delete copy2; + EXPECT_EQ(copy3, example_name); +} + +TEST_F(NameTest, assignment) { + Name copy("."); + copy = example_name; + EXPECT_EQ(copy, example_name); + + // Check if the copied data is valid even after the original is deleted + Name* copy2 = new Name(example_name); + Name copy3("."); + copy3 = *copy2; + delete copy2; + EXPECT_EQ(copy3, example_name); + + // Self assignment + copy = *© + EXPECT_EQ(example_name, copy); +} + +TEST_F(NameTest, toText) { + // tests derived from BIND9 + EXPECT_EQ("a.b.c.d", Name("a.b.c.d").toText(true)); + EXPECT_EQ("a.\\\\[[.c.d", Name("a.\\\\[\\[.c.d").toText(true)); + EXPECT_EQ("a.b.C.d.", Name("a.b.C.d").toText(false)); + EXPECT_EQ("a.b.", Name("a.b.").toText(false)); + + // test omit_final_dot. It's false by default. + EXPECT_EQ("a.b.c.d", Name("a.b.c.d.").toText(true)); + EXPECT_EQ(Name("a.b.").toText(false), Name("a.b.").toText()); + + // the root name is a special case: omit_final_dot will be ignored. + EXPECT_EQ(".", Name(".").toText(true)); + + // test all printable characters to see whether special characters are + // escaped while the others are intact. note that the conversion is + // implementation specific; for example, it's not invalid to escape a + // "normal" character such as 'a' with regard to the standard. + string all_printable("!\\\"#\\$%&'\\(\\)*+,-\\./0123456789:\\;<=>?\\@" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "[\\\\]^_.`abcdefghijklmnopqrstuvwxyz{|}~."); + EXPECT_EQ(all_printable, + nameFactoryFromWire("name_fromWire13", 0).toText()); + + string all_nonprintable( + "\\000\\001\\002\\003\\004\\005\\006\\007\\008\\009" + "\\010\\011\\012\\013\\014\\015\\016\\017\\018\\019" + "\\020\\021\\022\\023\\024\\025\\026\\027\\028\\029" + "\\030\\031\\032\\127\\128\\129" + "\\130\\131\\132\\133\\134\\135\\136\\137\\138\\139" + "\\140\\141\\142\\143\\144\\145\\146\\147\\148\\149" + "\\150\\151\\152\\153\\154\\155\\156." + "\\157\\158\\159" + "\\160\\161\\162\\163\\164\\165\\166\\167\\168\\169" + "\\170\\171\\172\\173\\174\\175\\176\\177\\178\\179" + "\\180\\181\\182\\183\\184\\185\\186\\187\\188\\189" + "\\190\\191\\192\\193\\194\\195\\196\\197\\198\\199" + "\\200\\201\\202\\203\\204\\205\\206\\207\\208\\209" + "\\210\\211\\212\\213\\214\\215\\216\\217\\218\\219." + "\\220\\221\\222\\223\\224\\225\\226\\227\\228\\229" + "\\230\\231\\232\\233\\234\\235\\236\\237\\238\\239" + "\\240\\241\\242\\243\\244\\245\\246\\247\\248\\249" + "\\250\\251\\252\\253\\254\\255."); + EXPECT_EQ(all_nonprintable, + nameFactoryFromWire("name_fromWire14", 0).toText()); +} + +TEST_F(NameTest, toWireBuffer) { + vector<unsigned char> data; + OutputBuffer buffer(0); + + UnitTestUtil::readWireData(string("01610376697803636f6d00"), data); + Name("a.vix.com.").toWire(buffer); + matchWireData(&data[0], data.size(), + buffer.getData(), buffer.getLength()); +} + +// +// We test various corner cases in Renderer tests, but add this test case +// to fill the code coverage gap. +// +TEST_F(NameTest, toWireRenderer) { + vector<unsigned char> data; + MessageRenderer renderer; + + UnitTestUtil::readWireData(string("01610376697803636f6d00"), data); + Name("a.vix.com.").toWire(renderer); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +// +// Helper class to hold comparison test parameters. +// +struct CompareParameters { + CompareParameters(const Name& n1, const Name& n2, + NameComparisonResult::NameRelation r, int o, + unsigned int l) : + name1(n1), name2(n2), reln(r), order(o), labels(l) {} + static int normalizeOrder(int o) + { + if (o > 0) { + return (1); + } else if (o < 0) { + return (-1); + } + return (0); + } + Name name1; + Name name2; + NameComparisonResult::NameRelation reln; + int order; + unsigned int labels; +}; + +TEST_F(NameTest, compare) { + vector<CompareParameters> params; + params.push_back(CompareParameters(Name("c.d"), Name("a.b.c.d"), + NameComparisonResult::SUPERDOMAIN, + -1, 3)); + params.push_back(CompareParameters(Name("a.b.c.d"), Name("c.d"), + NameComparisonResult::SUBDOMAIN, 1, 3)); + params.push_back(CompareParameters(Name("a.b.c.d"), Name("c.d.e.f"), + NameComparisonResult::COMMONANCESTOR, + -1, 1)); + params.push_back(CompareParameters(Name("a.b.c.d"), Name("f.g.c.d"), + NameComparisonResult::COMMONANCESTOR, + -1, 3)); + params.push_back(CompareParameters(Name("a.b.c.d"), Name("A.b.C.d."), + NameComparisonResult::EQUAL, + 0, 5)); + + vector<CompareParameters>::const_iterator it; + for (it = params.begin(); it != params.end(); ++it) { + NameComparisonResult result = (*it).name1.compare((*it).name2); + EXPECT_EQ((*it).reln, result.getRelation()); + EXPECT_EQ((*it).order, + CompareParameters::normalizeOrder(result.getOrder())); + EXPECT_EQ((*it).labels, result.getCommonLabels()); + } +} + +TEST_F(NameTest, equal) { + EXPECT_TRUE(example_name == Name("WWW.EXAMPLE.COM.")); + EXPECT_TRUE(example_name.equals(Name("WWW.EXAMPLE.COM."))); + EXPECT_TRUE(example_name != Name("www.example.org.")); + EXPECT_TRUE(example_name.nequals(Name("www.example.org."))); + // lengths don't match + EXPECT_TRUE(example_name != Name("www2.example.com.")); + EXPECT_TRUE(example_name.nequals(Name("www2.example.com."))); + // lengths are equal, but # of labels don't match (first test checks the + // prerequisite). + EXPECT_EQ(example_name.getLength(), Name("www\\.example.com.").getLength()); + EXPECT_TRUE(example_name != Name("www\\.example.com.")); + EXPECT_TRUE(example_name.nequals(Name("www\\.example.com."))); +} + +TEST_F(NameTest, isWildcard) { + EXPECT_FALSE(example_name.isWildcard()); + EXPECT_TRUE(Name("*.a.example.com").isWildcard()); + EXPECT_FALSE(Name("a.*.example.com").isWildcard()); +} + +TEST_F(NameTest, concatenate) { + NameComparisonResult result = + Name("aaa.www.example.com.").compare(Name("aaa").concatenate(example_name)); + EXPECT_EQ(NameComparisonResult::EQUAL, result.getRelation()); + + result = example_name.compare(Name(".").concatenate(example_name)); + EXPECT_EQ(NameComparisonResult::EQUAL, result.getRelation()); + + result = example_name.compare(example_name.concatenate(Name("."))); + EXPECT_EQ(NameComparisonResult::EQUAL, result.getRelation()); + + // concatenating two valid names would result in too long a name. + Name n1("123456789.123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789.123456789."); + Name n2("123456789.123456789.123456789.123456789.123456789." + "123456789.123456789.123456789.123456789.123456789." + "1234."); + EXPECT_THROW(n1.concatenate(n2), TooLongName); +} + +TEST_F(NameTest, reverse) { + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name.reverse(), + Name("com.example.www.")); + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, Name(".").reverse(), + Name(".")); + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, + Name("a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s").reverse(), + Name("s.r.q.p.o.n.m.l.k.j.i.h.g.f.e.d.c.b.a")); +} + +TEST_F(NameTest, split) { + // normal cases with or without explicitly specifying the trailing dot. + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name.split(1, 2), + Name("example.com.")); + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name.split(1, 3), + Name("example.com.")); + // edge cases: only the first or last label. + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name.split(0, 1), + Name("www.")); + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name.split(3, 1), + Name(".")); + // invalid range: an exception should be thrown. + EXPECT_THROW(example_name.split(1, 0), OutOfRange); + EXPECT_THROW(example_name.split(2, 3), OutOfRange); + + // invalid range: the following parameters would cause overflow, + // bypassing naive validation. + EXPECT_THROW(example_name.split(1, numeric_limits<unsigned int>::max()), + OutOfRange); +} + +TEST_F(NameTest, split_for_suffix) { + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name.split(1), + Name("example.com")); + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name.split(0), + example_name); + EXPECT_PRED_FORMAT2(UnitTestUtil::matchName, example_name.split(3), + Name(".")); + + // Invalid case: the level must be less than the original label count. + EXPECT_THROW(example_name.split(4), OutOfRange); +} + +TEST_F(NameTest, downcase) { + // usual case: all-upper case name to all-lower case + compareInWireFormat(example_name_upper.downcase(), example_name); + // confirm that non upper-case characters are intact + compareInWireFormat(nameFactoryLowerCase().downcase(), + nameFactoryLowerCase()); + // confirm the calling object is actually modified + example_name_upper.downcase(); + compareInWireFormat(example_name_upper, example_name); +} + +TEST_F(NameTest, at) { + // Confirm at() produces the exact sequence of wire-format name data + vector<uint8_t> data; + + for (size_t i = 0; i < example_name.getLength(); i++) { + data.push_back(example_name.at(i)); + } + + example_name.toWire(buffer_expected); + matchWireData(&data[0], data.size(), + buffer_expected.getData(), buffer_expected.getLength()); + + // Out-of-range access: should trigger an exception. + EXPECT_THROW(example_name.at(example_name.getLength()), OutOfRange); +} + +// +// The following set of tests confirm the result of <=, <, >=, > +// The test logic is simple, and all tests are just straightforward variations +// of the first one. +// +TEST_F(NameTest, leq) { + // small <= large is true + EXPECT_TRUE(small_name.leq(large_name)); + EXPECT_TRUE(small_name <= large_name); + + // small <= small is true + EXPECT_TRUE(small_name.leq(small_name)); + EXPECT_LE(small_name, small_name); + + // large <= small is false + EXPECT_FALSE(large_name.leq(small_name)); + EXPECT_FALSE(large_name <= small_name); +} + +TEST_F(NameTest, geq) { + EXPECT_TRUE(large_name.geq(small_name)); + EXPECT_TRUE(large_name >= small_name); + + EXPECT_TRUE(large_name.geq(large_name)); + EXPECT_GE(large_name, large_name); + + EXPECT_FALSE(small_name.geq(large_name)); + EXPECT_FALSE(small_name >= large_name); +} + +TEST_F(NameTest, lthan) { + EXPECT_TRUE(small_name.lthan(large_name)); + EXPECT_TRUE(small_name < large_name); + + EXPECT_FALSE(small_name.lthan(small_name)); + // cppcheck-suppress duplicateExpression + EXPECT_FALSE(small_name < small_name); + + EXPECT_FALSE(large_name.lthan(small_name)); + EXPECT_FALSE(large_name < small_name); +} + +TEST_F(NameTest, gthan) { + EXPECT_TRUE(large_name.gthan(small_name)); + EXPECT_TRUE(large_name > small_name); + + EXPECT_FALSE(large_name.gthan(large_name)); + // cppcheck-suppress duplicateExpression + EXPECT_FALSE(large_name > large_name); + + EXPECT_FALSE(small_name.gthan(large_name)); + EXPECT_FALSE(small_name > large_name); +} + +TEST_F(NameTest, constants) { + EXPECT_EQ(Name("."), Name::ROOT_NAME()); +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST_F(NameTest, LeftShiftOperator) { + ostringstream oss; + oss << example_name; + EXPECT_EQ(example_name.toText(), oss.str()); +} + +// The following verifies that toRawText() returns a string +// actual characters in place of escape sequences. We do not +// bother with an exhaustive set of tests here as this is +// not a primary use case. +TEST_F(NameTest, toRawText) { + Name n("a bc.$exa(m)ple.@org"); + EXPECT_EQ("a bc.$exa(m)ple.@org", n.toRawText(true)); + EXPECT_EQ("a bc.$exa(m)ple.@org.", n.toRawText(false)); + // Verify default value of omit parameter is false. + EXPECT_EQ("a bc.$exa(m)ple.@org.", n.toRawText()); +} + +} diff --git a/src/lib/dns/tests/nsec3hash_unittest.cc b/src/lib/dns/tests/nsec3hash_unittest.cc new file mode 100644 index 0000000..b47bb49 --- /dev/null +++ b/src/lib/dns/tests/nsec3hash_unittest.cc @@ -0,0 +1,269 @@ +// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> + +#include <gtest/gtest.h> + +#include <boost/scoped_ptr.hpp> + +#include <dns/nsec3hash.h> +#include <dns/labelsequence.h> +#include <dns/rdataclass.h> +#include <util/encode/hex.h> + +using boost::scoped_ptr; +using namespace std; +using namespace isc::dns; +using namespace isc::dns::rdata; +using namespace isc::util; +using namespace isc::util::encode; + +namespace { +typedef scoped_ptr<NSEC3Hash> NSEC3HashPtr; + +// Commonly used NSEC3 suffix, defined to reduce the amount of typing +const char* const nsec3_common = "2T7B4G4VSA5SMI47K61MV5BV1A22BOJR A RRSIG"; + +class NSEC3HashTest : public ::testing::Test { +protected: + NSEC3HashTest() : + test_hash(NSEC3Hash::create(generic::NSEC3PARAM("1 0 12 aabbccdd"))), + test_hash_nsec3(NSEC3Hash::create(generic::NSEC3 + ("1 0 12 aabbccdd " + + string(nsec3_common)))) + { + const uint8_t salt[] = {0xaa, 0xbb, 0xcc, 0xdd}; + test_hash_args.reset(NSEC3Hash::create(1, 12, salt, sizeof(salt))); + } + + ~NSEC3HashTest() { + // Make sure we reset the hash creator to the default + setNSEC3HashCreator(NULL); + } + + // An NSEC3Hash object commonly used in tests. Parameters are borrowed + // from the RFC5155 example. Construction of this object implicitly + // checks a successful case of the creation. + NSEC3HashPtr test_hash; + + // Similar to test_hash, but created from NSEC3 RR. + NSEC3HashPtr test_hash_nsec3; + + // Similar to test_hash, but created from passed args. + NSEC3HashPtr test_hash_args; +}; + +TEST_F(NSEC3HashTest, unknownAlgorithm) { + EXPECT_THROW(NSEC3HashPtr( + NSEC3Hash::create( + generic::NSEC3PARAM("2 0 12 aabbccdd"))), + UnknownNSEC3HashAlgorithm); + EXPECT_THROW(NSEC3HashPtr( + NSEC3Hash::create( + generic::NSEC3("2 0 12 aabbccdd " + + string(nsec3_common)))), + UnknownNSEC3HashAlgorithm); + + const uint8_t salt[] = {0xaa, 0xbb, 0xcc, 0xdd}; + EXPECT_THROW(NSEC3HashPtr(NSEC3Hash::create(2, 12, salt, sizeof(salt))), + UnknownNSEC3HashAlgorithm); +} + +// Common checks for NSEC3 hash calculation +void +calculateCheck(NSEC3Hash& hash) { + // A couple of normal cases from the RFC5155 example. + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + hash.calculate(Name("example"))); + EXPECT_EQ("35MTHGPGCU1QG68FAB165KLNSNK3DPVL", + hash.calculate(Name("a.example"))); + + // Check case-insensitiveness + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + hash.calculate(Name("EXAMPLE"))); + + // Repeat for the LabelSequence variant. + + // A couple of normal cases from the RFC5155 example. + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + hash.calculate(LabelSequence(Name("example")))); + EXPECT_EQ("35MTHGPGCU1QG68FAB165KLNSNK3DPVL", + hash.calculate(LabelSequence(Name("a.example")))); + + // Check case-insensitiveness + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + hash.calculate(LabelSequence(Name("EXAMPLE")))); +} + +TEST_F(NSEC3HashTest, calculate) { + { + SCOPED_TRACE("calculate check with NSEC3PARAM based hash"); + calculateCheck(*test_hash); + } + { + SCOPED_TRACE("calculate check with NSEC3 based hash"); + calculateCheck(*test_hash_nsec3); + } + { + SCOPED_TRACE("calculate check with args based hash"); + calculateCheck(*test_hash_args); + } + + // Some boundary cases: 0-iteration and empty salt. Borrowed from the + // .com zone data. + EXPECT_EQ("CK0POJMG874LJREF7EFN8430QVIT8BSM", + NSEC3HashPtr(NSEC3Hash::create(generic::NSEC3PARAM("1 0 0 -"))) + ->calculate(Name("com"))); + EXPECT_EQ("CK0POJMG874LJREF7EFN8430QVIT8BSM", + NSEC3HashPtr(NSEC3Hash::create(generic::NSEC3PARAM("1 0 0 -"))) + ->calculate(LabelSequence(Name("com")))); + + // Using unusually large iterations, something larger than the 8-bit range. + // (expected hash value generated by BIND 9's dnssec-signzone) + EXPECT_EQ("COG6A52MJ96MNMV3QUCAGGCO0RHCC2Q3", + NSEC3HashPtr(NSEC3Hash::create( + generic::NSEC3PARAM("1 0 256 AABBCCDD"))) + ->calculate(LabelSequence(Name("example.org")))); +} + +// Common checks for match cases +template <typename RDATAType> +void +matchCheck(NSEC3Hash& hash, const string& postfix) { + // If all parameters match, it's considered to be matched. + EXPECT_TRUE(hash.match(RDATAType("1 0 12 aabbccdd" + postfix))); + + // Algorithm doesn't match + EXPECT_FALSE(hash.match(RDATAType("2 0 12 aabbccdd" + postfix))); + // Iterations doesn't match + EXPECT_FALSE(hash.match(RDATAType("1 0 1 aabbccdd" + postfix))); + // Salt doesn't match + EXPECT_FALSE(hash.match(RDATAType("1 0 12 aabbccde" + postfix))); + // Salt doesn't match: the other has an empty salt + EXPECT_FALSE(hash.match(RDATAType("1 0 12 -" + postfix))); + // Flags don't matter + EXPECT_TRUE(hash.match(RDATAType("1 1 12 aabbccdd" + postfix))); +} + +TEST_F(NSEC3HashTest, matchWithNSEC3) { + { + SCOPED_TRACE("match NSEC3PARAM based hash against NSEC3 parameters"); + matchCheck<generic::NSEC3>(*test_hash, " " + string(nsec3_common)); + } + { + SCOPED_TRACE("match NSEC3 based hash against NSEC3 parameters"); + matchCheck<generic::NSEC3>(*test_hash_nsec3, + " " + string(nsec3_common)); + } +} + +TEST_F(NSEC3HashTest, matchWithNSEC3PARAM) { + { + SCOPED_TRACE("match NSEC3PARAM based hash against NSEC3 parameters"); + matchCheck<generic::NSEC3PARAM>(*test_hash, ""); + } + { + SCOPED_TRACE("match NSEC3 based hash against NSEC3 parameters"); + matchCheck<generic::NSEC3PARAM>(*test_hash_nsec3, ""); + } +} + +// A simple faked hash calculator and a dedicated creator for it. +class TestNSEC3Hash : public NSEC3Hash { + virtual string calculate(const Name&) const { + return ("00000000000000000000000000000000"); + } + virtual string calculate(const LabelSequence&) const { + return ("00000000000000000000000000000000"); + } + virtual bool match(const generic::NSEC3PARAM&) const { + return (true); + } + virtual bool match(const generic::NSEC3&) const { + return (true); + } +}; + +// This faked creator basically creates the faked calculator regardless of +// the passed NSEC3PARAM or NSEC3. But if the most significant bit of flags +// is set, it will behave like the default creator. +class TestNSEC3HashCreator : public NSEC3HashCreator { +public: + virtual NSEC3Hash* create(const generic::NSEC3PARAM& param) const { + if ((param.getFlags() & 0x80) != 0) { + return (default_creator_.create(param)); + } + return (new TestNSEC3Hash); + } + virtual NSEC3Hash* create(const generic::NSEC3& nsec3) const { + if ((nsec3.getFlags() & 0x80) != 0) { + return (default_creator_.create(nsec3)); + } + return (new TestNSEC3Hash); + } + virtual NSEC3Hash* create(uint8_t, uint16_t, + const uint8_t*, size_t) const { + isc_throw(isc::Unexpected, + "This method is not implemented here."); + } +private: + DefaultNSEC3HashCreator default_creator_; +}; + +TEST_F(NSEC3HashTest, setCreator) { + // Re-check an existing case using the default creator/hash implementation + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + test_hash->calculate(Name("example"))); + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + test_hash->calculate(LabelSequence(Name("example")))); + + // Replace the creator, and confirm the hash values are faked + TestNSEC3HashCreator test_creator; + setNSEC3HashCreator(&test_creator); + // Re-create the hash object with the new creator + test_hash.reset(NSEC3Hash::create(generic::NSEC3PARAM("1 0 12 aabbccdd"))); + EXPECT_EQ("00000000000000000000000000000000", + test_hash->calculate(Name("example"))); + EXPECT_EQ("00000000000000000000000000000000", + test_hash->calculate(LabelSequence(Name("example")))); + // Same for hash from NSEC3 RDATA + test_hash.reset(NSEC3Hash::create(generic::NSEC3 + ("1 0 12 aabbccdd " + + string(nsec3_common)))); + EXPECT_EQ("00000000000000000000000000000000", + test_hash->calculate(Name("example"))); + EXPECT_EQ("00000000000000000000000000000000", + test_hash->calculate(LabelSequence(Name("example")))); + + // If we set a special flag big (0x80) on creation, it will act like the + // default creator. + test_hash.reset(NSEC3Hash::create(generic::NSEC3PARAM( + "1 128 12 aabbccdd"))); + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + test_hash->calculate(Name("example"))); + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + test_hash->calculate(LabelSequence(Name("example")))); + test_hash.reset(NSEC3Hash::create(generic::NSEC3 + ("1 128 12 aabbccdd " + + string(nsec3_common)))); + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + test_hash->calculate(Name("example"))); + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + test_hash->calculate(LabelSequence(Name("example")))); + + // Reset the creator to default, and confirm that + setNSEC3HashCreator(NULL); + test_hash.reset(NSEC3Hash::create(generic::NSEC3PARAM("1 0 12 aabbccdd"))); + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + test_hash->calculate(Name("example"))); + EXPECT_EQ("0P9MHAVEQVM6T7VBL5LOP2U3T2RP3TOM", + test_hash->calculate(LabelSequence(Name("example")))); +} + +} // end namespace diff --git a/src/lib/dns/tests/opcode_unittest.cc b/src/lib/dns/tests/opcode_unittest.cc new file mode 100644 index 0000000..9bc60b5 --- /dev/null +++ b/src/lib/dns/tests/opcode_unittest.cc @@ -0,0 +1,100 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <vector> +#include <sstream> + +#include <exceptions/exceptions.h> + +#include <dns/opcode.h> + +#include <gtest/gtest.h> + +using namespace std; +using namespace isc::dns; + +namespace { +TEST(OpcodeTest, construct) { + // This test also tests getCode() + EXPECT_EQ(0, Opcode(0).getCode()); + EXPECT_EQ(15, Opcode(Opcode::RESERVED15_CODE).getCode()); + + EXPECT_THROW(Opcode(16), isc::OutOfRange); +} + +TEST(OpcodeTest, constants) { + // We'll only test arbitrarily chosen subsets of the codes. + // This class is quite simple, so it should be suffice. + + EXPECT_EQ(Opcode::QUERY_CODE, Opcode(0).getCode()); + EXPECT_EQ(Opcode::IQUERY_CODE, Opcode(1).getCode()); + EXPECT_EQ(Opcode::NOTIFY_CODE, Opcode(4).getCode()); + EXPECT_EQ(Opcode::UPDATE_CODE, Opcode(5).getCode()); + EXPECT_EQ(Opcode::RESERVED15_CODE, Opcode(15).getCode()); + + EXPECT_EQ(Opcode::QUERY_CODE, Opcode::QUERY().getCode()); + EXPECT_EQ(Opcode::IQUERY_CODE, Opcode::IQUERY().getCode()); + EXPECT_EQ(Opcode::NOTIFY_CODE, Opcode::NOTIFY().getCode()); + EXPECT_EQ(Opcode::UPDATE_CODE, Opcode::UPDATE().getCode()); + EXPECT_EQ(Opcode::RESERVED15_CODE, Opcode::RESERVED15().getCode()); +} + +TEST(OpcodeTest, equal) { + EXPECT_TRUE(Opcode::QUERY() == Opcode(Opcode::QUERY_CODE)); + EXPECT_TRUE(Opcode::QUERY().equals(Opcode(Opcode::QUERY_CODE))); + EXPECT_TRUE(Opcode::IQUERY() == Opcode(Opcode::IQUERY_CODE)); + EXPECT_TRUE(Opcode::IQUERY().equals(Opcode(Opcode::IQUERY_CODE))); + EXPECT_TRUE(Opcode::NOTIFY() == Opcode(Opcode::NOTIFY_CODE)); + EXPECT_TRUE(Opcode::NOTIFY().equals(Opcode(Opcode::NOTIFY_CODE))); + EXPECT_TRUE(Opcode::UPDATE() == Opcode(Opcode::UPDATE_CODE)); + EXPECT_TRUE(Opcode::UPDATE().equals(Opcode(Opcode::UPDATE_CODE))); + EXPECT_TRUE(Opcode::RESERVED15() == Opcode(Opcode::RESERVED15())); + EXPECT_TRUE(Opcode::RESERVED15().equals(Opcode(Opcode::RESERVED15()))); +} + +TEST(OpcodeTest, nequal) { + EXPECT_TRUE(Opcode::QUERY() != Opcode::IQUERY()); + EXPECT_TRUE(Opcode::QUERY().nequals(Opcode::IQUERY())); + EXPECT_TRUE(Opcode::NOTIFY() != Opcode(1)); + EXPECT_TRUE(Opcode::NOTIFY().nequals(Opcode(1))); + EXPECT_TRUE(Opcode(10) != Opcode(11)); + EXPECT_TRUE(Opcode(10).nequals(Opcode(11))); +} + +TEST(OpcodeTest, toText) { + vector<const char*> expects; + expects.resize(Opcode::RESERVED15_CODE + 1); + expects[Opcode::QUERY_CODE] = "QUERY"; + expects[Opcode::IQUERY_CODE] = "IQUERY"; + expects[Opcode::STATUS_CODE] = "STATUS"; + expects[Opcode::RESERVED3_CODE] = "RESERVED3"; + expects[Opcode::NOTIFY_CODE] = "NOTIFY"; + expects[Opcode::UPDATE_CODE] = "UPDATE"; + expects[Opcode::RESERVED6_CODE] = "RESERVED6"; + expects[Opcode::RESERVED7_CODE] = "RESERVED7"; + expects[Opcode::RESERVED8_CODE] = "RESERVED8"; + expects[Opcode::RESERVED9_CODE] = "RESERVED9"; + expects[Opcode::RESERVED10_CODE] = "RESERVED10"; + expects[Opcode::RESERVED11_CODE] = "RESERVED11"; + expects[Opcode::RESERVED12_CODE] = "RESERVED12"; + expects[Opcode::RESERVED13_CODE] = "RESERVED13"; + expects[Opcode::RESERVED14_CODE] = "RESERVED14"; + expects[Opcode::RESERVED15_CODE] = "RESERVED15"; + + for (unsigned int i = 0; i <= Opcode::RESERVED15_CODE; ++i) { + EXPECT_EQ(expects.at(i), Opcode(i).toText()); + } +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST(OpcodeTest, LeftShiftOperator) { + ostringstream oss; + oss << Opcode::NOTIFY(); + EXPECT_EQ(Opcode::NOTIFY().toText(), oss.str()); +} +} diff --git a/src/lib/dns/tests/qid_gen_unittest.cc b/src/lib/dns/tests/qid_gen_unittest.cc new file mode 100644 index 0000000..20a2dfa --- /dev/null +++ b/src/lib/dns/tests/qid_gen_unittest.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2011-2021 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/// \brief Test of QidGenerator +/// + +#include <config.h> + +#include <gtest/gtest.h> + +#include <dns/qid_gen.h> + +using namespace isc::dns; + +// Tests the operation of the Qid generator + +// Check that getInstance returns a singleton +TEST(QidGenerator, singleton) { + QidGenerator& g1 = QidGenerator::getInstance(); + QidGenerator& g2 = QidGenerator::getInstance(); + + EXPECT_TRUE(&g1 == &g2); +} + +TEST(QidGenerator, generate) { + // We'll assume that cryptolink's generator is 'good enough', and won't + // do full statistical checking here. Let's just call it the xkcd + // test (http://xkcd.com/221/), and check if three consecutive + // generates are not all the same. + uint16_t one, two, three; + QidGenerator& gen = QidGenerator::getInstance(); + one = gen.generateQid(); + two = gen.generateQid(); + three = gen.generateQid(); + ASSERT_FALSE((one == two) && (one == three)); +} diff --git a/src/lib/dns/tests/question_unittest.cc b/src/lib/dns/tests/question_unittest.cc new file mode 100644 index 0000000..03d31b1 --- /dev/null +++ b/src/lib/dns/tests/question_unittest.cc @@ -0,0 +1,196 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <vector> +#include <sstream> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/name.h> +#include <dns/question.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class QuestionTest : public ::testing::Test { +protected: + QuestionTest() : obuffer(0), + example_name1(Name("foo.example.com")), + example_name2(Name("bar.example.com")), + test_question1(example_name1, RRClass::IN(), + RRType::NS()), + test_question2(example_name2, RRClass::CH(), + RRType::A()) + {} + OutputBuffer obuffer; + MessageRenderer renderer; + Name example_name1; + Name example_name2; + Question test_question1; + Question test_question2; + vector<unsigned char> wiredata; +}; + +Question +questionFromWire(const char* datafile, size_t position = 0) { + vector<unsigned char> data; + UnitTestUtil::readWireData(datafile, data); + + InputBuffer buffer(&data[0], data.size()); + buffer.setPosition(position); + + return (Question(buffer)); +} + +TEST_F(QuestionTest, fromWire) { + Question q = questionFromWire("question_fromWire"); + + EXPECT_EQ(example_name1, q.getName()); + EXPECT_EQ(RRClass::IN(), q.getClass()); + EXPECT_EQ(RRType::NS(), q.getType()); + + // owner name of the second Question is compressed. It's uncommon + // (to have multiple questions), but isn't prohibited by the protocol. + q = questionFromWire("question_fromWire", 21); + EXPECT_EQ(example_name2, q.getName()); + EXPECT_EQ(RRClass::CH(), q.getClass()); + EXPECT_EQ(RRType::A(), q.getType()); + + // Pathological cases: Corresponding exceptions will be thrown from + // the underlying parser. + EXPECT_THROW(questionFromWire("question_fromWire", 31), DNSMessageFORMERR); + EXPECT_THROW(questionFromWire("question_fromWire", 36), IncompleteRRClass); +} + +TEST_F(QuestionTest, toText) { + EXPECT_EQ("foo.example.com. IN NS", test_question1.toText()); + EXPECT_EQ("bar.example.com. CH A", test_question2.toText()); + + EXPECT_EQ("foo.example.com. IN NS", test_question1.toText(false)); + EXPECT_EQ("bar.example.com. CH A", test_question2.toText(false)); + + EXPECT_EQ("foo.example.com. IN NS\n", test_question1.toText(true)); + EXPECT_EQ("bar.example.com. CH A\n", test_question2.toText(true)); +} + +TEST_F(QuestionTest, toWireBuffer) { + test_question1.toWire(obuffer); + test_question2.toWire(obuffer); + UnitTestUtil::readWireData("question_toWire1", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(QuestionTest, toWireRenderer) { + test_question1.toWire(renderer); + test_question2.toWire(renderer); + UnitTestUtil::readWireData("question_toWire2", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(QuestionTest, toWireTruncated) { + // If the available length in the renderer is too small, it would require + // truncation. This won't happen in normal cases, but protocol wise it + // could still happen if and when we support some (possibly future) opcode + // that allows multiple questions. + + // Set the length limit to the qname length so that the whole question + // would request truncated + renderer.setLengthLimit(example_name1.getLength()); + + EXPECT_FALSE(renderer.isTruncated()); // check pre-render condition + EXPECT_EQ(0, test_question1.toWire(renderer)); + EXPECT_TRUE(renderer.isTruncated()); + EXPECT_EQ(0, renderer.getLength()); // renderer shouldn't have any data +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST_F(QuestionTest, LeftShiftOperator) { + ostringstream oss; + oss << test_question1; + EXPECT_EQ(test_question1.toText(), oss.str()); +} + +TEST_F(QuestionTest, comparison) { + const Name a("a"), b("b"); + const RRClass in(RRClass::IN()), ch(RRClass::CH()); + const RRType ns(RRType::NS()), aaaa(RRType::AAAA()); + + EXPECT_TRUE(Question(a, in, ns) < Question(a, in, aaaa)); + EXPECT_FALSE(Question(a, in, aaaa) < Question(a, in, ns)); + + EXPECT_TRUE(Question(a, in, ns) < Question(a, ch, ns)); + EXPECT_FALSE(Question(a, ch, ns) < Question(a, in, ns)); + + EXPECT_TRUE(Question(a, in, ns) < Question(a, ch, aaaa)); + EXPECT_FALSE(Question(a, ch, aaaa) < Question(a, in, ns)); + + EXPECT_TRUE(Question(a, in, ns) < Question(b, in, ns)); + EXPECT_FALSE(Question(a, in, ns) < Question(a, in, ns)); + + EXPECT_TRUE(Question(a, in, ns) < Question(b, ch, ns)); + EXPECT_FALSE(Question(b, ch, ns) < Question(a, in, ns)); + + EXPECT_TRUE(Question(a, in, ns) < Question(b, ch, aaaa)); + EXPECT_FALSE(Question(b, ch, aaaa) < Question(a, in, ns)); + + EXPECT_FALSE(Question(a, in, ns) < Question(a, in, ns)); + EXPECT_FALSE(Question(a, ch, ns) < Question(a, ch, ns)); + EXPECT_FALSE(Question(b, in, ns) < Question(b, in, ns)); + EXPECT_FALSE(Question(b, in, aaaa) < Question(b, in, aaaa)); + + // Identical questions are equal + + EXPECT_TRUE(Question(a, in, ns) == Question(a, in, ns)); + EXPECT_FALSE(Question(a, in, ns) != Question(a, in, ns)); + + // Components differing by one component are unequal... + + EXPECT_FALSE(Question(b, in, ns) == Question(a, in, ns)); + EXPECT_TRUE(Question(b, in, ns) != Question(a, in, ns)); + + EXPECT_FALSE(Question(a, ch, ns) == Question(a, in, ns)); + EXPECT_TRUE(Question(a, ch, ns) != Question(a, in, ns)); + + EXPECT_FALSE(Question(a, in, aaaa) == Question(a, in, ns)); + EXPECT_TRUE(Question(a, in, aaaa) != Question(a, in, ns)); + + // ... as are those differing by two components + + EXPECT_FALSE(Question(b, ch, ns) == Question(a, in, ns)); + EXPECT_TRUE(Question(b, ch, ns) != Question(a, in, ns)); + + EXPECT_FALSE(Question(b, in, aaaa) == Question(a, in, ns)); + EXPECT_TRUE(Question(b, in, aaaa) != Question(a, in, ns)); + + EXPECT_FALSE(Question(a, ch, aaaa) == Question(a, in, ns)); + EXPECT_TRUE(Question(a, ch, aaaa) != Question(a, in, ns)); + + // ... and question differing by all three + + EXPECT_FALSE(Question(b, ch, aaaa) == Question(a, in, ns)); + EXPECT_TRUE(Question(b, ch, aaaa) != Question(a, in, ns)); + +} + +} diff --git a/src/lib/dns/tests/rcode_unittest.cc b/src/lib/dns/tests/rcode_unittest.cc new file mode 100644 index 0000000..220248f --- /dev/null +++ b/src/lib/dns/tests/rcode_unittest.cc @@ -0,0 +1,126 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <vector> +#include <sstream> + +#include <exceptions/exceptions.h> + +#include <dns/rcode.h> + +#include <gtest/gtest.h> + +using namespace std; +using namespace isc::dns; + +namespace { +TEST(RcodeTest, constructFromCode) { + // Normal cases. This test also tests getCode() + EXPECT_EQ(0, Rcode(0).getCode()); + EXPECT_EQ(0xfff, Rcode(0xfff).getCode()); // possible max code + + // should fail on attempt of construction with an out of range code + EXPECT_THROW(Rcode(0x1000), isc::OutOfRange); + EXPECT_THROW(Rcode(0xffff), isc::OutOfRange); +} + +TEST(RcodeTest, constructFromCodePair) { + EXPECT_EQ(3, Rcode(Rcode::NXDOMAIN_CODE, 0).getCode()); + EXPECT_EQ(Rcode::BADVERS_CODE, Rcode(0, 1).getCode()); + EXPECT_EQ(0xfff, Rcode(0xf, 0xff).getCode()); + EXPECT_THROW(Rcode(0x10, 0xff), isc::OutOfRange); +} + +TEST(RcodeTest, getExtendedCode) { + EXPECT_EQ(0, Rcode::NOERROR().getExtendedCode()); + EXPECT_EQ(0, Rcode::YXRRSET().getExtendedCode()); + EXPECT_EQ(1, Rcode::BADVERS().getExtendedCode()); + EXPECT_EQ(0xab, Rcode(0xabf).getExtendedCode()); + EXPECT_EQ(0xff, Rcode(0xfff).getExtendedCode()); +} + +TEST(RcodeTest, constants) { + // We'll only test arbitrarily chosen subsets of the codes. + // This class is quite simple, so it should be suffice. + + EXPECT_EQ(Rcode::NOERROR_CODE, Rcode(0).getCode()); + EXPECT_EQ(Rcode::FORMERR_CODE, Rcode(1).getCode()); + EXPECT_EQ(Rcode::NOTIMP_CODE, Rcode(4).getCode()); + EXPECT_EQ(Rcode::REFUSED_CODE, Rcode(5).getCode()); + EXPECT_EQ(Rcode::RESERVED15_CODE, Rcode(15).getCode()); + EXPECT_EQ(Rcode::BADVERS_CODE, Rcode(16).getCode()); + + EXPECT_EQ(Rcode::NOERROR_CODE, Rcode::NOERROR().getCode()); + EXPECT_EQ(Rcode::FORMERR_CODE, Rcode::FORMERR().getCode()); + EXPECT_EQ(Rcode::NOTIMP_CODE, Rcode::NOTIMP().getCode()); + EXPECT_EQ(Rcode::REFUSED_CODE, Rcode::REFUSED().getCode()); + EXPECT_EQ(Rcode::RESERVED15_CODE, Rcode::RESERVED15().getCode()); + EXPECT_EQ(Rcode::BADVERS_CODE, Rcode::BADVERS().getCode()); +} + +TEST(RcodeTest, equal) { + EXPECT_TRUE(Rcode::NOERROR() == Rcode(Rcode::NOERROR_CODE)); + EXPECT_TRUE(Rcode::NOERROR().equals(Rcode(Rcode::NOERROR_CODE))); + EXPECT_TRUE(Rcode::FORMERR() == Rcode(Rcode::FORMERR_CODE)); + EXPECT_TRUE(Rcode::FORMERR().equals(Rcode(Rcode::FORMERR_CODE))); + EXPECT_TRUE(Rcode::NOTIMP() == Rcode(Rcode::NOTIMP_CODE)); + EXPECT_TRUE(Rcode::NOTIMP().equals(Rcode(Rcode::NOTIMP_CODE))); + EXPECT_TRUE(Rcode::REFUSED() == Rcode(Rcode::REFUSED_CODE)); + EXPECT_TRUE(Rcode::REFUSED().equals(Rcode(Rcode::REFUSED_CODE))); + EXPECT_TRUE(Rcode::RESERVED15() == Rcode(Rcode::RESERVED15())); + EXPECT_TRUE(Rcode::RESERVED15().equals(Rcode(Rcode::RESERVED15()))); + EXPECT_TRUE(Rcode::BADVERS() == Rcode(Rcode::BADVERS_CODE)); + EXPECT_TRUE(Rcode::BADVERS().equals(Rcode(Rcode::BADVERS_CODE))); +} + +TEST(RcodeTest, nequal) { + EXPECT_TRUE(Rcode::NOERROR() != Rcode::FORMERR()); + EXPECT_TRUE(Rcode::NOERROR().nequals(Rcode::FORMERR())); + EXPECT_TRUE(Rcode::NOTIMP() != Rcode(1)); + EXPECT_TRUE(Rcode::NOTIMP().nequals(Rcode(1))); + EXPECT_TRUE(Rcode(10) != Rcode(11)); + EXPECT_TRUE(Rcode(10).nequals(Rcode(11))); +} + +TEST(RcodeTest, toText) { + vector<const char*> expects; + expects.resize(Rcode::BADVERS_CODE + 1); + expects[Rcode::NOERROR_CODE] = "NOERROR"; + expects[Rcode::FORMERR_CODE] = "FORMERR"; + expects[Rcode::SERVFAIL_CODE] = "SERVFAIL"; + expects[Rcode::NXDOMAIN_CODE] = "NXDOMAIN"; + expects[Rcode::NOTIMP_CODE] = "NOTIMP"; + expects[Rcode::REFUSED_CODE] = "REFUSED"; + expects[Rcode::YXDOMAIN_CODE] = "YXDOMAIN"; + expects[Rcode::YXRRSET_CODE] = "YXRRSET"; + expects[Rcode::NXRRSET_CODE] = "NXRRSET"; + expects[Rcode::NOTAUTH_CODE] = "NOTAUTH"; + expects[Rcode::NOTZONE_CODE] = "NOTZONE"; + expects[Rcode::RESERVED11_CODE] = "RESERVED11"; + expects[Rcode::RESERVED12_CODE] = "RESERVED12"; + expects[Rcode::RESERVED13_CODE] = "RESERVED13"; + expects[Rcode::RESERVED14_CODE] = "RESERVED14"; + expects[Rcode::RESERVED15_CODE] = "RESERVED15"; + expects[Rcode::BADVERS_CODE] = "BADVERS"; + + for (unsigned int i = 0; i <= Rcode::BADVERS_CODE; ++i) { + EXPECT_EQ(expects.at(i), Rcode(i).toText()); + } + + // Non well-known Rcodes + EXPECT_EQ("17", Rcode(Rcode::BADVERS().getCode() + 1).toText()); + EXPECT_EQ("4095", Rcode(Rcode(0xfff)).toText()); +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST(RcodeTest, LeftShiftOperator) { + ostringstream oss; + oss << Rcode::SERVFAIL(); + EXPECT_EQ(Rcode::SERVFAIL().toText(), oss.str()); +} +} diff --git a/src/lib/dns/tests/rdata_afsdb_unittest.cc b/src/lib/dns/tests/rdata_afsdb_unittest.cc new file mode 100644 index 0000000..26c3135 --- /dev/null +++ b/src/lib/dns/tests/rdata_afsdb_unittest.cc @@ -0,0 +1,235 @@ +// Copyright (C) 2011-2019 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +const char* const afsdb_text = "1 afsdb.example.com."; +const char* const afsdb_text2 = "0 root.example.com."; +const char* const too_long_label("012345678901234567890123456789" + "0123456789012345678901234567890123."); + +namespace { +class Rdata_AFSDB_Test : public RdataTest { +protected: + Rdata_AFSDB_Test() : + rdata_afsdb(string(afsdb_text)), rdata_afsdb2(string(afsdb_text2)) + {} + + const generic::AFSDB rdata_afsdb; + const generic::AFSDB rdata_afsdb2; + vector<uint8_t> expected_wire; +}; + + +TEST_F(Rdata_AFSDB_Test, createFromText) { + EXPECT_EQ(1, rdata_afsdb.getSubtype()); + EXPECT_EQ(Name("afsdb.example.com."), rdata_afsdb.getServer()); + + EXPECT_EQ(0, rdata_afsdb2.getSubtype()); + EXPECT_EQ(Name("root.example.com."), rdata_afsdb2.getServer()); +} + +TEST_F(Rdata_AFSDB_Test, badText) { + // subtype is too large + EXPECT_THROW(const generic::AFSDB rdata_afsdb("99999999 afsdb.example.com."), + InvalidRdataText); + // incomplete text + EXPECT_THROW(const generic::AFSDB rdata_afsdb("10"), InvalidRdataText); + EXPECT_THROW(const generic::AFSDB rdata_afsdb("SPOON"), InvalidRdataText); + EXPECT_THROW(const generic::AFSDB rdata_afsdb("1root.example.com."), InvalidRdataText); + // number of fields (must be 2) is incorrect + EXPECT_THROW(const generic::AFSDB rdata_afsdb("10 afsdb. example.com."), + InvalidRdataText); + // No origin and relative + EXPECT_THROW(const generic::AFSDB rdata_afsdb("1 afsdb.example.com"), + MissingNameOrigin); + // bad name + EXPECT_THROW(const generic::AFSDB rdata_afsdb("1 afsdb.example.com." + + string(too_long_label)), TooLongLabel); +} + +TEST_F(Rdata_AFSDB_Test, copy) { + const generic::AFSDB rdata_afsdb2(rdata_afsdb); + EXPECT_EQ(0, rdata_afsdb.compare(rdata_afsdb2)); +} + +TEST_F(Rdata_AFSDB_Test, assignment) { + generic::AFSDB copy((string(afsdb_text2))); + copy = rdata_afsdb; + EXPECT_EQ(0, copy.compare(rdata_afsdb)); + + // Check if the copied data is valid even after the original is deleted + generic::AFSDB* copy2 = new generic::AFSDB(rdata_afsdb); + generic::AFSDB copy3((string(afsdb_text2))); + copy3 = *copy2; + delete copy2; + EXPECT_EQ(0, copy3.compare(rdata_afsdb)); + + // Self assignment + copy = *© + EXPECT_EQ(0, copy.compare(rdata_afsdb)); +} + +TEST_F(Rdata_AFSDB_Test, createFromWire) { + // uncompressed names + EXPECT_EQ(0, rdata_afsdb.compare( + *rdataFactoryFromFile(RRType::AFSDB(), RRClass::IN(), + "rdata_afsdb_fromWire1.wire"))); + // compressed name + EXPECT_EQ(0, rdata_afsdb.compare( + *rdataFactoryFromFile(RRType::AFSDB(), RRClass::IN(), + "rdata_afsdb_fromWire2.wire", 13))); + // RDLENGTH is too short + EXPECT_THROW(rdataFactoryFromFile(RRType::AFSDB(), RRClass::IN(), + "rdata_afsdb_fromWire3.wire"), + InvalidRdataLength); + // RDLENGTH is too long + EXPECT_THROW(rdataFactoryFromFile(RRType::AFSDB(), RRClass::IN(), + "rdata_afsdb_fromWire4.wire"), + InvalidRdataLength); + // bogus server name, the error should be detected in the name + // constructor + EXPECT_THROW(rdataFactoryFromFile(RRType::AFSDB(), RRClass::IN(), + "rdata_afsdb_fromWire5.wire"), + DNSMessageFORMERR); +} + +TEST_F(Rdata_AFSDB_Test, createFromLexer) { + EXPECT_EQ(0, rdata_afsdb.compare( + *test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(), + afsdb_text))); + + // test::createRdataUsingLexer() constructs relative to + // "example.org." origin. + generic::AFSDB tmp = generic::AFSDB("1 afsdb2.example.org."); + EXPECT_EQ(0, tmp.compare( + *test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(), + "1 afsdb2"))); + + // Exceptions cause NULL to be returned. + EXPECT_FALSE(test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(), + "1root.example.com.")); + + // 65536 is larger than maximum possible subtype + EXPECT_FALSE(test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(), + "65536 afsdb.example.com.")); + + // Extra text at end of line + EXPECT_FALSE(test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(), + "1 afsdb.example.com. extra.")); +} + +TEST_F(Rdata_AFSDB_Test, toWireBuffer) { + // construct actual data + rdata_afsdb.toWire(obuffer); + + // construct expected data + UnitTestUtil::readWireData("rdata_afsdb_toWire1.wire", expected_wire); + + // then compare them + matchWireData(&expected_wire[0], expected_wire.size(), + obuffer.getData(), obuffer.getLength()); + + // clear buffer for the next test + obuffer.clear(); + + // construct actual data + Name("example.com.").toWire(obuffer); + rdata_afsdb2.toWire(obuffer); + + // construct expected data + UnitTestUtil::readWireData("rdata_afsdb_toWire2.wire", expected_wire); + + // then compare them + matchWireData(&expected_wire[0], expected_wire.size(), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_AFSDB_Test, toWireRenderer) { + // similar to toWireBuffer, but names in RDATA could be compressed due to + // preceding names. Actually they must not be compressed according to + // RFC3597, and this test checks that. + + // construct actual data + rdata_afsdb.toWire(renderer); + + // construct expected data + UnitTestUtil::readWireData("rdata_afsdb_toWire1.wire", expected_wire); + + // then compare them + matchWireData(&expected_wire[0], expected_wire.size(), + renderer.getData(), renderer.getLength()); + + // clear renderer for the next test + renderer.clear(); + + // construct actual data + renderer.writeName(Name("example.com.")); + rdata_afsdb2.toWire(renderer); + + // construct expected data + UnitTestUtil::readWireData("rdata_afsdb_toWire2.wire", expected_wire); + + // then compare them + matchWireData(&expected_wire[0], expected_wire.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_AFSDB_Test, toText) { + EXPECT_EQ(afsdb_text, rdata_afsdb.toText()); + EXPECT_EQ(afsdb_text2, rdata_afsdb2.toText()); +} + +TEST_F(Rdata_AFSDB_Test, compare) { + // check reflexivity + EXPECT_EQ(0, rdata_afsdb.compare(rdata_afsdb)); + + // name must be compared in case-insensitive manner + EXPECT_EQ(0, rdata_afsdb.compare(generic::AFSDB("1 " + "AFSDB.example.com."))); + + const generic::AFSDB small1("10 afsdb.example.com."); + const generic::AFSDB large1("65535 afsdb.example.com."); + const generic::AFSDB large2("256 afsdb.example.com."); + + // confirm these are compared as unsigned values + EXPECT_GT(0, rdata_afsdb.compare(large1)); + EXPECT_LT(0, large1.compare(rdata_afsdb)); + + // confirm these are compared in network byte order + EXPECT_GT(0, small1.compare(large2)); + EXPECT_LT(0, large2.compare(small1)); + + // another AFSDB whose server name is larger than that of rdata_afsdb. + const generic::AFSDB large3("256 zzzzz.example.com."); + EXPECT_GT(0, large2.compare(large3)); + EXPECT_LT(0, large3.compare(large2)); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(rdata_afsdb.compare(*rdata_nomatch), bad_cast); +} +} diff --git a/src/lib/dns/tests/rdata_caa_unittest.cc b/src/lib/dns/tests/rdata_caa_unittest.cc new file mode 100644 index 0000000..48b9076 --- /dev/null +++ b/src/lib/dns/tests/rdata_caa_unittest.cc @@ -0,0 +1,322 @@ +// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <algorithm> +#include <string> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +#include <boost/algorithm/string.hpp> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_CAA_Test : public RdataTest { +protected: + Rdata_CAA_Test() : + caa_txt("0 issue \"ca.example.net\""), + rdata_caa(caa_txt) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<generic::CAA, isc::Exception, isc::Exception>( + rdata_str, rdata_caa, false, false); + } + + void checkFromText_InvalidText(const string& rdata_str) { + checkFromText<generic::CAA, InvalidRdataText, InvalidRdataText>( + rdata_str, rdata_caa, true, true); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::CAA, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_caa, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText + <generic::CAA, InvalidRdataText, isc::Exception>( + rdata_str, rdata_caa, true, false); + } + + const string caa_txt; + const generic::CAA rdata_caa; +}; + +const uint8_t rdata_caa_wiredata[] = { + // flags + 0x00, + // tag length + 0x5, + // tag + 'i', 's', 's', 'u', 'e', + // value + 'c', 'a', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', + '.', 'n', 'e', 't' +}; + +TEST_F(Rdata_CAA_Test, createFromText) { + // Basic test + checkFromText_None(caa_txt); + + // With different spacing + checkFromText_None("0 issue \"ca.example.net\""); + + // Combination of lowercase and uppercase + checkFromText_None("0 IssUE \"ca.example.net\""); + + // string constructor throws if there's extra text, + // but lexer constructor doesn't + checkFromText_BadString(caa_txt + "\n" + caa_txt); + + // Missing value field + EXPECT_NO_THROW(const generic::CAA rdata_caa2("0 issue")); +} + +TEST_F(Rdata_CAA_Test, fields) { + // Some of these may not be RFC conformant, but we relax the check + // in our code to work with other field values that may show up in + // the future. + EXPECT_NO_THROW(const generic::CAA rdata_caa2("1 issue \"ca.example.net\"")); + EXPECT_NO_THROW(const generic::CAA rdata_caa2("2 issue \"ca.example.net\"")); + EXPECT_NO_THROW(const generic::CAA rdata_caa2("3 issue \"ca.example.net\"")); + EXPECT_NO_THROW(const generic::CAA rdata_caa2("128 issue \"ca.example.net\"")); + EXPECT_NO_THROW(const generic::CAA rdata_caa2("255 issue \"ca.example.net\"")); + + EXPECT_NO_THROW(const generic::CAA rdata_caa2("0 foo \"ca.example.net\"")); + EXPECT_NO_THROW(const generic::CAA rdata_caa2("0 bar \"ca.example.net\"")); + EXPECT_NO_THROW(const generic::CAA rdata_caa2("0 12345 \"ca.example.net\"")); + EXPECT_NO_THROW(const generic::CAA rdata_caa2("0 w0x1y2z3 \"ca.example.net\"")); + EXPECT_NO_THROW(const generic::CAA rdata_caa2("0 relaxed-too \"ca.example.net\"")); + EXPECT_NO_THROW(const generic::CAA rdata_caa2("0 RELAXED.too \"ca.example.net\"")); + + // No value (this is redundant to the last test case in the + // .createFromText test + EXPECT_NO_THROW(const generic::CAA rdata_caa2("0 issue")); + + // > 255 would be broken + EXPECT_THROW(const generic::CAA rdata_caa2("256 issue \"ca.example.net\""), + InvalidRdataText); + + // Missing tag causes the value to be parsed as the tag field. As + // the tag field does not allow quoted strings, this throws. + EXPECT_THROW(const generic::CAA rdata_caa2("0 \"ca.example.net\""), + InvalidRdataText); + + // Tag is too long + const std::string tag(256, 'a'); + const std::string rdata_txt("0 " + tag + " \"ca.example.net\""); + EXPECT_THROW(const generic::CAA rdata_caa2(rdata_txt), InvalidRdataText); +} + +TEST_F(Rdata_CAA_Test, characterStringValue) { + const generic::CAA rdata_caa_unquoted("0 issue ca.example.net"); + EXPECT_EQ(0, rdata_caa_unquoted.compare(rdata_caa)); + + const generic::CAA rdata_caa_escape_X("0 issue ca.e\\xample.net"); + EXPECT_EQ(0, rdata_caa_escape_X.compare(rdata_caa)); + + const generic::CAA rdata_caa_escape_DDD("0 issue ca.e\\120ample.net"); + EXPECT_EQ(0, rdata_caa_escape_DDD.compare(rdata_caa)); + + const generic::CAA rdata_caa_multiline("0 issue (\nca.example.net)"); + EXPECT_EQ(0, rdata_caa_multiline.compare(rdata_caa)); +} + +TEST_F(Rdata_CAA_Test, badText) { + checkFromText_LexerError("0"); + checkFromText_LexerError("ZERO issue \"ca.example.net\""); + EXPECT_THROW(const generic::CAA rdata_caa2(caa_txt + " extra text"), + InvalidRdataText); + + // Yes, this is redundant to the last test cases in the .fields test + checkFromText_InvalidText("2345 issue \"ca.example.net\""); + + // negative values are trapped in the lexer rather than the + // constructor + checkFromText_LexerError("-2 issue \"ca.example.net\""); +} + +TEST_F(Rdata_CAA_Test, copyAndAssign) { + // Copy construct + generic::CAA rdata_caa2(rdata_caa); + EXPECT_EQ(0, rdata_caa.compare(rdata_caa2)); + + // Assignment, mainly to confirm it doesn't cause disruption. + rdata_caa2 = rdata_caa; + EXPECT_EQ(0, rdata_caa.compare(rdata_caa2)); +} + +TEST_F(Rdata_CAA_Test, createFromWire) { + // Basic test + EXPECT_EQ(0, rdata_caa.compare( + *rdataFactoryFromFile(RRType("CAA"), RRClass("IN"), + "rdata_caa_fromWire1.wire"))); + + // Combination of lowercase and uppercase + EXPECT_EQ(0, rdata_caa.compare( + *rdataFactoryFromFile(RRType("CAA"), RRClass("IN"), + "rdata_caa_fromWire2.wire"))); + + // Value field is empty + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("CAA"), RRClass("IN"), + "rdata_caa_fromWire3.wire")); + + // Tag field is empty + EXPECT_THROW(rdataFactoryFromFile(RRType("CAA"), RRClass("IN"), + "rdata_caa_fromWire4.wire"), + InvalidRdataText); + + // Value field is shorter than rdata len + EXPECT_THROW(rdataFactoryFromFile(RRType("CAA"), RRClass("IN"), + "rdata_caa_fromWire5"), + InvalidBufferPosition); + + // all RDATA is missing + EXPECT_THROW(rdataFactoryFromFile(RRType("CAA"), RRClass("IN"), + "rdata_caa_fromWire6"), + InvalidBufferPosition); +} + +TEST_F(Rdata_CAA_Test, createFromParams) { + const generic::CAA rdata_caa2(0, "issue", "ca.example.net"); + EXPECT_EQ(0, rdata_caa2.compare(rdata_caa)); + + const generic::CAA rdata_caa4(0, "issue", "ca.e\\xample.net"); + EXPECT_EQ(0, rdata_caa4.compare(rdata_caa)); + + const generic::CAA rdata_caa5(0, "issue", "ca.e\\120ample.net"); + EXPECT_EQ(0, rdata_caa5.compare(rdata_caa)); + + // Tag is empty + EXPECT_THROW(const generic::CAA rdata_caa3(0, "", "ca.example.net"), + isc::InvalidParameter); + + // Tag is too long + const std::string tag(256, 'a'); + EXPECT_THROW(const generic::CAA rdata_caa3(0, tag, "ca.example.net"), + isc::InvalidParameter); + + // Value is too long + const std::string value(65536, 'a'); + EXPECT_THROW(const generic::CAA rdata_caa3(0, "issue", value), + InvalidRdataLength); +} + +TEST_F(Rdata_CAA_Test, toText) { + EXPECT_TRUE(boost::iequals(caa_txt, rdata_caa.toText())); + + const string caa_txt2("1 issue \"\""); + const generic::CAA rdata_caa2(caa_txt2); + EXPECT_TRUE(boost::iequals(caa_txt2, rdata_caa2.toText())); +} + +TEST_F(Rdata_CAA_Test, toWire) { + obuffer.clear(); + rdata_caa.toWire(obuffer); + + matchWireData(rdata_caa_wiredata, sizeof(rdata_caa_wiredata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_CAA_Test, compare) { + // Equality test is repeated from createFromWire tests above. + EXPECT_EQ(0, rdata_caa.compare( + *rdataFactoryFromFile(RRType("CAA"), RRClass("IN"), + "rdata_caa_fromWire1.wire"))); + + const generic::CAA rdata_caa2("1 issue \"ca.example.net\""); + + EXPECT_EQ(1, rdata_caa2.compare(rdata_caa)); + EXPECT_EQ(-1, rdata_caa.compare(rdata_caa2)); +} + +TEST_F(Rdata_CAA_Test, getFlags) { + EXPECT_EQ(0, rdata_caa.getFlags()); +} + +TEST_F(Rdata_CAA_Test, getTag) { + EXPECT_EQ("issue", rdata_caa.getTag()); +} + +TEST_F(Rdata_CAA_Test, getValue) { + const uint8_t value_data[] = { + 'c', 'a', '.', + 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', + 'n', 'e', 't' + }; + + const std::vector<uint8_t>& value = rdata_caa.getValue(); + matchWireData(value_data, sizeof(value_data), + &value[0], value.size()); +} + +TEST_F(Rdata_CAA_Test, emptyValueFromWire) { + const uint8_t rdf_wiredata[] = { + // flags + 0x00, + // tag length + 0x5, + // tag + 'i', 's', 's', 'u', 'e' + }; + + const generic::CAA rdf = + dynamic_cast<const generic::CAA&> + (*rdataFactoryFromFile(RRType("CAA"), RRClass("IN"), + "rdata_caa_fromWire3.wire")); + + EXPECT_EQ(0, rdf.getFlags()); + EXPECT_EQ("issue", rdf.getTag()); + + obuffer.clear(); + rdf.toWire(obuffer); + + matchWireData(rdf_wiredata, sizeof(rdf_wiredata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_CAA_Test, emptyValueFromString) { + const generic::CAA rdata_caa2("0 issue"); + const uint8_t rdata_caa2_wiredata[] = { + // flags + 0x00, + // tag length + 0x5, + // tag + 'i', 's', 's', 'u', 'e' + }; + + EXPECT_EQ(0, rdata_caa2.getFlags()); + EXPECT_EQ("issue", rdata_caa2.getTag()); + + obuffer.clear(); + rdata_caa2.toWire(obuffer); + + matchWireData(rdata_caa2_wiredata, sizeof(rdata_caa2_wiredata), + obuffer.getData(), obuffer.getLength()); +} +} diff --git a/src/lib/dns/tests/rdata_char_string_data_unittest.cc b/src/lib/dns/tests/rdata_char_string_data_unittest.cc new file mode 100644 index 0000000..4ffeadb --- /dev/null +++ b/src/lib/dns/tests/rdata_char_string_data_unittest.cc @@ -0,0 +1,181 @@ +// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/unittests/wiredata.h> + +#include <dns/exceptions.h> +#include <dns/rdata.h> +#include <dns/rdata/generic/detail/char_string.h> +#include <util/buffer.h> + +#include <gtest/gtest.h> + +#include <string> +#include <vector> + +using namespace isc::dns; +using namespace isc::dns::rdata; +using isc::dns::rdata::generic::detail::CharStringData; +using isc::dns::rdata::generic::detail::stringToCharStringData; +using isc::dns::rdata::generic::detail::charStringDataToString; +using isc::dns::rdata::generic::detail::compareCharStringDatas; +using isc::util::unittests::matchWireData; + +namespace { +const uint8_t test_charstr[] = { + 'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g' +}; + +class CharStringDataTest : public ::testing::Test { +protected: + CharStringDataTest() : + // char-string representation for test data using two types of escape + // ('r' = 114) + test_str("Test\\ St\\114ing") + { + str_region.beg = &test_str[0]; + str_region.len = test_str.size(); + } + CharStringData chstr; // place holder + const std::string test_str; + MasterToken::StringRegion str_region; +}; + +MasterToken::StringRegion +createStringRegion(const std::string& str) { + MasterToken::StringRegion region; + region.beg = &str[0]; // note std ensures this works even if str is empty + region.len = str.size(); + return (region); +} + +TEST_F(CharStringDataTest, normalConversion) { + uint8_t tmp[3]; // placeholder for expected sequence + + stringToCharStringData(str_region, chstr); + matchWireData(test_charstr, sizeof(test_charstr), &chstr[0], chstr.size()); + + // Empty string + chstr.clear(); + stringToCharStringData(createStringRegion(""), chstr); + EXPECT_TRUE(chstr.empty()); + + // Possible largest char string + chstr.clear(); + std::string long_str(255, 'x'); + stringToCharStringData(createStringRegion(long_str), chstr); + std::vector<uint8_t> expected; + expected.insert(expected.end(), long_str.begin(), long_str.end()); + matchWireData(&expected[0], expected.size(), &chstr[0], chstr.size()); + + // Escaped '\' + chstr.clear(); + tmp[0] = '\\'; + stringToCharStringData(createStringRegion("\\\\"), chstr); + matchWireData(tmp, 1, &chstr[0], chstr.size()); + + // Boundary values for \DDD + chstr.clear(); + tmp[0] = 0; + stringToCharStringData(createStringRegion("\\000"), chstr); + matchWireData(tmp, 1, &chstr[0], chstr.size()); + + chstr.clear(); + stringToCharStringData(createStringRegion("\\255"), chstr); + tmp[0] = 255; + matchWireData(tmp, 1, &chstr[0], chstr.size()); + + // Another digit follows DDD; it shouldn't cause confusion + chstr.clear(); + stringToCharStringData(createStringRegion("\\2550"), chstr); + tmp[1] = '0'; + matchWireData(tmp, 2, &chstr[0], chstr.size()); +} + +TEST_F(CharStringDataTest, badConversion) { + // input string ending with (non escaped) '\' + chstr.clear(); + EXPECT_THROW(stringToCharStringData(createStringRegion("foo\\"), chstr), + InvalidRdataText); +} + +TEST_F(CharStringDataTest, badDDD) { + // Check various type of bad form of \DDD + + // Not a number + EXPECT_THROW(stringToCharStringData(createStringRegion("\\1a2"), chstr), + InvalidRdataText); + EXPECT_THROW(stringToCharStringData(createStringRegion("\\12a"), chstr), + InvalidRdataText); + + // Not in the range of uint8_t + EXPECT_THROW(stringToCharStringData(createStringRegion("\\256"), chstr), + InvalidRdataText); + + // Short buffer + EXPECT_THROW(stringToCharStringData(createStringRegion("\\42"), chstr), + InvalidRdataText); +} + +const struct TestData { + const char *data; + const char *expected; +} conversion_data[] = { + {"Test\"Test", "Test\\\"Test"}, + {"Test;Test", "Test\\;Test"}, + {"Test\\Test", "Test\\\\Test"}, + {"Test\x1fTest", "Test\\031Test"}, + {"Test ~ Test", "Test ~ Test"}, + {"Test\x7fTest", "Test\\127Test"}, + {NULL, NULL} +}; + +TEST_F(CharStringDataTest, charStringDataToString) { + for (const TestData* cur = conversion_data; cur->data != NULL; ++cur) { + uint8_t idata[32]; + size_t length = std::strlen(cur->data); + ASSERT_LT(length, sizeof(idata)); + std::memcpy(idata, cur->data, length); + const CharStringData test_data(idata, idata + length); + EXPECT_EQ(cur->expected, charStringDataToString(test_data)); + } +} + +TEST_F(CharStringDataTest, compareCharStringData) { + CharStringData charstr; + CharStringData charstr2; + CharStringData charstr_small1; + CharStringData charstr_small2; + CharStringData charstr_large1; + CharStringData charstr_large2; + CharStringData charstr_empty; + + stringToCharStringData(createStringRegion("test string"), charstr); + stringToCharStringData(createStringRegion("test string"), charstr2); + stringToCharStringData(createStringRegion("test strin"), charstr_small1); + stringToCharStringData(createStringRegion("test strina"), charstr_small2); + stringToCharStringData(createStringRegion("test stringa"), charstr_large1); + stringToCharStringData(createStringRegion("test strinz"), charstr_large2); + + EXPECT_EQ(0, compareCharStringDatas(charstr, charstr2)); + EXPECT_EQ(0, compareCharStringDatas(charstr2, charstr)); + EXPECT_EQ(1, compareCharStringDatas(charstr, charstr_small1)); + EXPECT_EQ(1, compareCharStringDatas(charstr, charstr_small2)); + EXPECT_EQ(-1, compareCharStringDatas(charstr, charstr_large1)); + EXPECT_EQ(-1, compareCharStringDatas(charstr, charstr_large2)); + EXPECT_EQ(-1, compareCharStringDatas(charstr_small1, charstr)); + EXPECT_EQ(-1, compareCharStringDatas(charstr_small2, charstr)); + EXPECT_EQ(1, compareCharStringDatas(charstr_large1, charstr)); + EXPECT_EQ(1, compareCharStringDatas(charstr_large2, charstr)); + + EXPECT_EQ(-1, compareCharStringDatas(charstr_empty, charstr)); + EXPECT_EQ(1, compareCharStringDatas(charstr, charstr_empty)); + EXPECT_EQ(0, compareCharStringDatas(charstr_empty, charstr_empty)); +} + +} // unnamed namespace diff --git a/src/lib/dns/tests/rdata_char_string_unittest.cc b/src/lib/dns/tests/rdata_char_string_unittest.cc new file mode 100644 index 0000000..f1618b5 --- /dev/null +++ b/src/lib/dns/tests/rdata_char_string_unittest.cc @@ -0,0 +1,246 @@ +// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/unittests/wiredata.h> + +#include <dns/exceptions.h> +#include <dns/rdata.h> +#include <dns/rdata/generic/detail/char_string.h> +#include <util/buffer.h> + +#include <gtest/gtest.h> + +#include <string> +#include <vector> + +using namespace isc::dns; +using namespace isc::dns::rdata; +using isc::dns::rdata::generic::detail::CharString; +using isc::dns::rdata::generic::detail::bufferToCharString; +using isc::dns::rdata::generic::detail::stringToCharString; +using isc::dns::rdata::generic::detail::charStringToString; +using isc::dns::rdata::generic::detail::compareCharStrings; +using isc::util::unittests::matchWireData; + +namespace { +const uint8_t test_charstr[] = { + sizeof("Test String") - 1, + 'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g' +}; + +class CharStringTest : public ::testing::Test { +protected: + CharStringTest() : + // char-string representation for test data using two types of escape + // ('r' = 114) + test_str("Test\\ St\\114ing") + { + str_region.beg = &test_str[0]; + str_region.len = test_str.size(); + } + CharString chstr; // place holder + const std::string test_str; + MasterToken::StringRegion str_region; +}; + +MasterToken::StringRegion +createStringRegion(const std::string& str) { + MasterToken::StringRegion region; + region.beg = &str[0]; // note std ensures this works even if str is empty + region.len = str.size(); + return (region); +} + +TEST_F(CharStringTest, normalConversion) { + uint8_t tmp[3]; // placeholder for expected sequence + + stringToCharString(str_region, chstr); + matchWireData(test_charstr, sizeof(test_charstr), &chstr[0], chstr.size()); + + // Empty string + chstr.clear(); + stringToCharString(createStringRegion(""), chstr); + tmp[0] = 0; + matchWireData(tmp, 1, &chstr[0], chstr.size()); + + // Possible largest char string + chstr.clear(); + std::string long_str(255, 'x'); + stringToCharString(createStringRegion(long_str), chstr); + std::vector<uint8_t> expected; + expected.push_back(255); // len of char string + expected.insert(expected.end(), long_str.begin(), long_str.end()); + matchWireData(&expected[0], expected.size(), &chstr[0], chstr.size()); + + // Same data as the previous case, but the original string is longer than + // the max; this shouldn't be rejected + chstr.clear(); + long_str.at(254) = '\\'; // replace the last 'x' with '\' + long_str.append("120"); // 'x' = 120 + stringToCharString(createStringRegion(long_str), chstr); + matchWireData(&expected[0], expected.size(), &chstr[0], chstr.size()); + + // Escaped '\' + chstr.clear(); + tmp[0] = 1; + tmp[1] = '\\'; + stringToCharString(createStringRegion("\\\\"), chstr); + matchWireData(tmp, 2, &chstr[0], chstr.size()); + + // Boundary values for \DDD + chstr.clear(); + tmp[0] = 1; + tmp[1] = 0; + stringToCharString(createStringRegion("\\000"), chstr); + matchWireData(tmp, 2, &chstr[0], chstr.size()); + + chstr.clear(); + stringToCharString(createStringRegion("\\255"), chstr); + tmp[0] = 1; + tmp[1] = 255; + matchWireData(tmp, 2, &chstr[0], chstr.size()); + + // Another digit follows DDD; it shouldn't cause confusion + chstr.clear(); + stringToCharString(createStringRegion("\\2550"), chstr); + tmp[0] = 2; // string len is now 2 + tmp[2] = '0'; + matchWireData(tmp, 3, &chstr[0], chstr.size()); +} + +TEST_F(CharStringTest, badConversion) { + // string cannot exceed 255 bytes + EXPECT_THROW(stringToCharString(createStringRegion(std::string(256, 'a')), + chstr), + CharStringTooLong); + + // input string ending with (non escaped) '\' + chstr.clear(); + EXPECT_THROW(stringToCharString(createStringRegion("foo\\"), chstr), + InvalidRdataText); +} + +TEST_F(CharStringTest, badDDD) { + // Check various type of bad form of \DDD + + // Not a number + EXPECT_THROW(stringToCharString(createStringRegion("\\1a2"), chstr), + InvalidRdataText); + EXPECT_THROW(stringToCharString(createStringRegion("\\12a"), chstr), + InvalidRdataText); + + // Not in the range of uint8_t + EXPECT_THROW(stringToCharString(createStringRegion("\\256"), chstr), + InvalidRdataText); + + // Short buffer + EXPECT_THROW(stringToCharString(createStringRegion("\\42"), chstr), + InvalidRdataText); +} + +const struct TestData { + const char *data; + const char *expected; +} conversion_data[] = { + {"Test\"Test", "Test\\\"Test"}, + {"Test;Test", "Test\\;Test"}, + {"Test\\Test", "Test\\\\Test"}, + {"Test\x1fTest", "Test\\031Test"}, + {"Test ~ Test", "Test ~ Test"}, + {"Test\x7fTest", "Test\\127Test"}, + {NULL, NULL} +}; + +TEST_F(CharStringTest, charStringToString) { + for (const TestData* cur = conversion_data; cur->data != NULL; ++cur) { + uint8_t idata[32]; + size_t length = std::strlen(cur->data); + // length (1 byte) + string (length bytes) + assert(sizeof(idata) > length); + idata[0] = static_cast<uint8_t>(length); + std::memcpy(idata + 1, cur->data, length); + const CharString test_data(idata, idata + length + 1); + EXPECT_EQ(cur->expected, charStringToString(test_data)); + } +} + +TEST_F(CharStringTest, bufferToCharString) { + const size_t chstr_size = sizeof(test_charstr); + isc::util::InputBuffer buf(test_charstr, chstr_size); + size_t read = bufferToCharString(buf, chstr_size, chstr); + + EXPECT_EQ(chstr_size, read); + EXPECT_EQ("Test String", charStringToString(chstr)); +} + +TEST_F(CharStringTest, bufferToCharString_bad) { + const size_t chstr_size = sizeof(test_charstr); + isc::util::InputBuffer buf(test_charstr, chstr_size); + // Set valid data in both so we can make sure the charstr is not + // modified + bufferToCharString(buf, chstr_size, chstr); + ASSERT_EQ("Test String", charStringToString(chstr)); + + // Should be at end of buffer now, so it should fail + EXPECT_THROW(bufferToCharString(buf, chstr_size - 1, chstr), + DNSMessageFORMERR); + EXPECT_EQ("Test String", charStringToString(chstr)); + + // reset and try to read with too low rdata_len + buf.setPosition(0); + EXPECT_THROW(bufferToCharString(buf, chstr_size - 1, chstr), + DNSMessageFORMERR); + EXPECT_EQ("Test String", charStringToString(chstr)); + + // set internal charstring len too high + const uint8_t test_charstr_err[] = { + sizeof("Test String") + 1, + 'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g' + }; + buf = isc::util::InputBuffer(test_charstr_err, sizeof(test_charstr_err)); + EXPECT_THROW(bufferToCharString(buf, chstr_size, chstr), + DNSMessageFORMERR); + EXPECT_EQ("Test String", charStringToString(chstr)); + +} + + + +TEST_F(CharStringTest, compareCharString) { + CharString charstr; + CharString charstr2; + CharString charstr_small1; + CharString charstr_small2; + CharString charstr_large1; + CharString charstr_large2; + CharString charstr_empty; + + stringToCharString(createStringRegion("test string"), charstr); + stringToCharString(createStringRegion("test string"), charstr2); + stringToCharString(createStringRegion("test strin"), charstr_small1); + stringToCharString(createStringRegion("test strina"), charstr_small2); + stringToCharString(createStringRegion("test stringa"), charstr_large1); + stringToCharString(createStringRegion("test strinz"), charstr_large2); + + EXPECT_EQ(0, compareCharStrings(charstr, charstr2)); + EXPECT_EQ(0, compareCharStrings(charstr2, charstr)); + EXPECT_EQ(1, compareCharStrings(charstr, charstr_small1)); + EXPECT_EQ(1, compareCharStrings(charstr, charstr_small2)); + EXPECT_EQ(-1, compareCharStrings(charstr, charstr_large1)); + EXPECT_EQ(-1, compareCharStrings(charstr, charstr_large2)); + EXPECT_EQ(-1, compareCharStrings(charstr_small1, charstr)); + EXPECT_EQ(-1, compareCharStrings(charstr_small2, charstr)); + EXPECT_EQ(1, compareCharStrings(charstr_large1, charstr)); + EXPECT_EQ(1, compareCharStrings(charstr_large2, charstr)); + + EXPECT_EQ(-1, compareCharStrings(charstr_empty, charstr)); + EXPECT_EQ(1, compareCharStrings(charstr, charstr_empty)); + EXPECT_EQ(0, compareCharStrings(charstr_empty, charstr_empty)); +} + +} // unnamed namespace diff --git a/src/lib/dns/tests/rdata_cname_unittest.cc b/src/lib/dns/tests/rdata_cname_unittest.cc new file mode 100644 index 0000000..e666355 --- /dev/null +++ b/src/lib/dns/tests/rdata_cname_unittest.cc @@ -0,0 +1,135 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_CNAME_Test : public RdataTest { +public: + Rdata_CNAME_Test() : + rdata_cname("cn.example.com."), + rdata_cname2("cn2.example.com.") + {} + + const generic::CNAME rdata_cname; + const generic::CNAME rdata_cname2; +}; + +const uint8_t wiredata_cname[] = { + 0x02, 0x63, 0x6e, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, + 0x63, 0x6f, 0x6d, 0x00 }; +const uint8_t wiredata_cname2[] = { + // first name: cn.example.com. + 0x02, 0x63, 0x6e, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, + 0x63, 0x6f, 0x6d, 0x00, + // second name: cn2.example.com. all labels except the first should be + // compressed. + 0x03, 0x63, 0x6e, 0x32, 0xc0, 0x03 }; + +TEST_F(Rdata_CNAME_Test, createFromText) { + EXPECT_EQ(0, rdata_cname.compare(generic::CNAME("cn.example.com."))); + // explicitly add a trailing dot. should be the same RDATA. + EXPECT_EQ(0, rdata_cname.compare(generic::CNAME("cn.example.com."))); + // should be case sensitive. + EXPECT_EQ(0, rdata_cname.compare(generic::CNAME("CN.EXAMPLE.COM."))); + // RDATA of a class-independent type should be recognized for any + // "unknown" class. + EXPECT_EQ(0, rdata_cname.compare(*createRdata(RRType("CNAME"), + RRClass(65000), + "cn.example.com."))); +} + +TEST_F(Rdata_CNAME_Test, badText) { + // Extra text at end of line + EXPECT_THROW(generic::CNAME("cname.example.com. extra."), InvalidRdataText); +} + +TEST_F(Rdata_CNAME_Test, createFromWire) { + EXPECT_EQ(0, rdata_cname.compare( + *rdataFactoryFromFile(RRType("CNAME"), RRClass("IN"), + "rdata_cname_fromWire"))); + // RDLENGTH is too short + EXPECT_THROW(rdataFactoryFromFile(RRType("CNAME"), RRClass("IN"), + "rdata_cname_fromWire", 18), + InvalidRdataLength); + // RDLENGTH is too long + EXPECT_THROW(rdataFactoryFromFile(RRType("CNAME"), RRClass("IN"), + "rdata_cname_fromWire", 36), + InvalidRdataLength); + // incomplete name. the error should be detected in the name constructor + EXPECT_THROW(rdataFactoryFromFile(RRType("CNAME"), RRClass("IN"), + "rdata_cname_fromWire", 71), + DNSMessageFORMERR); + + EXPECT_EQ(0, generic::CNAME("cn2.example.com.").compare( + *rdataFactoryFromFile(RRType("CNAME"), RRClass("IN"), + "rdata_cname_fromWire", 55))); + EXPECT_THROW(*rdataFactoryFromFile(RRType("CNAME"), RRClass("IN"), + "rdata_cname_fromWire", 63), + InvalidRdataLength); +} + +TEST_F(Rdata_CNAME_Test, createFromLexer) { + EXPECT_EQ(0, rdata_cname.compare( + *test::createRdataUsingLexer(RRType::CNAME(), RRClass::IN(), + "cn.example.com."))); + + // test::createRdataUsingLexer() constructs relative to + // "example.org." origin. + EXPECT_EQ(0, generic::CNAME("cname10.example.org.").compare( + *test::createRdataUsingLexer(RRType::CNAME(), RRClass::IN(), + "cname10"))); + + // Extra text at end of line + EXPECT_FALSE(test::createRdataUsingLexer(RRType::CNAME(), RRClass::IN(), + "cname.example.com. extra.")); +} + +TEST_F(Rdata_CNAME_Test, toWireBuffer) { + rdata_cname.toWire(obuffer); + matchWireData(wiredata_cname, sizeof(wiredata_cname), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_CNAME_Test, toWireRenderer) { + rdata_cname.toWire(renderer); + matchWireData(wiredata_cname, sizeof(wiredata_cname), + renderer.getData(), renderer.getLength()); + + rdata_cname2.toWire(renderer); + matchWireData(wiredata_cname2, sizeof(wiredata_cname2), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_CNAME_Test, toText) { + EXPECT_EQ("cn.example.com.", rdata_cname.toText()); +} + +TEST_F(Rdata_CNAME_Test, getCname) { + EXPECT_EQ(Name("cn.example.com."), rdata_cname.getCname()); +} +} diff --git a/src/lib/dns/tests/rdata_dhcid_unittest.cc b/src/lib/dns/tests/rdata_dhcid_unittest.cc new file mode 100644 index 0000000..a96c3e4 --- /dev/null +++ b/src/lib/dns/tests/rdata_dhcid_unittest.cc @@ -0,0 +1,165 @@ +// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <dns/rdataclass.h> +#include <util/encode/base64.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::util::encode; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { + +class Rdata_DHCID_Test : public RdataTest { +protected: + Rdata_DHCID_Test() : + dhcid_txt("0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA="), + rdata_dhcid(dhcid_txt) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<in::DHCID, isc::Exception, isc::Exception>( + rdata_str, rdata_dhcid, false, false); + } + + void checkFromText_BadValue(const string& rdata_str) { + checkFromText<in::DHCID, BadValue, BadValue>( + rdata_str, rdata_dhcid, true, true); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <in::DHCID, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_dhcid, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText + <in::DHCID, InvalidRdataText, isc::Exception>( + rdata_str, rdata_dhcid, true, false); + } + + const string dhcid_txt; + const in::DHCID rdata_dhcid; +}; + +TEST_F(Rdata_DHCID_Test, fromText) { + EXPECT_EQ(dhcid_txt, rdata_dhcid.toText()); + + // Space in digest data is OK + checkFromText_None( + "0LIg0LvQtdGB0YMg 0YDQvtC00LjQu9Cw 0YHRjCDRkdC70L7R h9C60LA="); + + // Multi-line digest data is OK, if enclosed in parentheses + checkFromText_None( + "( 0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw\n0YHRjCDRkdC70L7R h9C60LA= )"); + + // Trailing garbage. This should cause only the string constructor + // to fail, but the lexer constructor must be able to continue + // parsing from it. + checkFromText_BadString( + "0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA=" + " ; comment\n" + "AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA="); +} + +TEST_F(Rdata_DHCID_Test, badText) { + // missing digest data + checkFromText_LexerError(""); + + // invalid base64 + checkFromText_BadValue("EEeeeeeeEEEeeeeeeGaaahAAAAAAAAHHHHHHHHHHH!="); + + // unterminated multi-line base64 + checkFromText_LexerError( + "( 0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw\n0YHRjCDRkdC70L7R h9C60LA="); +} + +TEST_F(Rdata_DHCID_Test, copy) { + const in::DHCID rdata_dhcid2(rdata_dhcid); + EXPECT_EQ(0, rdata_dhcid.compare(rdata_dhcid2)); +} + +TEST_F(Rdata_DHCID_Test, createFromWire) { + EXPECT_EQ(0, rdata_dhcid.compare( + *rdataFactoryFromFile(RRType("DHCID"), RRClass("IN"), + "rdata_dhcid_fromWire"))); + + InputBuffer buffer(NULL, 0); + EXPECT_THROW(in::DHCID(buffer, 0), InvalidRdataLength); + + // TBD: more tests +} + +TEST_F(Rdata_DHCID_Test, createFromLexer) { + EXPECT_EQ(0, rdata_dhcid.compare( + *test::createRdataUsingLexer(RRType::DHCID(), RRClass::IN(), + dhcid_txt))); +} + +TEST_F(Rdata_DHCID_Test, toWireRenderer) { + rdata_dhcid.toWire(renderer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_dhcid_toWire", data); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_DHCID_Test, toWireBuffer) { + rdata_dhcid.toWire(obuffer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_dhcid_toWire", data); + matchWireData(&data[0], data.size(), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_DHCID_Test, toText) { + EXPECT_EQ(dhcid_txt, rdata_dhcid.toText()); +} + +TEST_F(Rdata_DHCID_Test, getDHCIDDigest) { + const string dhcid_txt1(encodeBase64(rdata_dhcid.getDigest())); + + EXPECT_EQ(dhcid_txt, dhcid_txt1); +} + +TEST_F(Rdata_DHCID_Test, compare) { + // trivial case: self equivalence + // cppcheck-suppress uselessCallsCompare + EXPECT_EQ(0, rdata_dhcid.compare(rdata_dhcid)); + + in::DHCID rdata_dhcid1("0YLQvtC/0L7Qu9GPINC00LLQsCDRgNGD0LHQu9GP"); + in::DHCID rdata_dhcid2("0YLQvtC/0L7Qu9GPINGC0YDQuCDRgNGD0LHQu9GP"); + in::DHCID rdata_dhcid3("0YLQvtC/0L7Qu9GPINGH0LXRgtGL0YDQtSDRgNGD0LHQu9GP"); + + EXPECT_LT(rdata_dhcid1.compare(rdata_dhcid2), 0); + EXPECT_GT(rdata_dhcid2.compare(rdata_dhcid1), 0); + + EXPECT_LT(rdata_dhcid2.compare(rdata_dhcid3), 0); + EXPECT_GT(rdata_dhcid3.compare(rdata_dhcid2), 0); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(rdata_dhcid.compare(*rdata_nomatch), bad_cast); +} +} diff --git a/src/lib/dns/tests/rdata_dname_unittest.cc b/src/lib/dns/tests/rdata_dname_unittest.cc new file mode 100644 index 0000000..3bdfb23 --- /dev/null +++ b/src/lib/dns/tests/rdata_dname_unittest.cc @@ -0,0 +1,137 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_DNAME_Test : public RdataTest { +public: + Rdata_DNAME_Test() : + rdata_dname("dn.example.com."), + rdata_dname2("dn2.example.com.") + {} + + const generic::DNAME rdata_dname; + const generic::DNAME rdata_dname2; +}; + +const uint8_t wiredata_dname[] = { + 0x02, 0x64, 0x6e, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, + 0x63, 0x6f, 0x6d, 0x00 }; +const uint8_t wiredata_dname2[] = { + // first name: dn.example.com. + 0x02, 0x64, 0x6e, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, + 0x63, 0x6f, 0x6d, 0x00, + // second name: dn2.example.com. The "example.com" shouldn't be compressed + // because DNAME is not a well know type per RFC3597. + 0x03, 0x64, 0x6e, 0x32, + 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, + 0x63, 0x6f, 0x6d, 0x00 }; + +TEST_F(Rdata_DNAME_Test, createFromText) { + EXPECT_EQ(0, rdata_dname.compare(generic::DNAME("dn.example.com."))); + // explicitly add a trailing dot. should be the same RDATA. + EXPECT_EQ(0, rdata_dname.compare(generic::DNAME("dn.example.com."))); + // should be case sensitive. + EXPECT_EQ(0, rdata_dname.compare(generic::DNAME("DN.EXAMPLE.COM."))); + // RDATA of a class-independent type should be recognized for any + // "unknown" class. + EXPECT_EQ(0, rdata_dname.compare(*createRdata(RRType("DNAME"), + RRClass(65000), + "dn.example.com."))); +} + +TEST_F(Rdata_DNAME_Test, badText) { + // Extra text at end of line + EXPECT_THROW(generic::DNAME("dname.example.com. extra."), InvalidRdataText); +} + +TEST_F(Rdata_DNAME_Test, createFromWire) { + EXPECT_EQ(0, rdata_dname.compare( + *rdataFactoryFromFile(RRType("DNAME"), RRClass("IN"), + "rdata_dname_fromWire"))); + // RDLENGTH is too short + EXPECT_THROW(rdataFactoryFromFile(RRType("DNAME"), RRClass("IN"), + "rdata_dname_fromWire", 18), + InvalidRdataLength); + // RDLENGTH is too long + EXPECT_THROW(rdataFactoryFromFile(RRType("DNAME"), RRClass("IN"), + "rdata_dname_fromWire", 36), + InvalidRdataLength); + // incomplete name. the error should be detected in the name constructor + EXPECT_THROW(rdataFactoryFromFile(RRType("DNAME"), RRClass("IN"), + "rdata_dname_fromWire", 71), + DNSMessageFORMERR); + + EXPECT_EQ(0, generic::DNAME("dn2.example.com.").compare( + *rdataFactoryFromFile(RRType("DNAME"), RRClass("IN"), + "rdata_dname_fromWire", 55))); + EXPECT_THROW(*rdataFactoryFromFile(RRType("DNAME"), RRClass("IN"), + "rdata_dname_fromWire", 63), + InvalidRdataLength); +} + +TEST_F(Rdata_DNAME_Test, createFromLexer) { + EXPECT_EQ(0, rdata_dname.compare( + *test::createRdataUsingLexer(RRType::DNAME(), RRClass::IN(), + "dn.example.com."))); + + // test::createRdataUsingLexer() constructs relative to + // "example.org." origin. + EXPECT_EQ(0, generic::DNAME("dname8.example.org.").compare( + *test::createRdataUsingLexer(RRType::DNAME(), RRClass::IN(), + "dname8"))); + + // Extra text at end of line + EXPECT_FALSE(test::createRdataUsingLexer(RRType::DNAME(), RRClass::IN(), + "dname.example.com. extra.")); +} + +TEST_F(Rdata_DNAME_Test, toWireBuffer) { + rdata_dname.toWire(obuffer); + matchWireData(wiredata_dname, sizeof(wiredata_dname), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_DNAME_Test, toWireRenderer) { + rdata_dname.toWire(renderer); + matchWireData(wiredata_dname, sizeof(wiredata_dname), + renderer.getData(), renderer.getLength()); + + rdata_dname2.toWire(renderer); + matchWireData(wiredata_dname2, sizeof(wiredata_dname2), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_DNAME_Test, toText) { + EXPECT_EQ("dn.example.com.", rdata_dname.toText()); +} + +TEST_F(Rdata_DNAME_Test, getDname) { + EXPECT_EQ(Name("dn.example.com."), rdata_dname.getDname()); +} +} diff --git a/src/lib/dns/tests/rdata_dnskey_unittest.cc b/src/lib/dns/tests/rdata_dnskey_unittest.cc new file mode 100644 index 0000000..6f0866d --- /dev/null +++ b/src/lib/dns/tests/rdata_dnskey_unittest.cc @@ -0,0 +1,200 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_DNSKEY_Test : public RdataTest { +protected: + Rdata_DNSKEY_Test() : + dnskey_txt("257 3 5 BEAAAAOhHQDBrhQbtphgq2wQUpEQ5t4DtUHxoMV" + "Fu2hWLDMvoOMRXjGrhhCeFvAZih7yJHf8ZGfW6hd38hXG/x" + "ylYCO6Krpbdojwx8YMXLA5/kA+u50WIL8ZR1R6KTbsYVMf/" + "Qx5RiNbPClw+vT+U8eXEJmO20jIS1ULgqy347cBB1zMnnz/" + "4LJpA0da9CbKj3A254T515sNIMcwsB8/2+2E63/zZrQzBkj" + "0BrN/9Bexjpiks3jRhZatEsXn3dTy47R09Uix5WcJt+xzqZ" + "7+ysyLKOOedS39Z7SDmsn2eA0FKtQpwA6LXeG2w+jxmw3oA" + "8lVUgEf/rzeC/bByBNsO70aEFTd"), + dnskey_txt2("257 3 5 YmluZDEwLmlzYy5vcmc="), + rdata_dnskey(dnskey_txt), + rdata_dnskey2(dnskey_txt2) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<generic::DNSKEY, isc::Exception, isc::Exception>( + rdata_str, rdata_dnskey2, false, false); + } + + void checkFromText_InvalidText(const string& rdata_str) { + checkFromText<generic::DNSKEY, InvalidRdataText, InvalidRdataText>( + rdata_str, rdata_dnskey2, true, true); + } + + void checkFromText_InvalidLength(const string& rdata_str) { + checkFromText<generic::DNSKEY, InvalidRdataLength, InvalidRdataLength>( + rdata_str, rdata_dnskey2, true, true); + } + + void checkFromText_BadValue(const string& rdata_str) { + checkFromText<generic::DNSKEY, BadValue, BadValue>( + rdata_str, rdata_dnskey2, true, true); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::DNSKEY, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_dnskey2, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText + <generic::DNSKEY, InvalidRdataText, isc::Exception>( + rdata_str, rdata_dnskey2, true, false); + } + + const string dnskey_txt; + const string dnskey_txt2; + const generic::DNSKEY rdata_dnskey; + const generic::DNSKEY rdata_dnskey2; +}; + +TEST_F(Rdata_DNSKEY_Test, fromText) { + EXPECT_EQ(dnskey_txt, rdata_dnskey.toText()); + + // Space in key data is OK + checkFromText_None("257 3 5 YmluZDEw LmlzYy5vcmc="); + + // Delimited number in key data is OK + checkFromText_None("257 3 5 YmluZDEwLmlzYy 5 vcmc="); + + // Missing keydata is OK + EXPECT_NO_THROW(const generic::DNSKEY rdata_dnskey3("257 3 5")); + + // Key data too short for RSA/MD5 algorithm is OK when + // constructing. But getTag() on this object would throw (see + // .getTag tests). + EXPECT_NO_THROW(const generic::DNSKEY rdata_dnskey4("1 1 1 YQ==")); + + // Flags field out of range + checkFromText_InvalidText("65536 3 5 YmluZDEwLmlzYy5vcmc="); + + // Protocol field out of range + checkFromText_InvalidText("257 256 5 YmluZDEwLmlzYy5vcmc="); + + // Algorithm field out of range + checkFromText_InvalidText("257 3 256 YmluZDEwLmlzYy5vcmc="); + + // Missing algorithm field + checkFromText_LexerError("257 3 YmluZDEwLmlzYy5vcmc="); + + // Invalid key data field (not Base64) + checkFromText_BadValue("257 3 5 BAAAAAAAAAAAD"); + + // String instead of number + checkFromText_LexerError("foo 3 5 YmluZDEwLmlzYy5vcmc="); + checkFromText_LexerError("257 foo 5 YmluZDEwLmlzYy5vcmc="); + checkFromText_LexerError("257 3 foo YmluZDEwLmlzYy5vcmc="); + + // Trailing garbage. This should cause only the string constructor + // to fail, but the lexer constructor must be able to continue + // parsing from it. + checkFromText_BadString("257 3 5 YmluZDEwLmlzYy5vcmc= ; comment\n" + "257 3 4 YmluZDEwLmlzYy5vcmc="); + + // Unmatched parenthesis should cause a lexer error + checkFromText_LexerError("257 3 5 )YmluZDEwLmlzYy5vcmc="); +} + +TEST_F(Rdata_DNSKEY_Test, assign) { + generic::DNSKEY rdata_dnskey2("257 3 5 YQ=="); + rdata_dnskey2 = rdata_dnskey; + EXPECT_EQ(0, rdata_dnskey.compare(rdata_dnskey2)); +} + +TEST_F(Rdata_DNSKEY_Test, createFromLexer) { + EXPECT_EQ(0, rdata_dnskey.compare( + *test::createRdataUsingLexer(RRType::DNSKEY(), RRClass::IN(), + dnskey_txt))); +} + +TEST_F(Rdata_DNSKEY_Test, toWireRenderer) { + renderer.skip(2); + rdata_dnskey.toWire(renderer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_dnskey_fromWire.wire", data); + matchWireData(&data[2], data.size() - 2, + static_cast<const uint8_t *>(renderer.getData()) + 2, + renderer.getLength() - 2); +} + +TEST_F(Rdata_DNSKEY_Test, toWireBuffer) { + rdata_dnskey.toWire(obuffer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_dnskey_fromWire.wire", data); + matchWireData(&data[2], data.size() - 2, + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_DNSKEY_Test, createFromWire) { + EXPECT_EQ(0, rdata_dnskey.compare( + *rdataFactoryFromFile(RRType("DNSKEY"), RRClass("IN"), + "rdata_dnskey_fromWire.wire"))); + + // Missing keydata is OK + const generic::DNSKEY rdata_dnskey_missing_keydata("257 3 5"); + EXPECT_EQ(0, rdata_dnskey_missing_keydata.compare( + *rdataFactoryFromFile(RRType("DNSKEY"), RRClass("IN"), + "rdata_dnskey_empty_keydata_fromWire.wire"))); +} + +TEST_F(Rdata_DNSKEY_Test, getTag) { + EXPECT_EQ(12892, rdata_dnskey.getTag()); + + // Short keydata with algorithm RSA/MD5 must throw. + const generic::DNSKEY rdata_dnskey_short_keydata1("1 1 1 YQ=="); + EXPECT_THROW(rdata_dnskey_short_keydata1.getTag(), isc::OutOfRange); + + // Short keydata with algorithm not RSA/MD5 must not throw. + const generic::DNSKEY rdata_dnskey_short_keydata2("257 3 5 YQ=="); + EXPECT_NO_THROW(rdata_dnskey_short_keydata2.getTag()); +} + +TEST_F(Rdata_DNSKEY_Test, getAlgorithm) { + EXPECT_EQ(5, rdata_dnskey.getAlgorithm()); +} + +TEST_F(Rdata_DNSKEY_Test, getFlags) { + EXPECT_EQ(257, rdata_dnskey.getFlags()); +} + +} diff --git a/src/lib/dns/tests/rdata_ds_like_unittest.cc b/src/lib/dns/tests/rdata_ds_like_unittest.cc new file mode 100644 index 0000000..d4ea924 --- /dev/null +++ b/src/lib/dns/tests/rdata_ds_like_unittest.cc @@ -0,0 +1,229 @@ +// Copyright (C) 2011-2019 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <algorithm> +#include <string> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +// hacks to make templates work +template <class T> +class RRTYPE : public RRType { +public: + RRTYPE(); +}; + +template<> RRTYPE<generic::DS>::RRTYPE() : RRType(RRType::DS()) {} +template<> RRTYPE<generic::DLV>::RRTYPE() : RRType(RRType::DLV()) {} + +template <class DS_LIKE> +class Rdata_DS_LIKE_Test : public RdataTest { +protected: + Rdata_DS_LIKE_Test() : + ds_like_txt("12892 5 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"), + rdata_ds_like(ds_like_txt) + {} + const string ds_like_txt; + const DS_LIKE rdata_ds_like; +}; + +// The list of types we want to test. +typedef testing::Types<generic::DS, generic::DLV> Implementations; + +#ifdef TYPED_TEST_SUITE +TYPED_TEST_SUITE(Rdata_DS_LIKE_Test, Implementations); +#else +TYPED_TEST_CASE(Rdata_DS_LIKE_Test, Implementations); +#endif + +TYPED_TEST(Rdata_DS_LIKE_Test, createFromText) { + // It's valid for the digest's presentation format to contain + // spaces. See RFC4034 section 5.3. + EXPECT_EQ(0, this->rdata_ds_like.compare( + TypeParam("12892 5 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D5F0EB5" + "C777 58 6DE18 \t DA6B5"))); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, toText_DS_LIKE) { + EXPECT_EQ(this->ds_like_txt, this->rdata_ds_like.toText()); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, badText_DS_LIKE) { + EXPECT_THROW(const TypeParam ds_like2("99999 5 2 BEEF"), InvalidRdataText); + EXPECT_THROW(const TypeParam ds_like2("11111 555 2 BEEF"), + InvalidRdataText); + EXPECT_THROW(const TypeParam ds_like2("11111 5 22222 BEEF"), + InvalidRdataText); + EXPECT_THROW(const TypeParam ds_like2("11111 5 2"), InvalidRdataText); + EXPECT_THROW(const TypeParam ds_like2("GARBAGE IN"), InvalidRdataText); + // no space between the digest type and the digest. + EXPECT_THROW(const TypeParam ds_like2( + "12892 5 2F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"), InvalidRdataText); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, createFromWire_DS_LIKE) { + EXPECT_EQ(0, this->rdata_ds_like.compare( + *this->rdataFactoryFromFile(RRTYPE<TypeParam>(), RRClass::IN(), + "rdata_ds_fromWire"))); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, createFromLexer_DS_LIKE) { + EXPECT_EQ(0, this->rdata_ds_like.compare( + *test::createRdataUsingLexer(RRTYPE<TypeParam>(), RRClass::IN(), + this->ds_like_txt))); + + // Whitespace is okay + EXPECT_EQ(0, this->rdata_ds_like.compare( + *test::createRdataUsingLexer(RRTYPE<TypeParam>(), RRClass::IN(), + "12892 5 2 F1E184C0E1D615D20EB3C223ACED3B0" + "3C773DD952D5F0EB5C777 58 6DE18 \t DA6B5" + ))); + + // Exceptions cause NULL to be returned. + + // Bad tag + EXPECT_FALSE(test::createRdataUsingLexer(RRTYPE<TypeParam>(), RRClass::IN(), + "65536 5 2 BEEF")); + + // Bad algorithm + EXPECT_FALSE(test::createRdataUsingLexer(RRTYPE<TypeParam>(), RRClass::IN(), + "1024 256 2 BEEF")); + + // Bad digest type + EXPECT_FALSE(test::createRdataUsingLexer(RRTYPE<TypeParam>(), RRClass::IN(), + "2048 2 256 BEEF")); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, assignment_DS_LIKE) { + TypeParam copy(this->ds_like_txt); + copy = this->rdata_ds_like; + EXPECT_EQ(0, copy.compare(this->rdata_ds_like)); + + // Check if the copied data is valid even after the original is deleted + TypeParam* copy2 = new TypeParam(this->rdata_ds_like); + TypeParam copy3(this->ds_like_txt); + copy3 = *copy2; + delete copy2; + EXPECT_EQ(0, copy3.compare(this->rdata_ds_like)); + + // Self assignment + copy = *© + EXPECT_EQ(0, copy.compare(this->rdata_ds_like)); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, getTag_DS_LIKE) { + EXPECT_EQ(12892, this->rdata_ds_like.getTag()); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, toWireRenderer) { + Rdata_DS_LIKE_Test<TypeParam>::renderer.skip(2); + TypeParam rdata_ds_like(this->ds_like_txt); + rdata_ds_like.toWire(this->renderer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_ds_fromWire", data); + matchWireData(&data[2], data.size() - 2, + static_cast<const uint8_t*>(this->renderer.getData()) + 2, + this->renderer.getLength() - 2); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, toWireBuffer) { + TypeParam rdata_ds_like(this->ds_like_txt); + rdata_ds_like.toWire(this->obuffer); +} + +string ds_like_txt1("12892 5 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); +// different tag +string ds_like_txt2("12893 5 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); +// different algorithm +string ds_like_txt3("12892 6 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); +// different digest type +string ds_like_txt4("12892 5 3 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); +// different digest +string ds_like_txt5("12892 5 2 F2E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); +// different digest length +string ds_like_txt6("12892 5 2 F2E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B555"); + +TYPED_TEST(Rdata_DS_LIKE_Test, compare) { + const string ds_like_txt1( + "12892 5 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); + // different tag + const string ds_like_txt2( + "12893 5 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); + // different algorithm + const string ds_like_txt3( + "12892 6 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); + // different digest type + const string ds_like_txt4( + "12892 5 3 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); + // different digest + const string ds_like_txt5( + "12892 5 2 F2E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); + // different digest length + const string ds_like_txt6( + "12892 5 2 F2E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B555"); + + // trivial case: self equivalence + EXPECT_EQ(0, TypeParam(this->ds_like_txt). + compare(TypeParam(this->ds_like_txt))); + + // non-equivalence tests + EXPECT_LT(TypeParam(ds_like_txt1).compare(TypeParam(ds_like_txt2)), 0); + EXPECT_GT(TypeParam(ds_like_txt2).compare(TypeParam(ds_like_txt1)), 0); + + EXPECT_LT(TypeParam(ds_like_txt1).compare(TypeParam(ds_like_txt3)), 0); + EXPECT_GT(TypeParam(ds_like_txt3).compare(TypeParam(ds_like_txt1)), 0); + + EXPECT_LT(TypeParam(ds_like_txt1).compare(TypeParam(ds_like_txt4)), 0); + EXPECT_GT(TypeParam(ds_like_txt4).compare(TypeParam(ds_like_txt1)), 0); + + EXPECT_LT(TypeParam(ds_like_txt1).compare(TypeParam(ds_like_txt5)), 0); + EXPECT_GT(TypeParam(ds_like_txt5).compare(TypeParam(ds_like_txt1)), 0); + + EXPECT_LT(TypeParam(ds_like_txt1).compare(TypeParam(ds_like_txt6)), 0); + EXPECT_GT(TypeParam(ds_like_txt6).compare(TypeParam(ds_like_txt1)), 0); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(this->rdata_ds_like.compare(*this->rdata_nomatch), + bad_cast); +} + +} diff --git a/src/lib/dns/tests/rdata_hinfo_unittest.cc b/src/lib/dns/tests/rdata_hinfo_unittest.cc new file mode 100644 index 0000000..1830f05 --- /dev/null +++ b/src/lib/dns/tests/rdata_hinfo_unittest.cc @@ -0,0 +1,154 @@ +// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using namespace isc::dns::rdata::generic; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_HINFO_Test : public RdataTest { +}; + +static uint8_t hinfo_rdata[] = {0x07,0x50,0x65,0x6e,0x74,0x69,0x75,0x6d,0x05, + 0x4c,0x69,0x6e,0x75,0x78}; +static const char *hinfo_str = "\"Pentium\" \"Linux\""; +static const char *hinfo_str1 = "\"Pen\\\"tium\" \"Linux\""; + +static const char *hinfo_str_equal = "\"Pentium\"\"Linux\""; +static const char *hinfo_str_small1 = "\"Lentium\" \"Linux\""; +static const char *hinfo_str_small2 = "\"Pentium\" \"Kinux\""; +static const char *hinfo_str_large1 = "\"Qentium\" \"Linux\""; +static const char *hinfo_str_large2 = "\"Pentium\" \"UNIX\""; + +TEST_F(Rdata_HINFO_Test, createFromText) { + HINFO hinfo(hinfo_str); + EXPECT_EQ(string("Pentium"), hinfo.getCPU()); + EXPECT_EQ(string("Linux"), hinfo.getOS()); + // Test the text with double quotes in the middle of string + HINFO hinfo1(hinfo_str1); + EXPECT_EQ(string("Pen\\\"tium"), hinfo1.getCPU()); +} + +TEST_F(Rdata_HINFO_Test, badText) { + // Only 2 fields must exist + EXPECT_THROW(const HINFO hinfo("\"Pentium\"\"Linux\"\"Computer\""), + InvalidRdataText); + EXPECT_THROW(const HINFO hinfo("\"Pentium\" \"Linux\" \"Computer\""), + InvalidRdataText); + // Field cannot be missing + EXPECT_THROW(const HINFO hinfo("Pentium"), InvalidRdataText); + // The <character-string> cannot exceed 255 characters + string hinfo_str; + for (int i = 0; i < 257; ++i) { + hinfo_str += 'A'; + } + hinfo_str += " Linux"; + EXPECT_THROW(const HINFO hinfo(hinfo_str), CharStringTooLong); +} + +TEST_F(Rdata_HINFO_Test, createFromWire) { + InputBuffer input_buffer(hinfo_rdata, sizeof(hinfo_rdata)); + HINFO hinfo(input_buffer, sizeof(hinfo_rdata)); + EXPECT_EQ(string("Pentium"), hinfo.getCPU()); + EXPECT_EQ(string("Linux"), hinfo.getOS()); +} + +TEST_F(Rdata_HINFO_Test, createFromLexer) { + HINFO rdata_hinfo(hinfo_str); + EXPECT_EQ(0, rdata_hinfo.compare( + *test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(), + hinfo_str))); + EXPECT_EQ(0, rdata_hinfo.compare( + *test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(), + "\"Pentium\"\"Linux\""))); + // Exceptions cause NULL to be returned. + EXPECT_FALSE(test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(), + "\"Pentium\"\"Linux\"" + "\"Computer\"")); + EXPECT_FALSE(test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(), + "\"Pentium\" \"Linux\" " + "\"Computer\"")); + EXPECT_FALSE(test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(), + "\"Pentium\"")); +} + +TEST_F(Rdata_HINFO_Test, toText) { + HINFO hinfo(hinfo_str); + EXPECT_EQ(hinfo_str, hinfo.toText()); + + // will add quotes even if they were not in the original input + EXPECT_EQ("\"a\" \"b\"", HINFO("a b").toText()); + // will not add additional quotes + EXPECT_EQ("\"a\" \"b\"", HINFO("\"a\" \"b\"").toText()); + // And make sure escaped quotes and spaces are left intact + EXPECT_EQ("\"a\\\"\" \"b c\"", HINFO("\"a\\\"\" \"b c\"").toText()); +} + +TEST_F(Rdata_HINFO_Test, toWire) { + HINFO hinfo(hinfo_str); + + hinfo.toWire(obuffer); + matchWireData(hinfo_rdata, sizeof (hinfo_rdata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_HINFO_Test, toWireRenderer) { + HINFO hinfo(hinfo_str); + + hinfo.toWire(renderer); + matchWireData(hinfo_rdata, sizeof (hinfo_rdata), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_HINFO_Test, compare) { + HINFO hinfo(hinfo_str); + HINFO hinfo_small1(hinfo_str_small1); + HINFO hinfo_small2(hinfo_str_small2); + HINFO hinfo_large1(hinfo_str_large1); + HINFO hinfo_large2(hinfo_str_large2); + + EXPECT_EQ(0, hinfo.compare(HINFO(hinfo_str))); + EXPECT_EQ(0, hinfo.compare(HINFO(hinfo_str_equal))); + EXPECT_EQ(1, hinfo.compare(HINFO(hinfo_str_small1))); + EXPECT_EQ(1, hinfo.compare(HINFO(hinfo_str_small2))); + EXPECT_EQ(-1, hinfo.compare(HINFO(hinfo_str_large1))); + EXPECT_EQ(-1, hinfo.compare(HINFO(hinfo_str_large2))); +} + +// Copy/assign test +TEST_F(Rdata_HINFO_Test, copy) { + HINFO hinfo(hinfo_str); + HINFO hinfo2(hinfo); + HINFO hinfo3 = hinfo; + + EXPECT_EQ(0, hinfo.compare(hinfo2)); + EXPECT_EQ(0, hinfo.compare(hinfo3)); + + hinfo3 = hinfo; + EXPECT_EQ(0, hinfo.compare(hinfo3)); +} + +} diff --git a/src/lib/dns/tests/rdata_in_a_unittest.cc b/src/lib/dns/tests/rdata_in_a_unittest.cc new file mode 100644 index 0000000..809cfb5 --- /dev/null +++ b/src/lib/dns/tests/rdata_in_a_unittest.cc @@ -0,0 +1,159 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/rdataclass.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/master_lexer.h> +#include <dns/master_loader.h> +#include <dns/rdata.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +#include <sstream> + +#include <arpa/inet.h> +#include <sys/socket.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_IN_A_Test : public RdataTest { +protected: + Rdata_IN_A_Test() : rdata_in_a("192.0.2.1") {} + + void checkFromTextIN_A(const std::string& rdata_txt, + bool throw_str_version = true, + bool throw_lexer_version = true) { + checkFromText<in::A, InvalidRdataText, InvalidRdataText>( + rdata_txt, rdata_in_a, throw_str_version, throw_lexer_version); + } + + const in::A rdata_in_a; +}; + +const uint8_t wiredata_in_a[] = { 192, 0, 2, 1 }; + +TEST_F(Rdata_IN_A_Test, createFromText) { + // Normal case: no exception for either case, so the exception type + // doesn't matter. + checkFromText<in::A, isc::Exception, isc::Exception>("192.0.2.1", + rdata_in_a, false, + false); + + // should reject an abbreviated form of IPv4 address + checkFromTextIN_A("10.1"); + // or an IPv6 address + checkFromTextIN_A("2001:db8::1234"); + // or any meaningless text as an IP address + checkFromTextIN_A("xxx"); + + // NetBSD's inet_pton accepts trailing space after an IPv4 address, which + // would confuse some of the tests below. We check the case differently + // in these cases depending on the strictness of inet_pton (most + // implementations seem to be stricter). + uint8_t v4addr_buf[4]; + const bool reject_extra_space = + inet_pton(AF_INET, "192.0.2.1 ", v4addr_buf) == 0; + + // trailing white space: only string version throws + checkFromTextIN_A("192.0.2.1 ", reject_extra_space, false); + // same for beginning white space. + checkFromTextIN_A(" 192.0.2.1", true, false); + // same for trailing non-space garbage (note that lexer version still + // ignore it; it's expected to be detected at a higher layer). + checkFromTextIN_A("192.0.2.1 xxx", reject_extra_space, false); + + // nul character after a valid textual representation. + string nul_after_addr = "192.0.2.1"; + nul_after_addr.push_back(0); + checkFromTextIN_A(nul_after_addr, true, true); + + // a valid address surrounded by parentheses; only okay with lexer + checkFromTextIN_A("(192.0.2.1)", true, false); + + // input that would cause lexer-specific error; it's bad text as an + // address so should result in the string version, too. + checkFromText<in::A, InvalidRdataText, MasterLexer::LexerError>( + ")192.0.2.1", rdata_in_a); +} + +TEST_F(Rdata_IN_A_Test, createFromWire) { + // Valid data + EXPECT_EQ(0, rdata_in_a.compare( + *rdataFactoryFromFile(RRType::A(), RRClass::IN(), + "rdata_in_a_fromWire"))); + // RDLENGTH is too short + EXPECT_THROW(rdataFactoryFromFile(RRType::A(), RRClass::IN(), + "rdata_in_a_fromWire", 6), + DNSMessageFORMERR); + // RDLENGTH is too long + EXPECT_THROW(rdataFactoryFromFile(RRType::A(), RRClass::IN(), + "rdata_in_a_fromWire", 12), + DNSMessageFORMERR); + // buffer too short. + EXPECT_THROW(rdataFactoryFromFile(RRType::A(), RRClass::IN(), + "rdata_in_a_fromWire", 19), + DNSMessageFORMERR); +} + +TEST_F(Rdata_IN_A_Test, toWireBuffer) { + rdata_in_a.toWire(obuffer); + matchWireData(wiredata_in_a, sizeof (wiredata_in_a), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_IN_A_Test, toWireRenderer) { + rdata_in_a.toWire(renderer); + matchWireData(wiredata_in_a, sizeof (wiredata_in_a), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_IN_A_Test, toText) { + EXPECT_EQ("192.0.2.1", rdata_in_a.toText()); + + // this shouldn't make the code crash + const string longaddr("255.255.255.255"); + EXPECT_EQ(longaddr, in::A(longaddr).toText()); +} + +TEST_F(Rdata_IN_A_Test, compare) { + const in::A small1("1.1.1.1"); + const in::A small2("1.2.3.4"); + const in::A large1("255.255.255.255"); + const in::A large2("4.3.2.1"); + + // trivial case: self equivalence + // cppcheck-suppress uselessCallsCompare + EXPECT_EQ(0, small1.compare(small1)); + + // confirm these are compared as unsigned values + EXPECT_GT(0, small1.compare(large1)); + EXPECT_LT(0, large1.compare(small1)); + + // confirm these are compared in network byte order + EXPECT_GT(0, small2.compare(large2)); + EXPECT_LT(0, large2.compare(small2)); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(rdata_in_a.compare(*RdataTest::rdata_nomatch), bad_cast); +} +} diff --git a/src/lib/dns/tests/rdata_in_aaaa_unittest.cc b/src/lib/dns/tests/rdata_in_aaaa_unittest.cc new file mode 100644 index 0000000..cc7b07d --- /dev/null +++ b/src/lib/dns/tests/rdata_in_aaaa_unittest.cc @@ -0,0 +1,151 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_IN_AAAA_Test : public RdataTest { +protected: + Rdata_IN_AAAA_Test() : rdata_in_aaaa("2001:db8::1234") {} + + // Common check to see the result of in::A Rdata construction either from + // std::string or with MasterLexer object. If it's expected to succeed + // the result should be identical to the commonly used test data + // (rdata_in_a); otherwise it should result in the exception specified as + // the template parameter. + void checkFromTextIN_AAAA(const string& in_aaaa_txt, + bool throw_str_version = true, + bool throw_lexer_version = true) + { + checkFromText<in::AAAA, InvalidRdataText, InvalidRdataText>( + in_aaaa_txt, rdata_in_aaaa, throw_str_version, + throw_lexer_version); + } + + const in::AAAA rdata_in_aaaa; +}; + +const uint8_t wiredata_in_aaaa[] = { + 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x12, 0x34 }; + +TEST_F(Rdata_IN_AAAA_Test, createFromText) { + // Normal case: no exception for either case, so the exception type + // doesn't matter. + checkFromText<in::AAAA, isc::Exception, isc::Exception>( + "2001:db8::1234", rdata_in_aaaa, false, false); + + // should reject an IP4 address. + checkFromTextIN_AAAA("192.0.2.1"); + // or any meaningless text as an IPv6 address + checkFromTextIN_AAAA("xxx"); + + // trailing white space: only string version throws + checkFromTextIN_AAAA("2001:db8::1234 ", true, false); + // same for beginning white space. + checkFromTextIN_AAAA(" 2001:db8::1234", true, false); + // same for trailing non-space garbage (note that lexer version still + // ignore it; it's expected to be detected at a higher layer). + checkFromTextIN_AAAA("2001:db8::1234 xxx", true, false); + + // nul character after a valid textual representation. + string nul_after_addr = "2001:db8::1234"; + nul_after_addr.push_back(0); + checkFromTextIN_AAAA(nul_after_addr, true, true); + + // a valid address surrounded by parentheses; only okay with lexer + checkFromTextIN_AAAA("(2001:db8::1234)", true, false); + + // input that would cause lexer-specific error; it's bad text as an + // address so should result in the string version, too. + checkFromText<in::AAAA, InvalidRdataText, MasterLexer::LexerError>( + ")2001:db8::1234", rdata_in_aaaa); +} + +TEST_F(Rdata_IN_AAAA_Test, createFromWire) { + // Valid data + EXPECT_EQ(0, rdata_in_aaaa.compare( + *rdataFactoryFromFile(RRType::AAAA(), RRClass::IN(), + "rdata_in_aaaa_fromWire"))); + // RDLENGTH is too short + EXPECT_THROW(rdataFactoryFromFile(RRType::AAAA(), RRClass::IN(), + "rdata_in_aaaa_fromWire", 18), + DNSMessageFORMERR); + // RDLENGTH is too long + EXPECT_THROW(rdataFactoryFromFile(RRType::AAAA(), RRClass::IN(), + "rdata_in_aaaa_fromWire", 36), + DNSMessageFORMERR); + // buffer too short. + EXPECT_THROW(rdataFactoryFromFile(RRType::AAAA(), RRClass::IN(), + "rdata_in_aaaa_fromWire", 55), + DNSMessageFORMERR); +} + +TEST_F(Rdata_IN_AAAA_Test, createFromLexer) { + EXPECT_EQ(0, rdata_in_aaaa.compare( + *test::createRdataUsingLexer(RRType::AAAA(), RRClass::IN(), + "2001:db8::1234"))); +} + +TEST_F(Rdata_IN_AAAA_Test, toWireBuffer) { + rdata_in_aaaa.toWire(obuffer); + matchWireData(wiredata_in_aaaa, sizeof (wiredata_in_aaaa), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_IN_AAAA_Test, toWireRenderer) { + rdata_in_aaaa.toWire(renderer); + matchWireData(wiredata_in_aaaa, sizeof (wiredata_in_aaaa), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_IN_AAAA_Test, toText) { + EXPECT_EQ("2001:db8::1234", rdata_in_aaaa.toText()); +} + +TEST_F(Rdata_IN_AAAA_Test, compare) { + in::AAAA small1("::1"); + in::AAAA small2("1:2:3:4:5:6:7:8"); + in::AAAA large1("ffff::"); + in::AAAA large2("8:7:6:5:4:3:2:1"); + + // trivial case: self equivalence + // cppcheck-suppress uselessCallsCompare + EXPECT_EQ(0, small1.compare(small1)); + + // confirm these are compared as unsigned values + EXPECT_GT(0, small1.compare(large1)); + EXPECT_LT(0, large1.compare(small1)); + + // confirm these are compared in network byte order + EXPECT_GT(0, small2.compare(large2)); + EXPECT_LT(0, large2.compare(small2)); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(rdata_in_aaaa.compare(*RdataTest::rdata_nomatch), bad_cast); +} +} diff --git a/src/lib/dns/tests/rdata_minfo_unittest.cc b/src/lib/dns/tests/rdata_minfo_unittest.cc new file mode 100644 index 0000000..35ff55c --- /dev/null +++ b/src/lib/dns/tests/rdata_minfo_unittest.cc @@ -0,0 +1,230 @@ +// Copyright (C) 2011-2019 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::util; +using namespace isc::dns; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_MINFO_Test : public RdataTest { +protected: + Rdata_MINFO_Test(): + minfo_txt("rmailbox.example.com. emailbox.example.com."), + minfo_txt2("root.example.com. emailbox.example.com."), + too_long_label("01234567890123456789012345678901234567" + "89012345678901234567890123."), + rdata_minfo(minfo_txt), + rdata_minfo2(minfo_txt2) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<generic::MINFO, isc::Exception, isc::Exception>( + rdata_str, rdata_minfo, false, false); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::MINFO, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_minfo, true, true); + } + + void checkFromText_TooLongLabel(const string& rdata_str) { + checkFromText<generic::MINFO, TooLongLabel, TooLongLabel>( + rdata_str, rdata_minfo, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText<generic::MINFO, InvalidRdataText, isc::Exception>( + rdata_str, rdata_minfo, true, false); + } + + void checkFromText_EmptyLabel(const string& rdata_str) { + checkFromText<generic::MINFO, EmptyLabel, EmptyLabel>( + rdata_str, rdata_minfo, true, true); + } + + void checkFromText_MissingOrigin(const string& rdata_str) { + checkFromText + <generic::MINFO, MissingNameOrigin, MissingNameOrigin>( + rdata_str, rdata_minfo, true, true); + } + + void checkFromText_Origin(const string& rdata_str, const Name* origin) { + checkFromText<generic::MINFO, MissingNameOrigin, isc::Exception>( + rdata_str, rdata_minfo, true, false, origin); + } + + const string minfo_txt; + const string minfo_txt2; + const string too_long_label; + const generic::MINFO rdata_minfo; + const generic::MINFO rdata_minfo2; +}; + + +TEST_F(Rdata_MINFO_Test, createFromText) { + EXPECT_EQ(Name("rmailbox.example.com."), rdata_minfo.getRmailbox()); + EXPECT_EQ(Name("emailbox.example.com."), rdata_minfo.getEmailbox()); + + EXPECT_EQ(Name("root.example.com."), rdata_minfo2.getRmailbox()); + EXPECT_EQ(Name("emailbox.example.com."), rdata_minfo2.getEmailbox()); + + checkFromText_None(minfo_txt); + + // origin defined for lexer constructor, but not string constructor + const Name origin("example.com"); + checkFromText_Origin("rmailbox emailbox", &origin); + + // lexer constructor accepts extra text, but string constructor doesn't + checkFromText_BadString("rmailbox.example.com. emailbox.example.com. " + "extra.example.com."); +} + +TEST_F(Rdata_MINFO_Test, badText) { + // too long names + checkFromText_TooLongLabel("root.example.com." + too_long_label + + " emailbox.example.com."); + checkFromText_TooLongLabel("root.example.com. emailbox.example.com." + + too_long_label); + + // invalid names + checkFromText_EmptyLabel("root..example.com. emailbox.example.com."); + checkFromText_EmptyLabel("root.example.com. emailbox..example.com."); + + // missing name + checkFromText_LexerError("root.example.com."); + + // missing origin + checkFromText_MissingOrigin("root.example.com emailbox.example.com."); + checkFromText_MissingOrigin("root.example.com. emailbox.example.com"); +} + +TEST_F(Rdata_MINFO_Test, createFromWire) { + // uncompressed names + EXPECT_EQ(0, rdata_minfo.compare( + *rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(), + "rdata_minfo_fromWire1.wire"))); + // compressed names + EXPECT_EQ(0, rdata_minfo.compare( + *rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(), + "rdata_minfo_fromWire2.wire", 15))); + // RDLENGTH is too short + EXPECT_THROW(rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(), + "rdata_minfo_fromWire3.wire"), + InvalidRdataLength); + // RDLENGTH is too long + EXPECT_THROW(rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(), + "rdata_minfo_fromWire4.wire"), + InvalidRdataLength); + // bogus rmailbox name, the error should be detected in the name + // constructor + EXPECT_THROW(rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(), + "rdata_minfo_fromWire5.wire"), + DNSMessageFORMERR); + // bogus emailbox name, the error should be detected in the name + // constructor + EXPECT_THROW(rdataFactoryFromFile(RRType::MINFO(), RRClass::IN(), + "rdata_minfo_fromWire6.wire"), + DNSMessageFORMERR); +} + +TEST_F(Rdata_MINFO_Test, assignment) { + generic::MINFO copy((string(minfo_txt2))); + copy = rdata_minfo; + EXPECT_EQ(0, copy.compare(rdata_minfo)); + + // Check if the copied data is valid even after the original is deleted + generic::MINFO* copy2 = new generic::MINFO(rdata_minfo); + generic::MINFO copy3((string(minfo_txt2))); + copy3 = *copy2; + delete copy2; + EXPECT_EQ(0, copy3.compare(rdata_minfo)); + + // Self assignment + copy = *© + EXPECT_EQ(0, copy.compare(rdata_minfo)); +} + +TEST_F(Rdata_MINFO_Test, toWireBuffer) { + rdata_minfo.toWire(obuffer); + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_minfo_toWireUncompressed1.wire", data); + matchWireData(&data[0], data.size(), + obuffer.getData(), obuffer.getLength()); + + obuffer.clear(); + rdata_minfo2.toWire(obuffer); + vector<unsigned char> data2; + UnitTestUtil::readWireData("rdata_minfo_toWireUncompressed2.wire", data2); + matchWireData(&data2[0], data2.size(), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_MINFO_Test, toWireRenderer) { + rdata_minfo.toWire(renderer); + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_minfo_toWire1.wire", data); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); + + renderer.clear(); + rdata_minfo2.toWire(renderer); + vector<unsigned char> data2; + UnitTestUtil::readWireData("rdata_minfo_toWire2.wire", data2); + matchWireData(&data2[0], data2.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_MINFO_Test, toText) { + EXPECT_EQ(minfo_txt, rdata_minfo.toText()); + EXPECT_EQ(minfo_txt2, rdata_minfo2.toText()); +} + +TEST_F(Rdata_MINFO_Test, compare) { + // check reflexivity + EXPECT_EQ(0, rdata_minfo.compare(rdata_minfo)); + + // names must be compared in case-insensitive manner + EXPECT_EQ(0, rdata_minfo.compare(generic::MINFO("RMAILBOX.example.com. " + "emailbox.EXAMPLE.com."))); + + // another MINFO whose rmailbox name is larger than that of rdata_minfo. + const generic::MINFO large1_minfo("zzzzzzzz.example.com. " + "emailbox.example.com."); + EXPECT_GT(0, rdata_minfo.compare(large1_minfo)); + EXPECT_LT(0, large1_minfo.compare(rdata_minfo)); + + // another MINFO whose emailbox name is larger than that of rdata_minfo. + const generic::MINFO large2_minfo("rmailbox.example.com. " + "zzzzzzzzzzz.example.com."); + EXPECT_GT(0, rdata_minfo.compare(large2_minfo)); + EXPECT_LT(0, large2_minfo.compare(rdata_minfo)); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(rdata_minfo.compare(*RdataTest::rdata_nomatch), bad_cast); +} +} diff --git a/src/lib/dns/tests/rdata_mx_unittest.cc b/src/lib/dns/tests/rdata_mx_unittest.cc new file mode 100644 index 0000000..b11411f --- /dev/null +++ b/src/lib/dns/tests/rdata_mx_unittest.cc @@ -0,0 +1,147 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_MX_Test : public RdataTest { +public: + Rdata_MX_Test() : + rdata_mx(10, Name("mx.example.com")) + {} + + const generic::MX rdata_mx; +}; + +TEST_F(Rdata_MX_Test, createFromText) { + const generic::MX rdata_mx2("10 mx.example.com."); + EXPECT_EQ(0, rdata_mx2.compare(rdata_mx)); +} + +TEST_F(Rdata_MX_Test, badText) { + EXPECT_THROW(const generic::MX rdata_mx("99999999 mx."), InvalidRdataText); + EXPECT_THROW(const generic::MX rdata_mx("10"), InvalidRdataText); + EXPECT_THROW(const generic::MX rdata_mx("SPOON"), InvalidRdataText); + EXPECT_THROW(const generic::MX rdata_mx("10 mx. example.com."), + InvalidRdataText); + // No origin and relative + EXPECT_THROW(const generic::MX rdata_mx("10 mx.example.com"), + MissingNameOrigin); + // Extra text at end of line + EXPECT_THROW(const generic::MX rdata_mx("10 mx.example.com. extra."), + InvalidRdataText); +} + +TEST_F(Rdata_MX_Test, copy) { + const generic::MX rdata_mx2(rdata_mx); + EXPECT_EQ(0, rdata_mx.compare(rdata_mx2)); +} + +TEST_F(Rdata_MX_Test, createFromWire) { + EXPECT_EQ(0, rdata_mx.compare( + *rdataFactoryFromFile(RRType("MX"), RRClass("IN"), + "rdata_mx_fromWire"))); + // TBD: more tests +} + +TEST_F(Rdata_MX_Test, createFromLexer) { + EXPECT_EQ(0, rdata_mx.compare( + *test::createRdataUsingLexer(RRType::MX(), RRClass::IN(), + "10 mx.example.com."))); + + // test::createRdataUsingLexer() constructs relative to + // "example.org." origin. + EXPECT_EQ(0, generic::MX("10 mx2.example.org.").compare( + *test::createRdataUsingLexer(RRType::MX(), RRClass::IN(), + "10 mx2"))); + + // Exceptions cause NULL to be returned. + EXPECT_FALSE(test::createRdataUsingLexer(RRType::MX(), RRClass::IN(), + "10 mx. example.com.")); + + // 65536 is larger than maximum possible preference + EXPECT_FALSE(test::createRdataUsingLexer(RRType::MX(), RRClass::IN(), + "65536 mx.example.com.")); + + // Extra text at end of line + EXPECT_FALSE(test::createRdataUsingLexer(RRType::MX(), RRClass::IN(), + "10 mx.example.com. extra.")); +} + +TEST_F(Rdata_MX_Test, toWireRenderer) { + renderer.writeName(Name("example.com")); + rdata_mx.toWire(renderer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_mx_toWire1", data); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_MX_Test, toWireBuffer) { + Name("example.com").toWire(obuffer); + rdata_mx.toWire(obuffer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_mx_toWire2", data); + matchWireData(&data[0], data.size(), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_MX_Test, toText) { + EXPECT_EQ("10 mx.example.com.", rdata_mx.toText()); +} + +TEST_F(Rdata_MX_Test, getMXName) { + EXPECT_EQ(Name("mx.example.com."), rdata_mx.getMXName()); +} + +TEST_F(Rdata_MX_Test, getMXPref) { + EXPECT_EQ(10, rdata_mx.getMXPref()); +} + +TEST_F(Rdata_MX_Test, compare) { + generic::MX small1(1, Name("mx.example.com")); + generic::MX small2(10, Name("mx.example.com")); + generic::MX large1(65535, Name("mx.example.com")); + generic::MX large2(256, Name("mx.example.com")); + + // trivial case: self equivalence + // cppcheck-suppress uselessCallsCompare + EXPECT_EQ(0, small1.compare(small1)); + + // confirm these are compared as unsigned values + EXPECT_GT(0, small1.compare(large1)); + EXPECT_LT(0, large1.compare(small1)); + + // confirm these are compared in network byte order + EXPECT_GT(0, small2.compare(large2)); + EXPECT_LT(0, large2.compare(small2)); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(rdata_mx.compare(*rdata_nomatch), bad_cast); +} +} diff --git a/src/lib/dns/tests/rdata_naptr_unittest.cc b/src/lib/dns/tests/rdata_naptr_unittest.cc new file mode 100644 index 0000000..4ce008e --- /dev/null +++ b/src/lib/dns/tests/rdata_naptr_unittest.cc @@ -0,0 +1,239 @@ +// Copyright (C) 2011-2015,2021 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using namespace isc::dns::rdata::generic; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_NAPTR_Test : public RdataTest { +}; + +// 10 100 "S" "SIP+D2U" "" _sip._udp.example.com. +static uint8_t naptr_rdata[] = {0x00,0x0a,0x00,0x64,0x01,0x53,0x07,0x53,0x49, + 0x50,0x2b,0x44,0x32,0x55,0x00,0x04,0x5f,0x73,0x69,0x70,0x04,0x5f,0x75,0x64, + 0x70,0x07,0x65,0x78,0x61,0x6d,0x70,0x6c,0x65,0x03,0x63,0x6f,0x6d,0x00}; + +static const char *naptr_str = + "10 100 \"S\" \"SIP+D2U\" \"\" _sip._udp.example.com."; +static const char *naptr_str2 = + "10 100 S SIP+D2U \"\" _sip._udp.example.com."; + +static const char *naptr_str_small1 = + "9 100 \"S\" \"SIP+D2U\" \"\" _sip._udp.example.com."; +static const char *naptr_str_small2 = + "10 90 \"S\" \"SIP+D2U\" \"\" _sip._udp.example.com."; +static const char *naptr_str_small3 = + "10 100 \"R\" \"SIP+D2U\" \"\" _sip._udp.example.com."; +static const char *naptr_str_small4 = + "10 100 \"S\" \"SIP+C2U\" \"\" _sip._udp.example.com."; +static const char *naptr_str_small5 = + "10 100 \"S\" \"SIP+D2U\" \"\" _rip._udp.example.com."; + +static const char *naptr_str_large1 = + "11 100 \"S\" \"SIP+D2U\" \"\" _sip._udp.example.com."; +static const char *naptr_str_large2 = + "10 110 \"S\" \"SIP+D2U\" \"\" _sip._udp.example.com."; +static const char *naptr_str_large3 = + "10 100 \"T\" \"SIP+D2U\" \"\" _sip._udp.example.com."; +static const char *naptr_str_large4 = + "10 100 \"S\" \"SIP+E2U\" \"\" _sip._udp.example.com."; +static const char *naptr_str_large5 = + "10 100 \"S\" \"SIP+D2U\" \"\" _tip._udp.example.com."; + +TEST_F(Rdata_NAPTR_Test, createFromText) { + NAPTR naptr(naptr_str); + EXPECT_EQ(10, naptr.getOrder()); + EXPECT_EQ(100, naptr.getPreference()); + EXPECT_EQ(string("S"), naptr.getFlags()); + EXPECT_EQ(string("SIP+D2U"), naptr.getServices()); + EXPECT_EQ(string(""), naptr.getRegexp()); + EXPECT_EQ(Name("_sip._udp.example.com."), naptr.getReplacement()); + + // Test <char-string> that separated by space + NAPTR naptr2(naptr_str2); + EXPECT_EQ(string("S"), naptr2.getFlags()); + EXPECT_EQ(string("SIP+D2U"), naptr2.getServices()); +} + +TEST_F(Rdata_NAPTR_Test, badText) { + // Order number cannot exceed 65535 + EXPECT_THROW(const NAPTR naptr("65536 10 S SIP \"\" _sip._udp.example.com."), + InvalidRdataText); + // Preference number cannot exceed 65535 + EXPECT_THROW(const NAPTR naptr("100 65536 S SIP \"\" _sip._udp.example.com."), + InvalidRdataText); + // No regexp given + EXPECT_THROW(const NAPTR naptr("100 10 S SIP _sip._udp.example.com."), + InvalidRdataText); + // The double quotes seperator must match + EXPECT_THROW(const NAPTR naptr("100 10 \"S SIP \"\" _sip._udp.example.com."), + InvalidRdataText); + // Order or preference cannot be missed + EXPECT_THROW(const NAPTR naptr("10 \"S\" SIP \"\" _sip._udp.example.com."), + InvalidRdataText); + // Unquoted fields must be separated by spaces + EXPECT_THROW(const NAPTR naptr("100 10S SIP \"\" _sip._udp.example.com."), + InvalidRdataText); + EXPECT_THROW(const NAPTR naptr("10010 \"S\" \"SIP\" \"\" _sip._udp.example.com."), + InvalidRdataText); + EXPECT_THROW(const NAPTR naptr("100 10 SSIP \"\" _sip._udp.example.com."), + InvalidRdataText); + // Field cannot be missing + EXPECT_THROW(const NAPTR naptr("100 10 \"S\""), InvalidRdataText); + + // The <character-string> cannot exceed 255 characters + string naptr_str; + naptr_str += "100 10 "; + for (int i = 0; i < 257; ++i) { + naptr_str += 'A'; + } + naptr_str += " SIP \"\" _sip._udp.example.com."; + EXPECT_THROW(const NAPTR naptr(naptr_str), CharStringTooLong); +} + +TEST_F(Rdata_NAPTR_Test, createFromWire) { + InputBuffer input_buffer(naptr_rdata, sizeof(naptr_rdata)); + NAPTR naptr(input_buffer, sizeof(naptr_rdata)); + EXPECT_EQ(10, naptr.getOrder()); + EXPECT_EQ(100, naptr.getPreference()); + EXPECT_EQ(string("S"), naptr.getFlags()); + EXPECT_EQ(string("SIP+D2U"), naptr.getServices()); + EXPECT_EQ(string(""), naptr.getRegexp()); + EXPECT_EQ(Name("_sip._udp.example.com."), naptr.getReplacement()); +} + +TEST_F(Rdata_NAPTR_Test, createFromWireTooLongDataLen) { + static uint8_t naptr_rdata_long[] = { + 0x00,0x0a,0x00,0x64,0x01,0x53,0x07,0x53,0x49,0x50,0x2b,0x44,0x32,0x55, + 0x00,0x04,0x5f,0x73,0x69,0x70,0x04,0x5f,0x75,0x64,0x70,0x07,0x65,0x78, + 0x61,0x6d,0x70,0x6c,0x65,0x03,0x63,0x6f,0x6d,0x00,0xff,0xff,0xff,0xff}; + InputBuffer input_buffer(naptr_rdata_long, sizeof(naptr_rdata_long)); + EXPECT_THROW(NAPTR naptr(input_buffer, sizeof(naptr_rdata_long)), + isc::dns::DNSMessageFORMERR); +} + +TEST_F(Rdata_NAPTR_Test, createFromWireTooShortDataLen) { + // missing data (just set rdata_len too low) + for (size_t i = 0; i < sizeof(naptr_rdata); ++i) { + // Just use existing correct buffer but set rdata_len too low + InputBuffer input_buffer(naptr_rdata, sizeof(naptr_rdata)); + EXPECT_THROW(NAPTR naptr(input_buffer, i), + isc::dns::DNSMessageFORMERR); + } +} + +TEST_F(Rdata_NAPTR_Test, createFromLexer) { + const NAPTR rdata_naptr(naptr_str); + + EXPECT_EQ(0, rdata_naptr.compare( + *test::createRdataUsingLexer(RRType::NAPTR(), RRClass::IN(), + naptr_str))); + + // Exceptions cause NULL to be returned. + EXPECT_FALSE(test::createRdataUsingLexer(RRType::NAPTR(), RRClass::IN(), + "65536 10 S SIP \"\" " + "_sip._udp.example.com.")); +} + +TEST_F(Rdata_NAPTR_Test, toWire) { + NAPTR naptr(naptr_str); + + naptr.toWire(obuffer); + matchWireData(naptr_rdata, sizeof(naptr_rdata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_NAPTR_Test, toWireRenderer) { + NAPTR naptr(naptr_str); + + naptr.toWire(renderer); + matchWireData(naptr_rdata, sizeof(naptr_rdata), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_NAPTR_Test, toText) { + NAPTR naptr(naptr_str); + EXPECT_EQ(naptr_str, naptr.toText()); + + // will add quotes even if they were not in the original input + EXPECT_EQ("10 100 \"S\" \"SIP+D2U\" \".*\" _sip._udp.example.com.", + NAPTR("10 100 S SIP+D2U .* _sip._udp.example.com.").toText()); + // will not add additional quotes + EXPECT_EQ("10 100 \"S\" \"SIP+D2U\" \".*\" _sip._udp.example.com.", + NAPTR("10 100 \"S\" \"SIP+D2U\" \".*\" _sip._udp.example.com.") + .toText()); +} + +TEST_F(Rdata_NAPTR_Test, compare) { + NAPTR naptr(naptr_str); + NAPTR naptr_small1(naptr_str_small1); + NAPTR naptr_small2(naptr_str_small2); + NAPTR naptr_small3(naptr_str_small3); + NAPTR naptr_small4(naptr_str_small4); + NAPTR naptr_small5(naptr_str_small5); + NAPTR naptr_large1(naptr_str_large1); + NAPTR naptr_large2(naptr_str_large2); + NAPTR naptr_large3(naptr_str_large3); + NAPTR naptr_large4(naptr_str_large4); + NAPTR naptr_large5(naptr_str_large5); + + EXPECT_EQ(0, naptr.compare(NAPTR(naptr_str))); + EXPECT_EQ(1, naptr.compare(naptr_small1)); + EXPECT_EQ(1, naptr.compare(naptr_small2)); + EXPECT_EQ(1, naptr.compare(naptr_small3)); + EXPECT_EQ(1, naptr.compare(naptr_small4)); + EXPECT_EQ(1, naptr.compare(naptr_small5)); + EXPECT_EQ(-1, naptr.compare(naptr_large1)); + EXPECT_EQ(-1, naptr.compare(naptr_large2)); + EXPECT_EQ(-1, naptr.compare(naptr_large3)); + EXPECT_EQ(-1, naptr.compare(naptr_large4)); + EXPECT_EQ(-1, naptr.compare(naptr_large5)); + EXPECT_EQ(-1, naptr_small1.compare(naptr)); + EXPECT_EQ(-1, naptr_small2.compare(naptr)); + EXPECT_EQ(-1, naptr_small3.compare(naptr)); + EXPECT_EQ(-1, naptr_small4.compare(naptr)); + EXPECT_EQ(-1, naptr_small5.compare(naptr)); + EXPECT_EQ(1, naptr_large1.compare(naptr)); + EXPECT_EQ(1, naptr_large2.compare(naptr)); + EXPECT_EQ(1, naptr_large3.compare(naptr)); + EXPECT_EQ(1, naptr_large4.compare(naptr)); + EXPECT_EQ(1, naptr_large5.compare(naptr)); +} + +TEST_F(Rdata_NAPTR_Test, copy) { + NAPTR naptr(naptr_str); + NAPTR naptr2(naptr); + NAPTR naptr3 = naptr; + + EXPECT_EQ(0, naptr.compare(naptr2)); + EXPECT_EQ(0, naptr.compare(naptr3)); + + naptr3 = naptr; + EXPECT_EQ(0, naptr.compare(naptr3)); +} + +} diff --git a/src/lib/dns/tests/rdata_ns_unittest.cc b/src/lib/dns/tests/rdata_ns_unittest.cc new file mode 100644 index 0000000..31bb508 --- /dev/null +++ b/src/lib/dns/tests/rdata_ns_unittest.cc @@ -0,0 +1,145 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_NS_Test : public RdataTest { +public: + Rdata_NS_Test() : + rdata_ns("ns.example.com."), + rdata_ns2("ns2.example.com.") + {} + + const generic::NS rdata_ns; + const generic::NS rdata_ns2; +}; + +const uint8_t wiredata_ns[] = { + 0x02, 0x6e, 0x73, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, + 0x63, 0x6f, 0x6d, 0x00 }; +const uint8_t wiredata_ns2[] = { + // first name: ns.example.com. + 0x02, 0x6e, 0x73, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, + 0x63, 0x6f, 0x6d, 0x00, + // second name: ns2.example.com. all labels except the first should be + // compressed. + 0x03, 0x6e, 0x73, 0x32, 0xc0, 0x03 }; + +TEST_F(Rdata_NS_Test, createFromText) { + EXPECT_EQ(0, rdata_ns.compare(generic::NS("ns.example.com."))); + // explicitly add a trailing dot. should be the same RDATA. + EXPECT_EQ(0, rdata_ns.compare(generic::NS("ns.example.com."))); + // should be case sensitive. + EXPECT_EQ(0, rdata_ns.compare(generic::NS("NS.EXAMPLE.COM."))); + // RDATA of a class-independent type should be recognized for any + // "unknown" class. + EXPECT_EQ(0, rdata_ns.compare(*createRdata(RRType("NS"), RRClass(65000), + "ns.example.com."))); +} + +TEST_F(Rdata_NS_Test, badText) { + // Extra input at end of line + EXPECT_THROW(generic::NS("ns.example.com. extra."), InvalidRdataText); +} + +TEST_F(Rdata_NS_Test, createFromWire) { + EXPECT_EQ(0, rdata_ns.compare( + *rdataFactoryFromFile(RRType("NS"), RRClass("IN"), + "rdata_ns_fromWire"))); + // RDLENGTH is too short + EXPECT_THROW(rdataFactoryFromFile(RRType("NS"), RRClass("IN"), + "rdata_ns_fromWire", 18), + InvalidRdataLength); + // RDLENGTH is too long + EXPECT_THROW(rdataFactoryFromFile(RRType("NS"), RRClass("IN"), + "rdata_ns_fromWire", 36), + InvalidRdataLength); + // incomplete name. the error should be detected in the name constructor + EXPECT_THROW(rdataFactoryFromFile(RRType("NS"), RRClass("IN"), + "rdata_ns_fromWire", 71), + DNSMessageFORMERR); + + EXPECT_EQ(0, generic::NS("ns2.example.com.").compare( + *rdataFactoryFromFile(RRType("NS"), RRClass("IN"), + "rdata_ns_fromWire", 55))); + EXPECT_THROW(*rdataFactoryFromFile(RRType("NS"), RRClass("IN"), + "rdata_ns_fromWire", 63), + InvalidRdataLength); +} + +TEST_F(Rdata_NS_Test, createFromLexer) { + EXPECT_EQ(0, rdata_ns.compare( + *test::createRdataUsingLexer(RRType::NS(), RRClass::IN(), + "ns.example.com."))); + + // test::createRdataUsingLexer() constructs relative to + // "example.org." origin. + EXPECT_EQ(0, generic::NS("ns8.example.org.").compare( + *test::createRdataUsingLexer(RRType::NS(), RRClass::IN(), + "ns8"))); + + // Exceptions cause NULL to be returned. + EXPECT_FALSE(test::createRdataUsingLexer(RRType::NS(), RRClass::IN(), + "")); + + // Extra input at end of line + EXPECT_FALSE(test::createRdataUsingLexer(RRType::NS(), RRClass::IN(), + "ns.example.com. extra.")); +} + +TEST_F(Rdata_NS_Test, toWireBuffer) { + rdata_ns.toWire(obuffer); + matchWireData(wiredata_ns, sizeof(wiredata_ns), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_NS_Test, toWireRenderer) { + rdata_ns.toWire(renderer); + matchWireData(wiredata_ns, sizeof(wiredata_ns), + renderer.getData(), renderer.getLength()); + + rdata_ns2.toWire(renderer); + matchWireData(wiredata_ns2, sizeof(wiredata_ns2), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_NS_Test, toText) { + EXPECT_EQ("ns.example.com.", rdata_ns.toText()); +} + +TEST_F(Rdata_NS_Test, compare) { + generic::NS small("a.example."); + generic::NS large("example."); + EXPECT_TRUE(Name("a.example") > Name("example")); + EXPECT_GT(0, small.compare(large)); +} + +TEST_F(Rdata_NS_Test, getNSName) { + EXPECT_EQ(Name("ns.example.com."), rdata_ns.getNSName()); +} +} diff --git a/src/lib/dns/tests/rdata_nsec3_unittest.cc b/src/lib/dns/tests/rdata_nsec3_unittest.cc new file mode 100644 index 0000000..c6d3a07 --- /dev/null +++ b/src/lib/dns/tests/rdata_nsec3_unittest.cc @@ -0,0 +1,226 @@ +// Copyright (C) 2010-2017 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> + +using isc::UnitTestUtil; +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; + +namespace { + +// Note: some tests can be shared with NSEC3PARAM. They are unified as +// typed tests defined in nsec3param_like_unittest. +class Rdata_NSEC3_Test : public RdataTest { +protected: + Rdata_NSEC3_Test() : + nsec3_txt("1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6 " + "A NS SOA"), + nsec3_nosalt_txt("1 1 1 - H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A NS SOA"), + nsec3_notype_txt("1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6"), + rdata_nsec3(nsec3_txt) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<generic::NSEC3, isc::Exception, isc::Exception>( + rdata_str, rdata_nsec3, false, false); + } + + void checkFromText_InvalidText(const string& rdata_str) { + checkFromText<generic::NSEC3, InvalidRdataText, InvalidRdataText>( + rdata_str, rdata_nsec3, true, true); + } + + void checkFromText_BadValue(const string& rdata_str) { + checkFromText<generic::NSEC3, BadValue, BadValue>( + rdata_str, rdata_nsec3, true, true); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::NSEC3, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_nsec3, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText + <generic::NSEC3, InvalidRdataText, isc::Exception>( + rdata_str, rdata_nsec3, true, false); + } + + const string nsec3_txt; + const string nsec3_nosalt_txt; + const string nsec3_notype_txt; + const generic::NSEC3 rdata_nsec3; +}; + +TEST_F(Rdata_NSEC3_Test, fromText) { + // Hash that has the possible max length + EXPECT_EQ(255, generic::NSEC3("1 1 1 D399EAAB " + + string((255 * 8) / 5, '0') + + " NS").getNext().size()); + + // Hash is too long. Max = 255 bytes, base32-hex converts each 5 bytes + // of the original to 8 characters, so 260 * 8 / 5 is the smallest length + // of the encoded string that exceeds the max and doesn't require padding. + checkFromText_InvalidText("1 1 1 D399EAAB " + string((260 * 8) / 5, '0') + + " A NS SOA"); + + // Type bitmap is empty. it's possible and allowed for NSEC3. + EXPECT_NO_THROW(const generic::NSEC3 rdata_notype_nsec3(nsec3_notype_txt)); + + // Empty salt is also okay. + EXPECT_NO_THROW(const generic::NSEC3 rdata_nosalt_nsec3(nsec3_nosalt_txt)); + + // Bad type mnemonics + checkFromText_InvalidText("1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6" + " BIFF POW SPOON"); + + // Bad base32hex + checkFromText_BadValue("1 1 1 D399EAAB " + "WXYZWXYZWXYZ=WXYZWXYZ==WXYZWXYZW A NS SOA"); + + // Hash algorithm out of range + checkFromText_InvalidText("256 1 1 D399EAAB " + "H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A NS SOA"); + + // Flags out of range + checkFromText_InvalidText("1 256 1 D399EAAB " + "H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A NS SOA"); + + // Iterations out of range + checkFromText_InvalidText("1 1 65536 D399EAAB " + "H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A NS SOA"); + + // Space is not allowed in salt or the next hash. This actually + // causes the Base32 decoder that parses the next hash that comes + // afterwards, to throw. + checkFromText_BadValue("1 1 1 D399 EAAB H9RSFB7FPF2L8" + "HG35CMPC765TDK23RP6 A NS SOA"); + + // Next hash must not contain padding (trailing '=' characters) + checkFromText_InvalidText("1 1 1 D399EAAB " + "AAECAwQFBgcICQoLDA0ODw== A NS SOA"); + + // String instead of number + checkFromText_LexerError("foo 1 1 D399EAAB " + "H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A NS SOA"); + checkFromText_LexerError("1 foo 1 D399EAAB " + "H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A NS SOA"); + checkFromText_LexerError("1 1 foo D399EAAB " + "H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A NS SOA"); + + // Trailing garbage. This should cause only the string constructor + // to fail, but the lexer constructor must be able to continue + // parsing from it. + checkFromText_BadString( + "1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A NS SOA ;comment\n" + "1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A NS SOA"); + + // Unmatched parenthesis should cause a lexer error + checkFromText_LexerError("1 1 1 D399EAAB " + "H9RSFB7FPF2L8HG35CMPC765TDK23RP6 A ) NS SOA"); +} + +TEST_F(Rdata_NSEC3_Test, createFromWire) { + // A valid NSEC3 RR with empty type bitmap. + EXPECT_NO_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(), + "rdata_nsec3_fromWire15.wire")); + + // Invalid bitmap cases are tested in Rdata_NSECBITMAP_Test. + + // hash length is too large + EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(), + "rdata_nsec3_fromWire12.wire"), + DNSMessageFORMERR); + + // empty hash. invalid. + EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(), + "rdata_nsec3_fromWire14.wire"), + DNSMessageFORMERR); + + // RDLEN is too short to hold the hash length field + EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(), + "rdata_nsec3_fromWire17.wire"), + DNSMessageFORMERR); + + // Short buffer cases. The data is valid NSEC3 RDATA, but the buffer + // is trimmed at the end. All cases should result in an exception from + // the buffer class. + vector<uint8_t> data; + UnitTestUtil::readWireData("rdata_nsec3_fromWire1", data); + const uint16_t rdlen = (data.at(0) << 8) + data.at(1); + for (int i = 0; i < rdlen; ++i) { + // intentionally construct a short buffer + InputBuffer b(&data[0] + 2, i); + EXPECT_THROW(createRdata(RRType::NSEC3(), RRClass::IN(), b, 39), + InvalidBufferPosition); + } +} + +TEST_F(Rdata_NSEC3_Test, createFromLexer) { + EXPECT_EQ(0, rdata_nsec3.compare( + *test::createRdataUsingLexer(RRType::NSEC3(), RRClass::IN(), + nsec3_txt))); + + // empty salt is also okay. + const generic::NSEC3 rdata_nosalt_nsec3(nsec3_nosalt_txt); + EXPECT_EQ(0, rdata_nosalt_nsec3.compare( + *test::createRdataUsingLexer(RRType::NSEC3(), RRClass::IN(), + nsec3_nosalt_txt))); +} + +TEST_F(Rdata_NSEC3_Test, assign) { + generic::NSEC3 other_nsec3 = rdata_nsec3; + EXPECT_EQ(0, rdata_nsec3.compare(other_nsec3)); +} + +TEST_F(Rdata_NSEC3_Test, compare) { + // trivial case: self equivalence + EXPECT_EQ(0, generic::NSEC3(nsec3_txt).compare(generic::NSEC3(nsec3_txt))); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(generic::NSEC3(nsec3_txt).compare(*rdata_nomatch), + bad_cast); + + // test RDATAs, sorted in the ascending order. We only check comparison + // on NSEC3-specific fields. Bitmap comparison is tested in the bitmap + // tests. Common cases for NSEC3 and NSECPARAM3 are in their shared tests. + vector<generic::NSEC3> compare_set; + compare_set.push_back(generic::NSEC3("1 1 1 FF99EA0000 D1K6GQ38")); + compare_set.push_back(generic::NSEC3("1 1 1 FF99EA0000 D1K6GQ0000000000")); + compare_set.push_back(generic::NSEC3("1 1 1 FF99EA0000 D1K6GQ00UUUUUUUU")); + + vector<generic::NSEC3>::const_iterator it; + const vector<generic::NSEC3>::const_iterator it_end = compare_set.end(); + for (it = compare_set.begin(); it != it_end - 1; ++it) { + SCOPED_TRACE("compare " + it->toText() + " to " + (it + 1)->toText()); + EXPECT_GT(0, (*it).compare(*(it + 1))); + EXPECT_LT(0, (*(it + 1)).compare(*it)); + } +} + +} diff --git a/src/lib/dns/tests/rdata_nsec3param_like_unittest.cc b/src/lib/dns/tests/rdata_nsec3param_like_unittest.cc new file mode 100644 index 0000000..914a6f4 --- /dev/null +++ b/src/lib/dns/tests/rdata_nsec3param_like_unittest.cc @@ -0,0 +1,272 @@ +// Copyright (C) 2012-2019 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/exceptions.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +#include <string> +#include <vector> + +using namespace std; +using namespace isc::dns; +using namespace isc::dns::rdata; +using namespace isc::util; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { + +// Template for shared tests for NSEC3 and NSEC3PARAM +template <typename RDATA_TYPE> +class NSEC3PARAMLikeTest : public RdataTest { +protected: + NSEC3PARAMLikeTest() : + salt_txt("1 1 1 D399EAAB" + getCommonText()), + nosalt_txt("1 1 1 -" + getCommonText()), + obuffer(0) + {} + + RDATA_TYPE fromText(const string& rdata_text) { + return (RDATA_TYPE(rdata_text)); + } + + void compareCheck() const { + typename vector<RDATA_TYPE>::const_iterator it; + typename vector<RDATA_TYPE>::const_iterator const it_end = + compare_set.end(); + for (it = compare_set.begin(); it != it_end - 1; ++it) { + SCOPED_TRACE("compare " + it->toText() + " to " + + (it + 1)->toText()); + EXPECT_GT(0, (*it).compare(*(it + 1))); + EXPECT_LT(0, (*(it + 1)).compare(*it)); + } + } + + const string salt_txt; // RDATA text with salt + const string nosalt_txt; // RDATA text without salt + OutputBuffer obuffer; // used in toWire() tests + MessageRenderer renderer; // ditto + vector<RDATA_TYPE> compare_set; // used in compare() tests + + // Convert generic Rdata to the corresponding derived Rdata class object. + // Defined here because it depends on the template parameter. + static const RDATA_TYPE& convert(const Rdata& rdata) { + return (dynamic_cast<const RDATA_TYPE&>(rdata)); + } + + // These depend on the specific RR type. We use specialized methods + // for them. + static RRType getType(); // return either RRType::NSEC3() or NSEC3PARAM() + static string getWireFilePrefix(); + static string getCommonText(); // commonly used part of textual form +}; + +// Instantiate specific typed tests +typedef ::testing::Types<generic::NSEC3, generic::NSEC3PARAM> TestRdataTypes; +#ifdef TYPED_TEST_SUITE +TYPED_TEST_SUITE(NSEC3PARAMLikeTest, TestRdataTypes); +#else +TYPED_TEST_CASE(NSEC3PARAMLikeTest, TestRdataTypes); +#endif + +template <> +RRType +NSEC3PARAMLikeTest<generic::NSEC3>::getType() { + return (RRType::NSEC3()); +} + +template <> +RRType +NSEC3PARAMLikeTest<generic::NSEC3PARAM>::getType() { + return (RRType::NSEC3PARAM()); +} + +template <> +string +NSEC3PARAMLikeTest<generic::NSEC3>::getWireFilePrefix() { + return ("rdata_nsec3_"); +} + +template <> +string +NSEC3PARAMLikeTest<generic::NSEC3PARAM>::getWireFilePrefix() { + return ("rdata_nsec3param_"); +} + +template <> +string +NSEC3PARAMLikeTest<generic::NSEC3>::getCommonText() { + // next hash + RR type bitmap + return (" H9RSFB7FPF2L8HG35CMPC765TDK23RP6 " + "NS SOA RRSIG DNSKEY NSEC3PARAM"); +} + +template <> +string +NSEC3PARAMLikeTest<generic::NSEC3PARAM>::getCommonText() { + // there's no more text for NSEC3PARAM + return (""); +} + +TYPED_TEST(NSEC3PARAMLikeTest, fromText) { + // Numeric parameters have possible maximum values. Unusual, but must + // be accepted. + EXPECT_NO_THROW(this->fromText("255 255 65535 D399EAAB" + + this->getCommonText())); + + // 0-length salt + EXPECT_EQ(0, this->fromText(this->nosalt_txt).getSalt().size()); + + // salt that has the possible max length + EXPECT_EQ(255, this->fromText("1 1 1 " + string(255 * 2, '0') + + this->getCommonText()).getSalt().size()); +} + +TYPED_TEST(NSEC3PARAMLikeTest, badText) { + // Bad salt hex + EXPECT_THROW(this->fromText("1 1 1 SPORK0" + this->getCommonText()), + isc::BadValue); + EXPECT_THROW(this->fromText("1 1 1 ADDAFEE" + this->getCommonText()), + isc::BadValue); + + // Space within salt + EXPECT_THROW(this->fromText("1 1 1 ADDAFE ADDAFEEE" + + this->getCommonText()), + InvalidRdataText); + + // Similar to empty salt, but not really. This shouldn't cause confusion. + EXPECT_THROW(this->fromText("1 1 1 --" + this->getCommonText()), + isc::BadValue); + + // Too large algorithm + EXPECT_THROW(this->fromText("1000000 1 1 ADDAFEEE" + this->getCommonText()), + InvalidRdataText); + + // Too large flags + EXPECT_THROW(this->fromText("1 1000000 1 ADDAFEEE" + this->getCommonText()), + InvalidRdataText); + + // Too large iterations + EXPECT_THROW(this->fromText("1 1 65536 ADDAFEEE" + this->getCommonText()), + InvalidRdataText); + + // There should be a space between "1" and "D399EAAB" (salt) + EXPECT_THROW(this->fromText("1 1 1D399EAAB" + this->getCommonText()), + InvalidRdataText); + + // Salt is too long (possible max + 1 bytes) + EXPECT_THROW(this->fromText("1 1 1 " + string(256 * 2, '0') + + this->getCommonText()), + InvalidRdataText); +} + +TYPED_TEST(NSEC3PARAMLikeTest, toText) { + // normal case + EXPECT_EQ(this->salt_txt, this->fromText(this->salt_txt).toText()); + + // empty salt case + EXPECT_EQ(this->nosalt_txt, this->fromText(this->nosalt_txt).toText()); +} + +TYPED_TEST(NSEC3PARAMLikeTest, createFromWire) { + // Normal case + EXPECT_EQ(0, this->fromText(this->salt_txt).compare( + *this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire1").c_str()))); + + // Too short RDLENGTH: it doesn't even contain the first 5 octets. + EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire2.wire").c_str()), + DNSMessageFORMERR); + + // salt length is too large + EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire11.wire").c_str()), + DNSMessageFORMERR); + + // empty salt. not so usual, but valid. + ConstRdataPtr rdata = + this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire13.wire").c_str()); + EXPECT_EQ(0, this->convert(*rdata).getSalt().size()); +} + +TYPED_TEST(NSEC3PARAMLikeTest, createFromLexer) { + EXPECT_EQ(0, this->fromText(this->salt_txt).compare( + *test::createRdataUsingLexer(this->getType(), RRClass::IN(), + this->salt_txt))); + + // Exceptions cause NULL to be returned. + EXPECT_FALSE(test::createRdataUsingLexer(this->getType(), RRClass::IN(), + "1000000 1 1 ADDAFEEE" + + this->getCommonText())); +} + +template <typename OUTPUT_TYPE> +void +toWireCheck(RRType rrtype, OUTPUT_TYPE& output, const string& data_file) { + vector<uint8_t> data; + UnitTestUtil::readWireData(data_file.c_str(), data); + InputBuffer buffer(&data[0], data.size()); + const uint16_t rdlen = buffer.readUint16(); + + output.clear(); + output.writeUint16(rdlen); + createRdata(rrtype, RRClass::IN(), buffer, rdlen)->toWire(output); + matchWireData(&data[0], data.size(), + output.getData(), output.getLength()); +} + +TYPED_TEST(NSEC3PARAMLikeTest, toWire) { + // normal case + toWireCheck(this->getType(), this->renderer, + this->getWireFilePrefix() + "fromWire1"); + toWireCheck(this->getType(), this->obuffer, + this->getWireFilePrefix() + "fromWire1"); + + // empty salt + toWireCheck(this->getType(), this->renderer, + this->getWireFilePrefix() + "fromWire13.wire"); + toWireCheck(this->getType(), this->obuffer, + this->getWireFilePrefix() + "fromWire13.wire"); +} + +TYPED_TEST(NSEC3PARAMLikeTest, compare) { + // test RDATAs, sorted in the ascending order. + this->compare_set.push_back(this->fromText("0 0 0 D399EAAB" + + this->getCommonText())); + this->compare_set.push_back(this->fromText("1 0 0 D399EAAB" + + this->getCommonText())); + this->compare_set.push_back(this->fromText("1 1 0 D399EAAB" + + this->getCommonText())); + this->compare_set.push_back(this->fromText("1 1 1 -" + + this->getCommonText())); + this->compare_set.push_back(this->fromText("1 1 1 D399EAAB" + + this->getCommonText())); + this->compare_set.push_back(this->fromText("1 1 1 FF99EAAB" + + this->getCommonText())); + this->compare_set.push_back(this->fromText("1 1 1 FF99EA0000" + + this->getCommonText())); + + this->compareCheck(); +} + +} diff --git a/src/lib/dns/tests/rdata_nsec3param_unittest.cc b/src/lib/dns/tests/rdata_nsec3param_unittest.cc new file mode 100644 index 0000000..9a677be --- /dev/null +++ b/src/lib/dns/tests/rdata_nsec3param_unittest.cc @@ -0,0 +1,209 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_NSEC3PARAM_Test : public RdataTest { +protected: + Rdata_NSEC3PARAM_Test() : + nsec3param_txt("1 1 1 D399EAAB"), + nsec3param_nosalt_txt("1 1 1 -"), + rdata_nsec3param(nsec3param_txt) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<generic::NSEC3PARAM, isc::Exception, isc::Exception>( + rdata_str, rdata_nsec3param, false, false); + } + + void checkFromText_InvalidText(const string& rdata_str) { + checkFromText<generic::NSEC3PARAM, InvalidRdataText, InvalidRdataText>( + rdata_str, rdata_nsec3param, true, true); + } + + void checkFromText_BadValue(const string& rdata_str) { + checkFromText<generic::NSEC3PARAM, BadValue, BadValue>( + rdata_str, rdata_nsec3param, true, true); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::NSEC3PARAM, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_nsec3param, true, true); + } + + void checkFromText_BadString(const string& rdata_str, + const generic::NSEC3PARAM& rdata) + { + checkFromText + <generic::NSEC3PARAM, InvalidRdataText, isc::Exception>( + rdata_str, rdata, true, false); + } + + const string nsec3param_txt; + const string nsec3param_nosalt_txt; + const generic::NSEC3PARAM rdata_nsec3param; +}; + +TEST_F(Rdata_NSEC3PARAM_Test, fromText) { + // Empty salt is okay. + EXPECT_EQ(0, generic::NSEC3PARAM(nsec3param_nosalt_txt).getSalt().size()); + + // Salt is missing. + checkFromText_LexerError("1 1 1"); + + // Salt has whitespace within. This only fails in the string + // constructor, as the lexer constructor stops reading at the end of + // its RDATA. + const generic::NSEC3PARAM rdata_nsec3param2("1 1 1 D399"); + checkFromText_BadString("1 1 1 D399 EAAB", rdata_nsec3param2); + + // Hash algorithm out of range. + checkFromText_InvalidText("256 1 1 D399EAAB"); + + // Flags out of range. + checkFromText_InvalidText("1 256 1 D399EAAB"); + + // Iterations out of range. + checkFromText_InvalidText("1 1 65536 D399EAAB"); + + // Bad hex sequence + checkFromText_BadValue("1 1 256 D399EAABZOO"); + + // String instead of number + checkFromText_LexerError("foo 1 256 D399EAAB"); + checkFromText_LexerError("1 foo 256 D399EAAB"); + checkFromText_LexerError("1 1 foo D399EAAB"); + + // Trailing garbage. This should cause only the string constructor + // to fail, but the lexer constructor must be able to continue + // parsing from it. + checkFromText_BadString("1 1 1 D399EAAB ; comment\n" + "1 1 1 D399EAAB", rdata_nsec3param); +} + +TEST_F(Rdata_NSEC3PARAM_Test, toText) { + EXPECT_EQ(nsec3param_txt, rdata_nsec3param.toText()); + + // Garbage space at the end should be ok. RFC5155 only forbids + // whitespace within the salt field, but any whitespace afterwards + // should be fine. + EXPECT_NO_THROW(generic::NSEC3PARAM("1 1 1 D399EAAB ")); + + // Hash algorithm in range. + EXPECT_NO_THROW(generic::NSEC3PARAM("255 1 1 D399EAAB")); + + // Flags in range. + EXPECT_NO_THROW(generic::NSEC3PARAM("1 255 1 D399EAAB")); + + // Iterations in range. + EXPECT_NO_THROW(generic::NSEC3PARAM("1 1 65535 D399EAAB")); +} + +TEST_F(Rdata_NSEC3PARAM_Test, createFromWire) { + EXPECT_EQ(0, rdata_nsec3param.compare( + *rdataFactoryFromFile(RRType::NSEC3PARAM(), RRClass::IN(), + "rdata_nsec3param_fromWire1"))); + + // Short buffer cases. The data is valid NSEC3PARAM RDATA, but the buffer + // is trimmed at the end. All cases should result in an exception from + // the buffer class. + vector<uint8_t> data; + UnitTestUtil::readWireData("rdata_nsec3param_fromWire1", data); + const uint16_t rdlen = (data.at(0) << 8) + data.at(1); + for (int i = 0; i < rdlen; ++i) { + // intentionally construct a short buffer + InputBuffer b(&data[0] + 2, i); + EXPECT_THROW(createRdata(RRType::NSEC3PARAM(), RRClass::IN(), b, 9), + InvalidBufferPosition); + } +} + +TEST_F(Rdata_NSEC3PARAM_Test, createFromLexer) { + EXPECT_EQ(0, rdata_nsec3param.compare( + *test::createRdataUsingLexer(RRType::NSEC3PARAM(), RRClass::IN(), + nsec3param_txt))); + + // empty salt is also okay. + const generic::NSEC3PARAM rdata_nosalt_nsec3param(nsec3param_nosalt_txt); + EXPECT_EQ(0, rdata_nosalt_nsec3param.compare( + *test::createRdataUsingLexer(RRType::NSEC3PARAM(), RRClass::IN(), + nsec3param_nosalt_txt))); +} + +TEST_F(Rdata_NSEC3PARAM_Test, toWireRenderer) { + renderer.skip(2); + rdata_nsec3param.toWire(renderer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_nsec3param_fromWire1", data); + matchWireData(&data[2], data.size() - 2, + static_cast<const uint8_t *>(renderer.getData()) + 2, + renderer.getLength() - 2); +} + +TEST_F(Rdata_NSEC3PARAM_Test, toWireBuffer) { + rdata_nsec3param.toWire(obuffer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_nsec3param_fromWire1", data); + matchWireData(&data[2], data.size() - 2, + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_NSEC3PARAM_Test, getHashAlg) { + EXPECT_EQ(1, rdata_nsec3param.getHashalg()); +} + +TEST_F(Rdata_NSEC3PARAM_Test, getFlags) { + EXPECT_EQ(1, rdata_nsec3param.getFlags()); +} + +TEST_F(Rdata_NSEC3PARAM_Test, assign) { + generic::NSEC3PARAM other_nsec3param("1 1 1 -"); + other_nsec3param = rdata_nsec3param; + EXPECT_EQ(0, rdata_nsec3param.compare(other_nsec3param)); +} + +TEST_F(Rdata_NSEC3PARAM_Test, compare) { + // trivial case: self equivalence + EXPECT_EQ(0, generic::NSEC3PARAM(nsec3param_txt). + compare(generic::NSEC3PARAM(nsec3param_txt))); + EXPECT_EQ(0, generic::NSEC3PARAM("1 1 1 -"). + compare(generic::NSEC3PARAM("1 1 1 -"))); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(generic::NSEC3PARAM(nsec3param_txt).compare(*rdata_nomatch), + bad_cast); +} + +} diff --git a/src/lib/dns/tests/rdata_nsec_unittest.cc b/src/lib/dns/tests/rdata_nsec_unittest.cc new file mode 100644 index 0000000..570a2ab --- /dev/null +++ b/src/lib/dns/tests/rdata_nsec_unittest.cc @@ -0,0 +1,138 @@ +// Copyright (C) 2010-2017 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_NSEC_Test : public RdataTest { + // there's nothing to specialize +}; + +const char* const nsec_txt = "www2.isc.org. CNAME RRSIG NSEC"; + +TEST_F(Rdata_NSEC_Test, toText_NSEC) { + const generic::NSEC rdata_nsec(nsec_txt); + EXPECT_EQ(nsec_txt, rdata_nsec.toText()); +} + +TEST_F(Rdata_NSEC_Test, badText_NSEC) { + EXPECT_THROW(generic::NSEC rdata_nsec("www.isc.org. BIFF POW SPOON"), + InvalidRdataText); + EXPECT_THROW(generic::NSEC rdata_nsec("www.isc.org."), + InvalidRdataText); +} + +TEST_F(Rdata_NSEC_Test, createFromWire_NSEC) { + const generic::NSEC rdata_nsec(nsec_txt); + EXPECT_EQ(0, rdata_nsec.compare( + *rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(), + "rdata_nsec_fromWire1"))); + + // Too short RDLENGTH + EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC(), RRClass::IN(), + "rdata_nsec_fromWire2"), + DNSMessageFORMERR); + + // Invalid bitmap cases are tested in Rdata_NSECBITMAP_Test. +} + +TEST_F(Rdata_NSEC_Test, createFromLexer_NSEC) { + const generic::NSEC rdata_nsec(nsec_txt); + EXPECT_EQ(0, rdata_nsec.compare( + *test::createRdataUsingLexer(RRType::NSEC(), RRClass::IN(), + nsec_txt))); + + // test::createRdataUsingLexer() constructs relative to + // "example.org." origin. + EXPECT_EQ(0, generic::NSEC("www2.example.org. CNAME RRSIG NSEC").compare( + *test::createRdataUsingLexer(RRType::NSEC(), RRClass::IN(), + "www2 CNAME RRSIG NSEC"))); + + // Exceptions cause NULL to be returned. + EXPECT_FALSE(test::createRdataUsingLexer(RRType::NSEC(), RRClass::IN(), + "www.isc.org.")); +} + +TEST_F(Rdata_NSEC_Test, toWireRenderer_NSEC) { + renderer.skip(2); + const generic::NSEC rdata_nsec(nsec_txt); + rdata_nsec.toWire(renderer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_nsec_fromWire1", data); + matchWireData(&data[2], data.size() - 2, + static_cast<const uint8_t *>(renderer.getData()) + 2, + renderer.getLength() - 2); +} + +TEST_F(Rdata_NSEC_Test, toWireBuffer_NSEC) { + const generic::NSEC rdata_nsec(nsec_txt); + rdata_nsec.toWire(obuffer); +} + +TEST_F(Rdata_NSEC_Test, assign) { + generic::NSEC rdata_nsec(nsec_txt); + generic::NSEC rdata_nsec2 = rdata_nsec; + EXPECT_EQ(0, rdata_nsec.compare(rdata_nsec2)); +} + +TEST_F(Rdata_NSEC_Test, getNextName) { + // The implementation is quite trivial, so we simply check it's actually + // defined and does work as intended in a simple case. + EXPECT_EQ(Name("www2.isc.org"), generic::NSEC((nsec_txt)).getNextName()); +} + +TEST_F(Rdata_NSEC_Test, compare) { + // trivial case: self equivalence + EXPECT_EQ(0, generic::NSEC("example. A"). + compare(generic::NSEC("example. A"))); + EXPECT_EQ(0, generic::NSEC("EXAMPLE. A"). // should be case insensitive + compare(generic::NSEC("example. A"))); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(generic::NSEC(nsec_txt).compare(*rdata_nomatch), + bad_cast); + + // test RDATAs, sorted in the ascending order. We only compare the + // next name here. Bitmap comparison is tested in the bitmap tests. + // Note that names are compared as wire-format data, not based on the + // domain name comparison. + vector<generic::NSEC> compare_set; + compare_set.push_back(generic::NSEC("a.example. A")); + compare_set.push_back(generic::NSEC("example. A")); + vector<generic::NSEC>::const_iterator it; + const vector<generic::NSEC>::const_iterator it_end = compare_set.end(); + for (it = compare_set.begin(); it != it_end - 1; ++it) { + SCOPED_TRACE("compare " + it->toText() + " to " + (it + 1)->toText()); + EXPECT_GT(0, (*it).compare(*(it + 1))); + EXPECT_LT(0, (*(it + 1)).compare(*it)); + } +} + +} diff --git a/src/lib/dns/tests/rdata_nsecbitmap_unittest.cc b/src/lib/dns/tests/rdata_nsecbitmap_unittest.cc new file mode 100644 index 0000000..f18e9df --- /dev/null +++ b/src/lib/dns/tests/rdata_nsecbitmap_unittest.cc @@ -0,0 +1,269 @@ +// Copyright (C) 2011-2019 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/tests/unittest_util.h> + +#include <dns/exceptions.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +#include <boost/lexical_cast.hpp> + +#include <string> +#include <vector> + +using namespace std; +using namespace isc::dns; +using namespace isc::dns::rdata; +using namespace isc::util; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; +using boost::lexical_cast; + +namespace { + +// Template for shared tests for NSEC and NSEC3 bitmaps +template <typename RDATA_TYPE> +class NSECLikeBitmapTest : public RdataTest { +protected: + RDATA_TYPE fromText(const string& rdata_text) { + return (RDATA_TYPE(rdata_text)); + } + + vector<RDATA_TYPE> compare_set; // used in compare() tests + + void compareCheck() const { + typename vector<RDATA_TYPE>::const_iterator it; + typename vector<RDATA_TYPE>::const_iterator const it_end = + compare_set.end(); + for (it = compare_set.begin(); it != it_end - 1; ++it) { + SCOPED_TRACE("compare " + it->toText() + " to " + + (it + 1)->toText()); + EXPECT_GT(0, (*it).compare(*(it + 1))); + EXPECT_LT(0, (*(it + 1)).compare(*it)); + } + } + + // These depend on the specific RR type. We use specialized methods + // for them. + static RRType getType(); // return either RRType::NSEC() or NSEC3() + static string getWireFilePrefix(); + static string getCommonText(); // commonly used part of textual form +}; + +// Instantiate specific typed tests +typedef ::testing::Types<generic::NSEC, generic::NSEC3> TestRdataTypes; +#ifdef TYPED_TEST_SUITE +TYPED_TEST_SUITE(NSECLikeBitmapTest, TestRdataTypes); +#else +TYPED_TEST_CASE(NSECLikeBitmapTest, TestRdataTypes); +#endif + +// NSEC and NSEC3 bitmaps have some subtle differences, in which case we +// need to test them separately. Using these typedef type names with TEST_F +// will do the trick. +typedef NSECLikeBitmapTest<generic::NSEC3> NSEC3BitmapTest; +typedef NSECLikeBitmapTest<generic::NSEC> NSECBitmapTest; + +template <> +string +NSECLikeBitmapTest<generic::NSEC>::getWireFilePrefix() { + return ("rdata_nsec_"); +} + +template <> +RRType +NSECLikeBitmapTest<generic::NSEC>::getType() { + return (RRType::NSEC()); +} + +template <> +string +NSECLikeBitmapTest<generic::NSEC3>::getWireFilePrefix() { + return ("rdata_nsec3_"); +} + +template <> +RRType +NSECLikeBitmapTest<generic::NSEC3>::getType() { + return (RRType::NSEC3()); +} + +template <> +string +NSECLikeBitmapTest<generic::NSEC>::getCommonText() { + return ("next. "); +} + +template <> +string +NSECLikeBitmapTest<generic::NSEC3>::getCommonText() { + return ("1 1 12 AABBCCDD 2T7B4G4VSA5SMI47K61MV5BV1A22BOJR "); +} + +// Tests against various types of bogus NSEC/NSEC3 type bitmaps. +// The syntax and semantics are common for both RR types, and our +// implementation of that part is shared, so in theory it should be sufficient +// to test for only one RR type. But we check for both just in case. +TYPED_TEST(NSECLikeBitmapTest, createFromWire) { + // A malformed NSEC bitmap length field that could cause overflow. + EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire4.wire").c_str()), + DNSMessageFORMERR); + + // The bitmap field is incomplete (only the first byte is included) + EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire5.wire").c_str()), + DNSMessageFORMERR); + + // Bitmap length is 0, which is invalid. + EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire6.wire").c_str()), + DNSMessageFORMERR); + + // Too large bitmap length with a short buffer. + EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire3").c_str()), + DNSMessageFORMERR); + + // A boundary case: longest possible bitmaps (32 maps). This should be + // accepted. + EXPECT_NO_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire7.wire").c_str())); + + // Another boundary condition: 33 bitmaps, which should be rejected. + EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire8.wire").c_str()), + DNSMessageFORMERR); + + // Disordered bitmap window blocks. + EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire9.wire").c_str()), + DNSMessageFORMERR); + + // Bitmap ending with all-zero bytes. Not necessarily harmful except + // the additional overhead of parsing, but invalid according to the + // spec anyway. + EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire10.wire").c_str()), + DNSMessageFORMERR); +} + +// This tests the result of toText() with various kinds of NSEC/NSEC3 bitmaps. +// It also tests the "from text" constructor as a result. +TYPED_TEST(NSECLikeBitmapTest, toText) { + // A simple case (some commonly seen RR types in NSEC(3) bitmaps) + string rdata_text = this->getCommonText() + "NS SOA RRSIG DNSKEY"; + EXPECT_EQ(rdata_text, this->fromText(rdata_text).toText()); + + // Similar to above, but involves more than one bitmap window blocks. + rdata_text = this->getCommonText() + "NS DLV"; + EXPECT_EQ(rdata_text, this->fromText(rdata_text).toText()); + + // Make sure all possible bits in a one-octet bitmap field are handled + // correctly. + // We use the range around 1024 (reasonably higher number) so it's + // unlikely that they have predefined mnemonic and can be safely converted + // to TYPEnnnn by toText(). + for (unsigned int i = 1024; i < 1032; ++i) { + rdata_text = this->getCommonText() + "TYPE" + lexical_cast<string>(i); + EXPECT_EQ(rdata_text, this->fromText(rdata_text).toText()); + } + + // Make sure all possible 32 octets in a longest possible block are + // handled correctly. + for (unsigned int i = 1024; i < 1024 + 256; i += 8) { + rdata_text = this->getCommonText() + "TYPE" + lexical_cast<string>(i); + EXPECT_EQ(rdata_text, this->fromText(rdata_text).toText()); + } + + // Check for the highest window block. + rdata_text = this->getCommonText() + "TYPE65535"; + EXPECT_EQ(rdata_text, this->fromText(rdata_text).toText()); +} + +TYPED_TEST(NSECLikeBitmapTest, compare) { + // Bit map: [win=0][len=1] 00000010 + this->compare_set.push_back(this->fromText(this->getCommonText() + "SOA")); + // Bit map: [win=0][len=1] 00000010, [win=4][len=1] 10000000 + this->compare_set.push_back(this->fromText(this->getCommonText() + + "SOA TYPE1024")); + // Bit map: [win=0][len=1] 00100000 + this->compare_set.push_back(this->fromText(this->getCommonText() + "NS")); + // Bit map: [win=0][len=1] 00100010 + this->compare_set.push_back(this->fromText(this->getCommonText() + + "NS SOA")); + // Bit map: [win=0][len=2] 00100000, 00000001 + this->compare_set.push_back(this->fromText(this->getCommonText() + + "NS MX")); + // Bit map: [win=4][len=1] 10000000 + this->compare_set.push_back(this->fromText(this->getCommonText() + + "TYPE1024")); + + this->compareCheck(); +} + +// NSEC bitmaps must not be empty +TEST_F(NSECBitmapTest, emptyMap) { + EXPECT_THROW(this->fromText("next.example.").toText(), InvalidRdataText); + + EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(), + (this->getWireFilePrefix() + + "fromWire16.wire").c_str()), + DNSMessageFORMERR); +} + +// NSEC3 bitmaps can be empty +TEST_F(NSEC3BitmapTest, emptyMap) { + // Read wire data wit an empty NSEC3 bitmap. This should succeed. + vector<uint8_t> data; + UnitTestUtil::readWireData((this->getWireFilePrefix() + + "fromWire16.wire").c_str(), data); + InputBuffer buffer(&data[0], data.size()); + const uint16_t rdlen = buffer.readUint16(); + const generic::NSEC3 empty_nsec3 = + dynamic_cast<const generic::NSEC3&>(*createRdata( + RRType::NSEC3(), RRClass::IN(), + buffer, rdlen)); + + // Check the toText() result. + EXPECT_EQ("1 0 1 7373737373 D1K6GQ38D1K6GQ38D1K6GQ38D1K6GQ38", + empty_nsec3.toText()); + + // Check the toWire() result. + OutputBuffer obuffer(0); + obuffer.writeUint16(rdlen); + empty_nsec3.toWire(obuffer); + matchWireData(&data[0], data.size(), + obuffer.getData(), obuffer.getLength()); + + // Same for MessageRenderer. + obuffer.clear(); + MessageRenderer renderer; + renderer.writeUint16(rdlen); + empty_nsec3.toWire(renderer); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +} diff --git a/src/lib/dns/tests/rdata_opt_unittest.cc b/src/lib/dns/tests/rdata_opt_unittest.cc new file mode 100644 index 0000000..a235183 --- /dev/null +++ b/src/lib/dns/tests/rdata_opt_unittest.cc @@ -0,0 +1,198 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_OPT_Test : public RdataTest { + // there's nothing to specialize +}; + +const uint8_t rdata_opt_wiredata[] = { + // Option code + 0x00, 0x2a, + // Option length + 0x00, 0x03, + // Option data + 0x00, 0x01, 0x02 +}; + +TEST_F(Rdata_OPT_Test, createFromText) { + // OPT RR cannot be created from text. + EXPECT_THROW(generic::OPT("this does not matter"), InvalidRdataText); +} + +TEST_F(Rdata_OPT_Test, createFromWire) { + // Valid cases: in the simple implementation with no supported options, + // we can only check these don't throw. + EXPECT_NO_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass("CLASS4096"), + "rdata_opt_fromWire1")); + EXPECT_NO_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass::CH(), + "rdata_opt_fromWire1", 2)); + + // Short RDLEN. This throws InvalidRdataLength even if subsequent + // pseudo RRs cause RDLEN size to be exhausted. + EXPECT_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass::IN(), + "rdata_opt_fromWire2"), + InvalidRdataLength); + EXPECT_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass::IN(), + "rdata_opt_fromWire3"), + InvalidRdataLength); + // Option lengths can add up and overflow RDLEN. Unlikely when + // parsed from wire data, but we'll check for it anyway. + EXPECT_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass::IN(), + "rdata_opt_fromWire4"), + InvalidRdataText); + + // short buffer case. + EXPECT_THROW(rdataFactoryFromFile(RRType::OPT(), RRClass::IN(), + "rdata_opt_fromWire1", 11), + InvalidBufferPosition); +} + +TEST_F(Rdata_OPT_Test, createFromLexer) { + // OPT RR cannot be created from text. Exceptions cause NULL to be + // returned. + EXPECT_FALSE(test::createRdataUsingLexer(RRType::OPT(), RRClass::IN(), + "this does not matter")); +} + +TEST_F(Rdata_OPT_Test, toWireBuffer) { + const generic::OPT rdata_opt = + dynamic_cast<const generic::OPT&> + (*rdataFactoryFromFile(RRType("OPT"), RRClass("IN"), + "rdata_opt_fromWire1", 2)); + + obuffer.clear(); + rdata_opt.toWire(obuffer); + + matchWireData(rdata_opt_wiredata, sizeof(rdata_opt_wiredata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_OPT_Test, toWireRenderer) { + const generic::OPT rdata_opt = + dynamic_cast<const generic::OPT&> + (*rdataFactoryFromFile(RRType("OPT"), RRClass("IN"), + "rdata_opt_fromWire1", 2)); + + renderer.clear(); + rdata_opt.toWire(renderer); + + matchWireData(rdata_opt_wiredata, sizeof(rdata_opt_wiredata), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_OPT_Test, toText) { + // empty OPT + const generic::OPT rdata_opt; + + EXPECT_THROW(rdata_opt.toText(), + isc::InvalidOperation); +} + +TEST_F(Rdata_OPT_Test, compare) { + // empty OPT + const generic::OPT rdata_opt; + + EXPECT_THROW(rdata_opt.compare( + *rdataFactoryFromFile(RRType::OPT(), RRClass::CH(), + "rdata_opt_fromWire1", 2)), + isc::InvalidOperation); + + // comparison attempt between incompatible RR types also results in + // isc::InvalidOperation. + EXPECT_THROW(rdata_opt.compare(*RdataTest::rdata_nomatch), + isc::InvalidOperation); +} + +TEST_F(Rdata_OPT_Test, appendPseudoRR) { + generic::OPT rdata_opt; + + // Append empty option data + rdata_opt.appendPseudoRR(0x0042, NULL, 0); + + // Append simple option data + const uint8_t option_data[] = {'H', 'e', 'l', 'l', 'o'}; + rdata_opt.appendPseudoRR(0x0043, option_data, sizeof(option_data)); + + // Duplicate option codes are okay. + rdata_opt.appendPseudoRR(0x0042, option_data, sizeof(option_data)); + + // When option length may overflow RDLEN, append should throw. + const std::vector<uint8_t> buffer((1 << 16) - 1); + EXPECT_THROW(rdata_opt.appendPseudoRR(0x0044, &buffer[0], buffer.size()), + isc::InvalidParameter); + + const uint8_t rdata_opt_wiredata2[] = { + // OPTION #1 + // ` Option code + 0x00, 0x42, + // ` Option length + 0x00, 0x00, + + // OPTION #2 + // ` Option code + 0x00, 0x43, + // ` Option length + 0x00, 0x05, + // ` Option data + 'H', 'e', 'l', 'l', 'o', + + // OPTION #3 + // ` Option code + 0x00, 0x42, + // ` Option length + 0x00, 0x05, + // ` Option data + 'H', 'e', 'l', 'l', 'o' + }; + + obuffer.clear(); + rdata_opt.toWire(obuffer); + + matchWireData(rdata_opt_wiredata2, sizeof(rdata_opt_wiredata2), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_OPT_Test, getPseudoRRs) { + const generic::OPT rdf = + dynamic_cast<const generic::OPT&> + (*rdataFactoryFromFile(RRType("OPT"), RRClass("IN"), + "rdata_opt_fromWire1", 2)); + + const std::vector<generic::OPT::PseudoRR>& rrs = rdf.getPseudoRRs(); + ASSERT_FALSE(rrs.empty()); + EXPECT_EQ(1, rrs.size()); + EXPECT_EQ(0x2a, rrs.at(0).getCode()); + EXPECT_EQ(3, rrs.at(0).getLength()); + + const uint8_t expected_data[] = {0x00, 0x01, 0x02}; + const uint8_t* actual_data = rrs.at(0).getData(); + EXPECT_EQ(0, std::memcmp(expected_data, actual_data, + sizeof(expected_data))); +} +} diff --git a/src/lib/dns/tests/rdata_pimpl_holder_unittest.cc b/src/lib/dns/tests/rdata_pimpl_holder_unittest.cc new file mode 100644 index 0000000..d639541 --- /dev/null +++ b/src/lib/dns/tests/rdata_pimpl_holder_unittest.cc @@ -0,0 +1,56 @@ +// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/rdata_pimpl_holder.h> + +#include <gtest/gtest.h> + +using namespace isc::dns::rdata; + +namespace { + +TEST(RdataPimplHolderTest, all) { + // Let's check with an integer + int* i1 = new int(42); + RdataPimplHolder<int> holder1(i1); + // The same pointer must be returned. + EXPECT_EQ(i1, holder1.get()); + // Obviously the value should match too. + EXPECT_EQ(42, *holder1.get()); + // We don't explicitly delete i or holder1, so it should not leak + // anything when the test is done (checked by Valgrind). + + // The following cases are similar: + + // Test no-argument reset() + int* i2 = new int(43); + RdataPimplHolder<int> holder2(i2); + holder2.reset(); + EXPECT_EQ(NULL, holder2.get()); + + // Test reset() with argument + int* i3 = new int(44); + int* i4 = new int(45); + RdataPimplHolder<int> holder3(i3); + EXPECT_EQ(i3, holder3.get()); + holder3.reset(i4); + EXPECT_EQ(i4, holder3.get()); + EXPECT_EQ(45, *holder3.get()); + + // Test release() + RdataPimplHolder<int> holder4(new int(46)); + EXPECT_NE(static_cast<void*>(NULL), holder4.get()); + EXPECT_EQ(46, *holder4.get()); + int* i5 = holder4.release(); + EXPECT_EQ(NULL, holder4.get()); + EXPECT_NE(static_cast<void*>(NULL), i5); + EXPECT_EQ(46, *i5); + delete i5; +} + +} diff --git a/src/lib/dns/tests/rdata_ptr_unittest.cc b/src/lib/dns/tests/rdata_ptr_unittest.cc new file mode 100644 index 0000000..5ed3bce --- /dev/null +++ b/src/lib/dns/tests/rdata_ptr_unittest.cc @@ -0,0 +1,145 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +// +// This test currently simply copies the NS RDATA tests. +// + +namespace { +class Rdata_PTR_Test : public RdataTest { +public: + Rdata_PTR_Test() : + rdata_ptr("ns.example.com."), + rdata_ptr2("ns2.example.com.") + {} + + const generic::PTR rdata_ptr; + const generic::PTR rdata_ptr2; +}; + +const uint8_t wiredata_ptr[] = { + 0x02, 0x6e, 0x73, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, + 0x63, 0x6f, 0x6d, 0x00 }; +const uint8_t wiredata_ptr2[] = { + // first name: ns.example.com. + 0x02, 0x6e, 0x73, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, + 0x63, 0x6f, 0x6d, 0x00, + // second name: ns2.example.com. all labels except the first should be + // compressed. + 0x03, 0x6e, 0x73, 0x32, 0xc0, 0x03 }; + +TEST_F(Rdata_PTR_Test, createFromText) { + EXPECT_EQ(0, rdata_ptr.compare(generic::PTR("ns.example.com."))); + // explicitly add a trailing dot. should be the same RDATA. + EXPECT_EQ(0, rdata_ptr.compare(generic::PTR("ns.example.com."))); + // should be case sensitive. + EXPECT_EQ(0, rdata_ptr.compare(generic::PTR("NS.EXAMPLE.COM."))); + // RDATA of a class-independent type should be recognized for any + // "unknown" class. + EXPECT_EQ(0, rdata_ptr.compare(*createRdata(RRType("PTR"), RRClass(65000), + "ns.example.com."))); +} + +TEST_F(Rdata_PTR_Test, badText) { + // Extra text at end of line + EXPECT_THROW(generic::PTR("foo.example.com. extra."), InvalidRdataText); +} + +TEST_F(Rdata_PTR_Test, createFromWire) { + EXPECT_EQ(0, rdata_ptr.compare( + *rdataFactoryFromFile(RRType("PTR"), RRClass("IN"), + "rdata_ns_fromWire"))); + // RDLENGTH is too short + EXPECT_THROW(rdataFactoryFromFile(RRType("PTR"), RRClass("IN"), + "rdata_ns_fromWire", 18), + InvalidRdataLength); + // RDLENGTH is too long + EXPECT_THROW(rdataFactoryFromFile(RRType("PTR"), RRClass("IN"), + "rdata_ns_fromWire", 36), + InvalidRdataLength); + // incomplete name. the error should be detected in the name constructor + EXPECT_THROW(rdataFactoryFromFile(RRType("PTR"), RRClass("IN"), + "rdata_ns_fromWire", 71), + DNSMessageFORMERR); + + EXPECT_EQ(0, generic::PTR("ns2.example.com.").compare( + *rdataFactoryFromFile(RRType("PTR"), RRClass("IN"), + "rdata_ns_fromWire", 55))); + EXPECT_THROW(*rdataFactoryFromFile(RRType("PTR"), RRClass("IN"), + "rdata_ns_fromWire", 63), + InvalidRdataLength); +} + +TEST_F(Rdata_PTR_Test, createFromLexer) { + EXPECT_EQ(0, rdata_ptr.compare( + *test::createRdataUsingLexer(RRType::PTR(), RRClass::IN(), + "ns.example.com."))); + + // test::createRdataUsingLexer() constructs relative to + // "example.org." origin. + EXPECT_EQ(0, generic::PTR("foo0.example.org.").compare( + *test::createRdataUsingLexer(RRType::PTR(), RRClass::IN(), + "foo0"))); + + // Extra text at end of line + EXPECT_FALSE(test::createRdataUsingLexer(RRType::PTR(), RRClass::IN(), + "foo.example.com. extra.")); +} + +TEST_F(Rdata_PTR_Test, toWireBuffer) { + rdata_ptr.toWire(obuffer); + matchWireData(wiredata_ptr, sizeof(wiredata_ptr), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_PTR_Test, toWireRenderer) { + rdata_ptr.toWire(renderer); + matchWireData(wiredata_ptr, sizeof(wiredata_ptr), + renderer.getData(), renderer.getLength()); + + rdata_ptr2.toWire(renderer); + matchWireData(wiredata_ptr2, sizeof(wiredata_ptr2), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_PTR_Test, toText) { + EXPECT_EQ("ns.example.com.", rdata_ptr.toText()); +} + +TEST_F(Rdata_PTR_Test, compare) { + generic::PTR small("a.example."); + generic::PTR large("example."); + EXPECT_TRUE(Name("a.example") > Name("example")); + EXPECT_GT(0, small.compare(large)); +} + +TEST_F(Rdata_PTR_Test, getPTRName) { + EXPECT_EQ(Name("ns.example.com"), rdata_ptr.getPTRName()); +} +} diff --git a/src/lib/dns/tests/rdata_rp_unittest.cc b/src/lib/dns/tests/rdata_rp_unittest.cc new file mode 100644 index 0000000..e752f13 --- /dev/null +++ b/src/lib/dns/tests/rdata_rp_unittest.cc @@ -0,0 +1,200 @@ +// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/rdataclass.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::util; +using namespace isc::dns; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_RP_Test : public RdataTest { +protected: + Rdata_RP_Test() : + mailbox_name("root.example.com."), + text_name("rp-text.example.com."), + // this also serves as a test for "from text" constructor in a normal + // case. + rdata_rp("root.example.com. rp-text.example.com."), + obuffer(0) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<generic::RP, isc::Exception, isc::Exception>( + rdata_str, rdata_rp, false, false); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::RP, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_rp, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText<generic::RP, InvalidRdataText, isc::Exception>( + rdata_str, rdata_rp, true, false); + } + + void checkFromText_EmptyLabel(const string& rdata_str) { + checkFromText<generic::RP, EmptyLabel, EmptyLabel>( + rdata_str, rdata_rp, true, true); + } + + void checkFromText_MissingOrigin(const string& rdata_str) { + checkFromText + <generic::RP, MissingNameOrigin, MissingNameOrigin>( + rdata_str, rdata_rp, true, true); + } + + void checkFromText_Origin(const string& rdata_str, const Name* origin) { + checkFromText<generic::RP, MissingNameOrigin, isc::Exception>( + rdata_str, rdata_rp, true, false, origin); + } + + const Name mailbox_name, text_name; + const generic::RP rdata_rp; // commonly used test RDATA + OutputBuffer obuffer; + MessageRenderer renderer; + vector<uint8_t> expected_wire; +}; + +TEST_F(Rdata_RP_Test, createFromText) { + EXPECT_EQ(mailbox_name, rdata_rp.getMailbox()); + EXPECT_EQ(text_name, rdata_rp.getText()); + + checkFromText_None("root.example.com. rp-text.example.com."); + + // origin defined for lexer constructor, but not string constructor + const Name origin("example.com"); + checkFromText_Origin("root rp-text", &origin); + + // lexer constructor accepts extra text, but string constructor doesn't + checkFromText_BadString("root.example.com. rp-text.example.com. " + "extra.example.com."); +} + +TEST_F(Rdata_RP_Test, badText) { + // invalid names + checkFromText_EmptyLabel("root..example.com. rp-text.example.com."); + checkFromText_EmptyLabel("root.example.com. rp-text..example.com."); + + // missing field + checkFromText_LexerError("root.example.com."); + + // missing origin + checkFromText_MissingOrigin("root.example.com rp-text.example.com."); + checkFromText_MissingOrigin("root.example.com. rp-text.example.com"); +} + +TEST_F(Rdata_RP_Test, createFromWire) { + RdataPtr rdata(rdataFactoryFromFile(RRType::RP(), RRClass::IN(), + "rdata_rp_fromWire1.wire")); + EXPECT_EQ(mailbox_name, dynamic_cast<generic::RP&>(*rdata).getMailbox()); + EXPECT_EQ(text_name, dynamic_cast<generic::RP&>(*rdata).getText()); + + // a similar test with names being compressed + rdata = rdataFactoryFromFile(RRType::RP(), RRClass::IN(), + "rdata_rp_fromWire2.wire", 30); + EXPECT_EQ(mailbox_name, dynamic_cast<generic::RP&>(*rdata).getMailbox()); + EXPECT_EQ(Name("rp-text.example.net"), + dynamic_cast<generic::RP&>(*rdata).getText()); +} + +TEST_F(Rdata_RP_Test, badFromWire) { + // RDLEN is too short + EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(), + "rdata_rp_fromWire3.wire"), + InvalidRdataLength); + + // RDLEN is too long + EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(), + "rdata_rp_fromWire4.wire"), + InvalidRdataLength); + + // bogus mailbox name + EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(), + "rdata_rp_fromWire5.wire"), + DNSMessageFORMERR); + + // bogus text name + EXPECT_THROW(rdataFactoryFromFile(RRType::RP(), RRClass::IN(), + "rdata_rp_fromWire6.wire"), + DNSMessageFORMERR); +} + +TEST_F(Rdata_RP_Test, createFromParams) { + EXPECT_EQ(mailbox_name, generic::RP(mailbox_name, text_name).getMailbox()); + EXPECT_EQ(text_name, generic::RP(mailbox_name, text_name).getText()); +} + +TEST_F(Rdata_RP_Test, toWireBuffer) { + // construct expected data + UnitTestUtil::readWireData("rdata_rp_toWire1.wire", expected_wire); + + // construct actual data + rdata_rp.toWire(obuffer); + + // then compare them + matchWireData(&expected_wire[0], expected_wire.size(), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_RP_Test, toWireRenderer) { + // similar to toWireBuffer, but names in RDATA could be compressed due to + // preceding names. Actually they must not be compressed according to + // RFC3597, and this test checks that. + + UnitTestUtil::readWireData("rdata_rp_toWire2.wire", expected_wire); + + renderer.writeName(Name("a.example.com")); + renderer.writeName(Name("b.example.net")); + generic::RP(mailbox_name, Name("rp-text.example.net")).toWire(renderer); + matchWireData(&expected_wire[0], expected_wire.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_RP_Test, toText) { + // there's not much to test for this method. Only checking a simple case. + EXPECT_EQ("root.example.com. rp-text.example.com.", rdata_rp.toText()); +} + +TEST_F(Rdata_RP_Test, compare) { + // check reflexivity + EXPECT_EQ(0, rdata_rp.compare(rdata_rp)); + + // names must be compared in case-insensitive manner + EXPECT_EQ(0, rdata_rp.compare(generic::RP("ROOT.example.com. " + "rp-text.EXAMPLE.com."))); + + // another RP whose mailbox name is larger than that of rdata_rp. + const generic::RP large1_rp("zzzz.example.com. rp-text.example.com."); + EXPECT_GT(0, rdata_rp.compare(large1_rp)); + EXPECT_LT(0, large1_rp.compare(rdata_rp)); + + // yet another RP whose text name is larger than that of rdata_rp. + const generic::RP large2_rp("root.example.com. zzzzzzz.example.com."); + EXPECT_GT(0, rdata_rp.compare(large2_rp)); + EXPECT_LT(0, large2_rp.compare(rdata_rp)); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(rdata_rp.compare(*RdataTest::rdata_nomatch), bad_cast); +} +} diff --git a/src/lib/dns/tests/rdata_rrsig_unittest.cc b/src/lib/dns/tests/rdata_rrsig_unittest.cc new file mode 100644 index 0000000..b198d15 --- /dev/null +++ b/src/lib/dns/tests/rdata_rrsig_unittest.cc @@ -0,0 +1,369 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <util/time_utilities.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> +#include <dns/tests/rdata_unittest.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { + +const uint8_t wiredata_rrsig[] = { + // type covered = A + 0x00, 0x01, + // algorithm = 5 + 0x05, + // labels = 4 + 0x04, + // original TTL = 43200 (0x0000a8c0) + 0x00, 0x00, 0xa8, 0xc0, + // signature expiration = 1266961577 (0x4b844ca9) + 0x4b, 0x84, 0x4c, 0xa9, + // signature inception = 1266875177 (0x4b82fb29) + 0x4b, 0x82, 0xfb, 0x29, + // key tag = 8496 (0x2130) + 0x21, 0x30, + // signer's name (isc.org.) + // 3 i s c 3 o r g 0 + 0x03, 0x69, 0x73, 0x63, 0x03, 0x6f, 0x72, 0x67, 0x00, + // signature data follows + 0x7a, 0xfc, 0x61, 0x94, 0x6c, + 0x75, 0xde, 0x6a, 0x4a, 0x2d, 0x59, 0x0a, 0xb2, + 0x3a, 0x46, 0xcf, 0x27, 0x12, 0xe6, 0xdc, 0x2d, + 0x22, 0x8c, 0x4e, 0x9a, 0x53, 0x75, 0xe3, 0x0f, + 0x6d, 0xe4, 0x08, 0x33, 0x18, 0x19, 0xb3, 0x76, + 0x21, 0x9d, 0x2c, 0x8a, 0xc5, 0x69, 0xba, 0xab, + 0xef, 0x66, 0x9f, 0xda, 0xb5, 0x2a, 0xf9, 0x40, + 0xc1, 0x28, 0xc5, 0x97, 0xba, 0x3c, 0x19, 0x4d, + 0x95, 0x13, 0xc2, 0xcd, 0xf6, 0xb1, 0x59, 0x5d, + 0x0c, 0xf9, 0x3f, 0x35, 0xbb, 0x9a, 0x70, 0x93, + 0x36, 0xe5, 0xf4, 0x17, 0x7e, 0xfe, 0x66, 0x3b, + 0x70, 0x1f, 0xed, 0x33, 0xa8, 0xa3, 0x0d, 0xc0, + 0x8c, 0xc6, 0x95, 0x1b, 0xd8, 0x9c, 0x8c, 0x25, + 0xb4, 0x57, 0x9e, 0x56, 0x71, 0x64, 0x14, 0x7f, + 0x8f, 0x6d, 0xfa, 0xc5, 0xca, 0x3f, 0x36, 0xe2, + 0xa4, 0xdf, 0x60, 0xfa, 0xcd, 0x59, 0x3e, 0x22, + 0x32, 0xa1, 0xf7 +}; + +class Rdata_RRSIG_Test : public RdataTest { +protected: + Rdata_RRSIG_Test() : + rrsig_txt("A 5 4 43200 20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="), + rdata_rrsig(rrsig_txt) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<generic::RRSIG, isc::Exception, isc::Exception>( + rdata_str, rdata_rrsig, false, false); + } + + void checkFromText_InvalidText(const string& rdata_str) { + checkFromText<generic::RRSIG, InvalidRdataText, InvalidRdataText>( + rdata_str, rdata_rrsig, true, true); + } + + void checkFromText_InvalidType(const string& rdata_str) { + checkFromText<generic::RRSIG, InvalidRRType, InvalidRRType>( + rdata_str, rdata_rrsig, true, true); + } + + void checkFromText_InvalidTime(const string& rdata_str) { + checkFromText<generic::RRSIG, InvalidTime, InvalidTime>( + rdata_str, rdata_rrsig, true, true); + } + + void checkFromText_BadValue(const string& rdata_str) { + checkFromText<generic::RRSIG, BadValue, BadValue>( + rdata_str, rdata_rrsig, true, true); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::RRSIG, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_rrsig, true, true); + } + + void checkFromText_MissingOrigin(const string& rdata_str) { + checkFromText + <generic::RRSIG, MissingNameOrigin, MissingNameOrigin>( + rdata_str, rdata_rrsig, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText + <generic::RRSIG, InvalidRdataText, isc::Exception>( + rdata_str, rdata_rrsig, true, false); + } + + const string rrsig_txt; + const generic::RRSIG rdata_rrsig; +}; + +TEST_F(Rdata_RRSIG_Test, fromText) { + EXPECT_EQ(rrsig_txt, rdata_rrsig.toText()); + EXPECT_EQ(isc::dns::RRType::A(), rdata_rrsig.typeCovered()); + + // Missing signature is OK + EXPECT_NO_THROW(const generic::RRSIG sig( + "A 5 4 43200 20100223214617 20100222214617 8496 isc.org.")); + + // Space in signature data is OK + checkFromText_None( + "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz " + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/ " + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU " + "f49t+sXKPzbipN9g+s1ZPiIyofc="); + + // Multi-line signature data is OK, if enclosed in parentheses + checkFromText_None( + "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. " + "( evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz\n" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/\n" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU\n" + "f49t+sXKPzbipN9g+s1ZPiIyofc= )"); + + // Trailing garbage. This should cause only the string constructor + // to fail, but the lexer constructor must be able to continue + // parsing from it. + checkFromText_BadString( + "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc= ; comment\n" + "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); +} + +TEST_F(Rdata_RRSIG_Test, badText_missingFields) { + checkFromText_LexerError("A"); + checkFromText_LexerError("A 5"); + checkFromText_LexerError("A 5 4"); + checkFromText_LexerError("A 5 4 43200"); + checkFromText_LexerError("A 5 4 43200 20100223214617"); + checkFromText_LexerError("A 5 4 43200 20100223214617 20100222214617"); + checkFromText_LexerError("A 5 4 43200 20100223214617 20100222214617 " + "8496"); +} + +TEST_F(Rdata_RRSIG_Test, badText_coveredType) { + checkFromText_InvalidType("SPORK"); +} + +TEST_F(Rdata_RRSIG_Test, badText_algorithm) { + checkFromText_InvalidText( + "A 555 4 43200 " + "20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); + checkFromText_LexerError( + "A FIVE 4 43200 " + "20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); +} + +TEST_F(Rdata_RRSIG_Test, badText_labels) { + checkFromText_InvalidText( + "A 5 4444 43200 " + "20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); + checkFromText_LexerError( + "A 5 FOUR 43200 " + "20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); +} + +TEST_F(Rdata_RRSIG_Test, badText_ttl) { + checkFromText_LexerError( + "A 5 4 999999999999 " + "20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); + checkFromText_LexerError( + "A 5 4 TTL " + "20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); + + // alternate form of TTL is not okay + checkFromText_LexerError( + "A 5 4 12H 20100223214617 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz " + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/ " + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU " + "f49t+sXKPzbipN9g+s1ZPiIyofc="); +} + +TEST_F(Rdata_RRSIG_Test, badText_expiration) { + checkFromText_InvalidTime( + "A 5 4 43200 " + "201002232 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); + checkFromText_InvalidTime( + "A 5 4 43200 " + "EXPIRATION 20100222214617 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); +} + +TEST_F(Rdata_RRSIG_Test, badText_inception) { + checkFromText_InvalidTime( + "A 5 4 43200 " + "20100223214617 20100227 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); + checkFromText_InvalidTime( + "A 5 4 43200 " + "20100223214617 INCEPTION 8496 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); +} + +TEST_F(Rdata_RRSIG_Test, badText_keytag) { + checkFromText_InvalidText( + "A 5 4 43200 " + "20100223214617 20100222214617 999999 isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); + checkFromText_LexerError( + "A 5 4 43200 " + "20100223214617 20100222214617 TAG isc.org. " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); +} + +TEST_F(Rdata_RRSIG_Test, badText_signer) { + checkFromText_MissingOrigin( + "A 5 4 43200 " + "20100223214617 20100222214617 8496 isc.org " + "evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); +} + +TEST_F(Rdata_RRSIG_Test, badText_signature) { + checkFromText_BadValue( + "A 5 4 43200 " + "20100223214617 20100222214617 8496 isc.org. " + "EEeeeeeeEEEeeeeeeGaaahAAAAAAAAHHHHHHHHHHH!="); + + // no space between the tag and signer + checkFromText_LexerError( + "A 5 4 43200 20100223214617 20100222214617 " + "8496isc.org. ofc="); + + // unterminated multi-line base64 + checkFromText_LexerError( + "A 5 4 43200 20100223214617 20100222214617 8496 isc.org. " + "( evxhlGx13mpKLVkKsjpGzycS5twtIoxOmlN14w9t5AgzGBmz\n" + "diGdLIrFabqr72af2rUq+UDBKMWXujwZTZUTws32sVldDPk/\n" + "NbuacJM25fQXfv5mO3Af7TOoow3AjMaVG9icjCW0V55WcWQU\n" + "f49t+sXKPzbipN9g+s1ZPiIyofc="); +} + +TEST_F(Rdata_RRSIG_Test, createFromLexer) { + EXPECT_EQ(0, rdata_rrsig.compare( + *test::createRdataUsingLexer(RRType::RRSIG(), RRClass::IN(), + rrsig_txt))); + + // Exceptions cause NULL to be returned. + EXPECT_FALSE(test::createRdataUsingLexer(RRType::RRSIG(), RRClass::IN(), + "INVALIDINPUT")); +} + +TEST_F(Rdata_RRSIG_Test, toWireRenderer) { + rdata_rrsig.toWire(renderer); + + matchWireData(wiredata_rrsig, sizeof(wiredata_rrsig), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_RRSIG_Test, toWireBuffer) { + rdata_rrsig.toWire(obuffer); + + matchWireData(wiredata_rrsig, sizeof(wiredata_rrsig), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_RRSIG_Test, createFromWire) { + const string rrsig_txt2( + "A 5 2 43200 20100327070149 20100225070149 2658 isc.org. " + "HkJk/xZTvzePU8NENl/ley8bbUumhk1hXciyqhLnz1VQFzkDooej6neX" + "ZgWZzQKeTKPOYWrnYtdZW4PnPQFeUl3orgLev7F8J6FZlDn0y/J/ThR5" + "m36Mo2/Gdxjj8lJ/IjPVkdpKyBpcnYND8KEIma5MyNCNeyO1UkfPQZGHNSQ="); + EXPECT_EQ(rrsig_txt2, + rdataFactoryFromFile(RRType("RRSIG"), RRClass("IN"), + "rdata_rrsig_fromWire1")->toText()); + const generic::RRSIG rdata_rrsig2(rrsig_txt2); + EXPECT_EQ(0, rdata_rrsig2.compare( + *rdataFactoryFromFile(RRType("RRSIG"), RRClass("IN"), + "rdata_rrsig_fromWire1"))); + + // RDLEN is too short + EXPECT_THROW(rdataFactoryFromFile(RRType::RRSIG(), RRClass::IN(), + "rdata_rrsig_fromWire2.wire"), + InvalidRdataLength); +} +} diff --git a/src/lib/dns/tests/rdata_soa_unittest.cc b/src/lib/dns/tests/rdata_soa_unittest.cc new file mode 100644 index 0000000..21f4dc4 --- /dev/null +++ b/src/lib/dns/tests/rdata_soa_unittest.cc @@ -0,0 +1,249 @@ +// Copyright (C) 2010-2017 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_SOA_Test : public RdataTest { +protected: + Rdata_SOA_Test() : + rdata_soa(Name("ns.example.com"), + Name("root.example.com"), + 2010012601, 3600, 300, 3600000, 1200) + {} + + template <typename ExForString, typename ExForLexer> + void checkFromTextSOA(const string& soa_txt, const Name* origin = NULL, + bool throw_str_version = true, + bool throw_lexer_version = true) + { + checkFromText<generic::SOA, ExForString, ExForLexer>( + soa_txt, rdata_soa, throw_str_version, throw_lexer_version, + origin); + } + + const generic::SOA rdata_soa; +}; + +TEST_F(Rdata_SOA_Test, createFromText) { + // Below we specify isc::Exception as a dummy value for the exception type + // in case it's not expected to throw an exception; the type isn't used + // in the check code. + + // A simple case. + checkFromTextSOA<isc::Exception, isc::Exception>( + "ns.example.com. root.example.com. 2010012601 3600 300 3600000 1200", + NULL, false, false); + + // Beginning and trailing space are ignored. + checkFromTextSOA<isc::Exception, isc::Exception>( + " ns.example.com. root.example.com. " + "2010012601 3600 300 3600000 1200 ", NULL, false, false); + + // using extended TTL-like form for some parameters. + checkFromTextSOA<isc::Exception, isc::Exception>( + "ns.example.com. root.example.com. 2010012601 1H 5M 1000H 20M", + NULL, false, false); + + // multi-line. + checkFromTextSOA<isc::Exception, isc::Exception>( + "ns.example.com. (root.example.com.\n" + "2010012601 1H 5M 1000H) 20M", NULL, false, false); + + // relative names for MNAME and RNAME with a separate origin (lexer + // version only) + const Name origin("example.com"); + checkFromTextSOA<MissingNameOrigin, isc::Exception>( + "ns root 2010012601 1H 5M 1000H 20M", &origin, true, false); + + // with the '@' notation with a separate origin (lexer version only; + // string version would throw) + const Name full_mname("ns.example.com"); + checkFromTextSOA<MissingNameOrigin, isc::Exception>( + "@ root.example.com. 2010012601 1H 5M 1000H 20M", &full_mname, true, + false); + + // bad MNAME/RNAMEs + checkFromTextSOA<EmptyLabel, EmptyLabel>( + "bad..example. . 2010012601 1H 5M 1000H 20M"); + checkFromTextSOA<EmptyLabel, EmptyLabel>( + ". bad..example. 2010012601 1H 5M 1000H 20M"); + + // Names shouldn't be quoted. + checkFromTextSOA<InvalidRdataText, MasterLexer::LexerError>( + "\".\" . 0 0 0 0 0"); + checkFromTextSOA<InvalidRdataText, MasterLexer::LexerError>( + ". \".\" 0 0 0 0 0"); + + // Missing MAME or RNAME: for the string version, the serial would be + // tried as RNAME and result in "not absolute". For the lexer version, + // it reaches the end-of-line, missing min TTL. + checkFromTextSOA<MissingNameOrigin, MasterLexer::LexerError>( + ". 2010012601 0 0 0 0", &Name::ROOT_NAME()); + + // bad serial. the string version converts lexer error to + // InvalidRdataText. + checkFromTextSOA<InvalidRdataText, MasterLexer::LexerError>( + ". . bad 0 0 0 0"); + + // bad serial; exceeding the uint32_t range (4294967296 = 2^32) + checkFromTextSOA<InvalidRdataText, MasterLexer::LexerError>( + ". . 4294967296 0 0 0 0"); + + // Bad format for other numeric parameters. These will be tried as a TTL, + // and result in an exception there. + checkFromTextSOA<InvalidRRTTL, InvalidRRTTL>( + ". . 2010012601 bad 0 0 0"); + checkFromTextSOA<InvalidRRTTL, InvalidRRTTL>( + ". . 2010012601 4294967296 0 0 0"); + checkFromTextSOA<InvalidRRTTL, InvalidRRTTL>( + ". . 2010012601 0 bad 0 0"); + checkFromTextSOA<InvalidRRTTL, InvalidRRTTL>( + ". . 2010012601 0 4294967296 0 0"); + checkFromTextSOA<InvalidRRTTL, InvalidRRTTL>( + ". . 2010012601 0 0 bad 0"); + checkFromTextSOA<InvalidRRTTL, InvalidRRTTL>( + ". . 2010012601 0 0 4294967296 0"); + checkFromTextSOA<InvalidRRTTL, InvalidRRTTL>( + ". . 2010012601 0 0 0 bad"); + checkFromTextSOA<InvalidRRTTL, InvalidRRTTL>( + ". . 2010012601 0 0 0 4294967296"); + + // No space between RNAME and serial. This case is the same as missing + // M/RNAME. + checkFromTextSOA<MissingNameOrigin, MasterLexer::LexerError>( + ". example.0 0 0 0 0", &Name::ROOT_NAME()); + + // Extra parameter. string version immediately detects the error. + // lexer version defers the check to the upper layer (we pass origin + // to skip the check with the string version). + checkFromTextSOA<InvalidRdataText, isc::Exception>( + "ns.example.com. root.example.com. 2010012601 1H 5M 1000H 20M " + "extra", &origin, true, false); + + // Likewise. Redundant newline is also considered an error. The lexer + // version accepts trailing newline, but not the beginning one (where + // the lexer expects a string excluding newline and EOF). + checkFromTextSOA<InvalidRdataText, isc::Exception>( + "ns.example.com. root.example.com. 2010012601 1H 5M 1000H 20M\n", + NULL, true, false); + checkFromTextSOA<InvalidRdataText, MasterLexer::LexerError>( + "\nns.example.com. root.example.com. 2010012601 1H 5M 1000H 20M", + NULL, true, true); +} + +TEST_F(Rdata_SOA_Test, createFromWire) { + EXPECT_EQ(0, rdata_soa.compare( + *rdataFactoryFromFile(RRType("SOA"), RRClass("IN"), + "rdata_soa_fromWire"))); + // TBD: more tests +} + +TEST_F(Rdata_SOA_Test, createFromLexer) { + EXPECT_EQ(0, rdata_soa.compare( + *test::createRdataUsingLexer(RRType::SOA(), RRClass::IN(), + "ns.example.com. root.example.com. " + "2010012601 3600 300 3600000 1200"))); +} + +TEST_F(Rdata_SOA_Test, toWireRenderer) { + renderer.skip(2); + rdata_soa.toWire(renderer); + + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_soa_fromWire", data); + matchWireData(&data[2], data.size() - 2, + static_cast<const uint8_t *>(renderer.getData()) + 2, + renderer.getLength() - 2); +} + +TEST_F(Rdata_SOA_Test, toWireBuffer) { + obuffer.skip(2); + rdata_soa.toWire(obuffer); + vector<unsigned char> data; + UnitTestUtil::readWireData("rdata_soa_toWireUncompressed.wire", data); + matchWireData(&data[2], data.size() - 2, + static_cast<const uint8_t *>(obuffer.getData()) + 2, + obuffer.getLength() - 2); +} + +TEST_F(Rdata_SOA_Test, toText) { + EXPECT_EQ("ns.example.com. root.example.com. " + "2010012601 3600 300 3600000 1200", rdata_soa.toText()); +} + +TEST_F(Rdata_SOA_Test, getSerial) { + EXPECT_EQ(2010012601, rdata_soa.getSerial().getValue()); +} + +TEST_F(Rdata_SOA_Test, getMinimum) { + EXPECT_EQ(1200, rdata_soa.getMinimum()); + + // Also check with a very large number (with the MSB being 1). + EXPECT_EQ(2154848336u, generic::SOA(Name("ns.example.com"), + Name("root.example.com"), + 0, 0, 0, 0, 0x80706050).getMinimum()); +} + +void +compareCheck(const generic::SOA& small, const generic::SOA& large) { + EXPECT_GT(0, small.compare(large)); + EXPECT_LT(0, large.compare(small)); +} + +TEST_F(Rdata_SOA_Test, compare) { + // Check simple equivalence + EXPECT_EQ(0, rdata_soa.compare(generic::SOA( + "ns.example.com. root.example.com. " + "2010012601 3600 300 3600000 1200"))); + // Check name comparison is case insensitive + EXPECT_EQ(0, rdata_soa.compare(generic::SOA( + "NS.example.com. root.EXAMPLE.com. " + "2010012601 3600 300 3600000 1200"))); + + // Check names are compared in the RDATA comparison semantics (different + // from DNSSEC ordering for owner names) + compareCheck(generic::SOA("a.example. . 0 0 0 0 0"), + generic::SOA("example. . 0 0 0 0 0")); + compareCheck(generic::SOA(". a.example. 0 0 0 0 0"), + generic::SOA(". example. 0 0 0 0 0")); + + // Compare other numeric fields: 1076895760 = 0x40302010, + // 270544960 = 0x10203040. These are chosen to make sure that machine + // endianness doesn't confuse the comparison results. + compareCheck(generic::SOA(". . 270544960 0 0 0 0"), + generic::SOA(". . 1076895760 0 0 0 0")); + compareCheck(generic::SOA(". . 0 270544960 0 0 0"), + generic::SOA(". . 0 1076895760 0 0 0")); + compareCheck(generic::SOA(". . 0 0 270544960 0 0"), + generic::SOA(". . 0 0 1076895760 0 0")); + compareCheck(generic::SOA(". . 0 0 0 270544960 0"), + generic::SOA(". . 0 0 0 1076895760 0")); + compareCheck(generic::SOA(". . 0 0 0 0 270544960"), + generic::SOA(". . 0 0 0 0 1076895760")); +} + +} diff --git a/src/lib/dns/tests/rdata_srv_unittest.cc b/src/lib/dns/tests/rdata_srv_unittest.cc new file mode 100644 index 0000000..a3296f2 --- /dev/null +++ b/src/lib/dns/tests/rdata_srv_unittest.cc @@ -0,0 +1,205 @@ +// Copyright (C) 2011-2019 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_SRV_Test : public RdataTest { +public: + Rdata_SRV_Test() : + srv_txt("1 5 1500 a.example.com."), + srv_txt2("1 5 1400 example.com."), + too_long_label("012345678901234567890123456789" + "0123456789012345678901234567890123."), + rdata_srv(srv_txt), + rdata_srv2(srv_txt2) + {} + + const string srv_txt; + const string srv_txt2; + const string too_long_label; + const in::SRV rdata_srv; + const in::SRV rdata_srv2; +}; + +// 1 5 1500 a.example.com. +const uint8_t wiredata_srv[] = { + 0x00, 0x01, 0x00, 0x05, 0x05, 0xdc, 0x01, 0x61, 0x07, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00}; +// 1 5 1400 example.com. +const uint8_t wiredata_srv2[] = { + 0x00, 0x01, 0x00, 0x05, 0x05, 0x78, 0x07, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00}; + +TEST_F(Rdata_SRV_Test, createFromText) { + EXPECT_EQ(1, rdata_srv.getPriority()); + EXPECT_EQ(5, rdata_srv.getWeight()); + EXPECT_EQ(1500, rdata_srv.getPort()); + EXPECT_EQ(Name("a.example.com."), rdata_srv.getTarget()); +} + +TEST_F(Rdata_SRV_Test, badText) { + // priority is too large (2814...6 is 2^48) + EXPECT_THROW(in::SRV("281474976710656 5 1500 a.example.com."), + InvalidRdataText); + // weight is too large + EXPECT_THROW(in::SRV("1 281474976710656 1500 a.example.com."), + InvalidRdataText); + // port is too large + EXPECT_THROW(in::SRV("1 5 281474976710656 a.example.com."), + InvalidRdataText); + // incomplete text + EXPECT_THROW(in::SRV("1 5 a.example.com."), + InvalidRdataText); + EXPECT_THROW(in::SRV("1 5 1500a.example.com."), + InvalidRdataText); + // bad name + EXPECT_THROW(in::SRV("1 5 1500 a.example.com." + too_long_label), + TooLongLabel); + // Extra text at end of line + EXPECT_THROW(in::SRV("1 5 1500 a.example.com. extra."), InvalidRdataText); +} + +TEST_F(Rdata_SRV_Test, assignment) { + in::SRV copy((string(srv_txt2))); + copy = rdata_srv; + EXPECT_EQ(0, copy.compare(rdata_srv)); + + // Check if the copied data is valid even after the original is deleted + in::SRV* copy2 = new in::SRV(rdata_srv); + in::SRV copy3((string(srv_txt2))); + copy3 = *copy2; + delete copy2; + EXPECT_EQ(0, copy3.compare(rdata_srv)); + + // Self assignment + copy = *© + EXPECT_EQ(0, copy.compare(rdata_srv)); +} + +TEST_F(Rdata_SRV_Test, createFromWire) { + EXPECT_EQ(0, rdata_srv.compare( + *rdataFactoryFromFile(RRType("SRV"), RRClass("IN"), + "rdata_srv_fromWire"))); + // RDLENGTH is too short + EXPECT_THROW(rdataFactoryFromFile(RRType("SRV"), RRClass("IN"), + "rdata_srv_fromWire", 23), + InvalidRdataLength); + // RDLENGTH is too long + EXPECT_THROW(rdataFactoryFromFile(RRType("SRV"), RRClass("IN"), + "rdata_srv_fromWire", 46), + InvalidRdataLength); + // incomplete name. the error should be detected in the name constructor + EXPECT_THROW(rdataFactoryFromFile(RRType("SRV"), RRClass("IN"), + "rdata_cname_fromWire", 69), + DNSMessageFORMERR); + // parse compressed target name + EXPECT_EQ(0, rdata_srv.compare( + *rdataFactoryFromFile(RRType("SRV"), RRClass("IN"), + "rdata_srv_fromWire", 89))); +} + +TEST_F(Rdata_SRV_Test, createFromLexer) { + EXPECT_EQ(0, rdata_srv.compare( + *test::createRdataUsingLexer(RRType::SRV(), RRClass::IN(), + "1 5 1500 a.example.com."))); + + // test::createRdataUsingLexer() constructs relative to + // "example.org." origin. + EXPECT_EQ(0, in::SRV("1 5 1500 server16.example.org.").compare( + *test::createRdataUsingLexer(RRType::SRV(), RRClass::IN(), + "1 5 1500 server16"))); + + // Exceptions cause NULL to be returned. + + // Bad priority + EXPECT_FALSE(test::createRdataUsingLexer(RRType::SRV(), RRClass::IN(), + "65536 5 1500 " + "a.example.com.")); + // Bad weight + EXPECT_FALSE(test::createRdataUsingLexer(RRType::SRV(), RRClass::IN(), + "1 65536 1500 " + "a.example.com.")); + // Bad port + EXPECT_FALSE(test::createRdataUsingLexer(RRType::SRV(), RRClass::IN(), + "1 5 281474976710656 " + "a.example.com.")); + // Extra text at end of line + EXPECT_FALSE(test::createRdataUsingLexer(RRType::SRV(), RRClass::IN(), + "1 5 1500 a.example.com. extra.")); +} + +TEST_F(Rdata_SRV_Test, toWireBuffer) { + rdata_srv.toWire(obuffer); + matchWireData(wiredata_srv, sizeof(wiredata_srv), + obuffer.getData(), obuffer.getLength()); + + obuffer.clear(); + rdata_srv2.toWire(obuffer); + matchWireData(wiredata_srv2, sizeof(wiredata_srv2), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_SRV_Test, toWireRenderer) { + rdata_srv.toWire(renderer); + matchWireData(wiredata_srv, sizeof(wiredata_srv), + renderer.getData(), renderer.getLength()); + + renderer.clear(); + rdata_srv2.toWire(renderer); + matchWireData(wiredata_srv2, sizeof(wiredata_srv2), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_SRV_Test, toText) { + EXPECT_EQ(srv_txt, rdata_srv.toText()); + EXPECT_EQ(srv_txt2, rdata_srv2.toText()); +} + +TEST_F(Rdata_SRV_Test, compare) { + // test RDATAs, sorted in the ascending order. + vector<in::SRV> compare_set; + compare_set.push_back(in::SRV("1 5 1500 a.example.com.")); + compare_set.push_back(in::SRV("2 5 1500 a.example.com.")); + compare_set.push_back(in::SRV("2 6 1500 a.example.com.")); + compare_set.push_back(in::SRV("2 6 1600 a.example.com.")); + compare_set.push_back(in::SRV("2 6 1600 example.com.")); + + EXPECT_EQ(0, compare_set[0].compare( + in::SRV("1 5 1500 a.example.com."))); + + vector<in::SRV>::const_iterator it; + vector<in::SRV>::const_iterator it_end = compare_set.end(); + for (it = compare_set.begin(); it != it_end - 1; ++it) { + EXPECT_GT(0, (*it).compare(*(it + 1))); + EXPECT_LT(0, (*(it + 1)).compare(*it)); + } + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(rdata_srv.compare(*RdataTest::rdata_nomatch), bad_cast); +} +} diff --git a/src/lib/dns/tests/rdata_sshfp_unittest.cc b/src/lib/dns/tests/rdata_sshfp_unittest.cc new file mode 100644 index 0000000..2bf88f3 --- /dev/null +++ b/src/lib/dns/tests/rdata_sshfp_unittest.cc @@ -0,0 +1,311 @@ +// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <algorithm> +#include <string> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +#include <boost/algorithm/string.hpp> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_SSHFP_Test : public RdataTest { +protected: + Rdata_SSHFP_Test() : + sshfp_txt("2 1 123456789abcdef67890123456789abcdef67890"), + rdata_sshfp(sshfp_txt) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<generic::SSHFP, isc::Exception, isc::Exception>( + rdata_str, rdata_sshfp, false, false); + } + + void checkFromText_InvalidText(const string& rdata_str) { + checkFromText<generic::SSHFP, InvalidRdataText, InvalidRdataText>( + rdata_str, rdata_sshfp, true, true); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::SSHFP, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_sshfp, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText + <generic::SSHFP, InvalidRdataText, isc::Exception>( + rdata_str, rdata_sshfp, true, false); + } + + const string sshfp_txt; + const generic::SSHFP rdata_sshfp; +}; + +const uint8_t rdata_sshfp_wiredata[] = { + // algorithm + 0x02, + // fingerprint type + 0x01, + // fingerprint + 0x12, 0x34, 0x56, 0x78, + 0x9a, 0xbc, 0xde, 0xf6, + 0x78, 0x90, 0x12, 0x34, + 0x56, 0x78, 0x9a, 0xbc, + 0xde, 0xf6, 0x78, 0x90 +}; + +TEST_F(Rdata_SSHFP_Test, createFromText) { + // Basic test + checkFromText_None(sshfp_txt); + + // With different spacing + checkFromText_None("2 1 123456789abcdef67890123456789abcdef67890"); + + // Combination of lowercase and uppercase + checkFromText_None("2 1 123456789ABCDEF67890123456789abcdef67890"); + + // spacing in the fingerprint field + checkFromText_None("2 1 123456789abcdef67890 123456789abcdef67890"); + + // multi-line fingerprint field + checkFromText_None("2 1 ( 123456789abcdef67890\n 123456789abcdef67890 )"); + + // string constructor throws if there's extra text, + // but lexer constructor doesn't + checkFromText_BadString(sshfp_txt + "\n" + sshfp_txt); +} + +TEST_F(Rdata_SSHFP_Test, algorithmTypes) { + // Some of these may not be RFC conformant, but we relax the check + // in our code to work with algorithm and fingerprint types that may + // show up in the future. + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 1 12ab")); + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("2 1 12ab")); + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("3 1 12ab")); + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("128 1 12ab")); + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("255 1 12ab")); + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 1 12ab")); + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 2 12ab")); + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 3 12ab")); + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 128 12ab")); + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 255 12ab")); + + // 0 is reserved, but we allow that too + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("0 1 12ab")); + EXPECT_NO_THROW(const generic::SSHFP rdata_sshfp("1 0 12ab")); + + // > 255 would be broken + EXPECT_THROW(const generic::SSHFP rdata_sshfp("256 1 12ab"), + InvalidRdataText); + EXPECT_THROW(const generic::SSHFP rdata_sshfp("2 256 12ab"), + InvalidRdataText); +} + +TEST_F(Rdata_SSHFP_Test, badText) { + checkFromText_LexerError("1"); + checkFromText_LexerError("ONE 2 123456789abcdef67890123456789abcdef67890"); + checkFromText_LexerError("1 TWO 123456789abcdef67890123456789abcdef67890"); + checkFromText_InvalidText("1 2 BUCKLEMYSHOE"); + checkFromText_InvalidText(sshfp_txt + " extra text"); + + // yes, these are redundant to the last test cases in algorithmTypes + checkFromText_InvalidText( + "2345 1 123456789abcdef67890123456789abcdef67890"); + checkFromText_InvalidText( + "2 1234 123456789abcdef67890123456789abcdef67890"); + + // negative values are trapped in the lexer rather than the constructor + checkFromText_LexerError("-2 1 123456789abcdef67890123456789abcdef67890"); + checkFromText_LexerError("2 -1 123456789abcdef67890123456789abcdef67890"); +} + +TEST_F(Rdata_SSHFP_Test, copyAndAssign) { + // Copy construct + generic::SSHFP rdata_sshfp2(rdata_sshfp); + EXPECT_EQ(0, rdata_sshfp.compare(rdata_sshfp2)); + + // Assignment, mainly to confirm it doesn't cause disruption. + rdata_sshfp2 = rdata_sshfp; + EXPECT_EQ(0, rdata_sshfp.compare(rdata_sshfp2)); +} + +TEST_F(Rdata_SSHFP_Test, createFromWire) { + // Basic test + EXPECT_EQ(0, rdata_sshfp.compare( + *rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire"))); + // Combination of lowercase and uppercase + EXPECT_EQ(0, rdata_sshfp.compare( + *rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire2"))); + // algorithm=1, fingerprint=1 + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire3.wire")); + + // algorithm=255, fingerprint=1 + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire4.wire")); + + // algorithm=0, fingerprint=1 + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire5.wire")); + + // algorithm=5, fingerprint=0 + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire6.wire")); + + // algorithm=255, fingerprint=255 + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire7.wire")); + + // short fingerprint data + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire8.wire")); + + // fingerprint is shorter than rdata len + EXPECT_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire9"), + InvalidBufferPosition); + + // fingerprint is missing + EXPECT_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire10"), + InvalidBufferPosition); + + // all rdata is missing + EXPECT_THROW(rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire11"), + InvalidBufferPosition); +} + +TEST_F(Rdata_SSHFP_Test, createFromParams) { + const generic::SSHFP rdata_sshfp2( + 2, 1, "123456789abcdef67890123456789abcdef67890"); + EXPECT_EQ(0, rdata_sshfp2.compare(rdata_sshfp)); +} + +TEST_F(Rdata_SSHFP_Test, toText) { + EXPECT_TRUE(boost::iequals(sshfp_txt, rdata_sshfp.toText())); + + const string sshfp_txt2("2 1"); + const generic::SSHFP rdata_sshfp2(sshfp_txt2); + EXPECT_TRUE(boost::iequals(sshfp_txt2, rdata_sshfp2.toText())); + + const generic::SSHFP rdata_sshfp3("2 1 "); + EXPECT_TRUE(boost::iequals(sshfp_txt2, rdata_sshfp3.toText())); +} + +TEST_F(Rdata_SSHFP_Test, toWire) { + this->obuffer.clear(); + rdata_sshfp.toWire(this->obuffer); + + EXPECT_EQ(sizeof (rdata_sshfp_wiredata), + this->obuffer.getLength()); + + matchWireData(rdata_sshfp_wiredata, sizeof(rdata_sshfp_wiredata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_SSHFP_Test, compare) { + const generic::SSHFP rdata_sshfp2("2 1"); + EXPECT_EQ(-1, rdata_sshfp2.compare(rdata_sshfp)); + EXPECT_EQ(1, rdata_sshfp.compare(rdata_sshfp2)); +} + +TEST_F(Rdata_SSHFP_Test, getAlgorithmNumber) { + EXPECT_EQ(2, rdata_sshfp.getAlgorithmNumber()); +} + +TEST_F(Rdata_SSHFP_Test, getFingerprintType) { + EXPECT_EQ(1, rdata_sshfp.getFingerprintType()); +} + +TEST_F(Rdata_SSHFP_Test, getFingerprint) { + const std::vector<uint8_t>& fingerprint = + rdata_sshfp.getFingerprint(); + + EXPECT_EQ(rdata_sshfp.getFingerprintLength(), + fingerprint.size()); + for (size_t i = 0; i < fingerprint.size(); ++i) { + EXPECT_EQ(rdata_sshfp_wiredata[i + 2], + fingerprint.at(i)); + } +} + +TEST_F(Rdata_SSHFP_Test, getFingerprintLength) { + EXPECT_EQ(20, rdata_sshfp.getFingerprintLength()); +} + +TEST_F(Rdata_SSHFP_Test, emptyFingerprintFromWire) { + const uint8_t rdf_wiredata[] = { + // algorithm + 0x04, + // fingerprint type + 0x09 + }; + + const generic::SSHFP rdf = + dynamic_cast<const generic::SSHFP&> + (*rdataFactoryFromFile(RRType("SSHFP"), RRClass("IN"), + "rdata_sshfp_fromWire12")); + + EXPECT_EQ(4, rdf.getAlgorithmNumber()); + EXPECT_EQ(9, rdf.getFingerprintType()); + EXPECT_EQ(0, rdf.getFingerprintLength()); + + this->obuffer.clear(); + rdf.toWire(this->obuffer); + + EXPECT_EQ(2, this->obuffer.getLength()); + + matchWireData(rdf_wiredata, sizeof(rdf_wiredata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_SSHFP_Test, emptyFingerprintFromString) { + const generic::SSHFP rdata_sshfp2("5 6"); + const uint8_t rdata_sshfp2_wiredata[] = { + // algorithm + 0x05, + // fingerprint type + 0x06 + }; + + EXPECT_EQ(5, rdata_sshfp2.getAlgorithmNumber()); + EXPECT_EQ(6, rdata_sshfp2.getFingerprintType()); + EXPECT_EQ(0, rdata_sshfp2.getFingerprintLength()); + + this->obuffer.clear(); + rdata_sshfp2.toWire(this->obuffer); + + EXPECT_EQ(2, this->obuffer.getLength()); + + matchWireData(rdata_sshfp2_wiredata, sizeof(rdata_sshfp2_wiredata), + obuffer.getData(), obuffer.getLength()); +} +} diff --git a/src/lib/dns/tests/rdata_tkey_unittest.cc b/src/lib/dns/tests/rdata_tkey_unittest.cc new file mode 100644 index 0000000..8592a27 --- /dev/null +++ b/src/lib/dns/tests/rdata_tkey_unittest.cc @@ -0,0 +1,450 @@ +// Copyright (C) 2021 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <util/time_utilities.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> +#include <dns/tsigerror.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { + +class Rdata_TKEY_Test : public RdataTest { +protected: + Rdata_TKEY_Test() : + // no Key or Other Data + valid_text1("gss-tsig. 20210501120000 20210501130000 GSS-API NOERROR 0 0"), + // Key but no Other Data + valid_text2("GSS-TSIG. 20210501120000 20210501130000 GSS-API BADSIG " + "12 FAKEFAKEFAKEFAKE 0"), + // Key and Other Data + valid_text3("gss.tsig. 20210501120000 20210501130000 GSS-API BADSIG " + "12 FAKEFAKEFAKEFAKE 6 FAKEFAKE"), + // Key and Other Data (with Error that doesn't expect Other Data) + valid_text4("gss.tsig. 20210501120000 20210501130000 3 BADSIG 12 " + "FAKEFAKEFAKEFAKE 6 FAKEFAKE"), + // numeric error code + valid_text5("GSS-TSIG. 20210501120000 20210501130000 GSS-API 2845 12 " + "FAKEFAKEFAKEFAKE 0"), + // GSS-API mode + valid_text6("gss-tsig. 20210501120000 20210501130000 GSS-API 0 12 " + "FAKEFAKEFAKEFAKE 0"), + rdata_tkey(valid_text1) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<generic::TKEY, isc::Exception, isc::Exception>( + rdata_str, rdata_tkey, false, false); + } + + void checkFromText_InvalidTime(const string& rdata_str) { + checkFromText<generic::TKEY, InvalidTime, InvalidTime>( + rdata_str, rdata_tkey, true, true); + } + + void checkFromText_InvalidText(const string& rdata_str) { + checkFromText<generic::TKEY, InvalidRdataText, InvalidRdataText>( + rdata_str, rdata_tkey, true, true); + } + + void checkFromText_BadValue(const string& rdata_str) { + checkFromText<generic::TKEY, BadValue, BadValue>( + rdata_str, rdata_tkey, true, true); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::TKEY, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_tkey, true, true); + } + + void checkFromText_TooLongLabel(const string& rdata_str) { + checkFromText<generic::TKEY, TooLongLabel, TooLongLabel>( + rdata_str, rdata_tkey, true, true); + } + + void checkFromText_EmptyLabel(const string& rdata_str) { + checkFromText<generic::TKEY, EmptyLabel, EmptyLabel>( + rdata_str, rdata_tkey, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText + <generic::TKEY, InvalidRdataText, isc::Exception>( + rdata_str, rdata_tkey, true, false); + } + + template <typename Output> + void toWireCommonChecks(Output& output) const; + + const string valid_text1; + const string valid_text2; + const string valid_text3; + const string valid_text4; + const string valid_text5; + const string valid_text6; + vector<uint8_t> expect_data; + const generic::TKEY rdata_tkey; // commonly used test RDATA +}; + +TEST_F(Rdata_TKEY_Test, fromText) { + // normal case. it also tests getter methods. + EXPECT_EQ(Name("gss-tsig"), rdata_tkey.getAlgorithm()); + EXPECT_EQ(1619870400, rdata_tkey.getInception()); + EXPECT_EQ("20210501120000", rdata_tkey.getInceptionDate()); + EXPECT_EQ(1619874000, rdata_tkey.getExpire()); + EXPECT_EQ("20210501130000", rdata_tkey.getExpireDate()); + EXPECT_EQ(3, rdata_tkey.getMode()); + EXPECT_EQ(0, rdata_tkey.getError()); + EXPECT_EQ(0, rdata_tkey.getKeyLen()); + EXPECT_EQ(static_cast<void*>(0), rdata_tkey.getKey()); + EXPECT_EQ(0, rdata_tkey.getOtherLen()); + EXPECT_EQ(static_cast<void*>(0), rdata_tkey.getOtherData()); + + generic::TKEY tkey2(valid_text2); + EXPECT_EQ(12, tkey2.getKeyLen()); + EXPECT_EQ(TSIGError::BAD_SIG_CODE, tkey2.getError()); + + generic::TKEY tkey3(valid_text3); + EXPECT_EQ(6, tkey3.getOtherLen()); + + // The other data is unusual, but we don't reject it. + EXPECT_NO_THROW(generic::TKEY tkey4(valid_text4)); + + // numeric representation of TKEY error + generic::TKEY tkey5(valid_text5); + EXPECT_EQ(2845, tkey5.getError()); + + // symbolic representation of TKEY mode + generic::TKEY tkey6(valid_text6); + EXPECT_EQ(generic::TKEY::GSS_API_MODE, tkey6.getMode()); + + // not fully qualified algorithm name + generic::TKEY tkey1("gss-tsig 20210501120000 20210501130000 3 0 0 0"); + EXPECT_EQ(0, tkey1.compare(rdata_tkey)); + + // multi-line rdata + checkFromText_None("gss-tsig. ( 20210501120000 20210501130000 GSS-API \n" + "NOERROR 0 0 )"); +}; + +TEST_F(Rdata_TKEY_Test, badText) { + // too many fields + checkFromText_BadString(valid_text1 + " 0 0"); + // not enough fields + checkFromText_LexerError("foo 20210501120000 20210501130000 0 BADKEY"); + // bad domain name + checkFromText_TooLongLabel( + "0123456789012345678901234567890123456789012345678901234567890123" + " 20210501120000 20210501130000 0 0 0 0"); + checkFromText_EmptyLabel("foo..bar 20210501120000 20210501130000 0 0 0 0"); + // invalid inception (no digit) + checkFromText_InvalidTime("foo TIME 20210501130000 0 0 0 0"); + // invalid inception (bad format) + checkFromText_InvalidTime("foo 0 20210501130000 0 0 0 0"); + // invalid expire (no digit) + checkFromText_InvalidTime("foo 20210501120000 TIME 0 0 0 0"); + // invalid expire (bad format) + checkFromText_InvalidTime("foo 20210501120000 0 0 0 0 0"); + // Unknown mode + checkFromText_InvalidText("foo 20210501120000 20210501130000 TEST 0 0 0"); + // Numeric mode is is too large + checkFromText_InvalidText("foo 20210501120000 20210501130000 65536 0 0 0"); + // Numeric mode is negative + checkFromText_InvalidText("foo 20210501120000 20210501130000 -1 0 0 0 0"); + // Unknown error code + checkFromText_InvalidText("foo 20210501120000 20210501130000 0 TEST 0 0"); + // Numeric error code is too large + checkFromText_InvalidText("foo 20210501120000 20210501130000 0 65536 0 0"); + // Numeric error code is negative + checkFromText_InvalidText("foo 20210501120000 20210501130000 0 -1 0 0"); + // Key len is too large + checkFromText_InvalidText("foo 20210501120000 20210501130000 0 0 65536 0"); + // invalid Key len (negative) + checkFromText_LexerError("foo 20210501120000 20210501130000 0 0 -1 0"); + // invalid Key len (not a number) + checkFromText_LexerError("foo 20210501120000 20210501130000 0 0 MACSIZE 0"); + // Key len and Key mismatch + checkFromText_InvalidText("foo 20210501120000 20210501130000 0 0 9 FAKE 0"); + // Key is bad base64 + checkFromText_BadValue("foo 20210501120000 20210501130000 0 0 3 FAK= 0"); + // Other len is too large + checkFromText_InvalidText("foo 20210501120000 20210501130000 0 0 0 65536 FAKE"); + // Other len is negative + checkFromText_LexerError("foo 20210501120000 20210501130000 0 0 0 -1 FAKE"); + // invalid Other len + checkFromText_LexerError("foo 20210501120000 20210501130000 0 0 0 LEN FAKE"); + // Other len and data mismatch + checkFromText_InvalidText("foo 20210501120000 20210501130000 0 0 0 9 FAKE"); +} + +void +fromWireCommonChecks(const generic::TKEY& tkey) { + EXPECT_EQ(Name("gss-tsig"), tkey.getAlgorithm()); + EXPECT_EQ(1619870400, tkey.getInception()); + EXPECT_EQ("20210501120000", tkey.getInceptionDate()); + EXPECT_EQ(1619874000, tkey.getExpire()); + EXPECT_EQ("20210501130000", tkey.getExpireDate()); + EXPECT_EQ(3, tkey.getMode()); + EXPECT_EQ(0, tkey.getError()); + + vector<uint8_t> expect_key(32, 'x'); + matchWireData(&expect_key[0], expect_key.size(), + tkey.getKey(), tkey.getKeyLen()); + + EXPECT_EQ(0, tkey.getOtherLen()); + EXPECT_EQ(static_cast<const void*>(0), tkey.getOtherData()); +} + +TEST_F(Rdata_TKEY_Test, createFromWire) { + RdataPtr rdata(rdataFactoryFromFile(RRType::TKEY(), RRClass::ANY(), + "rdata_tkey_fromWire1.wire")); + fromWireCommonChecks(dynamic_cast<generic::TKEY&>(*rdata)); +} + +TEST_F(Rdata_TKEY_Test, createFromWireWithOtherData) { + RdataPtr rdata(rdataFactoryFromFile(RRType::TKEY(), RRClass::ANY(), + "rdata_tkey_fromWire2.wire")); + const generic::TKEY& tkey(dynamic_cast<generic::TKEY&>(*rdata)); + + vector<uint8_t> expect_key(32, 'x'); + matchWireData(&expect_key[0], expect_key.size(), + tkey.getKey(), tkey.getKeyLen()); + + vector<uint8_t> expect_data = { 'a', 'b', 'c', 'd', '0', '1', '2', '3' }; + matchWireData(&expect_data[0], expect_data.size(), + tkey.getOtherData(), tkey.getOtherLen()); +} + +TEST_F(Rdata_TKEY_Test, createFromWireWithoutKey) { + RdataPtr rdata(rdataFactoryFromFile(RRType::TKEY(), RRClass::ANY(), + "rdata_tkey_fromWire3.wire")); + const generic::TKEY& tkey(dynamic_cast<generic::TKEY&>(*rdata)); + EXPECT_EQ(0, tkey.getKeyLen()); + EXPECT_EQ(static_cast<const void*>(0), tkey.getKey()); + + vector<uint8_t> expect_data = { 'a', 'b', 'c', 'd', '0', '1', '2', '3' }; + matchWireData(&expect_data[0], expect_data.size(), + tkey.getOtherData(), tkey.getOtherLen()); +} + +TEST_F(Rdata_TKEY_Test, createFromWireWithCompression) { + RdataPtr rdata(rdataFactoryFromFile(RRType::TKEY(), RRClass::ANY(), + "rdata_tkey_fromWire4.wire", + // we need to skip the dummy name: + Name("gss-tsig").getLength())); + fromWireCommonChecks(dynamic_cast<generic::TKEY&>(*rdata)); +} + +TEST_F(Rdata_TKEY_Test, badFromWire) { + // RDLENGTH is too short: + EXPECT_THROW(rdataFactoryFromFile(RRType::TKEY(), RRClass::ANY(), + "rdata_tkey_fromWire5.wire"), + InvalidRdataLength); + // RDLENGTH is too long: + EXPECT_THROW(rdataFactoryFromFile(RRType::TKEY(), RRClass::ANY(), + "rdata_tkey_fromWire6.wire"), + InvalidRdataLength); + // Algorithm name is broken: + EXPECT_THROW(rdataFactoryFromFile(RRType::TKEY(), RRClass::ANY(), + "rdata_tkey_fromWire7.wire"), + DNSMessageFORMERR); + // Key length is bogus: + EXPECT_THROW(rdataFactoryFromFile(RRType::TKEY(), RRClass::ANY(), + "rdata_tkey_fromWire8.wire"), + InvalidBufferPosition); + // Other-data length is bogus: + EXPECT_THROW(rdataFactoryFromFile(RRType::TKEY(), RRClass::ANY(), + "rdata_tkey_fromWire9.wire"), + InvalidBufferPosition); +} + +TEST_F(Rdata_TKEY_Test, copyConstruct) { + const generic::TKEY copy(rdata_tkey); + EXPECT_EQ(0, copy.compare(rdata_tkey)); + + // Check the copied data is valid even after the original is deleted + generic::TKEY* copy2 = new generic::TKEY(rdata_tkey); + generic::TKEY copy3(*copy2); + delete copy2; + EXPECT_EQ(0, copy3.compare(rdata_tkey)); +} + +TEST_F(Rdata_TKEY_Test, createFromParams) { + EXPECT_EQ(0, rdata_tkey.compare(generic::TKEY(Name("gss-tsig"), + 1619870400, + 1619874000, + 3, 0, 0, 0, 0, 0))); + + const uint8_t fake_data[] = { 0x14, 0x02, 0x84, 0x14, 0x02, 0x84, + 0x14, 0x02, 0x84, 0x14, 0x02, 0x84 }; + EXPECT_EQ(0, generic::TKEY(valid_text2).compare( + generic::TKEY(Name("GSS-TSIG"), 1619870400, 1619874000, + 3, 16, 12, fake_data, 0, 0))); + + const uint8_t fake_data2[] = { 0x14, 0x02, 0x84, 0x14, 0x02, 0x84 }; + EXPECT_EQ(0, generic::TKEY(valid_text3).compare( + generic::TKEY(Name("gss.tsig"), 1619870400, 1619874000, + 3, 16, 12, fake_data, 6, fake_data2))); + + EXPECT_THROW(generic::TKEY(Name("gss-tsig"), 0, 0, 0, 0, 0, fake_data, 0, 0), + isc::InvalidParameter); + EXPECT_THROW(generic::TKEY(Name("gss-tsig"), 0, 0, 0, 0, 12, 0, 0, 0), + isc::InvalidParameter); + EXPECT_THROW(generic::TKEY(Name("gss-tsig"), 0, 0, 0, 0, 0, 0, 0, fake_data), + isc::InvalidParameter); + EXPECT_THROW(generic::TKEY(Name("fake_data"), 0, 0, 0, 0, 0, 0, 6, 0), + isc::InvalidParameter); +} + +TEST_F(Rdata_TKEY_Test, assignment) { + generic::TKEY copy(valid_text2); + copy = rdata_tkey; + EXPECT_EQ(0, copy.compare(rdata_tkey)); + + // Check if the copied data is valid even after the original is deleted + generic::TKEY* copy2 = new generic::TKEY(rdata_tkey); + generic::TKEY copy3(valid_text2); + copy3 = *copy2; + delete copy2; + EXPECT_EQ(0, copy3.compare(rdata_tkey)); + + // Self assignment + copy = *© + EXPECT_EQ(0, copy.compare(rdata_tkey)); +} + +template <typename Output> +void +Rdata_TKEY_Test::toWireCommonChecks(Output& output) const { + vector<uint8_t> expect_data; + + output.clear(); + expect_data.clear(); + rdata_tkey.toWire(output); + // read the expected wire format data and trim the RDLEN part. + UnitTestUtil::readWireData("rdata_tkey_toWire1.wire", expect_data); + expect_data.erase(expect_data.begin(), expect_data.begin() + 2); + matchWireData(&expect_data[0], expect_data.size(), + output.getData(), output.getLength()); + + expect_data.clear(); + output.clear(); + generic::TKEY(valid_text2).toWire(output); + UnitTestUtil::readWireData("rdata_tkey_toWire2.wire", expect_data); + expect_data.erase(expect_data.begin(), expect_data.begin() + 2); + matchWireData(&expect_data[0], expect_data.size(), + output.getData(), output.getLength()); + + expect_data.clear(); + output.clear(); + generic::TKEY(valid_text3).toWire(output); + UnitTestUtil::readWireData("rdata_tkey_toWire3.wire", expect_data); + expect_data.erase(expect_data.begin(), expect_data.begin() + 2); + matchWireData(&expect_data[0], expect_data.size(), + output.getData(), output.getLength()); +} + +TEST_F(Rdata_TKEY_Test, toWireBuffer) { + toWireCommonChecks<OutputBuffer>(obuffer); +} + +TEST_F(Rdata_TKEY_Test, toWireRenderer) { + toWireCommonChecks<MessageRenderer>(renderer); + + // check algorithm name won't compressed when it would otherwise. + expect_data.clear(); + renderer.clear(); + renderer.writeName(Name("gss-tsig")); + renderer.writeUint16(26); // RDLEN + rdata_tkey.toWire(renderer); + UnitTestUtil::readWireData("rdata_tkey_toWire4.wire", expect_data); + matchWireData(&expect_data[0], expect_data.size(), + renderer.getData(), renderer.getLength()); + + // check algorithm can be used as a compression target. + expect_data.clear(); + renderer.clear(); + renderer.writeUint16(26); + rdata_tkey.toWire(renderer); + renderer.writeName(Name("gss-tsig")); + UnitTestUtil::readWireData("rdata_tkey_toWire5.wire", expect_data); + matchWireData(&expect_data[0], expect_data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_TKEY_Test, toText) { + EXPECT_EQ(valid_text1, rdata_tkey.toText()); + EXPECT_EQ(valid_text2, generic::TKEY(valid_text2).toText()); + EXPECT_EQ(valid_text3, generic::TKEY(valid_text3).toText()); + EXPECT_EQ(valid_text5, generic::TKEY(valid_text5).toText()); +} + +TEST_F(Rdata_TKEY_Test, compare) { + // test RDATAs, sorted in the ascending order. + // "AAAA" encoded in BASE64 corresponds to 0x000000, so it should be the + // smallest data of the same length. + vector<generic::TKEY> compare_set; + compare_set.push_back(generic::TKEY("a.example 20210501120000 " + "20210501130000 3 0 0 0")); + compare_set.push_back(generic::TKEY("example 20210501120000 " + "20210501130000 3 0 0 0")); + compare_set.push_back(generic::TKEY("example 20210501120001 " + "20210501130000 3 0 0 0")); + compare_set.push_back(generic::TKEY("example 20210501120001 " + "20210501130001 3 0 0 0")); + compare_set.push_back(generic::TKEY("example 20210501120001 " + "20210501130001 4 0 0 0")); + compare_set.push_back(generic::TKEY("example 20210501120001 " + "20210501130001 4 1 0 0")); + compare_set.push_back(generic::TKEY("example 20210501120001 " + "20210501130001 4 1 3 AAAA 0")); + compare_set.push_back(generic::TKEY("example 20210501120001 " + "20210501130001 4 1 3 FAKE 0")); + compare_set.push_back(generic::TKEY("example 20210501120001 " + "20210501130001 4 1 3 FAKE 3 AAAA")); + compare_set.push_back(generic::TKEY("example 20210501120001 " + "20210501130001 4 1 3 FAKE 3 FAKE")); + + EXPECT_EQ(0, + compare_set[0].compare(generic::TKEY("A.EXAMPLE 20210501120000 " + "20210501130000 3 0 0 0"))); + + vector<generic::TKEY>::const_iterator it; + vector<generic::TKEY>::const_iterator it_end = compare_set.end(); + for (it = compare_set.begin(); it != it_end - 1; ++it) { + EXPECT_GT(0, (*it).compare(*(it + 1))); + EXPECT_LT(0, (*(it + 1)).compare(*it)); + } + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(rdata_tkey.compare(*RdataTest::rdata_nomatch), bad_cast); +} +} diff --git a/src/lib/dns/tests/rdata_tlsa_unittest.cc b/src/lib/dns/tests/rdata_tlsa_unittest.cc new file mode 100644 index 0000000..92970cb --- /dev/null +++ b/src/lib/dns/tests/rdata_tlsa_unittest.cc @@ -0,0 +1,276 @@ +// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <algorithm> +#include <string> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +#include <boost/algorithm/string.hpp> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class Rdata_TLSA_Test : public RdataTest { +protected: + Rdata_TLSA_Test() : + tlsa_txt("0 0 1 d2abde240d7cd3ee6b4b28c54df034b9" + "7983a1d16e8a410e4561cb106618e971"), + rdata_tlsa(tlsa_txt) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<generic::TLSA, isc::Exception, isc::Exception>( + rdata_str, rdata_tlsa, false, false); + } + + void checkFromText_InvalidText(const string& rdata_str) { + checkFromText<generic::TLSA, InvalidRdataText, InvalidRdataText>( + rdata_str, rdata_tlsa, true, true); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <generic::TLSA, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_tlsa, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText + <generic::TLSA, InvalidRdataText, isc::Exception>( + rdata_str, rdata_tlsa, true, false); + } + + const string tlsa_txt; + const generic::TLSA rdata_tlsa; +}; + +const uint8_t rdata_tlsa_wiredata[] = { + // certificate usage + 0x00, + // selector + 0x00, + // matching type + 0x01, + // certificate association data + 0xd2, 0xab, 0xde, 0x24, 0x0d, 0x7c, 0xd3, 0xee, + 0x6b, 0x4b, 0x28, 0xc5, 0x4d, 0xf0, 0x34, 0xb9, + 0x79, 0x83, 0xa1, 0xd1, 0x6e, 0x8a, 0x41, 0x0e, + 0x45, 0x61, 0xcb, 0x10, 0x66, 0x18, 0xe9, 0x71 +}; + +TEST_F(Rdata_TLSA_Test, createFromText) { + // Basic test + checkFromText_None(tlsa_txt); + + // With different spacing + checkFromText_None("0 0 1 d2abde240d7cd3ee6b4b28c54df034b9" + "7983a1d16e8a410e4561cb106618e971"); + + // Combination of lowercase and uppercase + checkFromText_None("0 0 1 D2ABDE240D7CD3EE6B4B28C54DF034B9" + "7983a1d16e8a410e4561cb106618e971"); + + // spacing in the certificate association data field + checkFromText_None("0 0 1 d2abde240d7cd3ee6b4b28c54df034b9" + " 7983a1d16e8a410e4561cb106618e971"); + + // multi-line certificate association data field + checkFromText_None("0 0 1 ( d2abde240d7cd3ee6b4b28c54df034b9\n" + " 7983a1d16e8a410e4561cb106618e971 )"); + + // string constructor throws if there's extra text, + // but lexer constructor doesn't + checkFromText_BadString(tlsa_txt + "\n" + tlsa_txt); +} + +TEST_F(Rdata_TLSA_Test, fields) { + // Some of these may not be RFC conformant, but we relax the check + // in our code to work with other field values that may show up in + // the future. + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("1 0 1 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("2 0 1 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("3 0 1 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("128 0 1 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("255 0 1 12ab")); + + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 1 1 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 2 1 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 3 1 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 128 1 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 255 1 12ab")); + + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 0 1 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 0 2 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 0 3 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 0 128 12ab")); + EXPECT_NO_THROW(const generic::TLSA rdata_tlsa("0 0 255 12ab")); + + // > 255 would be broken + EXPECT_THROW(const generic::TLSA rdata_tlsa("256 0 1 12ab"), + InvalidRdataText); + EXPECT_THROW(const generic::TLSA rdata_tlsa("0 256 1 12ab"), + InvalidRdataText); + EXPECT_THROW(const generic::TLSA rdata_tlsa("0 0 256 12ab"), + InvalidRdataText); +} + +TEST_F(Rdata_TLSA_Test, badText) { + checkFromText_LexerError("1"); + checkFromText_LexerError("ONE 2 3 123456789abcdef67890123456789abcdef67890"); + checkFromText_LexerError("1 TWO 3 123456789abcdef67890123456789abcdef67890"); + checkFromText_LexerError("1 2 THREE 123456789abcdef67890123456789abcdef67890"); + checkFromText_InvalidText("1 2 3 BAABAABLACKSHEEP"); + checkFromText_InvalidText(tlsa_txt + " extra text"); + + // yes, these are redundant to the last test cases in the .fields + // test + checkFromText_InvalidText( + "2345 1 2 123456789abcdef67890123456789abcdef67890"); + checkFromText_InvalidText( + "3 1234 4 123456789abcdef67890123456789abcdef67890"); + checkFromText_InvalidText( + "5 6 1234 123456789abcdef67890123456789abcdef67890"); + + // negative values are trapped in the lexer rather than the + // constructor + checkFromText_LexerError("-2 0 1 123456789abcdef67890123456789abcdef67890"); + checkFromText_LexerError("0 -2 1 123456789abcdef67890123456789abcdef67890"); + checkFromText_LexerError("0 0 -2 123456789abcdef67890123456789abcdef67890"); +} + +TEST_F(Rdata_TLSA_Test, copyAndAssign) { + // Copy construct + generic::TLSA rdata_tlsa2(rdata_tlsa); + EXPECT_EQ(0, rdata_tlsa.compare(rdata_tlsa2)); + + // Assignment, mainly to confirm it doesn't cause disruption. + rdata_tlsa2 = rdata_tlsa; + EXPECT_EQ(0, rdata_tlsa.compare(rdata_tlsa2)); +} + +TEST_F(Rdata_TLSA_Test, createFromWire) { + // Basic test + EXPECT_EQ(0, rdata_tlsa.compare( + *rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire"))); + // Combination of lowercase and uppercase + EXPECT_EQ(0, rdata_tlsa.compare( + *rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire2"))); + // certificate_usage=0, selector=0, matching_type=1 + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire3.wire")); + + // certificate_usage=255, selector=0, matching_type=1 + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire4.wire")); + + // certificate_usage=0, selector=255, matching_type=1 + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire5.wire")); + + // certificate_usage=0, selector=0, matching_type=255 + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire6.wire")); + + // certificate_usage=3, selector=1, matching_type=2 + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire7.wire")); + + // short certificate association data + EXPECT_NO_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire8.wire")); + + // certificate association data is shorter than rdata len + EXPECT_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire9"), + InvalidBufferPosition); + + // certificate association data is missing + EXPECT_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire10"), + InvalidBufferPosition); + + // certificate association data is empty + EXPECT_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire12"), + InvalidRdataLength); + + // all RDATA is missing + EXPECT_THROW(rdataFactoryFromFile(RRType("TLSA"), RRClass("IN"), + "rdata_tlsa_fromWire11"), + InvalidBufferPosition); +} + +TEST_F(Rdata_TLSA_Test, createFromParams) { + const generic::TLSA rdata_tlsa2( + 0, 0, 1, "d2abde240d7cd3ee6b4b28c54df034b9" + "7983a1d16e8a410e4561cb106618e971"); + EXPECT_EQ(0, rdata_tlsa2.compare(rdata_tlsa)); + + // empty certificate association data should throw + EXPECT_THROW(const generic::TLSA rdata_tlsa2(0, 0, 1, ""), + InvalidRdataText); +} + +TEST_F(Rdata_TLSA_Test, toText) { + EXPECT_TRUE(boost::iequals(tlsa_txt, rdata_tlsa.toText())); +} + +TEST_F(Rdata_TLSA_Test, toWire) { + this->obuffer.clear(); + rdata_tlsa.toWire(this->obuffer); + + EXPECT_EQ(sizeof (rdata_tlsa_wiredata), + this->obuffer.getLength()); + + matchWireData(rdata_tlsa_wiredata, sizeof(rdata_tlsa_wiredata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_TLSA_Test, compare) { + const generic::TLSA rdata_tlsa2("0 0 0 d2abde240d7cd3ee6b4b28c54df034b9" + "7983a1d16e8a410e4561cb106618e971"); + EXPECT_EQ(-1, rdata_tlsa2.compare(rdata_tlsa)); + EXPECT_EQ(1, rdata_tlsa.compare(rdata_tlsa2)); +} + +TEST_F(Rdata_TLSA_Test, getCertificateUsage) { + EXPECT_EQ(0, rdata_tlsa.getCertificateUsage()); +} + +TEST_F(Rdata_TLSA_Test, getSelector) { + EXPECT_EQ(0, rdata_tlsa.getSelector()); +} + +TEST_F(Rdata_TLSA_Test, getMatchingType) { + EXPECT_EQ(1, rdata_tlsa.getMatchingType()); +} + +TEST_F(Rdata_TLSA_Test, getDataLength) { + EXPECT_EQ(32, rdata_tlsa.getDataLength()); +} +} diff --git a/src/lib/dns/tests/rdata_tsig_unittest.cc b/src/lib/dns/tests/rdata_tsig_unittest.cc new file mode 100644 index 0000000..9d3bd89 --- /dev/null +++ b/src/lib/dns/tests/rdata_tsig_unittest.cc @@ -0,0 +1,423 @@ +// Copyright (C) 2010-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> +#include <dns/tsigerror.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using namespace isc::dns::rdata::any; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { + +class Rdata_TSIG_Test : public RdataTest { +protected: + Rdata_TSIG_Test() : + // no MAC or Other Data + valid_text1("hmac-md5.sig-alg.reg.int. 1286779327 300 " + "0 16020 BADKEY 0"), + // MAC but no Other Data + valid_text2("hmac-sha256. 1286779327 300 12 " + "FAKEFAKEFAKEFAKE 16020 BADSIG 0"), + // MAC and Other Data + valid_text3("hmac-sha1. 1286779327 300 12 " + "FAKEFAKEFAKEFAKE 16020 BADTIME 6 FAKEFAKE"), + // MAC and Other Data (with Error that doesn't expect Other Data) + valid_text4("hmac-sha1. 1286779327 300 12 " + "FAKEFAKEFAKEFAKE 16020 BADSIG 6 FAKEFAKE"), + // numeric error code + valid_text5("hmac-sha256. 1286779327 300 12 " + "FAKEFAKEFAKEFAKE 16020 2845 0"), + rdata_tsig(valid_text1) + {} + + void checkFromText_None(const string& rdata_str) { + checkFromText<TSIG, isc::Exception, isc::Exception>( + rdata_str, rdata_tsig, false, false); + } + + void checkFromText_InvalidText(const string& rdata_str) { + checkFromText<TSIG, InvalidRdataText, InvalidRdataText>( + rdata_str, rdata_tsig, true, true); + } + + void checkFromText_BadValue(const string& rdata_str) { + checkFromText<TSIG, BadValue, BadValue>( + rdata_str, rdata_tsig, true, true); + } + + void checkFromText_LexerError(const string& rdata_str) { + checkFromText + <TSIG, InvalidRdataText, MasterLexer::LexerError>( + rdata_str, rdata_tsig, true, true); + } + + void checkFromText_TooLongLabel(const string& rdata_str) { + checkFromText<TSIG, TooLongLabel, TooLongLabel>( + rdata_str, rdata_tsig, true, true); + } + + void checkFromText_EmptyLabel(const string& rdata_str) { + checkFromText<TSIG, EmptyLabel, EmptyLabel>( + rdata_str, rdata_tsig, true, true); + } + + void checkFromText_BadString(const string& rdata_str) { + checkFromText + <TSIG, InvalidRdataText, isc::Exception>( + rdata_str, rdata_tsig, true, false); + } + + template <typename Output> + void toWireCommonChecks(Output& output) const; + + const string valid_text1; + const string valid_text2; + const string valid_text3; + const string valid_text4; + const string valid_text5; + vector<uint8_t> expect_data; + const TSIG rdata_tsig; // commonly used test RDATA +}; + +TEST_F(Rdata_TSIG_Test, fromText) { + // normal case. it also tests getter methods. + EXPECT_EQ(Name("hmac-md5.sig-alg.reg.int"), rdata_tsig.getAlgorithm()); + EXPECT_EQ(1286779327, rdata_tsig.getTimeSigned()); + EXPECT_EQ(300, rdata_tsig.getFudge()); + EXPECT_EQ(0, rdata_tsig.getMACSize()); + EXPECT_EQ(static_cast<void*>(NULL), rdata_tsig.getMAC()); + EXPECT_EQ(16020, rdata_tsig.getOriginalID()); + EXPECT_EQ(TSIGError::BAD_KEY_CODE, rdata_tsig.getError()); + EXPECT_EQ(0, rdata_tsig.getOtherLen()); + EXPECT_EQ(static_cast<void*>(NULL), rdata_tsig.getOtherData()); + + TSIG tsig2(valid_text2); + EXPECT_EQ(12, tsig2.getMACSize()); + EXPECT_EQ(TSIGError::BAD_SIG_CODE, tsig2.getError()); + + TSIG tsig3(valid_text3); + EXPECT_EQ(6, tsig3.getOtherLen()); + + // The other data is unusual, but we don't reject it. + EXPECT_NO_THROW(TSIG tsig4(valid_text4)); + + // numeric representation of TSIG error + TSIG tsig5(valid_text5); + EXPECT_EQ(2845, tsig5.getError()); + + // not fully qualified algorithm name + TSIG tsig1("hmac-md5.sig-alg.reg.int 1286779327 300 0 16020 BADKEY 0"); + EXPECT_EQ(0, tsig1.compare(rdata_tsig)); + + // multi-line rdata + checkFromText_None("hmac-md5.sig-alg.reg.int. ( 1286779327 300 \n" + "0 16020 BADKEY 0 )"); + + // short-form HMAC-MD5 name + const TSIG tsig6("hmac-md5. 1286779327 300 0 16020 BADKEY 0"); + EXPECT_EQ(0, tsig6.compare(rdata_tsig)); +}; + +TEST_F(Rdata_TSIG_Test, badText) { + // too many fields + checkFromText_BadString(valid_text1 + " 0 0"); + // not enough fields + checkFromText_LexerError("foo 0 0 0 0 BADKEY"); + // bad domain name + checkFromText_TooLongLabel( + "0123456789012345678901234567890123456789012345678901234567890123" + " 0 0 0 0 BADKEY 0"); + checkFromText_EmptyLabel("foo..bar 0 0 0 0 BADKEY"); + // time is too large (2814...6 is 2^48) + checkFromText_InvalidText("foo 281474976710656 0 0 0 BADKEY 0"); + // invalid time (negative) + checkFromText_InvalidText("foo -1 0 0 0 BADKEY 0"); + // invalid time (not a number) + checkFromText_InvalidText("foo TIME 0 0 0 BADKEY 0"); + // fudge is too large + checkFromText_InvalidText("foo 0 65536 0 0 BADKEY 0"); + // invalid fudge (negative) + checkFromText_LexerError("foo 0 -1 0 0 BADKEY 0"); + // invalid fudge (not a number) + checkFromText_LexerError("foo 0 FUDGE 0 0 BADKEY 0"); + // MAC size is too large + checkFromText_InvalidText("foo 0 0 65536 0 BADKEY 0"); + // invalid MAC size (negative) + checkFromText_LexerError("foo 0 0 -1 0 BADKEY 0"); + // invalid MAC size (not a number) + checkFromText_LexerError("foo 0 0 MACSIZE 0 BADKEY 0"); + // MAC size and MAC mismatch + checkFromText_InvalidText("foo 0 0 9 FAKE 0 BADKEY 0"); + // MAC is bad base64 + checkFromText_BadValue("foo 0 0 3 FAK= 0 BADKEY 0"); + // Unknown error code + checkFromText_InvalidText("foo 0 0 0 0 TEST 0"); + // Numeric error code is too large + checkFromText_InvalidText("foo 0 0 0 0 65536 0"); + // Numeric error code is negative + checkFromText_InvalidText("foo 0 0 0 0 -1 0"); + // Other len is too large + checkFromText_InvalidText("foo 0 0 0 0 NOERROR 65536 FAKE"); + // Other len is negative + checkFromText_LexerError("foo 0 0 0 0 NOERROR -1 FAKE"); + // invalid Other len + checkFromText_LexerError("foo 0 0 0 0 NOERROR LEN FAKE"); + // Other len and data mismatch + checkFromText_InvalidText("foo 0 0 0 0 NOERROR 9 FAKE"); +} + +void +fromWireCommonChecks(const TSIG& tsig) { + EXPECT_EQ(Name("hmac-sha256"), tsig.getAlgorithm()); + EXPECT_EQ(1286978795, tsig.getTimeSigned()); + EXPECT_EQ(300, tsig.getFudge()); + + vector<uint8_t> expect_mac(32, 'x'); + matchWireData(&expect_mac[0], expect_mac.size(), + tsig.getMAC(), tsig.getMACSize()); + + EXPECT_EQ(2845, tsig.getOriginalID()); + + EXPECT_EQ(0, tsig.getOtherLen()); + EXPECT_EQ(static_cast<const void*>(NULL), tsig.getOtherData()); +} + +TEST_F(Rdata_TSIG_Test, createFromWire) { + RdataPtr rdata(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(), + "rdata_tsig_fromWire1.wire")); + fromWireCommonChecks(dynamic_cast<TSIG&>(*rdata)); +} + +TEST_F(Rdata_TSIG_Test, createFromWireWithOtherData) { + RdataPtr rdata(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(), + "rdata_tsig_fromWire2.wire")); + const TSIG& tsig(dynamic_cast<TSIG&>(*rdata)); + + EXPECT_EQ(18, tsig.getError()); + const uint64_t otherdata = 1286978795 + 300 + 1; // time-signed + fudge + 1 + expect_data.resize(6); + expect_data[0] = (otherdata >> 40); + expect_data[1] = ((otherdata >> 32) & 0xff); + expect_data[2] = ((otherdata >> 24) & 0xff); + expect_data[3] = ((otherdata >> 16) & 0xff); + expect_data[4] = ((otherdata >> 8) & 0xff); + expect_data[5] = (otherdata & 0xff); + matchWireData(&expect_data[0], expect_data.size(), + tsig.getOtherData(), tsig.getOtherLen()); +} + +TEST_F(Rdata_TSIG_Test, createFromWireWithoutMAC) { + RdataPtr rdata(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(), + "rdata_tsig_fromWire3.wire")); + const TSIG& tsig(dynamic_cast<TSIG&>(*rdata)); + EXPECT_EQ(16, tsig.getError()); + EXPECT_EQ(0, tsig.getMACSize()); + EXPECT_EQ(static_cast<const void*>(NULL), tsig.getMAC()); +} + +TEST_F(Rdata_TSIG_Test, createFromWireWithCompression) { + RdataPtr rdata(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(), + "rdata_tsig_fromWire4.wire", + // we need to skip the dummy name: + Name("hmac-sha256").getLength())); + fromWireCommonChecks(dynamic_cast<TSIG&>(*rdata)); +} + +TEST_F(Rdata_TSIG_Test, badFromWire) { + // RDLENGTH is too short: + EXPECT_THROW(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(), + "rdata_tsig_fromWire5.wire"), + InvalidRdataLength); + // RDLENGTH is too long: + EXPECT_THROW(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(), + "rdata_tsig_fromWire6.wire"), + InvalidRdataLength); + // Algorithm name is broken: + EXPECT_THROW(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(), + "rdata_tsig_fromWire7.wire"), + DNSMessageFORMERR); + // MAC size is bogus: + EXPECT_THROW(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(), + "rdata_tsig_fromWire8.wire"), + InvalidBufferPosition); + // Other-data length is bogus: + EXPECT_THROW(rdataFactoryFromFile(RRType::TSIG(), RRClass::ANY(), + "rdata_tsig_fromWire9.wire"), + InvalidBufferPosition); +} + +TEST_F(Rdata_TSIG_Test, copyConstruct) { + const TSIG copy(rdata_tsig); + EXPECT_EQ(0, copy.compare(rdata_tsig)); + + // Check the copied data is valid even after the original is deleted + TSIG* copy2 = new TSIG(rdata_tsig); + TSIG copy3(*copy2); + delete copy2; + EXPECT_EQ(0, copy3.compare(rdata_tsig)); +} + +TEST_F(Rdata_TSIG_Test, createFromParams) { + EXPECT_EQ(0, rdata_tsig.compare(TSIG(Name("hmac-md5.sig-alg.reg.int"), + 1286779327, 300, 0, NULL, 16020, 17, 0, NULL))); + + const uint8_t fake_data[] = { 0x14, 0x02, 0x84, 0x14, 0x02, 0x84, + 0x14, 0x02, 0x84, 0x14, 0x02, 0x84 }; + EXPECT_EQ(0, TSIG(valid_text2).compare(TSIG(Name("hmac-sha256"), 1286779327, 300, 12, + fake_data, 16020, 16, 0, NULL))); + + const uint8_t fake_data2[] = { 0x14, 0x02, 0x84, 0x14, 0x02, 0x84 }; + EXPECT_EQ(0, TSIG(valid_text3).compare(TSIG(Name("hmac-sha1"), 1286779327, 300, 12, + fake_data, 16020, 18, 6, fake_data2))); + + EXPECT_THROW(TSIG(Name("hmac-sha256"), 1ULL << 48, 300, 12, fake_data, 16020, 18, 6, fake_data2), + isc::OutOfRange); + EXPECT_THROW(TSIG(Name("hmac-sha256"), 0, 300, 0, fake_data, 16020, 18, 0, NULL), + isc::InvalidParameter); + EXPECT_THROW(TSIG(Name("hmac-sha256"), 0, 300, 12, NULL, 16020, 18, 0, NULL), + isc::InvalidParameter); + EXPECT_THROW(TSIG(Name("hmac-sha256"), 0, 300, 0, NULL, 16020, 18, 0, fake_data), + isc::InvalidParameter); + EXPECT_THROW(TSIG(Name("hmac-sha256"), 0, 300, 0, NULL, 16020, 18, 6, NULL), + isc::InvalidParameter); +} + +TEST_F(Rdata_TSIG_Test, assignment) { + TSIG copy(valid_text2); + copy = rdata_tsig; + EXPECT_EQ(0, copy.compare(rdata_tsig)); + + // Check if the copied data is valid even after the original is deleted + TSIG* copy2 = new TSIG(rdata_tsig); + TSIG copy3(valid_text2); + copy3 = *copy2; + delete copy2; + EXPECT_EQ(0, copy3.compare(rdata_tsig)); + + // Self assignment + copy = *© + EXPECT_EQ(0, copy.compare(rdata_tsig)); +} + +template <typename Output> +void +Rdata_TSIG_Test::toWireCommonChecks(Output& output) const { + vector<uint8_t> expect_data; + + output.clear(); + expect_data.clear(); + rdata_tsig.toWire(output); + // read the expected wire format data and trim the RDLEN part. + UnitTestUtil::readWireData("rdata_tsig_toWire1.wire", expect_data); + expect_data.erase(expect_data.begin(), expect_data.begin() + 2); + matchWireData(&expect_data[0], expect_data.size(), + output.getData(), output.getLength()); + + expect_data.clear(); + output.clear(); + TSIG(valid_text2).toWire(output); + UnitTestUtil::readWireData("rdata_tsig_toWire2.wire", expect_data); + expect_data.erase(expect_data.begin(), expect_data.begin() + 2); + matchWireData(&expect_data[0], expect_data.size(), + output.getData(), output.getLength()); + + expect_data.clear(); + output.clear(); + TSIG(valid_text3).toWire(output); + UnitTestUtil::readWireData("rdata_tsig_toWire3.wire", expect_data); + expect_data.erase(expect_data.begin(), expect_data.begin() + 2); + matchWireData(&expect_data[0], expect_data.size(), + output.getData(), output.getLength()); +} + +TEST_F(Rdata_TSIG_Test, toWireBuffer) { + toWireCommonChecks<OutputBuffer>(obuffer); +} + +TEST_F(Rdata_TSIG_Test, toWireRenderer) { + toWireCommonChecks<MessageRenderer>(renderer); + + // check algorithm name won't compressed when it would otherwise. + expect_data.clear(); + renderer.clear(); + renderer.writeName(Name("hmac-md5.sig-alg.reg.int")); + renderer.writeUint16(42); // RDLEN + rdata_tsig.toWire(renderer); + UnitTestUtil::readWireData("rdata_tsig_toWire4.wire", expect_data); + matchWireData(&expect_data[0], expect_data.size(), + renderer.getData(), renderer.getLength()); + + // check algorithm can be used as a compression target. + expect_data.clear(); + renderer.clear(); + renderer.writeUint16(42); + rdata_tsig.toWire(renderer); + renderer.writeName(Name("hmac-md5.sig-alg.reg.int")); + UnitTestUtil::readWireData("rdata_tsig_toWire5.wire", expect_data); + matchWireData(&expect_data[0], expect_data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_TSIG_Test, toText) { + EXPECT_EQ(valid_text1, rdata_tsig.toText()); + EXPECT_EQ(valid_text2, TSIG(valid_text2).toText()); + EXPECT_EQ(valid_text3, TSIG(valid_text3).toText()); + EXPECT_EQ(valid_text5, TSIG(valid_text5).toText()); +} + +TEST_F(Rdata_TSIG_Test, compare) { + // test RDATAs, sorted in the ascending order. + // "AAAA" encoded in BASE64 corresponds to 0x000000, so it should be the + // smallest data of the same length. + vector<TSIG> compare_set; + compare_set.push_back(TSIG("a.example 0 300 0 16020 0 0")); + compare_set.push_back(TSIG("example 0 300 0 16020 0 0")); + compare_set.push_back(TSIG("example 1 300 0 16020 0 0")); + compare_set.push_back(TSIG("example 1 600 0 16020 0 0")); + compare_set.push_back(TSIG("example 1 600 3 AAAA 16020 0 0")); + compare_set.push_back(TSIG("example 1 600 3 FAKE 16020 0 0")); + compare_set.push_back(TSIG("example 1 600 3 FAKE 16021 0 0")); + compare_set.push_back(TSIG("example 1 600 3 FAKE 16021 1 0")); + compare_set.push_back(TSIG("example 1 600 3 FAKE 16021 1 3 AAAA")); + compare_set.push_back(TSIG("example 1 600 3 FAKE 16021 1 3 FAKE")); + + EXPECT_EQ(0, compare_set[0].compare(TSIG("A.EXAMPLE 0 300 0 16020 0 0"))); + + vector<TSIG>::const_iterator it; + vector<TSIG>::const_iterator it_end = compare_set.end(); + for (it = compare_set.begin(); it != it_end - 1; ++it) { + EXPECT_GT(0, (*it).compare(*(it + 1))); + EXPECT_LT(0, (*(it + 1)).compare(*it)); + } + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(rdata_tsig.compare(*RdataTest::rdata_nomatch), bad_cast); +} +} diff --git a/src/lib/dns/tests/rdata_txt_like_unittest.cc b/src/lib/dns/tests/rdata_txt_like_unittest.cc new file mode 100644 index 0000000..e2828c2 --- /dev/null +++ b/src/lib/dns/tests/rdata_txt_like_unittest.cc @@ -0,0 +1,397 @@ +// Copyright (C) 2011-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// This is the common code for TXT and SPF tests. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/exceptions.h> +#include <dns/rdataclass.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> + +#include <util/unittests/wiredata.h> + +#include <gtest/gtest.h> + +#include <string> +#include <sstream> +#include <vector> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { + +template<class T> +class RRTYPE : public RRType { +public: + RRTYPE(); +}; + +template<> RRTYPE<generic::TXT>::RRTYPE() : RRType(RRType::TXT()) {} +template<> RRTYPE<generic::SPF>::RRTYPE() : RRType(RRType::SPF()) {} + +const uint8_t wiredata_txt_like[] = { + sizeof("Test-String") - 1, + 'T', 'e', 's', 't', '-', 'S', 't', 'r', 'i', 'n', 'g' +}; + +const uint8_t wiredata_nulltxt[] = { 0 }; + +template<class TXT_LIKE> +class Rdata_TXT_LIKE_Test : public RdataTest { +protected: + Rdata_TXT_LIKE_Test() : + wiredata_longesttxt(256, 'a'), + rdata_txt_like("Test-String"), + rdata_txt_like_empty("\"\""), + rdata_txt_like_quoted("\"Test-String\"") + { + wiredata_longesttxt[0] = 255; // adjust length + } + +protected: + vector<uint8_t> wiredata_longesttxt; + const TXT_LIKE rdata_txt_like; + const TXT_LIKE rdata_txt_like_empty; + const TXT_LIKE rdata_txt_like_quoted; +}; + +// The list of types we want to test. +typedef testing::Types<generic::TXT, generic::SPF> Implementations; + +#ifdef TYPED_TEST_SUITE +TYPED_TEST_SUITE(Rdata_TXT_LIKE_Test, Implementations); +#else +TYPED_TEST_CASE(Rdata_TXT_LIKE_Test, Implementations); +#endif + +TYPED_TEST(Rdata_TXT_LIKE_Test, createFromText) { + // Below we check the behavior for the "from text" constructors, both + // from std::string and with MasterLexer. The underlying implementation + // is the same, so both should work exactly same, but we confirm both + // cases. + + const std::string multi_line = "(\n \"Test-String\" )"; + const std::string escaped_txt = "Test\\045Strin\\g"; + + // test input for the lexer version + std::stringstream ss; + ss << "Test-String\n"; + ss << "\"Test-String\"\n"; // explicitly surrounded by '"'s + ss << multi_line << "\n"; // multi-line text with () + ss << escaped_txt << "\n"; // using the two types of escape with '\' + ss << "\"\"\n"; // empty string (note: still valid char-str) + ss << string(255, 'a') << "\n"; // Longest possible character-string. + ss << string(256, 'a') << "\n"; // char-string too long + ss << "\"Test-String\\\"\n"; // unbalanced quote + ss << "\"Test-String\\\"\"\n"; + this->lexer.pushSource(ss); + + // commonly used Rdata to compare below, created from wire + ConstRdataPtr const rdata = + this->rdataFactoryFromFile(RRTYPE<TypeParam>(), + RRClass("IN"), "rdata_txt_fromWire1"); + + // normal case is covered in toWireBuffer. First check the std::string + // case, then with MasterLexer. For the latter, we need to read and skip + // '\n'. These apply to most of the other cases below. + EXPECT_EQ(0, this->rdata_txt_like.compare(*rdata)); + EXPECT_EQ(0, TypeParam(this->lexer, NULL, MasterLoader::MANY_ERRORS, + this->loader_cb).compare(*rdata)); + EXPECT_EQ(MasterToken::END_OF_LINE, this->lexer.getNextToken().getType()); + + // surrounding double-quotes shouldn't change the result. + EXPECT_EQ(0, this->rdata_txt_like_quoted.compare(*rdata)); + EXPECT_EQ(0, TypeParam(this->lexer, NULL, MasterLoader::MANY_ERRORS, + this->loader_cb).compare(*rdata)); + EXPECT_EQ(MasterToken::END_OF_LINE, this->lexer.getNextToken().getType()); + + // multi-line input with () + EXPECT_EQ(0, TypeParam(multi_line).compare(*rdata)); + EXPECT_EQ(0, TypeParam(this->lexer, NULL, MasterLoader::MANY_ERRORS, + this->loader_cb).compare(*rdata)); + EXPECT_EQ(MasterToken::END_OF_LINE, this->lexer.getNextToken().getType()); + + // for the same data using escape + EXPECT_EQ(0, TypeParam(escaped_txt).compare(*rdata)); + EXPECT_EQ(0, TypeParam(this->lexer, NULL, MasterLoader::MANY_ERRORS, + this->loader_cb).compare(*rdata)); + EXPECT_EQ(MasterToken::END_OF_LINE, this->lexer.getNextToken().getType()); + + // Null character-string. + this->obuffer.clear(); + TypeParam(string("\"\"")).toWire(this->obuffer); + matchWireData(wiredata_nulltxt, sizeof(wiredata_nulltxt), + this->obuffer.getData(), this->obuffer.getLength()); + + this->obuffer.clear(); + TypeParam(this->lexer, NULL, MasterLoader::MANY_ERRORS, this->loader_cb). + toWire(this->obuffer); + matchWireData(wiredata_nulltxt, sizeof(wiredata_nulltxt), + this->obuffer.getData(), this->obuffer.getLength()); + + EXPECT_EQ(MasterToken::END_OF_LINE, this->lexer.getNextToken().getType()); + + // Longest possible character-string. + this->obuffer.clear(); + TypeParam(string(255, 'a')).toWire(this->obuffer); + matchWireData(&this->wiredata_longesttxt[0], + this->wiredata_longesttxt.size(), + this->obuffer.getData(), this->obuffer.getLength()); + + this->obuffer.clear(); + TypeParam(this->lexer, NULL, MasterLoader::MANY_ERRORS, this->loader_cb). + toWire(this->obuffer); + matchWireData(&this->wiredata_longesttxt[0], + this->wiredata_longesttxt.size(), + this->obuffer.getData(), this->obuffer.getLength()); + + EXPECT_EQ(MasterToken::END_OF_LINE, this->lexer.getNextToken().getType()); + + // Too long text for a valid character-string. + EXPECT_THROW(TypeParam(string(256, 'a')), CharStringTooLong); + EXPECT_THROW(TypeParam(this->lexer, NULL, MasterLoader::MANY_ERRORS, + this->loader_cb), CharStringTooLong); + EXPECT_EQ(MasterToken::END_OF_LINE, this->lexer.getNextToken().getType()); + + // The escape character makes the double quote a part of character-string, + // so this is invalid input and should be rejected. + EXPECT_THROW(TypeParam("\"Test-String\\\""), InvalidRdataText); + EXPECT_THROW(TypeParam(this->lexer, NULL, MasterLoader::MANY_ERRORS, + this->loader_cb), MasterLexer::LexerError); + EXPECT_EQ(MasterToken::END_OF_LINE, this->lexer.getNextToken().getType()); +} + +TYPED_TEST(Rdata_TXT_LIKE_Test, createMultiStringsFromText) { + // Tests for "from text" variants construction with various forms of + // multi character-strings. + + std::vector<std::string > texts; + texts.push_back("\"Test-String\" \"Test-String\""); // most common form + texts.push_back("\"Test-String\"\"Test-String\""); // no space between'em + texts.push_back("\"Test-String\" Test-String"); // no '"' for one + texts.push_back("\"Test-String\"Test-String"); // and no space either + texts.push_back("Test-String \"Test-String\""); // no '"' for the other + texts.push_back("Test-String\"Test-String\""); // and no space either + + std::stringstream ss; + for (std::vector<std::string >::const_iterator it = texts.begin(); + it != texts.end(); ++it) { + ss << *it << "\n"; + } + this->lexer.pushSource(ss); + + // The corresponding Rdata built from wire to compare in the checks below. + ConstRdataPtr const rdata = + this->rdataFactoryFromFile(RRTYPE<TypeParam>(), + RRClass("IN"), "rdata_txt_fromWire3.wire"); + + // Confirm we can construct the Rdata from the test text, both from + // std::string and with lexer, and that matches the from-wire data. + for (std::vector<std::string >::const_iterator it = texts.begin(); + it != texts.end(); ++it) { + SCOPED_TRACE(*it); + EXPECT_EQ(0, TypeParam(*it).compare(*rdata)); + + EXPECT_EQ(0, TypeParam(this->lexer, NULL, MasterLoader::MANY_ERRORS, + this->loader_cb).compare(*rdata)); + EXPECT_EQ(MasterToken::END_OF_LINE, + this->lexer.getNextToken().getType()); + } +} + +TYPED_TEST(Rdata_TXT_LIKE_Test, createFromTextExtra) { + // This is for the std::string version only: the input must end with EOF; + // an extra new-line will result in an exception. + EXPECT_THROW(TypeParam("\"Test-String\"\n"), InvalidRdataText); + // Same if there's a space before '\n' + EXPECT_THROW(TypeParam("\"Test-String\" \n"), InvalidRdataText); +} + +TYPED_TEST(Rdata_TXT_LIKE_Test, fromTextEmpty) { + // If the input text doesn't contain any character-string, it should be + // rejected + EXPECT_THROW(TypeParam(""), InvalidRdataText); + EXPECT_THROW(TypeParam(" "), InvalidRdataText); // even with a space + EXPECT_THROW(TypeParam("(\n)"), InvalidRdataText); // or multi-line with () +} + +void +makeLargest(vector<uint8_t>& data) { + uint8_t ch = 0; + + // create 255 sets of character-strings, each of which has the longest + // length (255bytes string + 1-byte length field) + for (int i = 0; i < 255; ++i, ++ch) { + data.push_back(255); + data.insert(data.end(), 255, ch); + } + // the last character-string should be 255 bytes (including the one-byte + // length field) in length so that the total length should be in the range + // of 16-bit integers. + data.push_back(254); + data.insert(data.end(), 254, ch); + + assert(data.size() == 65535); +} + +TYPED_TEST(Rdata_TXT_LIKE_Test, createFromWire) { + EXPECT_EQ(0, this->rdata_txt_like.compare( + *this->rdataFactoryFromFile(RRTYPE<TypeParam>(), + RRClass("IN"), + "rdata_txt_fromWire1"))); + + // Empty character string + EXPECT_EQ(0, this->rdata_txt_like_empty.compare( + *this->rdataFactoryFromFile(RRTYPE<TypeParam>(), + RRClass("IN"), + "rdata_txt_fromWire2.wire"))); + + // Multiple character strings + this->obuffer.clear(); + this->rdataFactoryFromFile(RRTYPE<TypeParam>(), RRClass("IN"), + "rdata_txt_fromWire3.wire")->toWire(this->obuffer); + // the result should be 'wiredata_txt' repeated twice + vector<uint8_t> expected_data(wiredata_txt_like, wiredata_txt_like + + sizeof(wiredata_txt_like)); + expected_data.insert(expected_data.end(), wiredata_txt_like, + wiredata_txt_like + sizeof(wiredata_txt_like)); + matchWireData(&expected_data[0], expected_data.size(), + this->obuffer.getData(), this->obuffer.getLength()); + + // Largest length of data. There's nothing special, but should be + // constructed safely, and the content should be identical to the original + // data. + vector<uint8_t> largest_txt_like_data; + makeLargest(largest_txt_like_data); + InputBuffer ibuffer(&largest_txt_like_data[0], + largest_txt_like_data.size()); + TypeParam largest_txt_like(ibuffer, largest_txt_like_data.size()); + this->obuffer.clear(); + largest_txt_like.toWire(this->obuffer); + matchWireData(&largest_txt_like_data[0], largest_txt_like_data.size(), + this->obuffer.getData(), this->obuffer.getLength()); + + // rdlen parameter is out of range. This is a rare event because we'd + // normally call the constructor via a polymorphic wrapper, where the + // length is validated. But this should be checked explicitly. + InputBuffer ibuffer2(&largest_txt_like_data[0], + largest_txt_like_data.size()); + EXPECT_THROW(TypeParam(ibuffer2, 65536), InvalidRdataLength); + + // RDATA is empty, which is invalid for TXT_LIKE. + EXPECT_THROW(this->rdataFactoryFromFile(RRTYPE<TypeParam>(), RRClass("IN"), + "rdata_txt_fromWire4.wire"), + DNSMessageFORMERR); + + // character-string length is too large, which could cause overrun. + EXPECT_THROW(this->rdataFactoryFromFile(RRTYPE<TypeParam>(), RRClass("IN"), + "rdata_txt_fromWire5.wire"), + DNSMessageFORMERR); +} + +TYPED_TEST(Rdata_TXT_LIKE_Test, createFromLexer) { + EXPECT_EQ(0, this->rdata_txt_like.compare( + *test::createRdataUsingLexer(RRTYPE<TypeParam>(), RRClass::IN(), + "Test-String"))); +} + +TYPED_TEST(Rdata_TXT_LIKE_Test, toWireBuffer) { + this->rdata_txt_like.toWire(this->obuffer); + matchWireData(wiredata_txt_like, sizeof(wiredata_txt_like), + this->obuffer.getData(), this->obuffer.getLength()); +} + +TYPED_TEST(Rdata_TXT_LIKE_Test, toWireRenderer) { + this->rdata_txt_like.toWire(this->renderer); + matchWireData(wiredata_txt_like, sizeof(wiredata_txt_like), + this->renderer.getData(), this->renderer.getLength()); +} + +TYPED_TEST(Rdata_TXT_LIKE_Test, toText) { + EXPECT_EQ("\"Test-String\"", this->rdata_txt_like.toText()); + EXPECT_EQ("\"\"", this->rdata_txt_like_empty.toText()); + EXPECT_EQ("\"Test-String\"", this->rdata_txt_like_quoted.toText()); + + // Check escape behavior + const TypeParam double_quotes("Test-String\"Test-String\""); + EXPECT_EQ("\"Test-String\" \"Test-String\"", double_quotes.toText()); + const TypeParam semicolon("Test-String\\;Test-String"); + EXPECT_EQ("\"Test-String\\;Test-String\"", semicolon.toText()); + const TypeParam backslash("Test-String\\\\Test-String"); + EXPECT_EQ("\"Test-String\\\\Test-String\"", backslash.toText()); + const TypeParam before_x20("Test-String\\031Test-String"); + EXPECT_EQ("\"Test-String\\031Test-String\"", before_x20.toText()); + const TypeParam from_x20_to_x7e("\"Test-String ~ Test-String\""); + EXPECT_EQ("\"Test-String ~ Test-String\"", from_x20_to_x7e.toText()); + const TypeParam from_x20_to_x7e_2("Test-String\\032\\126\\032Test-String"); + EXPECT_EQ("\"Test-String ~ Test-String\"", from_x20_to_x7e_2.toText()); + const TypeParam after_x7e("Test-String\\127Test-String"); + EXPECT_EQ("\"Test-String\\127Test-String\"", after_x7e.toText()); +} + +TYPED_TEST(Rdata_TXT_LIKE_Test, assignment) { + TypeParam rdata1("assignment1"); + TypeParam rdata2("assignment2"); + rdata1 = rdata2; + EXPECT_EQ(0, rdata2.compare(rdata1)); + + // Check if the copied data is valid even after the original is deleted + TypeParam* rdata3 = new TypeParam(rdata1); + TypeParam rdata4("assignment3"); + rdata4 = *rdata3; + delete rdata3; + EXPECT_EQ(0, rdata4.compare(rdata1)); + + // Self assignment + rdata2 = *&rdata2; + EXPECT_EQ(0, rdata2.compare(rdata1)); +} + +TYPED_TEST(Rdata_TXT_LIKE_Test, compare) { + string const txt1("aaaaaaaa"); + string const txt2("aaaaaaaaaa"); + string const txt3("bbbbbbbb"); + string const txt4(129, 'a'); + string const txt5(128, 'b'); + + EXPECT_EQ(TypeParam(txt1).compare(TypeParam(txt1)), 0); + + EXPECT_LT(TypeParam("\"\"").compare(TypeParam(txt1)), 0); + EXPECT_GT(TypeParam(txt1).compare(TypeParam("\"\"")), 0); + + EXPECT_LT(TypeParam(txt1).compare(TypeParam(txt2)), 0); + EXPECT_GT(TypeParam(txt2).compare(TypeParam(txt1)), 0); + + EXPECT_LT(TypeParam(txt1).compare(TypeParam(txt3)), 0); + EXPECT_GT(TypeParam(txt3).compare(TypeParam(txt1)), 0); + + // we're comparing the data raw, starting at the length octet, so a shorter + // string sorts before a longer one no matter the lexicopraphical order + EXPECT_LT(TypeParam(txt3).compare(TypeParam(txt2)), 0); + EXPECT_GT(TypeParam(txt2).compare(TypeParam(txt3)), 0); + + // to make sure the length octet compares unsigned + EXPECT_LT(TypeParam(txt1).compare(TypeParam(txt4)), 0); + EXPECT_GT(TypeParam(txt4).compare(TypeParam(txt1)), 0); + + EXPECT_LT(TypeParam(txt5).compare(TypeParam(txt4)), 0); + EXPECT_GT(TypeParam(txt4).compare(TypeParam(txt5)), 0); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(TypeParam(txt1).compare(*this->rdata_nomatch), + bad_cast); +} + +} diff --git a/src/lib/dns/tests/rdata_unittest.cc b/src/lib/dns/tests/rdata_unittest.cc new file mode 100644 index 0000000..afc16a1 --- /dev/null +++ b/src/lib/dns/tests/rdata_unittest.cc @@ -0,0 +1,467 @@ +// Copyright (C) 2010-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <functional> +#include <iomanip> +#include <vector> +#include <string> +#include <sstream> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> + +#include <gtest/gtest.h> + +#include <dns/tests/unittest_util.h> +#include <dns/tests/rdata_unittest.h> + +#include <util/unittests/wiredata.h> + +#include <boost/lexical_cast.hpp> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; +namespace ph = std::placeholders; + +namespace isc { +namespace dns { +namespace rdata { +RdataTest::RdataTest() : + obuffer(0), rdata_nomatch(createRdata(RRType(0), RRClass(1), "\\# 0")), + loader_cb(MasterLoaderCallbacks::getNullCallbacks()) +{} + +RdataPtr +RdataTest::rdataFactoryFromFile(const RRType& rrtype, const RRClass& rrclass, + const char* datafile, size_t position) +{ + std::vector<unsigned char> data; + UnitTestUtil::readWireData(datafile, data); + + InputBuffer buffer(&data[0], data.size()); + buffer.setPosition(position); + + uint16_t rdlen = buffer.readUint16(); + return (createRdata(rrtype, rrclass, buffer, rdlen)); +} + +namespace test { + +RdataPtr +createRdataUsingLexer(const RRType& rrtype, const RRClass& rrclass, + const std::string& str) +{ + std::stringstream ss(str); + MasterLexer lexer; + lexer.pushSource(ss); + + MasterLoaderCallbacks callbacks = + MasterLoaderCallbacks::getNullCallbacks(); + const Name origin("example.org."); + + return (createRdata(rrtype, rrclass, lexer, &origin, + MasterLoader::MANY_ERRORS, callbacks)); +} + +} // end of namespace isc::dns::rdata::test + +// A mock class to check parameters passed via loader callbacks. Its callback +// records the passed parameters, allowing the test to check them later via +// the check() method. +class CreateRdataCallback { +public: + enum CallbackType { NONE, ERROR, WARN }; + CreateRdataCallback() : type_(NONE), line_(0) {} + void callback(CallbackType type, const string& source, size_t line, + const string& reason_txt) { + type_ = type; + source_ = source; + line_ = line; + reason_txt_ = reason_txt; + } + + void clear() { + type_ = NONE; + source_.clear(); + line_ = 0; + reason_txt_.clear(); + } + + // Return if callback is called since the previous call to clear(). + bool isCalled() const { return (type_ != NONE); } + + void check(const string& expected_srcname, size_t expected_line, + CallbackType expected_type, const string& expected_reason) + const + { + EXPECT_EQ(expected_srcname, source_); + EXPECT_EQ(expected_line, line_); + EXPECT_EQ(expected_type, type_); + EXPECT_EQ(expected_reason, reason_txt_); + } + +private: + CallbackType type_; + string source_; + size_t line_; + string reason_txt_; +}; + +// Test class/type-independent behavior of createRdata(). +TEST_F(RdataTest, createRdataWithLexer) { + const in::AAAA aaaa_rdata("2001:db8::1"); + + stringstream ss; + const string src_name = "stream-" + boost::lexical_cast<string>(&ss); + ss << aaaa_rdata.toText() << "\n"; // valid case + ss << aaaa_rdata.toText() << "; comment, should be ignored\n"; + ss << aaaa_rdata.toText() << " extra-token\n"; // extra token + ss << aaaa_rdata.toText() << " extra token\n"; // 2 extra tokens + ss << ")\n"; // causing lexer error in parsing the RDATA text + ss << "192.0.2.1\n"; // semantics error: IPv4 address is given for AAAA + ss << aaaa_rdata.toText(); // valid, but end with EOF, not EOL + lexer.pushSource(ss); + + CreateRdataCallback callback; + MasterLoaderCallbacks callbacks( + std::bind(&CreateRdataCallback::callback, &callback, + CreateRdataCallback::ERROR, ph::_1, ph::_2, ph::_3), + std::bind(&CreateRdataCallback::callback, &callback, + CreateRdataCallback::WARN, ph::_1, ph::_2, ph::_3)); + + size_t line = 0; + + // Valid case. + ++line; + ConstRdataPtr rdata = createRdata(RRType::AAAA(), RRClass::IN(), lexer, + NULL, MasterLoader::MANY_ERRORS, + callbacks); + EXPECT_EQ(0, aaaa_rdata.compare(*rdata)); + EXPECT_FALSE(callback.isCalled()); + + // Similar to the previous case, but RDATA is followed by a comment. + // It should cause any confusion. + ++line; + callback.clear(); + rdata = createRdata(RRType::AAAA(), RRClass::IN(), lexer, NULL, + MasterLoader::MANY_ERRORS, callbacks); + EXPECT_EQ(0, aaaa_rdata.compare(*rdata)); + EXPECT_FALSE(callback.isCalled()); + + // Broken RDATA text: extra token. createRdata() returns NULL, error + // callback is called. + ++line; + callback.clear(); + EXPECT_FALSE(createRdata(RRType::AAAA(), RRClass::IN(), lexer, NULL, + MasterLoader::MANY_ERRORS, callbacks)); + callback.check(src_name, line, CreateRdataCallback::ERROR, + "createRdata from text failed near 'extra-token': " + "extra input text"); + + // Similar to the previous case, but only the first extra token triggers + // callback. + ++line; + callback.clear(); + EXPECT_FALSE(createRdata(RRType::AAAA(), RRClass::IN(), lexer, NULL, + MasterLoader::MANY_ERRORS, callbacks)); + callback.check(src_name, line, CreateRdataCallback::ERROR, + "createRdata from text failed near 'extra': " + "extra input text"); + + // Lexer error will happen, corresponding error callback will be triggered. + ++line; + callback.clear(); + EXPECT_FALSE(createRdata(RRType::AAAA(), RRClass::IN(), lexer, NULL, + MasterLoader::MANY_ERRORS, callbacks)); + callback.check(src_name, line, CreateRdataCallback::ERROR, + "createRdata from text failed: unbalanced parentheses"); + + // Semantics level error will happen, corresponding error callback will be + // triggered. + ++line; + callback.clear(); + EXPECT_FALSE(createRdata(RRType::AAAA(), RRClass::IN(), lexer, NULL, + MasterLoader::MANY_ERRORS, callbacks)); + callback.check(src_name, line, CreateRdataCallback::ERROR, + "createRdata from text failed: Bad IN/AAAA RDATA text: " + "'192.0.2.1'"); + + // Input is valid and parse will succeed, but with a warning that the + // file is not ended with a newline. + ++line; + callback.clear(); + rdata = createRdata(RRType::AAAA(), RRClass::IN(), lexer, NULL, + MasterLoader::MANY_ERRORS, callbacks); + EXPECT_EQ(0, aaaa_rdata.compare(*rdata)); + callback.check(src_name, line, CreateRdataCallback::WARN, + "file does not end with newline"); +} + +TEST_F(RdataTest, getLength) { + const in::AAAA aaaa_rdata("2001:db8::1"); + EXPECT_EQ(16, aaaa_rdata.getLength()); + + const generic::TXT txt_rdata("Hello World"); + EXPECT_EQ(12, txt_rdata.getLength()); +} + +} +} +} + +namespace { + +// Wire-format data correspond to rdata_unknown. Note that it doesn't +// include RDLENGTH. +const uint8_t wiredata_unknown[] = { 0xa1, 0xb2, 0xc3, 0x0d }; + +class Rdata_Unknown_Test : public RdataTest { +public: + Rdata_Unknown_Test() : + // "Unknown" RR Type used for the test cases below. If/when we + // use this type number as a "well-known" (probably + // experimental) type, we'll need to renumber it. + unknown_rrtype(RRType(65000)), + rdata_unknowntxt("\\# 4 a1b2c30d"), + rdata_unknown(rdata_unknowntxt) + {} +protected: + static string getLongestRdataTxt(); + static void getLongestRdataWire(vector<uint8_t>& v); + + const RRType unknown_rrtype; + const std::string rdata_unknowntxt; + const generic::Generic rdata_unknown; +}; + +string +Rdata_Unknown_Test::getLongestRdataTxt() { + ostringstream oss; + + oss << "\\# " << MAX_RDLENGTH << " "; + oss.fill('0'); + oss << right << hex; + for (int i = 0; i < MAX_RDLENGTH; i++) { + oss << setw(2) << (i & 0xff); + } + + return (oss.str()); +} + +void +Rdata_Unknown_Test::getLongestRdataWire(vector<uint8_t>& v) { + unsigned char ch = 0; + for (int i = 0; i < MAX_RDLENGTH; ++i, ++ch) { + v.push_back(ch); + } +} + +TEST_F(Rdata_Unknown_Test, createFromText) { + // valid construction. This also tests a normal case of "FromWire". + EXPECT_EQ(0, generic::Generic("\\# 4 a1b2c30d").compare( + *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(), + "rdata_unknown_fromWire"))); + // upper case hexadecimal digits should also be okay. + EXPECT_EQ(0, generic::Generic("\\# 4 A1B2C30D").compare( + *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(), + "rdata_unknown_fromWire"))); + // 0-length RDATA should be accepted + EXPECT_EQ(0, generic::Generic("\\# 0").compare( + *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(), + "rdata_unknown_fromWire", 6))); + // hex encoding can be space-separated + EXPECT_EQ(0, generic::Generic("\\# 4 a1 b2c30d").compare(rdata_unknown)); + EXPECT_EQ(0, generic::Generic("\\# 4 a1b2 c30d").compare(rdata_unknown)); + EXPECT_EQ(0, generic::Generic("\\# 4 a1 b2 c3 0d").compare(rdata_unknown)); + EXPECT_EQ(0, generic::Generic("\\# 4 a1\tb2c3 0d").compare(rdata_unknown)); + + // Max-length RDATA + vector<uint8_t> v; + getLongestRdataWire(v); + InputBuffer ibuffer(&v[0], v.size()); + EXPECT_EQ(0, generic::Generic(getLongestRdataTxt()).compare( + generic::Generic(ibuffer, v.size()))); + + // the length field must match the encoding data length. + EXPECT_THROW(generic::Generic("\\# 4 1080c0ff00"), InvalidRdataLength); + EXPECT_THROW(generic::Generic("\\# 5 1080c0ff"), InvalidRdataLength); + // RDATA encoding part must consist of an even number of hex digits. + EXPECT_THROW(generic::Generic("\\# 1 1"), InvalidRdataText); + EXPECT_THROW(generic::Generic("\\# 1 ax"), InvalidRdataText); + // the length should be 16-bit unsigned integer + EXPECT_THROW(generic::Generic("\\# 65536 a1b2c30d"), InvalidRdataLength); + EXPECT_THROW(generic::Generic("\\# -1 a1b2c30d"), InvalidRdataLength); + EXPECT_THROW(generic::Generic("\\# 1.1 a1"), InvalidRdataLength); + EXPECT_THROW(generic::Generic("\\# 0a 00010203040506070809"), + InvalidRdataLength); + // should reject if the special token is missing. + EXPECT_THROW(generic::Generic("4 a1b2c30d"), InvalidRdataText); + // the special token, the RDLENGTH and the data must be space separated. + EXPECT_THROW(generic::Generic("\\#0"), InvalidRdataText); + EXPECT_THROW(generic::Generic("\\# 1ff"), InvalidRdataLength); +} + +TEST_F(Rdata_Unknown_Test, createFromWire) { + // normal case (including 0-length data) is covered in createFromText. + + // buffer too short. the error should be detected in buffer read + EXPECT_THROW(rdataFactoryFromFile(unknown_rrtype, RRClass::IN(), + "rdata_unknown_fromWire", 8), + InvalidBufferPosition); + + // too large data + vector<uint8_t> v; + getLongestRdataWire(v); + v.push_back(0); // making it too long + InputBuffer ibuffer(&v[0], v.size()); + EXPECT_THROW(generic::Generic(ibuffer, v.size()), InvalidRdataLength); +} + +// The following 3 sets of tests check the behavior of createRdata() variants +// with the "unknown" RRtype. The result should be RRclass independent. +TEST_F(Rdata_Unknown_Test, createRdataFromString) { + EXPECT_EQ(0, rdata_unknown.compare( + *createRdata(unknown_rrtype, RRClass::IN(), + rdata_unknowntxt))); + EXPECT_EQ(0, rdata_unknown.compare( + *createRdata(unknown_rrtype, RRClass::CH(), + rdata_unknowntxt))); + EXPECT_EQ(0, rdata_unknown.compare( + *createRdata(unknown_rrtype, RRClass("CLASS65000"), + rdata_unknowntxt))); +} + +TEST_F(Rdata_Unknown_Test, createRdataFromWire) { + InputBuffer ibuffer(wiredata_unknown, sizeof(wiredata_unknown)); + EXPECT_EQ(0, rdata_unknown.compare( + *createRdata(unknown_rrtype, RRClass::IN(), + ibuffer, sizeof(wiredata_unknown)))); + + InputBuffer ibuffer2(wiredata_unknown, sizeof(wiredata_unknown)); + EXPECT_EQ(0, rdata_unknown.compare( + *createRdata(unknown_rrtype, RRClass::CH(), + ibuffer2, sizeof(wiredata_unknown)))); + + InputBuffer ibuffer3(wiredata_unknown, sizeof(wiredata_unknown)); + EXPECT_EQ(0, rdata_unknown.compare( + *createRdata(unknown_rrtype, RRClass(65000), + ibuffer3, sizeof(wiredata_unknown)))); +} + +TEST_F(Rdata_Unknown_Test, createRdataByCopy) { + EXPECT_EQ(0, rdata_unknown.compare( + *createRdata(unknown_rrtype, RRClass::IN(), rdata_unknown))); + EXPECT_EQ(0, rdata_unknown.compare( + *createRdata(unknown_rrtype, RRClass::CH(), rdata_unknown))); + EXPECT_EQ(0, rdata_unknown.compare( + *createRdata(unknown_rrtype, RRClass(65000), + rdata_unknown))); +} + +TEST_F(Rdata_Unknown_Test, copyConstruct) { + generic::Generic copy(rdata_unknown); + EXPECT_EQ(0, copy.compare(rdata_unknown)); + + // Check the copied data is valid even after the original is deleted + generic::Generic* copy2 = new generic::Generic(rdata_unknown); + generic::Generic copy3(*copy2); + delete copy2; + EXPECT_EQ(0, copy3.compare(rdata_unknown)); +} + +TEST_F(Rdata_Unknown_Test, assignment) { + generic::Generic copy("\\# 1 10"); + copy = rdata_unknown; + EXPECT_EQ(0, copy.compare(rdata_unknown)); + + // Check if the copied data is valid even after the original is deleted + generic::Generic* copy2 = new generic::Generic(rdata_unknown); + generic::Generic copy3("\\# 1 10"); + copy3 = *copy2; + delete copy2; + EXPECT_EQ(0, copy3.compare(rdata_unknown)); + + // Self assignment + copy = *© + EXPECT_EQ(0, copy.compare(rdata_unknown)); +} + +TEST_F(Rdata_Unknown_Test, toText) { + EXPECT_EQ(rdata_unknowntxt, rdata_unknown.toText()); + EXPECT_EQ(getLongestRdataTxt(), + generic::Generic(getLongestRdataTxt()).toText()); +} + +TEST_F(Rdata_Unknown_Test, toWireBuffer) { + rdata_unknown.toWire(obuffer); + matchWireData(wiredata_unknown, sizeof(wiredata_unknown), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(Rdata_Unknown_Test, toWireRenderer) { + rdata_unknown.toWire(renderer); + matchWireData(wiredata_unknown, sizeof(wiredata_unknown), + renderer.getData(), renderer.getLength()); +} + +TEST_F(Rdata_Unknown_Test, compare) { + // comparison as left-justified unsigned octet sequences: + // cppcheck-suppress uselessCallsCompare + EXPECT_EQ(0, rdata_unknown.compare(rdata_unknown)); + + generic::Generic rdata_unknown_small("\\# 4 00b2c3ff"); + EXPECT_GT(0, rdata_unknown_small.compare(rdata_unknown)); + EXPECT_LT(0, rdata_unknown.compare(rdata_unknown_small)); + + generic::Generic rdata_unknown_large("\\# 4 ffb2c300"); + EXPECT_LT(0, rdata_unknown_large.compare(rdata_unknown)); + EXPECT_GT(0, rdata_unknown.compare(rdata_unknown_large)); + + // the absence of an octet sorts before a zero octet. + generic::Generic rdata_unknown_short("\\# 3 a1b2c3"); + EXPECT_GT(0, rdata_unknown_short.compare(rdata_unknown)); + EXPECT_LT(0, rdata_unknown.compare(rdata_unknown_short)); +} + +TEST_F(Rdata_Unknown_Test, LeftShiftOperator) { + ostringstream oss; + oss << rdata_unknown; + EXPECT_EQ(rdata_unknown.toText(), oss.str()); +} + +// +// Tests for global utility functions +// +TEST_F(RdataTest, compareNames) { + Name small("a.example"); + Name large("example"); + + // Check the case where the order is different from the owner name + // comparison: + EXPECT_TRUE(small > large); + EXPECT_EQ(-1, compareNames(small, large)); + EXPECT_EQ(1, compareNames(large, small)); + + // Check case insensitive comparison: + Name small_upper("A.EXAMPLE"); + EXPECT_EQ(0, compareNames(small, small_upper)); + + // the absence of an octet sorts before a zero octet. + Name large2("a.example2"); + EXPECT_EQ(-1, compareNames(small, large2)); + EXPECT_EQ(1, compareNames(large2, small)); +} +} diff --git a/src/lib/dns/tests/rdata_unittest.h b/src/lib/dns/tests/rdata_unittest.h new file mode 100644 index 0000000..0c9178e --- /dev/null +++ b/src/lib/dns/tests/rdata_unittest.h @@ -0,0 +1,92 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef RDATA_UNITTEST_H +#define RDATA_UNITTEST_H 1 + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> +#include <dns/rdata.h> +#include <dns/master_lexer.h> + +#include <gtest/gtest.h> + +#include <string> +#include <sstream> + +namespace isc { +namespace dns { +namespace rdata { +class RdataTest : public ::testing::Test { +protected: + RdataTest(); + static RdataPtr rdataFactoryFromFile(const RRType& rrtype, + const RRClass& rrclass, + const char* datafile, + size_t position = 0); + + // Common check to see the result of Rdata construction of given type + // (template parameter RdataType) either from std::string or with + // MasterLexer object. If it's expected to succeed the result should be + // identical to the commonly used test data (rdata_expected); otherwise it + // should result in the exception specified as the template parameter: + // ExForString for the string version, and ExForLexer for the lexer + // version. throw_str_version and throw_lexer_version are set to true + // iff the string/lexer version is expected to throw, respectively. + // Parameter origin can be set to non NULL for the origin parameter of + // the lexer version of Rdata constructor. + template <typename RdataType, typename ExForString, typename ExForLexer> + void checkFromText(const std::string& rdata_txt, + const RdataType& rdata_expected, + bool throw_str_version = true, + bool throw_lexer_version = true, + const Name* origin = NULL) + { + SCOPED_TRACE(rdata_txt); + + if (throw_str_version) { + EXPECT_THROW(RdataType rdata(rdata_txt), ExForString); + } else { + EXPECT_EQ(0, RdataType(rdata_txt).compare(rdata_expected)); + } + + std::stringstream ss(rdata_txt); + MasterLexer lexer; + lexer.pushSource(ss); + if (throw_lexer_version) { + EXPECT_THROW(RdataType rdata(lexer, origin, MasterLoader::DEFAULT, + loader_cb), ExForLexer); + } else { + EXPECT_EQ(0, RdataType(lexer, origin, MasterLoader::DEFAULT, + loader_cb).compare(rdata_expected)); + } + } + + isc::util::OutputBuffer obuffer; + MessageRenderer renderer; + /// This is an RDATA object of some "unknown" RR type so that it can be + /// used to test the compare() method against a well-known RR type. + RdataPtr rdata_nomatch; + MasterLexer lexer; + MasterLoaderCallbacks loader_cb; +}; + +namespace test { +RdataPtr +createRdataUsingLexer(const RRType& rrtype, const RRClass& rrclass, + const std::string& str); +} + +} +} +} +#endif // RDATA_UNITTEST_H + +// Local Variables: +// mode: c++ +// End: diff --git a/src/lib/dns/tests/rdatafields_unittest.cc b/src/lib/dns/tests/rdatafields_unittest.cc new file mode 100644 index 0000000..0531439 --- /dev/null +++ b/src/lib/dns/tests/rdatafields_unittest.cc @@ -0,0 +1,366 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <vector> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/name.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rdatafields.h> +#include <dns/tests/unittest_util.h> + +#include <util/unittests/wiredata.h> + +#include <gtest/gtest.h> + +using namespace std; +using namespace isc::dns; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::OutputBuffer; +using isc::util::InputBuffer; +using isc::util::unittests::matchWireData; + +namespace { +class RdataFieldsTest : public ::testing::Test { +protected: + RdataFieldsTest() : obuffer(0), ns_name("example.com"), + other_name("www.example.com") + {} + void constructCommonTests(const RdataFields& fields, + const uint8_t* const expected_data, + const size_t expected_data_len); + void constructCommonTestsNS(const RdataFields& fields); + void constructCommonTestsTXT(const RdataFields& fields); + void constructCommonTestsRRSIG(const RdataFields& fields); + void constructCommonTestsOPT(const RdataFields& fields); + OutputBuffer obuffer; + MessageRenderer renderer; + const Name ns_name; + const Name other_name; + vector<unsigned char> expected_wire; + vector<unsigned char> fields_wire; +}; + +const uint8_t in_a_data[] = { 192, 0, 2, 1 }; +// binary representation of example.com. +const uint8_t ns_data[] = { 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x03, 0x63, 0x6f, 0x6d, 0x00 }; + +// +// IN/A RDATA: fixed length, single data field +// +void +RdataFieldsTest::constructCommonTests(const RdataFields& fields, + const uint8_t* const expected_data, + const size_t expected_data_len) +{ + matchWireData(expected_data, expected_data_len, + fields.getData(), fields.getDataLength()); + + EXPECT_EQ(sizeof(RdataFields::FieldSpec), fields.getFieldSpecDataSize()); + EXPECT_EQ(1, fields.getFieldCount()); + EXPECT_EQ(RdataFields::DATA, fields.getFieldSpec(0).type); + EXPECT_EQ(4, fields.getFieldSpec(0).len); + + fields.toWire(obuffer); + matchWireData(expected_data, expected_data_len, + obuffer.getData(), obuffer.getLength()); + + fields.toWire(renderer); + matchWireData(expected_data, expected_data_len, + renderer.getData(), renderer.getLength()); +} + +TEST_F(RdataFieldsTest, constructFromRdata) { + const RdataFields fields(in::A("192.0.2.1")); + constructCommonTests(fields, in_a_data, sizeof(in_a_data)); +} + +TEST_F(RdataFieldsTest, constructFromParams) { + const RdataFields::FieldSpec spec(RdataFields::DATA, 4); + const RdataFields fields(&spec, sizeof(spec), in_a_data, + sizeof(in_a_data)); + constructCommonTests(fields, in_a_data, sizeof(in_a_data)); +} + +// +// NS RDATA: containing a compressible name. +// +void +RdataFieldsTest::constructCommonTestsNS(const RdataFields& fields) { + EXPECT_EQ(sizeof(RdataFields::FieldSpec), fields.getFieldSpecDataSize()); + EXPECT_EQ(1, fields.getFieldCount()); + EXPECT_EQ(RdataFields::COMPRESSIBLE_NAME, fields.getFieldSpec(0).type); + EXPECT_EQ(ns_name.getLength(), fields.getFieldSpec(0).len); + + expected_wire.clear(); + UnitTestUtil::readWireData("rdatafields1.wire", expected_wire); + other_name.toWire(obuffer); + fields.toWire(obuffer); + matchWireData(&expected_wire[0], expected_wire.size(), + obuffer.getData(), obuffer.getLength()); + + expected_wire.clear(); + UnitTestUtil::readWireData("rdatafields2.wire", expected_wire); + other_name.toWire(renderer); + fields.toWire(renderer); + matchWireData(&expected_wire[0], expected_wire.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(RdataFieldsTest, constructFromRdataNS) { + const RdataFields fields_ns((generic::NS(ns_name))); + constructCommonTestsNS(fields_ns); +} + +TEST_F(RdataFieldsTest, constructFromParamsNS) { + const RdataFields::FieldSpec spec(RdataFields::COMPRESSIBLE_NAME, + sizeof(ns_data)); + const RdataFields fields_ns(&spec, sizeof(spec), ns_data, sizeof(ns_data)); + constructCommonTestsNS(fields_ns); +} + +// +// TXT RDATA: multiple fields, lengths vary +// +void +RdataFieldsTest::constructCommonTestsTXT(const RdataFields& fields) { + // Since all fields are plain data, they are handled as a single data + // field. + EXPECT_EQ(sizeof(RdataFields::FieldSpec), fields.getFieldSpecDataSize()); + EXPECT_EQ(1, fields.getFieldCount()); + EXPECT_EQ(RdataFields::DATA, fields.getFieldSpec(0).type); + EXPECT_EQ(expected_wire.size(), fields.getFieldSpec(0).len); + + fields.toWire(obuffer); + matchWireData(&expected_wire[0], expected_wire.size(), + obuffer.getData(), obuffer.getLength()); + + fields.toWire(renderer); + matchWireData(&expected_wire[0], expected_wire.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(RdataFieldsTest, constructFromRdataTXT) { + UnitTestUtil::readWireData("rdatafields3.wire", expected_wire); + InputBuffer ibuffer(&expected_wire[0], expected_wire.size()); + const uint16_t rdlen = ibuffer.readUint16(); + const RdataFields fields(generic::TXT(ibuffer, rdlen)); + + // drop the RDLEN part + expected_wire.erase(expected_wire.begin(), expected_wire.begin() + 2); + + constructCommonTestsTXT(fields); +} + +TEST_F(RdataFieldsTest, constructFromParamsTXT) { + UnitTestUtil::readWireData("rdatafields3.wire", expected_wire); + expected_wire.erase(expected_wire.begin(), expected_wire.begin() + 2); + const RdataFields::FieldSpec spec(RdataFields::DATA, expected_wire.size()); + const RdataFields fields(&spec, sizeof(spec), &expected_wire[0], + expected_wire.size()); + constructCommonTestsTXT(fields); +} + +// +// RRSIG: multiple fields, with an incompressible name +// +void +RdataFieldsTest::constructCommonTestsRRSIG(const RdataFields& fields) { + // In terms of RdataFields RRSIG RDATA consists of 3 fields: + // - 18-byte data field (from the "type covered" field to "key tag" field) + // - an incompressible name field (for the signer's name field). + // this is a variable length field. In this test it's a 13-byte field. + // - a variable-length data field for the signature. In this tests + // it's a 15-byte field. + EXPECT_EQ(3 * sizeof(RdataFields::FieldSpec), + fields.getFieldSpecDataSize()); + EXPECT_EQ(3, fields.getFieldCount()); + EXPECT_EQ(RdataFields::DATA, fields.getFieldSpec(0).type); + EXPECT_EQ(18, fields.getFieldSpec(0).len); + EXPECT_EQ(RdataFields::INCOMPRESSIBLE_NAME, fields.getFieldSpec(1).type); + EXPECT_EQ(13, fields.getFieldSpec(1).len); + EXPECT_EQ(RdataFields::DATA, fields.getFieldSpec(2).type); + EXPECT_EQ(15, fields.getFieldSpec(2).len); + + expected_wire.clear(); + UnitTestUtil::readWireData("rdatafields5.wire", expected_wire); + Name("com").toWire(obuffer); + obuffer.writeUint16(fields.getDataLength()); + fields.toWire(obuffer); + other_name.toWire(obuffer); + matchWireData(&expected_wire[0], expected_wire.size(), + obuffer.getData(), obuffer.getLength()); + + expected_wire.clear(); + UnitTestUtil::readWireData("rdatafields6.wire", expected_wire); + Name("com").toWire(renderer); + renderer.writeUint16(fields.getDataLength()); + fields.toWire(renderer); // the signer field won't be compressed + other_name.toWire(renderer); // but will be used as a compression target + matchWireData(&expected_wire[0], expected_wire.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(RdataFieldsTest, constructFromRdataRRSIG) { + UnitTestUtil::readWireData("rdatafields4.wire", expected_wire); + InputBuffer ibuffer(&expected_wire[0], expected_wire.size()); + const uint16_t rdlen = ibuffer.readUint16(); + const RdataFields fields(generic::RRSIG(ibuffer, rdlen)); + + // drop the RDLEN part + expected_wire.erase(expected_wire.begin(), expected_wire.begin() + 2); + + constructCommonTestsRRSIG(fields); +} + +TEST_F(RdataFieldsTest, constructFromParamsRRSIG) { + UnitTestUtil::readWireData("rdatafields4.wire", fields_wire); + fields_wire.erase(fields_wire.begin(), fields_wire.begin() + 2); + + const RdataFields::FieldSpec specs[] = { + RdataFields::FieldSpec(RdataFields::DATA, 18), + RdataFields::FieldSpec(RdataFields::INCOMPRESSIBLE_NAME, 13), + RdataFields::FieldSpec(RdataFields::DATA, 15) + }; + const RdataFields fields(specs, sizeof(specs), &fields_wire[0], + fields_wire.size()); + constructCommonTestsRRSIG(fields); +} + +TEST_F(RdataFieldsTest, convertRdatatoParams) { + // Confirm we can restore the original data from the serialized data. + // We use RRSIG as a relatively complicated field structure. + UnitTestUtil::readWireData("rdatafields4.wire", expected_wire); + InputBuffer ibuffer(&expected_wire[0], expected_wire.size()); + const uint16_t rdlen = ibuffer.readUint16(); + const RdataFields fields(generic::RRSIG(ibuffer, rdlen)); + + expected_wire.erase(expected_wire.begin(), expected_wire.begin() + 2); + + // Copy the data in separate storage + vector<uint8_t> spec_store(fields.getFieldSpecDataSize()); + void* cp_spec = &spec_store[0]; + memcpy(cp_spec, fields.getFieldSpecData(), spec_store.size()); + vector<uint8_t> data_store(fields.getDataLength()); + memcpy(&data_store[0], fields.getData(), fields.getDataLength()); + + // Restore the data in the form of RdataFields + const RdataFields fields_byparams(cp_spec, fields.getFieldSpecDataSize(), + &data_store[0], fields.getDataLength()); + + // Check it's valid + constructCommonTestsRRSIG(fields_byparams); +} + +// +// OPT: an empty RDATA +// +void +RdataFieldsTest::constructCommonTestsOPT(const RdataFields& fields) { + EXPECT_EQ(0, fields.getFieldSpecDataSize()); + EXPECT_EQ(0, fields.getFieldCount()); + EXPECT_EQ(0, fields.getDataLength()); + EXPECT_EQ((const uint8_t*) NULL, fields.getData()); + fields.toWire(obuffer); + EXPECT_EQ(0, obuffer.getLength()); + fields.toWire(renderer); + EXPECT_EQ(0, renderer.getLength()); +} + +TEST_F(RdataFieldsTest, constructFromRdataOPT) { + InputBuffer ibuffer(NULL, 0); + const RdataFields fields(generic::OPT(ibuffer, 0)); + constructCommonTestsOPT(fields); +} + +TEST_F(RdataFieldsTest, constructFromParamsOPT) { + const RdataFields fields(NULL, 0, NULL, 0); + constructCommonTestsOPT(fields); +} + +// Invalid input to the "from parameter" constructor: sum of the field lengths +// is not equal to the data length. +TEST_F(RdataFieldsTest, invalidFieldLength) { + UnitTestUtil::readWireData("rdatafields4.wire", fields_wire); + fields_wire.erase(fields_wire.begin(), fields_wire.begin() + 2); + + const RdataFields::FieldSpec specs[] = { + RdataFields::FieldSpec(RdataFields::DATA, 18), + RdataFields::FieldSpec(RdataFields::INCOMPRESSIBLE_NAME, 13), + RdataFields::FieldSpec(RdataFields::DATA, 14) + }; + // sum of field len < data len + EXPECT_THROW(RdataFields(specs, 3, &fields_wire[0], fields_wire.size()), + isc::InvalidParameter); + // sum of field len > data len + EXPECT_THROW(RdataFields(specs, 3, &fields_wire[0], + fields_wire.size() - 2), + isc::InvalidParameter); +} + +// Invalid input to the "from parameter" constructor: NULL vs length mismatch +TEST_F(RdataFieldsTest, mismatchFieldLengthAndData) { + const unsigned char dummy_data = 0; + const RdataFields::FieldSpec dummy_spec(RdataFields::DATA, 1); + + EXPECT_THROW(RdataFields(NULL, 1, &dummy_data, 1), isc::InvalidParameter); + EXPECT_THROW(RdataFields(&dummy_spec, 0, NULL, 0), isc::InvalidParameter); + EXPECT_THROW(RdataFields(&dummy_spec, 1, NULL, 1), isc::InvalidParameter); + EXPECT_THROW(RdataFields(NULL, 0, &dummy_data, 0), isc::InvalidParameter); +} + +// Bogus input to getFieldSpec() +TEST_F(RdataFieldsTest, getFieldSpecWithBadFieldId) { + const RdataFields fields_in_a(in::A("192.0.2.1")); + EXPECT_THROW(fields_in_a.getFieldSpec(1), isc::OutOfRange); +} + +// Tests for unexpected methods in RdataFieldComposerTest. Confirm +// a call to these methods triggers an exception. Expected methods are +// tested via other tests above. +class DummyRdata : public Rdata { +public: + enum Mode { CLEAR, SKIP, TRIM }; + explicit DummyRdata(Mode mode) : mode_(mode) {} + DummyRdata(const DummyRdata& source) : Rdata(), mode_(source.mode_) {} + virtual ~DummyRdata() {} + virtual void toWire(AbstractMessageRenderer& renderer) const { + // call the unexpected method corresponding to the test mode. + // method parameters don't matter. + switch (mode_) { + case CLEAR: + renderer.clear(); + break; + case SKIP: + renderer.skip(2); + break; + case TRIM: + renderer.trim(2); + break; + } + } + + // These are defined only to make the compiler happy. We don't use them + // for the test. + virtual string toText() const { return (""); } + virtual void toWire(OutputBuffer&) const {} + virtual int compare(const Rdata&) const { return (0); } +private: + const int mode_; +}; + +TEST(RdataFieldComposerTest, unusedMethods) { + EXPECT_THROW(RdataFields(DummyRdata(DummyRdata::CLEAR)), isc::Unexpected); +} +} diff --git a/src/lib/dns/tests/rrclass_unittest.cc b/src/lib/dns/tests/rrclass_unittest.cc new file mode 100644 index 0000000..ae85f01 --- /dev/null +++ b/src/lib/dns/tests/rrclass_unittest.cc @@ -0,0 +1,174 @@ +// Copyright (C) 2010-2017 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <gtest/gtest.h> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rrclass.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +#include <boost/scoped_ptr.hpp> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using boost::scoped_ptr; +using isc::util::unittests::matchWireData; + +namespace { +class RRClassTest : public ::testing::Test { +protected: + RRClassTest() : obuffer(0) {} + + OutputBuffer obuffer; + MessageRenderer renderer; + + static RRClass rrclassFactoryFromWire(const char* datafile); + static const RRClass rrclass_1, rrclass_0x80, rrclass_0x800, + rrclass_0x8000, rrclass_max; + static const uint8_t wiredata[]; +}; + +const RRClass RRClassTest::rrclass_1(1); +const RRClass RRClassTest::rrclass_0x80(0x80); +const RRClass RRClassTest::rrclass_0x800(0x800); +const RRClass RRClassTest::rrclass_0x8000(0x8000); +const RRClass RRClassTest::rrclass_max(0xffff); +// This is wire-format data for the above sample RRClass rendered in the +// appearing order. +const uint8_t RRClassTest::wiredata[] = { 0x00, 0x01, 0x00, 0x80, 0x08, + 0x00, 0x80, 0x00, 0xff, 0xff }; + +RRClass +RRClassTest::rrclassFactoryFromWire(const char* datafile) { + std::vector<unsigned char> data; + UnitTestUtil::readWireData(datafile, data); + + InputBuffer buffer(&data[0], data.size()); + + return (RRClass(buffer)); +} + +TEST_F(RRClassTest, fromTextConstructor) { + EXPECT_EQ("IN", RRClass("IN").toText()); + EXPECT_EQ("CH", RRClass("CH").toText()); + + EXPECT_EQ("CLASS65535", RRClass("CLASS65535").toText()); + + // some uncommon cases: see the corresponding RRType tests. + EXPECT_EQ(53, RRClass("CLASS00053").getCode()); + EXPECT_THROW(RRClass("CLASS000053"), InvalidRRClass); + + // bogus CLASSnnn representations: should trigger an exception + EXPECT_THROW(RRClass("CLASS"), InvalidRRClass); + EXPECT_THROW(RRClass("CLASS-1"), InvalidRRClass); + EXPECT_THROW(RRClass("CLASSxxx"), InvalidRRClass); + EXPECT_THROW(RRClass("CLASS65536"), InvalidRRClass); + EXPECT_THROW(RRClass("CLASS6500x"), InvalidRRClass); + EXPECT_THROW(RRClass("CLASS65000 "), InvalidRRClass); +} + +TEST_F(RRClassTest, fromWire) { + EXPECT_EQ(0x1234, + rrclassFactoryFromWire("rrcode16_fromWire1").getCode()); + EXPECT_THROW(rrclassFactoryFromWire("rrcode16_fromWire2"), + IncompleteRRClass); +} + +TEST_F(RRClassTest, caseConstruct) { + EXPECT_EQ("IN", RRClass("in").toText()); + EXPECT_EQ("CH", RRClass("ch").toText()); + EXPECT_EQ("CLASS65535", RRClass("class65535").toText()); +} + +TEST_F(RRClassTest, toText) { + EXPECT_EQ("IN", RRClass(1).toText()); + EXPECT_EQ("CLASS65000", RRClass(65000).toText()); +} + +TEST_F(RRClassTest, createFromText) { + scoped_ptr<RRClass> chclass(RRClass::createFromText("CH")); + EXPECT_TRUE(chclass); + EXPECT_EQ("CH", chclass->toText()); + + scoped_ptr<RRClass> zzclass(RRClass::createFromText("ZZ")); + EXPECT_FALSE(zzclass); +} + +TEST_F(RRClassTest, toWireBuffer) { + rrclass_1.toWire(obuffer); + rrclass_0x80.toWire(obuffer); + rrclass_0x800.toWire(obuffer); + rrclass_0x8000.toWire(obuffer); + rrclass_max.toWire(obuffer); + + matchWireData(wiredata, sizeof (wiredata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(RRClassTest, toWireRenderer) { + rrclass_1.toWire(renderer); + rrclass_0x80.toWire(renderer); + rrclass_0x800.toWire(renderer); + rrclass_0x8000.toWire(renderer); + rrclass_max.toWire(renderer); + + matchWireData(wiredata, sizeof (wiredata), + renderer.getData(), renderer.getLength()); +} + +TEST_F(RRClassTest, wellKnownClass) { + EXPECT_EQ(1, RRClass::IN().getCode()); + EXPECT_EQ("IN", RRClass::IN().toText()); +} + +TEST_F(RRClassTest, compare) { + EXPECT_TRUE(RRClass(1) == RRClass("IN")); + EXPECT_TRUE(RRClass(1).equals(RRClass("IN"))); + EXPECT_TRUE(RRClass(0).nequals(RRClass("IN"))); + + EXPECT_TRUE(RRClass("IN") < RRClass("CH")); + EXPECT_TRUE(RRClass(100) < RRClass(65535)); +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST_F(RRClassTest, LeftShiftOperator) { + ostringstream oss; + oss << RRClass::IN(); + EXPECT_EQ(RRClass::IN().toText(), oss.str()); +} + +// Below, we'll check definitions for all well-known RR classes; whether they +// are defined and have the correct parameter values. Test data are generated +// from the list available at: +// http://www.iana.org/assignments/dns-parameters/dns-parameters.xml +struct ClassParam { + const char* const txt; // "IN", "CH", etc + const uint16_t code; // 1, 3, + const RRClass& (*obj)(); // RRClass::IN(), etc +} known_classes[] = { + {"IN", 1, RRClass::IN}, {"CH", 3, RRClass::CH}, {"HS", 4, RRClass::HS}, + {"NONE", 254, RRClass::NONE}, {"ANY", 255, RRClass::ANY}, + {NULL, 0, NULL} +}; + +TEST(RRClassConstTest, wellKnowns) { + for (int i = 0; known_classes[i].txt; ++i) { + SCOPED_TRACE("Checking well known RRClass: " + + string(known_classes[i].txt)); + EXPECT_EQ(known_classes[i].code, + RRClass(known_classes[i].txt).getCode()); + EXPECT_EQ(known_classes[i].code, + (*known_classes[i].obj)().getCode()); + } +} +} diff --git a/src/lib/dns/tests/rrcollator_unittest.cc b/src/lib/dns/tests/rrcollator_unittest.cc new file mode 100644 index 0000000..4247911 --- /dev/null +++ b/src/lib/dns/tests/rrcollator_unittest.cc @@ -0,0 +1,208 @@ +// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <exceptions/exceptions.h> + +#include <dns/name.h> +#include <dns/master_loader.h> +#include <dns/master_loader_callbacks.h> +#include <dns/rrclass.h> +#include <dns/rrcollator.h> +#include <dns/rdata.h> +#include <dns/rrset.h> +#include <dns/rrttl.h> + +#include <gtest/gtest.h> + +#include <functional> +#include <sstream> +#include <vector> + +using std::vector; +using namespace isc::dns; +using namespace isc::dns::rdata; +namespace ph = std::placeholders; + +namespace { + +typedef RRCollator::AddRRsetCallback AddRRsetCallback; + +void +addRRset(const RRsetPtr& rrset, vector<ConstRRsetPtr>* to_append, + const bool* do_throw) { + if (*do_throw) { + isc_throw(isc::Unexpected, "faked failure"); + } + to_append->push_back(rrset); +} + +class RRCollatorTest : public ::testing::Test { +protected: + RRCollatorTest() : + origin_("example.com"), rrclass_(RRClass::IN()), rrttl_(3600), + throw_from_callback_(false), + collator_(std::bind(addRRset, ph::_1, &rrsets_, &throw_from_callback_)), + rr_callback_(collator_.getCallback()), + a_rdata1_(createRdata(RRType::A(), rrclass_, "192.0.2.1")), + a_rdata2_(createRdata(RRType::A(), rrclass_, "192.0.2.2")), + txt_rdata_(createRdata(RRType::TXT(), rrclass_, "test")), + sig_rdata1_(createRdata(RRType::RRSIG(), rrclass_, + "A 5 3 3600 20000101000000 20000201000000 " + "12345 example.com. FAKE")), + sig_rdata2_(createRdata(RRType::RRSIG(), rrclass_, + "NS 5 3 3600 20000101000000 20000201000000 " + "12345 example.com. FAKE")) + {} + + void checkRRset(const Name& expected_name, const RRClass& expected_class, + const RRType& expected_type, const RRTTL& expected_ttl, + const vector<ConstRdataPtr>& expected_rdatas) { + SCOPED_TRACE(expected_name.toText(true) + "/" + + expected_class.toText() + "/" + expected_type.toText()); + + // This test always clears rrsets_ to confirm RRsets are added + // one-by-one + ASSERT_EQ(1, rrsets_.size()); + + ConstRRsetPtr actual = rrsets_[0]; + EXPECT_EQ(expected_name, actual->getName()); + EXPECT_EQ(expected_class, actual->getClass()); + EXPECT_EQ(expected_type, actual->getType()); + EXPECT_EQ(expected_ttl, actual->getTTL()); + ASSERT_EQ(expected_rdatas.size(), actual->getRdataCount()); + vector<ConstRdataPtr>::const_iterator it = expected_rdatas.begin(); + for (RdataIteratorPtr rit = actual->getRdataIterator(); + !rit->isLast(); + rit->next()) { + EXPECT_EQ(0, rit->getCurrent().compare(**it)); + ++it; + } + + rrsets_.clear(); + } + + const Name origin_; + const RRClass rrclass_; + const RRTTL rrttl_; + vector<ConstRRsetPtr> rrsets_; + bool throw_from_callback_; + RRCollator collator_; + AddRRCallback rr_callback_; + const RdataPtr a_rdata1_, a_rdata2_, txt_rdata_, sig_rdata1_, sig_rdata2_; + vector<ConstRdataPtr> rdatas_; // placeholder for expected data +}; + +TEST_F(RRCollatorTest, basicCases) { + // Add two RRs belonging to the same RRset. These will be buffered. + rr_callback_(origin_, rrclass_, RRType::A(), rrttl_, a_rdata1_); + EXPECT_TRUE(rrsets_.empty()); // not yet given as an RRset + rr_callback_(origin_, rrclass_, RRType::A(), rrttl_, a_rdata2_); + EXPECT_TRUE(rrsets_.empty()); // still not given + + // Add another type of RR. This completes the construction of the A RRset, + // which will be given via the callback. + rr_callback_(origin_, rrclass_, RRType::TXT(), rrttl_, txt_rdata_); + rdatas_.push_back(a_rdata1_); + rdatas_.push_back(a_rdata2_); + checkRRset(origin_, rrclass_, RRType::A(), rrttl_, rdatas_); + + // Add the same type of RR but of different name. This should make another + // callback for the previous TXT RR. + rr_callback_(Name("txt.example.com"), rrclass_, RRType::TXT(), rrttl_, + txt_rdata_); + rdatas_.clear(); + rdatas_.push_back(txt_rdata_); + checkRRset(origin_, rrclass_, RRType::TXT(), rrttl_, rdatas_); + + // Add the same type and name of RR but of different class (rare case + // in practice) + rr_callback_(Name("txt.example.com"), RRClass::CH(), RRType::TXT(), rrttl_, + txt_rdata_); + rdatas_.clear(); + rdatas_.push_back(txt_rdata_); + checkRRset(Name("txt.example.com"), rrclass_, RRType::TXT(), rrttl_, + rdatas_); + + // Tell the collator we are done, then we'll see the last RR as an RRset. + collator_.flush(); + checkRRset(Name("txt.example.com"), RRClass::CH(), RRType::TXT(), rrttl_, + rdatas_); + + // Redundant flush() will be no-op. + collator_.flush(); + EXPECT_TRUE(rrsets_.empty()); +} + +TEST_F(RRCollatorTest, minTTLFirst) { + // RRs of the same RRset but has different TTLs. The first RR has + // the smaller TTL, which should be used for the TTL of the RRset. + rr_callback_(origin_, rrclass_, RRType::A(), RRTTL(10), a_rdata1_); + rr_callback_(origin_, rrclass_, RRType::A(), RRTTL(20), a_rdata2_); + rdatas_.push_back(a_rdata1_); + rdatas_.push_back(a_rdata2_); + collator_.flush(); + checkRRset(origin_, rrclass_, RRType::A(), RRTTL(10), rdatas_); +} + +TEST_F(RRCollatorTest, maxTTLFirst) { + // RRs of the same RRset but has different TTLs. The second RR has + // the smaller TTL, which should be used for the TTL of the RRset. + rr_callback_(origin_, rrclass_, RRType::A(), RRTTL(20), a_rdata1_); + rr_callback_(origin_, rrclass_, RRType::A(), RRTTL(10), a_rdata2_); + rdatas_.push_back(a_rdata1_); + rdatas_.push_back(a_rdata2_); + collator_.flush(); + checkRRset(origin_, rrclass_, RRType::A(), RRTTL(10), rdatas_); +} + +TEST_F(RRCollatorTest, addRRSIGs) { + // RRSIG is special; they are also distinguished by their covered types. + rr_callback_(origin_, rrclass_, RRType::RRSIG(), rrttl_, sig_rdata1_); + rr_callback_(origin_, rrclass_, RRType::RRSIG(), rrttl_, sig_rdata2_); + + rdatas_.push_back(sig_rdata1_); + checkRRset(origin_, rrclass_, RRType::RRSIG(), rrttl_, rdatas_); +} + +TEST_F(RRCollatorTest, emptyFlush) { + collator_.flush(); + EXPECT_TRUE(rrsets_.empty()); +} + +TEST_F(RRCollatorTest, throwFromCallback) { + // Adding an A RR + rr_callback_(origin_, rrclass_, RRType::A(), rrttl_, a_rdata1_); + + // Adding a TXT RR, which would trigger RRset callback, but in this test + // it throws. The added TXT RR will be effectively lost. + throw_from_callback_ = true; + EXPECT_THROW(rr_callback_(origin_, rrclass_, RRType::TXT(), rrttl_, + txt_rdata_), isc::Unexpected); + + // We'll only see the A RR. + throw_from_callback_ = false; + collator_.flush(); + rdatas_.push_back(a_rdata1_); + checkRRset(origin_, rrclass_, RRType::A(), rrttl_, rdatas_); +} + +TEST_F(RRCollatorTest, withMasterLoader) { + // Test a simple case with MasterLoader. There shouldn't be anything + // special, but that's the mainly intended usage of the collator, so we + // check it explicitly. + std::istringstream ss("example.com. 3600 IN A 192.0.2.1\n"); + MasterLoader loader(ss, origin_, rrclass_, + MasterLoaderCallbacks::getNullCallbacks(), + collator_.getCallback()); + loader.load(); + collator_.flush(); + rdatas_.push_back(a_rdata1_); + checkRRset(origin_, rrclass_, RRType::A(), rrttl_, rdatas_); +} + +} diff --git a/src/lib/dns/tests/rrparamregistry_unittest.cc b/src/lib/dns/tests/rrparamregistry_unittest.cc new file mode 100644 index 0000000..90574d0 --- /dev/null +++ b/src/lib/dns/tests/rrparamregistry_unittest.cc @@ -0,0 +1,185 @@ +// Copyright (C) 2010-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> +#include <sstream> + +#include <stdint.h> + +#include <gtest/gtest.h> + +#include <dns/rrclass.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrparamregistry.h> +#include <dns/rrtype.h> +#include <dns/master_loader.h> + +#include <boost/scoped_ptr.hpp> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; + +namespace { +class RRParamRegistryTest : public ::testing::Test { +protected: + RRParamRegistryTest() + { + ostringstream oss1; + oss1 << test_class_code; + // cppcheck-suppress useInitializationList + test_class_unknown_str = "CLASS" + oss1.str(); + + ostringstream oss2; + oss2 << test_type_code; + test_type_unknown_str = "TYPE" + oss2.str(); + } + ~RRParamRegistryTest() + { + // cleanup any non well-known parameters that possibly remain + // as a side effect. + RRParamRegistry::getRegistry().removeType(test_type_code); + RRParamRegistry::getRegistry().removeClass(test_class_code); + RRParamRegistry::getRegistry().removeRdataFactory( + RRType(test_type_code), RRClass(test_class_code)); + RRParamRegistry::getRegistry().removeRdataFactory( + RRType(test_type_code)); + } + + string test_class_unknown_str; + string test_type_unknown_str; + + // we assume class/type numbers are officially unassigned. If not we'll + // need to update the test cases. + static const uint16_t test_class_code = 65533; + static const uint16_t test_type_code = 65534; + static const string test_class_str; + static const string test_type_str; +}; + +const string RRParamRegistryTest::test_class_str("TESTCLASS"); +const string RRParamRegistryTest::test_type_str("TESTTYPE"); + +TEST_F(RRParamRegistryTest, addRemove) { + RRParamRegistry::getRegistry().addType(test_type_str, test_type_code); + RRParamRegistry::getRegistry().addClass(test_class_str, test_class_code); + EXPECT_EQ(65533, RRClass("TESTCLASS").getCode()); + EXPECT_EQ(65534, RRType("TESTTYPE").getCode()); + + // the first removal attempt should succeed + EXPECT_TRUE(RRParamRegistry::getRegistry().removeType(test_type_code)); + // then toText() should treat it as an "unknown" + EXPECT_EQ(test_type_unknown_str, RRType(test_type_code).toText()); + // attempt of removing non-existent mapping should result in 'false' + EXPECT_FALSE(RRParamRegistry::getRegistry().removeType(test_type_code)); + + // same set of tests for RR class. + EXPECT_TRUE(RRParamRegistry::getRegistry().removeClass(test_class_code)); + EXPECT_EQ(test_class_unknown_str, RRClass(test_class_code).toText()); + EXPECT_FALSE(RRParamRegistry::getRegistry().removeClass(test_class_code)); +} + +TEST_F(RRParamRegistryTest, addError) { + // An attempt to override a pre-registered class should fail with an + // exception, and the pre-registered one should remain in the registry. + EXPECT_THROW(RRParamRegistry::getRegistry().addClass(test_class_str, 1), + RRClassExists); + EXPECT_EQ("IN", RRClass(1).toText()); + + // Same for RRType + EXPECT_THROW(RRParamRegistry::getRegistry().addType(test_type_str, 1), + RRTypeExists); + EXPECT_EQ("A", RRType(1).toText()); +} + +class TestRdataFactory : public AbstractRdataFactory { +public: + virtual RdataPtr create(const string& rdata_str) const + { return (RdataPtr(new in::A(rdata_str))); } + virtual RdataPtr create(InputBuffer& buffer, size_t rdata_len) const + { return (RdataPtr(new in::A(buffer, rdata_len))); } + virtual RdataPtr create(const Rdata& source) const + { return (RdataPtr(new in::A(dynamic_cast<const in::A&>(source)))); } + virtual RdataPtr create(MasterLexer& lexer, const Name* origin, + MasterLoader::Options options, + MasterLoaderCallbacks& callbacks) const + { return (RdataPtr(new in::A(lexer, origin, options, callbacks))); } +}; + +TEST_F(RRParamRegistryTest, addRemoveFactory) { + // By default, the test type/code pair should be considered "unknown", + // so the following should trigger an exception. + EXPECT_THROW(createRdata(RRType(test_type_code), RRClass(test_class_code), + "192.0.2.1"), + InvalidRdataText); + // Add factories so that we can treat this pair just like in::A. + RRParamRegistry::getRegistry().add(test_type_str, test_type_code, + test_class_str, test_class_code, + RdataFactoryPtr(new TestRdataFactory)); + // Now it should be accepted, and should be identical to the same data of + // in::A. + EXPECT_EQ(0, in::A("192.0.2.1").compare( + *createRdata(RRType(test_type_code), RRClass(test_class_code), + "192.0.2.1"))); + // It should still fail with other classes as we specified the factories + // as class-specific. + EXPECT_THROW(createRdata(RRType(test_type_code), RRClass("IN"), + "192.0.2.1"), + InvalidRdataText); + // Add the factories also as a class independent RRtype + RRParamRegistry::getRegistry().add(test_type_str, test_type_code, + RdataFactoryPtr(new TestRdataFactory)); + // Now it should be okay for other classes than the test class. + EXPECT_EQ(0, in::A("192.0.2.1").compare( + *createRdata(RRType(test_type_code), RRClass("IN"), + "192.0.2.1"))); + + // Remove the added factories: first attempt should succeed; the second + // should return false as there's no match + EXPECT_TRUE(RRParamRegistry::getRegistry().removeRdataFactory( + RRType(test_type_code), RRClass(test_class_code))); + EXPECT_FALSE(RRParamRegistry::getRegistry().removeRdataFactory( + RRType(test_type_code), RRClass(test_class_code))); + EXPECT_TRUE(RRParamRegistry::getRegistry().removeRdataFactory( + RRType(test_type_code))); + EXPECT_FALSE(RRParamRegistry::getRegistry().removeRdataFactory( + RRType(test_type_code))); +} + +RdataPtr +createRdataHelper(const std::string& str) { + boost::scoped_ptr<AbstractRdataFactory> rdf(new TestRdataFactory); + + std::stringstream ss(str); + MasterLexer lexer; + lexer.pushSource(ss); + + MasterLoaderCallbacks callbacks(MasterLoaderCallbacks::getNullCallbacks()); + const Name origin("example.org."); + + return (rdf->create(lexer, &origin, + MasterLoader::MANY_ERRORS, + callbacks)); +} + +TEST_F(RRParamRegistryTest, createFromLexer) { + // This test basically checks that the string version of + // AbstractRdataFactory::create() is called by the MasterLexer + // variant of create(). + EXPECT_EQ(0, in::A("192.168.0.1").compare( + *createRdataHelper("192.168.0.1"))); + + // This should parse only up to the end of line. Everything that + // comes afterwards is not parsed. + EXPECT_EQ(0, in::A("192.168.0.42").compare( + *createRdataHelper("192.168.0.42\na b c d e f"))); +} + +} diff --git a/src/lib/dns/tests/rrset_collection_unittest.cc b/src/lib/dns/tests/rrset_collection_unittest.cc new file mode 100644 index 0000000..be16ab5 --- /dev/null +++ b/src/lib/dns/tests/rrset_collection_unittest.cc @@ -0,0 +1,240 @@ +// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/rrset_collection.h> +#include <dns/rrttl.h> +#include <dns/rdataclass.h> + +#include <gtest/gtest.h> + +#include <list> +#include <fstream> + +using namespace isc::dns; +using namespace isc::dns::rdata; +using namespace std; + +namespace { + +class RRsetCollectionTest : public ::testing::Test { +public: + RRsetCollectionTest() : + rrclass("IN"), + origin("example.org"), + collection(TEST_DATA_SRCDIR "/example.org", origin, rrclass) + {} + + const RRClass rrclass; + const Name origin; + RRsetCollection collection; +}; + +TEST_F(RRsetCollectionTest, istreamConstructor) { + std::ifstream fs(TEST_DATA_SRCDIR "/example.org"); + RRsetCollection collection2(fs, origin, rrclass); + + RRsetCollectionBase::Iterator iter = collection.begin(); + RRsetCollectionBase::Iterator iter2 = collection2.begin(); + while (iter != collection.end()) { + ASSERT_TRUE(iter2 != collection2.end()); + EXPECT_EQ((*iter).toText(), (*iter2).toText()); + ++iter; + ++iter2; + } + ASSERT_TRUE(iter2 == collection2.end()); +} + +template <typename T, typename TP> +void doFind(T& collection, const RRClass& rrclass) { + // Test the find() that returns ConstRRsetPtr + TP rrset = collection.find(Name("www.example.org"), rrclass, RRType::A()); + EXPECT_TRUE(rrset); + EXPECT_EQ(RRType::A(), rrset->getType()); + EXPECT_EQ(RRTTL(3600), rrset->getTTL()); + EXPECT_EQ(RRClass("IN"), rrset->getClass()); + EXPECT_EQ(Name("www.example.org"), rrset->getName()); + + // foo.example.org doesn't exist + rrset = collection.find(Name("foo.example.org"), rrclass, RRType::A()); + EXPECT_FALSE(rrset); + + // www.example.org exists, but not with MX + rrset = collection.find(Name("www.example.org"), rrclass, RRType::MX()); + EXPECT_FALSE(rrset); + + // www.example.org exists, with AAAA + rrset = collection.find(Name("www.example.org"), rrclass, RRType::AAAA()); + EXPECT_TRUE(rrset); + + // www.example.org with AAAA does not exist in RRClass::CH() + rrset = collection.find(Name("www.example.org"), RRClass::CH(), + RRType::AAAA()); + EXPECT_FALSE(rrset); +} + +TEST_F(RRsetCollectionTest, findConst) { + // Test the find() that returns ConstRRsetPtr + const RRsetCollection& ccln = collection; + doFind<const RRsetCollection, ConstRRsetPtr>(ccln, rrclass); +} + +TEST_F(RRsetCollectionTest, find) { + // Test the find() that returns RRsetPtr + doFind<RRsetCollection, RRsetPtr>(collection, rrclass); +} + +void +doAddAndRemove(RRsetCollection& collection, const RRClass& rrclass) { + // foo.example.org/A doesn't exist + RRsetPtr rrset_found = collection.find(Name("foo.example.org"), rrclass, + RRType::A()); + EXPECT_FALSE(rrset_found); + + // Add foo.example.org/A + RRsetPtr rrset(new BasicRRset(Name("foo.example.org"), rrclass, RRType::A(), + RRTTL(7200))); + rrset->addRdata(in::A("192.0.2.1")); + collection.addRRset(rrset); + + // foo.example.org/A should now exist + rrset_found = collection.find(Name("foo.example.org"), rrclass, + RRType::A()); + EXPECT_TRUE(rrset_found); + EXPECT_EQ(RRType::A(), rrset_found->getType()); + EXPECT_EQ(RRTTL(7200), rrset_found->getTTL()); + EXPECT_EQ(RRClass("IN"), rrset_found->getClass()); + EXPECT_EQ(Name("foo.example.org"), rrset_found->getName()); + + // The collection must not be empty. + EXPECT_TRUE(collection.end() != collection.begin()); + + // Adding a duplicate RRset must throw. + EXPECT_THROW({ + collection.addRRset(rrset); + }, isc::InvalidParameter); + + // Remove foo.example.org/A, which should pass + EXPECT_TRUE(collection.removeRRset(Name("foo.example.org"), + rrclass, RRType::A())); + // foo.example.org/A should not exist now + rrset_found = collection.find(Name("foo.example.org"), rrclass, + RRType::A()); + EXPECT_FALSE(rrset_found); + + // Removing foo.example.org/A should fail now + EXPECT_FALSE(collection.removeRRset(Name("foo.example.org"), + rrclass, RRType::A())); +} + +TEST_F(RRsetCollectionTest, addAndRemove) { + doAddAndRemove(collection, rrclass); +} + +TEST_F(RRsetCollectionTest, empty) { + RRsetCollection cln; + + // Here, cln is empty. + EXPECT_TRUE(cln.end() == cln.begin()); + + doAddAndRemove(cln, rrclass); + + // cln should be empty again here, after the add and remove + // operations. + EXPECT_TRUE(cln.end() == cln.begin()); +} + +TEST_F(RRsetCollectionTest, iteratorTest) { + // The collection must not be empty. + EXPECT_TRUE(collection.end() != collection.begin()); + + // Here, we just count the records and do some basic tests on them. + size_t count = 0; + for (RRsetCollection::Iterator it = collection.begin(); + it != collection.end(); ++it) { + ++count; + const AbstractRRset& rrset = *it; + EXPECT_EQ(rrclass, rrset.getClass()); + EXPECT_EQ(RRTTL(3600), rrset.getTTL()); + } + + // example.org master file has SOA, NS, A, AAAA + EXPECT_EQ(4, count); +} + +// This is a dummy class which is used in iteratorCompareDifferent test +// to compare iterators from different RRsetCollectionBase +// implementations. +class MyRRsetCollection : public RRsetCollectionBase { +public: + MyRRsetCollection() + {} + + virtual isc::dns::ConstRRsetPtr find(const isc::dns::Name&, + const isc::dns::RRClass&, + const isc::dns::RRType&) const { + return (ConstRRsetPtr()); + } + + typedef std::list<isc::dns::RRset> MyCollection; + +protected: + class MyIter : public RRsetCollectionBase::Iter { + public: + MyIter(MyCollection::iterator& iter) : + iter_(iter) + {} + + virtual const isc::dns::AbstractRRset& getValue() { + return (*iter_); + } + + virtual IterPtr getNext() { + MyCollection::iterator it = iter_; + ++it; + return (RRsetCollectionBase::IterPtr(new MyIter(it))); + } + + virtual bool equals(Iter& other) { + const MyIter* other_real = dynamic_cast<MyIter*>(&other); + if (other_real == NULL) { + return (false); + } + return (iter_ == other_real->iter_); + } + + private: + MyCollection::iterator iter_; + }; + + virtual RRsetCollectionBase::IterPtr getBeginning() { + MyCollection::iterator it = dummy_list_.begin(); + return (RRsetCollectionBase::IterPtr(new MyIter(it))); + } + + virtual RRsetCollectionBase::IterPtr getEnd() { + MyCollection::iterator it = dummy_list_.end(); + return (RRsetCollectionBase::IterPtr(new MyIter(it))); + } + +private: + MyCollection dummy_list_; +}; + +TEST_F(RRsetCollectionTest, iteratorCompareDifferent) { + // Create objects of two different RRsetCollectionBase + // implementations. + RRsetCollection cln1; + MyRRsetCollection cln2; + + // Comparing two iterators from different RRsetCollectionBase + // implementations must not throw. + EXPECT_TRUE(cln2.begin() != cln1.begin()); + EXPECT_TRUE(cln1.end() != cln2.end()); +} + +} // namespace diff --git a/src/lib/dns/tests/rrset_unittest.cc b/src/lib/dns/tests/rrset_unittest.cc new file mode 100644 index 0000000..0425812 --- /dev/null +++ b/src/lib/dns/tests/rrset_unittest.cc @@ -0,0 +1,442 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/name.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> +#include <dns/rrttl.h> +#include <dns/rrset.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +#include <gtest/gtest.h> + +#include <stdexcept> +#include <sstream> + +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class RRsetTest : public ::testing::Test { +protected: + RRsetTest() : buffer(0), + test_name("test.example.com"), + test_domain("example.com"), + test_nsname("ns.example.com"), + rrset_a(test_name, RRClass::IN(), RRType::A(), RRTTL(3600)), + rrset_a_empty(test_name, RRClass::IN(), RRType::A(), + RRTTL(3600)), + rrset_any_a_empty(test_name, RRClass::ANY(), RRType::A(), + RRTTL(3600)), + rrset_none_a_empty(test_name, RRClass::NONE(), RRType::A(), + RRTTL(3600)), + rrset_ns(test_domain, RRClass::IN(), RRType::NS(), + RRTTL(86400)), + rrset_ch_txt(test_domain, RRClass::CH(), RRType::TXT(), + RRTTL(0)) + { + rrset_a.addRdata(in::A("192.0.2.1")); + rrset_a.addRdata(in::A("192.0.2.2")); + } + + OutputBuffer buffer; + MessageRenderer renderer; + Name test_name; + Name test_domain; + Name test_nsname; + RRset rrset_a; + RRset rrset_a_empty; + RRset rrset_any_a_empty; + RRset rrset_none_a_empty; + RRset rrset_ns; + RRset rrset_ch_txt; + std::vector<unsigned char> wiredata; + + // max number of Rdata objects added to a test RRset object. + // this is an arbitrary chosen limit, but should be sufficiently large + // in practice and reasonable even as an extreme test case. + static const int MAX_RDATA_COUNT = 100; +}; + +TEST_F(RRsetTest, getRdataCount) { + for (int i = 0; i < MAX_RDATA_COUNT; ++i) { + EXPECT_EQ(i, rrset_a_empty.getRdataCount()); + rrset_a_empty.addRdata(in::A("192.0.2.1")); + } +} + +TEST_F(RRsetTest, getName) { + EXPECT_EQ(test_name, rrset_a.getName()); + EXPECT_EQ(test_domain, rrset_ns.getName()); +} + +TEST_F(RRsetTest, getClass) { + EXPECT_EQ(RRClass("IN"), rrset_a.getClass()); + EXPECT_EQ(RRClass("CH"), rrset_ch_txt.getClass()); +} + +TEST_F(RRsetTest, getType) { + EXPECT_EQ(RRType("A"), rrset_a.getType()); + EXPECT_EQ(RRType("NS"), rrset_ns.getType()); + EXPECT_EQ(RRType("TXT"), rrset_ch_txt.getType()); +} + +TEST_F(RRsetTest, getTTL) { + EXPECT_EQ(RRTTL(3600), rrset_a.getTTL()); + EXPECT_EQ(RRTTL(86400), rrset_ns.getTTL()); + EXPECT_EQ(RRTTL(0), rrset_ch_txt.getTTL()); +} + +TEST_F(RRsetTest, setTTL) { + rrset_a.setTTL(RRTTL(86400)); + EXPECT_EQ(RRTTL(86400), rrset_a.getTTL()); + rrset_a.setTTL(RRTTL(0)); + EXPECT_EQ(RRTTL(0), rrset_a.getTTL()); +} + +TEST_F(RRsetTest, isSameKind) { + RRset rrset_w(test_name, RRClass::IN(), RRType::A(), RRTTL(3600)); + RRset rrset_x(test_name, RRClass::IN(), RRType::A(), RRTTL(3600)); + RRset rrset_y(test_name, RRClass::IN(), RRType::NS(), RRTTL(3600)); + RRset rrset_z(test_name, RRClass::CH(), RRType::A(), RRTTL(3600)); + RRset rrset_p(test_nsname, RRClass::IN(), RRType::A(), RRTTL(3600)); + + EXPECT_TRUE(rrset_w.isSameKind(rrset_w)); + EXPECT_TRUE(rrset_w.isSameKind(rrset_x)); + EXPECT_FALSE(rrset_w.isSameKind(rrset_y)); + EXPECT_FALSE(rrset_w.isSameKind(rrset_z)); + EXPECT_FALSE(rrset_w.isSameKind(rrset_p)); +} + +void +addRdataTestCommon(const RRset& rrset) { + ASSERT_EQ(2, rrset.getRdataCount()); + + RdataIteratorPtr it = rrset.getRdataIterator(); // cursor is set to the 1st + EXPECT_FALSE(it->isLast()); + EXPECT_EQ(0, it->getCurrent().compare(in::A("192.0.2.1"))); + it->next(); + EXPECT_FALSE(it->isLast()); + EXPECT_EQ(0, it->getCurrent().compare(in::A("192.0.2.2"))); + it->next(); + EXPECT_TRUE(it->isLast()); +} + +TEST_F(RRsetTest, addRdata) { + addRdataTestCommon(rrset_a); + + // Reference version of addRdata() doesn't allow to add a different + // type of Rdata. + EXPECT_THROW(rrset_a.addRdata(generic::NS(test_nsname)), std::bad_cast); +} + +TEST_F(RRsetTest, addRdataPtr) { + rrset_a_empty.addRdata(createRdata(rrset_a_empty.getType(), + rrset_a_empty.getClass(), + "192.0.2.1")); + rrset_a_empty.addRdata(createRdata(rrset_a_empty.getType(), + rrset_a_empty.getClass(), + "192.0.2.2")); + addRdataTestCommon(rrset_a_empty); +} + +TEST_F(RRsetTest, addRdataPtrMismatched) { + // Pointer version of addRdata() doesn't type check and does allow to + //add a different type of Rdata as a result. + + // Type mismatch + rrset_a_empty.addRdata(createRdata(RRType::NS(), RRClass::IN(), + "ns.example.com.")); + EXPECT_EQ(1, rrset_a_empty.getRdataCount()); + + // Class mismatch + rrset_ch_txt.addRdata(createRdata(RRType::TXT(), RRClass::IN(), + "Test String")); + EXPECT_EQ(1, rrset_ch_txt.getRdataCount()); +} + +TEST_F(RRsetTest, addRdataString) { + rrset_a_empty.addRdata("192.0.2.1"); + rrset_a_empty.addRdata("192.0.2.2"); + + addRdataTestCommon(rrset_a_empty); + + // String version of addRdata() will throw for bad RDATA for + // RRType::A(). + EXPECT_THROW(rrset_a_empty.addRdata("ns.example.com."), InvalidRdataText); + addRdataTestCommon(rrset_a_empty); +} + +TEST_F(RRsetTest, iterator) { + // Iterator for an empty RRset. + RdataIteratorPtr it = rrset_a_empty.getRdataIterator(); + EXPECT_TRUE(it->isLast()); + + // Normal case (already tested, but do it again just in case) + rrset_a_empty.addRdata(in::A("192.0.2.1")); + rrset_a_empty.addRdata(in::A("192.0.2.2")); + addRdataTestCommon(rrset_a_empty); + + // Rewind test: should be repeat the iteration by calling first(). + for (int i = 0; i < 2; ++i) { + it = rrset_a_empty.getRdataIterator(); + it->first(); + EXPECT_FALSE(it->isLast()); + it->next(); + EXPECT_FALSE(it->isLast()); + it->next(); + EXPECT_TRUE(it->isLast()); + } +} + +TEST_F(RRsetTest, toText) { + EXPECT_EQ("test.example.com. 3600 IN A 192.0.2.1\n" + "test.example.com. 3600 IN A 192.0.2.2\n", + rrset_a.toText()); + + // toText() cannot be performed for an empty RRset + EXPECT_THROW(rrset_a_empty.toText(), EmptyRRset); + + // Unless it is type ANY or NONE + EXPECT_EQ("test.example.com. 3600 ANY A\n", + rrset_any_a_empty.toText()); + EXPECT_EQ("test.example.com. 3600 NONE A\n", + rrset_none_a_empty.toText()); +} + +TEST_F(RRsetTest, getLength) { + // Empty RRset should throw + EXPECT_THROW(rrset_a_empty.getLength(), EmptyRRset); + + // Unless it is type ANY or NONE: + // test.example.com = 1 + 4 + 1 + 7 + 1 + 3 + 1 = 18 octets + // TYPE field = 2 octets + // CLASS field = 2 octets + // TTL field = 4 octets + // RDLENGTH field = 2 octets + // Total = 18 + 2 + 2 + 4 + 2 = 28 octets + EXPECT_EQ(28, rrset_any_a_empty.getLength()); + EXPECT_EQ(28, rrset_none_a_empty.getLength()); + + // RRset with single RDATA + // 28 (above) + 4 octets (A RDATA) = 32 octets + rrset_a_empty.addRdata(in::A("192.0.2.1")); + EXPECT_EQ(32, rrset_a_empty.getLength()); + + // 2 A RRs + rrset_a_empty.addRdata(in::A("192.0.2.2")); + EXPECT_EQ(32 + 32, rrset_a_empty.getLength()); +} + +TEST_F(RRsetTest, toWireBuffer) { + rrset_a.toWire(buffer); + + UnitTestUtil::readWireData("rrset_toWire1", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + buffer.getData(), buffer.getLength()); + + // toWire() cannot be performed for an empty RRset except when + // class=ANY or class=NONE. + buffer.clear(); + EXPECT_THROW(rrset_a_empty.toWire(buffer), EmptyRRset); + + // When class=ANY or class=NONE, toWire() can also be performed for + // an empty RRset. + buffer.clear(); + rrset_any_a_empty.toWire(buffer); + wiredata.clear(); + UnitTestUtil::readWireData("rrset_toWire3", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + buffer.getData(), buffer.getLength()); + + buffer.clear(); + rrset_none_a_empty.toWire(buffer); + wiredata.clear(); + UnitTestUtil::readWireData("rrset_toWire4", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + buffer.getData(), buffer.getLength()); +} + +TEST_F(RRsetTest, toWireRenderer) { + rrset_ns.addRdata(generic::NS(test_nsname)); + + rrset_a.toWire(renderer); + rrset_ns.toWire(renderer); + + UnitTestUtil::readWireData("rrset_toWire2", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + renderer.getData(), renderer.getLength()); + + // toWire() cannot be performed for an empty RRset except when + // class=ANY or class=NONE. + renderer.clear(); + EXPECT_THROW(rrset_a_empty.toWire(renderer), EmptyRRset); + + // When class=ANY or class=NONE, toWire() can also be performed for + // an empty RRset. + renderer.clear(); + rrset_any_a_empty.toWire(renderer); + wiredata.clear(); + UnitTestUtil::readWireData("rrset_toWire3", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + renderer.getData(), renderer.getLength()); + + renderer.clear(); + rrset_none_a_empty.toWire(renderer); + wiredata.clear(); + UnitTestUtil::readWireData("rrset_toWire4", wiredata); + matchWireData(&wiredata[0], wiredata.size(), + renderer.getData(), renderer.getLength()); +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST_F(RRsetTest, LeftShiftOperator) { + ostringstream oss; + oss << rrset_a; + EXPECT_EQ(rrset_a.toText(), oss.str()); +} + +class RRsetRRSIGTest : public ::testing::Test { +protected: + RRsetRRSIGTest() : test_name("test.example.com") + { + rrset_a = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::A(), RRTTL(3600))); + rrset_a->addRdata(in::A("192.0.2.1")); + rrset_a->addRdata(in::A("192.0.2.2")); + + rrset_aaaa = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::AAAA(), RRTTL(3600))); + rrset_aaaa->addRdata(in::AAAA("2001:db8::1234")); + + rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::RRSIG(), RRTTL(3600))); + rrset_rrsig->addRdata(generic::RRSIG("AAAA 5 3 7200 20100322084538 " + "20100220084538 1 example.com. " + "FAKEFAKEFAKEFAKE")); + rrset_aaaa->addRRsig(rrset_rrsig); + } + + const Name test_name; + RRsetPtr rrset_a; // A RRset with two RDATAs + RRsetPtr rrset_aaaa; // AAAA RRset with one RDATA with RRSIG + RRsetPtr rrset_rrsig; // RRSIG for the AAAA RRset +}; + +TEST_F(RRsetRRSIGTest, getRRsig) { + RRsetPtr sp = rrset_a->getRRsig(); + EXPECT_EQ(static_cast<void*>(NULL), sp.get()); + + sp = rrset_aaaa->getRRsig(); + EXPECT_NE(static_cast<void*>(NULL), sp.get()); +} + +TEST_F(RRsetRRSIGTest, addRRsig) { + RRsetPtr sp = rrset_a->getRRsig(); + EXPECT_EQ(static_cast<void*>(NULL), sp.get()); + + rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::RRSIG(), RRTTL(3600))); + // one signature algorithm (5 = RSA/SHA-1) + rrset_rrsig->addRdata(generic::RRSIG("A 5 3 3600 " + "20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE")); + // another signature algorithm (3 = DSA/SHA-1) + rrset_rrsig->addRdata(generic::RRSIG("A 3 3 3600 " + "20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE")); + rrset_a->addRRsig(rrset_rrsig); + + sp = rrset_a->getRRsig(); + EXPECT_NE(static_cast<void*>(NULL), sp.get()); + EXPECT_EQ(2, sp->getRdataCount()); + + // add to existing RRSIG + rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::RRSIG(), RRTTL(3600))); + // another signature algorithm (4 = ECC) + rrset_rrsig->addRdata(generic::RRSIG("A 4 3 3600 " + "20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE")); + rrset_a->addRRsig(rrset_rrsig); + EXPECT_EQ(3, sp->getRdataCount()); +} + +TEST_F(RRsetRRSIGTest, getRRsigDataCount) { + EXPECT_EQ(1, rrset_aaaa->getRRsigDataCount()); + EXPECT_EQ(0, rrset_a->getRRsigDataCount()); + + rrset_rrsig = RRsetPtr(new RRset(test_name, RRClass::IN(), + RRType::RRSIG(), RRTTL(3600))); + // one signature algorithm (5 = RSA/SHA-1) + rrset_rrsig->addRdata(generic::RRSIG("A 5 3 3600 " + "20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE")); + // another signature algorithm (3 = DSA/SHA-1) + rrset_rrsig->addRdata(generic::RRSIG("A 3 3 3600 " + "20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE")); + rrset_a->addRRsig(rrset_rrsig); + EXPECT_EQ(2, rrset_a->getRRsigDataCount()); + + rrset_a->removeRRsig(); + EXPECT_EQ(0, rrset_a->getRRsigDataCount()); +} + +TEST_F(RRsetRRSIGTest, toText) { + // toText() should also return the associated RRSIG. + EXPECT_EQ("test.example.com. 3600 IN AAAA 2001:db8::1234\n" + "test.example.com. 3600 IN RRSIG AAAA 5 3 7200 " + "20100322084538 20100220084538 1 example.com. FAKEFAKEFAKEFAKE\n", + rrset_aaaa->toText()); +} + +TEST_F(RRsetRRSIGTest, getLength) { + // A RR + // test.example.com = 1 + 4 + 1 + 7 + 1 + 3 + 1 = 18 octets + // TYPE field = 2 octets + // CLASS field = 2 octets + // TTL field = 4 octets + // RDLENGTH field = 2 octets + // A RDATA = 4 octets + // Total = 18 + 2 + 2 + 4 + 2 + 4 = 32 octets + + // 2 A RRs + EXPECT_EQ(32 + 32, rrset_a->getLength()); + + // RRSIG + // test.example.com = 1 + 4 + 1 + 7 + 1 + 3 + 1 = 18 octets + // TYPE field = 2 octets + // CLASS field = 2 octets + // TTL field = 4 octets + // RDLENGTH field = 2 octets + // RRSIG RDATA = 40 octets + // Total = 18 + 2 + 2 + 4 + 2 + 40 = 68 octets + RRsetPtr my_rrsig(new RRset(test_name, RRClass::IN(), + RRType::RRSIG(), RRTTL(3600))); + my_rrsig->addRdata(generic::RRSIG("A 4 3 3600 " + "20000101000000 20000201000000 " + "12345 example.com. FAKEFAKEFAKE")); + EXPECT_EQ(68, my_rrsig->getLength()); + + // RRset with attached RRSIG + rrset_a->addRRsig(my_rrsig); + + EXPECT_EQ(32 + 32 + 68, rrset_a->getLength()); +} +} diff --git a/src/lib/dns/tests/rrttl_unittest.cc b/src/lib/dns/tests/rrttl_unittest.cc new file mode 100644 index 0000000..3cada14 --- /dev/null +++ b/src/lib/dns/tests/rrttl_unittest.cc @@ -0,0 +1,279 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <gtest/gtest.h> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rrttl.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +#include <boost/scoped_ptr.hpp> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using boost::scoped_ptr; +using isc::util::unittests::matchWireData; + +namespace { +class RRTTLTest : public ::testing::Test { +protected: + RRTTLTest() : obuffer(0) {} + + OutputBuffer obuffer; + MessageRenderer renderer; + + static RRTTL rrttlFactoryFromWire(const char* datafile); + static const RRTTL ttl_0, ttl_1h, ttl_1d, ttl_32bit, ttl_max; + static const RRTTL ttl_small, ttl_large; + static const uint8_t wiredata[20]; +}; + +const RRTTL RRTTLTest::ttl_0(0); +const RRTTL RRTTLTest::ttl_1h(3600); +const RRTTL RRTTLTest::ttl_1d(86400); +const RRTTL RRTTLTest::ttl_32bit(0x12345678); +const RRTTL RRTTLTest::ttl_max(0xffffffff); + +const RRTTL RRTTLTest::ttl_small(1); +const RRTTL RRTTLTest::ttl_large(0x80000001); +// This is wire-format data for the above sample RRTTLs rendered in the +// appearing order. +const uint8_t RRTTLTest::wiredata[20] = { 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x10, + 0x00, 0x01, 0x51, 0x80, + 0x12, 0x34, 0x56, 0x78, + 0xff, 0xff, 0xff, 0xff }; + +RRTTL +RRTTLTest::rrttlFactoryFromWire(const char* datafile) { + std::vector<unsigned char> data; + UnitTestUtil::readWireData(datafile, data); + + InputBuffer buffer(&data[0], data.size()); + + return (RRTTL(buffer)); +} + +TEST_F(RRTTLTest, getValue) { + EXPECT_EQ(0, ttl_0.getValue()); + EXPECT_EQ(3600, ttl_1h.getValue()); + EXPECT_EQ(86400, ttl_1d.getValue()); + EXPECT_EQ(0x12345678, ttl_32bit.getValue()); + EXPECT_EQ(0xffffffff, ttl_max.getValue()); +} + +TEST_F(RRTTLTest, copyConstruct) { + const RRTTL ttl1(3600); + const RRTTL ttl2(ttl1); + EXPECT_EQ(ttl1.getValue(), ttl2.getValue()); +} + +TEST_F(RRTTLTest, fromText) { + // Border cases + EXPECT_EQ(0, RRTTL("0").getValue()); + EXPECT_EQ(4294967295U, RRTTL("4294967295").getValue()); + + // Invalid cases + EXPECT_THROW(RRTTL("0xdeadbeef"), InvalidRRTTL); // must be decimal + EXPECT_THROW(RRTTL("-1"), InvalidRRTTL); // must be positive + EXPECT_THROW(RRTTL("1.1"), InvalidRRTTL); // must be integer + EXPECT_THROW(RRTTL("4294967296"), InvalidRRTTL); // must be 32-bit +} + +TEST_F(RRTTLTest, createFromText) { + // It returns an actual RRTTL iff the given text is recognized as a + // valid RR TTL. + scoped_ptr<RRTTL> good_ttl(RRTTL::createFromText("3600")); + EXPECT_TRUE(good_ttl); + EXPECT_EQ(RRTTL(3600), *good_ttl); + + scoped_ptr<RRTTL> bad_ttl(RRTTL::createFromText("bad")); + EXPECT_FALSE(bad_ttl); +} + +void +checkUnit(unsigned multiply, char suffix) { + SCOPED_TRACE(string("Unit check with suffix ") + suffix); + const uint32_t value = 10 * multiply; + const string num = "10"; + // Check both lower and upper version of the suffix + EXPECT_EQ(value, + RRTTL(num + static_cast<char>(tolower(suffix))).getValue()); + EXPECT_EQ(value, + RRTTL(num + static_cast<char>(toupper(suffix))).getValue()); +} + +// Check parsing the unit form (1D, etc) +TEST_F(RRTTLTest, fromTextUnit) { + // Check each of the units separately + checkUnit(1, 'S'); + checkUnit(60, 'M'); + checkUnit(60 * 60, 'H'); + checkUnit(24 * 60 * 60, 'D'); + checkUnit(7 * 24 * 60 * 60, 'W'); + + // Some border cases (with units) + EXPECT_EQ(4294967295U, RRTTL("4294967295S").getValue()); + EXPECT_EQ(0, RRTTL("0W0D0H0M0S").getValue()); + EXPECT_EQ(4294967295U, RRTTL("1193046H1695S").getValue()); + // Leading zeroes are accepted + EXPECT_EQ(4294967295U, RRTTL("0000000000000004294967295S").getValue()); + + // Now some compound ones. We allow any order (it would be much work to + // check the order anyway). + EXPECT_EQ(60 * 60 + 3, RRTTL("1H3S").getValue()); + + // Awkward, but allowed case - the same unit used twice. + EXPECT_EQ(20 * 3600, RRTTL("12H8H").getValue()); + + // Negative number in part of the expression, but the total is positive. + // Rejected. + EXPECT_THROW(RRTTL("-1S1H"), InvalidRRTTL); + + // Some things out of range in the ttl, but it wraps to number in range + // in int64_t. Should still not get fooled and reject it. + + // First part out of range + EXPECT_THROW(RRTTL("9223372036854775807S9223372036854775807S2S"), + InvalidRRTTL); + // Second part out of range, but it immediately wraps (2S+2^64-2S) + EXPECT_THROW(RRTTL("2S18446744073709551614S"), InvalidRRTTL); + // The whole thing wraps right away (2^64S) + EXPECT_THROW(RRTTL("18446744073709551616S"), InvalidRRTTL); + // Second part out of range, and will become negative with the unit, + EXPECT_THROW(RRTTL("256S307445734561825856M"), InvalidRRTTL); + + // Missing before unit. + EXPECT_THROW(RRTTL("W5H"), InvalidRRTTL); + EXPECT_THROW(RRTTL("5hW"), InvalidRRTTL); + + // Empty string is not allowed + EXPECT_THROW(RRTTL(""), InvalidRRTTL); + // Missing the last unit is not allowed + EXPECT_THROW(RRTTL("3D5"), InvalidRRTTL); + + // There are some wrong units + EXPECT_THROW(RRTTL("13X"), InvalidRRTTL); + EXPECT_THROW(RRTTL("3D5F"), InvalidRRTTL); +} + +TEST_F(RRTTLTest, fromWire) { + EXPECT_EQ(0x12345678, + rrttlFactoryFromWire("rrcode32_fromWire1").getValue()); + EXPECT_THROW(rrttlFactoryFromWire("rrcode32_fromWire2"), + IncompleteRRTTL); +} + +TEST_F(RRTTLTest, toText) { + EXPECT_EQ("0", ttl_0.toText()); + EXPECT_EQ("3600", ttl_1h.toText()); + EXPECT_EQ("86400", ttl_1d.toText()); + EXPECT_EQ("305419896", ttl_32bit.toText()); + EXPECT_EQ("4294967295", ttl_max.toText()); +} + +TEST_F(RRTTLTest, toWireBuffer) { + ttl_0.toWire(obuffer); + ttl_1h.toWire(obuffer); + ttl_1d.toWire(obuffer); + ttl_32bit.toWire(obuffer); + ttl_max.toWire(obuffer); + + matchWireData(wiredata, sizeof(wiredata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(RRTTLTest, toWireRenderer) { + ttl_0.toWire(renderer); + ttl_1h.toWire(renderer); + ttl_1d.toWire(renderer); + ttl_32bit.toWire(renderer); + ttl_max.toWire(renderer); + + matchWireData(wiredata, sizeof(wiredata), + renderer.getData(), renderer.getLength()); +} + +TEST_F(RRTTLTest, equal) { + EXPECT_TRUE(RRTTL("3600") == ttl_1h); + EXPECT_TRUE(RRTTL("86400").equals(ttl_1d)); + + EXPECT_TRUE(ttl_1d != ttl_1h); + EXPECT_TRUE(ttl_1d.nequals(ttl_max)); +} + +// +// The following set of tests confirm the result of <=, <, >=, > +// The test logic is simple, and all tests are just straightforward variations +// of the first one. +// +TEST_F(RRTTLTest, leq) { + // small <= large is true + EXPECT_TRUE(ttl_small.leq(ttl_large)); + EXPECT_TRUE(ttl_small <= ttl_large); + + // small <= small is true + EXPECT_TRUE(ttl_small.leq(ttl_small)); + EXPECT_LE(ttl_small, ttl_small); + + // large <= small is false + EXPECT_FALSE(ttl_large.leq(ttl_small)); + EXPECT_FALSE(ttl_large <= ttl_small); +} + +TEST_F(RRTTLTest, geq) { + EXPECT_TRUE(ttl_large.geq(ttl_small)); + EXPECT_TRUE(ttl_large >= ttl_small); + + EXPECT_TRUE(ttl_large.geq(ttl_large)); + EXPECT_GE(ttl_large, ttl_large); + + EXPECT_FALSE(ttl_small.geq(ttl_large)); + EXPECT_FALSE(ttl_small >= ttl_large); +} + +TEST_F(RRTTLTest, lthan) { + EXPECT_TRUE(ttl_small.lthan(ttl_large)); + EXPECT_TRUE(ttl_small < ttl_large); + + EXPECT_FALSE(ttl_small.lthan(ttl_small)); + // cppcheck-suppress duplicateExpression + EXPECT_FALSE(ttl_small < ttl_small); + + EXPECT_FALSE(ttl_large.lthan(ttl_small)); + EXPECT_FALSE(ttl_large < ttl_small); +} + +TEST_F(RRTTLTest, gthan) { + EXPECT_TRUE(ttl_large.gthan(ttl_small)); + EXPECT_TRUE(ttl_large > ttl_small); + + EXPECT_FALSE(ttl_large.gthan(ttl_large)); + // cppcheck-suppress duplicateExpression + EXPECT_FALSE(ttl_large > ttl_large); + + EXPECT_FALSE(ttl_small.gthan(ttl_large)); + EXPECT_FALSE(ttl_small > ttl_large); +} + +TEST_F(RRTTLTest, maxTTL) { + EXPECT_EQ((1u << 31) - 1, RRTTL::MAX_TTL().getValue()); +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST_F(RRTTLTest, LeftShiftOperator) { + ostringstream oss; + oss << ttl_1h; + EXPECT_EQ(ttl_1h.toText(), oss.str()); +} +} diff --git a/src/lib/dns/tests/rrtype_unittest.cc b/src/lib/dns/tests/rrtype_unittest.cc new file mode 100644 index 0000000..a2f8ba5 --- /dev/null +++ b/src/lib/dns/tests/rrtype_unittest.cc @@ -0,0 +1,195 @@ +// Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <gtest/gtest.h> + +#include <util/buffer.h> +#include <dns/messagerenderer.h> +#include <dns/rrtype.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using isc::util::unittests::matchWireData; + +namespace { +class RRTypeTest : public ::testing::Test { +protected: + RRTypeTest() : obuffer(0) {} + + OutputBuffer obuffer; + MessageRenderer renderer; + + static RRType rrtypeFactoryFromWire(const char* datafile); + static const RRType rrtype_1, rrtype_0x80, rrtype_0x800, rrtype_0x8000, + rrtype_max; + static const uint8_t wiredata[]; +}; + +const RRType RRTypeTest::rrtype_1(1); +const RRType RRTypeTest::rrtype_0x80(0x80); +const RRType RRTypeTest::rrtype_0x800(0x800); +const RRType RRTypeTest::rrtype_0x8000(0x8000); +const RRType RRTypeTest::rrtype_max(0xffff); +// This is wire-format data for the above sample RRTypes rendered in the +// appearing order. +const uint8_t RRTypeTest::wiredata[] = { 0x00, 0x01, 0x00, 0x80, 0x08, + 0x00, 0x80, 0x00, 0xff, 0xff }; + +RRType +RRTypeTest::rrtypeFactoryFromWire(const char* datafile) { + std::vector<unsigned char> data; + UnitTestUtil::readWireData(datafile, data); + + InputBuffer buffer(&data[0], data.size()); + + return (RRType(buffer)); +} + +TEST_F(RRTypeTest, fromText) { + EXPECT_EQ("A", RRType("A").toText()); + EXPECT_EQ("NS", RRType("NS").toText()); + + EXPECT_EQ("TYPE65535", RRType("TYPE65535").toText()); + + // something unusual, but existing implementations accept this form, + // so do we. + EXPECT_EQ(53, RRType("TYPE00053").getCode()); + // again, unusual, and the majority of other implementations reject it. + // In any case, there should be no reasonable reason to accept such a + // ridiculously long input. + EXPECT_THROW(RRType("TYPE000053"), InvalidRRType); + + // bogus TYPEnnn representations: should trigger an exception + EXPECT_THROW(RRType("TYPE"), InvalidRRType); + EXPECT_THROW(RRType("TYPE-1"), InvalidRRType); + EXPECT_THROW(RRType("TYPExxx"), InvalidRRType); + EXPECT_THROW(RRType("TYPE65536"), InvalidRRType); + EXPECT_THROW(RRType("TYPE6500x"), InvalidRRType); + EXPECT_THROW(RRType("TYPE65000 "), InvalidRRType); +} + +TEST_F(RRTypeTest, fromWire) { + EXPECT_EQ(0x1234, + rrtypeFactoryFromWire("rrcode16_fromWire1").getCode()); + EXPECT_THROW(rrtypeFactoryFromWire("rrcode16_fromWire2"), IncompleteRRType); +} + +// from string, lower case +TEST_F(RRTypeTest, caseConstruct) { + EXPECT_EQ("A", RRType("a").toText()); + EXPECT_EQ("NS", RRType("ns").toText()); + EXPECT_EQ("TYPE65535", RRType("type65535").toText()); +} + +TEST_F(RRTypeTest, toText) { + EXPECT_EQ("A", RRType(1).toText()); + EXPECT_EQ("TYPE65000", RRType(65000).toText()); +} + +TEST_F(RRTypeTest, toWireBuffer) { + rrtype_1.toWire(obuffer); + rrtype_0x80.toWire(obuffer); + rrtype_0x800.toWire(obuffer); + rrtype_0x8000.toWire(obuffer); + rrtype_max.toWire(obuffer); + + matchWireData(wiredata, sizeof(wiredata), + obuffer.getData(), obuffer.getLength()); +} + +TEST_F(RRTypeTest, toWireRenderer) { + rrtype_1.toWire(renderer); + rrtype_0x80.toWire(renderer); + rrtype_0x800.toWire(renderer); + rrtype_0x8000.toWire(renderer); + rrtype_max.toWire(renderer); + + matchWireData(wiredata, sizeof(wiredata), + renderer.getData(), renderer.getLength()); +} + +TEST_F(RRTypeTest, wellKnownTypes) { + EXPECT_EQ(1, RRType::A().getCode()); + EXPECT_EQ("A", RRType::A().toText()); +} + +TEST_F(RRTypeTest, compare) { + EXPECT_TRUE(RRType(1) == RRType("A")); + EXPECT_TRUE(RRType(1).equals(RRType("A"))); + EXPECT_TRUE(RRType(0) != RRType("A")); + EXPECT_TRUE(RRType(0).nequals(RRType("A"))); + + EXPECT_TRUE(RRType("A") < RRType("NS")); + EXPECT_TRUE(RRType(100) < RRType(65535)); +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST_F(RRTypeTest, LeftShiftOperator) { + ostringstream oss; + oss << RRType::A(); + EXPECT_EQ(RRType::A().toText(), oss.str()); +} + +// Below, we'll check definitions for all well-known RR types; whether they +// are defined and have the correct parameter values. Test data are generated +// from the list available at: +// http://www.iana.org/assignments/dns-parameters/dns-parameters.xml +struct TypeParam { + const char* const txt; // "A", "AAAA", "NS", etc + const uint16_t code; // 1, 28, 2, etc + const RRType& (*obj)(); // RRType::A(), etc +} known_types[] = { + {"A", 1, RRType::A}, {"NS", 2, RRType::NS}, {"MD", 3, RRType::MD}, + {"MF", 4, RRType::MF}, {"CNAME", 5, RRType::CNAME}, + {"SOA", 6, RRType::SOA}, {"MB", 7, RRType::MB}, {"MG", 8, RRType::MG}, + {"MR", 9, RRType::MR}, {"NULL", 10, RRType::Null}, + {"WKS", 11, RRType::WKS}, {"PTR", 12, RRType::PTR}, + {"HINFO", 13, RRType::HINFO}, {"MINFO", 14, RRType::MINFO}, + {"MX", 15, RRType::MX}, {"TXT", 16, RRType::TXT}, {"RP", 17, RRType::RP}, + {"AFSDB", 18, RRType::AFSDB}, {"X25", 19, RRType::X25}, + {"ISDN", 20, RRType::ISDN}, {"RT", 21, RRType::RT}, + {"NSAP", 22, RRType::NSAP}, {"NSAP-PTR", 23, RRType::NSAP_PTR}, + {"SIG", 24, RRType::SIG}, {"KEY", 25, RRType::KEY}, + {"PX", 26, RRType::PX}, {"GPOS", 27, RRType::GPOS}, + {"AAAA", 28, RRType::AAAA}, {"LOC", 29, RRType::LOC}, + {"NXT", 30, RRType::NXT}, {"SRV", 33, RRType::SRV}, + {"NAPTR", 35, RRType::NAPTR}, {"KX", 36, RRType::KX}, + {"CERT", 37, RRType::CERT}, {"A6", 38, RRType::A6}, + {"DNAME", 39, RRType::DNAME}, {"OPT", 41, RRType::OPT}, + {"APL", 42, RRType::APL}, {"DS", 43, RRType::DS}, + {"SSHFP", 44, RRType::SSHFP}, {"IPSECKEY", 45, RRType::IPSECKEY}, + {"RRSIG", 46, RRType::RRSIG}, {"NSEC", 47, RRType::NSEC}, + {"DNSKEY", 48, RRType::DNSKEY}, {"DHCID", 49, RRType::DHCID}, + {"NSEC3", 50, RRType::NSEC3}, {"NSEC3PARAM", 51, RRType::NSEC3PARAM}, + {"TLSA", 52, RRType::TLSA}, {"HIP", 55, RRType::HIP}, + {"SPF", 99, RRType::SPF}, {"UNSPEC", 103, RRType::UNSPEC}, + {"NID", 104, RRType::NID}, {"L32", 105, RRType::L32}, + {"L64", 106, RRType::L64}, {"LP", 107, RRType::LP}, + {"TKEY", 249, RRType::TKEY}, {"TSIG", 250, RRType::TSIG}, + {"IXFR", 251, RRType::IXFR}, {"AXFR", 252, RRType::AXFR}, + {"MAILB", 253, RRType::MAILB}, {"MAILA", 254, RRType::MAILA}, + {"ANY", 255, RRType::ANY}, {"URI", 256, RRType::URI}, + {"CAA", 257, RRType::CAA}, {"DLV", 32769, RRType::DLV}, + {NULL, 0, NULL} +}; + +TEST(RRTypeConstTest, wellKnowns) { + for (int i = 0; known_types[i].txt; ++i) { + SCOPED_TRACE("Checking well known RRType: " + + string(known_types[i].txt)); + EXPECT_EQ(known_types[i].code, RRType(known_types[i].txt).getCode()); + EXPECT_EQ(known_types[i].code, + (*known_types[i].obj)().getCode()); + } +} +} diff --git a/src/lib/dns/tests/run_unittests.cc b/src/lib/dns/tests/run_unittests.cc new file mode 100644 index 0000000..de396fa --- /dev/null +++ b/src/lib/dns/tests/run_unittests.cc @@ -0,0 +1,24 @@ +// Copyright (C) 2009-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <gtest/gtest.h> +#include <util/unittests/run_all.h> + +#include <util/unittests/testdata.h> +#include <dns/tests/unittest_util.h> + +int +main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + isc::UnitTestUtil::addDataPath(TEST_DATA_SRCDIR); + isc::util::unittests::addTestDataPath(TEST_DATA_SRCDIR); + isc::UnitTestUtil::addDataPath(TEST_DATA_BUILDDIR); + isc::util::unittests::addTestDataPath(TEST_DATA_BUILDDIR); + + return (isc::util::unittests::run_all()); +} diff --git a/src/lib/dns/tests/serial_unittest.cc b/src/lib/dns/tests/serial_unittest.cc new file mode 100644 index 0000000..305b0b0 --- /dev/null +++ b/src/lib/dns/tests/serial_unittest.cc @@ -0,0 +1,173 @@ +// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <gtest/gtest.h> + +#include <dns/serial.h> + +using namespace isc::dns; + +class SerialTest : public ::testing::Test { +public: + SerialTest() : one(1), one_2(1), two(2), + date_zero(1980120100), date_one(1980120101), + min(0), max(4294967295u), + number_low(12345), + number_medium(2000000000), + number_high(4000000000u) + {} + Serial one, one_2, two, date_zero, date_one, min, max, number_low, number_medium, number_high; +}; + +// +// Basic tests +// + +TEST_F(SerialTest, get_value) { + EXPECT_EQ(1, one.getValue()); + EXPECT_NE(2, one.getValue()); + EXPECT_EQ(2, two.getValue()); + EXPECT_EQ(1980120100, date_zero.getValue()); + EXPECT_EQ(1980120101, date_one.getValue()); + EXPECT_EQ(0, min.getValue()); + EXPECT_EQ(4294967295u, max.getValue()); + EXPECT_EQ(12345, number_low.getValue()); + EXPECT_EQ(2000000000, number_medium.getValue()); + EXPECT_EQ(4000000000u, number_high.getValue()); +} + +TEST_F(SerialTest, equals) { + EXPECT_EQ(one, one); + EXPECT_EQ(one, one_2); + EXPECT_NE(one, two); + EXPECT_NE(two, one); + EXPECT_EQ(Serial(12345), number_low); + EXPECT_NE(Serial(12346), number_low); +} + +TEST_F(SerialTest, comparison) { + // These should be true/false even without serial arithmetic + EXPECT_LE(one, one); + EXPECT_LE(one, one_2); + EXPECT_LT(one, two); + EXPECT_LE(one, two); + EXPECT_GE(two, two); + EXPECT_GT(two, one); + EXPECT_GE(two, one); + EXPECT_LT(one, number_low); + EXPECT_LT(number_low, number_medium); + EXPECT_LT(number_medium, number_high); + + // now let's try some that 'wrap', as it were + EXPECT_GT(min, max); + EXPECT_LT(max, min); + EXPECT_LT(number_high, number_low); +} + +// +// RFC 1982 Section 3.1 +// +TEST_F(SerialTest, addition) { + EXPECT_EQ(two, one + one); + EXPECT_EQ(two, one + one_2); + EXPECT_EQ(max, max + min); + EXPECT_EQ(min, max + one); + EXPECT_EQ(one, max + two); + EXPECT_EQ(one, max + one + one); + + EXPECT_EQ(one + 100, max + 102); + EXPECT_EQ(min + 2147483645, max + 2147483646); + EXPECT_EQ(min + 2147483646, max + MAX_SERIAL_INCREMENT); +} + +// +// RFC 1982 Section 3.2 has been checked by the basic tests above +// + +// +// RFC 1982 Section 4.1 +// + +// Helper function for addition_always_larger test, add some numbers +// and check that the result is always larger than the original +void do_addition_larger_test(const Serial& number) { + EXPECT_GE(number + 0, number); + EXPECT_EQ(number + 0, number); + EXPECT_GT(number + 1, number); + EXPECT_GT(number + 2, number); + EXPECT_GT(number + 100, number); + EXPECT_GT(number + 1111111, number); + EXPECT_GT(number + 2147483646, number); + EXPECT_GT(number + MAX_SERIAL_INCREMENT, number); + // Try MAX_SERIAL_INCREMENT as a hardcoded number as well + EXPECT_GT(number + 2147483647, number); +} + +TEST_F(SerialTest, addition_always_larger) { + do_addition_larger_test(one); + do_addition_larger_test(two); + do_addition_larger_test(date_zero); + do_addition_larger_test(date_one); + do_addition_larger_test(min); + do_addition_larger_test(max); + do_addition_larger_test(number_low); + do_addition_larger_test(number_medium); + do_addition_larger_test(number_high); +} + +// +// RFC 1982 Section 4.2 +// + +// Helper function to do the second addition +void +do_two_additions_test_second(const Serial &original, + const Serial &number) +{ + EXPECT_NE(original, number); + EXPECT_NE(original, number + 0); + EXPECT_NE(original, number + 1); + EXPECT_NE(original, number + 2); + EXPECT_NE(original, number + 100); + EXPECT_NE(original, number + 1111111); + EXPECT_NE(original, number + 2147483646); + EXPECT_NE(original, number + MAX_SERIAL_INCREMENT); + EXPECT_NE(original, number + 2147483647); +} + +void do_two_additions_test_first(const Serial &number) { + do_two_additions_test_second(number, number + 1); + do_two_additions_test_second(number, number + 2); + do_two_additions_test_second(number, number + 100); + do_two_additions_test_second(number, number + 1111111); + do_two_additions_test_second(number, number + 2147483646); + do_two_additions_test_second(number, number + MAX_SERIAL_INCREMENT); + do_two_additions_test_second(number, number + 2147483647); +} + +TEST_F(SerialTest, two_additions_never_equal) { + do_two_additions_test_first(one); + do_two_additions_test_first(two); + do_two_additions_test_first(date_zero); + do_two_additions_test_first(date_one); + do_two_additions_test_first(min); + do_two_additions_test_first(max); + do_two_additions_test_first(number_low); + do_two_additions_test_first(number_medium); + do_two_additions_test_first(number_high); +} + +// +// RFC 1982 Section 4.3 and 4.4 have nothing to test +// + +// +// Tests from RFC 1982 examples +// +TEST(SerialTextRFCExamples, rfc_example_tests) { +} diff --git a/src/lib/dns/tests/testdata/Makefile.am b/src/lib/dns/tests/testdata/Makefile.am new file mode 100644 index 0000000..e5c8081 --- /dev/null +++ b/src/lib/dns/tests/testdata/Makefile.am @@ -0,0 +1,219 @@ +CLEANFILES = + +# NOTE: keep this in sync with real file listing +# so is included in tarball +EXTRA_DIST = edns_toWire1.spec edns_toWire2.spec +EXTRA_DIST += edns_toWire3.spec edns_toWire4.spec +EXTRA_DIST += masterload.txt +EXTRA_DIST += message_fromWire1 message_fromWire2 +EXTRA_DIST += message_fromWire3 message_fromWire4 +EXTRA_DIST += message_fromWire5 message_fromWire6 +EXTRA_DIST += message_fromWire7 message_fromWire8 +EXTRA_DIST += message_fromWire9 message_fromWire10.spec +EXTRA_DIST += message_fromWire11.spec message_fromWire12.spec +EXTRA_DIST += message_fromWire13.spec message_fromWire14.spec +EXTRA_DIST += message_fromWire15.spec message_fromWire16.spec +EXTRA_DIST += message_fromWire17.spec message_fromWire18.spec +EXTRA_DIST += message_fromWire19.spec message_fromWire20.spec +EXTRA_DIST += message_fromWire21.spec message_fromWire22.spec +EXTRA_DIST += message_toWire1 message_toWire2.spec message_toWire3.spec +EXTRA_DIST += message_toWire4.spec message_toWire5.spec +EXTRA_DIST += message_toWire6 message_toWire7 +EXTRA_DIST += message_toText1.txt message_toText1.spec +EXTRA_DIST += message_toText2.txt message_toText2.spec +EXTRA_DIST += message_toText3.txt message_toText3.spec +EXTRA_DIST += name_fromWire1 name_fromWire2 name_fromWire3_1 name_fromWire3_2 +EXTRA_DIST += name_fromWire4 name_fromWire6 name_fromWire7 name_fromWire8 +EXTRA_DIST += name_fromWire9 name_fromWire10 name_fromWire11 name_fromWire12 +EXTRA_DIST += name_fromWire13 name_fromWire14 +EXTRA_DIST += name_toWire1 name_toWire2 name_toWire3 name_toWire4 +EXTRA_DIST += name_toWire5.spec name_toWire6.spec +EXTRA_DIST += name_toWire7 name_toWire8 name_toWire9 +EXTRA_DIST += question_fromWire question_toWire1 question_toWire2 +EXTRA_DIST += rdatafields1.spec rdatafields2.spec rdatafields3.spec +EXTRA_DIST += rdatafields4.spec rdatafields5.spec rdatafields6.spec +EXTRA_DIST += rdata_cname_fromWire rdata_dname_fromWire +EXTRA_DIST += rdata_dnskey_fromWire.spec rdata_dnskey_empty_keydata_fromWire.spec +EXTRA_DIST += rdata_dhcid_fromWire rdata_dhcid_toWire +EXTRA_DIST += rdata_ds_fromWire rdata_in_a_fromWire rdata_in_aaaa_fromWire +EXTRA_DIST += rdata_mx_fromWire rdata_mx_toWire1 rdata_mx_toWire2 +EXTRA_DIST += rdata_ns_fromWire +EXTRA_DIST += rdata_nsec_fromWire1 rdata_nsec_fromWire2 rdata_nsec_fromWire3 +EXTRA_DIST += rdata_nsec_fromWire4.spec rdata_nsec_fromWire5.spec +EXTRA_DIST += rdata_nsec_fromWire6.spec rdata_nsec_fromWire7.spec +EXTRA_DIST += rdata_nsec_fromWire8.spec rdata_nsec_fromWire9.spec +EXTRA_DIST += rdata_nsec_fromWire10.spec +EXTRA_DIST += rdata_nsec_fromWire16.spec +EXTRA_DIST += rdata_nsec3param_fromWire1 +EXTRA_DIST += rdata_nsec3param_fromWire2.spec +EXTRA_DIST += rdata_nsec3param_fromWire11.spec +EXTRA_DIST += rdata_nsec3param_fromWire13.spec +EXTRA_DIST += rdata_nsec3_fromWire1 rdata_nsec3_fromWire1.spec +EXTRA_DIST += rdata_nsec3_fromWire2.spec rdata_nsec3_fromWire3 +EXTRA_DIST += rdata_nsec3_fromWire4.spec rdata_nsec3_fromWire5.spec +EXTRA_DIST += rdata_nsec3_fromWire6.spec rdata_nsec3_fromWire7.spec +EXTRA_DIST += rdata_nsec3_fromWire8.spec rdata_nsec3_fromWire9.spec +EXTRA_DIST += rdata_nsec3_fromWire10.spec rdata_nsec3_fromWire11.spec +EXTRA_DIST += rdata_nsec3_fromWire12.spec rdata_nsec3_fromWire13.spec +EXTRA_DIST += rdata_nsec3_fromWire14.spec rdata_nsec3_fromWire15.spec +EXTRA_DIST += rdata_nsec3_fromWire16.spec rdata_nsec3_fromWire17.spec +EXTRA_DIST += rdata_opt_fromWire1 rdata_opt_fromWire2 +EXTRA_DIST += rdata_opt_fromWire3 rdata_opt_fromWire4 +EXTRA_DIST += rdata_rrsig_fromWire1 +EXTRA_DIST += rdata_rrsig_fromWire2.spec +EXTRA_DIST += rdata_rp_fromWire1.spec rdata_rp_fromWire2.spec +EXTRA_DIST += rdata_rp_fromWire3.spec rdata_rp_fromWire4.spec +EXTRA_DIST += rdata_rp_fromWire5.spec rdata_rp_fromWire6.spec +EXTRA_DIST += rdata_rp_toWire1.spec rdata_rp_toWire2.spec +EXTRA_DIST += rdata_sshfp_fromWire rdata_sshfp_fromWire2 +EXTRA_DIST += rdata_sshfp_fromWire1.spec rdata_sshfp_fromWire2.spec +EXTRA_DIST += rdata_sshfp_fromWire3.spec rdata_sshfp_fromWire4.spec +EXTRA_DIST += rdata_sshfp_fromWire5.spec rdata_sshfp_fromWire6.spec +EXTRA_DIST += rdata_sshfp_fromWire7.spec rdata_sshfp_fromWire8.spec +EXTRA_DIST += rdata_sshfp_fromWire9 rdata_sshfp_fromWire10 +EXTRA_DIST += rdata_sshfp_fromWire11 rdata_sshfp_fromWire12 +EXTRA_DIST += rdata_afsdb_fromWire1.spec rdata_afsdb_fromWire2.spec +EXTRA_DIST += rdata_afsdb_fromWire3.spec rdata_afsdb_fromWire4.spec +EXTRA_DIST += rdata_afsdb_fromWire5.spec +EXTRA_DIST += rdata_afsdb_toWire1.spec rdata_afsdb_toWire2.spec +EXTRA_DIST += rdata_soa_fromWire rdata_soa_toWireUncompressed.spec +EXTRA_DIST += rdata_srv_fromWire +EXTRA_DIST += rdata_minfo_fromWire1.spec rdata_minfo_fromWire2.spec +EXTRA_DIST += rdata_minfo_fromWire3.spec rdata_minfo_fromWire4.spec +EXTRA_DIST += rdata_minfo_fromWire5.spec rdata_minfo_fromWire6.spec +EXTRA_DIST += rdata_minfo_toWire1.spec rdata_minfo_toWire2.spec +EXTRA_DIST += rdata_minfo_toWireUncompressed1.spec +EXTRA_DIST += rdata_minfo_toWireUncompressed2.spec +EXTRA_DIST += rdata_txt_fromWire1 rdata_txt_fromWire2.spec +EXTRA_DIST += rdata_txt_fromWire3.spec rdata_txt_fromWire4.spec +EXTRA_DIST += rdata_txt_fromWire5.spec rdata_unknown_fromWire +EXTRA_DIST += rrcode16_fromWire1 rrcode16_fromWire2 +EXTRA_DIST += rrcode32_fromWire1 rrcode32_fromWire2 +EXTRA_DIST += rrset_toWire1 rrset_toWire2 +EXTRA_DIST += rrset_toWire3 rrset_toWire4 +EXTRA_DIST += rdata_tkey_fromWire1.spec rdata_tkey_fromWire2.spec +EXTRA_DIST += rdata_tkey_fromWire3.spec rdata_tkey_fromWire4.spec +EXTRA_DIST += rdata_tkey_fromWire5.spec rdata_tkey_fromWire6.spec +EXTRA_DIST += rdata_tkey_fromWire7.spec rdata_tkey_fromWire8.spec +EXTRA_DIST += rdata_tkey_fromWire9.spec +EXTRA_DIST += rdata_tkey_toWire1.spec rdata_tkey_toWire2.spec +EXTRA_DIST += rdata_tkey_toWire3.spec rdata_tkey_toWire4.spec +EXTRA_DIST += rdata_tkey_toWire5.spec +EXTRA_DIST += rdata_tlsa_fromWire rdata_tlsa_fromWire2 +EXTRA_DIST += rdata_tlsa_fromWire3.spec rdata_tlsa_fromWire4.spec +EXTRA_DIST += rdata_tlsa_fromWire5.spec rdata_tlsa_fromWire6.spec +EXTRA_DIST += rdata_tlsa_fromWire7.spec rdata_tlsa_fromWire8.spec +EXTRA_DIST += rdata_tlsa_fromWire9 rdata_tlsa_fromWire10 +EXTRA_DIST += rdata_tlsa_fromWire11 rdata_tlsa_fromWire12 +EXTRA_DIST += rdata_tsig_fromWire1.spec rdata_tsig_fromWire2.spec +EXTRA_DIST += rdata_tsig_fromWire3.spec rdata_tsig_fromWire4.spec +EXTRA_DIST += rdata_tsig_fromWire5.spec rdata_tsig_fromWire6.spec +EXTRA_DIST += rdata_tsig_fromWire7.spec rdata_tsig_fromWire8.spec +EXTRA_DIST += rdata_tsig_fromWire9.spec +EXTRA_DIST += rdata_tsig_toWire1.spec rdata_tsig_toWire2.spec +EXTRA_DIST += rdata_tsig_toWire3.spec rdata_tsig_toWire4.spec +EXTRA_DIST += rdata_tsig_toWire5.spec +EXTRA_DIST += rdata_caa_fromWire1.spec rdata_caa_fromWire2.spec +EXTRA_DIST += rdata_caa_fromWire3.spec rdata_caa_fromWire4.spec +EXTRA_DIST += rdata_caa_fromWire5 rdata_caa_fromWire6 +EXTRA_DIST += tsigrecord_toWire1.spec tsigrecord_toWire2.spec +EXTRA_DIST += tsig_verify1.spec tsig_verify2.spec tsig_verify3.spec +EXTRA_DIST += tsig_verify4.spec tsig_verify5.spec tsig_verify6.spec +EXTRA_DIST += tsig_verify7.spec tsig_verify8.spec tsig_verify9.spec +EXTRA_DIST += tsig_verify10.spec tsig_verify11.spec +EXTRA_DIST += example.org +EXTRA_DIST += broken.zone +EXTRA_DIST += origincheck.txt +EXTRA_DIST += omitcheck.txt + +# Generated .wire files +EXTRA_DIST += edns_toWire1.wire edns_toWire2.wire +EXTRA_DIST += edns_toWire3.wire edns_toWire4.wire +EXTRA_DIST += message_fromWire10.wire +EXTRA_DIST += message_fromWire11.wire message_fromWire12.wire +EXTRA_DIST += message_fromWire13.wire message_fromWire14.wire +EXTRA_DIST += message_fromWire15.wire message_fromWire16.wire +EXTRA_DIST += message_fromWire17.wire message_fromWire18.wire +EXTRA_DIST += message_fromWire19.wire message_fromWire20.wire +EXTRA_DIST += message_fromWire21.wire message_fromWire22.wire +EXTRA_DIST += message_toWire1 message_toWire2.wire message_toWire3.wire +EXTRA_DIST += message_toWire4.wire message_toWire5.wire +EXTRA_DIST += message_toText1.txt message_toText1.wire +EXTRA_DIST += message_toText2.txt message_toText2.wire +EXTRA_DIST += message_toText3.txt message_toText3.wire +EXTRA_DIST += name_toWire5.wire name_toWire6.wire +EXTRA_DIST += rdatafields1.wire rdatafields2.wire rdatafields3.wire +EXTRA_DIST += rdatafields4.wire rdatafields5.wire rdatafields6.wire +EXTRA_DIST += rdata_dnskey_fromWire.wire rdata_dnskey_empty_keydata_fromWire.wire +EXTRA_DIST += rdata_nsec_fromWire4.wire rdata_nsec_fromWire5.wire +EXTRA_DIST += rdata_nsec_fromWire6.wire rdata_nsec_fromWire7.wire +EXTRA_DIST += rdata_nsec_fromWire8.wire rdata_nsec_fromWire9.wire +EXTRA_DIST += rdata_nsec_fromWire10.wire +EXTRA_DIST += rdata_nsec_fromWire16.wire +EXTRA_DIST += rdata_nsec3param_fromWire2.wire +EXTRA_DIST += rdata_nsec3param_fromWire11.wire +EXTRA_DIST += rdata_nsec3param_fromWire13.wire +EXTRA_DIST += rdata_nsec3_fromWire2.wire rdata_nsec3_fromWire3 +EXTRA_DIST += rdata_nsec3_fromWire4.wire rdata_nsec3_fromWire5.wire +EXTRA_DIST += rdata_nsec3_fromWire6.wire rdata_nsec3_fromWire7.wire +EXTRA_DIST += rdata_nsec3_fromWire8.wire rdata_nsec3_fromWire9.wire +EXTRA_DIST += rdata_nsec3_fromWire10.wire rdata_nsec3_fromWire11.wire +EXTRA_DIST += rdata_nsec3_fromWire12.wire rdata_nsec3_fromWire13.wire +EXTRA_DIST += rdata_nsec3_fromWire14.wire rdata_nsec3_fromWire15.wire +EXTRA_DIST += rdata_nsec3_fromWire16.wire rdata_nsec3_fromWire17.wire +EXTRA_DIST += rdata_rrsig_fromWire2.wire +EXTRA_DIST += rdata_rp_fromWire1.wire rdata_rp_fromWire2.wire +EXTRA_DIST += rdata_rp_fromWire3.wire rdata_rp_fromWire4.wire +EXTRA_DIST += rdata_rp_fromWire5.wire rdata_rp_fromWire6.wire +EXTRA_DIST += rdata_rp_toWire1.wire rdata_rp_toWire2.wire +EXTRA_DIST += rdata_sshfp_fromWire1.wire rdata_sshfp_fromWire2.wire +EXTRA_DIST += rdata_sshfp_fromWire3.wire rdata_sshfp_fromWire4.wire +EXTRA_DIST += rdata_sshfp_fromWire5.wire rdata_sshfp_fromWire6.wire +EXTRA_DIST += rdata_sshfp_fromWire7.wire rdata_sshfp_fromWire8.wire +EXTRA_DIST += rdata_afsdb_fromWire1.wire rdata_afsdb_fromWire2.wire +EXTRA_DIST += rdata_afsdb_fromWire3.wire rdata_afsdb_fromWire4.wire +EXTRA_DIST += rdata_afsdb_fromWire5.wire +EXTRA_DIST += rdata_afsdb_toWire1.wire rdata_afsdb_toWire2.wire +EXTRA_DIST += rdata_soa_fromWire rdata_soa_toWireUncompressed.wire +EXTRA_DIST += rdata_minfo_fromWire1.wire rdata_minfo_fromWire2.wire +EXTRA_DIST += rdata_minfo_fromWire3.wire rdata_minfo_fromWire4.wire +EXTRA_DIST += rdata_minfo_fromWire5.wire rdata_minfo_fromWire6.wire +EXTRA_DIST += rdata_minfo_toWire1.wire rdata_minfo_toWire2.wire +EXTRA_DIST += rdata_minfo_toWireUncompressed1.wire +EXTRA_DIST += rdata_minfo_toWireUncompressed2.wire +EXTRA_DIST += rdata_txt_fromWire1 rdata_txt_fromWire2.wire +EXTRA_DIST += rdata_txt_fromWire3.wire rdata_txt_fromWire4.wire +EXTRA_DIST += rdata_txt_fromWire5.wire rdata_unknown_fromWire +EXTRA_DIST += rdata_tlsa_fromWire3.wire rdata_tlsa_fromWire4.wire +EXTRA_DIST += rdata_tlsa_fromWire5.wire rdata_tlsa_fromWire6.wire +EXTRA_DIST += rdata_tlsa_fromWire7.wire rdata_tlsa_fromWire8.wire +EXTRA_DIST += rdata_tsig_fromWire1.wire rdata_tsig_fromWire2.wire +EXTRA_DIST += rdata_tsig_fromWire3.wire rdata_tsig_fromWire4.wire +EXTRA_DIST += rdata_tsig_fromWire5.wire rdata_tsig_fromWire6.wire +EXTRA_DIST += rdata_tsig_fromWire7.wire rdata_tsig_fromWire8.wire +EXTRA_DIST += rdata_tsig_fromWire9.wire +EXTRA_DIST += rdata_tsig_toWire1.wire rdata_tsig_toWire2.wire +EXTRA_DIST += rdata_tsig_toWire3.wire rdata_tsig_toWire4.wire +EXTRA_DIST += rdata_tsig_toWire5.wire +EXTRA_DIST += rdata_caa_fromWire1.wire rdata_caa_fromWire2.wire +EXTRA_DIST += rdata_caa_fromWire3.wire rdata_caa_fromWire4.wire +EXTRA_DIST += rdata_tkey_fromWire1.wire rdata_tkey_fromWire2.wire +EXTRA_DIST += rdata_tkey_fromWire3.wire rdata_tkey_fromWire4.wire +EXTRA_DIST += rdata_tkey_fromWire5.wire rdata_tkey_fromWire6.wire +EXTRA_DIST += rdata_tkey_fromWire7.wire rdata_tkey_fromWire8.wire +EXTRA_DIST += rdata_tkey_fromWire9.wire +EXTRA_DIST += rdata_tkey_toWire1.wire rdata_tkey_toWire2.wire +EXTRA_DIST += rdata_tkey_toWire3.wire rdata_tkey_toWire4.wire +EXTRA_DIST += rdata_tkey_toWire5.wire +EXTRA_DIST += tsigrecord_toWire1.wire tsigrecord_toWire2.wire +EXTRA_DIST += tsig_verify1.wire tsig_verify2.wire tsig_verify3.wire +EXTRA_DIST += tsig_verify4.wire tsig_verify5.wire tsig_verify6.wire +EXTRA_DIST += tsig_verify7.wire tsig_verify8.wire tsig_verify9.wire +EXTRA_DIST += tsig_verify10.wire tsig_verify11.wire + +# We no longer use gen_wiredata.py during build process, so the +# dependency is no longer needed. However, we'll keep this dependency +# commented till the gen_wiredata.py script is removed. + +#.spec.wire: +# $(PYTHON) $(top_builddir)/src/lib/util/python/gen_wiredata.py -o $@ $< diff --git a/src/lib/dns/tests/testdata/Makefile.in b/src/lib/dns/tests/testdata/Makefile.in new file mode 100644 index 0000000..0a311f3 --- /dev/null +++ b/src/lib/dns/tests/testdata/Makefile.in @@ -0,0 +1,740 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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@ +subdir = src/lib/dns/tests/testdata +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4macros/ax_boost_for_kea.m4 \ + $(top_srcdir)/m4macros/ax_cpp11.m4 \ + $(top_srcdir)/m4macros/ax_cpp20.m4 \ + $(top_srcdir)/m4macros/ax_crypto.m4 \ + $(top_srcdir)/m4macros/ax_find_library.m4 \ + $(top_srcdir)/m4macros/ax_gssapi.m4 \ + $(top_srcdir)/m4macros/ax_gtest.m4 \ + $(top_srcdir)/m4macros/ax_isc_rpath.m4 \ + $(top_srcdir)/m4macros/ax_netconf.m4 \ + $(top_srcdir)/m4macros/libtool.m4 \ + $(top_srcdir)/m4macros/ltoptions.m4 \ + $(top_srcdir)/m4macros/ltsugar.m4 \ + $(top_srcdir)/m4macros/ltversion.m4 \ + $(top_srcdir)/m4macros/lt~obsolete.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)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +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 = +SOURCES = +DIST_SOURCES = +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) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ASCIIDOC = @ASCIIDOC@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BOOST_INCLUDES = @BOOST_INCLUDES@ +BOOST_LIBS = @BOOST_LIBS@ +BOTAN_TOOL = @BOTAN_TOOL@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CONTRIB_DIR = @CONTRIB_DIR@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTO_CFLAGS = @CRYPTO_CFLAGS@ +CRYPTO_INCLUDES = @CRYPTO_INCLUDES@ +CRYPTO_LDFLAGS = @CRYPTO_LDFLAGS@ +CRYPTO_LIBS = @CRYPTO_LIBS@ +CRYPTO_PACKAGE = @CRYPTO_PACKAGE@ +CRYPTO_RPATH = @CRYPTO_RPATH@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISTCHECK_BOOST_CONFIGURE_FLAG = @DISTCHECK_BOOST_CONFIGURE_FLAG@ +DISTCHECK_CONTRIB_CONFIGURE_FLAG = @DISTCHECK_CONTRIB_CONFIGURE_FLAG@ +DISTCHECK_CRYPTO_CONFIGURE_FLAG = @DISTCHECK_CRYPTO_CONFIGURE_FLAG@ +DISTCHECK_GSSAPI_CONFIGURE_FLAG = @DISTCHECK_GSSAPI_CONFIGURE_FLAG@ +DISTCHECK_GTEST_CONFIGURE_FLAG = @DISTCHECK_GTEST_CONFIGURE_FLAG@ +DISTCHECK_KEA_SHELL_CONFIGURE_FLAG = @DISTCHECK_KEA_SHELL_CONFIGURE_FLAG@ +DISTCHECK_LIBYANGCPP_CONFIGURE_FLAG = @DISTCHECK_LIBYANGCPP_CONFIGURE_FLAG@ +DISTCHECK_LIBYANG_CONFIGURE_FLAG = @DISTCHECK_LIBYANG_CONFIGURE_FLAG@ +DISTCHECK_LOG4CPLUS_CONFIGURE_FLAG = @DISTCHECK_LOG4CPLUS_CONFIGURE_FLAG@ +DISTCHECK_MYSQL_CONFIGURE_FLAG = @DISTCHECK_MYSQL_CONFIGURE_FLAG@ +DISTCHECK_PERFDHCP_CONFIGURE_FLAG = @DISTCHECK_PERFDHCP_CONFIGURE_FLAG@ +DISTCHECK_PGSQL_CONFIGURE_FLAG = @DISTCHECK_PGSQL_CONFIGURE_FLAG@ +DISTCHECK_PREMIUM_CONFIGURE_FLAG = @DISTCHECK_PREMIUM_CONFIGURE_FLAG@ +DISTCHECK_SYSREPOCPP_CONFIGURE_FLAG = @DISTCHECK_SYSREPOCPP_CONFIGURE_FLAG@ +DISTCHECK_SYSREPO_CONFIGURE_FLAG = @DISTCHECK_SYSREPO_CONFIGURE_FLAG@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GENHTML = @GENHTML@ +GREP = @GREP@ +GSSAPI_CFLAGS = @GSSAPI_CFLAGS@ +GSSAPI_LIBS = @GSSAPI_LIBS@ +GTEST_CONFIG = @GTEST_CONFIG@ +GTEST_INCLUDES = @GTEST_INCLUDES@ +GTEST_LDADD = @GTEST_LDADD@ +GTEST_LDFLAGS = @GTEST_LDFLAGS@ +GTEST_SOURCE = @GTEST_SOURCE@ +HAVE_NETCONF = @HAVE_NETCONF@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KEA_CXXFLAGS = @KEA_CXXFLAGS@ +KEA_SRCID = @KEA_SRCID@ +KRB5_CONFIG = @KRB5_CONFIG@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIBYANGCPP_CPPFLAGS = @LIBYANGCPP_CPPFLAGS@ +LIBYANGCPP_INCLUDEDIR = @LIBYANGCPP_INCLUDEDIR@ +LIBYANGCPP_LIBS = @LIBYANGCPP_LIBS@ +LIBYANGCPP_PREFIX = @LIBYANGCPP_PREFIX@ +LIBYANGCPP_VERSION = @LIBYANGCPP_VERSION@ +LIBYANG_CPPFLAGS = @LIBYANG_CPPFLAGS@ +LIBYANG_INCLUDEDIR = @LIBYANG_INCLUDEDIR@ +LIBYANG_LIBS = @LIBYANG_LIBS@ +LIBYANG_PREFIX = @LIBYANG_PREFIX@ +LIBYANG_VERSION = @LIBYANG_VERSION@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LOG4CPLUS_INCLUDES = @LOG4CPLUS_INCLUDES@ +LOG4CPLUS_LIBS = @LOG4CPLUS_LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@ +MYSQL_LIBS = @MYSQL_LIBS@ +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@ +PACKAGE_VERSION_TYPE = @PACKAGE_VERSION_TYPE@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PDFLATEX = @PDFLATEX@ +PERL = @PERL@ +PGSQL_CPPFLAGS = @PGSQL_CPPFLAGS@ +PGSQL_LIBS = @PGSQL_LIBS@ +PKGPYTHONDIR = @PKGPYTHONDIR@ +PKG_CONFIG = @PKG_CONFIG@ +PLANTUML = @PLANTUML@ +PREMIUM_DIR = @PREMIUM_DIR@ +PYTHON = @PYTHON@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +RANLIB = @RANLIB@ +SED = @SED@ +SEP = @SEP@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPHINXBUILD = @SPHINXBUILD@ +SRPD_PLUGINS_PATH = @SRPD_PLUGINS_PATH@ +SR_PLUGINS_PATH = @SR_PLUGINS_PATH@ +SR_REPO_PATH = @SR_REPO_PATH@ +STRIP = @STRIP@ +SYSREPOCPP_CPPFLAGS = @SYSREPOCPP_CPPFLAGS@ +SYSREPOCPP_INCLUDEDIR = @SYSREPOCPP_INCLUDEDIR@ +SYSREPOCPP_LIBS = @SYSREPOCPP_LIBS@ +SYSREPOCPP_PREFIX = @SYSREPOCPP_PREFIX@ +SYSREPOCPP_VERSION = @SYSREPOCPP_VERSION@ +SYSREPO_CPPFLAGS = @SYSREPO_CPPFLAGS@ +SYSREPO_INCLUDEDIR = @SYSREPO_INCLUDEDIR@ +SYSREPO_LIBS = @SYSREPO_LIBS@ +SYSREPO_PREFIX = @SYSREPO_PREFIX@ +SYSREPO_VERSION = @SYSREPO_VERSION@ +USE_LCOV = @USE_LCOV@ +VALGRIND = @VALGRIND@ +VERSION = @VERSION@ +WARNING_GCC_44_STRICT_ALIASING_CFLAG = @WARNING_GCC_44_STRICT_ALIASING_CFLAG@ +YACC = @YACC@ +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_CXX = @ac_ct_CXX@ +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@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +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@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +CLEANFILES = + +# NOTE: keep this in sync with real file listing +# so is included in tarball + +# Generated .wire files +EXTRA_DIST = edns_toWire1.spec edns_toWire2.spec edns_toWire3.spec \ + edns_toWire4.spec masterload.txt message_fromWire1 \ + message_fromWire2 message_fromWire3 message_fromWire4 \ + message_fromWire5 message_fromWire6 message_fromWire7 \ + message_fromWire8 message_fromWire9 message_fromWire10.spec \ + message_fromWire11.spec message_fromWire12.spec \ + message_fromWire13.spec message_fromWire14.spec \ + message_fromWire15.spec message_fromWire16.spec \ + message_fromWire17.spec message_fromWire18.spec \ + message_fromWire19.spec message_fromWire20.spec \ + message_fromWire21.spec message_fromWire22.spec \ + message_toWire1 message_toWire2.spec message_toWire3.spec \ + message_toWire4.spec message_toWire5.spec message_toWire6 \ + message_toWire7 message_toText1.txt message_toText1.spec \ + message_toText2.txt message_toText2.spec message_toText3.txt \ + message_toText3.spec name_fromWire1 name_fromWire2 \ + name_fromWire3_1 name_fromWire3_2 name_fromWire4 \ + name_fromWire6 name_fromWire7 name_fromWire8 name_fromWire9 \ + name_fromWire10 name_fromWire11 name_fromWire12 \ + name_fromWire13 name_fromWire14 name_toWire1 name_toWire2 \ + name_toWire3 name_toWire4 name_toWire5.spec name_toWire6.spec \ + name_toWire7 name_toWire8 name_toWire9 question_fromWire \ + question_toWire1 question_toWire2 rdatafields1.spec \ + rdatafields2.spec rdatafields3.spec rdatafields4.spec \ + rdatafields5.spec rdatafields6.spec rdata_cname_fromWire \ + rdata_dname_fromWire rdata_dnskey_fromWire.spec \ + rdata_dnskey_empty_keydata_fromWire.spec rdata_dhcid_fromWire \ + rdata_dhcid_toWire rdata_ds_fromWire rdata_in_a_fromWire \ + rdata_in_aaaa_fromWire rdata_mx_fromWire rdata_mx_toWire1 \ + rdata_mx_toWire2 rdata_ns_fromWire rdata_nsec_fromWire1 \ + rdata_nsec_fromWire2 rdata_nsec_fromWire3 \ + rdata_nsec_fromWire4.spec rdata_nsec_fromWire5.spec \ + rdata_nsec_fromWire6.spec rdata_nsec_fromWire7.spec \ + rdata_nsec_fromWire8.spec rdata_nsec_fromWire9.spec \ + rdata_nsec_fromWire10.spec rdata_nsec_fromWire16.spec \ + rdata_nsec3param_fromWire1 rdata_nsec3param_fromWire2.spec \ + rdata_nsec3param_fromWire11.spec \ + rdata_nsec3param_fromWire13.spec rdata_nsec3_fromWire1 \ + rdata_nsec3_fromWire1.spec rdata_nsec3_fromWire2.spec \ + rdata_nsec3_fromWire3 rdata_nsec3_fromWire4.spec \ + rdata_nsec3_fromWire5.spec rdata_nsec3_fromWire6.spec \ + rdata_nsec3_fromWire7.spec rdata_nsec3_fromWire8.spec \ + rdata_nsec3_fromWire9.spec rdata_nsec3_fromWire10.spec \ + rdata_nsec3_fromWire11.spec rdata_nsec3_fromWire12.spec \ + rdata_nsec3_fromWire13.spec rdata_nsec3_fromWire14.spec \ + rdata_nsec3_fromWire15.spec rdata_nsec3_fromWire16.spec \ + rdata_nsec3_fromWire17.spec rdata_opt_fromWire1 \ + rdata_opt_fromWire2 rdata_opt_fromWire3 rdata_opt_fromWire4 \ + rdata_rrsig_fromWire1 rdata_rrsig_fromWire2.spec \ + rdata_rp_fromWire1.spec rdata_rp_fromWire2.spec \ + rdata_rp_fromWire3.spec rdata_rp_fromWire4.spec \ + rdata_rp_fromWire5.spec rdata_rp_fromWire6.spec \ + rdata_rp_toWire1.spec rdata_rp_toWire2.spec \ + rdata_sshfp_fromWire rdata_sshfp_fromWire2 \ + rdata_sshfp_fromWire1.spec rdata_sshfp_fromWire2.spec \ + rdata_sshfp_fromWire3.spec rdata_sshfp_fromWire4.spec \ + rdata_sshfp_fromWire5.spec rdata_sshfp_fromWire6.spec \ + rdata_sshfp_fromWire7.spec rdata_sshfp_fromWire8.spec \ + rdata_sshfp_fromWire9 rdata_sshfp_fromWire10 \ + rdata_sshfp_fromWire11 rdata_sshfp_fromWire12 \ + rdata_afsdb_fromWire1.spec rdata_afsdb_fromWire2.spec \ + rdata_afsdb_fromWire3.spec rdata_afsdb_fromWire4.spec \ + rdata_afsdb_fromWire5.spec rdata_afsdb_toWire1.spec \ + rdata_afsdb_toWire2.spec rdata_soa_fromWire \ + rdata_soa_toWireUncompressed.spec rdata_srv_fromWire \ + rdata_minfo_fromWire1.spec rdata_minfo_fromWire2.spec \ + rdata_minfo_fromWire3.spec rdata_minfo_fromWire4.spec \ + rdata_minfo_fromWire5.spec rdata_minfo_fromWire6.spec \ + rdata_minfo_toWire1.spec rdata_minfo_toWire2.spec \ + rdata_minfo_toWireUncompressed1.spec \ + rdata_minfo_toWireUncompressed2.spec rdata_txt_fromWire1 \ + rdata_txt_fromWire2.spec rdata_txt_fromWire3.spec \ + rdata_txt_fromWire4.spec rdata_txt_fromWire5.spec \ + rdata_unknown_fromWire rrcode16_fromWire1 rrcode16_fromWire2 \ + rrcode32_fromWire1 rrcode32_fromWire2 rrset_toWire1 \ + rrset_toWire2 rrset_toWire3 rrset_toWire4 \ + rdata_tkey_fromWire1.spec rdata_tkey_fromWire2.spec \ + rdata_tkey_fromWire3.spec rdata_tkey_fromWire4.spec \ + rdata_tkey_fromWire5.spec rdata_tkey_fromWire6.spec \ + rdata_tkey_fromWire7.spec rdata_tkey_fromWire8.spec \ + rdata_tkey_fromWire9.spec rdata_tkey_toWire1.spec \ + rdata_tkey_toWire2.spec rdata_tkey_toWire3.spec \ + rdata_tkey_toWire4.spec rdata_tkey_toWire5.spec \ + rdata_tlsa_fromWire rdata_tlsa_fromWire2 \ + rdata_tlsa_fromWire3.spec rdata_tlsa_fromWire4.spec \ + rdata_tlsa_fromWire5.spec rdata_tlsa_fromWire6.spec \ + rdata_tlsa_fromWire7.spec rdata_tlsa_fromWire8.spec \ + rdata_tlsa_fromWire9 rdata_tlsa_fromWire10 \ + rdata_tlsa_fromWire11 rdata_tlsa_fromWire12 \ + rdata_tsig_fromWire1.spec rdata_tsig_fromWire2.spec \ + rdata_tsig_fromWire3.spec rdata_tsig_fromWire4.spec \ + rdata_tsig_fromWire5.spec rdata_tsig_fromWire6.spec \ + rdata_tsig_fromWire7.spec rdata_tsig_fromWire8.spec \ + rdata_tsig_fromWire9.spec rdata_tsig_toWire1.spec \ + rdata_tsig_toWire2.spec rdata_tsig_toWire3.spec \ + rdata_tsig_toWire4.spec rdata_tsig_toWire5.spec \ + rdata_caa_fromWire1.spec rdata_caa_fromWire2.spec \ + rdata_caa_fromWire3.spec rdata_caa_fromWire4.spec \ + rdata_caa_fromWire5 rdata_caa_fromWire6 \ + tsigrecord_toWire1.spec tsigrecord_toWire2.spec \ + tsig_verify1.spec tsig_verify2.spec tsig_verify3.spec \ + tsig_verify4.spec tsig_verify5.spec tsig_verify6.spec \ + tsig_verify7.spec tsig_verify8.spec tsig_verify9.spec \ + tsig_verify10.spec tsig_verify11.spec example.org broken.zone \ + origincheck.txt omitcheck.txt edns_toWire1.wire \ + edns_toWire2.wire edns_toWire3.wire edns_toWire4.wire \ + message_fromWire10.wire message_fromWire11.wire \ + message_fromWire12.wire message_fromWire13.wire \ + message_fromWire14.wire message_fromWire15.wire \ + message_fromWire16.wire message_fromWire17.wire \ + message_fromWire18.wire message_fromWire19.wire \ + message_fromWire20.wire message_fromWire21.wire \ + message_fromWire22.wire message_toWire1 message_toWire2.wire \ + message_toWire3.wire message_toWire4.wire message_toWire5.wire \ + message_toText1.txt message_toText1.wire message_toText2.txt \ + message_toText2.wire message_toText3.txt message_toText3.wire \ + name_toWire5.wire name_toWire6.wire rdatafields1.wire \ + rdatafields2.wire rdatafields3.wire rdatafields4.wire \ + rdatafields5.wire rdatafields6.wire rdata_dnskey_fromWire.wire \ + rdata_dnskey_empty_keydata_fromWire.wire \ + rdata_nsec_fromWire4.wire rdata_nsec_fromWire5.wire \ + rdata_nsec_fromWire6.wire rdata_nsec_fromWire7.wire \ + rdata_nsec_fromWire8.wire rdata_nsec_fromWire9.wire \ + rdata_nsec_fromWire10.wire rdata_nsec_fromWire16.wire \ + rdata_nsec3param_fromWire2.wire \ + rdata_nsec3param_fromWire11.wire \ + rdata_nsec3param_fromWire13.wire rdata_nsec3_fromWire2.wire \ + rdata_nsec3_fromWire3 rdata_nsec3_fromWire4.wire \ + rdata_nsec3_fromWire5.wire rdata_nsec3_fromWire6.wire \ + rdata_nsec3_fromWire7.wire rdata_nsec3_fromWire8.wire \ + rdata_nsec3_fromWire9.wire rdata_nsec3_fromWire10.wire \ + rdata_nsec3_fromWire11.wire rdata_nsec3_fromWire12.wire \ + rdata_nsec3_fromWire13.wire rdata_nsec3_fromWire14.wire \ + rdata_nsec3_fromWire15.wire rdata_nsec3_fromWire16.wire \ + rdata_nsec3_fromWire17.wire rdata_rrsig_fromWire2.wire \ + rdata_rp_fromWire1.wire rdata_rp_fromWire2.wire \ + rdata_rp_fromWire3.wire rdata_rp_fromWire4.wire \ + rdata_rp_fromWire5.wire rdata_rp_fromWire6.wire \ + rdata_rp_toWire1.wire rdata_rp_toWire2.wire \ + rdata_sshfp_fromWire1.wire rdata_sshfp_fromWire2.wire \ + rdata_sshfp_fromWire3.wire rdata_sshfp_fromWire4.wire \ + rdata_sshfp_fromWire5.wire rdata_sshfp_fromWire6.wire \ + rdata_sshfp_fromWire7.wire rdata_sshfp_fromWire8.wire \ + rdata_afsdb_fromWire1.wire rdata_afsdb_fromWire2.wire \ + rdata_afsdb_fromWire3.wire rdata_afsdb_fromWire4.wire \ + rdata_afsdb_fromWire5.wire rdata_afsdb_toWire1.wire \ + rdata_afsdb_toWire2.wire rdata_soa_fromWire \ + rdata_soa_toWireUncompressed.wire rdata_minfo_fromWire1.wire \ + rdata_minfo_fromWire2.wire rdata_minfo_fromWire3.wire \ + rdata_minfo_fromWire4.wire rdata_minfo_fromWire5.wire \ + rdata_minfo_fromWire6.wire rdata_minfo_toWire1.wire \ + rdata_minfo_toWire2.wire rdata_minfo_toWireUncompressed1.wire \ + rdata_minfo_toWireUncompressed2.wire rdata_txt_fromWire1 \ + rdata_txt_fromWire2.wire rdata_txt_fromWire3.wire \ + rdata_txt_fromWire4.wire rdata_txt_fromWire5.wire \ + rdata_unknown_fromWire rdata_tlsa_fromWire3.wire \ + rdata_tlsa_fromWire4.wire rdata_tlsa_fromWire5.wire \ + rdata_tlsa_fromWire6.wire rdata_tlsa_fromWire7.wire \ + rdata_tlsa_fromWire8.wire rdata_tsig_fromWire1.wire \ + rdata_tsig_fromWire2.wire rdata_tsig_fromWire3.wire \ + rdata_tsig_fromWire4.wire rdata_tsig_fromWire5.wire \ + rdata_tsig_fromWire6.wire rdata_tsig_fromWire7.wire \ + rdata_tsig_fromWire8.wire rdata_tsig_fromWire9.wire \ + rdata_tsig_toWire1.wire rdata_tsig_toWire2.wire \ + rdata_tsig_toWire3.wire rdata_tsig_toWire4.wire \ + rdata_tsig_toWire5.wire rdata_caa_fromWire1.wire \ + rdata_caa_fromWire2.wire rdata_caa_fromWire3.wire \ + rdata_caa_fromWire4.wire rdata_tkey_fromWire1.wire \ + rdata_tkey_fromWire2.wire rdata_tkey_fromWire3.wire \ + rdata_tkey_fromWire4.wire rdata_tkey_fromWire5.wire \ + rdata_tkey_fromWire6.wire rdata_tkey_fromWire7.wire \ + rdata_tkey_fromWire8.wire rdata_tkey_fromWire9.wire \ + rdata_tkey_toWire1.wire rdata_tkey_toWire2.wire \ + rdata_tkey_toWire3.wire rdata_tkey_toWire4.wire \ + rdata_tkey_toWire5.wire tsigrecord_toWire1.wire \ + tsigrecord_toWire2.wire tsig_verify1.wire tsig_verify2.wire \ + tsig_verify3.wire tsig_verify4.wire tsig_verify5.wire \ + tsig_verify6.wire tsig_verify7.wire tsig_verify8.wire \ + tsig_verify9.wire tsig_verify10.wire tsig_verify11.wire +all: all-am + +.SUFFIXES: +$(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 src/lib/dns/tests/testdata/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/lib/dns/tests/testdata/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): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +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 +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) + +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-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +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 Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool 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-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# We no longer use gen_wiredata.py during build process, so the +# dependency is no longer needed. However, we'll keep this dependency +# commented till the gen_wiredata.py script is removed. + +#.spec.wire: +# $(PYTHON) $(top_builddir)/src/lib/util/python/gen_wiredata.py -o $@ $< + +# 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/src/lib/dns/tests/testdata/broken.zone b/src/lib/dns/tests/testdata/broken.zone new file mode 100644 index 0000000..70f4540 --- /dev/null +++ b/src/lib/dns/tests/testdata/broken.zone @@ -0,0 +1,3 @@ +; This should fail due to broken TTL +; The file should _NOT_ end with EOLN +broken. 3600X IN A 192.0.2.2 More data
\ No newline at end of file diff --git a/src/lib/dns/tests/testdata/edns_toWire1.spec b/src/lib/dns/tests/testdata/edns_toWire1.spec new file mode 100644 index 0000000..483aefa --- /dev/null +++ b/src/lib/dns/tests/testdata/edns_toWire1.spec @@ -0,0 +1,5 @@ +# +# A simplest form of EDNS: all default parameters +# +[edns] + diff --git a/src/lib/dns/tests/testdata/edns_toWire1.wire b/src/lib/dns/tests/testdata/edns_toWire1.wire new file mode 100644 index 0000000..2884e29 --- /dev/null +++ b/src/lib/dns/tests/testdata/edns_toWire1.wire @@ -0,0 +1,9 @@ +### +### This data file was auto-generated from edns_toWire1.spec +### + +# EDNS OPT RR +# NAME=. TYPE=OPT(41) UDPSize=4096 ExtRcode=0 Version=0 DO=0 +00 0029 1000 0000 0000 +# RDLEN=0 +0000 diff --git a/src/lib/dns/tests/testdata/edns_toWire2.spec b/src/lib/dns/tests/testdata/edns_toWire2.spec new file mode 100644 index 0000000..7fe1ffd --- /dev/null +++ b/src/lib/dns/tests/testdata/edns_toWire2.spec @@ -0,0 +1,5 @@ +# +# Same as edns_toWire1 but setting the DO bit +# +[edns] +do: 1 diff --git a/src/lib/dns/tests/testdata/edns_toWire2.wire b/src/lib/dns/tests/testdata/edns_toWire2.wire new file mode 100644 index 0000000..cb09000 --- /dev/null +++ b/src/lib/dns/tests/testdata/edns_toWire2.wire @@ -0,0 +1,9 @@ +### +### This data file was auto-generated from edns_toWire2.spec +### + +# EDNS OPT RR +# NAME=. TYPE=OPT(41) UDPSize=4096 ExtRcode=0 Version=0 DO=1 +00 0029 1000 0000 8000 +# RDLEN=0 +0000 diff --git a/src/lib/dns/tests/testdata/edns_toWire3.spec b/src/lib/dns/tests/testdata/edns_toWire3.spec new file mode 100644 index 0000000..0332097 --- /dev/null +++ b/src/lib/dns/tests/testdata/edns_toWire3.spec @@ -0,0 +1,7 @@ +# +# Same as edns_toWire1 but setting the DO bit, and extended Rcode being non 0 +# (for BADVER) +# +[edns] +do: 1 +extrcode: 0x1 diff --git a/src/lib/dns/tests/testdata/edns_toWire3.wire b/src/lib/dns/tests/testdata/edns_toWire3.wire new file mode 100644 index 0000000..b8d0775 --- /dev/null +++ b/src/lib/dns/tests/testdata/edns_toWire3.wire @@ -0,0 +1,9 @@ +### +### This data file was auto-generated from edns_toWire3.spec +### + +# EDNS OPT RR +# NAME=. TYPE=OPT(41) UDPSize=4096 ExtRcode=1 Version=0 DO=1 +00 0029 1000 0100 8000 +# RDLEN=0 +0000 diff --git a/src/lib/dns/tests/testdata/edns_toWire4.spec b/src/lib/dns/tests/testdata/edns_toWire4.spec new file mode 100644 index 0000000..ea1f5e3 --- /dev/null +++ b/src/lib/dns/tests/testdata/edns_toWire4.spec @@ -0,0 +1,7 @@ +# +# Same as edns_toWire1 but setting the DO bit, and using an unusual +# UDP payload size +# +[edns] +do: 1 +udpsize = 511 diff --git a/src/lib/dns/tests/testdata/edns_toWire4.wire b/src/lib/dns/tests/testdata/edns_toWire4.wire new file mode 100644 index 0000000..73bf757 --- /dev/null +++ b/src/lib/dns/tests/testdata/edns_toWire4.wire @@ -0,0 +1,9 @@ +### +### This data file was auto-generated from edns_toWire4.spec +### + +# EDNS OPT RR +# NAME=. TYPE=OPT(41) UDPSize=511 ExtRcode=0 Version=0 DO=1 +00 0029 01ff 0000 8000 +# RDLEN=0 +0000 diff --git a/src/lib/dns/tests/testdata/example.org b/src/lib/dns/tests/testdata/example.org new file mode 100644 index 0000000..2708ef4 --- /dev/null +++ b/src/lib/dns/tests/testdata/example.org @@ -0,0 +1,17 @@ +example.org. 3600 IN SOA ( ; The SOA, split across lines for testing + ns1.example.org. + admin.example.org. + 1234 + 3600 + 1800 + 2419200 + 7200 + ) +; Check it accepts quoted name too +"\101xample.org." 3600 IN NS ns1.example.org. + + +; Some empty lines here. They are to make sure the loader can skip them. +www 3600 IN A 192.0.2.1 ; Test a relative name as well. + 3600 IN AAAA 2001:db8::1 ; And initial whitespace handling + ; Here be just some space, no RRs diff --git a/src/lib/dns/tests/testdata/masterload.txt b/src/lib/dns/tests/testdata/masterload.txt new file mode 100644 index 0000000..0d2f942 --- /dev/null +++ b/src/lib/dns/tests/testdata/masterload.txt @@ -0,0 +1,5 @@ +;; a simple (incomplete) zone file + +example.com. 3600 IN TXT "test data" +www.example.com. 60 IN A 192.0.2.1 +www.example.com. 60 IN A 192.0.2.2 diff --git a/src/lib/dns/tests/testdata/message_fromWire1 b/src/lib/dns/tests/testdata/message_fromWire1 new file mode 100644 index 0000000..5b76e3f --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire1 @@ -0,0 +1,22 @@ +# +# A simple DNS response message +# ID = 0x1035 +# QR=1 (response), Opcode=0, AA=1, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=2, other COUNTS=0 +# Question: test.example.com. IN A +# Answer: +# test.example.com. 3600 IN A 192.0.2.1 +# test.example.com. 7200 IN A 192.0.2.2 +# +1035 8500 +0001 0002 0000 0000 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# same name, fully compressed +c0 0c +# TTL=3600, A, IN, RDLENGTH=4, RDATA +0001 0001 00000e10 0004 c0 00 02 01 +# mostly same, with the slight difference in RDATA and TTL +c0 0c +0001 0001 00001c20 0004 c0 00 02 02 diff --git a/src/lib/dns/tests/testdata/message_fromWire10.spec b/src/lib/dns/tests/testdata/message_fromWire10.spec new file mode 100644 index 0000000..d3fb014 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire10.spec @@ -0,0 +1,13 @@ +# +# A simple DNS response message with an EDNS0 indicating a BADVERS error +# + +[header] +qr: response +rd: 1 +arcount: 1 +[question] +# use default +[edns] +do: 1 +extrcode: 1 diff --git a/src/lib/dns/tests/testdata/message_fromWire10.wire b/src/lib/dns/tests/testdata/message_fromWire10.wire new file mode 100644 index 0000000..fa76b92 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire10.wire @@ -0,0 +1,19 @@ +### +### This data file was auto-generated from message_fromWire10.spec +### + +# Header Section +# ID=4149 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) RD +1035 8100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=example.com. QTYPE=A(1) QCLASS=IN(1) +076578616d706c6503636f6d00 0001 0001 + +# EDNS OPT RR +# NAME=. TYPE=OPT(41) UDPSize=4096 ExtRcode=1 Version=0 DO=1 +00 0029 1000 0100 8000 +# RDLEN=0 +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire11.spec b/src/lib/dns/tests/testdata/message_fromWire11.spec new file mode 100644 index 0000000..5f31746 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire11.spec @@ -0,0 +1,15 @@ +# +# A simple DNS response message with an EDNS0 indicating the maximum error code +# (0xfff) +# + +[header] +qr: response +rd: 1 +rcode: 0xf +arcount: 1 +[question] +# use default +[edns] +do: 1 +extrcode: 0xff diff --git a/src/lib/dns/tests/testdata/message_fromWire11.wire b/src/lib/dns/tests/testdata/message_fromWire11.wire new file mode 100644 index 0000000..f20132c --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire11.wire @@ -0,0 +1,19 @@ +### +### This data file was auto-generated from message_fromWire11.spec +### + +# Header Section +# ID=4149 QR=Response Opcode=QUERY(0) Rcode=15 RD +1035 810f +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=example.com. QTYPE=A(1) QCLASS=IN(1) +076578616d706c6503636f6d00 0001 0001 + +# EDNS OPT RR +# NAME=. TYPE=OPT(41) UDPSize=4096 ExtRcode=255 Version=0 DO=1 +00 0029 1000 ff00 8000 +# RDLEN=0 +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire12.spec b/src/lib/dns/tests/testdata/message_fromWire12.spec new file mode 100644 index 0000000..4eadeed --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire12.spec @@ -0,0 +1,21 @@ +# +# A simple DNS response message with TSIG signed, but the owner name of TSIG +# is compressed +# + +[custom] +sections: header:question:tsig +[header] +id: 0x2d65 +rd: 1 +arcount: 1 +[question] +name: www.example.com +[tsig] +as_rr: True +rr_name: ptr=12 +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +mac: 0x227026ad297beee721ce6c6fff1e9ef3 +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/message_fromWire12.wire b/src/lib/dns/tests/testdata/message_fromWire12.wire new file mode 100644 index 0000000..9ceb356 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire12.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from message_fromWire12.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=ptr=12 Class=ANY(255) TTL=0, RDLEN=58) +c00c 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 227026ad297beee721ce6c6fff1e9ef3 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire13.spec b/src/lib/dns/tests/testdata/message_fromWire13.spec new file mode 100644 index 0000000..e81ec4c --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire13.spec @@ -0,0 +1,20 @@ +# +# Invalid TSIG: containing 2 TSIG RRs. +# + +[custom] +sections: header:question:tsig:tsig +[header] +id: 0x2d65 +rd: 1 +arcount: 2 +[question] +name: www.example.com +[tsig] +as_rr: True +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +mac: 0x227026ad297beee721ce6c6fff1e9ef3 +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/message_fromWire13.wire b/src/lib/dns/tests/testdata/message_fromWire13.wire new file mode 100644 index 0000000..05b064a --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire13.wire @@ -0,0 +1,35 @@ +### +### This data file was auto-generated from message_fromWire13.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=2 +0001 0000 0000 0002 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 227026ad297beee721ce6c6fff1e9ef3 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 227026ad297beee721ce6c6fff1e9ef3 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire14.spec b/src/lib/dns/tests/testdata/message_fromWire14.spec new file mode 100644 index 0000000..bf68a93 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire14.spec @@ -0,0 +1,21 @@ +# +# Invalid TSIG: not in the additional section. +# + +[custom] +sections: header:question:tsig +[header] +id: 0x2d65 +rd: 1 +# TSIG goes to the answer section +ancount: 1 +[question] +name: www.example.com +[tsig] +as_rr: True +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +mac: 0x227026ad297beee721ce6c6fff1e9ef3 +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/message_fromWire14.wire b/src/lib/dns/tests/testdata/message_fromWire14.wire new file mode 100644 index 0000000..17d0e21 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire14.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from message_fromWire14.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=1, NSCNT=0, ARCNT=0 +0001 0001 0000 0000 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 227026ad297beee721ce6c6fff1e9ef3 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire15.spec b/src/lib/dns/tests/testdata/message_fromWire15.spec new file mode 100644 index 0000000..25d810f --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire15.spec @@ -0,0 +1,22 @@ +# +# Invalid TSIG: not at the end of the message +# + +[custom] +sections: header:question:tsig:edns +[header] +id: 0x2d65 +rd: 1 +arcount: 2 +[question] +name: www.example.com +[tsig] +as_rr: True +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +mac: 0x227026ad297beee721ce6c6fff1e9ef3 +original_id: 0x2d65 +[edns] +# (all default) diff --git a/src/lib/dns/tests/testdata/message_fromWire15.wire b/src/lib/dns/tests/testdata/message_fromWire15.wire new file mode 100644 index 0000000..e3f36d0 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire15.wire @@ -0,0 +1,30 @@ +### +### This data file was auto-generated from message_fromWire15.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=2 +0001 0000 0000 0002 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 227026ad297beee721ce6c6fff1e9ef3 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 + +# EDNS OPT RR +# NAME=. TYPE=OPT(41) UDPSize=4096 ExtRcode=0 Version=0 DO=0 +00 0029 1000 0000 0000 +# RDLEN=0 +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire16.spec b/src/lib/dns/tests/testdata/message_fromWire16.spec new file mode 100644 index 0000000..be0abc3 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire16.spec @@ -0,0 +1,21 @@ +# +# Invalid TSIG: not in the additional section. +# + +[custom] +sections: header:question:tsig +[header] +id: 0x2d65 +rd: 1 +arcount: 1 +[question] +name: www.example.com +[tsig] +as_rr: True +rr_class: IN +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +mac: 0x227026ad297beee721ce6c6fff1e9ef3 +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/message_fromWire16.wire b/src/lib/dns/tests/testdata/message_fromWire16.wire new file mode 100644 index 0000000..04a791a --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire16.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from message_fromWire16.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=www.example.com Class=IN(1) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 0001 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 227026ad297beee721ce6c6fff1e9ef3 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire17.spec b/src/lib/dns/tests/testdata/message_fromWire17.spec new file mode 100644 index 0000000..366cf05 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire17.spec @@ -0,0 +1,22 @@ +# +# A simple DNS query message with TSIG signed +# + +[custom] +sections: header:question:tsig +[header] +id: 0x22c2 +rd: 1 +arcount: 1 +[question] +name: www.example.com +rrtype: TXT +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4e179212 +mac_size: 16 +mac: 0x8214b04634e32323d651ac60b08e6388 +original_id: 0x22c2 diff --git a/src/lib/dns/tests/testdata/message_fromWire17.wire b/src/lib/dns/tests/testdata/message_fromWire17.wire new file mode 100644 index 0000000..e607c52 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire17.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from message_fromWire17.spec +### + +# Header Section +# ID=8898 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +22c2 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=TXT(16) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0010 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1310167570 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004e179212 012c +# MAC Size=16 MAC=(see hex) +0010 8214b04634e32323d651ac60b08e6388 +# Original-ID=8898 Error=0 +22c2 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire18.spec b/src/lib/dns/tests/testdata/message_fromWire18.spec new file mode 100644 index 0000000..0b2592a --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire18.spec @@ -0,0 +1,23 @@ +# +# Another simple DNS query message with TSIG signed. Only ID and time signed +# (and MAC as a result) are different. +# + +[custom] +sections: header:question:tsig +[header] +id: 0xd6e2 +rd: 1 +arcount: 1 +[question] +name: www.example.com +rrtype: TXT +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4e17b38d +mac_size: 16 +mac: 0x903b5b194a799b03a37718820c2404f2 +original_id: 0xd6e2 diff --git a/src/lib/dns/tests/testdata/message_fromWire18.wire b/src/lib/dns/tests/testdata/message_fromWire18.wire new file mode 100644 index 0000000..82bdf6b --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire18.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from message_fromWire18.spec +### + +# Header Section +# ID=55010 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +d6e2 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=TXT(16) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0010 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1310176141 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004e17b38d 012c +# MAC Size=16 MAC=(see hex) +0010 903b5b194a799b03a37718820c2404f2 +# Original-ID=55010 Error=0 +d6e2 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire19.spec b/src/lib/dns/tests/testdata/message_fromWire19.spec new file mode 100644 index 0000000..8212dbf --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire19.spec @@ -0,0 +1,20 @@ +# +# A non realistic DNS response message containing mixed types of RRs in the +# answer section in a mixed order. +# + +[custom] +sections: header:question:a/1:aaaa:a/2 +[header] +qr: 1 +ancount: 3 +[question] +name: www.example.com +rrtype: A +[a/1] +as_rr: True +[aaaa] +as_rr: True +[a/2] +as_rr: True +address: 192.0.2.2 diff --git a/src/lib/dns/tests/testdata/message_fromWire19.wire b/src/lib/dns/tests/testdata/message_fromWire19.wire new file mode 100644 index 0000000..d154244 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire19.wire @@ -0,0 +1,28 @@ +### +### This data file was auto-generated from message_fromWire19.spec +### + +# Header Section +# ID=4149 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) +1035 8000 +# QDCNT=1, ANCNT=3, NSCNT=0, ARCNT=0 +0001 0003 0000 0000 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# A RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=4) +076578616d706c6503636f6d00 0001 0001 00015180 0004 +# Address=192.0.2.1 +c0000201 + +# AAAA RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=16) +076578616d706c6503636f6d00 001c 0001 00015180 0010 +# Address=2001:db8::1 +20010db8000000000000000000000001 + +# A RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=4) +076578616d706c6503636f6d00 0001 0001 00015180 0004 +# Address=192.0.2.2 +c0000202 diff --git a/src/lib/dns/tests/testdata/message_fromWire2 b/src/lib/dns/tests/testdata/message_fromWire2 new file mode 100644 index 0000000..194cbf2 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire2 @@ -0,0 +1,22 @@ +# +# A simple DNS query message with a valid EDNS0 OPT RR +# ID = 0x1035 +# QR=0 (query), Opcode=0, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=1 +# Question: test.example.com. IN A +1035 0100 +0001 0000 0000 0001 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# EDNS0 OPT RR +# owner name: "." +00 +# TYPE: OPT (41 = 0x29) +00 29 +# CLASS (= UDP size): 4096 +1000 +# TTL (extended RCODE and flags): RCODE=0, version=0, flags=DO +0000 8000 +# RDLEN = 0 +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire20.spec b/src/lib/dns/tests/testdata/message_fromWire20.spec new file mode 100644 index 0000000..91986e4 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire20.spec @@ -0,0 +1,20 @@ +# +# A non realistic DNS response message containing mixed types of RRs in the +# authority section in a mixed order. +# + +[custom] +sections: header:question:a/1:aaaa:a/2 +[header] +qr: 1 +nscount: 3 +[question] +name: www.example.com +rrtype: A +[a/1] +as_rr: True +[aaaa] +as_rr: True +[a/2] +as_rr: True +address: 192.0.2.2 diff --git a/src/lib/dns/tests/testdata/message_fromWire20.wire b/src/lib/dns/tests/testdata/message_fromWire20.wire new file mode 100644 index 0000000..887dd1e --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire20.wire @@ -0,0 +1,28 @@ +### +### This data file was auto-generated from message_fromWire20.spec +### + +# Header Section +# ID=4149 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) +1035 8000 +# QDCNT=1, ANCNT=0, NSCNT=3, ARCNT=0 +0001 0000 0003 0000 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# A RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=4) +076578616d706c6503636f6d00 0001 0001 00015180 0004 +# Address=192.0.2.1 +c0000201 + +# AAAA RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=16) +076578616d706c6503636f6d00 001c 0001 00015180 0010 +# Address=2001:db8::1 +20010db8000000000000000000000001 + +# A RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=4) +076578616d706c6503636f6d00 0001 0001 00015180 0004 +# Address=192.0.2.2 +c0000202 diff --git a/src/lib/dns/tests/testdata/message_fromWire21.spec b/src/lib/dns/tests/testdata/message_fromWire21.spec new file mode 100644 index 0000000..cd6aac9 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire21.spec @@ -0,0 +1,20 @@ +# +# A non realistic DNS response message containing mixed types of RRs in the +# additional section in a mixed order. +# + +[custom] +sections: header:question:a/1:aaaa:a/2 +[header] +qr: 1 +arcount: 3 +[question] +name: www.example.com +rrtype: A +[a/1] +as_rr: True +[aaaa] +as_rr: True +[a/2] +as_rr: True +address: 192.0.2.2 diff --git a/src/lib/dns/tests/testdata/message_fromWire21.wire b/src/lib/dns/tests/testdata/message_fromWire21.wire new file mode 100644 index 0000000..14cfcc0 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire21.wire @@ -0,0 +1,28 @@ +### +### This data file was auto-generated from message_fromWire21.spec +### + +# Header Section +# ID=4149 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) +1035 8000 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=3 +0001 0000 0000 0003 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# A RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=4) +076578616d706c6503636f6d00 0001 0001 00015180 0004 +# Address=192.0.2.1 +c0000201 + +# AAAA RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=16) +076578616d706c6503636f6d00 001c 0001 00015180 0010 +# Address=2001:db8::1 +20010db8000000000000000000000001 + +# A RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=4) +076578616d706c6503636f6d00 0001 0001 00015180 0004 +# Address=192.0.2.2 +c0000202 diff --git a/src/lib/dns/tests/testdata/message_fromWire22.spec b/src/lib/dns/tests/testdata/message_fromWire22.spec new file mode 100644 index 0000000..a52523b --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire22.spec @@ -0,0 +1,14 @@ +# +# A simple DNS message containing one SOA RR in the answer section. This is +# intended to be trimmed to emulate a bogus message. +# + +[custom] +sections: header:question:soa +[header] +qr: 1 +ancount: 1 +[question] +rrtype: SOA +[soa] +as_rr: True diff --git a/src/lib/dns/tests/testdata/message_fromWire22.wire b/src/lib/dns/tests/testdata/message_fromWire22.wire new file mode 100644 index 0000000..69c3254 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire22.wire @@ -0,0 +1,20 @@ +### +### This data file was auto-generated from message_fromWire22.spec +### + +# Header Section +# ID=4149 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) +1035 8000 +# QDCNT=1, ANCNT=1, NSCNT=0, ARCNT=0 +0001 0001 0000 0000 + +# Question Section +# QNAME=example.com. QTYPE=SOA(6) QCLASS=IN(1) +076578616d706c6503636f6d00 0006 0001 + +# SOA RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=54) +076578616d706c6503636f6d00 0006 0001 00015180 0036 +# NNAME=ns.example.com RNAME=root.example.com +026e73076578616d706c6503636f6d00 04726f6f74076578616d706c6503636f6d00 +# SERIAL(2010012601) REFRESH(3600) RETRY(300) EXPIRE(3600000) MINIMUM(1200) +77ce5bb9 00000e10 0000012c 0036ee80 000004b0 diff --git a/src/lib/dns/tests/testdata/message_fromWire3 b/src/lib/dns/tests/testdata/message_fromWire3 new file mode 100644 index 0000000..9bd536a --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire3 @@ -0,0 +1,22 @@ +# +# A simple DNS query message with a valid EDNS0 OPT RR, DO bit off +# ID = 0x1035 +# QR=0 (query), Opcode=0, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=1 +# Question: test.example.com. IN A +1035 0100 +0001 0000 0000 0001 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# EDNS0 OPT RR +# owner name: "." +00 +# TYPE: OPT (41 = 0x29) +00 29 +# CLASS (= UDP size): 4096 +1000 +# TTL (extended RCODE and flags): RCODE=0, version=0, flags=0 +0000 0000 +# RDLEN = 0 +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire4 b/src/lib/dns/tests/testdata/message_fromWire4 new file mode 100644 index 0000000..23eb7cf --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire4 @@ -0,0 +1,23 @@ +# +# A simple DNS query message with a bogus EDNS0 OPT RR (included in the +# answer section) +# ID = 0x1035 +# QR=0 (query), Opcode=0, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=1, NSCOUNT=0, ARCOUNT=0 +# Question: test.example.com. IN A +1035 0100 +0001 0001 0000 0000 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# EDNS0 OPT RR +# owner name: "." +00 +# TYPE: OPT (41 = 0x29) +00 29 +# CLASS (= UDP size): 4096 +1000 +# TTL (extended RCODE and flags): RCODE=0, version=0, flags=DO +0000 8000 +# RDLEN = 0 +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire5 b/src/lib/dns/tests/testdata/message_fromWire5 new file mode 100644 index 0000000..6f08d22 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire5 @@ -0,0 +1,33 @@ +# +# A simple DNS query message with multiple EDNS0 OPT RRs (bogus) +# ID = 0x1035 +# QR=0 (query), Opcode=0, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=2 +# Question: test.example.com. IN A +1035 0100 +0001 0000 0000 0002 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# EDNS0 OPT RR (1st) +# owner name: "." +00 +# TYPE: OPT (41 = 0x29) +00 29 +# CLASS (= UDP size): 4096 +1000 +# TTL (extended RCODE and flags): RCODE=0, version=0, flags=DO +0000 8000 +# RDLEN = 0 +0000 +# EDNS0 OPT RR (2nd) +# owner name: "." +00 +# TYPE: OPT (41 = 0x29) +00 29 +# CLASS (= UDP size): 4096 +1000 +# TTL (extended RCODE and flags): RCODE=0, version=0, flags=DO +0000 8000 +# RDLEN = 0 +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire6 b/src/lib/dns/tests/testdata/message_fromWire6 new file mode 100644 index 0000000..2783fd0 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire6 @@ -0,0 +1,23 @@ +# +# A simple DNS query message with EDNS0 OPT RRs of non root name (bogus) +# ID = 0x1035 +# QR=0 (query), Opcode=0, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=1 +1035 0100 +0001 0000 0000 0001 +# Question: test.example.com. IN A +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# EDNS0 OPT RR +# owner name: "example.com" +#(7) e x a m p l e (3) c o m . + 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# TYPE: OPT (41 = 0x29) +00 29 +# CLASS (= UDP size): 4096 +1000 +# TTL (extended RCODE and flags): RCODE=0, version=0, flags=DO +0000 8000 +# RDLEN = 0 +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire7 b/src/lib/dns/tests/testdata/message_fromWire7 new file mode 100644 index 0000000..4d85314 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire7 @@ -0,0 +1,27 @@ +# +# A simple DNS query message with EDNS0 OPT RRs of compressed owner name +# pointing to root (is this bogus?) +# ID = 0x1035 +# QR=0 (query), Opcode=0, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=1 +#0 1 2 3 +1035 0100 +#4 5 6 7 8 9 10 1 +0001 0000 0000 0001 +# Question: test.example.com. IN A +# 2 3 4 5 6 7 8 9 20 1 2 3 4 5 6 7 8 9 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# EDNS0 OPT RR +# owner name: "example.com" +# pointer = 29 (end of question section) + c0 1d +# TYPE: OPT (41 = 0x29) +00 29 +# CLASS (= UDP size): 4096 +1000 +# TTL (extended RCODE and flags): RCODE=0, version=0, flags=DO +0000 8000 +# RDLEN = 0 +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire8 b/src/lib/dns/tests/testdata/message_fromWire8 new file mode 100644 index 0000000..c950b5e --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire8 @@ -0,0 +1,22 @@ +# +# A simple DNS query message with a valid EDNS0 OPT RR (but unusual UDP size) +# ID = 0x1035 +# QR=0 (query), Opcode=0, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=1 +# Question: test.example.com. IN A +1035 0100 +0001 0000 0000 0001 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# EDNS0 OPT RR +# owner name: "." +00 +# TYPE: OPT (41 = 0x29) +00 29 +# CLASS (= UDP size): 500 +01f4 +# TTL (extended RCODE and flags): RCODE=0, version=0, flags=DO +0000 8000 +# RDLEN = 0 +0000 diff --git a/src/lib/dns/tests/testdata/message_fromWire9 b/src/lib/dns/tests/testdata/message_fromWire9 new file mode 100644 index 0000000..f9ff950 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_fromWire9 @@ -0,0 +1,22 @@ +# +# A simple DNS query message with an unsupported version of EDNS0 +# ID = 0x1035 +# QR=0 (query), Opcode=0, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=1 +# Question: test.example.com. IN A +1035 0100 +0001 0000 0000 0001 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# EDNS0 OPT RR +# owner name: "." +00 +# TYPE: OPT (41 = 0x29) +00 29 +# CLASS (= UDP size): 4096 +1000 +# TTL (extended RCODE and flags): RCODE=0, version=1, flags=DO +0001 8000 +# RDLEN = 0 +0000 diff --git a/src/lib/dns/tests/testdata/message_toText1.spec b/src/lib/dns/tests/testdata/message_toText1.spec new file mode 100644 index 0000000..b31310e --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toText1.spec @@ -0,0 +1,24 @@ +# +# A standard DNS message (taken from an invocation of dig) +# + +[custom] +sections: header:question:a/1:ns:a/2 +[header] +id: 29174 +qr: 1 +aa: 1 +ancount: 1 +nscount: 1 +arcount: 1 +[question] +name: www.example.com +[a/1] +as_rr: True +rr_name: www.example.com +address: 192.0.2.80 +[ns] +as_rr: True +[a/2] +as_rr: True +rr_name: ns.example.com diff --git a/src/lib/dns/tests/testdata/message_toText1.txt b/src/lib/dns/tests/testdata/message_toText1.txt new file mode 100644 index 0000000..58c7239 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toText1.txt @@ -0,0 +1,14 @@ +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 29174 +;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1 + +;; QUESTION SECTION: +;www.example.com. IN A + +;; ANSWER SECTION: +www.example.com. 86400 IN A 192.0.2.80 + +;; AUTHORITY SECTION: +example.com. 86400 IN NS ns.example.com. + +;; ADDITIONAL SECTION: +ns.example.com. 86400 IN A 192.0.2.1 diff --git a/src/lib/dns/tests/testdata/message_toText1.wire b/src/lib/dns/tests/testdata/message_toText1.wire new file mode 100644 index 0000000..2a959bd --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toText1.wire @@ -0,0 +1,28 @@ +### +### This data file was auto-generated from message_toText1.spec +### + +# Header Section +# ID=29174 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) AA +71f6 8400 +# QDCNT=1, ANCNT=1, NSCNT=1, ARCNT=1 +0001 0001 0001 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# A RR (QNAME=www.example.com Class=IN(1) TTL=86400, RDLEN=4) +03777777076578616d706c6503636f6d00 0001 0001 00015180 0004 +# Address=192.0.2.80 +c0000250 + +# NS RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=16) +076578616d706c6503636f6d00 0002 0001 00015180 0010 +# NS name=ns.example.com +026e73076578616d706c6503636f6d00 + +# A RR (QNAME=ns.example.com Class=IN(1) TTL=86400, RDLEN=4) +026e73076578616d706c6503636f6d00 0001 0001 00015180 0004 +# Address=192.0.2.1 +c0000201 diff --git a/src/lib/dns/tests/testdata/message_toText2.spec b/src/lib/dns/tests/testdata/message_toText2.spec new file mode 100644 index 0000000..978aab3 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toText2.spec @@ -0,0 +1,14 @@ +# +# A standard DNS message with EDNS (taken from an invocation of dig) +# + +[custom] +sections: header:question:edns +[header] +id: 45981 +qr: 1 +rcode: refused +arcount: 1 +[question] +[edns] +do: 1 diff --git a/src/lib/dns/tests/testdata/message_toText2.txt b/src/lib/dns/tests/testdata/message_toText2.txt new file mode 100644 index 0000000..42cc2c1 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toText2.txt @@ -0,0 +1,8 @@ +;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 45981 +;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags: do; udp: 4096 + +;; QUESTION SECTION: +;example.com. IN A diff --git a/src/lib/dns/tests/testdata/message_toText2.wire b/src/lib/dns/tests/testdata/message_toText2.wire new file mode 100644 index 0000000..1047b63 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toText2.wire @@ -0,0 +1,19 @@ +### +### This data file was auto-generated from message_toText2.spec +### + +# Header Section +# ID=45981 QR=Response Opcode=QUERY(0) Rcode=REFUSED(5) +b39d 8005 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=example.com. QTYPE=A(1) QCLASS=IN(1) +076578616d706c6503636f6d00 0001 0001 + +# EDNS OPT RR +# NAME=. TYPE=OPT(41) UDPSize=4096 ExtRcode=0 Version=0 DO=1 +00 0029 1000 0000 8000 +# RDLEN=0 +0000 diff --git a/src/lib/dns/tests/testdata/message_toText3.spec b/src/lib/dns/tests/testdata/message_toText3.spec new file mode 100644 index 0000000..a74ea1b --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toText3.spec @@ -0,0 +1,31 @@ +# +# A standard DNS message with TSIG (taken from an invocation of dig) +# + +[custom] +sections: header:question:a/1:ns:a/2:tsig +[header] +id: 10140 +qr: 1 +aa: 1 +ancount: 1 +nscount: 1 +arcount: 2 +[question] +name: www.example.com +[a/1] +as_rr: True +rr_name: www.example.com +address: 192.0.2.80 +[ns] +as_rr: True +[a/2] +as_rr: True +rr_name: ns.example.com +[tsig] +as_rr: True +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 1304384318 +original_id: 10140 +mac: 0x5257c80396f2fa95b20c77ae9a652fb2 diff --git a/src/lib/dns/tests/testdata/message_toText3.txt b/src/lib/dns/tests/testdata/message_toText3.txt new file mode 100644 index 0000000..359b9c5 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toText3.txt @@ -0,0 +1,17 @@ +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10140 +;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2 + +;; QUESTION SECTION: +;www.example.com. IN A + +;; ANSWER SECTION: +www.example.com. 86400 IN A 192.0.2.80 + +;; AUTHORITY SECTION: +example.com. 86400 IN NS ns.example.com. + +;; ADDITIONAL SECTION: +ns.example.com. 86400 IN A 192.0.2.1 + +;; TSIG PSEUDOSECTION: +www.example.com. 0 ANY TSIG hmac-md5.sig-alg.reg.int. 1304384318 300 16 UlfIA5by+pWyDHeummUvsg== 10140 NOERROR 0 diff --git a/src/lib/dns/tests/testdata/message_toText3.wire b/src/lib/dns/tests/testdata/message_toText3.wire new file mode 100644 index 0000000..eb3632b --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toText3.wire @@ -0,0 +1,39 @@ +### +### This data file was auto-generated from message_toText3.spec +### + +# Header Section +# ID=10140 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) AA +279c 8400 +# QDCNT=1, ANCNT=1, NSCNT=1, ARCNT=2 +0001 0001 0001 0002 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# A RR (QNAME=www.example.com Class=IN(1) TTL=86400, RDLEN=4) +03777777076578616d706c6503636f6d00 0001 0001 00015180 0004 +# Address=192.0.2.80 +c0000250 + +# NS RR (QNAME=example.com Class=IN(1) TTL=86400, RDLEN=16) +076578616d706c6503636f6d00 0002 0001 00015180 0010 +# NS name=ns.example.com +026e73076578616d706c6503636f6d00 + +# A RR (QNAME=ns.example.com Class=IN(1) TTL=86400, RDLEN=4) +026e73076578616d706c6503636f6d00 0001 0001 00015180 0004 +# Address=192.0.2.1 +c0000201 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1304384318 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004dbf533e 012c +# MAC Size=16 MAC=(see hex) +0010 5257c80396f2fa95b20c77ae9a652fb2 +# Original-ID=10140 Error=0 +279c 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_toWire1 b/src/lib/dns/tests/testdata/message_toWire1 new file mode 100644 index 0000000..daeb85a --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire1 @@ -0,0 +1,22 @@ +# +# A simple DNS query message +# ID = 0x1035 +# QR=1 (response), Opcode=0, AA=1, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=2, other COUNTS=0 +# Question: test.example.com. IN A +# Answer: +# test.example.com. 3600 IN A 192.0.2.1 +# test.example.com. 7200 IN A 192.0.2.2 +# +1035 8500 +0001 0002 0000 0000 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# same name, fully compressed +c0 0c +# TTL=3600, A, IN, RDLENGTH=4, RDATA +0001 0001 00000e10 0004 c0 00 02 01 +# mostly same, with the slight difference in RDATA +c0 0c +0001 0001 00000e10 0004 c0 00 02 02 diff --git a/src/lib/dns/tests/testdata/message_toWire2.spec b/src/lib/dns/tests/testdata/message_toWire2.spec new file mode 100644 index 0000000..d256052 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire2.spec @@ -0,0 +1,21 @@ +# +# A simple DNS query message with TSIG signed +# + +[custom] +sections: header:question:tsig +[header] +id: 0x2d65 +rd: 1 +arcount: 1 +[question] +name: www.example.com +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +mac: 0x227026ad297beee721ce6c6fff1e9ef3 +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/message_toWire2.wire b/src/lib/dns/tests/testdata/message_toWire2.wire new file mode 100644 index 0000000..a495253 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire2.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from message_toWire2.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 227026ad297beee721ce6c6fff1e9ef3 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_toWire3.spec b/src/lib/dns/tests/testdata/message_toWire3.spec new file mode 100644 index 0000000..c8e9453 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire3.spec @@ -0,0 +1,22 @@ +# +# A simple DNS query message with EDNS and TSIG +# + +[custom] +sections: header:question:edns:tsig +[header] +id: 0x06cd +rd: 1 +arcount: 2 +[question] +name: www.example.com +[edns] +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4db60d1f +mac_size: 16 +mac: 0x93444053881c83d7eb120e86f25b369e +original_id: 0x06cd diff --git a/src/lib/dns/tests/testdata/message_toWire3.wire b/src/lib/dns/tests/testdata/message_toWire3.wire new file mode 100644 index 0000000..46808b9 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire3.wire @@ -0,0 +1,30 @@ +### +### This data file was auto-generated from message_toWire3.spec +### + +# Header Section +# ID=1741 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +06cd 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=2 +0001 0000 0000 0002 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# EDNS OPT RR +# NAME=. TYPE=OPT(41) UDPSize=4096 ExtRcode=0 Version=0 DO=0 +00 0029 1000 0000 0000 +# RDLEN=0 +0000 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1303776543 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004db60d1f 012c +# MAC Size=16 MAC=(see hex) +0010 93444053881c83d7eb120e86f25b369e +# Original-ID=1741 Error=0 +06cd 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_toWire4.spec b/src/lib/dns/tests/testdata/message_toWire4.spec new file mode 100644 index 0000000..aab7e10 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire4.spec @@ -0,0 +1,27 @@ +# +# Truncated DNS response with TSIG signed +# This is expected to be a response to "fromWire17" +# + +[custom] +sections: header:question:tsig +[header] +id: 0x22c2 +rd: 1 +qr: 1 +aa: 1 +# It's "truncated": +tc: 1 +arcount: 1 +[question] +name: www.example.com +rrtype: TXT +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4e179212 +mac_size: 16 +mac: 0x88adc3811d1d6bec7c684438906fc694 +original_id: 0x22c2 diff --git a/src/lib/dns/tests/testdata/message_toWire4.wire b/src/lib/dns/tests/testdata/message_toWire4.wire new file mode 100644 index 0000000..d2cda30 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire4.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from message_toWire4.spec +### + +# Header Section +# ID=8898 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) AA TC RD +22c2 8700 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=TXT(16) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0010 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1310167570 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004e179212 012c +# MAC Size=16 MAC=(see hex) +0010 88adc3811d1d6bec7c684438906fc694 +# Original-ID=8898 Error=0 +22c2 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_toWire5.spec b/src/lib/dns/tests/testdata/message_toWire5.spec new file mode 100644 index 0000000..e316833 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire5.spec @@ -0,0 +1,36 @@ +# +# A longest possible (without EDNS) DNS response with TSIG, i.e. total +# length should be 512 bytes. +# + +[custom] +sections: header:question:txt/1:txt/2:tsig +[header] +id: 0xd6e2 +rd: 1 +qr: 1 +aa: 1 +ancount: 2 +arcount: 1 +[question] +name: www.example.com +rrtype: TXT +[txt/1] +as_rr: True +# QNAME is fully compressed +rr_name: ptr=12 +string: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde +[txt/2] +as_rr: True +# QNAME is fully compressed +rr_name: ptr=12 +string: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0 +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4e17b38d +mac_size: 16 +mac: 0xbe2ba477373d2496891e2fda240ee4ec +original_id: 0xd6e2 diff --git a/src/lib/dns/tests/testdata/message_toWire5.wire b/src/lib/dns/tests/testdata/message_toWire5.wire new file mode 100644 index 0000000..ef7ee6e --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire5.wire @@ -0,0 +1,34 @@ +### +### This data file was auto-generated from message_toWire5.spec +### + +# Header Section +# ID=55010 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) AA RD +d6e2 8500 +# QDCNT=1, ANCNT=2, NSCNT=0, ARCNT=1 +0001 0002 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=TXT(16) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0010 0001 + +# TXT RR (QNAME=ptr=12 Class=IN(1) TTL=86400, RDLEN=256) +c00c 0010 0001 00015180 0100 +# String Len=255, String="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde" +ff 303132333435363738396162636465663031323334353637383961626364656630313233343536373839616263646566303132333435363738396162636465663031323334353637383961626364656630313233343536373839616263646566303132333435363738396162636465663031323334353637383961626364656630313233343536373839616263646566303132333435363738396162636465663031323334353637383961626364656630313233343536373839616263646566303132333435363738396162636465663031323334353637383961626364656630313233343536373839616263646566303132333435363738396162636465 + +# TXT RR (QNAME=ptr=12 Class=IN(1) TTL=86400, RDLEN=114) +c00c 0010 0001 00015180 0072 +# String Len=113, String="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0" +71 3031323334353637383961626364656630313233343536373839616263646566303132333435363738396162636465663031323334353637383961626364656630313233343536373839616263646566303132333435363738396162636465663031323334353637383961626364656630 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1310176141 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004e17b38d 012c +# MAC Size=16 MAC=(see hex) +0010 be2ba477373d2496891e2fda240ee4ec +# Original-ID=55010 Error=0 +d6e2 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/message_toWire6 b/src/lib/dns/tests/testdata/message_toWire6 new file mode 100644 index 0000000..996c99c --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire6 @@ -0,0 +1,48 @@ +# +# A simple DNS query message (with a signed response) +# ID = 0x75c1 +# QR=1 (response), Opcode=0, AA=1, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=4, other COUNTS=0 +# Question: test.example.com. IN A +# Answer: +# test.example.com. 3600 IN A 192.0.2.1 +# test.example.com. 7200 IN A 192.0.2.2 +# +75c1 8500 +0001 0004 0000 0000 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0001 0001 +# same name, fully compressed +c0 0c +# TTL=3600, A, IN, RDLENGTH=4, RDATA +0001 0001 00000e10 0004 c0 00 02 01 +# mostly same, with the slight difference in RDATA +c0 0c +0001 0001 00000e10 0004 c0 00 02 02 + +# signature 1 + +# same name +c0 0c +# RRSIG, IN, TTL=3600, RDLENGTH=0x28 TYPE_COV=A ALGO=5 (RSA/SHA-1) LABELS=3 ORIG_TTL=3600 +002e 0001 00000e10 0028 0001 05 03 00000e10 +# SIG_EXPIRY=20000101000000 SIG_INCEP=20000201000000 KEY_ID=12345 +386d4380 38962200 3039 +#(7) e x a m p l e (3) c o m . + 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# FAKEFAKEFAKE +14 02 84 14 02 84 14 02 84 + +# signature 2 + +# same name +c0 0c +# RRSIG, IN, TTL=3600, RDLENGTH=0x28 TYPE_COV=A ALGO=3 (DSA/SHA-1) LABELS=3 ORIG_TTL=3600 +002e 0001 00000e10 0028 0001 03 03 00000e10 +# SIG_EXPIRY=20000101000000 SIG_INCEP=20000201000000 KEY_ID=12345 +386d4380 38962200 3039 +#(7) e x a m p l e (3) c o m . + 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# FAKEFAKEFAKE +14 02 84 14 02 84 14 02 84 diff --git a/src/lib/dns/tests/testdata/message_toWire7 b/src/lib/dns/tests/testdata/message_toWire7 new file mode 100644 index 0000000..ba22634 --- /dev/null +++ b/src/lib/dns/tests/testdata/message_toWire7 @@ -0,0 +1,35 @@ +# +# A simple DNS query message (with a signed response) +# ID = 0x75c1 +# QR=1 (response), Opcode=0, AA=1, RD=1 (other fields are 0) +# QDCOUNT=1, ANCOUNT=1, ADCOUNT=0 +# Question: test.example.com. IN TXT +# Answer: +# test.example.com. 3600 IN TXT aaaaa... +# +75c1 8700 +0001 0001 0000 0000 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +0010 0001 +# same name, fully compressed +c0 0c +# TTL=3600, TXT, IN, RDLENGTH=256, RDATA +0010 0001 00000e10 0100 ff +# 'a' repeated 255 times +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 +61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 diff --git a/src/lib/dns/tests/testdata/name_fromWire1 b/src/lib/dns/tests/testdata/name_fromWire1 new file mode 100644 index 0000000..42fc61d --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire1 @@ -0,0 +1,14 @@ +# +# a global14 compression pointer +# +000a85800001000300000003 +# V i x c o m +0356697803636f6d0000020001c00c00 +02000100000e10000b05697372763102 +7061c00cc00c0002000100000e100009 +066e732d657874c00cc00c0002000100 +000e10000e036e733104676e61630363 +6f6d00c0250001000100000e100004cc +98b886c03c0001000100000e100004cc +98b840c051000100010002a14a0004c6 +97f8f6 diff --git a/src/lib/dns/tests/testdata/name_fromWire10 b/src/lib/dns/tests/testdata/name_fromWire10 new file mode 100644 index 0000000..65be775 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire10 @@ -0,0 +1,12 @@ +# +# Too large name; should trigger an exception. +# +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 040102030400 diff --git a/src/lib/dns/tests/testdata/name_fromWire11 b/src/lib/dns/tests/testdata/name_fromWire11 new file mode 100644 index 0000000..32184f6 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire11 @@ -0,0 +1,12 @@ +# +# A name with possible maximum number of labels; should be accepted safely. +# +01000100010001000100 01000100010001000100 01000100010001000100 +01000100010001000100 01000100010001000100 01000100010001000100 +01000100010001000100 01000100010001000100 01000100010001000100 +01000100010001000100 01000100010001000100 01000100010001000100 +01000100010001000100 01000100010001000100 01000100010001000100 +01000100010001000100 01000100010001000100 01000100010001000100 +01000100010001000100 01000100010001000100 01000100010001000100 +01000100010001000100 01000100010001000100 01000100010001000100 +01000100010001000100 0100010000 diff --git a/src/lib/dns/tests/testdata/name_fromWire12 b/src/lib/dns/tests/testdata/name_fromWire12 new file mode 100644 index 0000000..073adda --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire12 @@ -0,0 +1,13 @@ +# +# Wire format including an invalid label length +# +#(1) a (7) e x a m p l e + 01 61 07 65 78 61 6d 70 6c 65 +# invalid label length: 64 +40 +# a "label" of 64 characters: shouldn't be parsed +00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f +10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f +20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f +30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f +00 diff --git a/src/lib/dns/tests/testdata/name_fromWire13 b/src/lib/dns/tests/testdata/name_fromWire13 new file mode 100644 index 0000000..447f54b --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire13 @@ -0,0 +1,5 @@ +# +# A name including all "printable" characters +# + +3f2122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f1f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e00 diff --git a/src/lib/dns/tests/testdata/name_fromWire14 b/src/lib/dns/tests/testdata/name_fromWire14 new file mode 100644 index 0000000..3123aec --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire14 @@ -0,0 +1,7 @@ +# +# A name including all "non-printable" characters +# + +3f000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f207f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c +3f9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadb +24dcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff00 diff --git a/src/lib/dns/tests/testdata/name_fromWire2 b/src/lib/dns/tests/testdata/name_fromWire2 new file mode 100644 index 0000000..0758a68 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire2 @@ -0,0 +1,15 @@ +# +# bogus label character (looks like a local compression pointer) +# +000a85800001000300000003 +#this is the bogus label character: +83 +76697803636f6d0000020001c00c00 +02000100000e10000b05697372763102 +7061c00cc00c0002000100000e100009 +066e732d657874c00cc00c0002000100 +000e10000e036e733104676e61630363 +6f6d00c0250001000100000e100004cc +98b886c03c0001000100000e100004cc +98b840c051000100010002a14a0004c6 +97f8f6 diff --git a/src/lib/dns/tests/testdata/name_fromWire3_1 b/src/lib/dns/tests/testdata/name_fromWire3_1 new file mode 100644 index 0000000..e38efcc --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire3_1 @@ -0,0 +1,11 @@ +# +# a bad compression pointer starting with the bits 1111 (too big pointer) +# +000a85800001000300000003 +03766978 03636f6d 00 0002 0001 +f00c 0002 0001 0000 0e10 000b 056973727631 027061 c00c +c00c 0002 0001 0000 0e10 0009 066e732d657874 c00c +c00c 0002 0001 0000 0e10 000e 036e7331 04676e6163 03636f6d 00 +c025 0001 0001 0000 0e10 0004 cc98b886 +c03c 0001 0001 0000 0e10 0004 cc98b840 +c051 0001 0001 0002 a14a 0004 c697f8f6 diff --git a/src/lib/dns/tests/testdata/name_fromWire3_2 b/src/lib/dns/tests/testdata/name_fromWire3_2 new file mode 100644 index 0000000..c377bb1 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire3_2 @@ -0,0 +1,13 @@ +# +# a bad compression pointer due to forward reference of 0x30 to +# another compression pointer with a valid backreference +# +000a85800001000300000003 +03766978 03636f6d 00 0002 0001 +#'30' is the forward reference, 'c00c' at the end is the valid pointer: +c030 0002 0001 0000 0e10 000b 056973727631 027061 c00c +c00c 0002 0001 0000 0e10 0009 066e732d657874 c00c +c00c 0002 0001 0000 0e10 000e 036e7331 04676e6163 03636f6d 00 +c025 0001 0001 0000 0e10 0004 cc98b886 +c03c 0001 0001 0000 0e10 0004 cc98b840 +c051 0001 0001 0002 a14a 0004 c697f8f6 diff --git a/src/lib/dns/tests/testdata/name_fromWire4 b/src/lib/dns/tests/testdata/name_fromWire4 new file mode 100644 index 0000000..dba6035 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire4 @@ -0,0 +1,45 @@ +# +# invalid name length, pointer at offset 0x0226 points to +# long name at offset 0x25 +# +000a 8580 0001 0003 0000 0001 +03 766978 03 636f6d 00 0002 0001 +c00c 0002 0001 00000e10 +0101 +# long name starts here +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a +03616263 0358595a 03616263 0358595a +03414243 0378797a 03414243 0378797a 00 +# compression pointer start here and refers back to long name +c023 0002 0001 00000e10 0009 066e732d657874 c00c +c00c 0002 0001 00000e10 000e 036e733104676e616303636f6d00 +c025 0001 0001 00000e10 0004 cc98b886 diff --git a/src/lib/dns/tests/testdata/name_fromWire6 b/src/lib/dns/tests/testdata/name_fromWire6 new file mode 100644 index 0000000..fa1abe6 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire6 @@ -0,0 +1,14 @@ +# +# a bad pointer +# +000a85800001000300000003 +# the bad pointer is f00c (offset = 300c) which is too large +0376697803636f6d0000020001 f00c 00 +02000100000e10000b05697372763102 +7061c00cc00c0002000100000e100009 +066e732d657874c00cc00c0002000100 +000e10000e036e733104676e61630363 +6f6d00c0250001000100000e100004cc +98b886c03c0001000100000e100004cc +98b840c051000100010002a14a0004c6 +97f8f6 diff --git a/src/lib/dns/tests/testdata/name_fromWire7 b/src/lib/dns/tests/testdata/name_fromWire7 new file mode 100644 index 0000000..2dedd4a --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire7 @@ -0,0 +1,6 @@ +# +# input ends unexpectedly +# +000a85800001000300000003 +# parser will start at the ending 'c0', which is an incomplete sequence. +0376697803636f6d0000020001 c0 diff --git a/src/lib/dns/tests/testdata/name_fromWire8 b/src/lib/dns/tests/testdata/name_fromWire8 new file mode 100644 index 0000000..575563d --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire8 @@ -0,0 +1,27 @@ +# +# many hops of compression. absolutely many, but should be decompressed. +# +000a85800001000300000013 +03 766978 03 636f6d 00 0002 0001 +c00c 0002 0001 00000e10 000b 056973727631027061 c00c +c019 0002 0001 00000e10 0009 066e732d657874 c00c +c030 0002 0001 00000e10 000e 036e7331 04676e6163 03636f6d 00 +c045 0001 0001 00000e10 0004 cc98b886 +c05f 0001 0001 00000e10 0004 cc98b840 +c06f 0001 0001 0002a14a 0004 c697f8f6 +c07f 0001 0001 0002a14a 0004 c697f8f6 +c08f 0001 0001 0002a14a 0004 c697f8f6 +c09f 0001 0001 0002a14a 0004 c697f8f6 +c0af 0001 0001 0002a14a 0004 c697f8f6 +c0bf 0001 0001 0002a14a 0004 c697f8f6 +c0cf 0001 0001 0002a14a 0004 c697f8f6 +c0df 0001 0001 0002a14a 0004 c697f8f6 +c0ef 0001 0001 0002a14a 0004 c697f8f6 +c0ff 0001 0001 0002a14a 0004 c697f8f6 +c10f 0001 0001 0002a14a 0004 c697f8f6 +c11f 0001 0001 0002a14a 0004 c697f8f6 +c12f 0001 0001 0002a14a 0004 c697f8f6 +c13f 0001 0001 0002a14a 0004 c697f8f6 +c14f 0001 0001 0002a14a 0004 c697f8f6 +c15f 0001 0001 0002a14a 0004 c697f8f6 +c16f 0001 0001 0002a14a 0004 c697f8f6 diff --git a/src/lib/dns/tests/testdata/name_fromWire9 b/src/lib/dns/tests/testdata/name_fromWire9 new file mode 100644 index 0000000..79b2978 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_fromWire9 @@ -0,0 +1,12 @@ +# +# A possible longest name; should be accepted safely. +# +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 09010203040506070809 09010203040506070809 +09010203040506070809 0301020300 diff --git a/src/lib/dns/tests/testdata/name_toWire1 b/src/lib/dns/tests/testdata/name_toWire1 new file mode 100644 index 0000000..c06ec4b --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire1 @@ -0,0 +1,12 @@ +# +# Rendering 3 names with compression. [x] means a compression pointer pointing +# to offset 'x'. +# +#bytes: +# 0 1 2 3 4 5 6 7 8 9 a b c d e +#(1)a(7)e x a m p l e(3)c o m . + 0161076578616d706c6503636f6d00 +#(1)b [2] + 0162c002 +# a . e x a m p l e . o r g . + 0161076578616d706c65036f726700 diff --git a/src/lib/dns/tests/testdata/name_toWire2 b/src/lib/dns/tests/testdata/name_toWire2 new file mode 100644 index 0000000..2377121 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire2 @@ -0,0 +1,14 @@ +# +# Rendering names in a large buffer. [x] means a compression pointer pointing +# to offset 'x'. +# +#bytes: +#3f 40 +#ff 00 +#(1) a (7) e x a m p l e (3) c o m . + 01 61 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +#[3fff] = a.example.com: can be compressed + ffff +#(1) b(7) e x a m p l e (3) c o m .; cannot compress as the pointer +# (0x4001) would exceed 0x4000 + 01 62 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 diff --git a/src/lib/dns/tests/testdata/name_toWire3 b/src/lib/dns/tests/testdata/name_toWire3 new file mode 100644 index 0000000..08c1474 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire3 @@ -0,0 +1,14 @@ +# +# Rendering names including one explicitly uncompressed. +# [x] means a compression pointer pointing to offset 'x'. +# +# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 (bytes) +#(1) a (7) e x a m p l e (3) c o m . + 01 61 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 + +#15 29 (bytes) +#(1) b (7) e x a m p l e (3) c o m .; specified to be not compressed, +# but can be pointed to from others + 01 62 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +#[0f] referring to the second (uncompressed name) + c0 0f diff --git a/src/lib/dns/tests/testdata/name_toWire4 b/src/lib/dns/tests/testdata/name_toWire4 new file mode 100644 index 0000000..740d718 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire4 @@ -0,0 +1,16 @@ +# +# Rendering 3 names with compression, including one resulting in a chain of +# pointers (the last one). +# legend: [x] means a compression pointer pointing to offset 'x'. +#bytes: +#00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e +#(1) a (7) e x a m p l e (3) c o m . + 01 61 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 + +#0f 10 11 12 +#(1) b [2] (b.example.com.) + 01 62 c0 02 + +#13 14 +# [0f]: (b.example.com.) + c0 0f diff --git a/src/lib/dns/tests/testdata/name_toWire5.spec b/src/lib/dns/tests/testdata/name_toWire5.spec new file mode 100644 index 0000000..87e140d --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire5.spec @@ -0,0 +1,19 @@ +# +# A sequence of names that would be compressed case-sensitive manner. +# First name: "a.example.com" +# Second name: "b.eXample.com". Due to case-sensitive comparison only "com" +# can be compressed. +# Third name: "c.eXample.com". "eXample.com" part matches that of the second +# name and can be compressed. +# + +[custom] +sections: name/1:name/2:name/3 +[name/1] +name: a.example.com +[name/2] +name: b.eXample +pointer: 10 +[name/3] +name: c +pointer: 17 diff --git a/src/lib/dns/tests/testdata/name_toWire5.wire b/src/lib/dns/tests/testdata/name_toWire5.wire new file mode 100644 index 0000000..c6e62ed --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire5.wire @@ -0,0 +1,12 @@ +### +### This data file was auto-generated from name_toWire5.spec +### + +# DNS Name: a.example.com +0161076578616d706c6503636f6d00 + +# DNS Name: b.eXample + compression pointer: 10 +0162076558616d706c65c00a + +# DNS Name: c + compression pointer: 17 +0163c011 diff --git a/src/lib/dns/tests/testdata/name_toWire6.spec b/src/lib/dns/tests/testdata/name_toWire6.spec new file mode 100644 index 0000000..a536f5d --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire6.spec @@ -0,0 +1,19 @@ +# +# A sequence of names that would be compressed both case-sensitive and +# case-insensitive manner (unusual, but allowed). +# First and second name: see name_toWire5.spec. +# Third name: "c.b.EXAMPLE.com". This is rendered with case-insensitive +# compression, so "b.EXAMPLE.com" part of the name matches that of the +# second name. +# + +[custom] +sections: name/1:name/2:name/3 +[name/1] +name: a.example.com +[name/2] +name: b.eXample +pointer: 10 +[name/3] +name: c +pointer: 15 diff --git a/src/lib/dns/tests/testdata/name_toWire6.wire b/src/lib/dns/tests/testdata/name_toWire6.wire new file mode 100644 index 0000000..dcaa39f --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire6.wire @@ -0,0 +1,12 @@ +### +### This data file was auto-generated from name_toWire6.spec +### + +# DNS Name: a.example.com +0161076578616d706c6503636f6d00 + +# DNS Name: b.eXample + compression pointer: 10 +0162076558616d706c65c00a + +# DNS Name: c + compression pointer: 15 +0163c00f diff --git a/src/lib/dns/tests/testdata/name_toWire7 b/src/lib/dns/tests/testdata/name_toWire7 new file mode 100644 index 0000000..bff599f --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire7 @@ -0,0 +1,10 @@ +# +# Rendering names including one explicitly uncompressed. +# [x] means a compression pointer pointing to offset 'x'. +# +# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 (bytes) +#(1) a (7) e x a m p l e (3) c o m . + 01 61 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 + +#[02] pointing to -> "example.com." + c0 02 diff --git a/src/lib/dns/tests/testdata/name_toWire8 b/src/lib/dns/tests/testdata/name_toWire8 new file mode 100644 index 0000000..d01093b --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire8 @@ -0,0 +1,7 @@ +# +# Rendering names. +# [x] means a compression pointer pointing to offset 'x'. +# +# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 (bytes) +#(1) a (7) e x a m p l e (3) c o m + 01 61 07 65 78 61 6d 70 6c 65 03 63 6f 6d diff --git a/src/lib/dns/tests/testdata/name_toWire9 b/src/lib/dns/tests/testdata/name_toWire9 new file mode 100644 index 0000000..51a1987 --- /dev/null +++ b/src/lib/dns/tests/testdata/name_toWire9 @@ -0,0 +1,13 @@ +# +# Rendering names including one explicitly uncompressed. +# [x] means a compression pointer pointing to offset 'x'. +# +# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 (bytes) +#(1) a (7) e x a m p l e (3) c o m . + 01 61 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +#(1) a (7) e x a m p l e (3) c o m + 01 61 07 65 78 61 6d 70 6c 65 03 63 6f 6d +#(1) a (7) e x a m p l e + 01 61 07 65 78 61 6d 70 6c 65 +#[1f] pointing to ^^ "example" + c0 1f diff --git a/src/lib/dns/tests/testdata/omitcheck.txt b/src/lib/dns/tests/testdata/omitcheck.txt new file mode 100644 index 0000000..580cab4 --- /dev/null +++ b/src/lib/dns/tests/testdata/omitcheck.txt @@ -0,0 +1 @@ + 1H IN A 192.0.2.1 diff --git a/src/lib/dns/tests/testdata/origincheck.txt b/src/lib/dns/tests/testdata/origincheck.txt new file mode 100644 index 0000000..c370ed2 --- /dev/null +++ b/src/lib/dns/tests/testdata/origincheck.txt @@ -0,0 +1,5 @@ +; We change the origin here. We want to check it is not propagated +; outside of the included file. +$ORIGIN www.example.org. + +@ 1H IN A 192.0.2.1 diff --git a/src/lib/dns/tests/testdata/question_fromWire b/src/lib/dns/tests/testdata/question_fromWire new file mode 100644 index 0000000..cbc28c0 --- /dev/null +++ b/src/lib/dns/tests/testdata/question_fromWire @@ -0,0 +1,33 @@ +# +# Wire-format data of a sequence of DNS questions. +# foo.example.com. IN NS +# bar.example.com. CH A (owner name is compressed) +# and some pathological cases +# +# 0 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 (-th byte) +#(3) f o o (7) e x a m p l e (3) c o m . + 03 66 6f 6f 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +#7 8 9 20 +# type/class: NS = 2, IN = 1 +00 02 00 01 + +# 1 2 3 4 5 6 +#(3) b a r [ptr=0x04] + 03 62 61 72 c0 04 +#7 8 9 30 +# type/class: A = 1, CH = 3 +00 01 00 03 + +# owner name is broken +#1 +# invalid label type +ff +#2 3 4 5 +#type/class IN/A +00 01 00 01 + +# short buffer +# (root name) +00 +#class is missing +00 01 diff --git a/src/lib/dns/tests/testdata/question_toWire1 b/src/lib/dns/tests/testdata/question_toWire1 new file mode 100644 index 0000000..77886db --- /dev/null +++ b/src/lib/dns/tests/testdata/question_toWire1 @@ -0,0 +1,14 @@ +# +# Rendering two DNS Questions without name compression +# foo.example.com. IN NS +# bar.example.com. CH A +# +#(3) f o o (7) e x a m p l e (3) c o m . + 03 66 6f 6f 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# type/class: NS = 2, IN = 1 +00 02 00 01 +#(3) b a r (7) e x a m p l e (3) c o m . + 03 62 61 72 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +#7 8 9 30 +# type/class: A = 1, CH = 3 +00 01 00 03 diff --git a/src/lib/dns/tests/testdata/question_toWire2 b/src/lib/dns/tests/testdata/question_toWire2 new file mode 100644 index 0000000..9117ab2 --- /dev/null +++ b/src/lib/dns/tests/testdata/question_toWire2 @@ -0,0 +1,14 @@ +# +# Rendering two DNS Questions with name compression +# foo.example.com. IN NS +# bar.example.com. CH A +# +# 0 1 2 3 4 ... (-th byte) +#(3) f o o (7) e x a m p l e (3) c o m . + 03 66 6f 6f 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# type/class: NS = 2, IN = 1 +00 02 00 01 +#(3) b a r [ptr=0x04] + 03 62 61 72 c0 04 +# type/class: A = 1, CH = 3 +00 01 00 03 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_fromWire1.spec b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire1.spec new file mode 100644 index 0000000..f831313 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire1.spec @@ -0,0 +1,3 @@ +[custom] +sections: afsdb +[afsdb] diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_fromWire1.wire b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire1.wire new file mode 100644 index 0000000..b32776b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire1.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_afsdb_fromWire1.spec +### + +# AFSDB RDATA, RDLEN=21 +0015 +# SUBTYPE=1 SERVER=afsdb.example.com +0001 056166736462076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire2.spec new file mode 100644 index 0000000..f33e768 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire2.spec @@ -0,0 +1,6 @@ +[custom] +sections: name:afsdb +[name] +name: example.com +[afsdb] +server: afsdb.ptr=0 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire2.wire new file mode 100644 index 0000000..fdc53c5 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire2.wire @@ -0,0 +1,11 @@ +### +### This data file was auto-generated from rdata_afsdb_fromWire2.spec +### + +# DNS Name: example.com +076578616d706c6503636f6d00 + +# AFSDB RDATA, RDLEN=10 +000a +# SUBTYPE=1 SERVER=afsdb.ptr=0 +0001 056166736462c000 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire3.spec new file mode 100644 index 0000000..993032f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire3.spec @@ -0,0 +1,4 @@ +[custom] +sections: afsdb +[afsdb] +rdlen: 3 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_fromWire3.wire b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire3.wire new file mode 100644 index 0000000..7ea4342 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire3.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_afsdb_fromWire3.spec +### + +# AFSDB RDATA, RDLEN=3 +0003 +# SUBTYPE=1 SERVER=afsdb.example.com +0001 056166736462076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire4.spec new file mode 100644 index 0000000..37abf13 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire4.spec @@ -0,0 +1,4 @@ +[custom] +sections: afsdb +[afsdb] +rdlen: 80 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire4.wire new file mode 100644 index 0000000..79ff6c2 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire4.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_afsdb_fromWire4.spec +### + +# AFSDB RDATA, RDLEN=80 +0050 +# SUBTYPE=1 SERVER=afsdb.example.com +0001 056166736462076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire5.spec new file mode 100644 index 0000000..0ea79dd --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire5.spec @@ -0,0 +1,4 @@ +[custom] +sections: afsdb +[afsdb] +server: "01234567890123456789012345678901234567890123456789012345678901234" diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_fromWire5.wire b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire5.wire new file mode 100644 index 0000000..13eb016 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_fromWire5.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_afsdb_fromWire5.spec +### + +# AFSDB RDATA, RDLEN=71 +0047 +# SUBTYPE=1 SERVER="01234567890123456789012345678901234567890123456789012345678901234" +0001 432230313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233342200 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_toWire1.spec b/src/lib/dns/tests/testdata/rdata_afsdb_toWire1.spec new file mode 100644 index 0000000..1946458 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_toWire1.spec @@ -0,0 +1,4 @@ +[custom] +sections: afsdb +[afsdb] +rdlen: -1 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_toWire1.wire b/src/lib/dns/tests/testdata/rdata_afsdb_toWire1.wire new file mode 100644 index 0000000..7746fa6 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_toWire1.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_afsdb_toWire1.spec +### + +# AFSDB RDATA + +# SUBTYPE=1 SERVER=afsdb.example.com +0001 056166736462076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_toWire2.spec b/src/lib/dns/tests/testdata/rdata_afsdb_toWire2.spec new file mode 100644 index 0000000..c80011a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_toWire2.spec @@ -0,0 +1,8 @@ +[custom] +sections: name:afsdb +[name] +name: example.com. +[afsdb] +subtype: 0 +server: root.example.com +rdlen: -1 diff --git a/src/lib/dns/tests/testdata/rdata_afsdb_toWire2.wire b/src/lib/dns/tests/testdata/rdata_afsdb_toWire2.wire new file mode 100644 index 0000000..7f01512 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_afsdb_toWire2.wire @@ -0,0 +1,11 @@ +### +### This data file was auto-generated from rdata_afsdb_toWire2.spec +### + +# DNS Name: example.com. +076578616d706c6503636f6d00 + +# AFSDB RDATA + +# SUBTYPE=0 SERVER=root.example.com +0000 04726f6f74076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_caa_fromWire1.spec b/src/lib/dns/tests/testdata/rdata_caa_fromWire1.spec new file mode 100644 index 0000000..d21987c --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_caa_fromWire1.spec @@ -0,0 +1,6 @@ +# +# The simplest form of CAA: all default parameters +# +[custom] +sections: caa +[caa] diff --git a/src/lib/dns/tests/testdata/rdata_caa_fromWire1.wire b/src/lib/dns/tests/testdata/rdata_caa_fromWire1.wire new file mode 100644 index 0000000..780bd8d --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_caa_fromWire1.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_caa_fromWire1.spec +### + +# CAA RDATA, RDLEN=21 +0015 +# FLAGS=0 TAG=issue VALUE=ca.example.net +00 05 697373756563612e6578616d706c652e6e6574 diff --git a/src/lib/dns/tests/testdata/rdata_caa_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_caa_fromWire2.spec new file mode 100644 index 0000000..867e43d --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_caa_fromWire2.spec @@ -0,0 +1,7 @@ +# +# Mixed case CAA tag field. +# +[custom] +sections: caa +[caa] +tag: 'ISSue' diff --git a/src/lib/dns/tests/testdata/rdata_caa_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_caa_fromWire2.wire new file mode 100644 index 0000000..09ca24d --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_caa_fromWire2.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_caa_fromWire2.spec +### + +# CAA RDATA, RDLEN=21 +0015 +# FLAGS=0 TAG=ISSue VALUE=ca.example.net +00 05 495353756563612e6578616d706c652e6e6574 diff --git a/src/lib/dns/tests/testdata/rdata_caa_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_caa_fromWire3.spec new file mode 100644 index 0000000..9297151 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_caa_fromWire3.spec @@ -0,0 +1,7 @@ +# +# Missing CAA value field. +# +[custom] +sections: caa +[caa] +value: '' diff --git a/src/lib/dns/tests/testdata/rdata_caa_fromWire3.wire b/src/lib/dns/tests/testdata/rdata_caa_fromWire3.wire new file mode 100644 index 0000000..16b5c43 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_caa_fromWire3.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_caa_fromWire3.spec +### + +# CAA RDATA, RDLEN=7 +0007 +# FLAGS=0 TAG=issue VALUE= +00 05 6973737565 diff --git a/src/lib/dns/tests/testdata/rdata_caa_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_caa_fromWire4.spec new file mode 100644 index 0000000..53e16b1 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_caa_fromWire4.spec @@ -0,0 +1,7 @@ +# +# Missing CAA value field. +# +[custom] +sections: caa +[caa] +tag: '' diff --git a/src/lib/dns/tests/testdata/rdata_caa_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_caa_fromWire4.wire new file mode 100644 index 0000000..3225e60 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_caa_fromWire4.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_caa_fromWire4.spec +### + +# CAA RDATA, RDLEN=16 +0010 +# FLAGS=0 TAG= VALUE=ca.example.net +00 00 63612e6578616d706c652e6e6574 diff --git a/src/lib/dns/tests/testdata/rdata_caa_fromWire5 b/src/lib/dns/tests/testdata/rdata_caa_fromWire5 new file mode 100644 index 0000000..123011f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_caa_fromWire5 @@ -0,0 +1,6 @@ +# Test where CAA value field is shorter than the RDATA length + +# CAA RDATA, RDLEN=32 +0020 +# FLAGS=0 TAG=c VALUE=ca.example.net +00 01 63 63612e6578616d706c652e6e6574 diff --git a/src/lib/dns/tests/testdata/rdata_caa_fromWire6 b/src/lib/dns/tests/testdata/rdata_caa_fromWire6 new file mode 100644 index 0000000..1a35a1a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_caa_fromWire6 @@ -0,0 +1,4 @@ +# Test where RDATA is completely missing + +# CAA RDATA, RDLEN=32 +0020 diff --git a/src/lib/dns/tests/testdata/rdata_cname_fromWire b/src/lib/dns/tests/testdata/rdata_cname_fromWire new file mode 100644 index 0000000..57eae13 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_cname_fromWire @@ -0,0 +1,44 @@ +# +# various kinds of CNAME RDATA stored in an input buffer +# +# Valid non-compressed RDATA for cn.example.com. +# RDLENGTH=16 bytes +# 0 1 + 00 10 +# 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7(bytes) +#(2) c n (7) e x a m p l e (3) c o m . + 02 63 6e 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# +# short length +# 8 9 + 00 0f +#20 1 2 3 4 5 6 7 8 9 30 1 2 3 4 5 + 02 63 6e 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# +# length too long +# 6 7 + 00 11 +# +# 8 9 40 1 2 3 4 5 6 7 8 9 50 1 2 3 4 + 02 63 6e 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 +# +# Valid compressed CNAME name: 'cn2' + pointer +# 5 6 + 00 06 +# 7 8 9 60 1 2 +#(3) c n 2 ptr=5 + 03 63 6e 32 c0 05 +# +# Valid compressed CNAME name but RDLENGTH is incorrect: it must be the length +# of the sequence from the head to the pointer, not the decompressed name +# length. +# 3 4 + 00 11 +# 5 6 7 8 9 70 + 03 63 6e 32 c0 05 +# incomplete name (no trailing dot). this can be tested only at the end of +# the buffer. +# 1 2 + 00 0f +# 3 4 5 6 7 8 9 80 1 2 3 4 5 6 7 + 02 63 6e 07 65 78 61 6d 70 6c 65 03 63 6f 6d diff --git a/src/lib/dns/tests/testdata/rdata_dhcid_fromWire b/src/lib/dns/tests/testdata/rdata_dhcid_fromWire new file mode 100644 index 0000000..b28b5b3 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_dhcid_fromWire @@ -0,0 +1,12 @@ +# +# DHCID RDATA stored in an input buffer +# +# Valid RDATA for 0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA= +# +# RDLENGTH=41 bytes +# 0 1 + 00 29 +# 0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA= +d0 b2 20 d0 bb d0 b5 d1 81 d1 83 20 d1 80 d0 be +d0 b4 d0 b8 d0 bb d0 b0 d1 81 d1 8c 20 d1 91 d0 +bb d0 be d1 87 d0 ba d0 b0 diff --git a/src/lib/dns/tests/testdata/rdata_dhcid_toWire b/src/lib/dns/tests/testdata/rdata_dhcid_toWire new file mode 100644 index 0000000..99ec229 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_dhcid_toWire @@ -0,0 +1,7 @@ +# +# DHCID RDATA stored in an output buffer +# +# 0LIg0LvQtdGB0YMg0YDQvtC00LjQu9Cw0YHRjCDRkdC70L7Rh9C60LA= +d0 b2 20 d0 bb d0 b5 d1 81 d1 83 20 d1 80 d0 be +d0 b4 d0 b8 d0 bb d0 b0 d1 81 d1 8c 20 d1 91 d0 +bb d0 be d1 87 d0 ba d0 b0 diff --git a/src/lib/dns/tests/testdata/rdata_dname_fromWire b/src/lib/dns/tests/testdata/rdata_dname_fromWire new file mode 100644 index 0000000..1c899bf --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_dname_fromWire @@ -0,0 +1,44 @@ +# +# various kinds of DNAME RDATA stored in an input buffer +# +# Valid non-compressed RDATA for dn.example.com. +# RDLENGTH=16 bytes +# 0 1 + 00 10 +# 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7(bytes) +#(2) d n (7) e x a m p l e (3) c o m . + 02 64 6e 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# +# short length +# 8 9 + 00 0f +#20 1 2 3 4 5 6 7 8 9 30 1 2 3 4 5 + 02 64 6e 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# +# length too long +# 6 7 + 00 11 +# +# 8 9 40 1 2 3 4 5 6 7 8 9 50 1 2 3 4 + 02 64 6e 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 +# +# Valid compressed DNAME name: 'dn2' + pointer +# 5 6 + 00 06 +# 7 8 9 60 1 2 +#(3) d n 2 ptr=5 + 03 64 6e 32 c0 05 +# +# Valid compressed DNAME name but RDLENGTH is incorrect: it must be the length +# of the sequence from the head to the pointer, not the decompressed name +# length. +# 3 4 + 00 11 +# 5 6 7 8 9 70 + 03 64 6e 32 c0 05 +# incomplete name (no trailing dot). this can be tested only at the end of +# the buffer. +# 1 2 + 00 0f +# 3 4 5 6 7 8 9 80 1 2 3 4 5 6 7 + 02 64 6e 07 65 78 61 6d 70 6c 65 03 63 6f 6d diff --git a/src/lib/dns/tests/testdata/rdata_dnskey_empty_keydata_fromWire.spec b/src/lib/dns/tests/testdata/rdata_dnskey_empty_keydata_fromWire.spec new file mode 100644 index 0000000..b65271d --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_dnskey_empty_keydata_fromWire.spec @@ -0,0 +1,7 @@ +# DNSKEY test data with empty digest + +[custom] +sections: dnskey + +[dnskey] +digest: diff --git a/src/lib/dns/tests/testdata/rdata_dnskey_empty_keydata_fromWire.wire b/src/lib/dns/tests/testdata/rdata_dnskey_empty_keydata_fromWire.wire new file mode 100644 index 0000000..35388b1 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_dnskey_empty_keydata_fromWire.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_dnskey_empty_keydata_fromWire.spec +### + +# DNSKEY RDATA, RDLEN=4 +0004 +# FLAGS=257 +0101 +# PROTOCOL=3 +03 +# ALGORITHM=5 +05 +# DIGEST= + diff --git a/src/lib/dns/tests/testdata/rdata_dnskey_fromWire.spec b/src/lib/dns/tests/testdata/rdata_dnskey_fromWire.spec new file mode 100644 index 0000000..87e66db --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_dnskey_fromWire.spec @@ -0,0 +1,7 @@ +# DNSKEY test data + +[custom] +sections: dnskey + +[dnskey] +digest: BEAAAAOhHQDBrhQbtphgq2wQUpEQ5t4DtUHxoMVFu2hWLDMvoOMRXjGrhhCeFvAZih7yJHf8ZGfW6hd38hXG/xylYCO6Krpbdojwx8YMXLA5/kA+u50WIL8ZR1R6KTbsYVMf/Qx5RiNbPClw+vT+U8eXEJmO20jIS1ULgqy347cBB1zMnnz/4LJpA0da9CbKj3A254T515sNIMcwsB8/2+2E63/zZrQzBkj0BrN/9Bexjpiks3jRhZatEsXn3dTy47R09Uix5WcJt+xzqZ7+ysyLKOOedS39Z7SDmsn2eA0FKtQpwA6LXeG2w+jxmw3oA8lVUgEf/rzeC/bByBNsO70aEFTd diff --git a/src/lib/dns/tests/testdata/rdata_dnskey_fromWire.wire b/src/lib/dns/tests/testdata/rdata_dnskey_fromWire.wire new file mode 100644 index 0000000..0a2e41f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_dnskey_fromWire.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_dnskey_fromWire.spec +### + +# DNSKEY RDATA, RDLEN=265 +0109 +# FLAGS=257 +0101 +# PROTOCOL=3 +03 +# ALGORITHM=5 +05 +# DIGEST=BEAAAAOhHQDBrhQbtphgq2wQUpEQ5t4DtUHxoMVFu2hWLDMvoOMRXjGrhhCeFvAZih7yJHf8ZGfW6hd38hXG/xylYCO6Krpbdojwx8YMXLA5/kA+u50WIL8ZR1R6KTbsYVMf/Qx5RiNbPClw+vT+U8eXEJmO20jIS1ULgqy347cBB1zMnnz/4LJpA0da9CbKj3A254T515sNIMcwsB8/2+2E63/zZrQzBkj0BrN/9Bexjpiks3jRhZatEsXn3dTy47R09Uix5WcJt+xzqZ7+ysyLKOOedS39Z7SDmsn2eA0FKtQpwA6LXeG2w+jxmw3oA8lVUgEf/rzeC/bByBNsO70aEFTd +0440000003a11d00c1ae141bb69860ab6c10529110e6de03b541f1a0c545bb68562c332fa0e3115e31ab86109e16f0198a1ef22477fc6467d6ea1777f215c6ff1ca56023ba2aba5b7688f0c7c60c5cb039fe403ebb9d1620bf1947547a2936ec61531ffd0c7946235b3c2970faf4fe53c79710998edb48c84b550b82acb7e3b701075ccc9e7cffe0b26903475af426ca8f7036e784f9d79b0d20c730b01f3fdbed84eb7ff366b4330648f406b37ff417b18e98a4b378d18596ad12c5e7ddd4f2e3b474f548b1e56709b7ec73a99efecacc8b28e39e752dfd67b4839ac9f6780d052ad429c00e8b5de1b6c3e8f19b0de803c95552011ffebcde0bf6c1c8136c3bbd1a1054dd diff --git a/src/lib/dns/tests/testdata/rdata_ds_fromWire b/src/lib/dns/tests/testdata/rdata_ds_fromWire new file mode 100644 index 0000000..81c412c --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_ds_fromWire @@ -0,0 +1,6 @@ +# RDLENGTH 36 bytes +00 24 +# DS record, keyid 12892 +32 5c 05 02 f1 e1 84 c0 e1 d6 15 d2 0e b3 c2 23 +ac ed 3b 03 c7 73 dd 95 2d 5f 0e b5 c7 77 58 6d +e1 8d a6 b5 diff --git a/src/lib/dns/tests/testdata/rdata_in_a_fromWire b/src/lib/dns/tests/testdata/rdata_in_a_fromWire new file mode 100644 index 0000000..12f508b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_in_a_fromWire @@ -0,0 +1,19 @@ +# +# various kinds of IN/A RDATA stored in an input buffer +# +# valid RDATA for 192.0.2.1 +# +# 0 1 2 3 4 5 (bytes) + 00 04 c0 00 02 01 +# +# short length +# 6 7 8 9 10 11 (bytes) + 00 03 c0 00 02 01 +# +# length too long +#12 13 14 15 16 17 18 + 00 05 c0 00 02 01 00 +# +# short buffer (this can be tested only at the end of the buffer) +#19 20 21 22 23 + 00 04 c0 00 02 diff --git a/src/lib/dns/tests/testdata/rdata_in_aaaa_fromWire b/src/lib/dns/tests/testdata/rdata_in_aaaa_fromWire new file mode 100644 index 0000000..22fdd1f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_in_aaaa_fromWire @@ -0,0 +1,18 @@ +# +# various kinds of IN/AAAA RDATA stored in an input buffer +# +# valid RDATA for 2001:db8::1234 +# +#RDLENGTH=16 +0010 +#IPv6 address (18 bytes) +2001 0db8 0000 0000 0000 0000 0000 1234 +# +# short length (36 bytes) +0008 2001 0db8 0000 0000 0000 0000 0000 1234 +# +# length too long (55 bytes) +0011 2001 0db8 0000 0000 0000 0000 0000 1234 ff +# +# short buffer (this can be tested only at the end of the buffer) +0010 2001 0db8 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire1.spec b/src/lib/dns/tests/testdata/rdata_minfo_fromWire1.spec new file mode 100644 index 0000000..2c43db0 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire1.spec @@ -0,0 +1,3 @@ +[custom] +sections: minfo +[minfo] diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire1.wire b/src/lib/dns/tests/testdata/rdata_minfo_fromWire1.wire new file mode 100644 index 0000000..3483e9b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire1.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_minfo_fromWire1.spec +### + +# MINFO RDATA, RDLEN=44 +002c +# RMAILBOX=rmailbox.example.com EMAILBOX=emailbox.example.com +08726d61696c626f78076578616d706c6503636f6d00 08656d61696c626f78076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_minfo_fromWire2.spec new file mode 100644 index 0000000..d781cac --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire2.spec @@ -0,0 +1,7 @@ +[custom] +sections: name:minfo +[name] +name: a.example.com. +[minfo] +rmailbox: rmailbox.ptr=02 +emailbox: emailbox.ptr=02 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_minfo_fromWire2.wire new file mode 100644 index 0000000..d79e936 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire2.wire @@ -0,0 +1,11 @@ +### +### This data file was auto-generated from rdata_minfo_fromWire2.spec +### + +# DNS Name: a.example.com. +0161076578616d706c6503636f6d00 + +# MINFO RDATA, RDLEN=22 +0016 +# RMAILBOX=rmailbox.ptr=02 EMAILBOX=emailbox.ptr=02 +08726d61696c626f78c002 08656d61696c626f78c002 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_minfo_fromWire3.spec new file mode 100644 index 0000000..a1d4b76 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire3.spec @@ -0,0 +1,6 @@ +[custom] +sections: minfo +# rdlength too short +[minfo] +emailbox: emailbox.ptr=11 +rdlen: 3 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire3.wire b/src/lib/dns/tests/testdata/rdata_minfo_fromWire3.wire new file mode 100644 index 0000000..55df1a2 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire3.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_minfo_fromWire3.spec +### + +# MINFO RDATA, RDLEN=3 +0003 +# RMAILBOX=rmailbox.example.com EMAILBOX=emailbox.ptr=11 +08726d61696c626f78076578616d706c6503636f6d00 08656d61696c626f78c00b diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_minfo_fromWire4.spec new file mode 100644 index 0000000..269a6ce --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire4.spec @@ -0,0 +1,6 @@ +[custom] +sections: minfo +# rdlength too long +[minfo] +emailbox: emailbox.ptr=11 +rdlen: 80 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_minfo_fromWire4.wire new file mode 100644 index 0000000..746f55a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire4.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_minfo_fromWire4.spec +### + +# MINFO RDATA, RDLEN=80 +0050 +# RMAILBOX=rmailbox.example.com EMAILBOX=emailbox.ptr=11 +08726d61696c626f78076578616d706c6503636f6d00 08656d61696c626f78c00b diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_minfo_fromWire5.spec new file mode 100644 index 0000000..3a888e3 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire5.spec @@ -0,0 +1,5 @@ +[custom] +sections: minfo +# bogus rmailbox name +[minfo] +rmailbox: "01234567890123456789012345678901234567890123456789012345678901234" diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire5.wire b/src/lib/dns/tests/testdata/rdata_minfo_fromWire5.wire new file mode 100644 index 0000000..dacd9a0 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire5.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_minfo_fromWire5.spec +### + +# MINFO RDATA, RDLEN=91 +005b +# RMAILBOX="01234567890123456789012345678901234567890123456789012345678901234" EMAILBOX=emailbox.example.com +432230313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233342200 08656d61696c626f78076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire6.spec b/src/lib/dns/tests/testdata/rdata_minfo_fromWire6.spec new file mode 100644 index 0000000..c75ed8e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire6.spec @@ -0,0 +1,5 @@ +[custom] +sections: minfo +# bogus emailbox name +[minfo] +emailbox: "01234567890123456789012345678901234567890123456789012345678901234" diff --git a/src/lib/dns/tests/testdata/rdata_minfo_fromWire6.wire b/src/lib/dns/tests/testdata/rdata_minfo_fromWire6.wire new file mode 100644 index 0000000..4199fee --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_fromWire6.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_minfo_fromWire6.spec +### + +# MINFO RDATA, RDLEN=91 +005b +# RMAILBOX=rmailbox.example.com EMAILBOX="01234567890123456789012345678901234567890123456789012345678901234" +08726d61696c626f78076578616d706c6503636f6d00 432230313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233342200 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_toWire1.spec b/src/lib/dns/tests/testdata/rdata_minfo_toWire1.spec new file mode 100644 index 0000000..7b340a3 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_toWire1.spec @@ -0,0 +1,5 @@ +[custom] +sections: minfo +[minfo] +emailbox: emailbox.ptr=09 +rdlen: -1 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_toWire1.wire b/src/lib/dns/tests/testdata/rdata_minfo_toWire1.wire new file mode 100644 index 0000000..8ac4afe --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_toWire1.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_minfo_toWire1.spec +### + +# MINFO RDATA + +# RMAILBOX=rmailbox.example.com EMAILBOX=emailbox.ptr=09 +08726d61696c626f78076578616d706c6503636f6d00 08656d61696c626f78c009 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_toWire2.spec b/src/lib/dns/tests/testdata/rdata_minfo_toWire2.spec new file mode 100644 index 0000000..132f118 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_toWire2.spec @@ -0,0 +1,6 @@ +[custom] +sections: minfo +[minfo] +rmailbox: root.example.com. +emailbox: emailbox.ptr=05 +rdlen: -1 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_toWire2.wire b/src/lib/dns/tests/testdata/rdata_minfo_toWire2.wire new file mode 100644 index 0000000..7fb847c --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_toWire2.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_minfo_toWire2.spec +### + +# MINFO RDATA + +# RMAILBOX=root.example.com. EMAILBOX=emailbox.ptr=05 +04726f6f74076578616d706c6503636f6d00 08656d61696c626f78c005 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed1.spec b/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed1.spec new file mode 100644 index 0000000..d99a381 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed1.spec @@ -0,0 +1,7 @@ +# +# A simplest form of MINFO: all default parameters +# +[custom] +sections: minfo +[minfo] +rdlen: -1 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed1.wire b/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed1.wire new file mode 100644 index 0000000..6de233e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed1.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_minfo_toWireUncompressed1.spec +### + +# MINFO RDATA + +# RMAILBOX=rmailbox.example.com EMAILBOX=emailbox.example.com +08726d61696c626f78076578616d706c6503636f6d00 08656d61696c626f78076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed2.spec b/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed2.spec new file mode 100644 index 0000000..0f78fcc --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed2.spec @@ -0,0 +1,8 @@ +# +# A simplest form of MINFO: custom rmailbox and default emailbox +# +[custom] +sections: minfo +[minfo] +rmailbox: root.example.com. +rdlen: -1 diff --git a/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed2.wire b/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed2.wire new file mode 100644 index 0000000..51e9e35 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_minfo_toWireUncompressed2.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_minfo_toWireUncompressed2.spec +### + +# MINFO RDATA + +# RMAILBOX=root.example.com. EMAILBOX=emailbox.example.com +04726f6f74076578616d706c6503636f6d00 08656d61696c626f78076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_mx_fromWire b/src/lib/dns/tests/testdata/rdata_mx_fromWire new file mode 100644 index 0000000..8e09154 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_mx_fromWire @@ -0,0 +1,15 @@ +# +# various kinds of MX RDATA stored in an input buffer +# +# Valid RDATA for "10 mail.example.com" +# +# RDLENGTH=18 bytes +# 0 1 + 00 12 +# 2 3 +# PREFERENCE: 10 + 00 0a +# EXCHANGE: non compressed +# 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 (bytes) +#(2) m x (7) e x a m p l e (3) c o m . + 02 6d 78 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 diff --git a/src/lib/dns/tests/testdata/rdata_mx_toWire1 b/src/lib/dns/tests/testdata/rdata_mx_toWire1 new file mode 100644 index 0000000..3049373 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_mx_toWire1 @@ -0,0 +1,12 @@ +# +# compressed MX RDATA stored in an output buffer +# +# sentinel name: example.com. +# 0 1 2 3 4 5 6 7 8 9 10 1 2 (bytes) +#(7) e x a m p l e (3) c o m . + 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# PREFERENCE: 10 + 00 0a +# EXCHANGE: compressed +#(4) m x ptr=0 + 02 6d 78 c0 00 diff --git a/src/lib/dns/tests/testdata/rdata_mx_toWire2 b/src/lib/dns/tests/testdata/rdata_mx_toWire2 new file mode 100644 index 0000000..ebd2f27 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_mx_toWire2 @@ -0,0 +1,12 @@ +# +# compressed MX RDATA stored in an output buffer +# +# sentinel name: example.com. +# 0 1 2 3 4 5 6 7 8 9 10 1 2 (bytes) +#(7) e x a m p l e (3) c o m . + 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# PREFERENCE: 10 + 00 0a +# EXCHANGE: not compressed +#(4) m x ptr=0 + 02 6d 78 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 diff --git a/src/lib/dns/tests/testdata/rdata_ns_fromWire b/src/lib/dns/tests/testdata/rdata_ns_fromWire new file mode 100644 index 0000000..973365f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_ns_fromWire @@ -0,0 +1,44 @@ +# +# various kinds of NS RDATA stored in an input buffer +# +# Valid non-compressed RDATA for ns.example.com. +# RDLENGTH=16 bytes +# 0 1 + 00 10 +# 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7(bytes) +#(2) n s (7) e x a m p l e (3) c o m . + 02 6e 73 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# +# short length +# 8 9 + 00 0f +#20 1 2 3 4 5 6 7 8 9 30 1 2 3 4 5 + 02 6e 73 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# +# length too long +# 6 7 + 00 11 +# +# 8 9 40 1 2 3 4 5 6 7 8 9 50 1 2 3 4 + 02 6e 73 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 +# +# Valid compressed NS name: 'ns2' + pointer +# 5 6 + 00 06 +# 7 8 9 60 1 2 +#(3) n s 2 ptr=5 + 03 6e 73 32 c0 05 +# +# Valid compressed NS name but RDLENGTH is incorrect: it must be the length +# of the sequence from the head to the pointer, not the decompressed name +# length. +# 3 4 + 00 11 +# 5 6 7 8 9 70 + 03 6e 73 32 c0 05 +# incomplete name (no trailing dot). this can be tested only at the end of +# the buffer. +# 1 2 + 00 0f +# 3 4 5 6 7 8 9 80 1 2 3 4 5 6 7 + 02 6e 73 07 65 78 61 6d 70 6c 65 03 63 6f 6d diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire1 b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire1 new file mode 100644 index 0000000..1dd5f52 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire1 @@ -0,0 +1,7 @@ +# RDLENGTH, 39 bytes +00 27 +# NSEC3 record: +# 1 1 1 D399EAAB H9RSFB7FPF2L8HG35CMPC765TDK23RP6 NS SOA RRSIG DNSKEY NSEC3PARAM +01 01 00 01 04 d3 99 ea ab 14 8a 77 c7 ac ef cb +c5 54 46 03 2b 2d 96 1c c5 eb 68 21 ef 26 00 07 +22 00 00 00 00 02 90 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire1.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire1.spec new file mode 100644 index 0000000..39a78d7 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire1.spec @@ -0,0 +1,7 @@ +# +# A malformed NSEC3 RDATA: bit map length is too large, causing overflow +# + +[custom] +sections: nsec3 +[nsec3] diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire10.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire10.spec new file mode 100644 index 0000000..30417f5 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire10.spec @@ -0,0 +1,8 @@ +# +# An invalid NSEC3 RDATA: a bitmap block containing empty bytes +# + +[custom] +sections: nsec3 +[nsec3] +bitmap: '01000000' diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire10.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire10.wire new file mode 100644 index 0000000..99c5afd --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire10.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire10.spec +### + +# NSEC3 RDATA, RDLEN=37 +0025 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=4 +00 04 01000000 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire11.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire11.spec new file mode 100644 index 0000000..80ec59f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire11.spec @@ -0,0 +1,8 @@ +# +# An invalid NSEC3 RDATA: Saltlen is too large +# + +[custom] +sections: nsec3 +[nsec3] +rdlen: 7 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire11.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire11.wire new file mode 100644 index 0000000..48dc589 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire11.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire11.spec +### + +# NSEC3 RDATA, RDLEN=7 +0007 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=6 +00 06 040000000003 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire12.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire12.spec new file mode 100644 index 0000000..1e01655 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire12.spec @@ -0,0 +1,9 @@ +# +# An invalid NSEC3 RDATA: Hash length is too large +# + +[custom] +sections: nsec3 +[nsec3] +# only contains the first byte of hash +rdlen: 12 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire12.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire12.wire new file mode 100644 index 0000000..e880d55 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire12.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire12.spec +### + +# NSEC3 RDATA, RDLEN=12 +000c +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=6 +00 06 040000000003 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire13.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire13.spec new file mode 100644 index 0000000..fcc9d53 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire13.spec @@ -0,0 +1,9 @@ +# +# A valid (but unusual) NSEC3 RDATA: salt is empty. +# + +[custom] +sections: nsec3 +[nsec3] +saltlen: 0 +salt: '' diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire13.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire13.wire new file mode 100644 index 0000000..86a06c5 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire13.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire13.spec +### + +# NSEC3 RDATA, RDLEN=34 +0022 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=0, Salt='' +00 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=6 +00 06 040000000003 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire14.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire14.spec new file mode 100644 index 0000000..a0550d5 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire14.spec @@ -0,0 +1,9 @@ +# +# An invalid NSEC3 RDATA: empty hash +# + +[custom] +sections: nsec3 +[nsec3] +hashlen: 0 +hash: '' diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire14.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire14.wire new file mode 100644 index 0000000..9d76b5a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire14.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire14.spec +### + +# NSEC3 RDATA, RDLEN=19 +0013 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=0, Hash='' +00 +# Bitmap: Block=0, Length=6 +00 06 040000000003 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire15.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire15.spec new file mode 100644 index 0000000..4993e03 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire15.spec @@ -0,0 +1,10 @@ +# +# NSEC3 RDATA with empty type bitmap. It's okay. +# The test data includes bytes for a bitmap field, but RDLEN indicates +# it's not part of the RDATA and so it will be ignored. +# + +[custom] +sections: nsec3 +[nsec3] +rdlen: 31 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire15.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire15.wire new file mode 100644 index 0000000..bd636a7 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire15.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire15.spec +### + +# NSEC3 RDATA, RDLEN=31 +001f +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=6 +00 06 040000000003 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire16.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire16.spec new file mode 100644 index 0000000..dac14ea --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire16.spec @@ -0,0 +1,8 @@ +# +# NSEC3 RDATA with an empty bitmap +# + +[custom] +sections: nsec3 +[nsec3] +nbitmap: 0 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire16.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire16.wire new file mode 100644 index 0000000..bab957e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire16.wire @@ -0,0 +1,12 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire16.spec +### + +# NSEC3 RDATA, RDLEN=31 +001f +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire17.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire17.spec new file mode 100644 index 0000000..4253349 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire17.spec @@ -0,0 +1,8 @@ +# +# An invalid NSEC3 RDATA: RDLEN is too short to include the hash len field. +# + +[custom] +sections: nsec3 +[nsec3] +rdlen: 10 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire17.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire17.wire new file mode 100644 index 0000000..f7972a0 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire17.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire17.spec +### + +# NSEC3 RDATA, RDLEN=10 +000a +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=6 +00 06 040000000003 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire2.spec new file mode 100644 index 0000000..f35de83 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire2.spec @@ -0,0 +1,9 @@ +# +# A malformed NSEC3 RDATA: RDLEN indicates it doesn't even contain the fixed +# 5 octets +# + +[custom] +sections: nsec3 +[nsec3] +rdlen: 4 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire2.wire new file mode 100644 index 0000000..ec14a58 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire2.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire2.spec +### + +# NSEC3 RDATA, RDLEN=4 +0004 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=6 +00 06 040000000003 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire3 b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire3 new file mode 100644 index 0000000..a0c8f59 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire3 @@ -0,0 +1,6 @@ +# RDLENGTH, 39 bytes +00 27 +# NSEC3 record with a broken type bitmap +01 01 00 01 04 d3 99 ea ab 14 8a 77 c7 ac ef cb +c5 54 46 03 2b 2d 96 1c c5 eb 68 21 ef 26 00 ff +22 00 00 00 00 02 90 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire4.spec new file mode 100644 index 0000000..06d6eb4 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire4.spec @@ -0,0 +1,9 @@ +# +# A malformed NSEC3 RDATA: bit map length is too large, causing overflow +# + +[custom] +sections: nsec3 +[nsec3] +maplen: 31 +bitmap: '01' diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire4.wire new file mode 100644 index 0000000..527860c --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire4.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire4.spec +### + +# NSEC3 RDATA, RDLEN=34 +0022 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=31 +00 1f 01 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire5.spec new file mode 100644 index 0000000..2d5713c --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire5.spec @@ -0,0 +1,13 @@ +# +# A malformed NSEC3 RDATA: incomplete bit map field +# + +[custom] +sections: nsec3 +[nsec3] +# only containing the block field of the bitmap +rdlen: 32 +#dummy data +maplen: 31 +#dummy data +bitmap: '00' diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire5.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire5.wire new file mode 100644 index 0000000..97b798b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire5.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire5.spec +### + +# NSEC3 RDATA, RDLEN=32 +0020 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=31 +00 1f 00 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire6.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire6.spec new file mode 100644 index 0000000..36e9e59 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire6.spec @@ -0,0 +1,11 @@ +# +# A malformed NSEC3 RDATA: bit map length being 0 +# + +[custom] +sections: nsec3 +[nsec3] +rdlen: 33 +maplen: 0 +# dummy data: +bitmap: '01' diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire6.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire6.wire new file mode 100644 index 0000000..4cf1189 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire6.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire6.spec +### + +# NSEC3 RDATA, RDLEN=33 +0021 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=0 +00 00 01 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire7.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire7.spec new file mode 100644 index 0000000..338c0c9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire7.spec @@ -0,0 +1,9 @@ +# +# NSEC3 RDATA with a longest bitmap field (32 bitmap bytes) +# + +[custom] +sections: nsec3 +[nsec3] +maplen: 32 +bitmap: '0101010101010101010101010101010101010101010101010101010101010101' diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire7.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire7.wire new file mode 100644 index 0000000..1fddd58 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire7.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire7.spec +### + +# NSEC3 RDATA, RDLEN=65 +0041 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=32 +00 20 0101010101010101010101010101010101010101010101010101010101010101 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire8.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire8.spec new file mode 100644 index 0000000..041714e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire8.spec @@ -0,0 +1,9 @@ +# +# An invalid NSEC3 RDATA with an oversized bitmap field (33 bitmap bytes) +# + +[custom] +sections: nsec3 +[nsec3] +maplen: 33 +bitmap: '010101010101010101010101010101010101010101010101010101010101010101' diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire8.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire8.wire new file mode 100644 index 0000000..9569094 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire8.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire8.spec +### + +# NSEC3 RDATA, RDLEN=66 +0042 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=0, Length=33 +00 21 010101010101010101010101010101010101010101010101010101010101010101 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire9.spec b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire9.spec new file mode 100644 index 0000000..b04c84f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire9.spec @@ -0,0 +1,10 @@ +# +# An invalid NSEC3 RDATA: disordered bitmap blocks +# + +[custom] +sections: nsec3 +[nsec3] +nbitmap: 2 +block0: 2 +block1: 1 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3_fromWire9.wire b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire9.wire new file mode 100644 index 0000000..9c0de10 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3_fromWire9.wire @@ -0,0 +1,16 @@ +### +### This data file was auto-generated from rdata_nsec3_fromWire9.spec +### + +# NSEC3 RDATA, RDLEN=47 +002f +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 +# Hash Len=20, Hash='hhhhhhhhhhhhhhhhhhhh' +14 6868686868686868686868686868686868686868 +# Bitmap: Block=2, Length=6 +02 06 040000000003 +# Bitmap: Block=1, Length=6 +01 06 040000000003 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire1 b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire1 new file mode 100644 index 0000000..1b8697f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire1 @@ -0,0 +1,5 @@ +# RDLENGTH, 9 bytes +00 09 +# NSEC3PARAM record +# 1 1 1 D399EAAB +01 01 00 01 04 d3 99 ea ab diff --git a/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire11.spec b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire11.spec new file mode 100644 index 0000000..41e1784 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire11.spec @@ -0,0 +1,8 @@ +# +# An invalid NSEC3PARAM RDATA: Saltlen is too large +# + +[custom] +sections: nsec3param +[nsec3param] +rdlen: 7 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire11.wire b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire11.wire new file mode 100644 index 0000000..e9ffb46 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire11.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_nsec3param_fromWire11.spec +### + +# NSEC3PARAM RDATA, RDLEN=7 +0007 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire13.spec b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire13.spec new file mode 100644 index 0000000..311b2dd --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire13.spec @@ -0,0 +1,9 @@ +# +# A valid (but unusual) NSEC3PARAM RDATA: salt is empty. +# + +[custom] +sections: nsec3param +[nsec3param] +saltlen: 0 +salt: '' diff --git a/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire13.wire b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire13.wire new file mode 100644 index 0000000..511da87 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire13.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_nsec3param_fromWire13.spec +### + +# NSEC3PARAM RDATA, RDLEN=5 +0005 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=0, Salt='' +00 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire2.spec new file mode 100644 index 0000000..e04b818 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire2.spec @@ -0,0 +1,9 @@ +# +# A malformed NSEC3PARAM RDATA: RDLEN indicates it doesn't even contain the +# fixed 5 octets +# + +[custom] +sections: nsec3param +[nsec3param] +rdlen: 4 diff --git a/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire2.wire new file mode 100644 index 0000000..adc5ea9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec3param_fromWire2.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_nsec3param_fromWire2.spec +### + +# NSEC3PARAM RDATA, RDLEN=4 +0004 +# Hash Alg=SHA1(1), Opt-Out=0, Other Flags=0, Iterations=1 +01 00 0001 +# Salt Len=5, Salt='sssss' +05 7373737373 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire1 b/src/lib/dns/tests/testdata/rdata_nsec_fromWire1 new file mode 100644 index 0000000..9c34394 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire1 @@ -0,0 +1,6 @@ +# RDLENGTH, 22 bytes +00 16 +# NSEC record +# www2.isc.org. CNAME RRSIG NSEC +04 77 77 77 32 03 69 73 63 03 6f 72 67 00 00 06 +04 00 00 00 00 03 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire10.spec b/src/lib/dns/tests/testdata/rdata_nsec_fromWire10.spec new file mode 100644 index 0000000..39d19ae --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire10.spec @@ -0,0 +1,8 @@ +# +# An invalid NSEC RDATA: a bitmap block containing empty bytes +# + +[custom] +sections: nsec +[nsec] +bitmap: '01000000' diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire10.wire b/src/lib/dns/tests/testdata/rdata_nsec_fromWire10.wire new file mode 100644 index 0000000..1145dbd --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire10.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_nsec_fromWire10.spec +### + +# NSEC RDATA, RDLEN=24 +0018 +# Next Name=next.example.com (18 bytes) +046e657874076578616d706c6503636f6d00 +# Bitmap: Block=0, Length=4 +00 04 01000000 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire16.spec b/src/lib/dns/tests/testdata/rdata_nsec_fromWire16.spec new file mode 100644 index 0000000..d7faeed --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire16.spec @@ -0,0 +1,8 @@ +# +# An invalid NSEC RDATA: with an empty bitmap +# + +[custom] +sections: nsec +[nsec] +nbitmap: 0 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire16.wire b/src/lib/dns/tests/testdata/rdata_nsec_fromWire16.wire new file mode 100644 index 0000000..943601a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire16.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_nsec_fromWire16.spec +### + +# NSEC RDATA, RDLEN=18 +0012 +# Next Name=next.example.com (18 bytes) +046e657874076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire2 b/src/lib/dns/tests/testdata/rdata_nsec_fromWire2 new file mode 100644 index 0000000..e9b41e2 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire2 @@ -0,0 +1,10 @@ +# +# NSEC RDATA with a bogus RDLEN (too short) +# + +# RDLENGTH, 13 bytes (should be 22) +00 0d +# NSEC record +# www2.isc.org. CNAME RRSIG NSEC +04 77 77 77 32 03 69 73 63 03 6f 72 67 00 00 06 +04 00 00 00 00 03 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire3 b/src/lib/dns/tests/testdata/rdata_nsec_fromWire3 new file mode 100644 index 0000000..67e6b3f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire3 @@ -0,0 +1,10 @@ +# +# NSEC RDATA with an invalid type bitmap +# + +# RDLENGTH, 22 bytes +00 16 +# NSEC record +# www2.isc.org. followed by a broken bitmap +04 77 77 77 32 03 69 73 63 03 6f 72 67 00 00 ff +00 00 00 00 00 00 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_nsec_fromWire4.spec new file mode 100644 index 0000000..a5744c1 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire4.spec @@ -0,0 +1,9 @@ +# +# A malformed NSEC RDATA: bit map length is too large, causing overflow +# + +[custom] +sections: nsec +[nsec] +maplen: 31 +bitmap: '01' diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_nsec_fromWire4.wire new file mode 100644 index 0000000..1c4d4a4 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire4.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_nsec_fromWire4.spec +### + +# NSEC RDATA, RDLEN=21 +0015 +# Next Name=next.example.com (18 bytes) +046e657874076578616d706c6503636f6d00 +# Bitmap: Block=0, Length=31 +00 1f 01 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_nsec_fromWire5.spec new file mode 100644 index 0000000..795d1e0 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire5.spec @@ -0,0 +1,13 @@ +# +# A malformed NSEC RDATA: incomplete bit map field +# + +[custom] +sections: nsec +[nsec] +# only containing the block field of the bitmap +rdlen: 19 +#dummy data +maplen: 31 +#dummy data +bitmap: '00' diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire5.wire b/src/lib/dns/tests/testdata/rdata_nsec_fromWire5.wire new file mode 100644 index 0000000..104a2b9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire5.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_nsec_fromWire5.spec +### + +# NSEC RDATA, RDLEN=19 +0013 +# Next Name=next.example.com (18 bytes) +046e657874076578616d706c6503636f6d00 +# Bitmap: Block=0, Length=31 +00 1f 00 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire6.spec b/src/lib/dns/tests/testdata/rdata_nsec_fromWire6.spec new file mode 100644 index 0000000..cb864ab --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire6.spec @@ -0,0 +1,11 @@ +# +# A malformed NSEC RDATA: bit map length being 0 +# + +[custom] +sections: nsec +[nsec] +rdlen: 20 +maplen: 0 +# dummy data: +bitmap: '01' diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire6.wire b/src/lib/dns/tests/testdata/rdata_nsec_fromWire6.wire new file mode 100644 index 0000000..3108ed7 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire6.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_nsec_fromWire6.spec +### + +# NSEC RDATA, RDLEN=20 +0014 +# Next Name=next.example.com (18 bytes) +046e657874076578616d706c6503636f6d00 +# Bitmap: Block=0, Length=0 +00 00 01 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire7.spec b/src/lib/dns/tests/testdata/rdata_nsec_fromWire7.spec new file mode 100644 index 0000000..46b521b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire7.spec @@ -0,0 +1,9 @@ +# +# NSEC RDATA with a longest bitmap field (32 bitmap bytes) +# + +[custom] +sections: nsec +[nsec] +maplen: 32 +bitmap: '0101010101010101010101010101010101010101010101010101010101010101' diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire7.wire b/src/lib/dns/tests/testdata/rdata_nsec_fromWire7.wire new file mode 100644 index 0000000..e265a3b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire7.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_nsec_fromWire7.spec +### + +# NSEC RDATA, RDLEN=52 +0034 +# Next Name=next.example.com (18 bytes) +046e657874076578616d706c6503636f6d00 +# Bitmap: Block=0, Length=32 +00 20 0101010101010101010101010101010101010101010101010101010101010101 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire8.spec b/src/lib/dns/tests/testdata/rdata_nsec_fromWire8.spec new file mode 100644 index 0000000..3f957a3 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire8.spec @@ -0,0 +1,9 @@ +# +# An invalid NSEC RDATA with an oversized bitmap field (33 bitmap bytes) +# + +[custom] +sections: nsec +[nsec] +maplen: 33 +bitmap: '010101010101010101010101010101010101010101010101010101010101010101' diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire8.wire b/src/lib/dns/tests/testdata/rdata_nsec_fromWire8.wire new file mode 100644 index 0000000..066cd70 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire8.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_nsec_fromWire8.spec +### + +# NSEC RDATA, RDLEN=53 +0035 +# Next Name=next.example.com (18 bytes) +046e657874076578616d706c6503636f6d00 +# Bitmap: Block=0, Length=33 +00 21 010101010101010101010101010101010101010101010101010101010101010101 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire9.spec b/src/lib/dns/tests/testdata/rdata_nsec_fromWire9.spec new file mode 100644 index 0000000..a3bd0c9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire9.spec @@ -0,0 +1,10 @@ +# +# An invalid NSEC RDATA: disordered bitmap blocks +# + +[custom] +sections: nsec +[nsec] +nbitmap: 2 +block0: 2 +block1: 1 diff --git a/src/lib/dns/tests/testdata/rdata_nsec_fromWire9.wire b/src/lib/dns/tests/testdata/rdata_nsec_fromWire9.wire new file mode 100644 index 0000000..53ad6cc --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_nsec_fromWire9.wire @@ -0,0 +1,12 @@ +### +### This data file was auto-generated from rdata_nsec_fromWire9.spec +### + +# NSEC RDATA, RDLEN=34 +0022 +# Next Name=next.example.com (18 bytes) +046e657874076578616d706c6503636f6d00 +# Bitmap: Block=2, Length=6 +02 06 040000000003 +# Bitmap: Block=1, Length=6 +01 06 040000000003 diff --git a/src/lib/dns/tests/testdata/rdata_opt_fromWire1 b/src/lib/dns/tests/testdata/rdata_opt_fromWire1 new file mode 100644 index 0000000..f2eb680 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_opt_fromWire1 @@ -0,0 +1,15 @@ +# Various kinds of OPT RDATA stored in an input buffer +# +# Empty RDATA (which is okay) +# +# 0 1 (bytes) + 00 00 +# +# An OPT RR containing an NSID Option +# code=3 len=3 ID value (opaque) +# 2 3 4 5 6 7 8 9 10 + 00 07 00 2a 00 03 00 01 02 +# +# Short buffer (this can be tested only at the end of the buffer) +# 1 2 3 4 5 + 00 04 c0 00 02 diff --git a/src/lib/dns/tests/testdata/rdata_opt_fromWire2 b/src/lib/dns/tests/testdata/rdata_opt_fromWire2 new file mode 100644 index 0000000..2c5a11f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_opt_fromWire2 @@ -0,0 +1,4 @@ +# Short RDATA length +# +# OPT RDATA, RDLEN=1 +0001 diff --git a/src/lib/dns/tests/testdata/rdata_opt_fromWire3 b/src/lib/dns/tests/testdata/rdata_opt_fromWire3 new file mode 100644 index 0000000..52db1d8 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_opt_fromWire3 @@ -0,0 +1,8 @@ +# Short RDATA length (in second pseudo RR) +# +# OPT RDATA, RDLEN=8 +0008 +# Pseudo RR 1 of size 7 (code=3, len=3) +00 03 00 03 00 01 02 +# Pseudo RR 2 of size 7 exhausts RDLEN (code=4, len=3) +00 04 00 03 00 01 02 diff --git a/src/lib/dns/tests/testdata/rdata_opt_fromWire4 b/src/lib/dns/tests/testdata/rdata_opt_fromWire4 new file mode 100644 index 0000000..a302127 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_opt_fromWire4 @@ -0,0 +1,9 @@ +# Sum of option lengths would overflow RDLEN +# +# OPT RDATA, RDLEN=14 (0x000e) +000e +# Pseudo RR 1 (code=3, len=3) +00 03 00 03 00 01 02 +# Pseudo RR 2 (code=4, len=65535 overflows RDLEN) +00 04 ff ff 00 01 02 +# Rest of option data is omitted... diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire1.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire1.spec new file mode 100644 index 0000000..edb9f34 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire1.spec @@ -0,0 +1,6 @@ +# +# A simplest form of RP: all default parameters +# +[custom] +sections: rp +[rp] diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire1.wire b/src/lib/dns/tests/testdata/rdata_rp_fromWire1.wire new file mode 100644 index 0000000..aa93986 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire1.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_rp_fromWire1.spec +### + +# RP RDATA, RDLEN=39 +0027 +# MAILBOX=root.example.com TEXT=rp-text.example.com +04726f6f74076578616d706c6503636f6d00 0772702d74657874076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire2.spec new file mode 100644 index 0000000..57adb5a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire2.spec @@ -0,0 +1,12 @@ +# +# A simplest form of RP: names are compressed. +# +[custom] +sections: name/1:name/2:rp +[name/1] +name: a.example.com +[name/2] +name: b.example.net +[rp] +mailbox: root.ptr=2 +text: rp-text.ptr=17 diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_rp_fromWire2.wire new file mode 100644 index 0000000..507bb1a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire2.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_rp_fromWire2.spec +### + +# DNS Name: a.example.com +0161076578616d706c6503636f6d00 + +# DNS Name: b.example.net +0162076578616d706c65036e657400 + +# RP RDATA, RDLEN=17 +0011 +# MAILBOX=root.ptr=2 TEXT=rp-text.ptr=17 +04726f6f74c002 0772702d74657874c011 diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire3.spec new file mode 100644 index 0000000..a238b7e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire3.spec @@ -0,0 +1,7 @@ +# +# RP-like RDATA but RDLEN is too short. +# +[custom] +sections: rp +[rp] +rdlen: 38 diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire3.wire b/src/lib/dns/tests/testdata/rdata_rp_fromWire3.wire new file mode 100644 index 0000000..c2a7086 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire3.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_rp_fromWire3.spec +### + +# RP RDATA, RDLEN=38 +0026 +# MAILBOX=root.example.com TEXT=rp-text.example.com +04726f6f74076578616d706c6503636f6d00 0772702d74657874076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire4.spec new file mode 100644 index 0000000..6f3abd1 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire4.spec @@ -0,0 +1,7 @@ +# +# RP-like RDATA but RDLEN is too long. +# +[custom] +sections: rp +[rp] +rdlen: 40 diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_rp_fromWire4.wire new file mode 100644 index 0000000..56c643e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire4.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_rp_fromWire4.spec +### + +# RP RDATA, RDLEN=40 +0028 +# MAILBOX=root.example.com TEXT=rp-text.example.com +04726f6f74076578616d706c6503636f6d00 0772702d74657874076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire5.spec new file mode 100644 index 0000000..b8d5e29 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire5.spec @@ -0,0 +1,7 @@ +# +# RP-like RDATA but mailbox name is broken. +# +[custom] +sections: rp +[rp] +mailbox: "01234567890123456789012345678901234567890123456789012345678901234" diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire5.wire b/src/lib/dns/tests/testdata/rdata_rp_fromWire5.wire new file mode 100644 index 0000000..1127047 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire5.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_rp_fromWire5.spec +### + +# RP RDATA, RDLEN=90 +005a +# MAILBOX="01234567890123456789012345678901234567890123456789012345678901234" TEXT=rp-text.example.com +432230313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233342200 0772702d74657874076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire6.spec b/src/lib/dns/tests/testdata/rdata_rp_fromWire6.spec new file mode 100644 index 0000000..e9e79f3 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire6.spec @@ -0,0 +1,7 @@ +# +# RP-like RDATA but text name is broken. +# +[custom] +sections: rp +[rp] +text: "01234567890123456789012345678901234567890123456789012345678901234" diff --git a/src/lib/dns/tests/testdata/rdata_rp_fromWire6.wire b/src/lib/dns/tests/testdata/rdata_rp_fromWire6.wire new file mode 100644 index 0000000..49aedc6 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_fromWire6.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_rp_fromWire6.spec +### + +# RP RDATA, RDLEN=87 +0057 +# MAILBOX=root.example.com TEXT="01234567890123456789012345678901234567890123456789012345678901234" +04726f6f74076578616d706c6503636f6d00 432230313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233342200 diff --git a/src/lib/dns/tests/testdata/rdata_rp_toWire1.spec b/src/lib/dns/tests/testdata/rdata_rp_toWire1.spec new file mode 100644 index 0000000..948bd1a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_toWire1.spec @@ -0,0 +1,8 @@ +# +# A simplest form of RP for toWire test: all default parameters except rdlen, +# which is to be omitted. +# +[custom] +sections: rp +[rp] +rdlen: -1 diff --git a/src/lib/dns/tests/testdata/rdata_rp_toWire1.wire b/src/lib/dns/tests/testdata/rdata_rp_toWire1.wire new file mode 100644 index 0000000..dcadb15 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_toWire1.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_rp_toWire1.spec +### + +# RP RDATA + +# MAILBOX=root.example.com TEXT=rp-text.example.com +04726f6f74076578616d706c6503636f6d00 0772702d74657874076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdata_rp_toWire2.spec b/src/lib/dns/tests/testdata/rdata_rp_toWire2.spec new file mode 100644 index 0000000..09a7ddc --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_toWire2.spec @@ -0,0 +1,14 @@ +# +# A simple form of RP: names could be compressed (but MUST NOT). +# rdlen is omitted for the "to wire" test. +# +[custom] +sections: name/1:name/2:rp +[name/1] +name: a.example.com +[name/2] +name: b.example.net +[rp] +rdlen: -1 +mailbox: root.example.com +text: rp-text.example.net diff --git a/src/lib/dns/tests/testdata/rdata_rp_toWire2.wire b/src/lib/dns/tests/testdata/rdata_rp_toWire2.wire new file mode 100644 index 0000000..38057ef --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rp_toWire2.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_rp_toWire2.spec +### + +# DNS Name: a.example.com +0161076578616d706c6503636f6d00 + +# DNS Name: b.example.net +0162076578616d706c65036e657400 + +# RP RDATA + +# MAILBOX=root.example.com TEXT=rp-text.example.net +04726f6f74076578616d706c6503636f6d00 0772702d74657874076578616d706c65036e657400 diff --git a/src/lib/dns/tests/testdata/rdata_rrsig_fromWire1 b/src/lib/dns/tests/testdata/rdata_rrsig_fromWire1 new file mode 100644 index 0000000..1b799c2 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rrsig_fromWire1 @@ -0,0 +1,13 @@ +# RDLENGTH 155 bytes +00 9b +# RRSIG record +00 01 05 02 00 00 a8 c0 4b ad ad 5d 4b 86 20 5d +0a 62 03 69 73 63 03 6f 72 67 00 1e 42 64 ff 16 +53 bf 37 8f 53 c3 44 36 5f e5 7b 2f 1b 6d 4b a6 +86 4d 61 5d c8 b2 aa 12 e7 cf 55 50 17 39 03 a2 +87 a3 ea 77 97 66 05 99 cd 02 9e 4c a3 ce 61 6a +e7 62 d7 59 5b 83 e7 3d 01 5e 52 5d e8 ae 02 de +bf b1 7c 27 a1 59 94 39 f4 cb f2 7f 4e 14 79 9b +7e 8c a3 6f c6 77 18 e3 f2 52 7f 22 33 d5 91 da +4a c8 1a 5c 9d 83 43 f0 a1 08 99 ae 4c c8 d0 8d +7b 23 b5 52 47 cf 41 91 87 35 24 diff --git a/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2.spec new file mode 100644 index 0000000..582975a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2.spec @@ -0,0 +1,8 @@ +# +# RRSIG RDATA with a bogus RDLEN (too short) +# + +[custom] +sections: rrsig +[rrsig] +rdlen: 19 diff --git a/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2.wire new file mode 100644 index 0000000..b3601a1 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_rrsig_fromWire2.wire @@ -0,0 +1,12 @@ +### +### This data file was auto-generated from rdata_rrsig_fromWire2.spec +### + +# RRSIG RDATA, RDLEN=19 +0013 +# Covered=A(1) Algorithm=RSASHA1(5) Labels=2 OrigTTL=3600 +0001 05 02 00000e10 +# Expiration=1264935600, Inception=1262343600 +4b6562b0 4b3dd5b0 +# Tag=4149 Signer=example.com and Signature +1035 076578616d706c6503636f6d00 123456789abcdef123456789abcdef diff --git a/src/lib/dns/tests/testdata/rdata_soa_fromWire b/src/lib/dns/tests/testdata/rdata_soa_fromWire new file mode 100644 index 0000000..5cd67f0 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_soa_fromWire @@ -0,0 +1,20 @@ +# +# A common style of SOA RDATA stored in an input buffer +# +# Valid compressed RDATA for "(ns.example.com. root.example.com. +# 2010012601 3600 300 3600000 1200)" +# RDLENGTH=43 bytes +# 0 1 + 00 2b +# MNAME: non compressed +# 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7(bytes) +#(2) n s (7) e x a m p l e (3) c o m . + 02 6e 73 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# RNAME: compressed +# 8 9 20 1 2 3 4 +#(4) r o o t ptr=5 + 04 72 6f 6f 74 c0 05 +# other numeric parameters +# 28 32 36 40 44 +# serial, refresh, retry, expire, minimum + 77ce5bb9 00000e10 0000012c 0036ee80 000004b0 diff --git a/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed.spec b/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed.spec new file mode 100644 index 0000000..389cec9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed.spec @@ -0,0 +1,7 @@ +# +# A simple SOA RDATA without name compression +# + +[custom] +sections: soa +[soa] diff --git a/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed.wire b/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed.wire new file mode 100644 index 0000000..4b6442f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_soa_toWireUncompressed.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_soa_toWireUncompressed.spec +### + +# SOA RDATA, RDLEN=54 +0036 +# NNAME=ns.example.com RNAME=root.example.com +026e73076578616d706c6503636f6d00 04726f6f74076578616d706c6503636f6d00 +# SERIAL(2010012601) REFRESH(3600) RETRY(300) EXPIRE(3600000) MINIMUM(1200) +77ce5bb9 00000e10 0000012c 0036ee80 000004b0 diff --git a/src/lib/dns/tests/testdata/rdata_srv_fromWire b/src/lib/dns/tests/testdata/rdata_srv_fromWire new file mode 100644 index 0000000..0f1e4ec --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_srv_fromWire @@ -0,0 +1,36 @@ +# +# various kinds of SRV RDATA stored in an input buffer +# +# RDLENGTH=21 bytes +# 0 1 + 00 15 +# 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 20 1 2(bytes) + 00 01 00 05 05 dc 01 61 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# +# short length +# 3 4 + 00 12 +# 5 6 7 8 9 30 1 2 3 4 5 6 7 8 9 40 1 2 3 4 5 + 00 01 00 05 05 dc 01 61 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# +# length too long +# 6 7 + 00 19 +# +# 8 9 50 1 2 3 4 5 6 7 8 9 60 1 2 3 4 5 6 7 8 + 00 01 00 05 05 dc 01 61 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# +# +# incomplete target name +# 9 70 + 00 12 +# 1 2 3 4 5 6 7 8 9 80 1 2 3 4 5 6 7 8 + 00 01 00 05 05 dc 01 61 07 65 78 61 6d 70 6c 65 03 63 +# +# +# Valid compressed target name: 'a' + pointer +# 9 90 + 00 0a +# +# 1 2 3 4 5 6 7 8 9 100 + 00 01 00 05 05 dc 01 61 c0 0a diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire new file mode 100644 index 0000000..added40 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire @@ -0,0 +1,4 @@ +# SSHFP RDATA, RDLEN=22 +0016 +# ALGORITHM=2 FINGERPRINT_TYPE=1 FINGERPRINT=123456789abcdef67890123456789abcdef67890 +02 01 123456789abcdef67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire1.spec b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire1.spec new file mode 100644 index 0000000..e28a62f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire1.spec @@ -0,0 +1,6 @@ +# +# A simplest form of SSHFP: all default parameters +# +[custom] +sections: sshfp +[sshfp] diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire1.wire b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire1.wire new file mode 100644 index 0000000..c7059e1 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire1.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_sshfp_fromWire1.spec +### + +# SSHFP RDATA, RDLEN=22 +0016 +# ALGORITHM=2 FINGERPRINT_TYPE=1 FINGERPRINT=123456789abcdef67890123456789abcdef67890 +02 01 123456789abcdef67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire10 b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire10 new file mode 100644 index 0000000..220e570 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire10 @@ -0,0 +1,6 @@ +# Test where fingerprint is missing + +# SSHFP RDATA, RDLEN=32 +0020 +# ALGORITHM=2 FINGERPRINT_TYPE=1 FINGERPRINT=(none) +02 01 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire11 b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire11 new file mode 100644 index 0000000..a2f8636 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire11 @@ -0,0 +1,4 @@ +# Test where RDATA is completely missing + +# SSHFP RDATA, RDLEN=32 +0020 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire12 b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire12 new file mode 100644 index 0000000..eabd06b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire12 @@ -0,0 +1,4 @@ +# SSHFP RDATA, RDLEN=02 +0002 +# ALGORITHM=4 FINGERPRINT_TYPE=9 +04 09 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire2 b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire2 new file mode 100644 index 0000000..a695548 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire2 @@ -0,0 +1,4 @@ +# SSHFP RDATA, RDLEN=22 +0016 +# ALGORITHM=2 FINGERPRINT_TYPE=1 FINGERPRINT=123456789ABCDEF67890123456789abcdef67890 +02 01 123456789ABCDEF67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire2.spec new file mode 100644 index 0000000..59a336e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire2.spec @@ -0,0 +1,7 @@ +# +# SSHFP RDATA +# +[custom] +sections: sshfp +[sshfp] +fingerprint: 123456789abcdef67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire2.wire new file mode 100644 index 0000000..e492316 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire2.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_sshfp_fromWire2.spec +### + +# SSHFP RDATA, RDLEN=22 +0016 +# ALGORITHM=2 FINGERPRINT_TYPE=1 FINGERPRINT=123456789abcdef67890123456789abcdef67890 +02 01 123456789abcdef67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire3.spec new file mode 100644 index 0000000..d111afd --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire3.spec @@ -0,0 +1,8 @@ +# +# SSHFP RDATA +# +[custom] +sections: sshfp +[sshfp] +algorithm: 1 +fingerprint_type: 1 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire3.wire b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire3.wire new file mode 100644 index 0000000..daa102f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire3.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_sshfp_fromWire3.spec +### + +# SSHFP RDATA, RDLEN=22 +0016 +# ALGORITHM=1 FINGERPRINT_TYPE=1 FINGERPRINT=123456789abcdef67890123456789abcdef67890 +01 01 123456789abcdef67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire4.spec new file mode 100644 index 0000000..b9b2658 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire4.spec @@ -0,0 +1,8 @@ +# +# SSHFP RDATA +# +[custom] +sections: sshfp +[sshfp] +algorithm: 255 +fingerprint_type: 1 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire4.wire new file mode 100644 index 0000000..f05faad --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire4.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_sshfp_fromWire4.spec +### + +# SSHFP RDATA, RDLEN=22 +0016 +# ALGORITHM=255 FINGERPRINT_TYPE=1 FINGERPRINT=123456789abcdef67890123456789abcdef67890 +ff 01 123456789abcdef67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire5.spec new file mode 100644 index 0000000..b3a19fa --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire5.spec @@ -0,0 +1,8 @@ +# +# SSHFP RDATA +# +[custom] +sections: sshfp +[sshfp] +algorithm: 0 +fingerprint_type: 1 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire5.wire b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire5.wire new file mode 100644 index 0000000..ddc8edb --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire5.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_sshfp_fromWire5.spec +### + +# SSHFP RDATA, RDLEN=22 +0016 +# ALGORITHM=0 FINGERPRINT_TYPE=1 FINGERPRINT=123456789abcdef67890123456789abcdef67890 +00 01 123456789abcdef67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire6.spec b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire6.spec new file mode 100644 index 0000000..437e282 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire6.spec @@ -0,0 +1,8 @@ +# +# SSHFP RDATA +# +[custom] +sections: sshfp +[sshfp] +algorithm: 5 +fingerprint_type: 0 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire6.wire b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire6.wire new file mode 100644 index 0000000..d4e591e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire6.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_sshfp_fromWire6.spec +### + +# SSHFP RDATA, RDLEN=22 +0016 +# ALGORITHM=5 FINGERPRINT_TYPE=0 FINGERPRINT=123456789abcdef67890123456789abcdef67890 +05 00 123456789abcdef67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire7.spec b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire7.spec new file mode 100644 index 0000000..8e21d11 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire7.spec @@ -0,0 +1,8 @@ +# +# SSHFP RDATA +# +[custom] +sections: sshfp +[sshfp] +algorithm: 255 +fingerprint_type: 255 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire7.wire b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire7.wire new file mode 100644 index 0000000..c8b9d8b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire7.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_sshfp_fromWire7.spec +### + +# SSHFP RDATA, RDLEN=22 +0016 +# ALGORITHM=255 FINGERPRINT_TYPE=255 FINGERPRINT=123456789abcdef67890123456789abcdef67890 +ff ff 123456789abcdef67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire8.spec b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire8.spec new file mode 100644 index 0000000..98aa00f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire8.spec @@ -0,0 +1,9 @@ +# +# SSHFP RDATA +# +[custom] +sections: sshfp +[sshfp] +fingerprint: 082359342fd9 +algorithm: 255 +fingerprint_type: 255 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire8.wire b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire8.wire new file mode 100644 index 0000000..32cede8 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire8.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_sshfp_fromWire8.spec +### + +# SSHFP RDATA, RDLEN=8 +0008 +# ALGORITHM=255 FINGERPRINT_TYPE=255 FINGERPRINT=082359342fd9 +ff ff 082359342fd9 diff --git a/src/lib/dns/tests/testdata/rdata_sshfp_fromWire9 b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire9 new file mode 100644 index 0000000..05fc806 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_sshfp_fromWire9 @@ -0,0 +1,6 @@ +# Test where fingerprint length is smaller than what RDATA len indicates + +# SSHFP RDATA, RDLEN=32 +0020 +# ALGORITHM=2 FINGERPRINT_TYPE=1 FINGERPRINT=123456789abcdef67890123456789abcdef67890 +02 01 123456789abcdef67890123456789abcdef67890 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire1.spec b/src/lib/dns/tests/testdata/rdata_tkey_fromWire1.spec new file mode 100644 index 0000000..e46d9b3 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire1.spec @@ -0,0 +1,6 @@ +# +# A simplest form of TKEY: all default parameters +# +[custom] +sections: tkey +[tkey] diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire1.wire b/src/lib/dns/tests/testdata/rdata_tkey_fromWire1.wire new file mode 100644 index 0000000..e8ee944 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire1.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_fromWire1.spec +### + +# TKEY RDATA, RDLEN=58 +003a +# Algorithm=gss-tsig +086773732d7473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=32 Key=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_tkey_fromWire2.spec new file mode 100644 index 0000000..e4a1920 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire2.spec @@ -0,0 +1,8 @@ +# +# TKEY with other data +# +[custom] +sections: tkey +[tkey] +other_len: 8 +other_data: abcd0123 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_tkey_fromWire2.wire new file mode 100644 index 0000000..614844f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire2.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_fromWire2.spec +### + +# TKEY RDATA, RDLEN=66 +0042 +# Algorithm=gss-tsig +086773732d7473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=32 Key=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Other-Len=8 Other-Data=(see hex) +0008 6162636430313233 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_tkey_fromWire3.spec new file mode 100644 index 0000000..2566b58 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire3.spec @@ -0,0 +1,9 @@ +# +# TKEY without Key +# +[custom] +sections: tkey +[tkey] +key_len: 0 +other_len: 8 +other_data: abcd0123 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire3.wire b/src/lib/dns/tests/testdata/rdata_tkey_fromWire3.wire new file mode 100644 index 0000000..df27910 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire3.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_fromWire3.spec +### + +# TKEY RDATA, RDLEN=34 +0022 +# Algorithm=gss-tsig +086773732d7473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=0 Key=(see hex) +0000 +# Other-Len=8 Other-Data=(see hex) +0008 6162636430313233 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_tkey_fromWire4.spec new file mode 100644 index 0000000..33459eb --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire4.spec @@ -0,0 +1,11 @@ +# +# A simplest form of TKEY, but the algorithm name is compressed (quite +# pathological, but we accept it) +# +[custom] +sections: name:tkey +[name] +name: gss-tsig +[tkey] +algorithm: ptr=0 +key_len: 32 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_tkey_fromWire4.wire new file mode 100644 index 0000000..550052e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire4.wire @@ -0,0 +1,17 @@ +### +### This data file was auto-generated from rdata_tkey_fromWire4.spec +### + +# DNS Name: gss-tsig +086773732d7473696700 + +# TKEY RDATA, RDLEN=50 +0032 +# Algorithm=ptr=0 +c000 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=32 Key=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_tkey_fromWire5.spec new file mode 100644 index 0000000..6cfa4b4 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire5.spec @@ -0,0 +1,7 @@ +# +# TKEY-like RDATA but RDLEN is too short. +# +[custom] +sections: tkey +[tkey] +rdlen: 57 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire5.wire b/src/lib/dns/tests/testdata/rdata_tkey_fromWire5.wire new file mode 100644 index 0000000..fa32566 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire5.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_fromWire5.spec +### + +# TKEY RDATA, RDLEN=57 +0039 +# Algorithm=gss-tsig +086773732d7473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=32 Key=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire6.spec b/src/lib/dns/tests/testdata/rdata_tkey_fromWire6.spec new file mode 100644 index 0000000..87460a2 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire6.spec @@ -0,0 +1,7 @@ +# +# TKEY-like RDATA but RDLEN is too long. +# +[custom] +sections: tkey +[tkey] +rdlen: 60 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire6.wire b/src/lib/dns/tests/testdata/rdata_tkey_fromWire6.wire new file mode 100644 index 0000000..7f5f112 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire6.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_fromWire6.spec +### + +# TKEY RDATA, RDLEN=60 +003c +# Algorithm=gss-tsig +086773732d7473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=32 Key=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire7.spec b/src/lib/dns/tests/testdata/rdata_tkey_fromWire7.spec new file mode 100644 index 0000000..3fc0929 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire7.spec @@ -0,0 +1,8 @@ +# +# TKEY-like RDATA but algorithm name is broken. +# +[custom] +sections: tkey +[tkey] +algorithm: "01234567890123456789012345678901234567890123456789012345678901234" +key_len: 32 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire7.wire b/src/lib/dns/tests/testdata/rdata_tkey_fromWire7.wire new file mode 100644 index 0000000..73b277c --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire7.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_fromWire7.spec +### + +# TKEY RDATA, RDLEN=117 +0075 +# Algorithm="01234567890123456789012345678901234567890123456789012345678901234" +432230313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233342200 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=32 Key=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire8.spec b/src/lib/dns/tests/testdata/rdata_tkey_fromWire8.spec new file mode 100644 index 0000000..8338279 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire8.spec @@ -0,0 +1,8 @@ +# +# TKEY-like RDATA but Key len is bogus +# +[custom] +sections: tkey +[tkey] +key_len: 65535 +key: "dummy data" diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire8.wire b/src/lib/dns/tests/testdata/rdata_tkey_fromWire8.wire new file mode 100644 index 0000000..abeb95b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire8.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_fromWire8.spec +### + +# TKEY RDATA, RDLEN=38 +0026 +# Algorithm=gss-tsig +086773732d7473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=65535 Key=(see hex) +ffff 2264756d6d79206461746122 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire9.spec b/src/lib/dns/tests/testdata/rdata_tkey_fromWire9.spec new file mode 100644 index 0000000..9fb63e0 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire9.spec @@ -0,0 +1,8 @@ +# +# TKEY-like RDATA but Other-Data length is bogus +# +[custom] +sections: tkey +[tkey] +other_len: 65535 +otherdata: "dummy data" diff --git a/src/lib/dns/tests/testdata/rdata_tkey_fromWire9.wire b/src/lib/dns/tests/testdata/rdata_tkey_fromWire9.wire new file mode 100644 index 0000000..8e5f943 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_fromWire9.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_fromWire9.spec +### + +# TKEY RDATA, RDLEN=58 +003a +# Algorithm=gss-tsig +086773732d7473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=32 Key=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Other-Len=65535 Other-Data=(see hex) +ffff diff --git a/src/lib/dns/tests/testdata/rdata_tkey_toWire1.spec b/src/lib/dns/tests/testdata/rdata_tkey_toWire1.spec new file mode 100644 index 0000000..42521a3 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_toWire1.spec @@ -0,0 +1,8 @@ +# +# An artificial TKEY RDATA for toWire test. +# +[custom] +sections: tkey +[tkey] +algorithm: gss-tsig +key_len: 0 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_toWire1.wire b/src/lib/dns/tests/testdata/rdata_tkey_toWire1.wire new file mode 100644 index 0000000..3f49a69 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_toWire1.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_toWire1.spec +### + +# TKEY RDATA, RDLEN=26 +001a +# Algorithm=gss-tsig +086773732d7473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=0 Key=(see hex) +0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_toWire2.spec b/src/lib/dns/tests/testdata/rdata_tkey_toWire2.spec new file mode 100644 index 0000000..25d47e5 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_toWire2.spec @@ -0,0 +1,11 @@ +# +# An artificial TKEY RDATA for toWire test. +# +[custom] +sections: tkey +[tkey] +algorithm: GSS-TSIG +error: 16 +key_len: 12 +# 0x1402... would be FAKEFAKE... if encoded in BASE64 +key: 0x140284140284140284140284 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_toWire2.wire b/src/lib/dns/tests/testdata/rdata_tkey_toWire2.wire new file mode 100644 index 0000000..a1fdb9a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_toWire2.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_toWire2.spec +### + +# TKEY RDATA, RDLEN=38 +0026 +# Algorithm=GSS-TSIG +084753532d5453494700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=16 +608d42c0 608d50d0 0003 0010 +# Key Len=12 Key=(see hex) +000c 140284140284140284140284 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_toWire3.spec b/src/lib/dns/tests/testdata/rdata_tkey_toWire3.spec new file mode 100644 index 0000000..b3ea3db --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_toWire3.spec @@ -0,0 +1,13 @@ +# +# An artificial TKEY RDATA for toWire test. +# +[custom] +sections: tkey +[tkey] +algorithm: gss.tsig +error: 16 +key_len: 12 +# 0x1402... would be FAKEFAKE... if encoded in BASE64 +key: 0x140284140284140284140284 +other_len: 6 +other_data: 0x140284140284 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_toWire3.wire b/src/lib/dns/tests/testdata/rdata_tkey_toWire3.wire new file mode 100644 index 0000000..f2f8a6f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_toWire3.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tkey_toWire3.spec +### + +# TKEY RDATA, RDLEN=44 +002c +# Algorithm=gss.tsig +03677373047473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=16 +608d42c0 608d50d0 0003 0010 +# Key Len=12 Key=(see hex) +000c 140284140284140284140284 +# Other-Len=6 Other-Data=(see hex) +0006 140284140284 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_toWire4.spec b/src/lib/dns/tests/testdata/rdata_tkey_toWire4.spec new file mode 100644 index 0000000..e403c00 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_toWire4.spec @@ -0,0 +1,10 @@ +# +# An artificial TKEY RDATA for toWire test. +# +[custom] +sections: name:tkey +[name] +name: gss-tsig +[tkey] +algorithm: gss-tsig +key_len: 0 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_toWire4.wire b/src/lib/dns/tests/testdata/rdata_tkey_toWire4.wire new file mode 100644 index 0000000..81a1443 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_toWire4.wire @@ -0,0 +1,17 @@ +### +### This data file was auto-generated from rdata_tkey_toWire4.spec +### + +# DNS Name: gss-tsig +086773732d7473696700 + +# TKEY RDATA, RDLEN=26 +001a +# Algorithm=gss-tsig +086773732d7473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=0 Key=(see hex) +0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_toWire5.spec b/src/lib/dns/tests/testdata/rdata_tkey_toWire5.spec new file mode 100644 index 0000000..b4a1bca --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_toWire5.spec @@ -0,0 +1,10 @@ +# +# An artificial TKEY RDATA for toWire test. +# +[custom] +sections: tkey:name +[tkey] +algorithm: gss-tsig +key_len: 0 +[name] +name: ptr=2 diff --git a/src/lib/dns/tests/testdata/rdata_tkey_toWire5.wire b/src/lib/dns/tests/testdata/rdata_tkey_toWire5.wire new file mode 100644 index 0000000..e59a1f0 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tkey_toWire5.wire @@ -0,0 +1,17 @@ +### +### This data file was auto-generated from rdata_tkey_toWire5.spec +### + +# TKEY RDATA, RDLEN=26 +001a +# Algorithm=gss-tsig +086773732d7473696700 +# Inception=1619870400 Expire=1619874000 Mode=3 Error=0 +608d42c0 608d50d0 0003 0000 +# Key Len=0 Key=(see hex) +0000 +# Other-Len=0 Other-Data=(see hex) +0000 + +# DNS Name: ptr=2 +c002 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire new file mode 100644 index 0000000..38e279c --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire @@ -0,0 +1,4 @@ +# TLSA RDATA, RDLEN=35 +0023 +# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=... +00 00 01 d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire10 b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire10 new file mode 100644 index 0000000..67cecb1 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire10 @@ -0,0 +1,6 @@ +# Test where certificate association data is missing. + +# TLSA RDATA, RDLEN=35 +0023 +# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=(missing) +00 00 01 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire11 b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire11 new file mode 100644 index 0000000..4b8ec93 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire11 @@ -0,0 +1,4 @@ +# Test where RDATA is completely missing + +# TLSA RDATA, RDLEN=35 +0023 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire12 b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire12 new file mode 100644 index 0000000..71c7b9c --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire12 @@ -0,0 +1,4 @@ +# TLSA RDATA, RDLEN=3 +0003 +# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=(none) +03 01 02 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire2 b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire2 new file mode 100644 index 0000000..36ce278 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire2 @@ -0,0 +1,4 @@ +# TLSA RDATA, RDLEN=35 +0023 +# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=... +00 00 01 d2abde240d7cd3ee6b4b28c54df034b97983A1D16E8A410E4561CB106618E971 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire3.spec new file mode 100644 index 0000000..39c8057 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire3.spec @@ -0,0 +1,7 @@ +# +# TLSA RDATA +# +[custom] +sections: tlsa +[tlsa] +certificate_usage: 0 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire3.wire b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire3.wire new file mode 100644 index 0000000..6a8b552 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire3.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_tlsa_fromWire3.spec +### + +# TLSA RDATA, RDLEN=34 +0022 +# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 +00 00 01 d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire4.spec new file mode 100644 index 0000000..d97ae6a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire4.spec @@ -0,0 +1,7 @@ +# +# TLSA RDATA +# +[custom] +sections: tlsa +[tlsa] +certificate_usage: 255 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire4.wire new file mode 100644 index 0000000..b5a39c8 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire4.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_tlsa_fromWire4.spec +### + +# TLSA RDATA, RDLEN=34 +0022 +# CERTIFICATE_USAGE=255 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 +ff 00 01 d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire5.spec new file mode 100644 index 0000000..cc3e296 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire5.spec @@ -0,0 +1,7 @@ +# +# TLSA RDATA +# +[custom] +sections: tlsa +[tlsa] +selector: 255 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire5.wire b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire5.wire new file mode 100644 index 0000000..b79f97d --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire5.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_tlsa_fromWire5.spec +### + +# TLSA RDATA, RDLEN=34 +0022 +# CERTIFICATE_USAGE=0 SELECTOR=255 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 +00 ff 01 d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire6.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire6.spec new file mode 100644 index 0000000..eed0ab9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire6.spec @@ -0,0 +1,7 @@ +# +# TLSA RDATA +# +[custom] +sections: tlsa +[tlsa] +matching_type: 255 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire6.wire b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire6.wire new file mode 100644 index 0000000..02afe27 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire6.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_tlsa_fromWire6.spec +### + +# TLSA RDATA, RDLEN=34 +0022 +# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=255 CERTIFICATE_ASSOCIATION_DATA=d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 +00 00 ff d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire7.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire7.spec new file mode 100644 index 0000000..576df1e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire7.spec @@ -0,0 +1,9 @@ +# +# TLSA RDATA +# +[custom] +sections: tlsa +[tlsa] +certificate_usage: 3 +selector: 1 +matching_type: 2 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire7.wire b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire7.wire new file mode 100644 index 0000000..e5c23a4 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire7.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_tlsa_fromWire7.spec +### + +# TLSA RDATA, RDLEN=34 +0022 +# CERTIFICATE_USAGE=3 SELECTOR=1 MATCHING_TYPE=2 CERTIFICATE_ASSOCIATION_DATA=d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 +03 01 02 d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire8.spec b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire8.spec new file mode 100644 index 0000000..ef5c108 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire8.spec @@ -0,0 +1,7 @@ +# +# TLSA RDATA +# +[custom] +sections: tlsa +[tlsa] +certificate_association_data: '0123' diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire8.wire b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire8.wire new file mode 100644 index 0000000..dc29a0b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire8.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_tlsa_fromWire8.spec +### + +# TLSA RDATA, RDLEN=4 +0004 +# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=0123 +00 00 01 0123 diff --git a/src/lib/dns/tests/testdata/rdata_tlsa_fromWire9 b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire9 new file mode 100644 index 0000000..fc4560a --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tlsa_fromWire9 @@ -0,0 +1,7 @@ +# Test where certificate association data length is smaller than what +# RDATA length indicates. + +# TLSA RDATA, RDLEN=64 +0040 +# CERTIFICATE_USAGE=0 SELECTOR=0 MATCHING_TYPE=1 CERTIFICATE_ASSOCIATION_DATA=(32 bytes) +00 00 01 d2abde240d7cd3ee6b4b28c54df034b97983a1d16e8a410e4561cb106618e971 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire1.spec b/src/lib/dns/tests/testdata/rdata_tsig_fromWire1.spec new file mode 100644 index 0000000..a30c371 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire1.spec @@ -0,0 +1,6 @@ +# +# A simplest form of TSIG: all default parameters +# +[custom] +sections: tsig +[tsig] diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire1.wire b/src/lib/dns/tests/testdata/rdata_tsig_fromWire1.wire new file mode 100644 index 0000000..cec3a0f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire1.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_fromWire1.spec +### + +# TSIG RDATA, RDLEN=61 +003d +# Algorithm=hmac-sha256 Time-Signed=1286978795 Fudge=300 +0b686d61632d73686132353600 00004cb5bceb 012c +# MAC Size=32 MAC=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Original-ID=2845 Error=0 +0b1d 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_tsig_fromWire2.spec new file mode 100644 index 0000000..d1e49a5 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire2.spec @@ -0,0 +1,8 @@ +# +# TSIG with other data (error = BADTIME(18)) +# +[custom] +sections: tsig +[tsig] +mac_size: 0 +error: 18 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_tsig_fromWire2.wire new file mode 100644 index 0000000..ca85df4 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire2.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_fromWire2.spec +### + +# TSIG RDATA, RDLEN=35 +0023 +# Algorithm=hmac-sha256 Time-Signed=1286978795 Fudge=300 +0b686d61632d73686132353600 00004cb5bceb 012c +# MAC Size=0 MAC=(see hex) +0000 +# Original-ID=2845 Error=18 +0b1d 0012 +# Other-Len=6 Other-Data=(see hex) +0006 00004cb5be18 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_tsig_fromWire3.spec new file mode 100644 index 0000000..57f8e83 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire3.spec @@ -0,0 +1,8 @@ +# +# TSIG without MAC (error = BADSIG(16)) +# +[custom] +sections: tsig +[tsig] +mac_size: 0 +error: 16 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire3.wire b/src/lib/dns/tests/testdata/rdata_tsig_fromWire3.wire new file mode 100644 index 0000000..16c3e39 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire3.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_fromWire3.spec +### + +# TSIG RDATA, RDLEN=29 +001d +# Algorithm=hmac-sha256 Time-Signed=1286978795 Fudge=300 +0b686d61632d73686132353600 00004cb5bceb 012c +# MAC Size=0 MAC=(see hex) +0000 +# Original-ID=2845 Error=16 +0b1d 0010 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_tsig_fromWire4.spec new file mode 100644 index 0000000..8c38e9e --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire4.spec @@ -0,0 +1,11 @@ +# +# A simplest form of TSIG, but the algorithm name is compressed (quite +# pathological, but we accept it) +# +[custom] +sections: name:tsig +[name] +name: hmac-sha256 +[tsig] +algorithm: ptr=0 +mac_size: 32 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_tsig_fromWire4.wire new file mode 100644 index 0000000..6b8e0f3 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire4.wire @@ -0,0 +1,17 @@ +### +### This data file was auto-generated from rdata_tsig_fromWire4.spec +### + +# DNS Name: hmac-sha256 +0b686d61632d73686132353600 + +# TSIG RDATA, RDLEN=50 +0032 +# Algorithm=ptr=0 Time-Signed=1286978795 Fudge=300 +c000 00004cb5bceb 012c +# MAC Size=32 MAC=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Original-ID=2845 Error=0 +0b1d 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_tsig_fromWire5.spec new file mode 100644 index 0000000..da90b18 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire5.spec @@ -0,0 +1,7 @@ +# +# TSIG-like RDATA but RDLEN is too short. +# +[custom] +sections: tsig +[tsig] +rdlen: 60 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire5.wire b/src/lib/dns/tests/testdata/rdata_tsig_fromWire5.wire new file mode 100644 index 0000000..9656ce2 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire5.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_fromWire5.spec +### + +# TSIG RDATA, RDLEN=60 +003c +# Algorithm=hmac-sha256 Time-Signed=1286978795 Fudge=300 +0b686d61632d73686132353600 00004cb5bceb 012c +# MAC Size=32 MAC=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Original-ID=2845 Error=0 +0b1d 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire6.spec b/src/lib/dns/tests/testdata/rdata_tsig_fromWire6.spec new file mode 100644 index 0000000..9d2f627 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire6.spec @@ -0,0 +1,7 @@ +# +# TSIG-like RDATA but RDLEN is too long. +# +[custom] +sections: tsig +[tsig] +rdlen: 63 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire6.wire b/src/lib/dns/tests/testdata/rdata_tsig_fromWire6.wire new file mode 100644 index 0000000..bb1ecfb --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire6.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_fromWire6.spec +### + +# TSIG RDATA, RDLEN=63 +003f +# Algorithm=hmac-sha256 Time-Signed=1286978795 Fudge=300 +0b686d61632d73686132353600 00004cb5bceb 012c +# MAC Size=32 MAC=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Original-ID=2845 Error=0 +0b1d 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire7.spec b/src/lib/dns/tests/testdata/rdata_tsig_fromWire7.spec new file mode 100644 index 0000000..ed7a81c --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire7.spec @@ -0,0 +1,8 @@ +# +# TSIG-like RDATA but algorithm name is broken. +# +[custom] +sections: tsig +[tsig] +algorithm: "01234567890123456789012345678901234567890123456789012345678901234" +mac_size: 32 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire7.wire b/src/lib/dns/tests/testdata/rdata_tsig_fromWire7.wire new file mode 100644 index 0000000..327211f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire7.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_fromWire7.spec +### + +# TSIG RDATA, RDLEN=117 +0075 +# Algorithm="01234567890123456789012345678901234567890123456789012345678901234" Time-Signed=1286978795 Fudge=300 +432230313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233342200 00004cb5bceb 012c +# MAC Size=32 MAC=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Original-ID=2845 Error=0 +0b1d 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire8.spec b/src/lib/dns/tests/testdata/rdata_tsig_fromWire8.spec new file mode 100644 index 0000000..0b44f87 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire8.spec @@ -0,0 +1,8 @@ +# +# TSIG-like RDATA but MAC size is bogus +# +[custom] +sections: tsig +[tsig] +mac_size: 65535 +mac: "dummy data" diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire8.wire b/src/lib/dns/tests/testdata/rdata_tsig_fromWire8.wire new file mode 100644 index 0000000..a4209f9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire8.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_fromWire8.spec +### + +# TSIG RDATA, RDLEN=41 +0029 +# Algorithm=hmac-sha256 Time-Signed=1286978795 Fudge=300 +0b686d61632d73686132353600 00004cb5bceb 012c +# MAC Size=65535 MAC=(see hex) +ffff 2264756d6d79206461746122 +# Original-ID=2845 Error=0 +0b1d 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire9.spec b/src/lib/dns/tests/testdata/rdata_tsig_fromWire9.spec new file mode 100644 index 0000000..f512fb4 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire9.spec @@ -0,0 +1,8 @@ +# +# TSIG-like RDATA but Other-Data length is bogus +# +[custom] +sections: tsig +[tsig] +other_len: 65535 +otherdata: "dummy data" diff --git a/src/lib/dns/tests/testdata/rdata_tsig_fromWire9.wire b/src/lib/dns/tests/testdata/rdata_tsig_fromWire9.wire new file mode 100644 index 0000000..b356825 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_fromWire9.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_fromWire9.spec +### + +# TSIG RDATA, RDLEN=61 +003d +# Algorithm=hmac-sha256 Time-Signed=1286978795 Fudge=300 +0b686d61632d73686132353600 00004cb5bceb 012c +# MAC Size=32 MAC=(see hex) +0020 7878787878787878787878787878787878787878787878787878787878787878 +# Original-ID=2845 Error=0 +0b1d 0000 +# Other-Len=65535 Other-Data=(see hex) +ffff diff --git a/src/lib/dns/tests/testdata/rdata_tsig_toWire1.spec b/src/lib/dns/tests/testdata/rdata_tsig_toWire1.spec new file mode 100644 index 0000000..eb74000 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_toWire1.spec @@ -0,0 +1,11 @@ +# +# An artificial TSIG RDATA for toWire test. +# +[custom] +sections: tsig +[tsig] +algorithm: hmac-md5 +time_signed: 1286779327 +mac_size: 0 +original_id: 16020 +error: 17 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_toWire1.wire b/src/lib/dns/tests/testdata/rdata_tsig_toWire1.wire new file mode 100644 index 0000000..c368853 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_toWire1.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_toWire1.spec +### + +# TSIG RDATA, RDLEN=42 +002a +# Algorithm=hmac-md5 Time-Signed=1286779327 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004cb2b1bf 012c +# MAC Size=0 MAC=(see hex) +0000 +# Original-ID=16020 Error=17 +3e94 0011 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_toWire2.spec b/src/lib/dns/tests/testdata/rdata_tsig_toWire2.spec new file mode 100644 index 0000000..b2c38e9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_toWire2.spec @@ -0,0 +1,13 @@ +# +# An artificial TSIG RDATA for toWire test. +# +[custom] +sections: tsig +[tsig] +algorithm: hmac-sha256 +time_signed: 1286779327 +mac_size: 12 +# 0x1402... would be FAKEFAKE... if encoded in BASE64 +mac: 0x140284140284140284140284 +original_id: 16020 +error: 16 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_toWire2.wire b/src/lib/dns/tests/testdata/rdata_tsig_toWire2.wire new file mode 100644 index 0000000..7ea336d --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_toWire2.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_toWire2.spec +### + +# TSIG RDATA, RDLEN=41 +0029 +# Algorithm=hmac-sha256 Time-Signed=1286779327 Fudge=300 +0b686d61632d73686132353600 00004cb2b1bf 012c +# MAC Size=12 MAC=(see hex) +000c 140284140284140284140284 +# Original-ID=16020 Error=16 +3e94 0010 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_toWire3.spec b/src/lib/dns/tests/testdata/rdata_tsig_toWire3.spec new file mode 100644 index 0000000..6520a08 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_toWire3.spec @@ -0,0 +1,15 @@ +# +# An artificial TSIG RDATA for toWire test. +# +[custom] +sections: tsig +[tsig] +algorithm: hmac-sha1 +time_signed: 1286779327 +mac_size: 12 +# 0x1402... would be FAKEFAKE... if encoded in BASE64 +mac: 0x140284140284140284140284 +original_id: 16020 +error: 18 +other_len: 6 +other_data: 0x140284140284 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_toWire3.wire b/src/lib/dns/tests/testdata/rdata_tsig_toWire3.wire new file mode 100644 index 0000000..535a83b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_toWire3.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from rdata_tsig_toWire3.spec +### + +# TSIG RDATA, RDLEN=45 +002d +# Algorithm=hmac-sha1 Time-Signed=1286779327 Fudge=300 +09686d61632d7368613100 00004cb2b1bf 012c +# MAC Size=12 MAC=(see hex) +000c 140284140284140284140284 +# Original-ID=16020 Error=18 +3e94 0012 +# Other-Len=6 Other-Data=(see hex) +0006 140284140284 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_toWire4.spec b/src/lib/dns/tests/testdata/rdata_tsig_toWire4.spec new file mode 100644 index 0000000..d95cd23 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_toWire4.spec @@ -0,0 +1,13 @@ +# +# An artificial TSIG RDATA for toWire test. +# +[custom] +sections: name:tsig +[name] +name: hmac-md5.sig-alg.reg.int. +[tsig] +algorithm: hmac-md5 +time_signed: 1286779327 +mac_size: 0 +original_id: 16020 +error: 17 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_toWire4.wire b/src/lib/dns/tests/testdata/rdata_tsig_toWire4.wire new file mode 100644 index 0000000..5e8f68b --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_toWire4.wire @@ -0,0 +1,17 @@ +### +### This data file was auto-generated from rdata_tsig_toWire4.spec +### + +# DNS Name: hmac-md5.sig-alg.reg.int. +08686d61632d6d6435077369672d616c670372656703696e7400 + +# TSIG RDATA, RDLEN=42 +002a +# Algorithm=hmac-md5 Time-Signed=1286779327 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004cb2b1bf 012c +# MAC Size=0 MAC=(see hex) +0000 +# Original-ID=16020 Error=17 +3e94 0011 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_toWire5.spec b/src/lib/dns/tests/testdata/rdata_tsig_toWire5.spec new file mode 100644 index 0000000..81e3a78 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_toWire5.spec @@ -0,0 +1,13 @@ +# +# An artificial TSIG RDATA for toWire test. +# +[custom] +sections: tsig:name +[tsig] +algorithm: hmac-md5 +time_signed: 1286779327 +mac_size: 0 +original_id: 16020 +error: 17 +[name] +name: ptr=2 diff --git a/src/lib/dns/tests/testdata/rdata_tsig_toWire5.wire b/src/lib/dns/tests/testdata/rdata_tsig_toWire5.wire new file mode 100644 index 0000000..bc83de6 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_tsig_toWire5.wire @@ -0,0 +1,17 @@ +### +### This data file was auto-generated from rdata_tsig_toWire5.spec +### + +# TSIG RDATA, RDLEN=42 +002a +# Algorithm=hmac-md5 Time-Signed=1286779327 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004cb2b1bf 012c +# MAC Size=0 MAC=(see hex) +0000 +# Original-ID=16020 Error=17 +3e94 0011 +# Other-Len=0 Other-Data=(see hex) +0000 + +# DNS Name: ptr=2 +c002 diff --git a/src/lib/dns/tests/testdata/rdata_txt_fromWire1 b/src/lib/dns/tests/testdata/rdata_txt_fromWire1 new file mode 100644 index 0000000..547d76f --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_txt_fromWire1 @@ -0,0 +1,9 @@ +# +# various kinds of TXT RDATA stored in an input buffer +# +# Valid RDATA for "Test-String" +# +# RDLENGTH=12 bytes + 00 0c +# T e s t - S t r i n g + 0b 54 65 73 74 2d 53 74 72 69 6e 67 diff --git a/src/lib/dns/tests/testdata/rdata_txt_fromWire2.spec b/src/lib/dns/tests/testdata/rdata_txt_fromWire2.spec new file mode 100644 index 0000000..c5829d9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_txt_fromWire2.spec @@ -0,0 +1,8 @@ +# +# TXT RDATA with empty character-string. unusual, but valid. +# + +[custom] +sections: txt +[txt] +string: '' diff --git a/src/lib/dns/tests/testdata/rdata_txt_fromWire2.wire b/src/lib/dns/tests/testdata/rdata_txt_fromWire2.wire new file mode 100644 index 0000000..83ebea3 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_txt_fromWire2.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_txt_fromWire2.spec +### + +# TXT RDATA, RDLEN=1 +0001 +# String Len=0, String="" +00 diff --git a/src/lib/dns/tests/testdata/rdata_txt_fromWire3.spec b/src/lib/dns/tests/testdata/rdata_txt_fromWire3.spec new file mode 100644 index 0000000..fe5c129 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_txt_fromWire3.spec @@ -0,0 +1,8 @@ +# +# TXT RDATA with multiple character-strings. +# + +[custom] +sections: txt +[txt] +nstring: 2 diff --git a/src/lib/dns/tests/testdata/rdata_txt_fromWire3.wire b/src/lib/dns/tests/testdata/rdata_txt_fromWire3.wire new file mode 100644 index 0000000..42fdf76 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_txt_fromWire3.wire @@ -0,0 +1,10 @@ +### +### This data file was auto-generated from rdata_txt_fromWire3.spec +### + +# TXT RDATA, RDLEN=24 +0018 +# String Len=11, String="Test-String" +0b 546573742d537472696e67 +# String Len=11, String="Test-String" +0b 546573742d537472696e67 diff --git a/src/lib/dns/tests/testdata/rdata_txt_fromWire4.spec b/src/lib/dns/tests/testdata/rdata_txt_fromWire4.spec new file mode 100644 index 0000000..0e015d4 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_txt_fromWire4.spec @@ -0,0 +1,9 @@ +# +# Malformed TXT RDATA: RDLEN is 0 +# + +[custom] +sections: txt +[txt] +rdlen: 0 +# following data is provided, but that doesn't matter. diff --git a/src/lib/dns/tests/testdata/rdata_txt_fromWire4.wire b/src/lib/dns/tests/testdata/rdata_txt_fromWire4.wire new file mode 100644 index 0000000..6ac73b8 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_txt_fromWire4.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_txt_fromWire4.spec +### + +# TXT RDATA, RDLEN=0 +0000 +# String Len=11, String="Test-String" +0b 546573742d537472696e67 diff --git a/src/lib/dns/tests/testdata/rdata_txt_fromWire5.spec b/src/lib/dns/tests/testdata/rdata_txt_fromWire5.spec new file mode 100644 index 0000000..7710cdf --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_txt_fromWire5.spec @@ -0,0 +1,9 @@ +# +# Malformed TXT RDATA: character-string length is too large +# + +[custom] +sections: txt +[txt] +stringlen: 255 +string: 'too short' diff --git a/src/lib/dns/tests/testdata/rdata_txt_fromWire5.wire b/src/lib/dns/tests/testdata/rdata_txt_fromWire5.wire new file mode 100644 index 0000000..ea7a9cf --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_txt_fromWire5.wire @@ -0,0 +1,8 @@ +### +### This data file was auto-generated from rdata_txt_fromWire5.spec +### + +# TXT RDATA, RDLEN=10 +000a +# String Len=255, String="too short" +ff 746f6f2073686f7274 diff --git a/src/lib/dns/tests/testdata/rdata_unknown_fromWire b/src/lib/dns/tests/testdata/rdata_unknown_fromWire new file mode 100644 index 0000000..69ea8ff --- /dev/null +++ b/src/lib/dns/tests/testdata/rdata_unknown_fromWire @@ -0,0 +1,13 @@ +# +# various kinds of "unknown" RDATA stored in an input buffer +# +# 0 1 2 3 4 5 (bytes) + 00 04 a1 b2 c3 0d +# +# 0-length data +# 6 7 + 00 00 +# +# short buffer (this can be tested only at the end of the buffer) +# 8 9 10 1 2 + 00 04 a1 b2 c3 diff --git a/src/lib/dns/tests/testdata/rdatafields1.spec b/src/lib/dns/tests/testdata/rdatafields1.spec new file mode 100644 index 0000000..6e105fb --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields1.spec @@ -0,0 +1,10 @@ +# +# A sequence of names that could be compressed (but not compressed) +# + +[custom] +sections: name/1:name/2 +[name/1] +name: www.example.com +[name/2] +name: example.com diff --git a/src/lib/dns/tests/testdata/rdatafields1.wire b/src/lib/dns/tests/testdata/rdatafields1.wire new file mode 100644 index 0000000..42028c1 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields1.wire @@ -0,0 +1,9 @@ +### +### This data file was auto-generated from rdatafields1.spec +### + +# DNS Name: www.example.com +03777777076578616d706c6503636f6d00 + +# DNS Name: example.com +076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdatafields2.spec b/src/lib/dns/tests/testdata/rdatafields2.spec new file mode 100644 index 0000000..920dc95 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields2.spec @@ -0,0 +1,11 @@ +# +# A sequence of names that can be compressed. +# + +[custom] +sections: name/1:name/2 +[name/1] +name: www.example.com +[name/2] +name: '' +pointer: 4 diff --git a/src/lib/dns/tests/testdata/rdatafields2.wire b/src/lib/dns/tests/testdata/rdatafields2.wire new file mode 100644 index 0000000..cbb0ce0 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields2.wire @@ -0,0 +1,9 @@ +### +### This data file was auto-generated from rdatafields2.spec +### + +# DNS Name: www.example.com +03777777076578616d706c6503636f6d00 + +# DNS Name: + compression pointer: 4 +c004 diff --git a/src/lib/dns/tests/testdata/rdatafields3.spec b/src/lib/dns/tests/testdata/rdatafields3.spec new file mode 100644 index 0000000..b37fca3 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields3.spec @@ -0,0 +1,11 @@ +# +# TXT RDATA with multiple character-strings. +# + +[custom] +sections: txt +[txt] +nstring: 3 +string0: 'first string' +string1: 'second string' +string2: 'last string' diff --git a/src/lib/dns/tests/testdata/rdatafields3.wire b/src/lib/dns/tests/testdata/rdatafields3.wire new file mode 100644 index 0000000..3ff32f1 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields3.wire @@ -0,0 +1,12 @@ +### +### This data file was auto-generated from rdatafields3.spec +### + +# TXT RDATA, RDLEN=39 +0027 +# String Len=12, String="first string" +0c 666972737420737472696e67 +# String Len=13, String="second string" +0d 7365636f6e6420737472696e67 +# String Len=11, String="last string" +0b 6c61737420737472696e67 diff --git a/src/lib/dns/tests/testdata/rdatafields4.spec b/src/lib/dns/tests/testdata/rdatafields4.spec new file mode 100644 index 0000000..24b59aa --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields4.spec @@ -0,0 +1,7 @@ +# +# Simple form of RRSIG (all fields use the default of generator script) +# + +[custom] +sections: rrsig +[rrsig] diff --git a/src/lib/dns/tests/testdata/rdatafields4.wire b/src/lib/dns/tests/testdata/rdatafields4.wire new file mode 100644 index 0000000..e574426 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields4.wire @@ -0,0 +1,12 @@ +### +### This data file was auto-generated from rdatafields4.spec +### + +# RRSIG RDATA, RDLEN=46 +002e +# Covered=A(1) Algorithm=RSASHA1(5) Labels=2 OrigTTL=3600 +0001 05 02 00000e10 +# Expiration=1264935600, Inception=1262343600 +4b6562b0 4b3dd5b0 +# Tag=4149 Signer=example.com and Signature +1035 076578616d706c6503636f6d00 123456789abcdef123456789abcdef diff --git a/src/lib/dns/tests/testdata/rdatafields5.spec b/src/lib/dns/tests/testdata/rdatafields5.spec new file mode 100644 index 0000000..2c78282 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields5.spec @@ -0,0 +1,12 @@ +# +# Names and RDATA (RRSIG) with an incompressible name. All names are +# rendered without compression. +# + +[custom] +sections: name/1:rrsig:name/2 +[name/1] +name: com +[rrsig] +[name/2] +name: www.example.com diff --git a/src/lib/dns/tests/testdata/rdatafields5.wire b/src/lib/dns/tests/testdata/rdatafields5.wire new file mode 100644 index 0000000..d0cebc9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields5.wire @@ -0,0 +1,18 @@ +### +### This data file was auto-generated from rdatafields5.spec +### + +# DNS Name: com +03636f6d00 + +# RRSIG RDATA, RDLEN=46 +002e +# Covered=A(1) Algorithm=RSASHA1(5) Labels=2 OrigTTL=3600 +0001 05 02 00000e10 +# Expiration=1264935600, Inception=1262343600 +4b6562b0 4b3dd5b0 +# Tag=4149 Signer=example.com and Signature +1035 076578616d706c6503636f6d00 123456789abcdef123456789abcdef + +# DNS Name: www.example.com +03777777076578616d706c6503636f6d00 diff --git a/src/lib/dns/tests/testdata/rdatafields6.spec b/src/lib/dns/tests/testdata/rdatafields6.spec new file mode 100644 index 0000000..f9f0da1 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields6.spec @@ -0,0 +1,13 @@ +# +# Names and RDATA (RRSIG) with an incompressible name. The name in RRSIG +# isn't compressed, but it's used as the compression target. +# + +[custom] +sections: name/1:rrsig:name/2 +[name/1] +name: com +[rrsig] +[name/2] +name: www +pointer: 25 diff --git a/src/lib/dns/tests/testdata/rdatafields6.wire b/src/lib/dns/tests/testdata/rdatafields6.wire new file mode 100644 index 0000000..0e8b3d9 --- /dev/null +++ b/src/lib/dns/tests/testdata/rdatafields6.wire @@ -0,0 +1,18 @@ +### +### This data file was auto-generated from rdatafields6.spec +### + +# DNS Name: com +03636f6d00 + +# RRSIG RDATA, RDLEN=46 +002e +# Covered=A(1) Algorithm=RSASHA1(5) Labels=2 OrigTTL=3600 +0001 05 02 00000e10 +# Expiration=1264935600, Inception=1262343600 +4b6562b0 4b3dd5b0 +# Tag=4149 Signer=example.com and Signature +1035 076578616d706c6503636f6d00 123456789abcdef123456789abcdef + +# DNS Name: www + compression pointer: 25 +03777777c019 diff --git a/src/lib/dns/tests/testdata/rrcode16_fromWire1 b/src/lib/dns/tests/testdata/rrcode16_fromWire1 new file mode 100644 index 0000000..df2a177 --- /dev/null +++ b/src/lib/dns/tests/testdata/rrcode16_fromWire1 @@ -0,0 +1,4 @@ +# +# a 16 bit wire-format data (network byte order) +# +1234 diff --git a/src/lib/dns/tests/testdata/rrcode16_fromWire2 b/src/lib/dns/tests/testdata/rrcode16_fromWire2 new file mode 100644 index 0000000..fec2dd0 --- /dev/null +++ b/src/lib/dns/tests/testdata/rrcode16_fromWire2 @@ -0,0 +1,4 @@ +# +# an incomplete segment for a 16 bit wire-format data +# +12 diff --git a/src/lib/dns/tests/testdata/rrcode32_fromWire1 b/src/lib/dns/tests/testdata/rrcode32_fromWire1 new file mode 100644 index 0000000..fb2818f --- /dev/null +++ b/src/lib/dns/tests/testdata/rrcode32_fromWire1 @@ -0,0 +1,4 @@ +# +# a 32 bit wire-format data (network byte order) +# +12345678 diff --git a/src/lib/dns/tests/testdata/rrcode32_fromWire2 b/src/lib/dns/tests/testdata/rrcode32_fromWire2 new file mode 100644 index 0000000..504d9d2 --- /dev/null +++ b/src/lib/dns/tests/testdata/rrcode32_fromWire2 @@ -0,0 +1,4 @@ +# +# an incomplete segment for a 32 bit wire-format data +# +123456 diff --git a/src/lib/dns/tests/testdata/rrset_toWire1 b/src/lib/dns/tests/testdata/rrset_toWire1 new file mode 100644 index 0000000..8f81a0e --- /dev/null +++ b/src/lib/dns/tests/testdata/rrset_toWire1 @@ -0,0 +1,23 @@ +# +# Rendering an IN/A RRset containing 2 RRs: +# test.example.com. 3600 IN A 192.0.2.1 +# test.example.com. 3600 IN A 192.0.2.2 +# +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# type/class: A = 1, IN = 1 +00 01 00 01 +# TTL: 3600 +00 00 0e 10 +#6 7 +# RDLENGTH: 4 +00 04 +# RDATA: 192.0.2.1 +c0 00 02 01 +# +# 2nd RR: mostly the same except the RDATA +04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +00 01 00 01 +00 00 0e 10 +00 04 +c0 00 02 02 diff --git a/src/lib/dns/tests/testdata/rrset_toWire2 b/src/lib/dns/tests/testdata/rrset_toWire2 new file mode 100644 index 0000000..ca6483f --- /dev/null +++ b/src/lib/dns/tests/testdata/rrset_toWire2 @@ -0,0 +1,38 @@ +# +# Rendering an IN/A RRset and NS RRset as follows: +# test.example.com. 3600 IN A 192.0.2.1 +# test.example.com. 3600 IN A 192.0.2.2 +# example.com. 1D IN NS ns.example.com. +# Names will be compressed when possible. +# +# 0 1 2 3 4 5 +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# type/class: A = 1, IN = 1 +00 01 00 01 +# TTL: 3600 +00 00 0e 10 +#6 7 +# RDLENGTH: 4 +00 04 +# RDATA: 192.0.2.1 +c0 00 02 01 +# +# 2nd RR: the owner name is compressed +c0 00 +00 01 00 01 +00 00 0e 10 +00 04 +c0 00 02 02 +# 3rd RR: the owner name and NS name are compressed +# pointing to the 5th octet of the owner name of the 1st RR +c0 05 +# type/class: NS = 2, IN = 1 +00 02 00 01 +# TTL: 1D = 86400sec = 0x15180 +00 01 51 80 +# RDLENGTH: 5 octets +00 05 +# NSDNAME: "ns." + compression pointer +#(2) n s + 02 6e 73 c0 05 diff --git a/src/lib/dns/tests/testdata/rrset_toWire3 b/src/lib/dns/tests/testdata/rrset_toWire3 new file mode 100644 index 0000000..47f8e6b --- /dev/null +++ b/src/lib/dns/tests/testdata/rrset_toWire3 @@ -0,0 +1,12 @@ +# +# Rendering an empty IN/A RRset +# +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# type/class: A = 1, ANY = 255 +00 01 00 ff +# TTL: 3600 +00 00 0e 10 +#6 7 +# RDLENGTH: 0 +00 00 diff --git a/src/lib/dns/tests/testdata/rrset_toWire4 b/src/lib/dns/tests/testdata/rrset_toWire4 new file mode 100644 index 0000000..6fb409c --- /dev/null +++ b/src/lib/dns/tests/testdata/rrset_toWire4 @@ -0,0 +1,12 @@ +# +# Rendering an empty IN/A RRset +# +#(4) t e s t (7) e x a m p l e (3) c o m . + 04 74 65 73 74 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 +# type/class: A = 1, ANY = 255 +00 01 00 fe +# TTL: 3600 +00 00 0e 10 +#6 7 +# RDLENGTH: 0 +00 00 diff --git a/src/lib/dns/tests/testdata/tsig_verify1.spec b/src/lib/dns/tests/testdata/tsig_verify1.spec new file mode 100644 index 0000000..687013a --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify1.spec @@ -0,0 +1,19 @@ +# +# An example of signed AXFR request +# + +[custom] +sections: header:question:tsig +[header] +id: 0x3410 +arcount: 1 +[question] +rrtype: AXFR +[tsig] +as_rr: True +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8e951 +mac_size: 16 +mac: 0x35b2fd08268781634400c7c8a5533b13 +original_id: 0x3410 diff --git a/src/lib/dns/tests/testdata/tsig_verify1.wire b/src/lib/dns/tests/testdata/tsig_verify1.wire new file mode 100644 index 0000000..b2d12f1 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify1.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from tsig_verify1.spec +### + +# Header Section +# ID=13328 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) +3410 0000 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=example.com. QTYPE=AXFR(252) QCLASS=IN(1) +076578616d706c6503636f6d00 00fc 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302915409 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8e951 012c +# MAC Size=16 MAC=(see hex) +0010 35b2fd08268781634400c7c8a5533b13 +# Original-ID=13328 Error=0 +3410 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsig_verify10.spec b/src/lib/dns/tests/testdata/tsig_verify10.spec new file mode 100644 index 0000000..33ce83e --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify10.spec @@ -0,0 +1,22 @@ +# +# A simple DNS query message with TSIG signed whose MAC is too short +# (only 1 byte) +# + +[custom] +sections: header:question:tsig +[header] +id: 0x2d65 +rd: 1 +arcount: 1 +[question] +name: www.example.com +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 1 +mac: 0x22 +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/tsig_verify10.wire b/src/lib/dns/tests/testdata/tsig_verify10.wire new file mode 100644 index 0000000..9ffe4ea --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify10.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from tsig_verify10.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=43) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 002b +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=1 MAC=(see hex) +0001 22 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsig_verify11.spec b/src/lib/dns/tests/testdata/tsig_verify11.spec new file mode 100644 index 0000000..9927b48 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify11.spec @@ -0,0 +1,24 @@ +# +# A simple DNS query message with TSIG signed with truncated MAC +# using common HMAC-SHA512-256 +# + +[custom] +sections: header:question:tsig +[header] +id: 0x2d65 +rd: 1 +arcount: 1 +[question] +name: www.example.com +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-sha512 +time_signed: 0x4da8877a +#mac_size: 64 +mac_size: 32 +#mac: 0xc4bc4053572d62dd1b26998111565c18056be773dedc6ecea60dff31db2f25966e5d9bafbaaed56efbd5ee2d7e2a12ede4caad630ddf69846c980409724da34e +mac: 0xc4bc4053572d62dd1b26998111565c18056be773dedc6ecea60dff31db2f2596 +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/tsig_verify11.wire b/src/lib/dns/tests/testdata/tsig_verify11.wire new file mode 100644 index 0000000..f0a8f4f --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify11.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from tsig_verify11.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=61) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003d +# Algorithm=hmac-sha512 Time-Signed=1302890362 Fudge=300 +0b686d61632d73686135313200 00004da8877a 012c +# MAC Size=32 MAC=(see hex) +0020 c4bc4053572d62dd1b26998111565c18056be773dedc6ecea60dff31db2f2596 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsig_verify2.spec b/src/lib/dns/tests/testdata/tsig_verify2.spec new file mode 100644 index 0000000..ff98ca3 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify2.spec @@ -0,0 +1,32 @@ +# +# An example of signed AXFR response +# + +[custom] +sections: header:question:soa:tsig +[header] +id: 0x3410 +aa: 1 +qr: 1 +ancount: 1 +arcount: 1 +[question] +rrtype: AXFR +[soa] +# note that names are compressed in this RR +as_rr: True +rr_name: ptr=12 +mname: ns.ptr=12 +rname: root.ptr=12 +serial: 2011041503 +refresh: 7200 +retry: 3600 +expire: 2592000 +[tsig] +as_rr: True +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8e951 +mac_size: 16 +mac: 0xbdd612cd2c7f9e0648bd6dc23713e83c +original_id: 0x3410 diff --git a/src/lib/dns/tests/testdata/tsig_verify2.wire b/src/lib/dns/tests/testdata/tsig_verify2.wire new file mode 100644 index 0000000..65f5f89 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify2.wire @@ -0,0 +1,31 @@ +### +### This data file was auto-generated from tsig_verify2.spec +### + +# Header Section +# ID=13328 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) AA +3410 8400 +# QDCNT=1, ANCNT=1, NSCNT=0, ARCNT=1 +0001 0001 0000 0001 + +# Question Section +# QNAME=example.com. QTYPE=AXFR(252) QCLASS=IN(1) +076578616d706c6503636f6d00 00fc 0001 + +# SOA RR (QNAME=ptr=12 Class=IN(1) TTL=86400, RDLEN=32) +c00c 0006 0001 00015180 0020 +# NNAME=ns.ptr=12 RNAME=root.ptr=12 +026e73c00c 04726f6f74c00c +# SERIAL(2011041503) REFRESH(7200) RETRY(3600) EXPIRE(2592000) MINIMUM(1200) +77de0edf 00001c20 00000e10 00278d00 000004b0 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302915409 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8e951 012c +# MAC Size=16 MAC=(see hex) +0010 bdd612cd2c7f9e0648bd6dc23713e83c +# Original-ID=13328 Error=0 +3410 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsig_verify3.spec b/src/lib/dns/tests/testdata/tsig_verify3.spec new file mode 100644 index 0000000..7e2f797 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify3.spec @@ -0,0 +1,26 @@ +# +# An example of signed AXFR response (continued) +# + +[custom] +sections: header:ns:tsig +[header] +id: 0x3410 +aa: 1 +qr: 1 +qdcount: 0 +ancount: 1 +arcount: 1 +[ns] +# note that names are compressed in this RR +as_rr: True +rr_name: example.com. +nsname: ns.ptr=12 +[tsig] +as_rr: True +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8e951 +mac_size: 16 +mac: 0x102458f7f62ddd7d638d746034130968 +original_id: 0x3410 diff --git a/src/lib/dns/tests/testdata/tsig_verify3.wire b/src/lib/dns/tests/testdata/tsig_verify3.wire new file mode 100644 index 0000000..c479ac3 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify3.wire @@ -0,0 +1,25 @@ +### +### This data file was auto-generated from tsig_verify3.spec +### + +# Header Section +# ID=13328 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) AA +3410 8400 +# QDCNT=0, ANCNT=1, NSCNT=0, ARCNT=1 +0000 0001 0000 0001 + +# NS RR (QNAME=example.com. Class=IN(1) TTL=86400, RDLEN=5) +076578616d706c6503636f6d00 0002 0001 00015180 0005 +# NS name=ns.ptr=12 +026e73c00c + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302915409 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8e951 012c +# MAC Size=16 MAC=(see hex) +0010 102458f7f62ddd7d638d746034130968 +# Original-ID=13328 Error=0 +3410 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsig_verify4.spec b/src/lib/dns/tests/testdata/tsig_verify4.spec new file mode 100644 index 0000000..4ffbbcf --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify4.spec @@ -0,0 +1,27 @@ +# +# An example of signed DNS response with bogus MAC +# + +[custom] +sections: header:question:a:tsig +[header] +id: 0x2d65 +aa: 1 +qr: 1 +rd: 1 +ancount: 1 +arcount: 1 +[question] +name: www.example.com +[a] +as_rr: True +rr_name: ptr=12 +[tsig] +as_rr: True +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +# bogus MAC +mac: 0xdeadbeefdeadbeefdeadbeefdeadbeef +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/tsig_verify4.wire b/src/lib/dns/tests/testdata/tsig_verify4.wire new file mode 100644 index 0000000..de5e050 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify4.wire @@ -0,0 +1,29 @@ +### +### This data file was auto-generated from tsig_verify4.spec +### + +# Header Section +# ID=11621 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) AA RD +2d65 8500 +# QDCNT=1, ANCNT=1, NSCNT=0, ARCNT=1 +0001 0001 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# A RR (QNAME=ptr=12 Class=IN(1) TTL=86400, RDLEN=4) +c00c 0001 0001 00015180 0004 +# Address=192.0.2.1 +c0000201 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 deadbeefdeadbeefdeadbeefdeadbeef +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsig_verify5.spec b/src/lib/dns/tests/testdata/tsig_verify5.spec new file mode 100644 index 0000000..a6cc643 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify5.spec @@ -0,0 +1,26 @@ +# +# An example of signed DNS response +# + +[custom] +sections: header:question:a:tsig +[header] +id: 0x2d65 +aa: 1 +qr: 1 +rd: 1 +ancount: 1 +arcount: 1 +[question] +name: www.example.com +[a] +as_rr: True +rr_name: ptr=12 +[tsig] +as_rr: True +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +mac: 0x8fcda66a7cd1a3b9948eb1869d384a9f +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/tsig_verify5.wire b/src/lib/dns/tests/testdata/tsig_verify5.wire new file mode 100644 index 0000000..3cfb89b --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify5.wire @@ -0,0 +1,29 @@ +### +### This data file was auto-generated from tsig_verify5.spec +### + +# Header Section +# ID=11621 QR=Response Opcode=QUERY(0) Rcode=NOERROR(0) AA RD +2d65 8500 +# QDCNT=1, ANCNT=1, NSCNT=0, ARCNT=1 +0001 0001 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# A RR (QNAME=ptr=12 Class=IN(1) TTL=86400, RDLEN=4) +c00c 0001 0001 00015180 0004 +# Address=192.0.2.1 +c0000201 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 8fcda66a7cd1a3b9948eb1869d384a9f +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsig_verify6.spec b/src/lib/dns/tests/testdata/tsig_verify6.spec new file mode 100644 index 0000000..32e0818 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify6.spec @@ -0,0 +1,21 @@ +# +# Forwarded DNS query message with TSIG signed (header ID != orig ID) +# + +[custom] +sections: header:question:tsig +[header] +id: 0x1035 +rd: 1 +arcount: 1 +[question] +name: www.example.com +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +mac: 0x227026ad297beee721ce6c6fff1e9ef3 +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/tsig_verify6.wire b/src/lib/dns/tests/testdata/tsig_verify6.wire new file mode 100644 index 0000000..9e3e5b4 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify6.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from tsig_verify6.spec +### + +# Header Section +# ID=4149 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +1035 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 227026ad297beee721ce6c6fff1e9ef3 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsig_verify7.spec b/src/lib/dns/tests/testdata/tsig_verify7.spec new file mode 100644 index 0000000..377578e --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify7.spec @@ -0,0 +1,21 @@ +# +# DNS query message with TSIG that has empty MAC (invalidly) +# + +[custom] +sections: header:question:tsig +[header] +id: 0x2d65 +rd: 1 +arcount: 1 +[question] +name: www.example.com +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 0 +mac: '' +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/tsig_verify7.wire b/src/lib/dns/tests/testdata/tsig_verify7.wire new file mode 100644 index 0000000..4de7d24 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify7.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from tsig_verify7.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=42) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 002a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=0 MAC=(see hex) +0000 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsig_verify8.spec b/src/lib/dns/tests/testdata/tsig_verify8.spec new file mode 100644 index 0000000..5432d4a --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify8.spec @@ -0,0 +1,23 @@ +# +# DNS query message with TSIG that has empty MAC + BADKEY error +# + +[custom] +sections: header:question:tsig +[header] +id: 0x2d65 +rd: 1 +arcount: 1 +[question] +name: www.example.com +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 0 +mac: '' +# 17: BADKEY +error: 17 +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/tsig_verify8.wire b/src/lib/dns/tests/testdata/tsig_verify8.wire new file mode 100644 index 0000000..50845eb --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify8.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from tsig_verify8.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=42) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 002a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=0 MAC=(see hex) +0000 +# Original-ID=11621 Error=17 +2d65 0011 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsig_verify9.spec b/src/lib/dns/tests/testdata/tsig_verify9.spec new file mode 100644 index 0000000..5888455 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify9.spec @@ -0,0 +1,21 @@ +# +# A simple DNS query message with TSIG signed, but TSIG key and algorithm +# names have upper case characters (unusual) +# + +[custom] +sections: header:question:tsig +[header] +id: 0x2d65 +rd: 1 +arcount: 1 +[question] +name: www.example.com +[tsig] +as_rr: True +rr_name: WWW.EXAMPLE.COM +algorithm: HMAC-MD5.SIG-ALG.REG.INT +time_signed: 0x4da8877a +mac_size: 16 +mac: 0x227026ad297beee721ce6c6fff1e9ef3 +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/tsig_verify9.wire b/src/lib/dns/tests/testdata/tsig_verify9.wire new file mode 100644 index 0000000..163fcee --- /dev/null +++ b/src/lib/dns/tests/testdata/tsig_verify9.wire @@ -0,0 +1,24 @@ +### +### This data file was auto-generated from tsig_verify9.spec +### + +# Header Section +# ID=11621 QR=Query Opcode=QUERY(0) Rcode=NOERROR(0) RD +2d65 0100 +# QDCNT=1, ANCNT=0, NSCNT=0, ARCNT=1 +0001 0000 0000 0001 + +# Question Section +# QNAME=www.example.com QTYPE=A(1) QCLASS=IN(1) +03777777076578616d706c6503636f6d00 0001 0001 + +# TSIG RR (QNAME=WWW.EXAMPLE.COM Class=ANY(255) TTL=0, RDLEN=58) +03575757074558414d504c4503434f4d00 00fa 00ff 00000000 003a +# Algorithm=HMAC-MD5.SIG-ALG.REG.INT Time-Signed=1302890362 Fudge=300 +08484d41432d4d4435075349472d414c470352454703494e5400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 227026ad297beee721ce6c6fff1e9ef3 +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsigrecord_toWire1.spec b/src/lib/dns/tests/testdata/tsigrecord_toWire1.spec new file mode 100644 index 0000000..a25dc46 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsigrecord_toWire1.spec @@ -0,0 +1,16 @@ +# +# A simple TSIG RR (some of the parameters are taken from a live example +# and don't have a specific meaning) +# + +[custom] +sections: tsig +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +mac: 0xdadadadadadadadadadadadadadadada +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/tsigrecord_toWire1.wire b/src/lib/dns/tests/testdata/tsigrecord_toWire1.wire new file mode 100644 index 0000000..a125e3d --- /dev/null +++ b/src/lib/dns/tests/testdata/tsigrecord_toWire1.wire @@ -0,0 +1,14 @@ +### +### This data file was auto-generated from tsigrecord_toWire1.spec +### + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 dadadadadadadadadadadadadadadada +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/testdata/tsigrecord_toWire2.spec b/src/lib/dns/tests/testdata/tsigrecord_toWire2.spec new file mode 100644 index 0000000..f667e4c --- /dev/null +++ b/src/lib/dns/tests/testdata/tsigrecord_toWire2.spec @@ -0,0 +1,19 @@ +# +# TSIG RR after some names that could (unexpectedly) cause name compression +# + +[custom] +sections: name/1:name/2:tsig +[name/1] +name: hmac-md5.sig-alg.reg.int +[name/2] +name: foo.example.com +[tsig] +as_rr: True +# TSIG QNAME won't be compressed +rr_name: www.example.com +algorithm: hmac-md5 +time_signed: 0x4da8877a +mac_size: 16 +mac: 0xdadadadadadadadadadadadadadadada +original_id: 0x2d65 diff --git a/src/lib/dns/tests/testdata/tsigrecord_toWire2.wire b/src/lib/dns/tests/testdata/tsigrecord_toWire2.wire new file mode 100644 index 0000000..980e1f1 --- /dev/null +++ b/src/lib/dns/tests/testdata/tsigrecord_toWire2.wire @@ -0,0 +1,20 @@ +### +### This data file was auto-generated from tsigrecord_toWire2.spec +### + +# DNS Name: hmac-md5.sig-alg.reg.int +08686d61632d6d6435077369672d616c670372656703696e7400 + +# DNS Name: foo.example.com +03666f6f076578616d706c6503636f6d00 + +# TSIG RR (QNAME=www.example.com Class=ANY(255) TTL=0, RDLEN=58) +03777777076578616d706c6503636f6d00 00fa 00ff 00000000 003a +# Algorithm=hmac-md5 Time-Signed=1302890362 Fudge=300 +08686d61632d6d6435077369672d616c670372656703696e7400 00004da8877a 012c +# MAC Size=16 MAC=(see hex) +0010 dadadadadadadadadadadadadadadada +# Original-ID=11621 Error=0 +2d65 0000 +# Other-Len=0 Other-Data=(see hex) +0000 diff --git a/src/lib/dns/tests/tsig_unittest.cc b/src/lib/dns/tests/tsig_unittest.cc new file mode 100644 index 0000000..fde67bc --- /dev/null +++ b/src/lib/dns/tests/tsig_unittest.cc @@ -0,0 +1,1185 @@ +// Copyright (C) 2011-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <time.h> +#include <string> +#include <stdexcept> +#include <vector> + +#include <boost/scoped_ptr.hpp> + +#include <gtest/gtest.h> + +#include <exceptions/exceptions.h> + +#include <util/buffer.h> +#include <util/encode/base64.h> +#include <util/unittests/newhook.h> +#include <util/time_utilities.h> + +#include <dns/message.h> +#include <dns/messagerenderer.h> +#include <dns/question.h> +#include <dns/opcode.h> +#include <dns/rcode.h> +#include <dns/rrclass.h> +#include <dns/rrtype.h> +#include <dns/tsig.h> +#include <dns/tsigkey.h> +#include <dns/tsigrecord.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::util::encode; +using namespace isc::dns::rdata; +using namespace isc::dns::rdata::any; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +// @note: blocks and SCOPED_TRACE can make buggy cppchecks raise +// a spurious syntax error... + +// See dnssectime.cc +namespace isc { +namespace util { +namespace detail { +extern int64_t (*gettimeFunction)(); +} +} +} + +namespace { +// See dnssectime_unittest.cc +template <int64_t NOW> +int64_t +testGetTime() { + return (NOW); +} + +// Thin wrapper around TSIGContext to allow access to the +// update method. +class TestTSIGContext : public TSIGContext { +public: + TestTSIGContext(const TSIGKey& key) : + TSIGContext(key) + {} + TestTSIGContext(const Name& key_name, const Name& algorithm_name, + const TSIGKeyRing& keyring) : + TSIGContext(key_name, algorithm_name, keyring) + {} + void update(const void* const data, size_t len) { + TSIGContext::update(data, len); + } +}; + +class TSIGTest : public ::testing::Test { +protected: + TSIGTest() : + tsig_ctx(NULL), qid(0x2d65), test_name("www.example.com"), + badkey_name("badkey.example.com"), test_class(RRClass::IN()), + test_ttl(86400), message(Message::RENDER), + dummy_data(1024, 0xdd), // should be sufficiently large for all tests + dummy_record(badkey_name, TSIG(TSIGKey::HMACMD5_NAME(), 0x4da8877a, + TSIGContext::DEFAULT_FUDGE, 0, NULL, qid, 0, 0, NULL)) + { + // Make sure we use the system time by default so that we won't be + // confused due to other tests that tweak the time. + isc::util::detail::gettimeFunction = NULL; + + decodeBase64("SFuWd/q99SzF8Yzd1QbB9g==", secret); + tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name, + TSIGKey::HMACMD5_NAME(), + &secret[0], + secret.size()))); + tsig_verify_ctx.reset(new TSIGContext(TSIGKey(test_name, + TSIGKey::HMACMD5_NAME(), + &secret[0], + secret.size()))); + } + ~TSIGTest() { + isc::util::detail::gettimeFunction = NULL; + } + + // Many of the tests below create some DNS message and sign it under + // some specific TSIG context. This helper method unifies the common + // logic with slightly different parameters. + ConstTSIGRecordPtr createMessageAndSign(uint16_t qid, const Name& qname, + TSIGContext* ctx, + unsigned int message_flags = + RD_FLAG, + RRType qtype = RRType::A(), + const char* answer_data = NULL, + const RRType* answer_type = NULL, + bool add_question = true, + Rcode rcode = Rcode::NOERROR()); + + void createMessageFromFile(const char* datafile); + + // bit-wise constant flags to configure DNS header flags for test + // messages. + static const unsigned int QR_FLAG = 0x1; + static const unsigned int AA_FLAG = 0x2; + static const unsigned int RD_FLAG = 0x4; + + boost::scoped_ptr<TestTSIGContext> tsig_ctx; + boost::scoped_ptr<TSIGContext> tsig_verify_ctx; + TSIGKeyRing keyring; + const uint16_t qid; + const Name test_name; + const Name badkey_name; + const RRClass test_class; + const RRTTL test_ttl; + Message message; + MessageRenderer renderer; + vector<uint8_t> secret; + vector<uint8_t> dummy_data; + const TSIGRecord dummy_record; + vector<uint8_t> received_data; +}; + +ConstTSIGRecordPtr +TSIGTest::createMessageAndSign(uint16_t id, const Name& qname, + TSIGContext* ctx, unsigned int message_flags, + RRType qtype, const char* answer_data, + const RRType* answer_type, bool add_question, + Rcode rcode) +{ + message.clear(Message::RENDER); + message.setQid(id); + message.setOpcode(Opcode::QUERY()); + message.setRcode(rcode); + if ((message_flags & QR_FLAG) != 0) { + message.setHeaderFlag(Message::HEADERFLAG_QR); + } + if ((message_flags & AA_FLAG) != 0) { + message.setHeaderFlag(Message::HEADERFLAG_AA); + } + if ((message_flags & RD_FLAG) != 0) { + message.setHeaderFlag(Message::HEADERFLAG_RD); + } + if (add_question) { + message.addQuestion(Question(qname, test_class, qtype)); + } + if (answer_data != NULL) { + if (answer_type == NULL) { + answer_type = &qtype; + } + RRsetPtr answer_rrset(new RRset(qname, test_class, *answer_type, + test_ttl)); + answer_rrset->addRdata(createRdata(*answer_type, test_class, + answer_data)); + message.addRRset(Message::SECTION_ANSWER, answer_rrset); + } + renderer.clear(); + + TSIGContext::State expected_new_state = + (ctx->getState() == TSIGContext::INIT) ? + TSIGContext::SENT_REQUEST : TSIGContext::SENT_RESPONSE; + + message.toWire(renderer, ctx); + + message.clear(Message::PARSE); + InputBuffer buffer(renderer.getData(), renderer.getLength()); + message.fromWire(buffer); + + EXPECT_EQ(expected_new_state, ctx->getState()); + + return (ConstTSIGRecordPtr(new TSIGRecord(*message.getTSIGRecord()))); +} + +void +TSIGTest::createMessageFromFile(const char* datafile) { + message.clear(Message::PARSE); + received_data.clear(); + UnitTestUtil::readWireData(datafile, received_data); + InputBuffer buffer(&received_data[0], received_data.size()); + message.fromWire(buffer); +} + +void +commonSignChecks(ConstTSIGRecordPtr tsig, uint16_t expected_qid, + uint64_t expected_timesigned, + const uint8_t* expected_mac, size_t expected_maclen, + uint16_t expected_error = 0, + uint16_t expected_otherlen = 0, + const uint8_t* expected_otherdata = NULL, + const Name& expected_algorithm = TSIGKey::HMACMD5_NAME()) +{ + ASSERT_TRUE(tsig != NULL); + const TSIG& tsig_rdata = tsig->getRdata(); + + EXPECT_EQ(expected_algorithm, tsig_rdata.getAlgorithm()); + EXPECT_EQ(expected_timesigned, tsig_rdata.getTimeSigned()); + EXPECT_EQ(300, tsig_rdata.getFudge()); + EXPECT_EQ(expected_maclen, tsig_rdata.getMACSize()); + matchWireData(expected_mac, expected_maclen, + tsig_rdata.getMAC(), tsig_rdata.getMACSize()); + + EXPECT_EQ(expected_qid, tsig_rdata.getOriginalID()); + EXPECT_EQ(expected_error, tsig_rdata.getError()); + EXPECT_EQ(expected_otherlen, tsig_rdata.getOtherLen()); + matchWireData(expected_otherdata, expected_otherlen, + tsig_rdata.getOtherData(), tsig_rdata.getOtherLen()); +} + +void +commonVerifyChecks(TSIGContext& ctx, const TSIGRecord* record, + const void* data, size_t data_len, TSIGError expected_error, + TSIGContext::State expected_new_state = + TSIGContext::VERIFIED_RESPONSE, + bool last_should_throw = false) +{ + EXPECT_EQ(expected_error, ctx.verify(record, data, data_len)); + EXPECT_EQ(expected_error, ctx.getError()); + EXPECT_EQ(expected_new_state, ctx.getState()); + if (last_should_throw) { + EXPECT_THROW(ctx.lastHadSignature(), TSIGContextError); + } else { + EXPECT_EQ(record != NULL, ctx.lastHadSignature()); + } +} + +TEST_F(TSIGTest, initialState) { + // Until signing or verifying, the state should be INIT + EXPECT_EQ(TSIGContext::INIT, tsig_ctx->getState()); + + // And there should be no error code. + EXPECT_EQ(TSIGError(Rcode::NOERROR()), tsig_ctx->getError()); + + // Nothing verified yet + EXPECT_THROW(tsig_ctx->lastHadSignature(), TSIGContextError); +} + +TEST_F(TSIGTest, constructFromKeyRing) { + // Construct a TSIG context with an empty key ring. Key shouldn't be + // found, and the BAD_KEY error should be recorded. + TSIGContext ctx1(test_name, TSIGKey::HMACMD5_NAME(), keyring); + EXPECT_EQ(TSIGContext::INIT, ctx1.getState()); + EXPECT_EQ(TSIGError::BAD_KEY(), ctx1.getError()); + + // Add a matching key (we don't use the secret so leave it empty), and + // construct it again. This time it should be constructed with a valid + // key. + keyring.add(TSIGKey(test_name, TSIGKey::HMACMD5_NAME(), NULL, 0)); + TSIGContext ctx2(test_name, TSIGKey::HMACMD5_NAME(), keyring); + EXPECT_EQ(TSIGContext::INIT, ctx2.getState()); + EXPECT_EQ(TSIGError::NOERROR(), ctx2.getError()); + + // Similar to the first case except that the key ring isn't empty but + // it doesn't contain a matching key. + TSIGContext ctx3(test_name, TSIGKey::HMACSHA1_NAME(), keyring); + EXPECT_EQ(TSIGContext::INIT, ctx3.getState()); + EXPECT_EQ(TSIGError::BAD_KEY(), ctx3.getError()); + + TSIGContext ctx4(Name("different-key.example"), TSIGKey::HMACMD5_NAME(), + keyring); + EXPECT_EQ(TSIGContext::INIT, ctx4.getState()); + EXPECT_EQ(TSIGError::BAD_KEY(), ctx4.getError()); + + // "Unknown" algorithm name will result in BADKEY, too. + TSIGContext ctx5(test_name, Name("unknown.algorithm"), keyring); + EXPECT_EQ(TSIGContext::INIT, ctx5.getState()); + EXPECT_EQ(TSIGError::BAD_KEY(), ctx5.getError()); +} + +// Example output generated by +// "dig -y www.example.com:SFuWd/q99SzF8Yzd1QbB9g== www.example.com +// QID: 0x2d65 +// Time Signed: 0x00004da8877a +// MAC: 227026ad297beee721ce6c6fff1e9ef3 +const uint8_t common_expected_mac[] = { + 0x22, 0x70, 0x26, 0xad, 0x29, 0x7b, 0xee, 0xe7, + 0x21, 0xce, 0x6c, 0x6f, 0xff, 0x1e, 0x9e, 0xf3 +}; +TEST_F(TSIGTest, sign) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + { + SCOPED_TRACE("Sign test for query"); + commonSignChecks(createMessageAndSign(qid, test_name, tsig_ctx.get()), + qid, 0x4da8877a, common_expected_mac, + sizeof(common_expected_mac)); + } +} + +// Same test as sign, but specifying the key name with upper-case (i.e. +// non canonical) characters. The digest must be the same. It should actually +// be ensured at the level of TSIGKey, but we confirm that at this level, too. +TEST_F(TSIGTest, signUsingUpperCasedKeyName) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + TSIGContext cap_ctx(TSIGKey(Name("WWW.EXAMPLE.COM"), + TSIGKey::HMACMD5_NAME(), + &secret[0], secret.size())); + + { + SCOPED_TRACE("Sign test for query using non canonical key name"); + commonSignChecks(createMessageAndSign(qid, test_name, &cap_ctx), qid, + 0x4da8877a, common_expected_mac, + sizeof(common_expected_mac)); + } +} + +// Same as the previous test, but for the algorithm name. +TEST_F(TSIGTest, signUsingUpperCasedAlgorithmName) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + TSIGContext cap_ctx(TSIGKey(test_name, + Name("HMAC-md5.SIG-alg.REG.int"), + &secret[0], secret.size())); + + { + SCOPED_TRACE("Sign test for query using non canonical algorithm name"); + commonSignChecks(createMessageAndSign(qid, test_name, &cap_ctx), qid, + 0x4da8877a, common_expected_mac, + sizeof(common_expected_mac)); + } +} + +TEST_F(TSIGTest, signAtActualTime) { + // Sign the message using the actual time, and check the accuracy of it. + // We cannot reasonably predict the expected MAC, so don't bother to + // check it. + const uint64_t now = static_cast<uint64_t>(time(NULL)); + + { + SCOPED_TRACE("Sign test for query at actual time"); + ConstTSIGRecordPtr tsig = createMessageAndSign(qid, test_name, + tsig_ctx.get()); + const TSIG& tsig_rdata = tsig->getRdata(); + + // Check the resulted time signed is in the range of [now, now + 5] + // (5 is an arbitrary choice). Note that due to the order of the call + // to time() and sign(), time signed must not be smaller than the + // current time. + EXPECT_LE(now, tsig_rdata.getTimeSigned()); + EXPECT_GE(now + 5, tsig_rdata.getTimeSigned()); + } +} + +TEST_F(TSIGTest, signBadData) { + // some specific bad data should be rejected proactively. + const unsigned char dummy_data = 0; + EXPECT_THROW(tsig_ctx->sign(0, NULL, 10), InvalidParameter); + EXPECT_THROW(tsig_ctx->sign(0, &dummy_data, 0), InvalidParameter); +} + +TEST_F(TSIGTest, verifyBadData) { + // the data must at least hold the DNS message header and the specified + // TSIG. + EXPECT_THROW(tsig_ctx->verify(&dummy_record, &dummy_data[0], + 12 + dummy_record.getLength() - 1), + InvalidParameter); + + // Still nothing verified + EXPECT_THROW(tsig_ctx->lastHadSignature(), TSIGContextError); + + // And the data must not be NULL. + EXPECT_THROW(tsig_ctx->verify(&dummy_record, NULL, + 12 + dummy_record.getLength()), + InvalidParameter); + + // Still nothing verified + EXPECT_THROW(tsig_ctx->lastHadSignature(), TSIGContextError); + +} + +#ifdef ENABLE_CUSTOM_OPERATOR_NEW +// We enable this test only when we enable custom new/delete at build time +// We could enable/disable the test runtime using the gtest filter, but +// we'd basically like to minimize the number of disabled tests (they +// should generally be considered tests that temporarily fail and should +// be fixed). +TEST_F(TSIGTest, signExceptionSafety) { + // Check sign() provides the strong exception guarantee for the simpler + // case (with a key error and empty MAC). The general case is more + // complicated and involves more memory allocation, so the test result + // won't be reliable. + + commonVerifyChecks(*tsig_verify_ctx, &dummy_record, &dummy_data[0], + dummy_data.size(), TSIGError::BAD_KEY(), + TSIGContext::RECEIVED_REQUEST); + + try { + int dummydata; + isc::util::unittests::force_throw_on_new = true; + isc::util::unittests::throw_size_on_new = sizeof(TSIGRecord); + tsig_verify_ctx->sign(0, &dummydata, sizeof(dummydata)); + isc::util::unittests::force_throw_on_new = false; + ASSERT_FALSE(true) << "Expected throw on new, but it didn't happen"; + } catch (const std::bad_alloc&) { + isc::util::unittests::force_throw_on_new = false; + + // sign() threw, so the state should still be RECEIVED_REQUEST + EXPECT_EQ(TSIGContext::RECEIVED_REQUEST, tsig_verify_ctx->getState()); + } + isc::util::unittests::force_throw_on_new = false; +} +#endif // ENABLE_CUSTOM_OPERATOR_NEW + +// Same test as "sign" but use a different algorithm just to confirm we don't +// naively hardcode constants specific to a particular algorithm. +// Test data generated by +// "dig -y hmac-sha1:www.example.com:MA+QDhXbyqUak+qnMFyTyEirzng= www.example.com" +// QID: 0x0967, RDflag +// Current Time: 00004da8be86 +// Time Signed: 00004dae7d5f +// HMAC Size: 20 +// HMAC: 415340c7daf824ed684ee586f7b5a67a2febc0d3 +TEST_F(TSIGTest, signUsingHMACSHA1) { + isc::util::detail::gettimeFunction = testGetTime<0x4dae7d5f>; + + secret.clear(); + decodeBase64("MA+QDhXbyqUak+qnMFyTyEirzng=", secret); + TSIGContext sha1_ctx(TSIGKey(test_name, TSIGKey::HMACSHA1_NAME(), + &secret[0], secret.size())); + + const uint16_t sha1_qid = 0x0967; + const uint8_t expected_mac[] = { + 0x41, 0x53, 0x40, 0xc7, 0xda, 0xf8, 0x24, 0xed, 0x68, 0x4e, + 0xe5, 0x86, 0xf7, 0xb5, 0xa6, 0x7a, 0x2f, 0xeb, 0xc0, 0xd3 + }; + { + SCOPED_TRACE("Sign test using HMAC-SHA1"); + commonSignChecks(createMessageAndSign(sha1_qid, test_name, &sha1_ctx), + sha1_qid, 0x4dae7d5f, expected_mac, + sizeof(expected_mac), 0, 0, NULL, + TSIGKey::HMACSHA1_NAME()); + } +} + +TEST_F(TSIGTest, signUsingHMACSHA224) { + isc::util::detail::gettimeFunction = testGetTime<0x4dae7d5f>; + + secret.clear(); + decodeBase64("MA+QDhXbyqUak+qnMFyTyEirzng=", secret); + TSIGContext sha1_ctx(TSIGKey(test_name, TSIGKey::HMACSHA224_NAME(), + &secret[0], secret.size())); + + const uint16_t sha1_qid = 0x0967; + const uint8_t expected_mac[] = { + 0x3b, 0x93, 0xd3, 0xc5, 0xf9, 0x64, 0xb9, 0xc5, 0x00, 0x35, + 0x02, 0x69, 0x9f, 0xfc, 0x44, 0xd6, 0xe2, 0x66, 0xf4, 0x08, + 0xef, 0x33, 0xa2, 0xda, 0xa1, 0x48, 0x71, 0xd3 + }; + { + SCOPED_TRACE("Sign test using HMAC-SHA224"); + commonSignChecks(createMessageAndSign(sha1_qid, test_name, &sha1_ctx), + sha1_qid, 0x4dae7d5f, expected_mac, + sizeof(expected_mac), 0, 0, NULL, + TSIGKey::HMACSHA224_NAME()); + } +} + +// The first part of this test checks verifying the signed query used for +// the "sign" test. +// The second part of this test generates a signed response to the signed +// query as follows: +// Answer: www.example.com. 86400 IN A 192.0.2.1 +// MAC: 8fcda66a7cd1a3b9948eb1869d384a9f +TEST_F(TSIGTest, verifyThenSignResponse) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + // This test data for the message test has the same wire format data + // as the message used in the "sign" test. + createMessageFromFile("message_toWire2.wire"); + { + SCOPED_TRACE("Verify test for request"); + commonVerifyChecks(*tsig_verify_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::NOERROR(), TSIGContext::RECEIVED_REQUEST); + } + + // Transform the original message to a response, then sign the response + // with the context of "verified state". + ConstTSIGRecordPtr tsig = createMessageAndSign(qid, test_name, + tsig_verify_ctx.get(), + QR_FLAG|AA_FLAG|RD_FLAG, + RRType::A(), "192.0.2.1"); + const uint8_t expected_mac[] = { + 0x8f, 0xcd, 0xa6, 0x6a, 0x7c, 0xd1, 0xa3, 0xb9, + 0x94, 0x8e, 0xb1, 0x86, 0x9d, 0x38, 0x4a, 0x9f + }; + { + SCOPED_TRACE("Sign test for response"); + commonSignChecks(tsig, qid, 0x4da8877a, expected_mac, + sizeof(expected_mac)); + } +} + +TEST_F(TSIGTest, verifyUpperCaseNames) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + // This test data for the message test has the same wire format data + // as the message used in the "sign" test. + createMessageFromFile("tsig_verify9.wire"); + { + SCOPED_TRACE("Verify test for request"); + commonVerifyChecks(*tsig_verify_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::NOERROR(), TSIGContext::RECEIVED_REQUEST); + } +} + +TEST_F(TSIGTest, verifyForwardedMessage) { + // Similar to the first part of the previous test, but this test emulates + // the "forward" case, where the ID of the Header and the original ID in + // TSIG is different. + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + createMessageFromFile("tsig_verify6.wire"); + { + SCOPED_TRACE("Verify test for forwarded request"); + commonVerifyChecks(*tsig_verify_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::NOERROR(), TSIGContext::RECEIVED_REQUEST); + } +} + +// Example of signing multiple messages in a single TCP stream, +// taken from data using BIND 9's "one-answer" transfer-format. +// Request: +// QID: 0x3410, flags (none) +// Question: example.com/IN/AXFR +// Time Signed: 0x4da8e951 +// MAC: 35b2fd08268781634400c7c8a5533b13 +// First message: +// QID: 0x3410, flags QR, AA +// Question: example.com/IN/AXFR +// Answer: example.com. 86400 IN SOA ns.example.com. root.example.com. ( +// 2011041503 7200 3600 2592000 1200) +// MAC: bdd612cd2c7f9e0648bd6dc23713e83c +// Second message: +// Answer: example.com. 86400 IN NS ns.example.com. +// MAC: 102458f7f62ddd7d638d746034130968 +TEST_F(TSIGTest, signContinuation) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8e951>; + + const uint16_t axfr_qid = 0x3410; + const Name zone_name("example.com"); + + // Create and sign the AXFR request + ConstTSIGRecordPtr tsig = createMessageAndSign(axfr_qid, zone_name, + tsig_ctx.get(), 0, + RRType::AXFR()); + // Then verify it (the wire format test data should contain the same + // message data, and verification should succeed). + received_data.clear(); + UnitTestUtil::readWireData("tsig_verify1.wire", received_data); + { + SCOPED_TRACE("Verify AXFR query"); + commonVerifyChecks(*tsig_verify_ctx, tsig.get(), &received_data[0], + received_data.size(), TSIGError::NOERROR(), + TSIGContext::RECEIVED_REQUEST); + } + + // Create and sign the first response message + tsig = createMessageAndSign(axfr_qid, zone_name, tsig_verify_ctx.get(), + AA_FLAG|QR_FLAG, RRType::AXFR(), + "ns.example.com. root.example.com. " + "2011041503 7200 3600 2592000 1200", + &RRType::SOA()); + + // Then verify it at the requester side. + received_data.clear(); + UnitTestUtil::readWireData("tsig_verify2.wire", received_data); + { + SCOPED_TRACE("Verify first AXFR response"); + commonVerifyChecks(*tsig_ctx, tsig.get(), &received_data[0], + received_data.size(), TSIGError::NOERROR()); + } + + // Create and sign the second response message + const uint8_t expected_mac[] = { + 0x10, 0x24, 0x58, 0xf7, 0xf6, 0x2d, 0xdd, 0x7d, + 0x63, 0x8d, 0x74, 0x60, 0x34, 0x13, 0x09, 0x68 + }; + { + SCOPED_TRACE("Sign test for continued response in TCP stream"); + tsig = createMessageAndSign(axfr_qid, zone_name, tsig_verify_ctx.get(), + AA_FLAG|QR_FLAG, RRType::AXFR(), + "ns.example.com.", &RRType::NS(), false); + commonSignChecks(tsig, axfr_qid, 0x4da8e951, expected_mac, + sizeof(expected_mac)); + } + + // Then verify it at the requester side. + received_data.clear(); + UnitTestUtil::readWireData("tsig_verify3.wire", received_data); + { + SCOPED_TRACE("Verify second AXFR response"); + commonVerifyChecks(*tsig_ctx, tsig.get(), &received_data[0], + received_data.size(), TSIGError::NOERROR()); + } +} + +// BADTIME example, taken from data using specially hacked BIND 9's nsupdate +// Query: +// QID: 0x1830, RD flag +// Current Time: 00004da8be86 +// Time Signed: 00004da8b9d6 +// Question: www.example.com/IN/SOA +//(mac) 8406 7d50 b8e7 d054 3d50 5bd9 de2a bb68 +// Response: +// QRbit, RCODE=9(NOTAUTH) +// Time Signed: 00004da8b9d6 (the one in the query) +// MAC: d4b043f6f44495ec8a01260e39159d76 +// Error: 0x12 (BADTIME), Other Len: 6 +// Other data: 00004da8be86 +TEST_F(TSIGTest, badtimeResponse) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8b9d6>; + + const uint16_t test_qid = 0x7fc4; + ConstTSIGRecordPtr tsig = createMessageAndSign(test_qid, test_name, + tsig_ctx.get(), 0, + RRType::SOA()); + + // "advance the clock" and try validating, which should fail due to BADTIME + isc::util::detail::gettimeFunction = testGetTime<0x4da8be86>; + { + SCOPED_TRACE("Verify resulting in BADTIME due to expired SIG"); + commonVerifyChecks(*tsig_verify_ctx, tsig.get(), &dummy_data[0], + dummy_data.size(), TSIGError::BAD_TIME(), + TSIGContext::RECEIVED_REQUEST); + } + + // make and sign a response in the context of TSIG error. + tsig = createMessageAndSign(test_qid, test_name, tsig_verify_ctx.get(), + QR_FLAG, RRType::SOA(), NULL, NULL, + true, Rcode::NOTAUTH()); + const uint8_t expected_otherdata[] = { 0, 0, 0x4d, 0xa8, 0xbe, 0x86 }; + const uint8_t expected_mac[] = { + 0xd4, 0xb0, 0x43, 0xf6, 0xf4, 0x44, 0x95, 0xec, + 0x8a, 0x01, 0x26, 0x0e, 0x39, 0x15, 0x9d, 0x76 + }; + { + SCOPED_TRACE("Sign test for response with BADTIME"); + commonSignChecks(tsig, message.getQid(), 0x4da8b9d6, + expected_mac, sizeof(expected_mac), + 18, // error: BADTIME + sizeof(expected_otherdata), + expected_otherdata); + } +} + +TEST_F(TSIGTest, badtimeResponse2) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8b9d6>; + + ConstTSIGRecordPtr tsig = createMessageAndSign(qid, test_name, + tsig_ctx.get(), 0, + RRType::SOA()); + + // "rewind the clock" and try validating, which should fail due to BADTIME + isc::util::detail::gettimeFunction = testGetTime<0x4da8b9d6 - 600>; + { + SCOPED_TRACE("Verify resulting in BADTIME due to too future SIG"); + commonVerifyChecks(*tsig_verify_ctx, tsig.get(), &dummy_data[0], + dummy_data.size(), TSIGError::BAD_TIME(), + TSIGContext::RECEIVED_REQUEST); + } +} + +TEST_F(TSIGTest, badtimeBoundaries) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8b9d6>; + + // Test various boundary conditions. We intentionally use the magic + // number of 300 instead of the constant variable for testing. + // In the okay cases, signature is not correct, but it's sufficient to + // check the error code isn't BADTIME for the purpose of this test. + ConstTSIGRecordPtr tsig = createMessageAndSign(qid, test_name, + tsig_ctx.get(), 0, + RRType::SOA()); + isc::util::detail::gettimeFunction = testGetTime<0x4da8b9d6 + 301>; + EXPECT_EQ(TSIGError::BAD_TIME(), + tsig_verify_ctx->verify(tsig.get(), &dummy_data[0], + dummy_data.size())); + isc::util::detail::gettimeFunction = testGetTime<0x4da8b9d6 + 300>; + EXPECT_NE(TSIGError::BAD_TIME(), + tsig_verify_ctx->verify(tsig.get(), &dummy_data[0], + dummy_data.size())); + isc::util::detail::gettimeFunction = testGetTime<0x4da8b9d6 - 301>; + EXPECT_EQ(TSIGError::BAD_TIME(), + tsig_verify_ctx->verify(tsig.get(), &dummy_data[0], + dummy_data.size())); + isc::util::detail::gettimeFunction = testGetTime<0x4da8b9d6 - 300>; + EXPECT_NE(TSIGError::BAD_TIME(), + tsig_verify_ctx->verify(tsig.get(), &dummy_data[0], + dummy_data.size())); +} + +TEST_F(TSIGTest, badtimeOverflow) { + isc::util::detail::gettimeFunction = testGetTime<200>; + ConstTSIGRecordPtr tsig = createMessageAndSign(qid, test_name, + tsig_ctx.get(), 0, + RRType::SOA()); + + // This should be in the okay range, but since "200 - fudge" overflows + // and we compare them as 64-bit unsigned integers, it results in a false + // positive (we intentionally accept that). + isc::util::detail::gettimeFunction = testGetTime<100>; + EXPECT_EQ(TSIGError::BAD_TIME(), + tsig_verify_ctx->verify(tsig.get(), &dummy_data[0], + dummy_data.size())); +} + +TEST_F(TSIGTest, badsigResponse) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + // Try to sign a simple message with bogus secret. It should fail + // with BADSIG. + createMessageFromFile("message_toWire2.wire"); + TSIGContext bad_ctx(TSIGKey(test_name, TSIGKey::HMACMD5_NAME(), + &dummy_data[0], dummy_data.size())); + { + SCOPED_TRACE("Verify resulting in BADSIG"); + commonVerifyChecks(bad_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::BAD_SIG(), TSIGContext::RECEIVED_REQUEST); + } + + // Sign the same message (which doesn't matter for this test) with the + // context of "checked state". + { + SCOPED_TRACE("Sign test for response with BADSIG error"); + commonSignChecks(createMessageAndSign(qid, test_name, &bad_ctx), + message.getQid(), 0x4da8877a, NULL, 0, + 16); // 16: BADSIG + } +} + +TEST_F(TSIGTest, badkeyResponse) { + // A similar test as badsigResponse but for BADKEY + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + tsig_ctx.reset(new TestTSIGContext(badkey_name, TSIGKey::HMACMD5_NAME(), + keyring)); + { + SCOPED_TRACE("Verify resulting in BADKEY"); + commonVerifyChecks(*tsig_ctx, &dummy_record, &dummy_data[0], + dummy_data.size(), TSIGError::BAD_KEY(), + TSIGContext::RECEIVED_REQUEST); + } + + { + SCOPED_TRACE("Sign test for response with BADKEY error"); + ConstTSIGRecordPtr sig = createMessageAndSign(qid, test_name, + tsig_ctx.get()); + EXPECT_EQ(badkey_name, sig->getName()); + commonSignChecks(sig, qid, 0x4da8877a, NULL, 0, 17); // 17: BADKEY + } +} + +TEST_F(TSIGTest, badkeyForResponse) { + // "BADKEY" case for a response to a signed message + createMessageAndSign(qid, test_name, tsig_ctx.get()); + { + SCOPED_TRACE("Verify a response resulting in BADKEY"); + commonVerifyChecks(*tsig_ctx, &dummy_record, &dummy_data[0], + dummy_data.size(), TSIGError::BAD_KEY(), + TSIGContext::SENT_REQUEST); + } + + // A similar case with a different algorithm + const TSIGRecord dummy_record2(test_name, TSIG(TSIGKey::HMACSHA1_NAME(), + 0x4da8877a, + TSIGContext::DEFAULT_FUDGE, + 0, NULL, qid, 0, 0, NULL)); + { + SCOPED_TRACE("Verify a response resulting in BADKEY due to bad alg"); + commonVerifyChecks(*tsig_ctx, &dummy_record2, &dummy_data[0], + dummy_data.size(), TSIGError::BAD_KEY(), + TSIGContext::SENT_REQUEST); + } +} + +TEST_F(TSIGTest, badsigThenValidate) { + // According to RFC2845 4.6, if TSIG verification fails the client + // should discard that message and wait for another signed response. + // This test emulates that situation. + + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + createMessageAndSign(qid, test_name, tsig_ctx.get()); + + createMessageFromFile("tsig_verify4.wire"); + { + SCOPED_TRACE("Verify a response that should fail due to BADSIG"); + commonVerifyChecks(*tsig_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::BAD_SIG(), TSIGContext::SENT_REQUEST); + } + + createMessageFromFile("tsig_verify5.wire"); + { + SCOPED_TRACE("Verify a response after a BADSIG failure"); + commonVerifyChecks(*tsig_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::NOERROR(), + TSIGContext::VERIFIED_RESPONSE); + } +} + +TEST_F(TSIGTest, nosigThenValidate) { + // Similar to the previous test, but the first response doesn't contain + // TSIG. + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + createMessageAndSign(qid, test_name, tsig_ctx.get()); + + { + SCOPED_TRACE("Verify a response without TSIG that should exist"); + commonVerifyChecks(*tsig_ctx, NULL, &dummy_data[0], + dummy_data.size(), TSIGError::FORMERR(), + TSIGContext::SENT_REQUEST, true); + } + + createMessageFromFile("tsig_verify5.wire"); + { + SCOPED_TRACE("Verify a response after a FORMERR failure"); + commonVerifyChecks(*tsig_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::NOERROR(), + TSIGContext::VERIFIED_RESPONSE); + } +} + +TEST_F(TSIGTest, badtimeThenValidate) { + // Similar to the previous test, but the first response results in BADTIME. + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + ConstTSIGRecordPtr tsig = createMessageAndSign(qid, test_name, + tsig_ctx.get()); + + // "advance the clock" and try validating, which should fail due to BADTIME + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a + 600>; + { + SCOPED_TRACE("Verify resulting in BADTIME due to expired SIG"); + commonVerifyChecks(*tsig_ctx, tsig.get(), &dummy_data[0], + dummy_data.size(), TSIGError::BAD_TIME(), + TSIGContext::SENT_REQUEST); + } + + // revert the clock again. + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + createMessageFromFile("tsig_verify5.wire"); + { + SCOPED_TRACE("Verify a response after a BADTIME failure"); + commonVerifyChecks(*tsig_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::NOERROR(), + TSIGContext::VERIFIED_RESPONSE); + } +} + +TEST_F(TSIGTest, emptyMAC) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + // We don't allow empty MAC unless the TSIG error is BADSIG or BADKEY. + createMessageFromFile("tsig_verify7.wire"); + { + SCOPED_TRACE("Verify test for request"); + commonVerifyChecks(*tsig_verify_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::BAD_SIG(), TSIGContext::RECEIVED_REQUEST); + } + + // If the empty MAC comes with a BADKEY error, the error is passed + // transparently. + createMessageFromFile("tsig_verify8.wire"); + { + SCOPED_TRACE("Verify test for request"); + commonVerifyChecks(*tsig_verify_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::BAD_KEY(), TSIGContext::RECEIVED_REQUEST); + } +} + +TEST_F(TSIGTest, verifyAfterSendResponse) { + // Once the context is used for sending a signed response, it shouldn't + // be used for further verification. + + // The following are essentially the same as what verifyThenSignResponse + // does with simplification. + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + createMessageFromFile("message_toWire2.wire"); + tsig_verify_ctx->verify(message.getTSIGRecord(), &received_data[0], + received_data.size()); + EXPECT_EQ(TSIGContext::RECEIVED_REQUEST, tsig_verify_ctx->getState()); + createMessageAndSign(qid, test_name, tsig_verify_ctx.get(), + QR_FLAG|AA_FLAG|RD_FLAG, RRType::A(), "192.0.2.1"); + EXPECT_EQ(TSIGContext::SENT_RESPONSE, tsig_verify_ctx->getState()); + + // Now trying further verification. + createMessageFromFile("message_toWire2.wire"); + EXPECT_THROW(tsig_verify_ctx->verify(message.getTSIGRecord(), + &received_data[0], + received_data.size()), + TSIGContextError); +} + +TEST_F(TSIGTest, signAfterVerified) { + // Likewise, once the context verifies a response, it shouldn't for + // signing any more. + + // The following are borrowed from badsigThenValidate (without the + // intermediate failure) + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + createMessageAndSign(qid, test_name, tsig_ctx.get()); + createMessageFromFile("tsig_verify5.wire"); + tsig_ctx->verify(message.getTSIGRecord(), &received_data[0], + received_data.size()); + EXPECT_EQ(TSIGContext::VERIFIED_RESPONSE, tsig_ctx->getState()); + + // Now trying further signing. + EXPECT_THROW(createMessageAndSign(qid, test_name, tsig_ctx.get()), + TSIGContextError); +} + +TEST_F(TSIGTest, tooShortMAC) { + // Too short MAC should be rejected. + + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + createMessageFromFile("tsig_verify10.wire"); + { + SCOPED_TRACE("Verify test for request"); + commonVerifyChecks(*tsig_verify_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::FORMERR(), TSIGContext::RECEIVED_REQUEST); + } +} + +TEST_F(TSIGTest, truncatedMAC) { + // Check truncated MAC support with HMAC-SHA512-256 + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + secret.clear(); + decodeBase64("jI/Pa4qRu96t76Pns5Z/Ndxbn3QCkwcxLOgt9vgvnJw5wqTRvNyk3FtD6yIMd1dWVlqZ+Y4fe6Uasc0ckctEmg==", secret); + TSIGContext sha_ctx(TSIGKey(test_name, TSIGKey::HMACSHA512_NAME(), + &secret[0], secret.size(), 256)); + + createMessageFromFile("tsig_verify11.wire"); + { + SCOPED_TRACE("Verify test for request"); + commonVerifyChecks(sha_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::NOERROR(), TSIGContext::RECEIVED_REQUEST); + } + + // Try with HMAC-SHA512-264 (should fail) + TSIGContext bad_sha_ctx(TSIGKey(test_name, TSIGKey::HMACSHA512_NAME(), + &secret[0], secret.size(), 264)); + { + SCOPED_TRACE("Verify test for request"); + commonVerifyChecks(bad_sha_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::BAD_TRUNC(), TSIGContext::RECEIVED_REQUEST); + } +} + +TEST_F(TSIGTest, getTSIGLength) { + // Check for the most common case with various algorithms + // See the comment in TSIGContext::getTSIGLength() for calculation and + // parameter notation. + // The key name (www.example.com) is the same for most cases, where n1=17 + + // hmac-md5.sig-alg.reg.int.: n2=26, x=16 + EXPECT_EQ(85, tsig_ctx->getTSIGLength()); + + // hmac-md5-80: n2=26, x=10 + tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name, + TSIGKey::HMACMD5_NAME(), + &dummy_data[0], 10, 80))); + EXPECT_EQ(79, tsig_ctx->getTSIGLength()); + + // hmac-sha1: n2=11, x=20 + tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name, + TSIGKey::HMACSHA1_NAME(), + &dummy_data[0], 20))); + EXPECT_EQ(74, tsig_ctx->getTSIGLength()); + + // hmac-sha256: n2=13, x=32 + tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name, + TSIGKey::HMACSHA256_NAME(), + &dummy_data[0], 32))); + EXPECT_EQ(88, tsig_ctx->getTSIGLength()); + + // hmac-sha224: n2=13, x=28 + tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name, + TSIGKey::HMACSHA224_NAME(), + &dummy_data[0], 28))); + EXPECT_EQ(84, tsig_ctx->getTSIGLength()); + + // hmac-sha384: n2=13, x=48 + tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name, + TSIGKey::HMACSHA384_NAME(), + &dummy_data[0], 48))); + EXPECT_EQ(104, tsig_ctx->getTSIGLength()); + + // hmac-sha512: n2=13, x=64 + tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name, + TSIGKey::HMACSHA512_NAME(), + &dummy_data[0], 64))); + EXPECT_EQ(120, tsig_ctx->getTSIGLength()); + + // hmac-sha512-256: n2=13, x=32 + tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name, + TSIGKey::HMACSHA512_NAME(), + &dummy_data[0], 32, 256))); + EXPECT_EQ(88, tsig_ctx->getTSIGLength()); + + // bad key case: n1=len(badkey.example.com)=20, n2=26, x=0 + tsig_ctx.reset(new TestTSIGContext(badkey_name, TSIGKey::HMACMD5_NAME(), + keyring)); + EXPECT_EQ(72, tsig_ctx->getTSIGLength()); + + // bad sig case: n1=17, n2=26, x=0 + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + createMessageFromFile("message_toWire2.wire"); + tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name, + TSIGKey::HMACMD5_NAME(), + &dummy_data[0], + dummy_data.size()))); + { + SCOPED_TRACE("Verify resulting in BADSIG"); + commonVerifyChecks(*tsig_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::BAD_SIG(), TSIGContext::RECEIVED_REQUEST); + } + EXPECT_EQ(69, tsig_ctx->getTSIGLength()); + + // bad time case: n1=17, n2=26, x=16, y=6 + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a - 1000>; + tsig_ctx.reset(new TestTSIGContext(TSIGKey(test_name, + TSIGKey::HMACMD5_NAME(), + &dummy_data[0], + dummy_data.size()))); + { + SCOPED_TRACE("Verify resulting in BADTIME"); + commonVerifyChecks(*tsig_ctx, message.getTSIGRecord(), + &received_data[0], received_data.size(), + TSIGError::BAD_TIME(), + TSIGContext::RECEIVED_REQUEST); + } + EXPECT_EQ(91, tsig_ctx->getTSIGLength()); +} + +// Verify a stream of multiple messages. Some of them have a signature omitted. +// +// We have two contexts, one that signs, another that verifies. +TEST_F(TSIGTest, verifyMulti) { + isc::util::detail::gettimeFunction = testGetTime<0x4da8877a>; + + // First, send query from the verify one to the normal one, so + // we initialize something like AXFR + { + SCOPED_TRACE("Query"); + ConstTSIGRecordPtr tsig = createMessageAndSign(1234, test_name, + tsig_verify_ctx.get()); + commonVerifyChecks(*tsig_ctx, tsig.get(), + renderer.getData(), renderer.getLength(), + TSIGError(Rcode::NOERROR()), + TSIGContext::RECEIVED_REQUEST); + } + + { + SCOPED_TRACE("First message"); + ConstTSIGRecordPtr tsig = createMessageAndSign(1234, test_name, + tsig_ctx.get()); + commonVerifyChecks(*tsig_verify_ctx, tsig.get(), + renderer.getData(), renderer.getLength(), + TSIGError(Rcode::NOERROR()), + TSIGContext::VERIFIED_RESPONSE); + EXPECT_TRUE(tsig_verify_ctx->lastHadSignature()); + } + + { + SCOPED_TRACE("Second message"); + ConstTSIGRecordPtr tsig = createMessageAndSign(1234, test_name, + tsig_ctx.get()); + commonVerifyChecks(*tsig_verify_ctx, tsig.get(), + renderer.getData(), renderer.getLength(), + TSIGError(Rcode::NOERROR()), + TSIGContext::VERIFIED_RESPONSE); + EXPECT_TRUE(tsig_verify_ctx->lastHadSignature()); + } + + { + SCOPED_TRACE("Third message. Unsigned."); + // Another message does not carry the TSIG on it. But it should + // be OK, it's in the middle of stream. + message.clear(Message::RENDER); + message.setQid(1234); + message.setOpcode(Opcode::QUERY()); + message.setRcode(Rcode::NOERROR()); + RRsetPtr answer_rrset(new RRset(test_name, test_class, RRType::A(), + test_ttl)); + answer_rrset->addRdata(createRdata(RRType::A(), test_class, + "192.0.2.1")); + message.addRRset(Message::SECTION_ANSWER, answer_rrset); + message.toWire(renderer); + // Update the internal state. We abuse the knowledge of + // internals here a little bit to generate correct test data + tsig_ctx->update(renderer.getData(), renderer.getLength()); + + commonVerifyChecks(*tsig_verify_ctx, NULL, + renderer.getData(), renderer.getLength(), + TSIGError(Rcode::NOERROR()), + TSIGContext::VERIFIED_RESPONSE); + + EXPECT_FALSE(tsig_verify_ctx->lastHadSignature()); + } + + { + SCOPED_TRACE("Fourth message. Signed again."); + ConstTSIGRecordPtr tsig = createMessageAndSign(1234, test_name, + tsig_ctx.get()); + commonVerifyChecks(*tsig_verify_ctx, tsig.get(), + renderer.getData(), renderer.getLength(), + TSIGError(Rcode::NOERROR()), + TSIGContext::VERIFIED_RESPONSE); + EXPECT_TRUE(tsig_verify_ctx->lastHadSignature()); + } + + { + SCOPED_TRACE("Filling in bunch of unsigned messages"); + for (size_t i = 0; i < 100; ++i) { + SCOPED_TRACE(i); + // Another message does not carry the TSIG on it. But it should + // be OK, it's in the middle of stream. + message.clear(Message::RENDER); + message.setQid(1234); + message.setOpcode(Opcode::QUERY()); + message.setRcode(Rcode::NOERROR()); + RRsetPtr answer_rrset(new RRset(test_name, test_class, RRType::A(), + test_ttl)); + answer_rrset->addRdata(createRdata(RRType::A(), test_class, + "192.0.2.1")); + message.addRRset(Message::SECTION_ANSWER, answer_rrset); + message.toWire(renderer); + // Update the internal state. We abuse the knowledge of + // internals here a little bit to generate correct test data + tsig_ctx->update(renderer.getData(), renderer.getLength()); + + // 99 unsigned messages is OK. But the 100th must be signed, according + // to the RFC2845, section 4.4 + commonVerifyChecks(*tsig_verify_ctx, NULL, + renderer.getData(), renderer.getLength(), + i == 99 ? TSIGError::FORMERR() : + TSIGError(Rcode::NOERROR()), + TSIGContext::VERIFIED_RESPONSE); + + EXPECT_FALSE(tsig_verify_ctx->lastHadSignature()); + } + } +} + +} // end namespace diff --git a/src/lib/dns/tests/tsigerror_unittest.cc b/src/lib/dns/tests/tsigerror_unittest.cc new file mode 100644 index 0000000..e50f076 --- /dev/null +++ b/src/lib/dns/tests/tsigerror_unittest.cc @@ -0,0 +1,126 @@ +// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> +#include <ostream> + +#include <gtest/gtest.h> + +#include <exceptions/exceptions.h> + +#include <dns/rcode.h> +#include <dns/tsigerror.h> + +using namespace std; +using namespace isc; +using namespace isc::dns; + +namespace { +TEST(TSIGErrorTest, constructFromErrorCode) { + // These are pretty trivial, and also test getCode(); + EXPECT_EQ(0, TSIGError(0).getCode()); + EXPECT_EQ(18, TSIGError(18).getCode()); + EXPECT_EQ(65535, TSIGError(65535).getCode()); +} + +TEST(TSIGErrorTest, constructFromRcode) { + // We use RCODE for code values from 0-15. + EXPECT_EQ(0, TSIGError(Rcode::NOERROR()).getCode()); + EXPECT_EQ(15, TSIGError(Rcode(15)).getCode()); + + // From error code 16 TSIG errors define a separate space, so passing + // corresponding RCODE for such code values should be prohibited. + EXPECT_THROW(TSIGError(Rcode(16)).getCode(), OutOfRange); +} + +TEST(TSIGErrorTest, constants) { + // We'll only test arbitrarily chosen subsets of the codes. + // This class is quite simple, so it should be suffice. + + EXPECT_EQ(TSIGError::BAD_SIG_CODE, TSIGError(16).getCode()); + EXPECT_EQ(TSIGError::BAD_KEY_CODE, TSIGError(17).getCode()); + EXPECT_EQ(TSIGError::BAD_TIME_CODE, TSIGError(18).getCode()); + EXPECT_EQ(TSIGError::BAD_MODE_CODE, TSIGError(19).getCode()); + EXPECT_EQ(TSIGError::BAD_NAME_CODE, TSIGError(20).getCode()); + EXPECT_EQ(TSIGError::BAD_ALG_CODE, TSIGError(21).getCode()); + EXPECT_EQ(TSIGError::BAD_TRUNC_CODE, TSIGError(22).getCode()); + + EXPECT_EQ(0, TSIGError::NOERROR().getCode()); + EXPECT_EQ(9, TSIGError::NOTAUTH().getCode()); + EXPECT_EQ(14, TSIGError::RESERVED14().getCode()); + EXPECT_EQ(TSIGError::BAD_SIG_CODE, TSIGError::BAD_SIG().getCode()); + EXPECT_EQ(TSIGError::BAD_KEY_CODE, TSIGError::BAD_KEY().getCode()); + EXPECT_EQ(TSIGError::BAD_TIME_CODE, TSIGError::BAD_TIME().getCode()); + EXPECT_EQ(TSIGError::BAD_MODE_CODE, TSIGError::BAD_MODE().getCode()); + EXPECT_EQ(TSIGError::BAD_NAME_CODE, TSIGError::BAD_NAME().getCode()); + EXPECT_EQ(TSIGError::BAD_ALG_CODE, TSIGError::BAD_ALG().getCode()); + EXPECT_EQ(TSIGError::BAD_TRUNC_CODE, TSIGError::BAD_TRUNC().getCode()); +} + +TEST(TSIGErrorTest, equal) { + EXPECT_TRUE(TSIGError::NOERROR() == TSIGError(Rcode::NOERROR())); + EXPECT_TRUE(TSIGError(Rcode::NOERROR()) == TSIGError::NOERROR()); + EXPECT_TRUE(TSIGError::NOERROR().equals(TSIGError(Rcode::NOERROR()))); + EXPECT_TRUE(TSIGError::NOERROR().equals(TSIGError(Rcode::NOERROR()))); + + EXPECT_TRUE(TSIGError::BAD_SIG() == TSIGError(16)); + EXPECT_TRUE(TSIGError(16) == TSIGError::BAD_SIG()); + EXPECT_TRUE(TSIGError::BAD_SIG().equals(TSIGError(16))); + EXPECT_TRUE(TSIGError(16).equals(TSIGError::BAD_SIG())); +} + +TEST(TSIGErrorTest, nequal) { + EXPECT_TRUE(TSIGError::BAD_KEY() != TSIGError(Rcode::NOERROR())); + EXPECT_TRUE(TSIGError(Rcode::NOERROR()) != TSIGError::BAD_KEY()); + EXPECT_TRUE(TSIGError::BAD_KEY().nequals(TSIGError(Rcode::NOERROR()))); + EXPECT_TRUE(TSIGError(Rcode::NOERROR()).nequals(TSIGError::BAD_KEY())); +} + +TEST(TSIGErrorTest, toText) { + // TSIGError derived from the standard Rcode + EXPECT_EQ("NOERROR", TSIGError(Rcode::NOERROR()).toText()); + + // Well known TSIG errors + EXPECT_EQ("BADSIG", TSIGError::BAD_SIG().toText()); + EXPECT_EQ("BADKEY", TSIGError::BAD_KEY().toText()); + EXPECT_EQ("BADTIME", TSIGError::BAD_TIME().toText()); + EXPECT_EQ("BADMODE", TSIGError::BAD_MODE().toText()); + EXPECT_EQ("BADNAME", TSIGError::BAD_NAME().toText()); + EXPECT_EQ("BADALG", TSIGError::BAD_ALG().toText()); + EXPECT_EQ("BADTRUNC", TSIGError::BAD_TRUNC().toText()); + + // Unknown (or not yet supported) codes. Simply converted as numeric. + EXPECT_EQ("23", TSIGError(23).toText()); + EXPECT_EQ("65535", TSIGError(65535).toText()); +} + +TEST(TSIGErrorTest, toRcode) { + // TSIGError derived from the standard Rcode + EXPECT_EQ(Rcode::NOERROR(), TSIGError(Rcode::NOERROR()).toRcode()); + + // Well known TSIG errors + EXPECT_EQ(Rcode::NOTAUTH(), TSIGError::BAD_SIG().toRcode()); + EXPECT_EQ(Rcode::NOTAUTH(), TSIGError::BAD_KEY().toRcode()); + EXPECT_EQ(Rcode::NOTAUTH(), TSIGError::BAD_TIME().toRcode()); + EXPECT_EQ(Rcode::NOTAUTH(), TSIGError::BAD_MODE().toRcode()); + EXPECT_EQ(Rcode::NOTAUTH(), TSIGError::BAD_NAME().toRcode()); + EXPECT_EQ(Rcode::NOTAUTH(), TSIGError::BAD_ALG().toRcode()); + EXPECT_EQ(Rcode::NOTAUTH(), TSIGError::BAD_TRUNC().toRcode()); + + // Unknown (or not yet supported) codes are treated as SERVFAIL. + EXPECT_EQ(Rcode::SERVFAIL(), TSIGError(23).toRcode()); + EXPECT_EQ(Rcode::SERVFAIL(), TSIGError(65535).toRcode()); +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST(TSIGErrorTest, LeftShiftOperator) { + ostringstream oss; + oss << TSIGError::BAD_KEY(); + EXPECT_EQ(TSIGError::BAD_KEY().toText(), oss.str()); +} +} // end namespace diff --git a/src/lib/dns/tests/tsigkey_unittest.cc b/src/lib/dns/tests/tsigkey_unittest.cc new file mode 100644 index 0000000..90c59ac --- /dev/null +++ b/src/lib/dns/tests/tsigkey_unittest.cc @@ -0,0 +1,350 @@ +// Copyright (C) 2021-2019 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <string> + +#include <gtest/gtest.h> + +#include <exceptions/exceptions.h> + +#include <cryptolink/cryptolink.h> + +#include <dns/tsigkey.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::dns; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class TSIGKeyTest : public ::testing::Test { +protected: + TSIGKeyTest() : secret("someRandomData"), key_name("example.com") {} + string secret; + const Name key_name; +}; + +TEST_F(TSIGKeyTest, algorithmNames) { + EXPECT_EQ(Name("hmac-md5.sig-alg.reg.int"), TSIGKey::HMACMD5_NAME()); + EXPECT_EQ(Name("hmac-md5"), TSIGKey::HMACMD5_SHORT_NAME()); + EXPECT_EQ(Name("hmac-sha1"), TSIGKey::HMACSHA1_NAME()); + EXPECT_EQ(Name("hmac-sha256"), TSIGKey::HMACSHA256_NAME()); + EXPECT_EQ(Name("hmac-sha224"), TSIGKey::HMACSHA224_NAME()); + EXPECT_EQ(Name("hmac-sha384"), TSIGKey::HMACSHA384_NAME()); + EXPECT_EQ(Name("hmac-sha512"), TSIGKey::HMACSHA512_NAME()); + EXPECT_EQ(Name("gss-tsig"), TSIGKey::GSSTSIG_NAME()); + + // Also check conversion to cryptolink definitions + EXPECT_EQ(isc::cryptolink::MD5, TSIGKey(key_name, TSIGKey::HMACMD5_NAME(), + NULL, 0).getAlgorithm()); + EXPECT_EQ(isc::cryptolink::MD5, + TSIGKey(key_name, TSIGKey::HMACMD5_SHORT_NAME(), + NULL, 0).getAlgorithm()); + EXPECT_EQ(isc::cryptolink::SHA1, TSIGKey(key_name, TSIGKey::HMACSHA1_NAME(), + NULL, 0).getAlgorithm()); + EXPECT_EQ(isc::cryptolink::SHA256, TSIGKey(key_name, + TSIGKey::HMACSHA256_NAME(), + NULL, 0).getAlgorithm()); + EXPECT_EQ(isc::cryptolink::SHA224, TSIGKey(key_name, + TSIGKey::HMACSHA224_NAME(), + NULL, 0).getAlgorithm()); + EXPECT_EQ(isc::cryptolink::SHA384, TSIGKey(key_name, + TSIGKey::HMACSHA384_NAME(), + NULL, 0).getAlgorithm()); + EXPECT_EQ(isc::cryptolink::SHA512, TSIGKey(key_name, + TSIGKey::HMACSHA512_NAME(), + NULL, 0).getAlgorithm()); +} + +TEST_F(TSIGKeyTest, construct) { + TSIGKey key(key_name, TSIGKey::HMACMD5_NAME(), + secret.c_str(), secret.size()); + EXPECT_EQ(key_name, key.getKeyName()); + EXPECT_EQ(Name("hmac-md5.sig-alg.reg.int"), key.getAlgorithmName()); + matchWireData(secret.c_str(), secret.size(), + key.getSecret(), key.getSecretLength()); + + TSIGKey key_short_md5(key_name, TSIGKey::HMACMD5_SHORT_NAME(), + secret.c_str(), secret.size()); + EXPECT_EQ(key_name, key_short_md5.getKeyName()); + EXPECT_EQ(Name("hmac-md5.sig-alg.reg.int"), + key_short_md5.getAlgorithmName()); + matchWireData(secret.c_str(), secret.size(), + key_short_md5.getSecret(), key_short_md5.getSecretLength()); + + // "unknown" algorithm is only accepted with empty secret. + EXPECT_THROW(TSIGKey(key_name, Name("unknown-alg"), + secret.c_str(), secret.size()), + isc::InvalidParameter); + TSIGKey key2(key_name, Name("unknown-alg"), NULL, 0); + EXPECT_EQ(key_name, key2.getKeyName()); + EXPECT_EQ(Name("unknown-alg"), key2.getAlgorithmName()); + + // The algorithm name should be converted to the canonical form. + EXPECT_EQ("hmac-sha1.", + TSIGKey(key_name, Name("HMAC-sha1"), + secret.c_str(), + secret.size()).getAlgorithmName().toText()); + + // Same for key name + EXPECT_EQ("example.com.", + TSIGKey(Name("EXAMPLE.CoM."), TSIGKey::HMACSHA256_NAME(), + secret.c_str(), + secret.size()).getKeyName().toText()); + + // Check digestbits + EXPECT_EQ(key.getDigestbits(), 0); + TSIGKey key_trunc(key_name, TSIGKey::HMACMD5_NAME(), + secret.c_str(), secret.size(), 120); + EXPECT_EQ(key_trunc.getDigestbits(), 120); + + // Invalid combinations of secret and secret_len: + EXPECT_THROW(TSIGKey(key_name, TSIGKey::HMACSHA1_NAME(), secret.c_str(), 0), + isc::InvalidParameter); + EXPECT_THROW(TSIGKey(key_name, TSIGKey::HMACSHA256_NAME(), NULL, 16), + isc::InvalidParameter); + + // Empty secret + TSIGKey keye = TSIGKey(key_name, TSIGKey::HMACSHA256_NAME(), NULL, 0); + EXPECT_EQ(keye.getSecretLength(), 0); + EXPECT_EQ(keye.getSecret(), (const void*)0); +} + +void +compareTSIGKeys(const TSIGKey& expect, const TSIGKey& actual) { + EXPECT_EQ(expect.getKeyName(), actual.getKeyName()); + EXPECT_EQ(expect.getAlgorithmName(), actual.getAlgorithmName()); + EXPECT_EQ(expect.getDigestbits(), actual.getDigestbits()); + matchWireData(expect.getSecret(), expect.getSecretLength(), + actual.getSecret(), actual.getSecretLength()); +} + +TEST_F(TSIGKeyTest, copyConstruct) { + const TSIGKey original(key_name, TSIGKey::HMACSHA256_NAME(), + secret.c_str(), secret.size(), 128); + const TSIGKey copy(original); + compareTSIGKeys(original, copy); + + // Check the copied data is valid even after the original is deleted + TSIGKey* copy2 = new TSIGKey(original); + TSIGKey copy3(*copy2); + delete copy2; + compareTSIGKeys(original, copy3); +} + +TEST_F(TSIGKeyTest, assignment) { + const TSIGKey original(key_name, TSIGKey::HMACSHA256_NAME(), + secret.c_str(), secret.size(), 200); + TSIGKey copy = original; + compareTSIGKeys(original, copy); + + // Check if the copied data is valid even after the original is deleted + TSIGKey* copy2 = new TSIGKey(original); + TSIGKey copy3(original); + copy3 = *copy2; + delete copy2; + compareTSIGKeys(original, copy3); + + // Self assignment + copy = *© + compareTSIGKeys(original, copy); +} + +class TSIGKeyRingTest : public ::testing::Test { +protected: + TSIGKeyRingTest() : + key_name("example.com"), + md5_name("hmac-md5.sig-alg.reg.int"), + sha1_name("hmac-sha1"), + sha256_name("hmac-sha256"), + secretstring("anotherRandomData"), + secret(secretstring.c_str()), + secret_len(secretstring.size()) + {} + TSIGKeyRing keyring; + const Name key_name; + const Name md5_name; + const Name sha1_name; + const Name sha256_name; +private: + const string secretstring; +protected: + const char* secret; + size_t secret_len; +}; + +TEST_F(TSIGKeyRingTest, init) { + EXPECT_EQ(0, keyring.size()); +} + +TEST_F(TSIGKeyRingTest, add) { + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add( + TSIGKey(key_name, TSIGKey::HMACSHA256_NAME(), + secret, secret_len))); + EXPECT_EQ(1, keyring.size()); + EXPECT_EQ(TSIGKeyRing::EXIST, keyring.add( + TSIGKey(key_name, TSIGKey::HMACSHA256_NAME(), + secret, secret_len))); + // keys are identified by their names, the same name of key with a + // different algorithm would be considered a duplicate. + EXPECT_EQ(TSIGKeyRing::EXIST, keyring.add( + TSIGKey(Name("example.com"), TSIGKey::HMACSHA1_NAME(), + secret, secret_len))); + // names are compared in a case insensitive manner. + EXPECT_EQ(TSIGKeyRing::EXIST, keyring.add( + TSIGKey(Name("EXAMPLE.COM"), TSIGKey::HMACSHA1_NAME(), + secret, secret_len))); + EXPECT_EQ(1, keyring.size()); +} + +TEST_F(TSIGKeyRingTest, addMore) { + // essentially the same test, but try adding more than 1 + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add( + TSIGKey(key_name, TSIGKey::HMACSHA256_NAME(), + secret, secret_len))); + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add( + TSIGKey(Name("another.example"), TSIGKey::HMACMD5_NAME(), + secret, secret_len))); + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add( + TSIGKey(Name("more.example"), TSIGKey::HMACSHA1_NAME(), + secret, secret_len))); + EXPECT_EQ(3, keyring.size()); +} + +TEST_F(TSIGKeyRingTest, remove) { + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add( + TSIGKey(key_name, TSIGKey::HMACSHA256_NAME(), + secret, secret_len))); + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.remove(key_name)); + EXPECT_EQ(TSIGKeyRing::NOTFOUND, keyring.remove(key_name)); +} + +TEST_F(TSIGKeyRingTest, removeFromSome) { + // essentially the same test, but try removing from a larger set + + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add( + TSIGKey(key_name, TSIGKey::HMACSHA256_NAME(), + secret, secret_len))); + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add( + TSIGKey(Name("another.example"), TSIGKey::HMACMD5_NAME(), + secret, secret_len))); + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add( + TSIGKey(Name("more.example"), TSIGKey::HMACSHA1_NAME(), + secret, secret_len))); + + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.remove(Name("another.example"))); + EXPECT_EQ(TSIGKeyRing::NOTFOUND, keyring.remove(Name("noexist.example"))); + EXPECT_EQ(2, keyring.size()); +} + +TEST_F(TSIGKeyRingTest, find) { + // If the keyring is empty the search should fail. + EXPECT_EQ(TSIGKeyRing::NOTFOUND, keyring.find(key_name, md5_name).code); + EXPECT_EQ(static_cast<const TSIGKey*>(NULL), + keyring.find(key_name, md5_name).key); + + // Add a key and try to find it. Should succeed. + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add(TSIGKey(key_name, sha256_name, + secret, secret_len))); + const TSIGKeyRing::FindResult result1(keyring.find(key_name, sha256_name)); + EXPECT_EQ(TSIGKeyRing::SUCCESS, result1.code); + EXPECT_EQ(key_name, result1.key->getKeyName()); + EXPECT_EQ(TSIGKey::HMACSHA256_NAME(), result1.key->getAlgorithmName()); + matchWireData(secret, secret_len, + result1.key->getSecret(), result1.key->getSecretLength()); + + // If either key name or algorithm doesn't match, search should fail. + const TSIGKeyRing::FindResult result2 = + keyring.find(Name("different-key.example"), sha256_name); + EXPECT_EQ(TSIGKeyRing::NOTFOUND, result2.code); + EXPECT_EQ(static_cast<const TSIGKey*>(NULL), result2.key); + + const TSIGKeyRing::FindResult result3 = keyring.find(key_name, md5_name); + EXPECT_EQ(TSIGKeyRing::NOTFOUND, result3.code); + EXPECT_EQ(static_cast<const TSIGKey*>(NULL), result3.key); + + // But with just the name it should work + const TSIGKeyRing::FindResult result4(keyring.find(key_name)); + EXPECT_EQ(TSIGKeyRing::SUCCESS, result4.code); + EXPECT_EQ(key_name, result4.key->getKeyName()); + EXPECT_EQ(TSIGKey::HMACSHA256_NAME(), result4.key->getAlgorithmName()); + matchWireData(secret, secret_len, + result4.key->getSecret(), result4.key->getSecretLength()); +} + +TEST_F(TSIGKeyRingTest, findFromSome) { + // essentially the same test, but search a larger set + + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add(TSIGKey(key_name, sha256_name, + secret, secret_len))); + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add(TSIGKey(Name("another.example"), + md5_name, + secret, secret_len))); + EXPECT_EQ(TSIGKeyRing::SUCCESS, keyring.add(TSIGKey(Name("more.example"), + sha1_name, + secret, secret_len))); + + const TSIGKeyRing::FindResult result( + keyring.find(Name("another.example"), md5_name)); + EXPECT_EQ(TSIGKeyRing::SUCCESS, result.code); + EXPECT_EQ(Name("another.example"), result.key->getKeyName()); + EXPECT_EQ(TSIGKey::HMACMD5_NAME(), result.key->getAlgorithmName()); + + EXPECT_EQ(TSIGKeyRing::NOTFOUND, + keyring.find(Name("noexist.example"), sha1_name).code); + EXPECT_EQ(static_cast<const TSIGKey*>(NULL), + keyring.find(Name("noexist.example"), sha256_name).key); + + EXPECT_EQ(TSIGKeyRing::NOTFOUND, + keyring.find(Name("another.example"), sha1_name).code); + EXPECT_EQ(static_cast<const TSIGKey*>(NULL), + keyring.find(Name("another.example"), sha256_name).key); +} + +TEST(TSIGStringTest, TSIGKeyFromToString) { + TSIGKey k1 = TSIGKey("test.example:MSG6Ng==:hmac-md5.sig-alg.reg.int"); + TSIGKey k2 = TSIGKey("test.example.:MSG6Ng==:hmac-md5.sig-alg.reg.int."); + TSIGKey k3 = TSIGKey("test.example:MSG6Ng=="); + TSIGKey k4 = TSIGKey("test.example.:MSG6Ng==:hmac-md5.sig-alg.reg.int.:120"); + TSIGKey k5 = TSIGKey(Name("test.example."), Name("hmac-sha1."), NULL, 0); + // "Unknown" key with empty secret is okay + TSIGKey k6 = TSIGKey("test.example.::unknown"); + + EXPECT_EQ("test.example.:MSG6Ng==:hmac-md5.sig-alg.reg.int.", + k1.toText()); + EXPECT_EQ("test.example.:MSG6Ng==:hmac-md5.sig-alg.reg.int.", + k2.toText()); + EXPECT_EQ("test.example.:MSG6Ng==:hmac-md5.sig-alg.reg.int.", + k3.toText()); + EXPECT_EQ("test.example.:MSG6Ng==:hmac-md5.sig-alg.reg.int.:120", + k4.toText()); + EXPECT_EQ(120, k4.getDigestbits()); + EXPECT_EQ("test.example.::hmac-sha1.", k5.toText()); + EXPECT_EQ(Name("test.example."), k6.getKeyName()); + EXPECT_EQ(Name("unknown"), k6.getAlgorithmName()); + + EXPECT_THROW(TSIGKey(""), isc::InvalidParameter); + EXPECT_THROW(TSIGKey(":"), isc::InvalidParameter); + EXPECT_THROW(TSIGKey("::"), isc::InvalidParameter); + EXPECT_THROW(TSIGKey("..:aa:"), isc::InvalidParameter); + EXPECT_THROW(TSIGKey("test.example:xxxx:"), isc::InvalidParameter); + EXPECT_THROW(TSIGKey("test.example.::"), isc::InvalidParameter); + EXPECT_THROW(TSIGKey("test.example.:"), isc::InvalidParameter); + EXPECT_THROW(TSIGKey("test.example.:MSG6Ng==:"), isc::InvalidParameter); + EXPECT_THROW(TSIGKey("test.example.:MSG6Ng==:unknown"), isc::InvalidParameter); + EXPECT_THROW(TSIGKey("test.example.:MSG6Ng==:hmac-md5.sig-alg.reg.int.:"), + isc::InvalidParameter); + EXPECT_THROW(TSIGKey("test.example.:MSG6Ng==:hmac-md5.sig-alg.reg.int.:xxx"), + isc::InvalidParameter); +} + + +} // end namespace diff --git a/src/lib/dns/tests/tsigrecord_unittest.cc b/src/lib/dns/tests/tsigrecord_unittest.cc new file mode 100644 index 0000000..624f03b --- /dev/null +++ b/src/lib/dns/tests/tsigrecord_unittest.cc @@ -0,0 +1,158 @@ +// Copyright (C) 2011-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <vector> +#include <sstream> + +#include <gtest/gtest.h> + +#include <util/buffer.h> + +#include <dns/exceptions.h> +#include <dns/messagerenderer.h> +#include <dns/name.h> +#include <dns/rdata.h> +#include <dns/rdataclass.h> +#include <dns/tsig.h> +#include <dns/tsigkey.h> +#include <dns/tsigrecord.h> + +#include <dns/tests/unittest_util.h> +#include <util/unittests/wiredata.h> + +using namespace std; +using namespace isc::util; +using namespace isc::dns; +using namespace isc::dns::rdata; +using namespace isc::dns::rdata::any; +using isc::UnitTestUtil; +using isc::util::unittests::matchWireData; + +namespace { +class TSIGRecordTest : public ::testing::Test { +protected: + TSIGRecordTest() : + test_name("www.example.com"), test_mac(16, 0xda), + test_rdata(TSIG(TSIGKey::HMACMD5_NAME(), 0x4da8877a, TSIGContext::DEFAULT_FUDGE, + test_mac.size(), &test_mac[0], 0x2d65, 0, 0, NULL)), + test_record(test_name, test_rdata), + buffer(0) { + } + + const Name test_name; + + vector<unsigned char> test_mac; + + const TSIG test_rdata; + + const TSIGRecord test_record; + + OutputBuffer buffer; + + MessageRenderer renderer; + + vector<unsigned char> data; +}; + +TEST_F(TSIGRecordTest, getName) { + EXPECT_EQ(test_name, test_record.getName()); +} + +TEST_F(TSIGRecordTest, getLength) { + // 85 = 17 + 26 + 16 + 26 + // len(www.example.com) = 17 + // len(hmac-md5.sig-alg.reg.int) = 26 + // len(MAC) = 16 + // the rest are fixed length fields (26 in total) + EXPECT_EQ(85, test_record.getLength()); +} + +TEST_F(TSIGRecordTest, fromParams) { + // Construct the same TSIG RR as test_record from parameters. + // See the getLength test for the magic number of 85 (although it + // actually doesn't matter) + const TSIGRecord record(test_name, TSIGRecord::getClass(), + TSIGRecord::getTTL(), test_rdata, 85); + // Perform straight sanity checks + EXPECT_EQ(test_name, record.getName()); + EXPECT_EQ(85, record.getLength()); + EXPECT_EQ(0, test_rdata.compare(record.getRdata())); + + // The constructor doesn't check the length... + EXPECT_NO_THROW(TSIGRecord(test_name, TSIGRecord::getClass(), + TSIGRecord::getTTL(), test_rdata, 82)); + // ...even for impossibly small values... + EXPECT_NO_THROW(TSIGRecord(test_name, TSIGRecord::getClass(), + TSIGRecord::getTTL(), test_rdata, 1)); + // ...or too large values. + EXPECT_NO_THROW(TSIGRecord(test_name, TSIGRecord::getClass(), + TSIGRecord::getTTL(), test_rdata, 65536)); + + // RDATA must indeed be TSIG + EXPECT_THROW(TSIGRecord(test_name, TSIGRecord::getClass(), + TSIGRecord::getTTL(), in::A("192.0.2.1"), 85), + DNSMessageFORMERR); + + // Unexpected class + EXPECT_THROW(TSIGRecord(test_name, RRClass::IN(), TSIGRecord::getTTL(), + test_rdata, 85), DNSMessageFORMERR); + + // Unexpected TTL + EXPECT_THROW(TSIGRecord(test_name, TSIGRecord::getClass(), + RRTTL(3600), test_rdata, 85), DNSMessageFORMERR); +} + +TEST_F(TSIGRecordTest, recordToWire) { + UnitTestUtil::readWireData("tsigrecord_toWire1.wire", data); + EXPECT_EQ(1, test_record.toWire(renderer)); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); + + // Same test for a dumb buffer + buffer.clear(); + EXPECT_EQ(1, test_record.toWire(buffer)); + matchWireData(&data[0], data.size(), + buffer.getData(), buffer.getLength()); +} + +TEST_F(TSIGRecordTest, recordToOLongToWire) { + // By setting the limit to "record length - 1", it will fail, and the + // renderer will be marked as "truncated". + renderer.setLengthLimit(test_record.getLength() - 1); + EXPECT_FALSE(renderer.isTruncated()); // not marked before render attempt + EXPECT_EQ(0, test_record.toWire(renderer)); + EXPECT_TRUE(renderer.isTruncated()); +} + +TEST_F(TSIGRecordTest, recordToWireAfterNames) { + // A similar test but the TSIG RR follows some domain names that could + // cause name compression inside TSIG. Our implementation shouldn't + // compress either owner (key) name or the algorithm name. This test + // confirms that. + + UnitTestUtil::readWireData("tsigrecord_toWire2.wire", data); + renderer.writeName(TSIGKey::HMACMD5_NAME()); + renderer.writeName(Name("foo.example.com")); + EXPECT_EQ(1, test_record.toWire(renderer)); + matchWireData(&data[0], data.size(), + renderer.getData(), renderer.getLength()); +} + +TEST_F(TSIGRecordTest, toText) { + EXPECT_EQ("www.example.com. 0 ANY TSIG hmac-md5.sig-alg.reg.int. " + "1302890362 300 16 2tra2tra2tra2tra2tra2g== 11621 NOERROR 0\n", + test_record.toText()); +} + +// test operator<<. We simply confirm it appends the result of toText(). +TEST_F(TSIGRecordTest, LeftShiftOperator) { + ostringstream oss; + oss << test_record; + EXPECT_EQ(test_record.toText(), oss.str()); +} +} // end namespace diff --git a/src/lib/dns/tests/unittest_util.cc b/src/lib/dns/tests/unittest_util.cc new file mode 100644 index 0000000..b234c1c --- /dev/null +++ b/src/lib/dns/tests/unittest_util.cc @@ -0,0 +1,176 @@ +// Copyright (C) 2009-2015 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <iostream> +#include <fstream> +#include <sstream> +#include <stdexcept> +#include <vector> +#include <string> + +#include <gtest/gtest.h> + +#include <dns/rcode.h> +#include <dns/name.h> +#include <dns/message.h> +#include <dns/tests/unittest_util.h> + +using namespace std; +using namespace isc::dns; + +using isc::UnitTestUtil; + +namespace { +class UnitTestUtilConfig { +private: + // This is a singleton object and cannot be constructed explicitly. + UnitTestUtilConfig() {} + UnitTestUtilConfig(const UnitTestUtilConfig& source); + ~UnitTestUtilConfig() {} +public: + /// Return a singleton unit test configuration object. On first invocation + /// one will be constructed. + static UnitTestUtilConfig& getConfig(); + + /// A list of paths to wire data files. + /// \c UnitTestUtil::readWireData() (first version) + /// will search the directories in this list for the specified data file. + std::vector<string> data_paths_; +}; + +UnitTestUtilConfig& +UnitTestUtilConfig::getConfig() { + static UnitTestUtilConfig config; + return (config); +} +} + +void +UnitTestUtil::readWireData(const char* datafile, vector<unsigned char>& data) { + ifstream ifs; + + const UnitTestUtilConfig& config = UnitTestUtilConfig::getConfig(); + vector<string>::const_iterator it = config.data_paths_.begin(); + for (; it != config.data_paths_.end(); ++it) { + string data_path = *it; + if (data_path.empty() || *data_path.rbegin() != '/') { + data_path.push_back('/'); + } + ifs.open((data_path + datafile).c_str(), ios_base::in); + if ((ifs.rdstate() & istream::failbit) == 0) { + break; + } + } + + if (it == config.data_paths_.end()) { + throw runtime_error("failed to open data file in data paths: " + + string(datafile)); + } + + data.clear(); + + string s; + while (getline(ifs, s), !ifs.eof()) { + if (ifs.bad() || ifs.fail()) { + throw runtime_error("unexpected data line"); + } + if (s.empty() || s[0] == '#') { + continue; + } + + readWireData(s, data); + } +} + +void +UnitTestUtil::addDataPath(const string& directory) { + UnitTestUtilConfig::getConfig().data_paths_.push_back(directory); +} + +void +UnitTestUtil::readWireData(const string& datastr, + vector<unsigned char>& data) +{ + istringstream iss(datastr); + + do { + string bytes; + iss >> bytes; + if (iss.bad() || iss.fail() || (bytes.size() % 2) != 0) { + ostringstream err_oss; + err_oss << "unexpected input or I/O error in reading " << + datastr; + throw runtime_error(err_oss.str()); + } + + for (string::size_type pos = 0; pos < bytes.size(); pos += 2) { + istringstream iss_byte(bytes.substr(pos, 2)); + unsigned int ch; + + iss_byte >> hex >> ch; + if (iss_byte.rdstate() != istream::eofbit) { + ostringstream err_oss; + err_oss << "invalid byte representation: " << iss_byte.str(); + throw runtime_error(err_oss.str()); + } + data.push_back(static_cast<unsigned char>(ch)); + } + } while (!iss.eof()); +} + +::testing::AssertionResult +UnitTestUtil::matchName(const char*, const char*, + const isc::dns::Name& name1, + const isc::dns::Name& name2) +{ + ::testing::Message msg; + + NameComparisonResult cmpresult = name1.compare(name2); + if (cmpresult.getOrder() != 0 || + cmpresult.getRelation() != NameComparisonResult::EQUAL) { + msg << "Two names are expected to be equal but not:\n" + << " One: " << name1 << "\n" + << "Other: " << name2 << "\n"; + return (::testing::AssertionFailure(msg)); + } + return (::testing::AssertionSuccess()); +} + +void +UnitTestUtil::createRequestMessage(Message& message, + const Opcode& opcode, + const uint16_t qid, + const Name& name, + const RRClass& rrclass, + const RRType& rrtype) +{ + message.clear(Message::RENDER); + message.setOpcode(opcode); + message.setRcode(Rcode::NOERROR()); + message.setQid(qid); + message.addQuestion(Question(name, rrclass, rrtype)); +} + +void +UnitTestUtil::createDNSSECRequestMessage(Message& message, + const Opcode& opcode, + const uint16_t qid, + const Name& name, + const RRClass& rrclass, + const RRType& rrtype) +{ + message.clear(Message::RENDER); + message.setOpcode(opcode); + message.setRcode(Rcode::NOERROR()); + message.setQid(qid); + message.addQuestion(Question(name, rrclass, rrtype)); + EDNSPtr edns(new EDNS()); + edns->setUDPSize(4096); + edns->setDNSSECAwareness(true); + message.setEDNS(edns); +} diff --git a/src/lib/dns/tests/unittest_util.h b/src/lib/dns/tests/unittest_util.h new file mode 100644 index 0000000..8c6b8f5 --- /dev/null +++ b/src/lib/dns/tests/unittest_util.h @@ -0,0 +1,88 @@ +// Copyright (C) 2009-2017 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef UNITTEST_UTIL_H +#define UNITTEST_UTIL_H 1 + +#include <vector> +#include <string> + +#include <dns/name.h> +#include <dns/message.h> + +#include <gtest/gtest.h> + +namespace isc { + +class UnitTestUtil { +public: + /// + /// read text format wire data from a file and put it to the given vector. + /// + static void readWireData(const char* datafile, + std::vector<unsigned char>& data); + + /// + /// add a path that \c readWireData() will search for test data files. + /// + static void addDataPath(const std::string& directory); + + /// + /// convert a sequence of hex strings into the corresponding list of + /// 8-bit integers, and append them to the vector. + /// + static void readWireData(const std::string& datastr, + std::vector<unsigned char>& data); + + /// + /// Compare two names. + /// + /// This check method uses \c Name::compare() for comparison, which performs + /// deeper checks including the equality of offsets, and should be better + /// than EXPECT_EQ, which uses operator==. Like the \c matchWireData() + /// method, the usage is a bit awkward; the caller should use + /// \c EXPECT_PRED_FORMAT2. + /// + static ::testing::AssertionResult + matchName(const char* nameexp1, const char* nameexp2, + const isc::dns::Name& name1, const isc::dns::Name& name2); + + /// + /// Populate a request message + /// + /// Create a request message in 'request_message' using the + /// opcode 'opcode' and the name/class/type query tuple specified in + /// 'name', 'rrclass' and 'rrtype. + static void + createRequestMessage(isc::dns::Message& request_message, + const isc::dns::Opcode& opcode, + const uint16_t qid, + const isc::dns::Name& name, + const isc::dns::RRClass& rrclass, + const isc::dns::RRType& rrtype); + + /// + /// Populate a DNSSEC request message + /// + /// Create a request message in 'request_message' using the + /// opcode 'opcode' and the name/class/type query tuple specified in + /// 'name', 'rrclass' and 'rrtype. + /// EDNS will be added with DO=1 and bufsize 4096 + static void + createDNSSECRequestMessage(isc::dns::Message& request_message, + const isc::dns::Opcode& opcode, + const uint16_t qid, + const isc::dns::Name& name, + const isc::dns::RRClass& rrclass, + const isc::dns::RRType& rrtype); + +}; +} +#endif // UNITTEST_UTIL_H + +// Local Variables: +// mode: c++ +// End: diff --git a/src/lib/dns/tests/zone_checker_unittest.cc b/src/lib/dns/tests/zone_checker_unittest.cc new file mode 100644 index 0000000..863b439 --- /dev/null +++ b/src/lib/dns/tests/zone_checker_unittest.cc @@ -0,0 +1,349 @@ +// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <config.h> + +#include <dns/zone_checker.h> + +#include <exceptions/exceptions.h> + +#include <dns/name.h> +#include <dns/rrclass.h> +#include <dns/rrset.h> +#include <dns/rrtype.h> +#include <dns/rrttl.h> +#include <dns/rdataclass.h> +#include <dns/rrset_collection.h> + +#include <gtest/gtest.h> + +#include <boost/scoped_ptr.hpp> + +#include <algorithm> +#include <functional> +#include <string> +#include <sstream> +#include <vector> + +using isc::Unexpected; +using namespace isc::dns; +using namespace isc::dns::rdata; +namespace ph = std::placeholders; + +namespace { + +const char* const soa_txt = "ns.example.com. root.example.com. 0 0 0 0 0"; +const char* const ns_txt1 = "ns.example.com."; +const char* const ns_a_txt1 = "192.0.2.1"; +const char* const ns_txt2 = "ns2.example.com."; +const char* const ns_a_txt2 = "192.0.2.2"; + +class ZoneCheckerTest : public ::testing::Test { +protected: + ZoneCheckerTest() : + zname_("example.com"), zclass_(RRClass::IN()), + soa_(new RRset(zname_, zclass_, RRType::SOA(), RRTTL(60))), + ns_(new RRset(zname_, zclass_, RRType::NS(), RRTTL(60))), + callbacks_(std::bind(&ZoneCheckerTest::callback, this, ph::_1, true), + std::bind(&ZoneCheckerTest::callback, this, ph::_1, false)) + { + std::stringstream ss; + ss << "example.com. 60 IN SOA " << soa_txt << "\n"; + ss << "example.com. 60 IN NS " << ns_txt1 << "\n"; + ss << "ns.example.com. 60 IN A " << ns_a_txt1 << "\n"; + ss << "ns2.example.com. 60 IN A " << ns_a_txt2 << "\n"; + rrsets_.reset(new RRsetCollection(ss, zname_, zclass_)); + } + +public: + // This one is passed to std::bind. Some compilers seem to require + // it be public. + void callback(const std::string& reason, bool is_error) { + if (is_error) { + errors_.push_back(reason); + } else { + warns_.push_back(reason); + } + } + +protected: + // Check stored issue messages with expected ones. Clear vectors so + // the caller can check other cases. + void checkIssues() { + EXPECT_EQ(expected_errors_.size(), errors_.size()); + for (size_t i = 0; + i < std::min(expected_errors_.size(), errors_.size()); + ++i) { + // The actual message should begin with the expected message. + EXPECT_EQ(0, errors_[0].find(expected_errors_[0])) + << "actual message: " << errors_[0] << " expected: " << + expected_errors_[0]; + } + EXPECT_EQ(expected_warns_.size(), warns_.size()); + for (size_t i = 0; + i < std::min(expected_warns_.size(), warns_.size()); + ++i) { + EXPECT_EQ(0, warns_[0].find(expected_warns_[0])) + << "actual message: " << warns_[0] << " expected: " << + expected_warns_[0]; + } + + errors_.clear(); + expected_errors_.clear(); + warns_.clear(); + expected_warns_.clear(); + } + + const Name zname_; + const RRClass zclass_; + boost::scoped_ptr<RRsetCollection> rrsets_; + RRsetPtr soa_; + RRsetPtr ns_; + std::vector<std::string> errors_; + std::vector<std::string> warns_; + std::vector<std::string> expected_errors_; + std::vector<std::string> expected_warns_; + ZoneCheckerCallbacks callbacks_; +}; + +TEST_F(ZoneCheckerTest, checkGood) { + // Checking a valid case. No errors or warnings should be reported. + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + checkIssues(); + + // Multiple NS RRs are okay. + rrsets_->removeRRset(zname_, zclass_, RRType::NS()); + ns_->addRdata(generic::NS(ns_txt1)); + ns_->addRdata(generic::NS(ns_txt2)); + rrsets_->addRRset(ns_); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + checkIssues(); +} + +TEST_F(ZoneCheckerTest, checkSOA) { + // If the zone has no SOA it triggers an error. + rrsets_->removeRRset(zname_, zclass_, RRType::SOA()); + EXPECT_FALSE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_errors_.push_back("zone example.com/IN: has 0 SOA records"); + checkIssues(); + + // If null callback is specified, checkZone() only returns the final + // result. + ZoneCheckerCallbacks noerror_callbacks( + 0, std::bind(&ZoneCheckerTest::callback, this, ph::_1, false)); + EXPECT_FALSE(checkZone(zname_, zclass_, *rrsets_, noerror_callbacks)); + checkIssues(); + + // If there are more than 1 SOA RR, it's also an error. + errors_.clear(); + soa_->addRdata(generic::SOA(soa_txt)); + soa_->addRdata(generic::SOA("ns2.example.com. . 0 0 0 0 0")); + rrsets_->addRRset(soa_); + EXPECT_FALSE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_errors_.push_back("zone example.com/IN: has 2 SOA records"); + checkIssues(); + + // If the SOA RRset is "empty", it's treated as an implementation + // (rather than operational) error and results in an exception. + rrsets_->removeRRset(zname_, zclass_, RRType::SOA()); + soa_.reset(new RRset(zname_, zclass_, RRType::SOA(), RRTTL(60))); + rrsets_->addRRset(soa_); + EXPECT_THROW(checkZone(zname_, zclass_, *rrsets_, callbacks_), Unexpected); + checkIssues(); // no error/warning should be reported + + // Likewise, if the SOA RRset contains non SOA Rdata, it should be a bug. + rrsets_->removeRRset(zname_, zclass_, RRType::SOA()); + soa_.reset(new RRset(zname_, zclass_, RRType::SOA(), RRTTL(60))); + soa_->addRdata(createRdata(RRType::NS(), zclass_, "ns.example.com.")); + rrsets_->addRRset(soa_); + EXPECT_THROW(checkZone(zname_, zclass_, *rrsets_, callbacks_), Unexpected); + checkIssues(); // no error/warning should be reported +} + +TEST_F(ZoneCheckerTest, checkNS) { + // If the zone has no NS at origin it triggers an error. + rrsets_->removeRRset(zname_, zclass_, RRType::NS()); + EXPECT_FALSE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_errors_.push_back("zone example.com/IN: has no NS records"); + checkIssues(); + + // Check two buggy cases like the SOA tests + ns_.reset(new RRset(zname_, zclass_, RRType::NS(), RRTTL(60))); + rrsets_->addRRset(ns_); + EXPECT_THROW(checkZone(zname_, zclass_, *rrsets_, callbacks_), Unexpected); + checkIssues(); // no error/warning should be reported + + rrsets_->removeRRset(zname_, zclass_, RRType::NS()); + ns_.reset(new RRset(zname_, zclass_, RRType::NS(), RRTTL(60))); + ns_->addRdata(createRdata(RRType::TXT(), zclass_, "ns.example.com")); + rrsets_->addRRset(ns_); + EXPECT_THROW(checkZone(zname_, zclass_, *rrsets_, callbacks_), Unexpected); + checkIssues(); // no error/warning should be reported +} + +TEST_F(ZoneCheckerTest, checkNSData) { + const Name ns_name("ns.example.com"); + + // If a ("in-bailiwick") NS name doesn't have an address record, it's + // reported as a warning. + rrsets_->removeRRset(ns_name, zclass_, RRType::A()); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_warns_.push_back("zone example.com/IN: NS has no address"); + checkIssues(); + + // Same check, but disabling warning callback. Same result, but without + // the warning. + ZoneCheckerCallbacks nowarn_callbacks( + std::bind(&ZoneCheckerTest::callback, this, ph::_1, true), 0); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, nowarn_callbacks)); + checkIssues(); + + // A tricky case: if the name matches a wildcard, it should technically + // be considered valid, but this checker doesn't check that far and still + // warns. + RRsetPtr wild(new RRset(Name("*.example.com"), zclass_, RRType::A(), + RRTTL(0))); + wild->addRdata(in::A("192.0.2.255")); + rrsets_->addRRset(wild); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_warns_.push_back("zone example.com/IN: NS has no address"); + checkIssues(); + + // If there's a CNAME at the name instead, it's an error. + rrsets_->removeRRset(Name("*.example.com"), zclass_, RRType::A()); + RRsetPtr cname(new RRset(ns_name, zclass_, RRType::CNAME(), RRTTL(60))); + cname->addRdata(generic::CNAME("cname.example.com.")); + rrsets_->addRRset(cname); + EXPECT_FALSE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_errors_.push_back("zone example.com/IN: NS 'ns.example.com' is " + "a CNAME (illegal per RFC2181)"); + checkIssues(); + + // It doesn't have to be A. An AAAA is enough. + rrsets_->removeRRset(ns_name, zclass_, RRType::CNAME()); + RRsetPtr aaaa(new RRset(ns_name, zclass_, RRType::AAAA(), RRTTL(60))); + aaaa->addRdata(in::AAAA("2001:db8::1")); + rrsets_->addRRset(aaaa); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + checkIssues(); + + // Coexisting CNAME makes it error (CNAME with other record is itself + // invalid, but it's a different issue in this context) + rrsets_->addRRset(cname); + EXPECT_FALSE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_errors_.push_back("zone example.com/IN: NS 'ns.example.com' is " + "a CNAME (illegal per RFC2181)"); + checkIssues(); + + // It doesn't matter if the NS name is "out of bailiwick". + rrsets_->removeRRset(ns_name, zclass_, RRType::CNAME()); + rrsets_->removeRRset(zname_, zclass_, RRType::NS()); + ns_.reset(new RRset(zname_, zclass_, RRType::NS(), RRTTL(60))); + ns_->addRdata(generic::NS("ns.example.org.")); + rrsets_->addRRset(ns_); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + checkIssues(); + + // Note that if the NS name is the origin name, it should be checked + rrsets_->removeRRset(zname_, zclass_, RRType::NS()); + ns_.reset(new RRset(zname_, zclass_, RRType::NS(), RRTTL(60))); + ns_->addRdata(generic::NS(zname_)); + rrsets_->addRRset(ns_); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_warns_.push_back("zone example.com/IN: NS has no address"); + checkIssues(); +} + +TEST_F(ZoneCheckerTest, checkNSWithDelegation) { + // Tests various cases where there's a zone cut due to delegation between + // the zone origin and the NS name. In each case the NS name doesn't have + // an address record. + const Name ns_name("ns.child.example.com"); + + // Zone cut due to delegation in the middle; the check for the address + // record should be skipped. + rrsets_->removeRRset(zname_, zclass_, RRType::NS()); + ns_.reset(new RRset(zname_, zclass_, RRType::NS(), RRTTL(60))); + ns_->addRdata(generic::NS(ns_name)); + rrsets_->addRRset(ns_); + RRsetPtr child_ns(new RRset(Name("child.example.com"), zclass_, + RRType::NS(), RRTTL(60))); + child_ns->addRdata(generic::NS("ns.example.org.")); + rrsets_->addRRset(child_ns); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + checkIssues(); + + // Zone cut at the NS name. Same result. + rrsets_->removeRRset(child_ns->getName(), zclass_, RRType::NS()); + child_ns.reset(new RRset(ns_name, zclass_, RRType::NS(), RRTTL(60))); + child_ns->addRdata(generic::NS("ns.example.org.")); + rrsets_->addRRset(child_ns); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + checkIssues(); + + // Zone cut below the NS name. The check applies. + rrsets_->removeRRset(child_ns->getName(), zclass_, RRType::NS()); + child_ns.reset(new RRset(Name("another.ns.child.example.com"), zclass_, + RRType::NS(), RRTTL(60))); + child_ns->addRdata(generic::NS("ns.example.org.")); + rrsets_->addRRset(child_ns); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_warns_.push_back("zone example.com/IN: NS has no address"); + checkIssues(); +} + +TEST_F(ZoneCheckerTest, checkNSWithDNAME) { + // Similar to the above case, but the zone cut is due to DNAME. This is + // an invalid configuration. + const Name ns_name("ns.child.example.com"); + + // Zone cut due to DNAME at the zone origin. This is an invalid case. + rrsets_->removeRRset(zname_, zclass_, RRType::NS()); + ns_.reset(new RRset(zname_, zclass_, RRType::NS(), RRTTL(60))); + ns_->addRdata(generic::NS(ns_name)); + rrsets_->addRRset(ns_); + RRsetPtr dname(new RRset(zname_, zclass_, RRType::DNAME(), RRTTL(60))); + dname->addRdata(generic::DNAME("example.org.")); + rrsets_->addRRset(dname); + EXPECT_FALSE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_errors_.push_back("zone example.com/IN: NS 'ns.child.example.com'" + " is below a DNAME 'example.com'"); + checkIssues(); + + // Zone cut due to DNAME in the middle. Same result. + rrsets_->removeRRset(zname_, zclass_, RRType::DNAME()); + dname.reset(new RRset(Name("child.example.com"), zclass_, RRType::DNAME(), + RRTTL(60))); + dname->addRdata(generic::DNAME("example.org.")); + rrsets_->addRRset(dname); + EXPECT_FALSE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_errors_.push_back("zone example.com/IN: NS 'ns.child.example.com'" + " is below a DNAME 'child.example.com'"); + checkIssues(); + + // A tricky case: there's also an NS at the name that has DNAME. It's + // prohibited per RFC6672 so we could say it's "undefined". Nevertheless, + // this implementation prefers the NS and skips further checks. + ns_.reset(new RRset(Name("child.example.com"), zclass_, RRType::NS(), + RRTTL(60))); + ns_->addRdata(generic::NS("ns.example.org.")); + rrsets_->addRRset(ns_); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + checkIssues(); + + // Zone cut due to DNAME at the NS name. In this case DNAME doesn't + // affect the NS name, so it should result in "no address record" warning. + rrsets_->removeRRset(dname->getName(), zclass_, RRType::DNAME()); + rrsets_->removeRRset(ns_->getName(), zclass_, RRType::NS()); + dname.reset(new RRset(ns_name, zclass_, RRType::DNAME(), RRTTL(60))); + dname->addRdata(generic::DNAME("example.org.")); + rrsets_->addRRset(dname); + EXPECT_TRUE(checkZone(zname_, zclass_, *rrsets_, callbacks_)); + expected_warns_.push_back("zone example.com/IN: NS has no address"); + checkIssues(); +} + +} |