|
@@ -22,6 +22,7 @@
|
|
|
|
|
|
#include <dns/rrttl.h>
|
|
#include <dns/rrttl.h>
|
|
#include <dns/rdataclass.h>
|
|
#include <dns/rdataclass.h>
|
|
|
|
+#include <dns/rrclass.h>
|
|
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <gtest/gtest.h>
|
|
#include <boost/shared_ptr.hpp>
|
|
#include <boost/shared_ptr.hpp>
|
|
@@ -35,6 +36,7 @@
|
|
#include "../nsas_entry_compare.h"
|
|
#include "../nsas_entry_compare.h"
|
|
#include "../nameserver_entry.h"
|
|
#include "../nameserver_entry.h"
|
|
#include "../zone_entry.h"
|
|
#include "../zone_entry.h"
|
|
|
|
+#include "../address_request_callback.h"
|
|
#include "nsas_test.h"
|
|
#include "nsas_test.h"
|
|
|
|
|
|
using namespace isc::dns;
|
|
using namespace isc::dns;
|
|
@@ -55,9 +57,10 @@ public:
|
|
///
|
|
///
|
|
/// \param hashsize Size of the zone hash table
|
|
/// \param hashsize Size of the zone hash table
|
|
/// \param lrusize Size of the zone hash table
|
|
/// \param lrusize Size of the zone hash table
|
|
- DerivedNsas(ResolverInterface& resolver, uint32_t hashsize,
|
|
|
|
|
|
+ DerivedNsas(shared_ptr<TestResolver> resolver, uint32_t hashsize,
|
|
uint32_t lrusize) :
|
|
uint32_t lrusize) :
|
|
- NameserverAddressStore(resolver, hashsize, lrusize)
|
|
|
|
|
|
+ NameserverAddressStore(resolver, hashsize, lrusize),
|
|
|
|
+ resolver_(resolver)
|
|
{}
|
|
{}
|
|
|
|
|
|
/// \brief Virtual Destructor
|
|
/// \brief Virtual Destructor
|
|
@@ -67,16 +70,39 @@ public:
|
|
/// \brief Add Nameserver Entry to Hash and LRU Tables
|
|
/// \brief Add Nameserver Entry to Hash and LRU Tables
|
|
void AddNameserverEntry(boost::shared_ptr<NameserverEntry>& entry) {
|
|
void AddNameserverEntry(boost::shared_ptr<NameserverEntry>& entry) {
|
|
HashKey h = entry->hashKey();
|
|
HashKey h = entry->hashKey();
|
|
- nameserver_hash_.add(entry, h);
|
|
|
|
- nameserver_lru_.add(entry);
|
|
|
|
|
|
+ nameserver_hash_->add(entry, h);
|
|
|
|
+ nameserver_lru_->add(entry);
|
|
}
|
|
}
|
|
|
|
|
|
/// \brief Add Zone Entry to Hash and LRU Tables
|
|
/// \brief Add Zone Entry to Hash and LRU Tables
|
|
void AddZoneEntry(boost::shared_ptr<ZoneEntry>& entry) {
|
|
void AddZoneEntry(boost::shared_ptr<ZoneEntry>& entry) {
|
|
HashKey h = entry->hashKey();
|
|
HashKey h = entry->hashKey();
|
|
- zone_hash_.add(entry, h);
|
|
|
|
- zone_lru_.add(entry);
|
|
|
|
|
|
+ zone_hash_->add(entry, h);
|
|
|
|
+ zone_lru_->add(entry);
|
|
}
|
|
}
|
|
|
|
+ /**
|
|
|
|
+ * \short Just wraps the common lookup
|
|
|
|
+ *
|
|
|
|
+ * It calls the lookup and provides the authority section
|
|
|
|
+ * if it is asked for by the resolver.
|
|
|
|
+ */
|
|
|
|
+ void lookupAndAnswer(const string& name, const RRClass& class_code,
|
|
|
|
+ shared_ptr<AbstractRRset> authority,
|
|
|
|
+ shared_ptr<AddressRequestCallback> callback)
|
|
|
|
+ {
|
|
|
|
+ size_t size(resolver_->requests.size());
|
|
|
|
+ NameserverAddressStore::lookup(name, class_code, callback, ANY_OK);
|
|
|
|
+ // It asked something, the only thing it can ask is the NS list
|
|
|
|
+ if (size < resolver_->requests.size()) {
|
|
|
|
+ resolver_->provideNS(size, authority);
|
|
|
|
+ // Once answered, drop the request so noone else sees it
|
|
|
|
+ resolver_->requests.erase(resolver_->requests.begin() + size);
|
|
|
|
+ } else {
|
|
|
|
+ ADD_FAILURE() << "Not asked for NS";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+private:
|
|
|
|
+ shared_ptr<TestResolver> resolver_;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -89,22 +115,31 @@ protected:
|
|
authority_(new RRset(Name("example.net."), RRClass::IN(), RRType::NS(),
|
|
authority_(new RRset(Name("example.net."), RRClass::IN(), RRType::NS(),
|
|
RRTTL(128))),
|
|
RRTTL(128))),
|
|
empty_authority_(new RRset(Name("example.net."), RRClass::IN(),
|
|
empty_authority_(new RRset(Name("example.net."), RRClass::IN(),
|
|
- RRType::NS(), RRTTL(128)))
|
|
|
|
|
|
+ RRType::NS(), RRTTL(128))),
|
|
|
|
+ resolver_(new TestResolver)
|
|
{
|
|
{
|
|
- // Constructor - initialize a set of nameserver and zone objects. For convenience,
|
|
|
|
- // these are stored in vectors.
|
|
|
|
|
|
+ // Constructor - initialize a set of nameserver and zone objects. For
|
|
|
|
+ // convenience, these are stored in vectors.
|
|
for (int i = 1; i <= 9; ++i) {
|
|
for (int i = 1; i <= 9; ++i) {
|
|
- std::string name = "nameserver" + boost::lexical_cast<std::string>(i);
|
|
|
|
- nameservers_.push_back(boost::shared_ptr<NameserverEntry>(new NameserverEntry(name, (40 + i))));
|
|
|
|
|
|
+ std::string name = "nameserver" + boost::lexical_cast<std::string>(
|
|
|
|
+ i);
|
|
|
|
+ nameservers_.push_back(boost::shared_ptr<NameserverEntry>(
|
|
|
|
+ new NameserverEntry(name, RRClass(40 + i))));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // Some zones. They will not use the tables in this test, so it can be
|
|
|
|
+ // empty
|
|
for (int i = 1; i <= 9; ++i) {
|
|
for (int i = 1; i <= 9; ++i) {
|
|
std::string name = "zone" + boost::lexical_cast<std::string>(i);
|
|
std::string name = "zone" + boost::lexical_cast<std::string>(i);
|
|
- zones_.push_back(boost::shared_ptr<ZoneEntry>(new ZoneEntry(name, (40 + i))));
|
|
|
|
|
|
+ zones_.push_back(boost::shared_ptr<ZoneEntry>(new ZoneEntry(
|
|
|
|
+ resolver_, name, RRClass(40 + i),
|
|
|
|
+ shared_ptr<HashTable<NameserverEntry> >(),
|
|
|
|
+ shared_ptr<LruList<NameserverEntry> >())));
|
|
}
|
|
}
|
|
|
|
|
|
// A nameserver serving data
|
|
// A nameserver serving data
|
|
- authority_->addRdata(ConstRdataPtr(new rdata::generic::NS(Name("ns.example.com."))));
|
|
|
|
|
|
+ authority_->addRdata(ConstRdataPtr(new rdata::generic::NS(Name(
|
|
|
|
+ "ns.example.com."))));
|
|
|
|
|
|
// This is reused because of convenience, clear it just in case
|
|
// This is reused because of convenience, clear it just in case
|
|
NSASCallback::results.clear();
|
|
NSASCallback::results.clear();
|
|
@@ -116,7 +151,7 @@ protected:
|
|
|
|
|
|
RRsetPtr authority_, empty_authority_;
|
|
RRsetPtr authority_, empty_authority_;
|
|
|
|
|
|
- TestResolver defaultTestResolver;
|
|
|
|
|
|
+ shared_ptr<TestResolver> resolver_;
|
|
|
|
|
|
class NSASCallback : public AddressRequestCallback {
|
|
class NSASCallback : public AddressRequestCallback {
|
|
public:
|
|
public:
|
|
@@ -148,7 +183,7 @@ TEST_F(NameserverAddressStoreTest, ZoneDeletionCheck) {
|
|
|
|
|
|
// Create a NSAS with a hash size of three and a LRU size of 9 (both zone and
|
|
// Create a NSAS with a hash size of three and a LRU size of 9 (both zone and
|
|
// nameserver tables).
|
|
// nameserver tables).
|
|
- DerivedNsas nsas(defaultTestResolver, 2, 2);
|
|
|
|
|
|
+ DerivedNsas nsas(resolver_, 2, 2);
|
|
|
|
|
|
// Add six entries to the tables. After addition the reference count of each element
|
|
// Add six entries to the tables. After addition the reference count of each element
|
|
// should be 3 - one for the entry in the zones_ vector, and one each for the entries
|
|
// should be 3 - one for the entry in the zones_ vector, and one each for the entries
|
|
@@ -178,7 +213,7 @@ TEST_F(NameserverAddressStoreTest, NameserverDeletionCheck) {
|
|
|
|
|
|
// Create a NSAS with a hash size of three and a LRU size of 9 (both zone and
|
|
// Create a NSAS with a hash size of three and a LRU size of 9 (both zone and
|
|
// nameserver tables).
|
|
// nameserver tables).
|
|
- DerivedNsas nsas(defaultTestResolver, 2, 2);
|
|
|
|
|
|
+ DerivedNsas nsas(resolver_, 2, 2);
|
|
|
|
|
|
// Add six entries to the tables. After addition the reference count of each element
|
|
// Add six entries to the tables. After addition the reference count of each element
|
|
// should be 3 - one for the entry in the nameservers_ vector, and one each for the entries
|
|
// should be 3 - one for the entry in the nameservers_ vector, and one each for the entries
|
|
@@ -205,37 +240,29 @@ TEST_F(NameserverAddressStoreTest, NameserverDeletionCheck) {
|
|
* Check if it asks correct questions and it keeps correct internal state.
|
|
* Check if it asks correct questions and it keeps correct internal state.
|
|
*/
|
|
*/
|
|
TEST_F(NameserverAddressStoreTest, emptyLookup) {
|
|
TEST_F(NameserverAddressStoreTest, emptyLookup) {
|
|
- DerivedNsas nsas(defaultTestResolver, 10, 10);
|
|
|
|
|
|
+ DerivedNsas nsas(resolver_, 10, 10);
|
|
// Ask it a question
|
|
// Ask it a question
|
|
- nsas.lookup("example.net.", RRClass::IN().getCode(), *authority_,
|
|
|
|
- vector<AbstractRRset>(), getCallback());
|
|
|
|
- // It should ask for IP addresses for example.com.
|
|
|
|
- ASSERT_EQ(2, defaultTestResolver.requests.size());
|
|
|
|
- defaultTestResolver.asksIPs(Name("ns.example.com."), 0, 1);
|
|
|
|
|
|
+ nsas.lookupAndAnswer("example.net.", RRClass::IN(), authority_,
|
|
|
|
+ getCallback());
|
|
|
|
+ // It should ask for IP addresses for ns.example.com.
|
|
|
|
+ resolver_->asksIPs(Name("ns.example.com."), 0, 1);
|
|
|
|
|
|
// Ask another question for the same zone
|
|
// Ask another question for the same zone
|
|
- nsas.lookup("example.net.", RRClass::IN().getCode(), *authority_,
|
|
|
|
- vector<AbstractRRset>(), getCallback());
|
|
|
|
|
|
+ nsas.lookup("example.net.", RRClass::IN(), getCallback());
|
|
// It should ask no more questions now
|
|
// It should ask no more questions now
|
|
- EXPECT_EQ(2, defaultTestResolver.requests.size());
|
|
|
|
|
|
+ EXPECT_EQ(2, resolver_->requests.size());
|
|
|
|
|
|
// Ask another question with different zone but the same nameserver
|
|
// Ask another question with different zone but the same nameserver
|
|
authority_->setName(Name("example.com."));
|
|
authority_->setName(Name("example.com."));
|
|
- nsas.lookup("example.com.", RRClass::IN().getCode(), *authority_,
|
|
|
|
- vector<AbstractRRset>(), getCallback());
|
|
|
|
|
|
+ nsas.lookupAndAnswer("example.com.", RRClass::IN(), authority_,
|
|
|
|
+ getCallback());
|
|
// It still should ask nothing
|
|
// It still should ask nothing
|
|
- EXPECT_EQ(2, defaultTestResolver.requests.size());
|
|
|
|
|
|
+ EXPECT_EQ(2, resolver_->requests.size());
|
|
|
|
|
|
// We provide IP address of one nameserver, it should generate all the
|
|
// We provide IP address of one nameserver, it should generate all the
|
|
// results
|
|
// results
|
|
- RRsetPtr answer(new RRset(Name("example.com."), RRClass::IN(), RRType::A(),
|
|
|
|
- RRTTL(100)));
|
|
|
|
- answer->addRdata(rdata::in::A("192.0.2.1"));
|
|
|
|
- Message address(Message::RENDER); // Not able to create different one
|
|
|
|
- address.addRRset(Section::ANSWER(), answer);
|
|
|
|
- address.addRRset(Section::AUTHORITY(), authority_);
|
|
|
|
- address.addQuestion(defaultTestResolver[0]);
|
|
|
|
- defaultTestResolver.requests[0].second->success(address);
|
|
|
|
|
|
+ resolver_->answer(0, Name("ns.example.com."), RRType::A(),
|
|
|
|
+ rdata::in::A("192.0.2.1"));
|
|
EXPECT_EQ(3, NSASCallback::results.size());
|
|
EXPECT_EQ(3, NSASCallback::results.size());
|
|
BOOST_FOREACH(const NSASCallback::Result& result, NSASCallback::results) {
|
|
BOOST_FOREACH(const NSASCallback::Result& result, NSASCallback::results) {
|
|
EXPECT_TRUE(result.first);
|
|
EXPECT_TRUE(result.first);
|
|
@@ -249,12 +276,12 @@ TEST_F(NameserverAddressStoreTest, emptyLookup) {
|
|
* It should not ask anything and say it is unreachable right away.
|
|
* It should not ask anything and say it is unreachable right away.
|
|
*/
|
|
*/
|
|
TEST_F(NameserverAddressStoreTest, zoneWithoutNameservers) {
|
|
TEST_F(NameserverAddressStoreTest, zoneWithoutNameservers) {
|
|
- DerivedNsas nsas(defaultTestResolver, 10, 10);
|
|
|
|
|
|
+ DerivedNsas nsas(resolver_, 10, 10);
|
|
// Ask it a question
|
|
// Ask it a question
|
|
- nsas.lookup("example.net.", RRClass::IN().getCode(), *empty_authority_,
|
|
|
|
- vector<AbstractRRset>(), getCallback());
|
|
|
|
|
|
+ nsas.lookupAndAnswer("example.net.", RRClass::IN(), empty_authority_,
|
|
|
|
+ getCallback());
|
|
// There should be no questions, because there's nothing to ask
|
|
// There should be no questions, because there's nothing to ask
|
|
- EXPECT_EQ(0, defaultTestResolver.requests.size());
|
|
|
|
|
|
+ EXPECT_EQ(0, resolver_->requests.size());
|
|
// And there should be one „unreachable“ answer for the query
|
|
// And there should be one „unreachable“ answer for the query
|
|
ASSERT_EQ(1, NSASCallback::results.size());
|
|
ASSERT_EQ(1, NSASCallback::results.size());
|
|
EXPECT_FALSE(NSASCallback::results[0].first);
|
|
EXPECT_FALSE(NSASCallback::results[0].first);
|
|
@@ -268,35 +295,33 @@ TEST_F(NameserverAddressStoreTest, zoneWithoutNameservers) {
|
|
* without further asking.
|
|
* without further asking.
|
|
*/
|
|
*/
|
|
TEST_F(NameserverAddressStoreTest, unreachableNS) {
|
|
TEST_F(NameserverAddressStoreTest, unreachableNS) {
|
|
- DerivedNsas nsas(defaultTestResolver, 10, 10);
|
|
|
|
|
|
+ DerivedNsas nsas(resolver_, 10, 10);
|
|
// Ask it a question
|
|
// Ask it a question
|
|
- nsas.lookup("example.net.", RRClass::IN().getCode(), *authority_,
|
|
|
|
- vector<AbstractRRset>(), getCallback());
|
|
|
|
|
|
+ nsas.lookupAndAnswer("example.net.", RRClass::IN(), authority_,
|
|
|
|
+ getCallback());
|
|
// It should ask for IP addresses for example.com.
|
|
// It should ask for IP addresses for example.com.
|
|
- ASSERT_EQ(2, defaultTestResolver.requests.size());
|
|
|
|
- defaultTestResolver.asksIPs(Name("ns.example.com."), 0, 1);
|
|
|
|
|
|
+ ASSERT_EQ(2, resolver_->requests.size());
|
|
|
|
+ resolver_->asksIPs(Name("ns.example.com."), 0, 1);
|
|
|
|
|
|
// Ask another question with different zone but the same nameserver
|
|
// Ask another question with different zone but the same nameserver
|
|
authority_->setName(Name("example.com."));
|
|
authority_->setName(Name("example.com."));
|
|
- nsas.lookup("example.com.", RRClass::IN().getCode(), *authority_,
|
|
|
|
- vector<AbstractRRset>(), getCallback());
|
|
|
|
|
|
+ nsas.lookupAndAnswer("example.com.", RRClass::IN(), authority_,
|
|
|
|
+ getCallback());
|
|
// It should ask nothing more now
|
|
// It should ask nothing more now
|
|
- EXPECT_EQ(2, defaultTestResolver.requests.size());
|
|
|
|
|
|
+ EXPECT_EQ(2, resolver_->requests.size());
|
|
|
|
|
|
// We say there are no addresses
|
|
// We say there are no addresses
|
|
- defaultTestResolver.requests[0].second->failure();
|
|
|
|
- defaultTestResolver.requests[1].second->failure();
|
|
|
|
|
|
+ resolver_->requests[0].second->failure();
|
|
|
|
+ resolver_->requests[1].second->failure();
|
|
|
|
|
|
// We should have 2 answers now
|
|
// We should have 2 answers now
|
|
EXPECT_EQ(2, NSASCallback::results.size());
|
|
EXPECT_EQ(2, NSASCallback::results.size());
|
|
// When we ask one same and one other zone with the same nameserver,
|
|
// When we ask one same and one other zone with the same nameserver,
|
|
// it should generate no questions and answer right away
|
|
// it should generate no questions and answer right away
|
|
- authority_->setName(Name("example.net."));
|
|
|
|
- nsas.lookup("example.net.", RRClass::IN().getCode(), *authority_,
|
|
|
|
- vector<AbstractRRset>(), getCallback());
|
|
|
|
|
|
+ nsas.lookup("example.net.", RRClass::IN(), getCallback());
|
|
authority_->setName(Name("example.org."));
|
|
authority_->setName(Name("example.org."));
|
|
- nsas.lookup("example.org.", RRClass::IN().getCode(), *authority_,
|
|
|
|
- vector<AbstractRRset>(), getCallback());
|
|
|
|
|
|
+ nsas.lookupAndAnswer("example.org.", RRClass::IN(), authority_,
|
|
|
|
+ getCallback());
|
|
// There should be 4 negative answers now
|
|
// There should be 4 negative answers now
|
|
EXPECT_EQ(4, NSASCallback::results.size());
|
|
EXPECT_EQ(4, NSASCallback::results.size());
|
|
BOOST_FOREACH(const NSASCallback::Result& result, NSASCallback::results) {
|
|
BOOST_FOREACH(const NSASCallback::Result& result, NSASCallback::results) {
|
|
@@ -304,27 +329,11 @@ TEST_F(NameserverAddressStoreTest, unreachableNS) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-/// \short Test invalid authority section.
|
|
|
|
-TEST_F(NameserverAddressStoreTest, invalidAuthority) {
|
|
|
|
- DerivedNsas nsas(defaultTestResolver, 2, 2);
|
|
|
|
- EXPECT_THROW(nsas.lookup("example.net.", RRClass::CH().getCode(),
|
|
|
|
- *authority_, vector<AbstractRRset>(), getCallback()),
|
|
|
|
- InconsistentZone);
|
|
|
|
- EXPECT_EQ(0, defaultTestResolver.requests.size());
|
|
|
|
- EXPECT_EQ(0, NSASCallback::results.size());
|
|
|
|
- EXPECT_THROW(nsas.lookup("example.com.", RRClass::IN().getCode(),
|
|
|
|
- *authority_, vector<AbstractRRset>(), getCallback()),
|
|
|
|
- InconsistentZone);
|
|
|
|
- EXPECT_EQ(0, defaultTestResolver.requests.size());
|
|
|
|
- EXPECT_EQ(0, NSASCallback::results.size());
|
|
|
|
- BasicRRset aAuthority(Name("example.net."), RRClass::IN(), RRType::A(),
|
|
|
|
- RRTTL(128));
|
|
|
|
- EXPECT_THROW(nsas.lookup("example.net.", RRClass::IN().getCode(),
|
|
|
|
- aAuthority, vector<AbstractRRset>(),
|
|
|
|
- getCallback()), NotNS);
|
|
|
|
- EXPECT_EQ(0, defaultTestResolver.requests.size());
|
|
|
|
- EXPECT_EQ(0, NSASCallback::results.size());
|
|
|
|
-}
|
|
|
|
|
|
+/*
|
|
|
|
+ * TODO: More tests. Some eviction combined with lookups would make sense.
|
|
|
|
+ * Stressing the entries that some nameservers for zone are there and some
|
|
|
|
+ * are not, etc.
|
|
|
|
+ */
|
|
|
|
|
|
} // namespace nsas
|
|
} // namespace nsas
|
|
} // namespace isc
|
|
} // namespace isc
|