Commit 1d3d7c59 authored by JINMEI Tatuya's avatar JINMEI Tatuya

[1607] implemented basic cases of getAdditional() and tests.

parent 3e88cb09
;; test zone file used for ZoneFinderContext tests.
;; RRSIGs are (obviouslly) faked ones for testing.
example.org. 3600 IN SOA ns1.example.org. bugs.x.w.example.org. 9 3600 300 3600000 3600
example.org. 3600 IN SOA ns1.example.org. bugs.x.w.example.org. 20 3600 300 3600000 3600
example.org. 3600 IN NS ns1.example.org.
example.org. 3600 IN NS ns2.example.org.
example.org. 3600 IN MX 1 mx1.example.org.
example.org. 3600 IN MX 2 mx2.example.org.
example.org. 3600 IN MX 3 mx.a.example.org.
ns1.example.org. 3600 IN A 192.0.2.1
ns1.example.org. 3600 IN RRSIG A 7 3 3600 20150420235959 20051021000000 40430 example.org. FAKEFAKE
ns1.example.org. 3600 IN AAAA 2001:db8::1
ns1.example.org. 3600 IN RRSIG AAAA 7 3 3600 20150420235959 20051021000000 40430 example.org. FAKEFAKEFAKE
ns2.example.org. 3600 IN A 192.0.2.2
ns2.example.org. 3600 IN TXT "text data"
mx1.example.org. 3600 IN A 192.0.2.10
mx2.example.org. 3600 IN AAAA 2001:db8::10
......@@ -16,7 +21,9 @@ mx2.example.org. 3600 IN AAAA 2001:db8::10
;; delegation
a.example.org. 3600 IN NS ns1.a.example.org.
a.example.org. 3600 IN NS ns2.a.example.org.
a.example.org. 3600 IN NS ns.example.com.
ns1.a.example.org. 3600 IN A 192.0.2.5
ns2.a.example.org. 3600 IN A 192.0.2.6
ns2.a.example.org. 3600 IN AAAA 2001:db8::6
mx.a.example.org. 3600 IN A 192.0.2.7
......@@ -21,17 +21,23 @@
#include <datasrc/database.h>
#include <datasrc/sqlite3_accessor.h>
#include <testutils/dnsmessage_test.h>
#include <gtest/gtest.h>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <boost/shared_ptr.hpp>
#include <cstdlib>
#include <vector>
using namespace std;
using boost::shared_ptr;
using namespace isc::dns;
using namespace isc::datasrc;
using boost::shared_ptr;
using namespace isc::testutils;
namespace {
......@@ -88,6 +94,12 @@ createSQLite3Client(RRClass zclass, const Name& zname) {
ZoneUpdaterPtr updater = client->getUpdater(zname, true);
masterLoad(TEST_ZONE_FILE, zname, zclass, boost::bind(addRRset, updater,
_1));
// Insert an out-of-zone name to test if it's incorrectly returned.
// Note that neither updater nor SQLite3 accessor checks this condition,
// so this should succeed.
stringstream ss("ns.example.com. 3600 IN A 192.0.2.7");
masterLoad(ss, Name::ROOT_NAME(), zclass,
boost::bind(addRRset, updater, _1));
updater->commit();
return (client);
......@@ -101,12 +113,22 @@ class ZoneFinderContextTest :
protected:
ZoneFinderContextTest() : qclass_(RRClass::IN()), qzone_("example.org") {
client_ = (*GetParam())(qclass_, qzone_);
REQUESTED_A.push_back(RRType::A());
REQUESTED_AAAA.push_back(RRType::AAAA());
REQUESTED_BOTH.push_back(RRType::A());
REQUESTED_BOTH.push_back(RRType::AAAA());
}
const RRClass qclass_;
const Name qzone_;
DataSourceClientPtr client_;
ZoneFinderPtr finder_;
vector<RRType> requested_types_;
vector<RRType> REQUESTED_A;
vector<RRType> REQUESTED_AAAA;
vector<RRType> REQUESTED_BOTH;
vector<ConstRRsetPtr> result_sets_;
};
// We test the in-memory and SQLite3 data source implementations.
......@@ -114,9 +136,135 @@ INSTANTIATE_TEST_CASE_P(, ZoneFinderContextTest,
::testing::Values(createInMemoryClient,
createSQLite3Client));
TEST_P(ZoneFinderContextTest, getAdditional) {
finder_ = client_->findZone(Name("www.a.example.org")).zone_finder;
TEST_P(ZoneFinderContextTest, getAdditionalAuthNS) {
finder_ = client_->findZone(qzone_).zone_finder;
ASSERT_TRUE(finder_);
ZoneFinderContextPtr ctx = finder_->find(qzone_, RRType::NS());
EXPECT_EQ(ZoneFinder::SUCCESS, ctx->code);
// Getting both A and AAAA NS addresses
ctx->getAdditional(REQUESTED_BOTH, result_sets_);
rrsetsCheck("ns1.example.org. 3600 IN A 192.0.2.1\n"
"ns1.example.org. 3600 IN AAAA 2001:db8::1\n"
"ns2.example.org. 3600 IN A 192.0.2.2\n",
result_sets_.begin(), result_sets_.end());
// Getting only A
result_sets_.clear();
ctx->getAdditional(REQUESTED_A, result_sets_);
rrsetsCheck("ns1.example.org. 3600 IN A 192.0.2.1\n"
"ns2.example.org. 3600 IN A 192.0.2.2\n",
result_sets_.begin(), result_sets_.end());
// Getting only AAAA
result_sets_.clear();
ctx->getAdditional(REQUESTED_AAAA, result_sets_);
rrsetsCheck("ns1.example.org. 3600 IN AAAA 2001:db8::1\n",
result_sets_.begin(), result_sets_.end());
// Normally expected type set contain only A and/or AAAA, but others aren't
// excluded.
result_sets_.clear();
requested_types_.push_back(RRType::TXT());
ctx->getAdditional(requested_types_, result_sets_);
rrsetsCheck("ns2.example.org. 3600 IN TXT \"text data\"",
result_sets_.begin(), result_sets_.end());
// Even empty set is okay. The result should also be empty.
result_sets_.clear();
ctx->getAdditional(vector<RRType>(), result_sets_);
EXPECT_TRUE(result_sets_.empty());
}
TEST_P(ZoneFinderContextTest, getAdditionalDelegation) {
// Basically similar to the AuthNS case, but NS names are glues.
// It contains an out-of-zone NS name. Its address (even if it's somehow
// inserted to the zone data) shouldn't be returned.
const Name qname("www.a.example.org");
finder_ = client_->findZone(qname).zone_finder;
ASSERT_TRUE(finder_);
ZoneFinderContextPtr ctx = finder_->find(qname, RRType::AAAA());
EXPECT_EQ(ZoneFinder::DELEGATION, ctx->code);
ctx->getAdditional(REQUESTED_BOTH, result_sets_);
rrsetsCheck("ns1.a.example.org. 3600 IN A 192.0.2.5\n"
"ns2.a.example.org. 3600 IN A 192.0.2.6\n"
"ns2.a.example.org. 3600 IN AAAA 2001:db8::6\n",
result_sets_.begin(), result_sets_.end());
result_sets_.clear();
ctx->getAdditional(REQUESTED_A, result_sets_);
rrsetsCheck("ns1.a.example.org. 3600 IN A 192.0.2.5\n"
"ns2.a.example.org. 3600 IN A 192.0.2.6\n",
result_sets_.begin(), result_sets_.end());
result_sets_.clear();
ctx->getAdditional(REQUESTED_AAAA, result_sets_);
rrsetsCheck("ns2.a.example.org. 3600 IN AAAA 2001:db8::6\n",
result_sets_.begin(), result_sets_.end());
}
TEST_P(ZoneFinderContextTest, getAdditionalMX) {
// Similar to the previous cases, but for MX addresses. The test zone
// contains MX name under a zone cut. Its address shouldn't be returned.
finder_ = client_->findZone(qzone_).zone_finder;
ASSERT_TRUE(finder_);
ZoneFinderContextPtr ctx = finder_->find(qzone_, RRType::MX());
EXPECT_EQ(ZoneFinder::SUCCESS, ctx->code);
// Getting both A and AAAA NS addresses
ctx->getAdditional(REQUESTED_BOTH, result_sets_);
rrsetsCheck("mx1.example.org. 3600 IN A 192.0.2.10\n"
"mx2.example.org. 3600 IN AAAA 2001:db8::10\n",
result_sets_.begin(), result_sets_.end());
// Getting only A
result_sets_.clear();
ctx->getAdditional(REQUESTED_A, result_sets_);
rrsetsCheck("mx1.example.org. 3600 IN A 192.0.2.10\n",
result_sets_.begin(), result_sets_.end());
// Getting only AAAA
result_sets_.clear();
ctx->getAdditional(REQUESTED_AAAA, result_sets_);
rrsetsCheck("mx2.example.org. 3600 IN AAAA 2001:db8::10\n",
result_sets_.begin(), result_sets_.end());
}
TEST_P(ZoneFinderContextTest, getAdditionalWithSIG) {
// Similar to the AuthNS test, but the original find() requested DNSSEC
// RRSIGs. Then additional records will also have RRSIGs.
finder_ = client_->findZone(qzone_).zone_finder;
ASSERT_TRUE(finder_);
ZoneFinderContextPtr ctx = finder_->find(qzone_, RRType::NS(),
ZoneFinder::FIND_DNSSEC);
EXPECT_EQ(ZoneFinder::SUCCESS, ctx->code);
ctx->getAdditional(REQUESTED_BOTH, result_sets_);
rrsetsCheck("ns1.example.org. 3600 IN A 192.0.2.1\n"
"ns1.example.org. 3600 IN AAAA 2001:db8::1\n"
"ns2.example.org. 3600 IN A 192.0.2.2\n",
result_sets_.begin(), result_sets_.end());
vector<ConstRRsetPtr> sigresult_sets;
BOOST_FOREACH(ConstRRsetPtr rrset, result_sets_) {
ConstRRsetPtr sig_rrset = rrset->getRRsig();
if (sig_rrset) {
sigresult_sets.push_back(sig_rrset);
}
}
rrsetsCheck("ns1.example.org. 3600 IN RRSIG A 7 3 3600 20150420235959 "
"20051021000000 40430 example.org. FAKEFAKE\n"
"ns1.example.org. 3600 IN RRSIG AAAA 7 3 3600 20150420235959 "
"20051021000000 40430 example.org. FAKEFAKEFAKEFAKE\n",
sigresult_sets.begin(), sigresult_sets.end());
}
}
......@@ -15,9 +15,12 @@
#include <dns/rdata.h>
#include <dns/rrset.h>
#include <dns/rrtype.h>
#include <dns/rdataclass.h>
#include <datasrc/zone.h>
#include <boost/foreach.hpp>
#include <vector>
using namespace std;
......@@ -27,10 +30,50 @@ using namespace isc::dns::rdata;
namespace isc {
namespace datasrc {
namespace {
void
ZoneFinder::Context::getAdditional(const vector<RRType>& /*requested_types*/,
vector<ConstRRsetPtr>& /*result*/)
getAdditionalAddrs(ZoneFinder& finder, const Name& name,
const vector<RRType>& requested_types,
vector<ConstRRsetPtr>& result_rrsets,
ZoneFinder::FindOptions options)
{
// Ignore out-of-zone names
const NameComparisonResult cmp = finder.getOrigin().compare(name);
if ((cmp.getRelation() != NameComparisonResult::SUPERDOMAIN) &&
(cmp.getRelation() != NameComparisonResult::EQUAL)) {
return;
}
BOOST_FOREACH(RRType rrtype, requested_types) {
ConstZoneFinderContextPtr ctx = finder.find(name, rrtype, options);
if (ctx->code == ZoneFinder::SUCCESS) {
result_rrsets.push_back(ctx->rrset);
}
}
}
}
void
ZoneFinder::Context::getAdditional(const vector<RRType>& requested_types,
vector<ConstRRsetPtr>& result)
{
RdataIteratorPtr rdata_iterator(rrset->getRdataIterator());
ZoneFinder::FindOptions options = ZoneFinder::FIND_DEFAULT;
for (; !rdata_iterator->isLast(); rdata_iterator->next()) {
const Rdata& rdata(rdata_iterator->getCurrent());
if (rrset->getType() == RRType::NS()) {
// Need to perform the search in the "GLUE OK" mode.
const generic::NS& ns = dynamic_cast<const generic::NS&>(rdata);
getAdditionalAddrs(finder_, ns.getNSName(), requested_types,
result, options | ZoneFinder::FIND_GLUE_OK);
} else if (rrset->getType() == RRType::MX()) {
const generic::MX& mx = dynamic_cast<const generic::MX&>(rdata);
getAdditionalAddrs(finder_, mx.getMXName(), requested_types,
result, options);
}
}
}
} // namespace datasrc
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment