Commit d332e57d authored by Stephen Morris's avatar Stephen Morris

Add first part of the main NameserverAddressStore class.


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac356@3420 e5f2f494-b856-4b98-b285-d166d9295462
parent c3e43320
......@@ -8,13 +8,16 @@ AM_CXXFLAGS = $(B10_CXXFLAGS)
lib_LTLIBRARIES = libnsas.la
libnsas_la_SOURCES = address_entry.h address_entry.cc
libnsas_la_SOURCES += asiolink.h
libnsas_la_SOURCES += hash.cc hash.h
libnsas_la_SOURCES += hash_deleter.h
libnsas_la_SOURCES += hash_key.cc hash_key.h
libnsas_la_SOURCES += hash_table.h
libnsas_la_SOURCES += lru_list.h
libnsas_la_SOURCES += nameserver_address_store.cc nameserver_address_store.h
libnsas_la_SOURCES += nameserver_entry.cc nameserver_entry.h
libnsas_la_SOURCES += nsas_entry_compare.h
libnsas_la_SOURCES += nsas_entry.h
libnsas_la_SOURCES += asiolink.h
libnsas_la_SOURCES += zone_entry.h
CLEANFILES = *.gcno *.gcda
......@@ -19,6 +19,7 @@
#include <boost/shared_ptr.hpp>
#include "hash_table.h"
#include "lru_list.h"
namespace isc {
namespace nsas {
......@@ -53,7 +54,7 @@ public:
/// Performs the deletion of the zone entry from the hash table.
///
/// \param element Element to be deleted
virtual void operator()(boost::shared_ptr<T>& element);
virtual void operator()(T* element) const;
private:
HashTable<T>& hashtable_; ///< Hash table to access element
......@@ -61,7 +62,7 @@ private:
// delete the object from the relevant hash table
template <class T>
void HashDeleter<T>::operator()(boost::shared_ptr<T>& element) {
void HashDeleter<T>::operator()(T* element) const {
hashtable_.remove(element->hashKey());
}
......
......@@ -66,7 +66,7 @@ public:
/// LRU list.
///
/// \param drop Object being dropped.
virtual void operator()(boost::shared_ptr<T>& drop) = 0;
virtual void operator()(T* drop) const = 0;
};
/// \brief Constructor
......@@ -171,7 +171,7 @@ void LruList<T>::add(boost::shared_ptr<T>& element) {
// to-be-dropped object.
if (dropped_) {
(*dropped_)(*lru_.begin());
(*dropped_)(lru_.begin()->get());
}
// ... and get rid of it from the list
......
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <boost/shared_ptr.hpp>
#include "config.h"
#include "hash_deleter.h"
#include "nsas_entry_compare.h"
#include "nameserver_entry.h"
#include "nameserver_address_store.h"
#include "zone_entry.h"
namespace isc {
namespace nsas {
// Constructor.
//
// The LRU lists are set equal to three times the size of the respective
// hash table, on the assumption that three elements is the longest linear
// search we want to do when looking up names in the hash table.
NameserverAddressStore::NameserverAddressStore(uint32_t zonehashsize,
uint32_t nshashsize) :
zone_hash_(new NsasEntryCompare<ZoneEntry>, zonehashsize),
nameserver_hash_(new NsasEntryCompare<NameserverEntry>, nshashsize),
zone_lru_((3 * zonehashsize), new HashDeleter<ZoneEntry>(zone_hash_)),
nameserver_lru_((3 * nshashsize), new HashDeleter<NameserverEntry>(nameserver_hash_))
{
}
} // namespace nsas
} // namespace isc
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#ifndef __NAMESERVER_ADDRESS_STORE_H
#define __NAMESERVER_ADDRESS_STORE_H
#include <string>
#include <vector>
#include "rrset.h"
#include "address_request_callback.h"
#include "hash_table.h"
#include "nameserver_entry.h"
#include "lru_list.h"
#include "zone_entry.h"
namespace isc {
namespace nsas {
/// \brief Nameserver Address Store
///
/// This class implements the bare bones of the nameserver address store - the
/// storage of nameserver information. An additional layer above it implements
/// the logic for sending queries for the nameserver addresses if they are not
/// in the store.
class NameserverAddressStore {
public:
/// \brief Constructor
///
/// The constructor sizes all the tables. As there are various
/// relationships between the table sizes, and as some values are best as
/// prime numbers, the table sizes are determined by compile-time values.
///
/// \param zonehashsize Size of the zone hash table. The default value of
/// 1009 is the first prime number above 1000.
/// \param nshash size Size of the nameserver hash table. The default
/// value of 2003 is the first prime number over 2000, and by implication,
/// there is an assumption that there will be more nameservers than zones
/// in the store.
NameserverAddressStore(uint32_t zonehashsize = 1009,
uint32_t nshashsize = 3001);
/// \brief Destructor
///
/// Empty virtual destructor.
virtual ~NameserverAddressStore()
{}
/// \brief Lookup Address for a Zone
///
/// Looks up the address of a nameserver in the zone.
///
/// \param zone Name of zone for which an address is required.
/// \param authority Authority RRset from the referral containing the
/// nameservers that serve the zone.
/// \param additional Additional RRset(s) for authority information. These
/// are taken from the referral.
/// \param callback Callback object used to pass the result back to the
/// caller.
/* void lookup(const std::string& zone, isc::dns::AbstractRRset& authority,
const std::vector<isc::dns::AbstractRRset>& additional
boost::shared_ptr<isc::dns::AddressRequestCallback> callback ); */
/// \brief Protected Members
///
/// These members should be private. However, with so few public methods
/// and with a lot of internal processing, the testing of this class is
/// problematical.
///
/// To get round this, a number of elements are declared protected. This
/// means that tests can be carried out by testing a subclass. The subclass
/// does not override the main class methods, but does contain additional
/// methods to set up data and examine the internal state of the class.
//@{
protected:
// Zone and nameserver hash tables
HashTable<ZoneEntry> zone_hash_;
HashTable<NameserverEntry> nameserver_hash_;
// ... and the LRU lists
LruList<ZoneEntry> zone_lru_;
LruList<NameserverEntry> nameserver_lru_;
//}@
};
} // namespace nsas
} // namespace isc
#endif // __NAMESERVER_ADDRESS_STORE_H
......@@ -87,9 +87,9 @@ public:
/// \brief Constructor where no A records are supplied.
///
/// \param name Name of the nameserver,
/// \param classCode class of the nameserver
NameserverEntry(const std::string& name, uint16_t classCode) :
name_(name), classCode_(classCode)
/// \param class_code class of the nameserver
NameserverEntry(const std::string& name, uint16_t class_code) :
name_(name), classCode_(class_code)
{}
/// Constructor where one or more RRsets of A/AAAA records are supplied.
......
......@@ -23,9 +23,11 @@ run_unittests_SOURCES += hash_key_unittest.cc
run_unittests_SOURCES += hash_table_unittest.cc
run_unittests_SOURCES += hash_unittest.cc
run_unittests_SOURCES += lru_list_unittest.cc
run_unittests_SOURCES += nameserver_address_store_unittest.cc
run_unittests_SOURCES += nameserver_entry_unittest.cc
run_unittests_SOURCES += nsas_entry_compare_unittest.cc
run_unittests_SOURCES += nsas_test_utilities.h
run_unittests_SOURCES += zone_entry_unittest.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
......
......@@ -39,7 +39,7 @@ namespace nsas {
/// MS bit on the 16-bit class value.
class Dropped : public LruList<TestEntry>::Dropped {
public:
virtual void operator()(boost::shared_ptr<TestEntry>& entry) {
virtual void operator()(TestEntry* entry) const {
entry->setClass(entry->getClass() | 0x8000);
}
};
......
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
/// \brief Test Deleter Objects
///
/// This file contains tests for the "deleter" classes within the nameserver
/// address store. These act to delete zones from the zone hash table when
/// the element reaches the top of the LRU list.
#include <gtest/gtest.h>
#include <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include <string.h>
#include <vector>
#include "nameserver_address_store.h"
#include "nsas_entry_compare.h"
#include "nameserver_entry.h"
#include "zone_entry.h"
#include "nsas_test.h"
namespace isc {
namespace nsas {
/// \brief NSAS Store
///
/// This is a subclass of the NameserverAddressStore class, with methods to
/// access the internal members to check that the deleter objects are working.
class DerivedNsas : public NameserverAddressStore {
public:
/// \brief Constructor
///
/// \param hashsize Size of the zone hash table
/// \param lrusize Size of the zone hash table
DerivedNsas(uint32_t hashsize, uint32_t lrusize) :
NameserverAddressStore(hashsize, lrusize)
{}
/// \brief Virtual Destructor
virtual ~DerivedNsas()
{}
/// \brief Add Nameserver Entry to Hash and LRU Tables
void AddNameserverEntry(boost::shared_ptr<NameserverEntry>& entry) {
HashKey h = entry->hashKey();
nameserver_hash_.add(entry, h);
nameserver_lru_.add(entry);
}
/// \brief Add Zone Entry to Hash and LRU Tables
void AddZoneEntry(boost::shared_ptr<ZoneEntry>& entry) {
HashKey h = entry->hashKey();
zone_hash_.add(entry, h);
zone_lru_.add(entry);
}
};
/// \brief Text Fixture Class
class NameserverAddressStoreTest : public ::testing::Test {
protected:
// Constructor - initialize a set of nameserver and zone objects. For convenience,
// these are stored in vectors.
NameserverAddressStoreTest()
{
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))));
}
for (int i = 1; i <= 9; ++i) {
std::string name = "zone" + boost::lexical_cast<std::string>(i);
zones_.push_back(boost::shared_ptr<ZoneEntry>(new ZoneEntry(name, (40 + i))));
}
}
// Vector of pointers to nameserver and zone entries.
std::vector<boost::shared_ptr<NameserverEntry> > nameservers_;
std::vector<boost::shared_ptr<ZoneEntry> > zones_;
};
/// \brief Remove Zone Entry from Hash Table
///
/// Check that when an entry reaches the top of the zone LRU list, it is removed from the
/// hash table as well.
TEST_F(NameserverAddressStoreTest, ZoneDeletionCheck) {
// Create a NSAS with a hash size of three and a LRU size of 9 (both zone and
// nameserver tables).
DerivedNsas nsas(2, 2);
// 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
// in the LRU list and hash table.
for (int i = 1; i <= 6; ++i) {
EXPECT_EQ(1, zones_[i].use_count());
nsas.AddZoneEntry(zones_[i]);
EXPECT_EQ(3, zones_[i].use_count());
}
// Adding another entry should cause the first one to drop off the LRU list, which
// should also trigger the deletion of the entry from the hash table. This should
// reduce its use count to 1.
EXPECT_EQ(1, zones_[7].use_count());
nsas.AddZoneEntry(zones_[7]);
EXPECT_EQ(3, zones_[7].use_count());
EXPECT_EQ(1, zones_[1].use_count());
}
/// \brief Remove Entry from Hash Table
///
/// Check that when an entry reaches the top of the LRU list, it is removed from the
/// hash table as well.
TEST_F(NameserverAddressStoreTest, NameserverDeletionCheck) {
// Create a NSAS with a hash size of three and a LRU size of 9 (both zone and
// nameserver tables).
DerivedNsas nsas(2, 2);
// 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
// in the LRU list and hash table.
for (int i = 1; i <= 6; ++i) {
EXPECT_EQ(1, nameservers_[i].use_count());
nsas.AddNameserverEntry(nameservers_[i]);
EXPECT_EQ(3, nameservers_[i].use_count());
}
// Adding another entry should cause the first one to drop off the LRU list, which
// should also trigger the deletion of the entry from the hash table. This should
// reduce its use count to 1.
EXPECT_EQ(1, nameservers_[7].use_count());
nsas.AddNameserverEntry(nameservers_[7]);
EXPECT_EQ(3, nameservers_[7].use_count());
EXPECT_EQ(1, nameservers_[1].use_count());
}
} // namespace nsas
} // namespace isc
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <gtest/gtest.h>
#include "rrclass.h"
#include "asiolink.h"
#include "zone_entry.h"
#include "nsas_test.h"
using namespace asiolink;
using namespace std;
using namespace isc::dns;
namespace isc {
namespace nsas {
// String constants. These should end in a dot.
static const std::string EXAMPLE_CO_UK("example.co.uk.");
/// \brief Test Fixture Class
class ZoneEntryTest : public ::testing::Test {
protected:
};
/// Tests of the default constructor
TEST_F(ZoneEntryTest, DefaultConstructor) {
// Default constructor should not create any RRsets
ZoneEntry alpha(EXAMPLE_CO_UK, RRClass::IN().getCode());
EXPECT_EQ(EXAMPLE_CO_UK, alpha.getName());
EXPECT_EQ(RRClass::IN().getCode(), alpha.getClass());
}
} // namespace nsas
} // namespace isc
......@@ -19,12 +19,18 @@
#include <string>
#include <vector>
#include <boost/thread.h>
#include <boost/shared_ptr.h>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include "rrset.h"
#include "hash_key.h"
#include "nsas_entry.h"
#include "asiolink.h"
namespace isc {
namespace nsas {
class NameserverEntry;
/// \brief Zone Entry
......@@ -39,27 +45,55 @@ class NameserverEntry;
class ZoneEntry : public NsasEntry<ZoneEntry> {
public:
/// \brief Constructor where no NS records are supplied
///
/// \param name Name of the zone
/// \param class_code Class of this zone (zones of different classes have
/// different objects.
ZoneEntry(const std::string& name, uint16_t class_code) :
name_(name), classCode_(class_code)
{}
/// \brief Constructor
///
/// Creates a zone entry object with an RRset representing the nameservers,
/// plus possibly additional RRsets holding address information.
ZoneEntry(AbstractRRset* nsrrset,
const std::vector<AbstractRRSet*>& additional);
//ZoneEntry(isc::dns::AbstractRRset* nsrrset,
// const std::vector<isc::dns::AbstractRRset*>& additional);
/// \brief Destructor
virtual ~ZoneEntry()
{}
/// \return Name of the zone
virtual std::string getName() const {
return name_;
}
/// \return Class of zone
virtual short getClass() const {
return classCode_;
}
/// \return Return Hash Key
virtual HashKey hashKey() const {
return HashKey(name_, classCode_);
}
/// \brief Lookup Address
///
/// Returns the address with the lowest RTT.
asiolink::IOAddress getAddress() const;
public:
void updateNS
//virtual asiolink::IOAddress getAddress() const;
private:
boost::mutex mutex_; ///< Mutex protecting this zone entry
std::string name_; ///< Canonical zone name
short classCode_; ///< Class code
uint16_t classCode_; ///< Class code
std::vector<boost::shared_ptr<NameserverEntry> > nameservers_; ///< Nameservers
time_t expiry_; ///< Expiry time of this entry
};
} // namespace nsas
} // namespace isc
#endif // __ZONE_ENTRY_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment