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

[1309] handled unexpected cases

parent 08127115
......@@ -169,9 +169,17 @@ Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
void
Query::addWildcardProof(ZoneFinder& finder) {
// The query name shouldn't exist in the zone if there were no wildcard
// substitution. Confirm that by specifying NO_WILDCARD. It should result
// in NXDOMAIN and an NSEC RR that proves it should be returned.
const ZoneFinder::FindResult fresult =
finder.find(qname_, RRType::NSEC(), NULL,
dnssec_opt_ | ZoneFinder::NO_WILDCARD);
if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
fresult.rrset->getRdataCount() == 0) {
isc_throw(BadNSEC, "Unexpected result for wildcard proof");
return;
}
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<RRset>(fresult.rrset),
dnssec_);
......@@ -269,6 +277,7 @@ Query::process() {
break;
}
case ZoneFinder::CNAME:
case ZoneFinder::WILDCARD_CNAME:
/*
* We don't do chaining yet. Therefore handling a CNAME is
* mostly the same as handling SUCCESS, but we didn't get
......@@ -281,6 +290,12 @@ Query::process() {
response_.addRRset(Message::SECTION_ANSWER,
boost::const_pointer_cast<RRset>(db_result.rrset),
dnssec_);
// If the answer is a result of wildcard substitution,
// add a proof that there's no closer name.
if (dnssec_ && db_result.code == ZoneFinder::WILDCARD_CNAME) {
addWildcardProof(*result.zone_finder);
}
break;
case ZoneFinder::SUCCESS:
case ZoneFinder::WILDCARD:
......
......@@ -99,7 +99,7 @@ const char* const nsec_wild_txt =
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. A NSEC RRSIG\n";
"3600 IN NSEC delegation.example.com. CNAME 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.,
......@@ -406,6 +406,17 @@ MockZoneFinder::find(const Name& name, const RRType& type,
return (FindResult(WILDCARD,
substituteWild(*found_rrset->second, name)));
}
const Name cnamewild_suffix("cnamewild.example.com");
if (name.compare(cnamewild_suffix).getRelation() ==
NameComparisonResult::SUBDOMAIN) {
domain = domains_.find(Name("*").concatenate(cnamewild_suffix));
assert(domain != domains_.end());
RRsetStore::const_iterator found_rrset =
domain->second.find(RRType::CNAME());
assert(found_rrset != domain->second.end());
return (FindResult(WILDCARD_CNAME,
substituteWild(*found_rrset->second, name)));
}
}
// This is an NXDOMAIN case.
......@@ -867,6 +878,52 @@ TEST_F(QueryTest, wildcardNSEC) {
mock_finder->getOrigin());
}
TEST_F(QueryTest, CNAMEwildNSEC) {
// Similar to the previous case, but the matching wildcard record is
// CNAME.
Query(memory_client, Name("www.cnamewild.example.com"), RRType::A(),
response, true).process();
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 2, 0,
(string(cnamewild_txt).replace(0, 1, "www") +
string("www.cnamewild.example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("CNAME") + "\n").c_str(),
(string(nsec_cnamewild_txt) +
string("*.cnamewild.example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("NSEC") + "\n").c_str(),
NULL, // we are not interested in additionals in this test
mock_finder->getOrigin());
}
TEST_F(QueryTest, badWildcardProof1) {
// Unexpected case in wildcard proof: ZoneFinder::find() returns SUCCESS
// when NXDOMAIN is expected.
mock_finder->setNSECResult(Name("www.wild.example.com"),
ZoneFinder::SUCCESS,
mock_finder->delegation_rrset_);
EXPECT_THROW(Query(memory_client, Name("www.wild.example.com"),
RRType::A(), response, true).process(),
Query::BadNSEC);
}
TEST_F(QueryTest, badWildcardProof2) {
// "wildcard proof" doesn't return RRset.
mock_finder->setNSECResult(Name("www.wild.example.com"),
ZoneFinder::NXDOMAIN, ConstRRsetPtr());
EXPECT_THROW(Query(memory_client, Name("www.wild.example.com"),
RRType::A(), response, true).process(),
Query::BadNSEC);
}
TEST_F(QueryTest, badWildcardProof3) {
// "wildcard proof" returns empty NSEC.
mock_finder->setNSECResult(Name("www.wild.example.com"),
ZoneFinder::NXDOMAIN,
mock_finder->empty_nsec_rrset_);
EXPECT_THROW(Query(memory_client, Name("www.wild.example.com"),
RRType::A(), response, true).process(),
Query::BadNSEC);
}
/*
* This tests that when there's no SOA and we need a negative answer. It should
* throw in that case.
......
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