From cbddeb5ad8ecb4d3ef403943e588fa2c858b0d3b Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Fri, 9 Dec 2011 19:18:20 +0100 Subject: [PATCH 01/12] [1438] Strip the datasources of target parameter Is is being deprecated by a separate method in this branch, so get rid of it. --- src/lib/datasrc/database.cc | 3 +- src/lib/datasrc/database.h | 6 -- src/lib/datasrc/memory_datasrc.cc | 11 ++-- src/lib/datasrc/memory_datasrc.h | 1 - src/lib/datasrc/tests/database_unittest.cc | 35 ++++++----- .../datasrc/tests/memory_datasrc_unittest.cc | 59 +++++++++++-------- src/lib/datasrc/zone.h | 6 -- 7 files changed, 60 insertions(+), 61 deletions(-) diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc index 45ce0c2562..13ae3cd92a 100644 --- a/src/lib/datasrc/database.cc +++ b/src/lib/datasrc/database.cc @@ -393,7 +393,6 @@ DatabaseClient::Finder::findNSECCover(const Name& name) { ZoneFinder::FindResult DatabaseClient::Finder::find(const isc::dns::Name& name, const isc::dns::RRType& type, - isc::dns::RRsetList*, const FindOptions options) { // This variable is used to determine the difference between @@ -729,7 +728,7 @@ public: // Find the SOA of the zone (may or may not succeed). Note that // this must be done before starting the iteration context. soa_ = DatabaseClient::Finder(accessor_, zone.second, zone_name). - find(zone_name, RRType::SOA(), NULL).rrset; + find(zone_name, RRType::SOA()).rrset; // Request the context context_ = accessor_->getAllRecords(zone.second); diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h index 81e6241149..615ff1e4d7 100644 --- a/src/lib/datasrc/database.h +++ b/src/lib/datasrc/database.h @@ -753,10 +753,6 @@ public: * (this implementation is not complete, and currently only * does full matches, CNAMES, and the signatures for matches and * CNAMEs) - * \note target was used in the original design to handle ANY - * queries. This is not implemented yet, and may use - * target again for that, but it might also use something - * different. It is left in for compatibility at the moment. * \note options are ignored at this moment * * \note Maybe counter intuitively, this method is not a const member @@ -780,13 +776,11 @@ public: * * \param name The name to find * \param type The RRType to find - * \param target Unused at this moment * \param options Options about how to search. * See ZoneFinder::FindOptions. */ virtual FindResult find(const isc::dns::Name& name, const isc::dns::RRType& type, - isc::dns::RRsetList* target = NULL, const FindOptions options = FIND_DEFAULT); /** diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc index a79ee5bc3a..2684bcbb5d 100644 --- a/src/lib/datasrc/memory_datasrc.cc +++ b/src/lib/datasrc/memory_datasrc.cc @@ -421,8 +421,8 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { } // Implementation of InMemoryZoneFinder::find - FindResult find(const Name& name, RRType type, - RRsetList* target, const FindOptions options) const + FindResult find(const Name& name, RRType type, const FindOptions options) + const { LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_FIND).arg(name). arg(type); @@ -566,6 +566,8 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { } } +#if 0 + TODO: Move this to some other place, new method // handle type any query if (target != NULL && !node->getData()->empty()) { // Empty domain will be handled as NXRRSET by normal processing @@ -580,6 +582,7 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { arg(name); return (FindResult(SUCCESS, ConstRRsetPtr())); } +#endif found = node->getData()->find(type); if (found != node->getData()->end()) { @@ -629,9 +632,9 @@ InMemoryZoneFinder::getClass() const { ZoneFinder::FindResult InMemoryZoneFinder::find(const Name& name, const RRType& type, - RRsetList* target, const FindOptions options) + const FindOptions options) { - return (impl_->find(name, type, target, options)); + return (impl_->find(name, type, options)); } result::Result diff --git a/src/lib/datasrc/memory_datasrc.h b/src/lib/datasrc/memory_datasrc.h index b852eb369b..1d311ca242 100644 --- a/src/lib/datasrc/memory_datasrc.h +++ b/src/lib/datasrc/memory_datasrc.h @@ -74,7 +74,6 @@ public: /// (the base class documentation does not seem to require that). virtual FindResult find(const isc::dns::Name& name, const isc::dns::RRType& type, - isc::dns::RRsetList* target = NULL, const FindOptions options = FIND_DEFAULT); /// \brief Imelementation of the ZoneFinder::findPreviousName method diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc index 920c9a27a1..8491b7a1a2 100644 --- a/src/lib/datasrc/tests/database_unittest.cc +++ b/src/lib/datasrc/tests/database_unittest.cc @@ -1419,8 +1419,7 @@ doFindTest(ZoneFinder& finder, const ZoneFinder::FindOptions options = ZoneFinder::FIND_DEFAULT) { SCOPED_TRACE("doFindTest " + name.toText() + " " + type.toText()); - const ZoneFinder::FindResult result = finder.find(name, type, NULL, - options); + const ZoneFinder::FindResult result = finder.find(name, type, options); ASSERT_EQ(expected_result, result.code) << name << " " << type; if (!expected_rdatas.empty() && result.rrset) { checkRRset(result.rrset, expected_name != Name(".") ? expected_name : @@ -1670,58 +1669,58 @@ TYPED_TEST(DatabaseClientTest, find) { EXPECT_THROW(finder->find(isc::dns::Name("badcname1.example.org."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), DataSourceError); EXPECT_THROW(finder->find(isc::dns::Name("badcname2.example.org."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), DataSourceError); EXPECT_THROW(finder->find(isc::dns::Name("badcname3.example.org."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), DataSourceError); EXPECT_THROW(finder->find(isc::dns::Name("badrdata.example.org."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), DataSourceError); EXPECT_THROW(finder->find(isc::dns::Name("badtype.example.org."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), DataSourceError); EXPECT_THROW(finder->find(isc::dns::Name("badttl.example.org."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), DataSourceError); EXPECT_THROW(finder->find(isc::dns::Name("badsig.example.org."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), DataSourceError); // Trigger the hardcoded exceptions and see if find() has cleaned up if (this->is_mock_) { EXPECT_THROW(finder->find(isc::dns::Name("dsexception.in.search."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), DataSourceError); EXPECT_THROW(finder->find(isc::dns::Name("iscexception.in.search."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), isc::Exception); EXPECT_THROW(finder->find(isc::dns::Name("basicexception.in.search."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), std::exception); EXPECT_THROW(finder->find(isc::dns::Name("dsexception.in.getnext."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), DataSourceError); EXPECT_THROW(finder->find(isc::dns::Name("iscexception.in.getnext."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), isc::Exception); EXPECT_THROW(finder->find(isc::dns::Name("basicexception.in.getnext."), this->qtype_, - NULL, ZoneFinder::FIND_DEFAULT), + ZoneFinder::FIND_DEFAULT), std::exception); } @@ -1840,17 +1839,17 @@ TYPED_TEST(DatabaseClientTest, findDelegation) { // This is broken dname, it contains two targets EXPECT_THROW(finder->find(isc::dns::Name("below.baddname.example.org."), - this->qtype_, NULL, + this->qtype_, ZoneFinder::FIND_DEFAULT), DataSourceError); // Broken NS - it lives together with something else EXPECT_THROW(finder->find(isc::dns::Name("brokenns1.example.org."), - this->qtype_, NULL, + this->qtype_, ZoneFinder::FIND_DEFAULT), DataSourceError); EXPECT_THROW(finder->find(isc::dns::Name("brokenns2.example.org."), - this->qtype_, NULL, + this->qtype_, ZoneFinder::FIND_DEFAULT), DataSourceError); } diff --git a/src/lib/datasrc/tests/memory_datasrc_unittest.cc b/src/lib/datasrc/tests/memory_datasrc_unittest.cc index a1bd94e838..7812093b01 100644 --- a/src/lib/datasrc/tests/memory_datasrc_unittest.cc +++ b/src/lib/datasrc/tests/memory_datasrc_unittest.cc @@ -389,7 +389,6 @@ public: ZoneFinder::Result result, bool check_answer = true, const ConstRRsetPtr& answer = ConstRRsetPtr(), - RRsetList* target = NULL, InMemoryZoneFinder* zone_finder = NULL, ZoneFinder::FindOptions options = ZoneFinder::FIND_DEFAULT, bool check_wild_answer = false) @@ -402,7 +401,7 @@ public: EXPECT_NO_THROW({ ZoneFinder::FindResult find_result(zone_finder->find( name, rrtype, - target, options)); + options)); // Check it returns correct answers EXPECT_EQ(result, find_result.code); if (check_answer) { @@ -522,7 +521,7 @@ TEST_F(InMemoryZoneFinderTest, findCNAMEUnderZoneCut) { RRTTL(300))); EXPECT_EQ(SUCCESS, zone_finder_.add(rr_cname_under_cut_)); findTest(Name("cname.child.example.org"), RRType::AAAA(), - ZoneFinder::CNAME, true, rr_cname_under_cut_, NULL, NULL, + ZoneFinder::CNAME, true, rr_cname_under_cut_, NULL, ZoneFinder::FIND_GLUE_OK); } @@ -598,7 +597,7 @@ TEST_F(InMemoryZoneFinderTest, DNAMEUnderNS) { findTest(lowName, RRType::A(), ZoneFinder::DELEGATION, true, rr_child_ns_); findTest(lowName, RRType::A(), ZoneFinder::DNAME, true, rr_child_dname_, - NULL, NULL, ZoneFinder::FIND_GLUE_OK); + NULL, ZoneFinder::FIND_GLUE_OK); } // Test adding child zones and zone cut handling @@ -630,6 +629,8 @@ TEST_F(InMemoryZoneFinderTest, delegationNS) { ZoneFinder::DELEGATION, true, rr_child_ns_); } +#if 0 + TODO: Update to the new interface TEST_F(InMemoryZoneFinderTest, findAny) { EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_finder_.add(rr_a_))); EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_finder_.add(rr_ns_))); @@ -638,7 +639,7 @@ TEST_F(InMemoryZoneFinderTest, findAny) { // origin RRsetList origin_rrsets; findTest(origin_, RRType::ANY(), ZoneFinder::SUCCESS, true, - ConstRRsetPtr(), &origin_rrsets); + ConstRRsetPtr(), NULL, &origin_rrsets); EXPECT_EQ(2, origin_rrsets.size()); EXPECT_EQ(rr_a_, origin_rrsets.findRRset(RRType::A(), RRClass::IN())); EXPECT_EQ(rr_ns_, origin_rrsets.findRRset(RRType::NS(), RRClass::IN())); @@ -646,12 +647,12 @@ TEST_F(InMemoryZoneFinderTest, findAny) { // out zone name RRsetList out_rrsets; findTest(Name("example.com"), RRType::ANY(), ZoneFinder::NXDOMAIN, true, - ConstRRsetPtr(), &out_rrsets); + ConstRRsetPtr(), NULL, &out_rrsets); EXPECT_EQ(0, out_rrsets.size()); RRsetList glue_child_rrsets; findTest(rr_child_glue_->getName(), RRType::ANY(), ZoneFinder::SUCCESS, - true, ConstRRsetPtr(), &glue_child_rrsets); + true, ConstRRsetPtr(), NULL, &glue_child_rrsets); EXPECT_EQ(rr_child_glue_, glue_child_rrsets.findRRset(RRType::A(), RRClass::IN())); EXPECT_EQ(1, glue_child_rrsets.size()); @@ -674,6 +675,7 @@ TEST_F(InMemoryZoneFinderTest, findAny) { true, rr_child_ns_, &new_glue_child_rrsets); EXPECT_EQ(0, new_glue_child_rrsets.size()); } +#endif TEST_F(InMemoryZoneFinderTest, glue) { // install zone data: @@ -693,26 +695,26 @@ TEST_F(InMemoryZoneFinderTest, glue) { // If we do it in the "glue OK" mode, we should find the exact match. findTest(rr_child_glue_->getName(), RRType::A(), ZoneFinder::SUCCESS, true, - rr_child_glue_, NULL, NULL, ZoneFinder::FIND_GLUE_OK); + rr_child_glue_, NULL, ZoneFinder::FIND_GLUE_OK); // glue OK + NXRRSET case findTest(rr_child_glue_->getName(), RRType::AAAA(), ZoneFinder::NXRRSET, - true, ConstRRsetPtr(), NULL, NULL, ZoneFinder::FIND_GLUE_OK); + true, ConstRRsetPtr(), NULL, ZoneFinder::FIND_GLUE_OK); // glue OK + NXDOMAIN case findTest(Name("www.child.example.org"), RRType::A(), - ZoneFinder::DELEGATION, true, rr_child_ns_, NULL, NULL, + ZoneFinder::DELEGATION, true, rr_child_ns_, NULL, ZoneFinder::FIND_GLUE_OK); // nested cut case. The glue should be found. findTest(rr_grandchild_glue_->getName(), RRType::AAAA(), ZoneFinder::SUCCESS, - true, rr_grandchild_glue_, NULL, NULL, ZoneFinder::FIND_GLUE_OK); + true, rr_grandchild_glue_, NULL, ZoneFinder::FIND_GLUE_OK); // A non-existent name in nested cut. This should result in delegation // at the highest zone cut. findTest(Name("www.grand.child.example.org"), RRType::TXT(), - ZoneFinder::DELEGATION, true, rr_child_ns_, NULL, NULL, + ZoneFinder::DELEGATION, true, rr_child_ns_, NULL, ZoneFinder::FIND_GLUE_OK); } @@ -801,14 +803,14 @@ TEST_F(InMemoryZoneFinderTest, load) { // Now see there are some rrsets (we don't look inside, though) findTest(Name("."), RRType::SOA(), ZoneFinder::SUCCESS, false, - ConstRRsetPtr(), NULL, &rootzone); + ConstRRsetPtr(), &rootzone); findTest(Name("."), RRType::NS(), ZoneFinder::SUCCESS, false, - ConstRRsetPtr(), NULL, &rootzone); + ConstRRsetPtr(), &rootzone); findTest(Name("a.root-servers.net."), RRType::A(), ZoneFinder::SUCCESS, - false, ConstRRsetPtr(), NULL, &rootzone); + false, ConstRRsetPtr(), &rootzone); // But this should no longer be here findTest(rr_ns_a_->getName(), RRType::AAAA(), ZoneFinder::NXDOMAIN, true, - ConstRRsetPtr(), NULL, &rootzone); + ConstRRsetPtr(), &rootzone); // Try loading zone that is wrong in a different way EXPECT_THROW(zone_finder_.load(TEST_DATA_DIR "/duplicate_rrset.zone"), @@ -846,14 +848,14 @@ TEST_F(InMemoryZoneFinderTest, wildcard) { { SCOPED_TRACE("Search at created child"); findTest(Name("a.wild.example.org"), RRType::A(), ZoneFinder::SUCCESS, - false, rr_wild_, NULL, NULL, ZoneFinder::FIND_DEFAULT, true); + false, rr_wild_, NULL, ZoneFinder::FIND_DEFAULT, true); } // Search another created name, this time little bit lower { SCOPED_TRACE("Search at created grand-child"); findTest(Name("a.b.wild.example.org"), RRType::A(), - ZoneFinder::SUCCESS, false, rr_wild_, NULL, NULL, + ZoneFinder::SUCCESS, false, rr_wild_, NULL, ZoneFinder::FIND_DEFAULT, true); } @@ -885,11 +887,13 @@ TEST_F(InMemoryZoneFinderTest, delegatedWildcard) { { SCOPED_TRACE("Looking under delegation point in GLUE_OK mode"); findTest(Name("a.child.example.org"), RRType::A(), - ZoneFinder::DELEGATION, true, rr_child_ns_, NULL, NULL, + ZoneFinder::DELEGATION, true, rr_child_ns_, NULL, ZoneFinder::FIND_GLUE_OK); } } +#if 0 +When the new interface is created, use it // Tests combination of wildcard and ANY. TEST_F(InMemoryZoneFinderTest, anyWildcard) { EXPECT_EQ(SUCCESS, zone_finder_.add(rr_wild_)); @@ -916,6 +920,7 @@ TEST_F(InMemoryZoneFinderTest, anyWildcard) { EXPECT_EQ(Name("a.wild.example.org"), (*target.begin())->getName()); } } +#endif // Test there's nothing in the wildcard in the middle if we load // wild.*.foo.example.org. @@ -941,6 +946,8 @@ TEST_F(InMemoryZoneFinderTest, emptyWildcard) { findTest(Name("foo.example.org"), RRType::A(), ZoneFinder::NXRRSET); } +#if 0 + TODO: Update to the new interface { SCOPED_TRACE("Asking for ANY record"); RRsetList normalTarget; @@ -953,6 +960,7 @@ TEST_F(InMemoryZoneFinderTest, emptyWildcard) { ZoneFinder::NXRRSET, true, ConstRRsetPtr(), &wildTarget); EXPECT_EQ(0, wildTarget.size()); } +#endif { SCOPED_TRACE("Asking on the non-terminal"); @@ -1005,6 +1013,8 @@ TEST_F(InMemoryZoneFinderTest, nestedEmptyWildcard) { } } +#if 0 + TODO: Update to the new interface once it is created { SCOPED_TRACE("Asking for ANY on parent nodes"); @@ -1017,6 +1027,7 @@ TEST_F(InMemoryZoneFinderTest, nestedEmptyWildcard) { EXPECT_EQ(0, target.size()); } } +#endif } // We run this part twice from the below test, in two slightly different @@ -1054,7 +1065,7 @@ InMemoryZoneFinderTest::doCancelWildcardTest() { SCOPED_TRACE(string("Node ") + *name); findTest(Name(*name), RRType::A(), ZoneFinder::SUCCESS, false, - rr_wild_, NULL, NULL, ZoneFinder::FIND_DEFAULT, true); + rr_wild_, NULL, ZoneFinder::FIND_DEFAULT, true); } } @@ -1125,13 +1136,13 @@ TEST_F(InMemoryZoneFinderTest, swap) { EXPECT_EQ(RRClass::IN(), finder2.getClass()); // make sure the zone data is swapped, too findTest(origin_, RRType::NS(), ZoneFinder::NXDOMAIN, false, - ConstRRsetPtr(), NULL, &finder1); + ConstRRsetPtr(), &finder1); findTest(other_origin, RRType::TXT(), ZoneFinder::SUCCESS, false, - ConstRRsetPtr(), NULL, &finder1); + ConstRRsetPtr(), &finder1); findTest(origin_, RRType::NS(), ZoneFinder::SUCCESS, false, - ConstRRsetPtr(), NULL, &finder2); + ConstRRsetPtr(), &finder2); findTest(other_origin, RRType::TXT(), ZoneFinder::NXDOMAIN, false, - ConstRRsetPtr(), NULL, &finder2); + ConstRRsetPtr(), &finder2); } TEST_F(InMemoryZoneFinderTest, getFileName) { diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h index 9fcd289f2a..70767de4a3 100644 --- a/src/lib/datasrc/zone.h +++ b/src/lib/datasrc/zone.h @@ -237,9 +237,6 @@ public: /// a successful match, and the code of \c SUCCESS will be returned. /// - If the search name matches a delegation point of DNAME, it returns /// the code of \c DNAME and that DNAME RR. - /// - If the target isn't NULL, all RRsets under the domain are inserted - /// there and SUCCESS (or NXDOMAIN, in case of empty domain) is returned - /// instead of normall processing. This is intended to handle ANY query. /// /// \note This behavior is controversial as we discussed in /// https://lists.isc.org/pipermail/bind10-dev/2011-January/001918.html @@ -273,13 +270,10 @@ public: /// /// \param name The domain name to be searched for. /// \param type The RR type to be searched for. - /// \param target If target is not NULL, insert all RRs under the domain - /// into it. /// \param options The search options. /// \return A \c FindResult object enclosing the search result (see above). virtual FindResult find(const isc::dns::Name& name, const isc::dns::RRType& type, - isc::dns::RRsetList* target = NULL, const FindOptions options = FIND_DEFAULT) = 0; From 118d0d9c047879133c412390d67dda70004da589 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Fri, 9 Dec 2011 19:32:28 +0100 Subject: [PATCH 02/12] [1483] Defined the findAll method interface --- src/lib/datasrc/zone.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h index 70767de4a3..34aba82bb1 100644 --- a/src/lib/datasrc/zone.h +++ b/src/lib/datasrc/zone.h @@ -277,6 +277,21 @@ public: const FindOptions options = FIND_DEFAULT) = 0; + /// + /// \brief Finds all RRsets in the given name. + /// + /// This function works almost exactly in the same way as the find one. The + /// only difference is, when the lookup is successful (eg. the code is + /// SUCCESS or WILDCARD), all the RRsets residing in the named node are + /// copied into the \c target parameter and the rrset member of the result + /// is NULL. All the other (unsuccessful) cases are handled the same, + /// including returning delegations, NSEC/NSEC3 proofs, etc. The options + /// parameter works the same way and it should comfort to the same exception + /// restrictions. + virtual FindResult findAll(const isc::dns::Name& name, + std::vector &target, + const FindOptions options = FIND_DEFAULT) = 0; + /// \brief Get previous name in the zone /// /// Gets the previous name in the DNSSEC order. This can be used From 8e93f114a93671c4eda46f420c81e1101fc16e05 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Fri, 9 Dec 2011 21:26:31 +0100 Subject: [PATCH 03/12] [1483] Port the ANY logic in memory datasource To the new interface. The tests were reintroduced. --- src/lib/datasrc/database.cc | 8 ++ src/lib/datasrc/database.h | 10 ++ src/lib/datasrc/memory_datasrc.cc | 22 ++-- src/lib/datasrc/memory_datasrc.h | 13 ++- .../datasrc/tests/memory_datasrc_unittest.cc | 105 +++++++++--------- 5 files changed, 91 insertions(+), 67 deletions(-) diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc index 13ae3cd92a..25dc66ef0f 100644 --- a/src/lib/datasrc/database.cc +++ b/src/lib/datasrc/database.cc @@ -390,6 +390,14 @@ DatabaseClient::Finder::findNSECCover(const Name& name) { return (RRsetPtr()); } +ZoneFinder::FindResult +DatabaseClient::Finder::findAll(const isc::dns::Name&, + std::vector&, + const FindOptions) +{ + isc_throw(isc::NotImplemented, "Not implemented"); +} + ZoneFinder::FindResult DatabaseClient::Finder::find(const isc::dns::Name& name, const isc::dns::RRType& type, diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h index 615ff1e4d7..f0c4575c9a 100644 --- a/src/lib/datasrc/database.h +++ b/src/lib/datasrc/database.h @@ -782,6 +782,16 @@ public: virtual FindResult find(const isc::dns::Name& name, const isc::dns::RRType& type, const FindOptions options = FIND_DEFAULT); + /** + * \brief Implementation of the ZoneFinder::findAll method. + * + * In short, it is mostly the same thing as find, but it returns all + * RRsets in the named node through the target parameter in successful + * case. It acts the same in the unsuccessful one. + */ + virtual FindResult findAll(const isc::dns::Name& name, + std::vector& target, + const FindOptions options = FIND_DEFAULT); /** * \brief Implementation of ZoneFinder::findPreviousName method. diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc index 2684bcbb5d..d09eb6df68 100644 --- a/src/lib/datasrc/memory_datasrc.cc +++ b/src/lib/datasrc/memory_datasrc.cc @@ -421,8 +421,9 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { } // Implementation of InMemoryZoneFinder::find - FindResult find(const Name& name, RRType type, const FindOptions options) - const + FindResult find(const Name& name, RRType type, + std::vector *target, + const FindOptions options) const { LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_FIND).arg(name). arg(type); @@ -566,23 +567,18 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl { } } -#if 0 - TODO: Move this to some other place, new method // handle type any query if (target != NULL && !node->getData()->empty()) { // Empty domain will be handled as NXRRSET by normal processing for (found = node->getData()->begin(); found != node->getData()->end(); ++found) { - target->addRRset( - boost::const_pointer_cast(prepareRRset(name, - found->second, rename))); + target->push_back(prepareRRset(name, found->second, rename)); } LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_ANY_SUCCESS). arg(name); return (FindResult(SUCCESS, ConstRRsetPtr())); } -#endif found = node->getData()->find(type); if (found != node->getData()->end()) { @@ -634,7 +630,15 @@ ZoneFinder::FindResult InMemoryZoneFinder::find(const Name& name, const RRType& type, const FindOptions options) { - return (impl_->find(name, type, options)); + return (impl_->find(name, type, NULL, options)); +} + +ZoneFinder::FindResult +InMemoryZoneFinder::findAll(const Name& name, + std::vector& target, + const FindOptions options) +{ + return (impl_->find(name, RRType::ANY(), &target, options)); } result::Result diff --git a/src/lib/datasrc/memory_datasrc.h b/src/lib/datasrc/memory_datasrc.h index 1d311ca242..32cf518fbb 100644 --- a/src/lib/datasrc/memory_datasrc.h +++ b/src/lib/datasrc/memory_datasrc.h @@ -69,13 +69,20 @@ public: /// /// See documentation in \c Zone. /// - /// It returns NULL pointer in case of NXDOMAIN and NXRRSET, - /// and also SUCCESS if target is not NULL(TYPE_ANY query). - /// (the base class documentation does not seem to require that). + /// It returns NULL pointer in case of NXDOMAIN and NXRRSET. virtual FindResult find(const isc::dns::Name& name, const isc::dns::RRType& type, const FindOptions options = FIND_DEFAULT); + /// \brief Version of find that returns all types at once + /// + /// It acts the same as find, just that when the correct node is found, + /// all the RRsets are filled into the target parameter instead of being + /// returned by the result. + virtual FindResult findAll(const isc::dns::Name& name, + std::vector& target, + const FindOptions options = FIND_DEFAULT); + /// \brief Imelementation of the ZoneFinder::findPreviousName method /// /// This one throws NotImplemented exception, as InMemory doesn't diff --git a/src/lib/datasrc/tests/memory_datasrc_unittest.cc b/src/lib/datasrc/tests/memory_datasrc_unittest.cc index 7812093b01..0ca4bdea6f 100644 --- a/src/lib/datasrc/tests/memory_datasrc_unittest.cc +++ b/src/lib/datasrc/tests/memory_datasrc_unittest.cc @@ -16,6 +16,7 @@ #include #include +#include #include @@ -437,6 +438,32 @@ public: } }); } + /** + * \brief Calls the findAll on the finder and checks the result. + */ + std::vector findAllTest(const Name& name, + ZoneFinder::Result result, + size_t expected_size, + InMemoryZoneFinder* finder = NULL, + const ConstRRsetPtr &rrset_result = + ConstRRsetPtr(), + ZoneFinder::FindOptions options = + ZoneFinder::FIND_DEFAULT) + { + if (finder == NULL) { + finder = &zone_finder_; + } + std::vector target; + ZoneFinder::FindResult findResult(finder->findAll(name, target, + options)); + EXPECT_EQ(result, findResult.code); + EXPECT_EQ(rrset_result, findResult.rrset); + BOOST_FOREACH(const ConstRRsetPtr& rrset, target) { + EXPECT_EQ(name, rrset->getName()); + } + EXPECT_EQ(expected_size, target.size()); + return (target); + } // Internal part of the cancelWildcard test that is multiple times void doCancelWildcardTest(); }; @@ -629,33 +656,25 @@ TEST_F(InMemoryZoneFinderTest, delegationNS) { ZoneFinder::DELEGATION, true, rr_child_ns_); } -#if 0 - TODO: Update to the new interface TEST_F(InMemoryZoneFinderTest, findAny) { EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_finder_.add(rr_a_))); EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_finder_.add(rr_ns_))); EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_finder_.add(rr_child_glue_))); // origin - RRsetList origin_rrsets; - findTest(origin_, RRType::ANY(), ZoneFinder::SUCCESS, true, - ConstRRsetPtr(), NULL, &origin_rrsets); - EXPECT_EQ(2, origin_rrsets.size()); - EXPECT_EQ(rr_a_, origin_rrsets.findRRset(RRType::A(), RRClass::IN())); - EXPECT_EQ(rr_ns_, origin_rrsets.findRRset(RRType::NS(), RRClass::IN())); + std::vector rrsets(findAllTest(origin_, ZoneFinder::SUCCESS, + 2)); + EXPECT_FALSE(rrsets.end() == std::find(rrsets.begin(), rrsets.end(), + rr_a_)); + EXPECT_FALSE(rrsets.end() == std::find(rrsets.begin(), rrsets.end(), + rr_ns_)); // out zone name - RRsetList out_rrsets; - findTest(Name("example.com"), RRType::ANY(), ZoneFinder::NXDOMAIN, true, - ConstRRsetPtr(), NULL, &out_rrsets); - EXPECT_EQ(0, out_rrsets.size()); + findAllTest(Name("example.com"), ZoneFinder::NXDOMAIN, 0); - RRsetList glue_child_rrsets; - findTest(rr_child_glue_->getName(), RRType::ANY(), ZoneFinder::SUCCESS, - true, ConstRRsetPtr(), NULL, &glue_child_rrsets); - EXPECT_EQ(rr_child_glue_, glue_child_rrsets.findRRset(RRType::A(), - RRClass::IN())); - EXPECT_EQ(1, glue_child_rrsets.size()); + rrsets = findAllTest(rr_child_glue_->getName(), ZoneFinder::SUCCESS, 1); + EXPECT_FALSE(rrsets.end() == std::find(rrsets.begin(), rrsets.end(), + rr_child_glue_)); // TODO: test NXRRSET case after rbtree non-terminal logic has // been implemented @@ -664,18 +683,13 @@ TEST_F(InMemoryZoneFinderTest, findAny) { EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_finder_.add(rr_child_ns_))); // zone cut - RRsetList child_rrsets; - findTest(rr_child_ns_->getName(), RRType::ANY(), ZoneFinder::DELEGATION, - true, rr_child_ns_, &child_rrsets); - EXPECT_EQ(0, child_rrsets.size()); + findAllTest(rr_child_ns_->getName(), ZoneFinder::DELEGATION, 0, NULL, + rr_child_ns_); // glue for this zone cut - RRsetList new_glue_child_rrsets; - findTest(rr_child_glue_->getName(), RRType::ANY(), ZoneFinder::DELEGATION, - true, rr_child_ns_, &new_glue_child_rrsets); - EXPECT_EQ(0, new_glue_child_rrsets.size()); + findAllTest(rr_child_glue_->getName(),ZoneFinder::DELEGATION, 0, NULL, + rr_child_ns_); } -#endif TEST_F(InMemoryZoneFinderTest, glue) { // install zone data: @@ -892,8 +906,6 @@ TEST_F(InMemoryZoneFinderTest, delegatedWildcard) { } } -#if 0 -When the new interface is created, use it // Tests combination of wildcard and ANY. TEST_F(InMemoryZoneFinderTest, anyWildcard) { EXPECT_EQ(SUCCESS, zone_finder_.add(rr_wild_)); @@ -901,9 +913,9 @@ TEST_F(InMemoryZoneFinderTest, anyWildcard) { // First try directly the name (normal match) { SCOPED_TRACE("Asking direcly for *"); - RRsetList target; - findTest(Name("*.wild.example.org"), RRType::ANY(), - ZoneFinder::SUCCESS, true, ConstRRsetPtr(), &target); + const std::vector + target(findAllTest(Name("*.wild.example.org"), ZoneFinder::SUCCESS, + 1)); ASSERT_EQ(1, target.size()); EXPECT_EQ(RRType::A(), (*target.begin())->getType()); EXPECT_EQ(Name("*.wild.example.org"), (*target.begin())->getName()); @@ -912,15 +924,13 @@ TEST_F(InMemoryZoneFinderTest, anyWildcard) { // Then a wildcard match { SCOPED_TRACE("Asking in the wild way"); - RRsetList target; - findTest(Name("a.wild.example.org"), RRType::ANY(), - ZoneFinder::SUCCESS, true, ConstRRsetPtr(), &target); - ASSERT_EQ(1, target.size()); + const std::vector + target(findAllTest(Name("a.wild.example.org"), ZoneFinder::SUCCESS, + 1)); EXPECT_EQ(RRType::A(), (*target.begin())->getType()); EXPECT_EQ(Name("a.wild.example.org"), (*target.begin())->getName()); } } -#endif // Test there's nothing in the wildcard in the middle if we load // wild.*.foo.example.org. @@ -946,21 +956,12 @@ TEST_F(InMemoryZoneFinderTest, emptyWildcard) { findTest(Name("foo.example.org"), RRType::A(), ZoneFinder::NXRRSET); } -#if 0 - TODO: Update to the new interface { SCOPED_TRACE("Asking for ANY record"); - RRsetList normalTarget; - findTest(Name("*.foo.example.org"), RRType::ANY(), ZoneFinder::NXRRSET, - true, ConstRRsetPtr(), &normalTarget); - EXPECT_EQ(0, normalTarget.size()); + findAllTest(Name("*.foo.example.org"), ZoneFinder::NXRRSET, 0); - RRsetList wildTarget; - findTest(Name("a.foo.example.org"), RRType::ANY(), - ZoneFinder::NXRRSET, true, ConstRRsetPtr(), &wildTarget); - EXPECT_EQ(0, wildTarget.size()); + findAllTest(Name("a.foo.example.org"), ZoneFinder::NXRRSET, 0); } -#endif { SCOPED_TRACE("Asking on the non-terminal"); @@ -1013,21 +1014,15 @@ TEST_F(InMemoryZoneFinderTest, nestedEmptyWildcard) { } } -#if 0 - TODO: Update to the new interface once it is created { SCOPED_TRACE("Asking for ANY on parent nodes"); for (const char** name(names); *name != NULL; ++ name) { SCOPED_TRACE(string("Node ") + *name); - RRsetList target; - findTest(Name(*name), RRType::ANY(), ZoneFinder::NXRRSET, true, - ConstRRsetPtr(), &target); - EXPECT_EQ(0, target.size()); + findAllTest(Name(*name), ZoneFinder::NXRRSET, 0); } } -#endif } // We run this part twice from the below test, in two slightly different From 90c77658e79a21c3a60da992f22eb2f2660db667 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Mon, 12 Dec 2011 13:20:32 +0100 Subject: [PATCH 04/12] [1483] Port the rest to new interface --- src/bin/auth/query.cc | 36 +++++++++++-------- src/bin/auth/tests/query_unittest.cc | 38 ++++++++++++++------- src/lib/python/isc/datasrc/finder_python.cc | 2 +- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc index f1592620ae..ef7653fb7e 100644 --- a/src/bin/auth/query.cc +++ b/src/bin/auth/query.cc @@ -15,6 +15,8 @@ #include // for std::max #include #include +#include +#include #include #include @@ -67,7 +69,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname, // Find A rrset if (qname_ != qname || qtype_ != RRType::A()) { - ZoneFinder::FindResult a_result = zone.find(qname, RRType::A(), NULL, + ZoneFinder::FindResult a_result = zone.find(qname, RRType::A(), options | dnssec_opt_); if (a_result.code == ZoneFinder::SUCCESS) { response_.addRRset(Message::SECTION_ADDITIONAL, @@ -78,7 +80,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname, // Find AAAA rrset if (qname_ != qname || qtype_ != RRType::AAAA()) { ZoneFinder::FindResult aaaa_result = - zone.find(qname, RRType::AAAA(), NULL, options | dnssec_opt_); + zone.find(qname, RRType::AAAA(), options | dnssec_opt_); if (aaaa_result.code == ZoneFinder::SUCCESS) { response_.addRRset(Message::SECTION_ADDITIONAL, boost::const_pointer_cast(aaaa_result.rrset), @@ -90,7 +92,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname, void Query::addSOA(ZoneFinder& finder) { ZoneFinder::FindResult soa_result(finder.find(finder.getOrigin(), - RRType::SOA(), NULL, dnssec_opt_)); + RRType::SOA(), dnssec_opt_)); if (soa_result.code != ZoneFinder::SUCCESS) { isc_throw(NoSOA, "There's no SOA record in zone " << finder.getOrigin().toText()); @@ -146,7 +148,7 @@ Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) { // otherwise we shouldn't have got NXDOMAIN for the original query in // the first place). const ZoneFinder::FindResult fresult = finder.find(wildname, - RRType::NSEC(), NULL, + RRType::NSEC(), dnssec_opt_); if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset || fresult.rrset->getRdataCount() == 0) { @@ -171,7 +173,7 @@ Query::addWildcardProof(ZoneFinder& finder) { // 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, + finder.find(qname_, RRType::NSEC(), dnssec_opt_ | ZoneFinder::NO_WILDCARD); if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset || fresult.rrset->getRdataCount() == 0) { @@ -194,7 +196,7 @@ Query::addWildcardNXRRSETProof(ZoneFinder& finder, ConstRRsetPtr nsec) { boost::const_pointer_cast(nsec), dnssec_); const ZoneFinder::FindResult fresult = - finder.find(qname_, RRType::NSEC(), NULL, + finder.find(qname_, RRType::NSEC(), dnssec_opt_ | ZoneFinder::NO_WILDCARD); if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset || fresult.rrset->getRdataCount() == 0) { @@ -213,8 +215,7 @@ void Query::addAuthAdditional(ZoneFinder& finder) { // Fill in authority and addtional sections. ZoneFinder::FindResult ns_result = finder.find(finder.getOrigin(), - RRType::NS(), NULL, - dnssec_opt_); + RRType::NS(), dnssec_opt_); // zone origin name should have NS records if (ns_result.code != ZoneFinder::SUCCESS) { isc_throw(NoApexNS, "There's no apex NS records in zone " << @@ -253,9 +254,16 @@ Query::process() { response_.setRcode(Rcode::NOERROR()); while (keep_doing) { keep_doing = false; - std::auto_ptr target(qtype_is_any ? new RRsetList : NULL); - const ZoneFinder::FindResult db_result( - zfinder.find(qname_, qtype_, target.get(), dnssec_opt_)); + std::vector target; + boost::function0 find; + if (qtype_is_any) { + find = boost::bind(&ZoneFinder::findAll, &zfinder, qname_, + boost::ref(target), dnssec_opt_); + } else { + find = boost::bind(&ZoneFinder::find, &zfinder, qname_, qtype_, + dnssec_opt_); + } + ZoneFinder::FindResult db_result(find()); switch (db_result.code) { case ZoneFinder::DNAME: { // First, put the dname into the answer @@ -326,9 +334,9 @@ Query::process() { if (qtype_is_any) { // If quety type is ANY, insert all RRs under the domain // into answer section. - BOOST_FOREACH(RRsetPtr rrset, *target) { - response_.addRRset(Message::SECTION_ANSWER, rrset, - dnssec_); + BOOST_FOREACH(ConstRRsetPtr rrset, target) { + response_.addRRset(Message::SECTION_ANSWER, + boost::const_pointer_cast(rrset), dnssec_); // Handle additional for answer section addAdditional(*result.zone_finder, *rrset.get()); } diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc index 14067abb7d..858759ef98 100644 --- a/src/bin/auth/tests/query_unittest.cc +++ b/src/bin/auth/tests/query_unittest.cc @@ -211,8 +211,10 @@ public: virtual isc::dns::RRClass getClass() const { return (rrclass_); } virtual FindResult find(const isc::dns::Name& name, const isc::dns::RRType& type, - RRsetList* target = NULL, const FindOptions options = FIND_DEFAULT); + virtual FindResult findAll(const isc::dns::Name& name, + std::vector& target, + const FindOptions options = FIND_DEFAULT); // If false is passed, it makes the zone broken as if it didn't have the // SOA. @@ -304,9 +306,30 @@ substituteWild(const RRset& wild_rrset, const Name& real_name) { return (rrset); } +ZoneFinder::FindResult +MockZoneFinder::findAll(const Name& name, std::vector& target, + const FindOptions options) +{ + ZoneFinder::FindResult result(find(name, RRType::ANY(), options)); + if (result.code == NXRRSET) { + const Domains::const_iterator found_domain = domains_.find(name); + if (!found_domain->second.empty()) { + for (RRsetStore::const_iterator found_rrset = + found_domain->second.begin(); + found_rrset != found_domain->second.end(); ++found_rrset) { + // Insert RRs under the domain name into target + target.push_back(found_rrset->second); + } + return (FindResult(SUCCESS, RRsetPtr())); + } + } + + return (result); +} + ZoneFinder::FindResult MockZoneFinder::find(const Name& name, const RRType& type, - RRsetList* target, const FindOptions options) + const FindOptions options) { // Emulating a broken zone: mandatory apex RRs are missing if specifically // configured so (which are rare cases). @@ -358,17 +381,6 @@ MockZoneFinder::find(const Name& name, const RRType& type, return (FindResult(SUCCESS, rrset)); } - // If not found but we have a target, fill it with all RRsets here - if (!found_domain->second.empty() && target != NULL) { - for (found_rrset = found_domain->second.begin(); - found_rrset != found_domain->second.end(); ++found_rrset) { - // Insert RRs under the domain name into target - target->addRRset( - boost::const_pointer_cast(found_rrset->second)); - } - return (FindResult(SUCCESS, found_domain->second.begin()->second)); - } - // Otherwise, if this domain name has CNAME, return it. found_rrset = found_domain->second.find(RRType::CNAME()); if (found_rrset != found_domain->second.end()) { diff --git a/src/lib/python/isc/datasrc/finder_python.cc b/src/lib/python/isc/datasrc/finder_python.cc index 7f74133d8d..5aa9c3eb9c 100644 --- a/src/lib/python/isc/datasrc/finder_python.cc +++ b/src/lib/python/isc/datasrc/finder_python.cc @@ -74,7 +74,7 @@ PyObject* ZoneFinder_helper(ZoneFinder* finder, PyObject* args) { static_cast(options_int); const ZoneFinder::FindResult find_result( finder->find(PyName_ToName(name), PyRRType_ToRRType(rrtype), - NULL, options)); + options)); const ZoneFinder::Result r = find_result.code; isc::dns::ConstRRsetPtr rrsp = find_result.rrset; if (rrsp) { From b2da8d97a3f24f2f80af7f408f6b8d461f3dccd4 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Tue, 13 Dec 2011 14:07:00 +0100 Subject: [PATCH 05/12] [1483] Implement findAll on database --- src/lib/datasrc/database.cc | 59 ++++++++-- src/lib/datasrc/database.h | 23 +++- src/lib/datasrc/tests/database_unittest.cc | 121 +++++++++++++++++++++ 3 files changed, 193 insertions(+), 10 deletions(-) diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc index 25dc66ef0f..33aa2b9eb4 100644 --- a/src/lib/datasrc/database.cc +++ b/src/lib/datasrc/database.cc @@ -177,7 +177,8 @@ private: DatabaseClient::Finder::FoundRRsets DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types, - bool check_ns, const string* construct_name) + bool check_ns, const string* construct_name, + bool any) { RRsigStore sig_store; bool records_found = false; @@ -222,7 +223,7 @@ DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types, columns[DatabaseAccessor::RDATA_COLUMN])); } - if (types.find(cur_type) != types.end()) { + if (types.find(cur_type) != types.end() || any) { // This type is requested, so put it into result const RRTTL cur_ttl(columns[DatabaseAccessor::TTL_COLUMN]); // Ths sigtype column was an optimization for finding the @@ -287,6 +288,12 @@ DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types, sig_store.appendSignatures(i->second); } + if (records_found && any) { + result[RRType::ANY()] = RRsetPtr(); + // These will be sitting on the other RRsets. + result.erase(RRType::RRSIG()); + } + return (FoundRRsets(records_found, result)); } @@ -391,17 +398,27 @@ DatabaseClient::Finder::findNSECCover(const Name& name) { } ZoneFinder::FindResult -DatabaseClient::Finder::findAll(const isc::dns::Name&, - std::vector&, - const FindOptions) +DatabaseClient::Finder::findAll(const isc::dns::Name& name, + std::vector& target, + const FindOptions options) { - isc_throw(isc::NotImplemented, "Not implemented"); + return (findInternal(name, RRType::ANY(), &target, options)); } ZoneFinder::FindResult DatabaseClient::Finder::find(const isc::dns::Name& name, const isc::dns::RRType& type, const FindOptions options) +{ + return (findInternal(name, type, NULL, options)); +} + +ZoneFinder::FindResult +DatabaseClient::Finder::findInternal(const isc::dns::Name& name, + const isc::dns::RRType& type, + std::vector* + target, + const FindOptions options) { // This variable is used to determine the difference between // NXDOMAIN and NXRRSET @@ -409,6 +426,7 @@ DatabaseClient::Finder::find(const isc::dns::Name& name, bool glue_ok((options & FIND_GLUE_OK) != 0); const bool dnssec_data((options & FIND_DNSSEC) != 0); bool get_cover(false); + bool any(type == RRType::ANY()); isc::dns::RRsetPtr result_rrset; ZoneFinder::Result result_status = SUCCESS; FoundRRsets found; @@ -479,7 +497,8 @@ DatabaseClient::Finder::find(const isc::dns::Name& name, WantedTypes final_types(FINAL_TYPES()); final_types.insert(type); - found = getRRsets(name.toText(), final_types, name != origin); + found = getRRsets(name.toText(), final_types, name != origin, NULL, + any); records_found = found.first; // NS records, CNAME record and Wanted Type records @@ -505,7 +524,18 @@ DatabaseClient::Finder::find(const isc::dns::Name& name, } } else if (wti != found.second.end()) { // Just get the answer + // TODO update here result_rrset = wti->second; + if (any) { + for (FoundIterator it(found.second.begin()); + it != found.second.end(); ++it) { + if (it->second) { + // Skip over the empty ANY + target->push_back(it->second); + } + } + return (FindResult(result_status, result_rrset)); + } } else if (!records_found) { // Nothing lives here. // But check if something lives below this @@ -535,7 +565,7 @@ DatabaseClient::Finder::find(const isc::dns::Name& name, // TODO What do we do about DNAME here? // The types are the same as with original query found = getRRsets(wildcard, final_types, true, - &construct_name); + &construct_name, any); if (found.first) { if (first_ns) { // In case we are under NS, we don't @@ -572,7 +602,20 @@ DatabaseClient::Finder::find(const isc::dns::Name& name, result_status = DELEGATION; } else if (wti != found.second.end()) { result_rrset = wti->second; + // TODO Update here result_status = WILDCARD; + if (any) { + for (FoundIterator + it(found.second.begin()); + it != found.second.end(); ++it) { + if (it->second) { + // Skip over the empty ANY + target->push_back(it->second); + } + } + return (FindResult(result_status, + result_rrset)); + } } else { // NXRRSET case in the wildcard result_status = WILDCARD_NXRRSET; diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h index f0c4575c9a..f291064213 100644 --- a/src/lib/datasrc/database.h +++ b/src/lib/datasrc/database.h @@ -822,12 +822,26 @@ public: boost::shared_ptr accessor_; const int zone_id_; const isc::dns::Name origin_; - // /// \brief Shortcut name for the result of getRRsets typedef std::pair > FoundRRsets; /// \brief Just shortcut for set of types typedef std::set WantedTypes; + /** + * \brief Internal logit of find and findAll methods. + * + * Most of their handling is in the "error" cases and delegations + * and so on. So they share the logic here and find and findAll provide + * just an interface for it. + * + * Parameters and behaviour is like of those combined together. + * Unexpected parameters, like type != ANY and having the target, are + * just that - unexpected and not checked. + */ + FindResult findInternal(const isc::dns::Name& name, + const isc::dns::RRType& type, + std::vector* target, + const FindOptions options = FIND_DEFAULT); /** * \brief Searches database for RRsets of one domain. * @@ -846,6 +860,10 @@ public: * their name set to name. If it is not NULL, it overrides the name * and uses this one (this can be used for wildcard synthesized * records). + * \param any If this is true, it records all the types, not only the + * ones requested by types. It also puts a NULL pointer under the + * ANY type into the result, if it finds any RRs at all, to easy the + * identification of success. * \return A pair, where the first element indicates if the domain * contains any RRs at all (not only the requested, it may happen * this is set to true, but the second part is empty). The second @@ -857,7 +875,8 @@ public: */ FoundRRsets getRRsets(const std::string& name, const WantedTypes& types, bool check_ns, - const std::string* construct_name = NULL); + const std::string* construct_name = NULL, + bool any = false); /** * \brief Checks if something lives below this domain. * diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc index 8491b7a1a2..4f4af27340 100644 --- a/src/lib/datasrc/tests/database_unittest.cc +++ b/src/lib/datasrc/tests/database_unittest.cc @@ -1443,6 +1443,39 @@ doFindTest(ZoneFinder& finder, } } +void +doFindAllTestResult(ZoneFinder& finder, const isc::dns::Name& name, + ZoneFinder::Result expected_result, + const isc::dns::RRType expected_type, + std::vector expected_rdata, + const isc::dns::Name& expected_name = + isc::dns::Name::ROOT_NAME(), + const ZoneFinder::FindOptions options = + ZoneFinder::FIND_DEFAULT) +{ + SCOPED_TRACE("All test for " + name.toText()); + std::vector target; + ZoneFinder::FindResult result(finder.findAll(name, target, options)); + EXPECT_TRUE(target.empty()); + EXPECT_EQ(expected_result, result.code); + EXPECT_EQ(expected_type, result.rrset->getType()); + RdataIteratorPtr it(result.rrset->getRdataIterator()); + std::vector rdata; + while (!it->isLast()) { + rdata.push_back(it->getCurrent().toText()); + it->next(); + } + std::sort(rdata.begin(), rdata.end()); + std::sort(expected_rdata.begin(), expected_rdata.end()); + ASSERT_EQ(expected_rdata.size(), rdata.size()); + for (size_t i(0); i < expected_rdata.size(); ++ i) { + EXPECT_EQ(expected_rdata[i], rdata[i]); + } + EXPECT_TRUE(expected_rdata == rdata); + EXPECT_EQ(expected_name == isc::dns::Name::ROOT_NAME() ? name : + expected_name, result.rrset->getName()); +} + // When asking for an RRset where RRs somehow have different TTLs, it should // convert to the lowest one. TEST_F(MockDatabaseClientTest, ttldiff) { @@ -2254,6 +2287,94 @@ TYPED_TEST(DatabaseClientTest, emptyNonterminalNSEC) { Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC)); } +// Test the findAll method. +TYPED_TEST(DatabaseClientTest, getAll) { + // The domain doesn't exist, so we must get the right NSEC + shared_ptr finder(this->getFinder()); + + // It should act the same on the "failures" + std::vector target; + EXPECT_EQ(ZoneFinder::NXDOMAIN, + finder->findAll(isc::dns::Name("nothere.example.org."), + target).code); + EXPECT_TRUE(target.empty()); + EXPECT_EQ(ZoneFinder::NXRRSET, + finder->findAll(isc::dns::Name("here.wild.example.org."), + target).code); + this->expected_rdatas_.push_back("ns.delegation.example.org."); + this->expected_rdatas_.push_back("ns.example.com."); + doFindAllTestResult(*finder, isc::dns::Name("xx.delegation.example.org."), + ZoneFinder::DELEGATION, RRType::NS(), + this->expected_rdatas_, + isc::dns::Name("delegation.example.org.")); + this->expected_rdatas_.clear(); + this->expected_rdatas_.push_back("www.example.org."); + doFindAllTestResult(*finder, isc::dns::Name("cname.example.org"), + ZoneFinder::CNAME, RRType::CNAME(), + this->expected_rdatas_); + this->expected_rdatas_.clear(); + this->expected_rdatas_.push_back("dname.example.com."); + doFindAllTestResult(*finder, isc::dns::Name("a.dname.example.org"), + ZoneFinder::DNAME, RRType::DNAME(), + this->expected_rdatas_, + isc::dns::Name("dname.example.org.")); + // It should get the data on success + EXPECT_EQ(ZoneFinder::SUCCESS, + finder->findAll(isc::dns::Name("www2.example.org."), + target).code); + ASSERT_EQ(2, target.size()); + size_t a_idx(target[1]->getType() == RRType::A()); + EXPECT_EQ(RRType::A(), target[a_idx]->getType()); + std::string previous; + size_t count(0); + for (RdataIteratorPtr it(target[a_idx]->getRdataIterator()); + !it->isLast(); it->next()) { + count ++; + EXPECT_NE(previous, it->getCurrent().toText()); + EXPECT_TRUE(it->getCurrent().toText() == "192.0.2.1" || + it->getCurrent().toText() == "192.0.2.2"); + previous = it->getCurrent().toText(); + } + EXPECT_EQ(2, count); + EXPECT_EQ(RRType::AAAA(), target[1 - a_idx]->getType()); + RdataIteratorPtr it(target[1 - a_idx]->getRdataIterator()); + ASSERT_FALSE(it->isLast()); + EXPECT_EQ("2001:db8::1", it->getCurrent().toText()); + it->next(); + EXPECT_TRUE(it->isLast()); + + // And on wildcard. Check the signatures as well. + target.clear(); + EXPECT_EQ(ZoneFinder::WILDCARD, + finder->findAll(isc::dns::Name("a.wild.example.org"), + target, ZoneFinder::FIND_DNSSEC).code); + ASSERT_EQ(2, target.size()); + a_idx = target[1]->getType() == RRType::A(); + EXPECT_EQ(RRType::A(), target[a_idx]->getType()); + it = target[a_idx]->getRdataIterator(); + ASSERT_FALSE(it->isLast()); + EXPECT_EQ("192.0.2.5", it->getCurrent().toText()); + it->next(); + EXPECT_TRUE(it->isLast()); + ConstRRsetPtr sig(target[a_idx]->getRRsig()); + ASSERT_TRUE(sig); + EXPECT_EQ(RRType::RRSIG(), sig->getType()); + EXPECT_EQ("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE", + sig->getRdataIterator()->getCurrent().toText()); + EXPECT_EQ(RRType::NSEC(), target[1 - a_idx]->getType()); + it = target[1 - a_idx]->getRdataIterator(); + ASSERT_FALSE(it->isLast()); + EXPECT_EQ("cancel.here.wild.example.org. A RRSIG NSEC", + it->getCurrent().toText()); + it->next(); + EXPECT_TRUE(it->isLast()); + sig = target[1 - a_idx]->getRRsig(); + ASSERT_TRUE(sig); + EXPECT_EQ(RRType::RRSIG(), sig->getType()); + EXPECT_EQ("NSEC 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE", + sig->getRdataIterator()->getCurrent().toText()); +} + TYPED_TEST(DatabaseClientTest, getOrigin) { DataSourceClient::FindResult zone(this->client_->findZone(Name("example.org"))); From 7ffef24a4823b63694628ee9fdab0b196d7caa06 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Tue, 13 Dec 2011 14:22:09 +0100 Subject: [PATCH 06/12] [1483] Protect the method by exception --- src/lib/datasrc/database.cc | 3 +++ src/lib/datasrc/tests/database_unittest.cc | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc index 33aa2b9eb4..7c09df8fa3 100644 --- a/src/lib/datasrc/database.cc +++ b/src/lib/datasrc/database.cc @@ -410,6 +410,9 @@ DatabaseClient::Finder::find(const isc::dns::Name& name, const isc::dns::RRType& type, const FindOptions options) { + if (type == RRType::ANY()) { + isc_throw(isc::Unexpected, "Use findAll to answer ANY"); + } return (findInternal(name, type, NULL, options)); } diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc index 4f4af27340..9fc4cf35f2 100644 --- a/src/lib/datasrc/tests/database_unittest.cc +++ b/src/lib/datasrc/tests/database_unittest.cc @@ -2287,6 +2287,12 @@ TYPED_TEST(DatabaseClientTest, emptyNonterminalNSEC) { Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC)); } +TYPED_TEST(DatabaseClientTest, anyFromFind) { + // Find will reject answering an ANY query + EXPECT_THROW(this->getFinder()->find(isc::dns::Name("www2.example.org."), + RRType::ANY()), isc::Unexpected); +} + // Test the findAll method. TYPED_TEST(DatabaseClientTest, getAll) { // The domain doesn't exist, so we must get the right NSEC From 0d0b9b0ebea1a12b35cdd646700f332c9f5a7cb5 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Thu, 15 Dec 2011 14:16:53 +0100 Subject: [PATCH 07/12] [1483] Enable any mode on getRRsets --- src/lib/datasrc/database.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc index bc55cdfb9d..fcf18aff9b 100644 --- a/src/lib/datasrc/database.cc +++ b/src/lib/datasrc/database.cc @@ -597,7 +597,7 @@ DatabaseClient::Finder::findWildcardMatch( // RFC 4592 section 4.4). // Search for a match. The types are the same as with original query. FoundRRsets found = getRRsets(wildcard, final_types, true, - &construct_name); + &construct_name, type == RRType::ANY()); if (found.first) { // Found something - but what? @@ -863,7 +863,8 @@ DatabaseClient::Finder::findInternal(const isc::dns::Name& name, WantedTypes final_types(FINAL_TYPES()); final_types.insert(type); const FoundRRsets found = getRRsets(name.toText(), final_types, - !is_origin); + !is_origin, NULL, + type == RRType::ANY()); if (found.first) { // Something found at the domain name. Look into it further to get From 702631dc5f42c288ebb701eb5a8b67074f675de5 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Thu, 15 Dec 2011 14:24:44 +0100 Subject: [PATCH 08/12] [1483] Documentation --- src/lib/datasrc/database.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h index 31ab4328e2..fdbaa0ade5 100644 --- a/src/lib/datasrc/database.h +++ b/src/lib/datasrc/database.h @@ -925,6 +925,9 @@ public: /// for ZoneFinder::FindOptions. /// \param dresult Result of the search through the zone for a /// delegation. + /// \param target If the type happens to be ANY, it will insert all + /// the RRsets of the found name (if any is found) here instead + /// of being returned by the result. /// /// \return Tuple holding the result of the search - the RRset of the /// wildcard records matching the name, together with a status @@ -1005,6 +1008,9 @@ public: /// for ZoneFinder::FindOptions. /// \param dresult Result of the search through the zone for a /// delegation. + /// \param target If the query is for type ANY, the successfull result, + /// if there happens to be one, will be returned through the + /// parameter, as it doesn't fit into the result. /// /// \return Tuple holding the result of the search - the RRset of the /// wildcard records matching the name, together with a status From 86b08bc45b6e3c8934971625b8b189012ef51357 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Thu, 15 Dec 2011 14:35:25 +0100 Subject: [PATCH 09/12] [1483] Logging for any queries --- src/lib/datasrc/database.cc | 10 +++++++--- src/lib/datasrc/datasrc_messages.mes | 9 +++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc index fcf18aff9b..9214de953e 100644 --- a/src/lib/datasrc/database.cc +++ b/src/lib/datasrc/database.cc @@ -728,7 +728,10 @@ DatabaseClient::Finder::findOnNameResult(const Name& name, DATASRC_DATABASE_FOUND_CNAME)); } else if (wti != found.second.end()) { - if (type == RRType::ANY()) { + bool any(type == RRType::ANY()); + isc::log::MessageID lid(wild ? DATASRC_DATABASE_WILDCARD_MATCH : + DATASRC_DATABASE_FOUND_RRSET); + if (any) { // An ANY query, copy everything to the target instead of returning // directly. for (FoundIterator it(found.second.begin()); @@ -738,6 +741,8 @@ DatabaseClient::Finder::findOnNameResult(const Name& name, target->push_back(it->second); } } + lid = wild ? DATASRC_DATABASE_WILDCARD_ANY : + DATASRC_DATABASE_FOUND_ANY; } // Found an RR matching the query, so return it. (Note that this // includes the case where we were explicitly querying for a CNAME and @@ -745,8 +750,7 @@ DatabaseClient::Finder::findOnNameResult(const Name& name, // NS RRset and found it at the apex of the zone.) return (logAndCreateResult(name, wildname, type, wild ? WILDCARD : SUCCESS, wti->second, - wild ? DATASRC_DATABASE_WILDCARD_MATCH : - DATASRC_DATABASE_FOUND_RRSET)); + lid)); } // If we get here, we have found something at the requested name but not diff --git a/src/lib/datasrc/datasrc_messages.mes b/src/lib/datasrc/datasrc_messages.mes index 01fb0825f6..fd46896aad 100644 --- a/src/lib/datasrc/datasrc_messages.mes +++ b/src/lib/datasrc/datasrc_messages.mes @@ -78,6 +78,10 @@ different TTL values. This isn't allowed on the wire and is considered an error, so we set it to the lowest value we found (but we don't modify the database). The data in database should be checked and fixed. +% DATASRC_DATABASE_FOUND_ANY search in datasource %1 resulted in returning all records of %2 +The data returned by the database backend contained data for the given domain +name, so all the RRsets of the domain are returned. + % DATASRC_DATABASE_FOUND_CNAME search in datasource %1 for %2/%3/%4 found CNAME, resulting in %5 When searching the domain for a name a CNAME was found at that name. Even though it was not the RR type being sought, it is returned. (The @@ -178,6 +182,11 @@ whether the data is still valid. The zone name, its class, and the underlying database name as well as the error message thrown from the database module are shown in the log message. +% DATASRC_DATABASE_WILDCARD_ANY search in datasource %1 resulted in wildcard match type ANY on %2 +The database doesn't contain directly matching name. When searching +for a wildcard match, a wildcard record matching the name of the query +containing some RRsets was found. All the RRsets of the node are returned. + % DATASRC_DATABASE_WILDCARD_CANCEL_NS canceled wildcard match on %3 because %2 contains NS (data source %1) The database was queried to provide glue data and it didn't find direct match. It could create it from given wildcard, but matching wildcards is forbidden From 30b1cc45e2b536acdf0216a02b88de39c4fce4b3 Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Fri, 16 Dec 2011 13:42:57 +0100 Subject: [PATCH 10/12] [1483] Remove unused loop and control variable Unrelated cleanup. --- src/bin/auth/query.cc | 280 +++++++++++++++++++++--------------------- 1 file changed, 138 insertions(+), 142 deletions(-) diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc index ef7653fb7e..2bf8f5e8fb 100644 --- a/src/bin/auth/query.cc +++ b/src/bin/auth/query.cc @@ -230,7 +230,6 @@ Query::addAuthAdditional(ZoneFinder& finder) { void Query::process() { - bool keep_doing = true; const bool qtype_is_any = (qtype_ == RRType::ANY()); response_.setHeaderFlag(Message::HEADERFLAG_AA, false); @@ -252,154 +251,151 @@ Query::process() { // Found a zone which is the nearest ancestor to QNAME, set the AA bit response_.setHeaderFlag(Message::HEADERFLAG_AA); response_.setRcode(Rcode::NOERROR()); - while (keep_doing) { - keep_doing = false; - std::vector target; - boost::function0 find; - if (qtype_is_any) { - find = boost::bind(&ZoneFinder::findAll, &zfinder, qname_, - boost::ref(target), dnssec_opt_); - } else { - find = boost::bind(&ZoneFinder::find, &zfinder, qname_, qtype_, - dnssec_opt_); - } - ZoneFinder::FindResult db_result(find()); - switch (db_result.code) { - case ZoneFinder::DNAME: { - // First, put the dname into the answer - response_.addRRset(Message::SECTION_ANSWER, - boost::const_pointer_cast(db_result.rrset), - dnssec_); + std::vector target; + boost::function0 find; + if (qtype_is_any) { + find = boost::bind(&ZoneFinder::findAll, &zfinder, qname_, + boost::ref(target), dnssec_opt_); + } else { + find = boost::bind(&ZoneFinder::find, &zfinder, qname_, qtype_, + dnssec_opt_); + } + ZoneFinder::FindResult db_result(find()); + switch (db_result.code) { + case ZoneFinder::DNAME: { + // First, put the dname into the answer + response_.addRRset(Message::SECTION_ANSWER, + boost::const_pointer_cast(db_result.rrset), + dnssec_); + /* + * Empty DNAME should never get in, as it is impossible to + * create one in master file. + * + * FIXME: Other way to prevent this should be done + */ + assert(db_result.rrset->getRdataCount() > 0); + // Get the data of DNAME + const rdata::generic::DNAME& dname( + dynamic_cast( + db_result.rrset->getRdataIterator()->getCurrent())); + // The yet unmatched prefix dname + const Name prefix(qname_.split(0, qname_.getLabelCount() - + db_result.rrset->getName().getLabelCount())); + // If we put it together, will it be too long? + // (The prefix contains trailing ., which will be removed + if (prefix.getLength() - Name::ROOT_NAME().getLength() + + dname.getDname().getLength() > Name::MAX_WIRE) { /* - * Empty DNAME should never get in, as it is impossible to - * create one in master file. - * - * FIXME: Other way to prevent this should be done + * In case the synthesized name is too long, section 4.1 + * of RFC 2672 mandates we return YXDOMAIN. */ - assert(db_result.rrset->getRdataCount() > 0); - // Get the data of DNAME - const rdata::generic::DNAME& dname( - dynamic_cast( - db_result.rrset->getRdataIterator()->getCurrent())); - // The yet unmatched prefix dname - const Name prefix(qname_.split(0, qname_.getLabelCount() - - db_result.rrset->getName().getLabelCount())); - // If we put it together, will it be too long? - // (The prefix contains trailing ., which will be removed - if (prefix.getLength() - Name::ROOT_NAME().getLength() + - dname.getDname().getLength() > Name::MAX_WIRE) { - /* - * In case the synthesized name is too long, section 4.1 - * of RFC 2672 mandates we return YXDOMAIN. - */ - response_.setRcode(Rcode::YXDOMAIN()); - return; - } - // The new CNAME we are creating (it will be unsigned even - // with DNSSEC, the DNAME is signed and it can be validated - // by that) - RRsetPtr cname(new RRset(qname_, db_result.rrset->getClass(), - RRType::CNAME(), db_result.rrset->getTTL())); - // Construct the new target by replacing the end - cname->addRdata(rdata::generic::CNAME(qname_.split(0, - qname_.getLabelCount() - - db_result.rrset->getName().getLabelCount()). - concatenate(dname.getDname()))); - response_.addRRset(Message::SECTION_ANSWER, cname, dnssec_); - break; + response_.setRcode(Rcode::YXDOMAIN()); + return; } - 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 - * what we expected. It means no exceptions in ANY or NS - * on the origin (though CNAME in origin is probably - * forbidden anyway). - * - * So, just put it there. - */ + // The new CNAME we are creating (it will be unsigned even + // with DNSSEC, the DNAME is signed and it can be validated + // by that) + RRsetPtr cname(new RRset(qname_, db_result.rrset->getClass(), + RRType::CNAME(), db_result.rrset->getTTL())); + // Construct the new target by replacing the end + cname->addRdata(rdata::generic::CNAME(qname_.split(0, + qname_.getLabelCount() - + db_result.rrset->getName().getLabelCount()). + concatenate(dname.getDname()))); + response_.addRRset(Message::SECTION_ANSWER, cname, dnssec_); + 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 + * what we expected. It means no exceptions in ANY or NS + * on the origin (though CNAME in origin is probably + * forbidden anyway). + * + * So, just put it there. + */ + response_.addRRset(Message::SECTION_ANSWER, + boost::const_pointer_cast(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: + if (qtype_is_any) { + // If quety type is ANY, insert all RRs under the domain + // into answer section. + BOOST_FOREACH(ConstRRsetPtr rrset, target) { + response_.addRRset(Message::SECTION_ANSWER, + boost::const_pointer_cast(rrset), dnssec_); + // Handle additional for answer section + addAdditional(*result.zone_finder, *rrset.get()); + } + } else { response_.addRRset(Message::SECTION_ANSWER, boost::const_pointer_cast(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: - if (qtype_is_any) { - // If quety type is ANY, insert all RRs under the domain - // into answer section. - BOOST_FOREACH(ConstRRsetPtr rrset, target) { - response_.addRRset(Message::SECTION_ANSWER, - boost::const_pointer_cast(rrset), dnssec_); - // Handle additional for answer section - addAdditional(*result.zone_finder, *rrset.get()); - } - } else { - response_.addRRset(Message::SECTION_ANSWER, - boost::const_pointer_cast(db_result.rrset), - dnssec_); - // Handle additional for answer section - addAdditional(*result.zone_finder, *db_result.rrset); - } - // If apex NS records haven't been provided in the answer - // section, insert apex NS records into the authority section - // and AAAA/A RRS of each of the NS RDATA into the additional - // section. - if (qname_ != result.zone_finder->getOrigin() || - db_result.code != ZoneFinder::SUCCESS || - (qtype_ != RRType::NS() && !qtype_is_any)) - { - addAuthAdditional(*result.zone_finder); - } - - // 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) { - addWildcardProof(*result.zone_finder); - } - break; - case ZoneFinder::DELEGATION: - response_.setHeaderFlag(Message::HEADERFLAG_AA, false); - response_.addRRset(Message::SECTION_AUTHORITY, - boost::const_pointer_cast(db_result.rrset), - dnssec_); + // Handle additional for answer section addAdditional(*result.zone_finder, *db_result.rrset); - break; - case ZoneFinder::NXDOMAIN: - response_.setRcode(Rcode::NXDOMAIN()); - addSOA(*result.zone_finder); - if (dnssec_ && db_result.rrset) { - addNXDOMAINProof(zfinder, db_result.rrset); - } - break; - case ZoneFinder::NXRRSET: - addSOA(*result.zone_finder); - if (dnssec_ && db_result.rrset) { - response_.addRRset(Message::SECTION_AUTHORITY, - boost::const_pointer_cast( - db_result.rrset), - dnssec_); - } - break; - case ZoneFinder::WILDCARD_NXRRSET: - addSOA(*result.zone_finder); - if (dnssec_ && db_result.rrset) { - addWildcardNXRRSETProof(zfinder, db_result.rrset); - } - break; - default: - // This is basically a bug of the data source implementation, - // but could also happen in the middle of development where - // we try to add a new result code. - isc_throw(isc::NotImplemented, "Unknown result code"); - break; - } + } + // If apex NS records haven't been provided in the answer + // section, insert apex NS records into the authority section + // and AAAA/A RRS of each of the NS RDATA into the additional + // section. + if (qname_ != result.zone_finder->getOrigin() || + db_result.code != ZoneFinder::SUCCESS || + (qtype_ != RRType::NS() && !qtype_is_any)) + { + addAuthAdditional(*result.zone_finder); + } + + // 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) { + addWildcardProof(*result.zone_finder); + } + break; + case ZoneFinder::DELEGATION: + response_.setHeaderFlag(Message::HEADERFLAG_AA, false); + response_.addRRset(Message::SECTION_AUTHORITY, + boost::const_pointer_cast(db_result.rrset), + dnssec_); + addAdditional(*result.zone_finder, *db_result.rrset); + break; + case ZoneFinder::NXDOMAIN: + response_.setRcode(Rcode::NXDOMAIN()); + addSOA(*result.zone_finder); + if (dnssec_ && db_result.rrset) { + addNXDOMAINProof(zfinder, db_result.rrset); + } + break; + case ZoneFinder::NXRRSET: + addSOA(*result.zone_finder); + if (dnssec_ && db_result.rrset) { + response_.addRRset(Message::SECTION_AUTHORITY, + boost::const_pointer_cast( + db_result.rrset), + dnssec_); + } + break; + case ZoneFinder::WILDCARD_NXRRSET: + addSOA(*result.zone_finder); + if (dnssec_ && db_result.rrset) { + addWildcardNXRRSETProof(zfinder, db_result.rrset); + } + break; + default: + // This is basically a bug of the data source implementation, + // but could also happen in the middle of development where + // we try to add a new result code. + isc_throw(isc::NotImplemented, "Unknown result code"); + break; } } From 424113eeebb77e6edac02231a64595729bc04bbc Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Fri, 16 Dec 2011 13:47:06 +0100 Subject: [PATCH 11/12] [1483] Typo in documentation --- src/lib/datasrc/zone.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h index bb2f27f68e..485eedaef5 100644 --- a/src/lib/datasrc/zone.h +++ b/src/lib/datasrc/zone.h @@ -289,7 +289,7 @@ public: /// copied into the \c target parameter and the rrset member of the result /// is NULL. All the other (unsuccessful) cases are handled the same, /// including returning delegations, NSEC/NSEC3 proofs, etc. The options - /// parameter works the same way and it should comfort to the same exception + /// parameter works the same way and it should conform to the same exception /// restrictions. virtual FindResult findAll(const isc::dns::Name& name, std::vector &target, From 87a72f002abc5c6db9baeb3b3e2ac20c0a1e24ce Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Mon, 19 Dec 2011 18:04:08 +0100 Subject: [PATCH 12/12] [1483] Doxygen --- src/lib/datasrc/zone.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h index 485eedaef5..77e1148c15 100644 --- a/src/lib/datasrc/zone.h +++ b/src/lib/datasrc/zone.h @@ -291,6 +291,11 @@ public: /// including returning delegations, NSEC/NSEC3 proofs, etc. The options /// parameter works the same way and it should conform to the same exception /// restrictions. + /// + /// \param name \see find, parameter name + /// \param target the successfull result is returned through this + /// \param options \see find, parameter options + /// \return \see find and it's result virtual FindResult findAll(const isc::dns::Name& name, std::vector &target, const FindOptions options = FIND_DEFAULT) = 0;