Commit b8e5414e authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[master] Merge branch 'trac2480-2'

parents 60b979b7 aa32f38e
......@@ -1320,6 +1320,9 @@ AC_OUTPUT([doc/version.ent
src/bin/msgq/run_msgq.sh
src/bin/auth/auth.spec.pre
src/bin/auth/spec_config.h.pre
src/bin/auth/tests/testdata/example.zone
src/bin/auth/tests/testdata/example-base.zone
src/bin/auth/tests/testdata/example-nsec3.zone
src/bin/dhcp4/spec_config.h.pre
src/bin/dhcp6/spec_config.h.pre
src/bin/tests/process_rename_test.py
......
/run_unittests
/example_base_inc.cc
/example_nsec3_inc.cc
......@@ -7,7 +7,8 @@ AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CPPFLAGS += -DAUTH_OBJ_DIR=\"$(abs_top_builddir)/src/bin/auth\"
AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(abs_top_srcdir)/src/lib/testutils/testdata\"
AM_CPPFLAGS += -DTEST_OWN_DATA_DIR=\"$(abs_top_srcdir)/src/bin/auth/tests/testdata\"
AM_CPPFLAGS += -DTEST_OWN_DATA_DIR=\"$(abs_srcdir)/testdata\"
AM_CPPFLAGS += -DTEST_OWN_DATA_BUILDDIR=\"$(abs_builddir)/testdata\"
AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/testutils/testdata\"
AM_CPPFLAGS += -DDSRC_DIR=\"$(abs_top_builddir)/src/lib/datasrc\"
AM_CPPFLAGS += -DPLUGIN_DATA_PATH=\"$(abs_top_builddir)/src/bin/cfgmgr/plugins\"
......@@ -50,7 +51,6 @@ run_unittests_SOURCES += config_syntax_unittest.cc
run_unittests_SOURCES += command_unittest.cc
run_unittests_SOURCES += common_unittest.cc
run_unittests_SOURCES += query_unittest.cc
run_unittests_SOURCES += query_inmemory_unittest.cc
run_unittests_SOURCES += statistics_unittest.cc
run_unittests_SOURCES += test_datasrc_clients_mgr.h test_datasrc_clients_mgr.cc
run_unittests_SOURCES += datasrc_clients_builder_unittest.cc
......@@ -81,6 +81,40 @@ run_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libb10-threads.la
run_unittests_LDADD += $(GTEST_LDADD)
run_unittests_LDADD += $(SQLITE_LIBS)
# The following are definitions for auto-generating test data for query
# tests.
BUILT_SOURCES = example_base_inc.cc example_nsec3_inc.cc
BUILT_SOURCES += testdata/example-base.sqlite3
BUILT_SOURCES += testdata/example-nsec3.sqlite3
EXTRA_DIST = gen-query-testdata.py
CLEANFILES += example_base_inc.cc example_nsec3_inc.cc
example_base_inc.cc: $(srcdir)/testdata/example-base-inc.zone
$(PYTHON) $(srcdir)/gen-query-testdata.py \
$(srcdir)/testdata/example-base-inc.zone example_base_inc.cc
example_nsec3_inc.cc: $(srcdir)/testdata/example-nsec3-inc.zone
$(PYTHON) $(srcdir)/gen-query-testdata.py \
$(srcdir)/testdata/example-nsec3-inc.zone example_nsec3_inc.cc
testdata/example-base.sqlite3: testdata/example-base.zone
$(top_srcdir)/install-sh -c \
$(srcdir)/testdata/example-common-inc-template.zone \
testdata/example-common-inc.zone
$(SHELL) $(top_builddir)/src/bin/loadzone/run_loadzone.sh \
-c "{\"database_file\": \"$(builddir)/testdata/example-base.sqlite3\"}" \
example.com testdata/example-base.zone
testdata/example-nsec3.sqlite3: testdata/example-nsec3.zone
$(top_srcdir)/install-sh -c \
$(srcdir)/testdata/example-common-inc-template.zone \
testdata/example-common-inc.zone
$(SHELL) $(top_builddir)/src/bin/loadzone/run_loadzone.sh \
-c "{\"database_file\": \"$(builddir)/testdata/example-nsec3.sqlite3\"}" \
example.com testdata/example-nsec3.zone
check-local:
B10_FROM_BUILD=${abs_top_builddir} ./run_unittests
......
#!/usr/bin/env python3
# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
"""\
This is a supplemental script to auto generate test data in the form of
C++ source code from a DNS zone file.
Usage: python gen-query-testdata.py source_file output-cc-file
The usage doesn't matter much, though, because it's expected to be invoked
from Makefile, and that would be only use case of this script.
"""
import sys
import re
# Markup for variable definition
re_start_rr = re.compile('^;var=(.*)')
# Skip lines starting with ';' (comments) or empty lines. re_start_rr
# will also match this expression, so it should be checked first.
re_skip = re.compile('(^;)|(^\s*$)')
def parse_input(input_file):
'''Build an internal list of RR data from the input source file.
It generates a list of (variable_name, list of RR) tuples, where
variable_name is the expected C++ variable name for the subsequent RRs
if they are expected to be named. It can be an empty string if the RRs
are only expected to appear in the zone file.
The second element of the tuple is a list of strings, each of which
represents a single RR, e.g., "example.com 3600 IN A 192.0.2.1".
'''
result = []
rrs = None
with open(input_file) as f:
for line in f:
m = re_start_rr.match(line)
if m:
if rrs is not None:
result.append((rr_varname, rrs))
rrs = []
rr_varname = m.group(1)
elif re_skip.match(line):
continue
else:
rrs.append(line.rstrip('\n'))
# if needed, store the last RRs (they are not followed by 'var=' mark)
if rrs is not None:
result.append((rr_varname, rrs))
return result
def generate_variables(out_file, rrsets_data):
'''Generate a C++ source file containing a C-string variables for RRs.
This produces a definition of C-string for each RRset that is expected
to be named as follows:
const char* const var_name =
"example.com. 3600 IN A 192.0.2.1\n"
"example.com. 3600 IN A 192.0.2.2\n";
Escape character '\' in the string will be further escaped so it will
compile.
'''
with open(out_file, 'w') as out:
for (var_name, rrs) in rrsets_data:
if len(var_name) > 0:
out.write('const char* const ' + var_name + ' =\n')
# Combine all RRs, escaping '\' as a C-string
out.write('\n'.join([' \"%s\\n\"' %
(rr.replace('\\', '\\\\'))
for rr in rrs]))
out.write(';\n')
if __name__ == "__main__":
if len(sys.argv) < 3:
sys.stderr.write('gen-query-testdata.py require 2 args\n')
sys.exit(1)
rrsets_data = parse_input(sys.argv[1])
generate_variables(sys.argv[2], rrsets_data)
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <dns/name.h>
#include <dns/message.h>
#include <dns/rcode.h>
#include <dns/opcode.h>
#include <cc/data.h>
#include <datasrc/client_list.h>
#include <auth/query.h>
#include <testutils/dnsmessage_test.h>
#include <gtest/gtest.h>
#include <string>
using namespace isc::dns;
using namespace isc::auth;
using namespace isc::testutils;
using isc::datasrc::ConfigurableClientList;
using std::string;
namespace {
// The DNAME to do tests against
const char* const dname_txt =
"dname.example.com. 3600 IN DNAME "
"somethinglong.dnametarget.example.com.\n";
// This is not inside the zone, this is created at runtime
const char* const synthetized_cname_txt =
"www.dname.example.com. 3600 IN CNAME "
"www.somethinglong.dnametarget.example.com.\n";
// This is a subset of QueryTest using (subset of) the same test data, but
// with the production in-memory data source. Both tests should be eventually
// unified to avoid duplicates.
class InMemoryQueryTest : public ::testing::Test {
protected:
InMemoryQueryTest() : list(RRClass::IN()), response(Message::RENDER) {
response.setRcode(Rcode::NOERROR());
response.setOpcode(Opcode::QUERY());
list.configure(isc::data::Element::fromJSON(
"[{\"type\": \"MasterFiles\","
" \"cache-enable\": true, "
" \"params\": {\"example.com\": \"" +
string(TEST_OWN_DATA_DIR "/example.zone") +
"\"}}]"), true);
}
ConfigurableClientList list;
Message response;
Query query;
};
// A wrapper to check resulting response message commonly used in
// tests below.
// check_origin needs to be specified only when the authority section has
// an SOA RR. The interface is not generic enough but should be okay
// for our test cases in practice.
void
responseCheck(Message& response, const isc::dns::Rcode& rcode,
unsigned int flags, const unsigned int ancount,
const unsigned int nscount, const unsigned int arcount,
const char* const expected_answer,
const char* const expected_authority,
const char* const expected_additional,
const Name& check_origin = Name::ROOT_NAME())
{
// In our test cases QID, Opcode, and QDCOUNT should be constant, so
// we don't bother the test cases specifying these values.
headerCheck(response, response.getQid(), rcode, Opcode::QUERY().getCode(),
flags, 0, ancount, nscount, arcount);
if (expected_answer != NULL) {
rrsetsCheck(expected_answer,
response.beginSection(Message::SECTION_ANSWER),
response.endSection(Message::SECTION_ANSWER),
check_origin);
}
if (expected_authority != NULL) {
rrsetsCheck(expected_authority,
response.beginSection(Message::SECTION_AUTHORITY),
response.endSection(Message::SECTION_AUTHORITY),
check_origin);
}
if (expected_additional != NULL) {
rrsetsCheck(expected_additional,
response.beginSection(Message::SECTION_ADDITIONAL),
response.endSection(Message::SECTION_ADDITIONAL));
}
}
/*
* Test a query under a domain with DNAME. We should get a synthetized CNAME
* as well as the DNAME.
*
* TODO: Once we have CNAME chaining, check it works with synthetized CNAMEs
* as well. This includes tests pointing inside the zone, outside the zone,
* pointing to NXRRSET and NXDOMAIN cases (similarly as with CNAME).
*/
TEST_F(InMemoryQueryTest, DNAME) {
query.process(list, Name("www.dname.example.com"), RRType::A(),
response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 0, 0,
(string(dname_txt) + synthetized_cname_txt).c_str(),
NULL, NULL);
}
}
......@@ -12,10 +12,6 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <map>
#include <sstream>
#include <vector>
#include <boost/bind.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/static_assert.hpp>
......@@ -24,9 +20,12 @@
#include <dns/masterload.h>
#include <dns/message.h>
#include <dns/master_loader.h>
#include <dns/name.h>
#include <dns/nsec3hash.h>
#include <dns/opcode.h>
#include <dns/rcode.h>
#include <dns/rrcollator.h>
#include <dns/rrttl.h>
#include <dns/rrtype.h>
#include <dns/rdataclass.h>
......@@ -40,6 +39,12 @@
#include <gtest/gtest.h>
#include <cstdlib>
#include <fstream>
#include <map>
#include <sstream>
#include <vector>
using namespace std;
using namespace isc::dns;
using namespace isc::dns::rdata;
......@@ -49,7 +54,7 @@ using namespace isc::testutils;
namespace {
// Simple wrapper for a sincle data source client.
// Simple wrapper for a single data source client.
// The list simply delegates all the answers to the single
// client.
class SingletonList : public ClientList {
......@@ -79,150 +84,21 @@ private:
DataSourceClient& client_;
};
// These are commonly used data (auto-generated). There are some exceptional
// data that are only used in a limited scenario, which are defined separately
// below.
#include <auth/tests/example_base_inc.cc>
#include <auth/tests/example_nsec3_inc.cc>
// This is the content of the mock zone (see below).
// It's a sequence of textual RRs that is supposed to be parsed by
// dns::masterLoad(). Some of the RRs are also used as the expected
// data in specific tests, in which case they are referenced via specific
// local variables (such as soa_txt).
//
// For readability consistency, all strings are placed in a separate line,
// even if they are very short and can reasonably fit in a single line with
// the corresponding variable. For example, we write
// const char* const foo_txt =
// "foo.example.com. 3600 IN AAAA 2001:db8::1\n";
// instead of
// const char* const foo_txt = "foo.example.com. 3600 IN AAAA 2001:db8::1\n";
const char* const soa_txt =
"example.com. 3600 IN SOA . . 0 0 0 0 0\n";
const char* const zone_ns_txt =
"example.com. 3600 IN NS glue.delegation.example.com.\n"
"example.com. 3600 IN NS noglue.example.com.\n"
"example.com. 3600 IN NS example.net.\n";
// This is used only in one pathological test case.
const char* const zone_ds_txt =
"example.com. 3600 IN DS 57855 5 1 "
"B6DCD485719ADCA18E5F3D48A2331627FDD3 636B\n";
const char* const ns_addrs_txt =
"glue.delegation.example.com. 3600 IN A 192.0.2.153\n"
"glue.delegation.example.com. 3600 IN AAAA 2001:db8::53\n"
"noglue.example.com. 3600 IN A 192.0.2.53\n";
const char* const delegation_txt =
"delegation.example.com. 3600 IN NS glue.delegation.example.com.\n"
"delegation.example.com. 3600 IN NS noglue.example.com.\n"
"delegation.example.com. 3600 IN NS cname.example.com.\n"
"delegation.example.com. 3600 IN NS example.org.\n";
// Borrowed from the RFC4035
const char* const delegation_ds_txt =
"delegation.example.com. 3600 IN DS 57855 5 1 "
"B6DCD485719ADCA18E5F3D48A2331627FDD3 636B\n";
const char* const mx_txt =
"mx.example.com. 3600 IN MX 10 www.example.com.\n"
"mx.example.com. 3600 IN MX 20 mailer.example.org.\n"
"mx.example.com. 3600 IN MX 30 mx.delegation.example.com.\n";
const char* const www_a_txt =
"www.example.com. 3600 IN A 192.0.2.80\n";
const char* const cname_txt =
"cname.example.com. 3600 IN CNAME www.example.com.\n";
const char* const cname_nxdom_txt =
"cnamenxdom.example.com. 3600 IN CNAME nxdomain.example.com.\n";
// CNAME Leading out of zone
const char* const cname_out_txt =
"cnameout.example.com. 3600 IN CNAME www.example.org.\n";
// The DNAME to do tests against
const char* const dname_txt =
"dname.example.com. 3600 IN DNAME "
"somethinglong.dnametarget.example.com.\n";
// Some data at the dname node (allowed by RFC 2672)
const char* const dname_a_txt =
"dname.example.com. 3600 IN A 192.0.2.5\n";
// This is not inside the zone, this is created at runtime
const char* const synthetized_cname_txt =
"www.dname.example.com. 3600 IN CNAME "
"www.somethinglong.dnametarget.example.com.\n";
// The rest of data won't be referenced from the test cases.
const char* const other_zone_rrs =
"cnamemailer.example.com. 3600 IN CNAME www.example.com.\n"
"cnamemx.example.com. 3600 IN MX 10 cnamemailer.example.com.\n"
"mx.delegation.example.com. 3600 IN A 192.0.2.100\n";
// Wildcards
const char* const wild_txt =
"*.wild.example.com. 3600 IN A 192.0.2.7\n";
const char* const nsec_wild_txt =
"*.wild.example.com. 3600 IN NSEC www.example.com. A NSEC RRSIG\n";
const char* const cnamewild_txt =
"*.cnamewild.example.com. 3600 IN CNAME www.example.org.\n";
const char* const nsec_cnamewild_txt =
"*.cnamewild.example.com. 3600 IN NSEC "
"delegation.example.com. CNAME NSEC RRSIG\n";
// Wildcard_nxrrset
const char* const wild_txt_nxrrset =
"*.uwild.example.com. 3600 IN A 192.0.2.9\n";
const char* const nsec_wild_txt_nxrrset =
"*.uwild.example.com. 3600 IN NSEC www.uwild.example.com. A NSEC RRSIG\n";
const char* const wild_txt_next =
"www.uwild.example.com. 3600 IN A 192.0.2.11\n";
const char* const nsec_wild_txt_next =
"www.uwild.example.com. 3600 IN NSEC *.wild.example.com. A NSEC RRSIG\n";
// Wildcard empty
const char* const empty_txt =
"b.*.t.example.com. 3600 IN A 192.0.2.13\n";
const char* const nsec_empty_txt =
"b.*.t.example.com. 3600 IN NSEC *.uwild.example.com. A NSEC RRSIG\n";
const char* const empty_prev_txt =
"t.example.com. 3600 IN A 192.0.2.15\n";
const char* const nsec_empty_prev_txt =
"t.example.com. 3600 IN NSEC b.*.t.example.com. A NSEC RRSIG\n";
// Used in NXDOMAIN proof test. We are going to test some unusual case where
// the best possible wildcard is below the "next domain" of the NSEC RR that
// proves the NXDOMAIN, i.e.,
// mx.example.com. (exist)
// (.no.example.com. (qname, NXDOMAIN)
// ).no.example.com. (exist)
// *.no.example.com. (best possible wildcard, not exist)
const char* const no_txt =
").no.example.com. 3600 IN AAAA 2001:db8::53\n";
// NSEC records.
const char* const nsec_apex_txt =
"example.com. 3600 IN NSEC cname.example.com. NS SOA NSEC RRSIG\n";
const char* const nsec_mx_txt =
"mx.example.com. 3600 IN NSEC ).no.example.com. MX NSEC RRSIG\n";
const char* const nsec_no_txt =
").no.example.com. 3600 IN NSEC nz.no.example.com. AAAA NSEC RRSIG\n";
// We'll also test the case where a single NSEC proves both NXDOMAIN and the
// non existence of wildcard. The following records will be used for that
// test.
// ).no.example.com. (exist, whose NSEC proves everything)
// *.no.example.com. (best possible wildcard, not exist)
// nx.no.example.com. (NXDOMAIN)
// nz.no.example.com. (exist)
const char* const nz_txt =
"nz.no.example.com. 3600 IN AAAA 2001:db8::5300\n";
const char* const nsec_nz_txt =
"nz.no.example.com. 3600 IN NSEC noglue.example.com. AAAA NSEC RRSIG\n";
const char* const nsec_nxdomain_txt =
"noglue.example.com. 3600 IN NSEC nonsec.example.com. A\n";
// NSEC for the normal NXRRSET case
const char* const nsec_www_txt =
"www.example.com. 3600 IN NSEC example.com. A NSEC RRSIG\n";
// Authoritative data without NSEC
const char* const nonsec_a_txt =
"nonsec.example.com. 3600 IN A 192.0.2.0\n";
// NSEC3 RRs. You may also need to add mapping to MockZoneFinder::hash_map_.
const string nsec3_apex_txt =
"0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example.com. 3600 IN NSEC3 1 1 12 "
"aabbccdd 2t7b4g4vsa5smi47k61mv5bv1a22bojr NS SOA NSEC3PARAM RRSIG\n";
const string nsec3_apex_rrsig_txt =
"0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example.com. 3600 IN RRSIG NSEC3 5 3 "
"3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE";
const string nsec3_www_txt =
"q04jkcevqvmu85r014c7dkba38o0ji5r.example.com. 3600 IN NSEC3 1 1 12 "
"aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG\n";
const string nsec3_www_rrsig_txt =
"q04jkcevqvmu85r014c7dkba38o0ji5r.example.com. 3600 IN RRSIG NSEC3 5 3 "
"3600 20000101000000 20000201000000 12345 example.com. FAKEFAKEFAKE";
// NSEC3 for wild.example.com (used in wildcard tests, will be added on
// demand not to confuse other tests)
......@@ -246,42 +122,13 @@ const char* const nsec3_uwild_txt =
"t644ebqk9bibcna874givr6joj62mlhv.example.com. 3600 IN NSEC3 1 1 12 "
"aabbccdd r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG\n";
// (Secure) delegation data; Delegation with DS record
const char* const signed_delegation_txt =
"signed-delegation.example.com. 3600 IN NS ns.example.net.\n";
const char* const signed_delegation_ds_txt =
"signed-delegation.example.com. 3600 IN DS 12345 8 2 "
"764501411DE58E8618945054A3F620B36202E115D015A7773F4B78E0F952CECA\n";
// (Secure) delegation data; Delegation without DS record (and both NSEC
// and NSEC3 denying its existence)
const char* const unsigned_delegation_txt =
"unsigned-delegation.example.com. 3600 IN NS ns.example.net.\n";
const char* const unsigned_delegation_nsec_txt =
"unsigned-delegation.example.com. 3600 IN NSEC "
"unsigned-delegation-optout.example.com. NS RRSIG NSEC\n";
// This one will be added on demand
const char* const unsigned_delegation_nsec3_txt =
"q81r598950igr1eqvc60aedlq66425b5.example.com. 3600 IN NSEC3 1 1 12 "
"aabbccdd 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom NS RRSIG\n";
// Delegation without DS record, and no direct matching NSEC3 record
const char* const unsigned_delegation_optout_txt =
"unsigned-delegation-optout.example.com. 3600 IN NS ns.example.net.\n";
const char* const unsigned_delegation_optout_nsec_txt =
"unsigned-delegation-optout.example.com. 3600 IN NSEC "
"*.uwild.example.com. NS RRSIG NSEC\n";
// (Secure) delegation data; Delegation where the DS lookup will raise an
// exception.
const char* const bad_delegation_txt =
"bad-delegation.example.com. 3600 IN NS ns.example.net.\n";
// Delegation from an unsigned parent. There's no DS, and there's no NSEC
// or NSEC3 that proves it.
const char* const nosec_delegation_txt =
"nosec-delegation.example.com. 3600 IN NS ns.nosec.example.net.\n";
// A helper function that generates a textual representation of RRSIG RDATA
// for the given covered type. The resulting RRSIG may not necessarily make
// sense in terms of the DNSSEC protocol, but for our testing purposes it's
......@@ -314,58 +161,14 @@ textToRRset(const string& text_rrset, const Name& origin = Name::ROOT_NAME()) {
return (rrset);
}
// This is a mock Zone Finder class for testing.
// It is a derived class of ZoneFinder for the convenient of tests.
// Its find() method emulates the common behavior of protocol compliant
// ZoneFinder classes, but simplifies some minor cases and also supports broken
// behavior.
// For simplicity, most names are assumed to be "in zone"; delegations
// to child zones are identified by the existence of non origin NS records.
// Another special name is "dname.example.com". Query names under this name
// will result in DNAME.
// This mock zone doesn't handle empty non terminal nodes (if we need to test
// such cases find() should have specialized code for it).
class MockZoneFinder : public ZoneFinder {
// Setup for faked NSEC3 hash used throughout this test.
class TestNSEC3Hash : public NSEC3Hash {
private:
typedef map<Name, string> NSEC3HashMap;
typedef NSEC3HashMap::value_type NSEC3HashPair;
NSEC3HashMap hash_map_;
public:
MockZoneFinder() :
origin_(Name("example.com")),
bad_signed_delegation_name_("bad-delegation.example.com"),
dname_name_("dname.example.com"),
has_SOA_(true),
has_apex_NS_(true),
rrclass_(RRClass::IN()),
include_rrsig_anyway_(false),
use_nsec3_(false),
nsec_name_(origin_),
nsec3_fake_(NULL),
nsec3_name_(NULL)
{
stringstream zone_stream;
zone_stream << soa_txt << zone_ns_txt << ns_addrs_txt <<
delegation_txt << delegation_ds_txt << mx_txt << www_a_txt <<
cname_txt << cname_nxdom_txt << cname_out_txt << dname_txt <<
dname_a_txt << other_zone_rrs << no_txt << nz_txt <<
nsec_apex_txt << nsec_mx_txt << nsec_no_txt << nsec_nz_txt <<
nsec_nxdomain_txt << nsec_www_txt << nonsec_a_txt <<
wild_txt << nsec_wild_txt << cnamewild_txt << nsec_cnamewild_txt <<
wild_txt_nxrrset << nsec_wild_txt_nxrrset << wild_txt_next <<
nsec_wild_txt_next << empty_txt << nsec_empty_txt <<
empty_prev_txt << nsec_empty_prev_txt <<
nsec3_apex_txt << nsec3_www_txt <<
signed_delegation_txt << signed_delegation_ds_txt <<
unsigned_delegation_txt << unsigned_delegation_nsec_txt <<
unsigned_delegation_optout_txt <<
unsigned_delegation_optout_nsec_txt <<
bad_delegation_txt << nosec_delegation_txt;
masterLoad(zone_stream, origin_, rrclass_,
boost::bind(&MockZoneFinder::loadRRset, this, _1));
empty_nsec_rrset_ = ConstRRsetPtr(new RRset(Name::ROOT_NAME(),
RRClass::IN(),
RRType::NSEC(),
RRTTL(3600)));
TestNSEC3Hash() {
// (Faked) NSEC3 hash map. For convenience we use hardcoded built-in
// map instead of calculating and using actual hash.
// The used hash values are borrowed from RFC5155 examples (they are
......@@ -411,6 +214,79 @@ public:
hash_map_[Name("www1.uwild.example.com")] =
"q04jkcevqvmu85r014c7dkba38o0ji6r"; // a bit larger than H(www)
}
virtual string calculate(const Name& name) const {
const NSEC3HashMap::const_iterator found = ha