BIND 10 trac2140, updated. a1983f43686919fae5dfb05ad8e6da07e5534111 [2140] DUID no longer returns unsafe references, tests updated.
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Oct 10 17:28:24 UTC 2012
The branch, trac2140 has been updated
via a1983f43686919fae5dfb05ad8e6da07e5534111 (commit)
via 56dd56426342f9fa3d63c436f35ba86208512ee0 (commit)
via 08d6f75709a7669481b92fc0b2e4176174bc0f48 (commit)
from 0b7e9646307a6e58d3e1df60c68cbac5dbcbfecb (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit a1983f43686919fae5dfb05ad8e6da07e5534111
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Wed Oct 10 19:28:09 2012 +0200
[2140] DUID no longer returns unsafe references, tests updated.
commit 56dd56426342f9fa3d63c436f35ba86208512ee0
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Wed Oct 10 19:27:28 2012 +0200
[2140] Renew, rebind timers added to lease4, recycle-timer removed
commit 08d6f75709a7669481b92fc0b2e4176174bc0f48
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Wed Oct 10 16:03:26 2012 +0200
[2140] Changes after review: LeaseMgr::getLeaseX() methods expanded.
-----------------------------------------------------------------------
Summary of changes:
src/lib/dhcp/duid.cc | 29 +-----
src/lib/dhcp/duid.h | 24 ++---
src/lib/dhcp/lease_mgr.h | 150 ++++++++++++++++++++++++------
src/lib/dhcp/tests/duid_unittest.cc | 24 ++---
src/lib/dhcp/tests/lease_mgr_unittest.cc | 92 ++++++++++++++++--
5 files changed, 224 insertions(+), 95 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/lib/dhcp/duid.cc b/src/lib/dhcp/duid.cc
index 912fc48..db7ba25 100644
--- a/src/lib/dhcp/duid.cc
+++ b/src/lib/dhcp/duid.cc
@@ -37,8 +37,8 @@ DUID::DUID(const uint8_t * data, size_t len) {
duid_ = std::vector<uint8_t>(data, data + len);
}
-const std::vector<uint8_t>& DUID::getDuid() const {
- return duid_;
+const std::vector<uint8_t> DUID::getDuid() const {
+ return (duid_);
}
DUID::DUIDType DUID::getType() const {
@@ -71,30 +71,9 @@ ClientId::ClientId(const uint8_t *clientid, size_t len)
:DUID(clientid, len) {
}
-/// constructor based on IOAddress
-ClientId::ClientId(const isc::asiolink::IOAddress& addr)
- :DUID(std::vector<uint8_t>(4, 0)) {
- if (addr.getFamily() != AF_INET) {
- isc_throw(BadValue, "Client-id supports only IPv4 addresses");
- }
- isc::util::writeUint32(addr, &duid_[0]);
-}
-
-/// @brief returns reference to the client-id data
+/// @brief returns a copy of client-id data
const std::vector<uint8_t> ClientId::getClientId() const {
- return duid_;
-}
-
-isc::asiolink::IOAddress ClientId::getAddress() const {
- if (duid_.size() != sizeof(uint32_t)) {
- isc_throw(BadValue, "This client-id is not an IPv4 address");
- }
-
- return isc::asiolink::IOAddress( isc::util::readUint32(&duid_[0]) );
-}
-
-bool ClientId::isAddress() const {
- return (duid_.size() == sizeof(uint32_t));
+ return (duid_);
}
// compares two client-ids
diff --git a/src/lib/dhcp/duid.h b/src/lib/dhcp/duid.h
index 132d1d7..53257db 100644
--- a/src/lib/dhcp/duid.h
+++ b/src/lib/dhcp/duid.h
@@ -49,9 +49,12 @@ class DUID {
/// @brief returns a const reference to the actual DUID value
///
- /// Note: This reference is only valid as long as the DUID
- /// that returned it.
- const std::vector<uint8_t>& getDuid() const;
+ /// Note: For safety reasons, this method returns a copy of data as
+ /// otherwise the reference would be only valid as long as the object that
+ /// returned it. In any case, this method should be used only sporadically.
+ /// If there are frequent uses, we must implement some other method
+ /// (e.g. storeSelf()) that will avoid data copying.
+ const std::vector<uint8_t> getDuid() const;
/// @brief returns DUID type
DUIDType getType() const;
@@ -80,25 +83,10 @@ class ClientId : DUID {
/// constructor based on C-style data
ClientId(const uint8_t *clientid, size_t len);
- /// constructor based on IOAddress
- ///
- /// @throw BadValue if specified address is not IPv4
- ClientId(const isc::asiolink::IOAddress& addr);
-
/// @brief returns reference to the client-id data
///
- /// This reference is only valid as long as the object
- /// that returned it.
const std::vector<uint8_t> getClientId() const;
- /// @brief return an IPv4 address represented by this client-id
- ///
- /// @throw BadValue if this client-id is not an IPv4 address
- isc::asiolink::IOAddress getAddress() const;
-
- /// @brief returns if client-id is an address
- bool isAddress() const;
-
// compares two client-ids
bool operator == (const ClientId& other) const;
diff --git a/src/lib/dhcp/lease_mgr.h b/src/lib/dhcp/lease_mgr.h
index 3f90ee0..7dd69d4 100644
--- a/src/lib/dhcp/lease_mgr.h
+++ b/src/lib/dhcp/lease_mgr.h
@@ -24,6 +24,10 @@
namespace isc {
namespace dhcp {
+/// @brief specifies unique subnet identifier
+/// @todo: Move this to subnet.h once ticket #2237 is merged
+typedef uint32_t SubnetID;
+
/// @brief Structure that holds a lease for IPv4 address
///
/// For performance reasons it is a simple structure, not a class. If we chose
@@ -49,28 +53,38 @@ struct Lease4 {
/// @brief client identifier
boost::shared_ptr<ClientId> client_id_;
+ /// @brief renewal timer
+ ///
+ /// Specifies renewal time. Although technically it is a property of IA container,
+ /// not the address itself, since our data model does not define separate IA
+ /// entity, we are keeping it in the lease. In case of multiple addresses/prefixes
+ /// for the same IA, each must have consistent T1 and T2 values. Specified in
+ /// seconds since cltt.
+ uint32_t t1_;
+
+ /// @brief rebinding timer
+ ///
+ /// Specifies rebinding time. Although technically it is a property of IA container,
+ /// not the address itself, since our data model does not define separate IA
+ /// entity, we are keeping it in the lease. In case of multiple addresses/prefixes
+ /// for the same IA, each must have consistent T1 and T2 values. Specified in
+ /// seconds since cltt.
+ uint32_t t2_;
+
/// @brief valid lifetime
///
/// Expressed as number of seconds since cltt
uint32_t valid_lft_;
- /// @brief Recycle timer
- ///
- /// Typically, the lease return to free pool immediately after it is released
- /// or expired. This timer specifies number of seconds that it should be kept
- /// after release or expiration, in case the client returns. This feature is not
- /// currently used and this value is set to 0.
- uint32_t recycle_time_;
-
/// @brief client last transmission time
///
/// Specifies a timestamp, when last transmission from a client was received.
time_t cltt_;
- /// @brief Pool identifier
+ /// @brief Subnet identifier
///
- /// Specifies pool-id of the pool that the lease belongs to
- uint32_t pool_id_;
+ /// Specifies subnet-id of the subnet that the lease belongs to
+ SubnetID subnet_id_;
/// @brief Is this a fixed lease?
///
@@ -99,11 +113,15 @@ struct Lease4 {
/// Currently not used. It may be used for keeping comments made by the
/// system administrator.
std::string comments_;
+
+ /// @todo: Add DHCPv4 failover related fields here
};
/// @brief Pointer to a Lease4 structure.
typedef boost::shared_ptr<Lease4> Lease4Ptr;
+/// @brief A collection of IPv4 leases.
+typedef std::vector< boost::shared_ptr<Lease4Ptr> > Lease4Collection;
/// @brief Structure that holds a lease for IPv6 address and/or prefix
///
@@ -176,23 +194,15 @@ struct Lease6 {
/// seconds since cltt.
uint32_t t2_;
- /// @brief Recycle timer
- ///
- /// Typically, the lease return to free pool immediately after it is released
- /// or expired. This timer specifies number of seconds that it should be kept
- /// after release or expiration, in case the client returns. This feature is not
- /// currently used and this value is set to 0.
- uint32_t recycle_time_;
-
/// @brief client last transmission time
///
/// Specifies a timestamp, when last transmission from a client was received.
time_t cltt_;
- /// @brief Pool identifier
+ /// @brief Subnet identifier
///
- /// Specifies pool-id of the pool that the lease belongs to
- uint32_t pool_id_;
+ /// Specifies subnet-id of the subnet that the lease belongs to
+ SubnetID subnet_id_;
/// @brief Is this a fixed lease?
///
@@ -221,6 +231,8 @@ struct Lease6 {
///
/// This field is currently not used.
std::string comments_;
+
+ /// @todo: Add DHCPv6 failover related fields here
};
/// @brief Pointer to a Lease6 structure.
@@ -229,6 +241,8 @@ typedef boost::shared_ptr<Lease6> Lease6Ptr;
/// @brief Const pointer to a Lease6 structure.
typedef boost::shared_ptr<const Lease6> ConstLease6Ptr;
+/// @brief A collection of IPv6 leases.
+typedef std::vector< boost::shared_ptr<Lease6Ptr> > Lease6Collection;
/// @brief Abstract Lease Manager
///
@@ -264,39 +278,117 @@ public:
/// @param lease lease to be added
virtual bool addLease(Lease6Ptr lease) = 0;
- /// @brief Returns existing IPv4 lease for specified IPv4 address.
+ /// @brief Returns existing IPv4 lease for specified IPv4 address and subnet_id
+ ///
+ /// This method is used to get a lease for specific subnet_id. There can be
+ /// at most one lease for any given subnet, so this method returns a single
+ /// pointer.
///
/// @param addr address of the searched lease
+ /// @param subnet_id ID of the subnet the lease must belong to
+ ///
+ /// @return smart pointer to the lease (or NULL if a lease is not found)
+ virtual Lease4Ptr getLease4(isc::asiolink::IOAddress addr,
+ SubnetID subnet_id) const = 0;
+
+ /// @brief Returns an IPv4 lease for specified IPv4 address
+ ///
+ /// This method return a lease that is associated with a given address.
+ /// For other query types (by hardware addr, by client-id) there can be
+ /// several leases in different subnets (e.g. for mobile clients that
+ /// got address in different subnets). However, for a single address
+ /// there can be only one lease, so this method returns a pointer to
+ /// a single lease, not a container of leases.
+ ///
+ /// @param addr address of the searched lease
+ /// @param subnet_id ID of the subnet the lease must belong to
///
/// @return smart pointer to the lease (or NULL if a lease is not found)
virtual Lease4Ptr getLease4(isc::asiolink::IOAddress addr) const = 0;
- /// @brief Returns existing IPv4 lease for specified hardware address.
+ /// @brief Returns existing IPv4 leases for specified hardware address.
+ ///
+ /// Although in the usual case there will be only one lease, for mobile
+ /// clients or clients with multiple static/fixed/reserved leases there
+ /// can be more than one. Thus return type is a container, not a single
+ /// pointer.
///
/// @param hwaddr hardware address of the client
///
- /// @return smart pointer to the lease (or NULL if a lease is not found)
- virtual Lease4Ptr getLease4(const HWAddr& hwaddr) const = 0;
+ /// @return lease collection
+ virtual Lease4Collection getLease4(const HWAddr& hwaddr) const = 0;
+
+ /// @brief Returns existing IPv4 leases for specified hardware address
+ /// and a subnet
+ ///
+ /// There can be at most one lease for a given HW address in a single
+ /// pool, so this method with either return a single lease or NULL.
+ ///
+ /// @param hwaddr hardware address of the client
+ /// @param subnet_id identifier of the subnet that lease must belong to
+ ///
+ /// @return a pointer to the lease (or NULL if a lease is not found)
+ virtual Lease4Ptr getLease4(const HWAddr& hwaddr,
+ SubnetID subnet_id) const = 0;
+
+ /// @brief Returns existing IPv4 lease for specified client-id
+ ///
+ /// Although in the usual case there will be only one lease, for mobile
+ /// clients or clients with multiple static/fixed/reserved leases there
+ /// can be more than one. Thus return type is a container, not a single
+ /// pointer.
+ ///
+ /// @param clientid client identifier
+ ///
+ /// @return lease collection
+ virtual Lease4Collection getLease4(const ClientId& clientid) const = 0;
/// @brief Returns existing IPv4 lease for specified client-id
///
+ /// There can be at most one lease for a given HW address in a single
+ /// pool, so this method with either return a single lease or NULL.
+ ///
/// @param clientid client identifier
- virtual Lease4Ptr getLease4(const ClientId& clientid) const = 0;
+ /// @param subnet_id identifier of the subnet that lease must belong to
+ ///
+ /// @return a pointer to the lease (or NULL if a lease is not found)
+ virtual Lease4Ptr getLease4(const ClientId& clientid,
+ SubnetID subnet_id) const = 0;
/// @brief Returns existing IPv6 lease for a given IPv6 address.
///
+ /// For a given address, we assume that there will be only one lease.
+ /// The assumtion here is that there will not be site or link-local
+ /// addresses used, so there is no way of having address duplication.
+ ///
/// @param addr address of the searched lease
///
/// @return smart pointer to the lease (or NULL if a lease is not found)
virtual Lease6Ptr getLease6(isc::asiolink::IOAddress addr) const = 0;
+ /// @brief Returns existing IPv6 leases for a given DUID+IA combination
+ ///
+ /// Although in the usual case there will be only one lease, for mobile
+ /// clients or clients with multiple static/fixed/reserved leases there
+ /// can be more than one. Thus return type is a container, not a single
+ /// pointer.
+ ///
+ /// @param duid client DUID
+ /// @param iaid IA identifier
+ ///
+ /// @return smart pointer to the lease (or NULL if a lease is not found)
+ virtual Lease6Collection getLease6(const DUID& duid,
+ uint32_t iaid) const = 0;
+
/// @brief Returns existing IPv6 lease for a given DUID+IA combination
///
/// @param duid client DUID
/// @param iaid IA identifier
+ /// @param subnet_id subnet id of the subnet the lease belongs to
///
/// @return smart pointer to the lease (or NULL if a lease is not found)
- virtual Lease6Ptr getLease6(const DUID& duid, uint32_t iaid) const = 0;
+ virtual Lease6Ptr getLease6(const DUID& duid, uint32_t iaid,
+ SubnetID subnet_id) const = 0;
/// @brief Updates IPv4 lease.
///
@@ -346,7 +438,7 @@ public:
/// and then check that:
/// B>=A and B=C (it is ok to have newer backend, as it should be backward
/// compatible)
- /// Also if B>C, some database upgrade procedure may happen
+ /// Also if B>C, some database upgrade procedure may be triggered
virtual std::string getVersion() const = 0;
/// @todo: Add host management here
diff --git a/src/lib/dhcp/tests/duid_unittest.cc b/src/lib/dhcp/tests/duid_unittest.cc
index d3da6e8..93f304c 100644
--- a/src/lib/dhcp/tests/duid_unittest.cc
+++ b/src/lib/dhcp/tests/duid_unittest.cc
@@ -33,6 +33,8 @@ using boost::scoped_ptr;
namespace {
+// This test verifies if the constructors are working as expected
+// and process passed parameters.
TEST(DuidTest, constructor) {
uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6};
@@ -52,6 +54,8 @@ TEST(DuidTest, constructor) {
EXPECT_EQ(DUID::DUID_LLT, duid2->getType());
}
+// This test verifies if DUID size restrictions are implemented
+// properly.
TEST(DuidTest, size) {
const int MAX_DUID_SIZE = 128;
uint8_t data[MAX_DUID_SIZE + 1];
@@ -78,6 +82,8 @@ TEST(DuidTest, size) {
OutOfRange);
}
+// This test verifies if the implementation supports all defined
+// DUID types.
TEST(DuidTest, getType) {
uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6};
uint8_t en[] = {0, 2, 2, 3, 4, 5, 6};
@@ -98,6 +104,7 @@ TEST(DuidTest, getType) {
EXPECT_EQ(DUID::DUID_UNKNOWN, duid_invalid->getType());
}
+// This test checks if the comparison operators are sane.
TEST(DuidTest, operators) {
uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6};
uint8_t data2[] = {0, 1, 2, 3, 4};
@@ -118,38 +125,27 @@ TEST(DuidTest, operators) {
EXPECT_TRUE(*duid1 != *duid3);
}
+// This test verifies if the ClientId constructors are working properly
+// and passed parameters are used
TEST(ClientIdTest, constructor) {
IOAddress addr2("192.0.2.1");
IOAddress addr3("2001:db8:1::1");
uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6};
vector<uint8_t> data2(data1, data1 + sizeof(data1));
- uint8_t data3[] = {192, 0 , 2, 1 };
// checks for C-style construtor (uint8_t * + len)
scoped_ptr<ClientId> id1(new ClientId(data1, sizeof(data1)));
vector<uint8_t> vecdata = id1->getClientId();
EXPECT_EQ(data2, vecdata);
- EXPECT_FALSE(id1->isAddress());
- EXPECT_THROW(id1->getAddress(), BadValue);
// checks for vector-based constructor
scoped_ptr<ClientId> id2(new ClientId(data2));
vecdata = id2->getClientId();
EXPECT_EQ(data2, vecdata);
- EXPECT_FALSE(id1->isAddress());
- EXPECT_THROW(id1->getAddress(), BadValue);
-
- // checks for IOAddress based constructor
- scoped_ptr<ClientId> id3(new ClientId(addr2));
- vecdata = id3->getClientId();
- EXPECT_TRUE(vecdata == vector<uint8_t>(data3, data3 + 4));
- EXPECT_EQ("192.0.2.1", id3->getAddress().toText());
-
- // should support v4 address only, v6 is a wrong address here
- EXPECT_THROW(new ClientId(addr3), BadValue);
}
+// This test checks if the comparison operators are sane.
TEST(ClientIdTest, operators) {
uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6};
uint8_t data2[] = {0, 1, 2, 3, 4};
diff --git a/src/lib/dhcp/tests/lease_mgr_unittest.cc b/src/lib/dhcp/tests/lease_mgr_unittest.cc
index 39102bb..97659a1 100644
--- a/src/lib/dhcp/tests/lease_mgr_unittest.cc
+++ b/src/lib/dhcp/tests/lease_mgr_unittest.cc
@@ -59,20 +59,58 @@ public:
///
/// @param addr address of the searched lease
///
- /// @return smart pointer to the lease (or NULL if a lease is not found)
+ /// @return a collection of leases
virtual Lease4Ptr getLease4(isc::asiolink::IOAddress addr) const;
- /// @brief Returns existing IPv4 lease for specified hardware address.
+ /// @brief Returns existing IPv4 lease for specific address and subnet
+ /// @param addr address of the searched lease
+ /// @param subnet_id ID of the subnet the lease must belong to
+ ///
+ /// @return smart pointer to the lease (or NULL if a lease is not found)
+ virtual Lease4Ptr getLease4(isc::asiolink::IOAddress addr,
+ SubnetID subnet_id) const;
+
+ /// @brief Returns existing IPv4 leases for specified hardware address.
+ ///
+ /// Although in the usual case there will be only one lease, for mobile
+ /// clients or clients with multiple static/fixed/reserved leases there
+ /// can be more than one. Thus return type is a container, not a single
+ /// pointer.
///
/// @param hwaddr hardware address of the client
///
- /// @return smart pointer to the lease (or NULL if a lease is not found)
- virtual Lease4Ptr getLease4(const HWAddr& hwaddr) const;
+ /// @return lease collection
+ virtual Lease4Collection getLease4(const HWAddr& hwaddr) const;
+
+ /// @brief Returns existing IPv4 leases for specified hardware address
+ /// and a subnet
+ ///
+ /// There can be at most one lease for a given HW address in a single
+ /// pool, so this method with either return a single lease or NULL.
+ ///
+ /// @param hwaddr hardware address of the client
+ /// @param subnet_id identifier of the subnet that lease must belong to
+ ///
+ /// @return a pointer to the lease (or NULL if a lease is not found)
+ virtual Lease4Ptr getLease4(const HWAddr& hwaddr,
+ SubnetID subnet_id) const;
+
+ /// @brief Returns existing IPv4 lease for specified client-id
+ ///
+ /// @param clientid client identifier
+ virtual Lease4Collection getLease4(const ClientId& clientid) const;
/// @brief Returns existing IPv4 lease for specified client-id
///
+ /// There can be at most one lease for a given HW address in a single
+ /// pool, so this method with either return a single lease or NULL.
+ ///
/// @param clientid client identifier
- virtual Lease4Ptr getLease4(const ClientId& clientid) const;
+ /// @param subnet_id identifier of the subnet that lease must belong to
+ ///
+ /// @return a pointer to the lease (or NULL if a lease is not found)
+ virtual Lease4Ptr getLease4(const ClientId& clientid,
+ SubnetID subnet_id) const;
/// @brief Returns existing IPv6 lease for a given IPv6 address.
///
@@ -86,8 +124,17 @@ public:
/// @param duid client DUID
/// @param iaid IA identifier
///
+ /// @return collection of IPv6 leases
+ Lease6Collection getLease6(const DUID& duid, uint32_t iaid) const;
+
+ /// @brief Returns existing IPv6 lease for a given DUID+IA combination
+ ///
+ /// @param duid client DUID
+ /// @param iaid IA identifier
+ /// @param subnet_id identifier of the subnet the lease must belong to
+ ///
/// @return smart pointer to the lease (or NULL if a lease is not found)
- Lease6Ptr getLease6(const DUID& duid, uint32_t iaid) const;
+ Lease6Ptr getLease6(const DUID& duid, uint32_t iaid, SubnetID subnet_id) const;
/// @brief Updates IPv4 lease.
///
@@ -156,19 +203,40 @@ Lease4Ptr Memfile_LeaseMgr::getLease4(isc::asiolink::IOAddress) const {
return (Lease4Ptr());
}
-Lease4Ptr Memfile_LeaseMgr::getLease4(const HWAddr& ) const {
+Lease4Collection Memfile_LeaseMgr::getLease4(const HWAddr& ) const {
+ return (Lease4Collection());
+}
+
+Lease4Ptr Memfile_LeaseMgr::getLease4(isc::asiolink::IOAddress ,
+ SubnetID) const {
return (Lease4Ptr());
}
-Lease4Ptr Memfile_LeaseMgr::getLease4(const ClientId& ) const {
+Lease4Ptr Memfile_LeaseMgr::getLease4(const HWAddr&,
+ SubnetID) const {
return (Lease4Ptr());
}
+
+Lease4Ptr Memfile_LeaseMgr::getLease4(const ClientId&,
+ SubnetID) const {
+ return (Lease4Ptr());
+}
+
+Lease4Collection Memfile_LeaseMgr::getLease4(const ClientId& ) const {
+ return (Lease4Collection());
+}
+
Lease6Ptr Memfile_LeaseMgr::getLease6(isc::asiolink::IOAddress) const {
return (Lease6Ptr());
}
-Lease6Ptr Memfile_LeaseMgr::getLease6(const DUID& , uint32_t ) const {
+Lease6Collection Memfile_LeaseMgr::getLease6(const DUID& , uint32_t ) const {
+ return (Lease6Collection());
+}
+
+Lease6Ptr Memfile_LeaseMgr::getLease6(const DUID&, uint32_t,
+ SubnetID) const {
return (Lease6Ptr());
}
@@ -201,6 +269,8 @@ public:
}
};
+// This test checks if the LeaseMgr can be instantiated and that it
+// parses parameters string properly.
TEST_F(LeaseMgrTest, constructor) {
// should not throw any exceptions here
@@ -218,5 +288,9 @@ TEST_F(LeaseMgrTest, constructor) {
// There's no point in calling any other methods in LeaseMgr, as they
// are purely virtual, so we would only call Memfile_LeaseMgr methods.
+// Those methods are just stubs that does not return anything.
+// It seems likely that we will need to extend the memfile code for
+// allocation engine tests, so we may implement tests that call
+// Memfile_LeaseMgr methods then.
}; // end of anonymous namespace
More information about the bind10-changes
mailing list