[svn] commit: r4161 - in /trunk: ./ src/bin/auth/ src/bin/auth/tests/ src/bin/auth/tests/testdata/ src/bin/bind10/ src/bin/recurse/tests/ src/lib/asiolink/ src/lib/log/ src/lib/python/isc/utils/ src/lib/testutils/
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Jan 5 08:56:31 UTC 2011
Author: chenzhengzhang
Date: Wed Jan 5 08:56:31 2011
New Revision: 4161
Log:
merge #464(Additional processing for authoritative NS), which is a sub-task of authoritative query logic, skip changelog.
Modified:
trunk/ (props changed)
trunk/src/bin/auth/query.cc
trunk/src/bin/auth/query.h
trunk/src/bin/auth/tests/query_unittest.cc
trunk/src/bin/auth/tests/testdata/ (props changed)
trunk/src/bin/bind10/bind10.py.in (props changed)
trunk/src/bin/recurse/tests/ (props changed)
trunk/src/lib/asiolink/ (props changed)
trunk/src/lib/log/ (props changed)
trunk/src/lib/python/isc/utils/ (props changed)
trunk/src/lib/testutils/ (props changed)
Modified: trunk/src/bin/auth/query.cc
==============================================================================
--- trunk/src/bin/auth/query.cc (original)
+++ trunk/src/bin/auth/query.cc Wed Jan 5 08:56:31 2011
@@ -28,9 +28,7 @@
namespace auth {
void
-Query::getAdditional(const isc::datasrc::Zone& zone,
- const isc::dns::RRset& rrset) const
-{
+Query::getAdditional(const Zone& zone, const RRset& rrset) const {
if (rrset.getType() == RRType::NS()) {
// Need to perform the search in the "GLUE OK" mode.
RdataIteratorPtr rdata_iterator = rrset.getRdataIterator();
@@ -43,9 +41,8 @@
}
void
-Query::findAddrs(const isc::datasrc::Zone& zone,
- const isc::dns::Name& qname,
- const isc::datasrc::Zone::FindOptions options) const
+Query::findAddrs(const Zone& zone, const Name& qname,
+ const Zone::FindOptions options) const
{
// Out of zone name
NameComparisonResult result = zone.getOrigin().compare(qname);
@@ -53,17 +50,31 @@
(result.getRelation() != NameComparisonResult::EQUAL))
return;
+ // Omit additional data which has already been provided in the answer
+ // section from the additional.
+ //
+ // All the address rrset with the owner name of qname have been inserted
+ // into ANSWER section.
+ if (qname_ == qname && qtype_ == RRType::ANY())
+ return;
+
// Find A rrset
- Zone::FindResult a_result = zone.find(qname, RRType::A(), options);
- if (a_result.code == Zone::SUCCESS) {
- response_.addRRset(Message::SECTION_ADDITIONAL,
- boost::const_pointer_cast<RRset>(a_result.rrset));
+ if (qname_ != qname || qtype_ != RRType::A()) {
+ Zone::FindResult a_result = zone.find(qname, RRType::A(), options);
+ if (a_result.code == Zone::SUCCESS) {
+ response_.addRRset(Message::SECTION_ADDITIONAL,
+ boost::const_pointer_cast<RRset>(a_result.rrset));
+ }
}
+
// Find AAAA rrset
- Zone::FindResult aaaa_result = zone.find(qname, RRType::AAAA(), options);
- if (aaaa_result.code == Zone::SUCCESS) {
- response_.addRRset(Message::SECTION_ADDITIONAL,
- boost::const_pointer_cast<RRset>(aaaa_result.rrset));
+ if (qname_ != qname || qtype_ != RRType::AAAA()) {
+ Zone::FindResult aaaa_result =
+ zone.find(qname, RRType::AAAA(), options);
+ if (aaaa_result.code == Zone::SUCCESS) {
+ response_.addRRset(Message::SECTION_ADDITIONAL,
+ boost::const_pointer_cast<RRset>(aaaa_result.rrset));
+ }
}
}
@@ -82,6 +93,21 @@
*/
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<RRset>(soa_result.rrset));
+ }
+}
+
+void
+Query::getAuthAdditional(const Zone& zone) const {
+ // Fill in authority and addtional sections.
+ Zone::FindResult ns_result = zone.find(zone.getOrigin(), RRType::NS());
+ // zone origin name should have NS records
+ if (ns_result.code != Zone::SUCCESS) {
+ isc_throw(NoApexNS, "There's no apex NS records in zone " <<
+ zone.getOrigin().toText());
+ } else {
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<RRset>(ns_result.rrset));
+ getAdditional(zone, *ns_result.rrset);
}
}
@@ -112,8 +138,8 @@
case Zone::SUCCESS:
response_.setRcode(Rcode::NOERROR());
response_.addRRset(Message::SECTION_ANSWER,
- boost::const_pointer_cast<RRset>(db_result.rrset));
- // TODO : fill in authority and addtional sections.
+ boost::const_pointer_cast<RRset>(db_result.rrset));
+ getAuthAdditional(*result.zone);
break;
case Zone::DELEGATION:
response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
Modified: trunk/src/bin/auth/query.h
==============================================================================
--- trunk/src/bin/auth/query.h (original)
+++ trunk/src/bin/auth/query.h Wed Jan 5 08:56:31 2011
@@ -66,15 +66,19 @@
class Query {
private:
- /// \short Adds a SOA.
+ /// \brief Adds a SOA.
///
/// Adds a SOA of the zone into the authority zone of response_.
/// Can throw NoSOA.
///
void putSOA(const isc::datasrc::Zone& zone) const;
- /// Look up additional data (i.e., address records for the names included
- /// in NS or MX records).
+ /// \brief Look up additional data (i.e., address records for the names
+ /// included in NS or MX records).
+ ///
+ /// Note: Any additional data which has already been provided in the
+ /// answer section (i.e., if the original query happend to be for the
+ /// address of the DNS server), it should be omitted from the additional.
///
/// This method may throw a exception because its underlying methods may
/// throw exceptions.
@@ -86,7 +90,7 @@
void getAdditional(const isc::datasrc::Zone& zone,
const isc::dns::RRset& rrset) const;
- /// Find address records for a specified name.
+ /// \brief Find address records for a specified name.
///
/// Search the specified zone for AAAA/A RRs of each of the NS/MX RDATA
/// (domain name), and insert the found ones into the additional section
@@ -98,13 +102,33 @@
/// The glue records must exactly match the name in the NS RDATA, without
/// CNAME or wildcard processing.
///
- /// \param zone The Zone wherein the address records is to be found.
+ /// \param zone The \c Zone wherein the address records is to be found.
/// \param qname The name in rrset RDATA.
/// \param options The search options.
void findAddrs(const isc::datasrc::Zone& zone,
const isc::dns::Name& qname,
const isc::datasrc::Zone::FindOptions options
= isc::datasrc::Zone::FIND_DEFAULT) const;
+
+ /// \brief Look up \c Zone's NS and address records for the NS RDATA
+ /// (domain name) for authoritative answer.
+ ///
+ /// On returning an authoritative answer, insert the \c Zone's NS into the
+ /// authority section and AAAA/A RRs of each of the NS RDATA into the
+ /// additional section.
+ ///
+ /// <b>Notes to developer:</b>
+ ///
+ /// We should omit address records which has already been provided in the
+ /// answer section from the additional.
+ ///
+ /// For now, in order to optimize the additional section processing, we
+ /// include AAAA/A RRs under a zone cut in additional section. (BIND 9
+ /// excludes under-cut RRs; NSD include them.)
+ ///
+ /// \param zone The \c Zone wherein the additional data to the query is to
+ /// be found.
+ void getAuthAdditional(const isc::datasrc::Zone& zone) const;
public:
/// Constructor from query parameters.
@@ -173,6 +197,16 @@
{}
};
+ /// \short Zone is missing its apex NS records.
+ ///
+ /// We tried to add apex NS records into the authority section, but the
+ /// zone does not contain any.
+ struct NoApexNS: public BadZone {
+ NoApexNS(const char* file, size_t line, const char* what) :
+ BadZone(file, line, what)
+ {}
+ };
+
private:
const isc::datasrc::MemoryDataSrc& memory_datasrc_;
const isc::dns::Name& qname_;
Modified: trunk/src/bin/auth/tests/query_unittest.cc
==============================================================================
--- trunk/src/bin/auth/tests/query_unittest.cc (original)
+++ trunk/src/bin/auth/tests/query_unittest.cc Wed Jan 5 08:56:31 2011
@@ -47,8 +47,8 @@
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 @@
// 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 @@
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 @@
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 @@
} 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 @@
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 @@
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()));
-
- // Delegation
+ 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()));
+}
+
+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 @@
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));
More information about the bind10-changes
mailing list