|
@@ -47,8 +47,8 @@ RRsetPtr glue_aaaa_rrset(RRsetPtr(new RRset(Name("glue.ns.example.com"),
|
|
|
RRClass::IN(), RRType::AAAA(),
|
|
|
RRTTL(3600))));
|
|
|
RRsetPtr noglue_a_rrset(RRsetPtr(new RRset(Name("noglue.example.com"),
|
|
|
- RRClass::IN(), RRType::A(),
|
|
|
- RRTTL(3600))));
|
|
|
+ RRClass::IN(), RRType::A(),
|
|
|
+ RRTTL(3600))));
|
|
|
// This is a mock Zone class for testing.
|
|
|
// It is a derived class of Zone, and simply hardcode the results of find()
|
|
|
// return SUCCESS for "www.example.com",
|
|
@@ -58,15 +58,19 @@ RRsetPtr noglue_a_rrset(RRsetPtr(new RRset(Name("noglue.example.com"),
|
|
|
// otherwise return DNAME
|
|
|
class MockZone : public Zone {
|
|
|
public:
|
|
|
- MockZone(bool has_SOA = true) :
|
|
|
+ MockZone(bool has_SOA = true, bool has_apex_NS = true) :
|
|
|
origin_(Name("example.com")),
|
|
|
has_SOA_(has_SOA),
|
|
|
+ has_apex_NS_(has_apex_NS),
|
|
|
delegation_rrset(RRsetPtr(new RRset(Name("delegation.example.com"),
|
|
|
RRClass::IN(), RRType::NS(),
|
|
|
RRTTL(3600)))),
|
|
|
cname_rrset(RRsetPtr(new RRset(Name("cname.example.com"),
|
|
|
RRClass::IN(), RRType::CNAME(),
|
|
|
- RRTTL(3600))))
|
|
|
+ RRTTL(3600)))),
|
|
|
+ auth_ns_rrset(RRsetPtr(new RRset(Name("example.com"),
|
|
|
+ RRClass::IN(), RRType::NS(),
|
|
|
+ RRTTL(3600))))
|
|
|
{
|
|
|
delegation_rrset->addRdata(rdata::generic::NS(
|
|
|
Name("glue.ns.example.com")));
|
|
@@ -78,6 +82,12 @@ public:
|
|
|
Name("example.org")));
|
|
|
cname_rrset->addRdata(rdata::generic::CNAME(
|
|
|
Name("www.example.com")));
|
|
|
+ auth_ns_rrset->addRdata(rdata::generic::NS(
|
|
|
+ Name("glue.ns.example.com")));
|
|
|
+ auth_ns_rrset->addRdata(rdata::generic::NS(
|
|
|
+ Name("noglue.example.com")));
|
|
|
+ auth_ns_rrset->addRdata(rdata::generic::NS(
|
|
|
+ Name("example.net")));
|
|
|
}
|
|
|
virtual const isc::dns::Name& getOrigin() const;
|
|
|
virtual const isc::dns::RRClass& getClass() const;
|
|
@@ -89,8 +99,10 @@ public:
|
|
|
private:
|
|
|
Name origin_;
|
|
|
bool has_SOA_;
|
|
|
+ bool has_apex_NS_;
|
|
|
RRsetPtr delegation_rrset;
|
|
|
RRsetPtr cname_rrset;
|
|
|
+ RRsetPtr auth_ns_rrset;
|
|
|
};
|
|
|
|
|
|
const Name&
|
|
@@ -113,7 +125,8 @@ MockZone::find(const Name& name, const RRType& type,
|
|
|
} else if (name == Name("glue.ns.example.com") && type == RRType::A() &&
|
|
|
options == FIND_GLUE_OK) {
|
|
|
return (FindResult(SUCCESS, glue_a_rrset));
|
|
|
- } else if (name == Name("noglue.example.com") && type == RRType::A()) {
|
|
|
+ } else if (name == Name("noglue.example.com") && (type == RRType::A() ||
|
|
|
+ type == RRType::ANY())) {
|
|
|
return (FindResult(SUCCESS, noglue_a_rrset));
|
|
|
} else if (name == Name("glue.ns.example.com") && type == RRType::AAAA() &&
|
|
|
options == FIND_GLUE_OK) {
|
|
@@ -122,6 +135,10 @@ MockZone::find(const Name& name, const RRType& type,
|
|
|
has_SOA_)
|
|
|
{
|
|
|
return (FindResult(SUCCESS, soa_rrset));
|
|
|
+ } else if (name == Name("example.com") && type == RRType::NS() &&
|
|
|
+ has_apex_NS_)
|
|
|
+ {
|
|
|
+ return (FindResult(SUCCESS, auth_ns_rrset));
|
|
|
} else if (name == Name("delegation.example.com")) {
|
|
|
return (FindResult(DELEGATION, delegation_rrset));
|
|
|
} else if (name == Name("ns.example.com")) {
|
|
@@ -157,24 +174,104 @@ protected:
|
|
|
TEST_F(QueryTest, noZone) {
|
|
|
// There's no zone in the memory datasource. So the response should have
|
|
|
// REFUSED.
|
|
|
- query.process();
|
|
|
+ EXPECT_NO_THROW(query.process());
|
|
|
EXPECT_EQ(Rcode::REFUSED(), response.getRcode());
|
|
|
}
|
|
|
|
|
|
-TEST_F(QueryTest, matchZone) {
|
|
|
+TEST_F(QueryTest, exactMatch) {
|
|
|
// add a matching zone.
|
|
|
memory_datasrc.addZone(ZonePtr(new MockZone()));
|
|
|
- query.process();
|
|
|
+ EXPECT_NO_THROW(query.process());
|
|
|
+ // find match rrset
|
|
|
EXPECT_TRUE(response.getHeaderFlag(Message::HEADERFLAG_AA));
|
|
|
EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
|
|
|
EXPECT_TRUE(response.hasRRset(Message::SECTION_ANSWER,
|
|
|
Name("www.example.com"), RRClass::IN(),
|
|
|
RRType::A()));
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
|
|
|
+ Name("example.com"), RRClass::IN(),
|
|
|
+ RRType::NS()));
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
|
|
|
+ Name("glue.ns.example.com"),
|
|
|
+ RRClass::IN(), RRType::A()));
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
|
|
|
+ Name("glue.ns.example.com"),
|
|
|
+ RRClass::IN(), RRType::AAAA()));
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
|
|
|
+ Name("noglue.example.com"),
|
|
|
+ RRClass::IN(), RRType::A()));
|
|
|
+}
|
|
|
|
|
|
- // Delegation
|
|
|
+TEST_F(QueryTest, exactAddrMatch) {
|
|
|
+ // find match rrset, omit additional data which has already been provided
|
|
|
+ // in the answer section from the additional.
|
|
|
+ memory_datasrc.addZone(ZonePtr(new MockZone()));
|
|
|
+ const Name noglue_name(Name("noglue.example.com"));
|
|
|
+ Query noglue_query(memory_datasrc, noglue_name, qtype, response);
|
|
|
+ EXPECT_NO_THROW(noglue_query.process());
|
|
|
+ EXPECT_TRUE(response.getHeaderFlag(Message::HEADERFLAG_AA));
|
|
|
+ EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_ANSWER,
|
|
|
+ Name("noglue.example.com"), RRClass::IN(),
|
|
|
+ RRType::A()));
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
|
|
|
+ Name("example.com"), RRClass::IN(),
|
|
|
+ RRType::NS()));
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
|
|
|
+ Name("glue.ns.example.com"),
|
|
|
+ RRClass::IN(), RRType::A()));
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
|
|
|
+ Name("glue.ns.example.com"),
|
|
|
+ RRClass::IN(), RRType::AAAA()));
|
|
|
+ EXPECT_FALSE(response.hasRRset(Message::SECTION_ADDITIONAL,
|
|
|
+ Name("noglue.example.com"),
|
|
|
+ RRClass::IN(), RRType::A()));
|
|
|
+}
|
|
|
+
|
|
|
+TEST_F(QueryTest, exactAnyMatch) {
|
|
|
+ // find match rrset, omit additional data which has already been provided
|
|
|
+ // in the answer section from the additional.
|
|
|
+ memory_datasrc.addZone(ZonePtr(new MockZone()));
|
|
|
+ const Name noglue_name(Name("noglue.example.com"));
|
|
|
+ Query noglue_query(memory_datasrc, noglue_name, RRType::ANY(), response);
|
|
|
+ EXPECT_NO_THROW(noglue_query.process());
|
|
|
+ EXPECT_TRUE(response.getHeaderFlag(Message::HEADERFLAG_AA));
|
|
|
+ EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_ANSWER,
|
|
|
+ Name("noglue.example.com"), RRClass::IN(),
|
|
|
+ RRType::A()));
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
|
|
|
+ Name("example.com"), RRClass::IN(),
|
|
|
+ RRType::NS()));
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
|
|
|
+ Name("glue.ns.example.com"),
|
|
|
+ RRClass::IN(), RRType::A()));
|
|
|
+ EXPECT_TRUE(response.hasRRset(Message::SECTION_ADDITIONAL,
|
|
|
+ Name("glue.ns.example.com"),
|
|
|
+ RRClass::IN(), RRType::AAAA()));
|
|
|
+ EXPECT_FALSE(response.hasRRset(Message::SECTION_ADDITIONAL,
|
|
|
+ Name("noglue.example.com"),
|
|
|
+ RRClass::IN(), RRType::A()));
|
|
|
+}
|
|
|
+
|
|
|
+// This tests that when we need to look up Zone's apex NS records for
|
|
|
+// authoritative answer, and there is no apex NS records. It should
|
|
|
+// throw in that case.
|
|
|
+TEST_F(QueryTest, noApexNS) {
|
|
|
+ // Add a zone without apex NS records
|
|
|
+ memory_datasrc.addZone(ZonePtr(new MockZone(true, false)));
|
|
|
+ const Name noglue_name(Name("noglue.example.com"));
|
|
|
+ Query noglue_query(memory_datasrc, noglue_name, qtype, response);
|
|
|
+ EXPECT_THROW(noglue_query.process(), Query::NoApexNS);
|
|
|
+ // We don't look into the response, as it throwed
|
|
|
+}
|
|
|
+
|
|
|
+TEST_F(QueryTest, delegation) {
|
|
|
+ // add a matching zone.
|
|
|
+ memory_datasrc.addZone(ZonePtr(new MockZone()));
|
|
|
const Name delegation_name(Name("delegation.example.com"));
|
|
|
Query delegation_query(memory_datasrc, delegation_name, qtype, response);
|
|
|
- delegation_query.process();
|
|
|
+ EXPECT_NO_THROW(delegation_query.process());
|
|
|
EXPECT_FALSE(response.getHeaderFlag(Message::HEADERFLAG_AA));
|
|
|
EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
|
|
|
EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
|
|
@@ -199,21 +296,27 @@ TEST_F(QueryTest, matchZone) {
|
|
|
EXPECT_FALSE(response.hasRRset(Message::SECTION_ADDITIONAL,
|
|
|
Name("example.org"),
|
|
|
RRClass::IN(), RRType::A()));
|
|
|
+}
|
|
|
|
|
|
- // NXDOMAIN
|
|
|
+TEST_F(QueryTest, nxdomain) {
|
|
|
+ // add a matching zone.
|
|
|
+ memory_datasrc.addZone(ZonePtr(new MockZone()));
|
|
|
const Name nxdomain_name(Name("nxdomain.example.com"));
|
|
|
Query nxdomain_query(memory_datasrc, nxdomain_name, qtype, response);
|
|
|
- nxdomain_query.process();
|
|
|
+ EXPECT_NO_THROW(nxdomain_query.process());
|
|
|
EXPECT_EQ(Rcode::NXDOMAIN(), response.getRcode());
|
|
|
EXPECT_EQ(0, response.getRRCount(Message::SECTION_ANSWER));
|
|
|
EXPECT_EQ(0, response.getRRCount(Message::SECTION_ADDITIONAL));
|
|
|
EXPECT_TRUE(response.hasRRset(Message::SECTION_AUTHORITY,
|
|
|
Name("example.com"), RRClass::IN(), RRType::SOA()));
|
|
|
+}
|
|
|
|
|
|
- // NXRRSET
|
|
|
+TEST_F(QueryTest, nxrrset) {
|
|
|
+ // add a matching zone.
|
|
|
+ memory_datasrc.addZone(ZonePtr(new MockZone()));
|
|
|
const Name nxrrset_name(Name("nxrrset.example.com"));
|
|
|
Query nxrrset_query(memory_datasrc, nxrrset_name, qtype, response);
|
|
|
- nxrrset_query.process();
|
|
|
+ EXPECT_NO_THROW(nxrrset_query.process());
|
|
|
EXPECT_EQ(Rcode::NOERROR(), response.getRcode());
|
|
|
EXPECT_EQ(0, response.getRRCount(Message::SECTION_ANSWER));
|
|
|
EXPECT_EQ(0, response.getRRCount(Message::SECTION_ADDITIONAL));
|