Commit b3172918 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[master] Merge branch 'trac2592' (getLease4 in memfile LeaseMgr)

Conflicts:
	ChangeLog
	src/lib/dhcpsrv/memfile_lease_mgr.cc
	src/lib/dhcpsrv/memfile_lease_mgr.h
	src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
parents 5420c8bb a11683be
671. [func] dclink,tomek
memfile backend now supports getLease4(hwaddr) and getLease4(client-id)
methods. Thanks to David Carlier for contributing a patch.
(Trac #2592, git a11683be53db2f9f8f9b71c1d1c163511e0319b3)
670. [func] marcin
libdhcpsrv: Added support to MySQL lease database backend to
store FQDN data for the lease.
......
......@@ -1477,18 +1477,16 @@ TEST_F(Dhcpv4SrvTest, ReleaseBasic) {
EXPECT_FALSE(l);
// Try to get the lease by hardware address
// @todo: Uncomment this once trac2592 is implemented
// Lease4Collection leases = LeaseMgrFactory::instance().getLease4(hw->hwaddr_);
// EXPECT_EQ(leases.size(), 0);
Lease4Collection leases = LeaseMgrFactory::instance().getLease4(hw->hwaddr_);
EXPECT_EQ(leases.size(), 0);
// Try to get it by hw/subnet_id combination
l = LeaseMgrFactory::instance().getLease4(hw->hwaddr_, subnet_->getID());
EXPECT_FALSE(l);
// Try by client-id
// @todo: Uncomment this once trac2592 is implemented
//Lease4Collection leases = LeaseMgrFactory::instance().getLease4(*client_id_);
//EXPECT_EQ(leases.size(), 0);
leases = LeaseMgrFactory::instance().getLease4(*client_id_);
EXPECT_EQ(leases.size(), 0);
// Try by client-id/subnet-id
l = LeaseMgrFactory::instance().getLease4(*client_id_, subnet_->getID());
......
......@@ -210,6 +210,11 @@ A debug message issued when the server is attempting to obtain an IPv6
lease from the memory file database for a client with the specified IAID
(Identity Association ID), Subnet ID and DUID (DHCP Unique Identifier).
% DHCPSRV_MEMFILE_GET_CLIENTID_HWADDR_SUBID obtaining IPv4 lease for client ID %1, hardware address %2 and subnet ID %3
A debug message issued when the server is attempting to obtain an IPv4
lease from the memory file database for a client with the specified
client ID, hardware address and subnet ID.
% DHCPSRV_MEMFILE_GET_SUBID_CLIENTID obtaining IPv4 lease for subnet ID %1 and client ID %2
A debug message issued when the server is attempting to obtain an IPv4
lease from the memory file database for a client with the specified
......
......@@ -28,7 +28,8 @@ Memfile_LeaseMgr::Memfile_LeaseMgr(const ParameterMap& parameters)
Memfile_LeaseMgr::~Memfile_LeaseMgr() {
}
bool Memfile_LeaseMgr::addLease(const Lease4Ptr& lease) {
bool
Memfile_LeaseMgr::addLease(const Lease4Ptr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_ADD_ADDR4).arg(lease->addr_.toText());
......@@ -40,7 +41,8 @@ bool Memfile_LeaseMgr::addLease(const Lease4Ptr& lease) {
return (true);
}
bool Memfile_LeaseMgr::addLease(const Lease6Ptr& lease) {
bool
Memfile_LeaseMgr::addLease(const Lease6Ptr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_ADD_ADDR6).arg(lease->addr_.toText());
......@@ -52,7 +54,8 @@ bool Memfile_LeaseMgr::addLease(const Lease6Ptr& lease) {
return (true);
}
Lease4Ptr Memfile_LeaseMgr::getLease4(const isc::asiolink::IOAddress& addr) const {
Lease4Ptr
Memfile_LeaseMgr::getLease4(const isc::asiolink::IOAddress& addr) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_GET_ADDR4).arg(addr.toText());
......@@ -66,15 +69,27 @@ Lease4Ptr Memfile_LeaseMgr::getLease4(const isc::asiolink::IOAddress& addr) cons
}
}
Lease4Collection Memfile_LeaseMgr::getLease4(const HWAddr& hwaddr) const {
Lease4Collection
Memfile_LeaseMgr::getLease4(const HWAddr& hwaddr) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_GET_HWADDR).arg(hwaddr.toText());
typedef Lease4Storage::nth_index<0>::type SearchIndex;
Lease4Collection collection;
const SearchIndex& idx = storage4_.get<0>();
for(SearchIndex::const_iterator lease = idx.begin();
lease != idx.end(); ++lease) {
// Every Lease4 has a hardware address, so we can compare it
if((* lease)->hwaddr_ == hwaddr.hwaddr_) {
collection.push_back((* lease));
}
}
isc_throw(NotImplemented, "getLease4(HWaddr x) method not implemented yet");
return (collection);
}
Lease4Ptr Memfile_LeaseMgr::getLease4(const HWAddr& hwaddr,
SubnetID subnet_id) const {
Lease4Ptr
Memfile_LeaseMgr::getLease4(const HWAddr& hwaddr, SubnetID subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_GET_SUBID_HWADDR).arg(subnet_id)
.arg(hwaddr.toText());
......@@ -90,21 +105,65 @@ Lease4Ptr Memfile_LeaseMgr::getLease4(const HWAddr& hwaddr,
idx.find(boost::make_tuple(hwaddr.hwaddr_, subnet_id));
// Lease was not found. Return empty pointer to the caller.
if (lease == idx.end()) {
return Lease4Ptr();
return (Lease4Ptr());
}
// Lease was found. Return it to the caller.
return (Lease4Ptr(new Lease4(**lease)));
}
Lease4Collection Memfile_LeaseMgr::getLease4(const ClientId& clientid) const {
Lease4Collection
Memfile_LeaseMgr::getLease4(const ClientId& clientid) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_GET_CLIENTID).arg(clientid.toText());
isc_throw(NotImplemented, "getLease4(ClientId) not implemented");
typedef Memfile_LeaseMgr::Lease4Storage::nth_index<0>::type SearchIndex;
Lease4Collection collection;
const SearchIndex& idx = storage4_.get<0>();
for(SearchIndex::const_iterator lease = idx.begin();
lease != idx.end(); ++ lease) {
// client-id is not mandatory in DHCPv4. There can be a lease that does
// not have a client-id. Dereferencing null pointer would be a bad thing
if((*lease)->client_id_ && *(*lease)->client_id_ == clientid) {
collection.push_back((* lease));
}
}
return (collection);
}
Lease4Ptr Memfile_LeaseMgr::getLease4(const ClientId& client_id,
SubnetID subnet_id) const {
Lease4Ptr
Memfile_LeaseMgr::getLease4(const ClientId& client_id,
const HWAddr& hwaddr,
SubnetID subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_GET_CLIENTID_HWADDR_SUBID).arg(client_id.toText())
.arg(hwaddr.toText())
.arg(subnet_id);
// We are going to use index #3 of the multi index container.
// We define SearchIndex locally in this function because
// currently only this function uses this index.
typedef Lease4Storage::nth_index<3>::type SearchIndex;
// Get the index.
const SearchIndex& idx = storage4_.get<3>();
// Try to get the lease using client id, hardware address and subnet id.
SearchIndex::const_iterator lease =
idx.find(boost::make_tuple(client_id.getClientId(), hwaddr.hwaddr_,
subnet_id));
if (lease == idx.end()) {
// Lease was not found. Return empty pointer to the caller.
return (Lease4Ptr());
}
// Lease was found. Return it to the caller.
return (*lease);
}
Lease4Ptr
Memfile_LeaseMgr::getLease4(const ClientId& client_id,
SubnetID subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_GET_SUBID_CLIENTID).arg(subnet_id)
.arg(client_id.toText());
......@@ -120,7 +179,7 @@ Lease4Ptr Memfile_LeaseMgr::getLease4(const ClientId& client_id,
idx.find(boost::make_tuple(client_id.getClientId(), subnet_id));
// Lease was not found. Return empty pointer to the caller.
if (lease == idx.end()) {
return Lease4Ptr();
return (Lease4Ptr());
}
// Lease was found. Return it to the caller.
return (Lease4Ptr(new Lease4(**lease)));
......@@ -139,16 +198,17 @@ Memfile_LeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
}
}
Lease6Collection Memfile_LeaseMgr::getLease6(const DUID& duid,
uint32_t iaid) const {
Lease6Collection
Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_GET_IAID_DUID).arg(iaid).arg(duid.toText());
return (Lease6Collection());
}
Lease6Ptr Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
SubnetID subnet_id) const {
Lease6Ptr
Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
SubnetID subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_GET_IAID_SUBID_DUID)
.arg(iaid).arg(subnet_id).arg(duid.toText());
......@@ -170,7 +230,8 @@ Lease6Ptr Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
return (Lease6Ptr(new Lease6(**lease)));
}
void Memfile_LeaseMgr::updateLease4(const Lease4Ptr& lease) {
void
Memfile_LeaseMgr::updateLease4(const Lease4Ptr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_UPDATE_ADDR4).arg(lease->addr_.toText());
......@@ -182,7 +243,8 @@ void Memfile_LeaseMgr::updateLease4(const Lease4Ptr& lease) {
**lease_it = *lease;
}
void Memfile_LeaseMgr::updateLease6(const Lease6Ptr& lease) {
void
Memfile_LeaseMgr::updateLease6(const Lease6Ptr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_UPDATE_ADDR6).arg(lease->addr_.toText());
......@@ -194,7 +256,8 @@ void Memfile_LeaseMgr::updateLease6(const Lease6Ptr& lease) {
**lease_it = *lease;
}
bool Memfile_LeaseMgr::deleteLease(const isc::asiolink::IOAddress& addr) {
bool
Memfile_LeaseMgr::deleteLease(const isc::asiolink::IOAddress& addr) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_DELETE_ADDR).arg(addr.toText());
if (addr.isV4()) {
......@@ -221,7 +284,8 @@ bool Memfile_LeaseMgr::deleteLease(const isc::asiolink::IOAddress& addr) {
}
}
std::string Memfile_LeaseMgr::getDescription() const {
std::string
Memfile_LeaseMgr::getDescription() const {
return (std::string("This is a dummy memfile backend implementation.\n"
"It does not offer any useful lease management and its only\n"
"purpose is to test abstract lease manager API."));
......
......@@ -54,7 +54,6 @@ public:
/// @brief Adds an IPv4 lease.
///
/// @todo Not implemented yet
/// @param lease lease to be added
virtual bool addLease(const Lease4Ptr& lease);
......@@ -75,8 +74,6 @@ public:
/// @brief Returns existing IPv4 leases for specified hardware address.
///
/// @todo Not implemented yet
///
/// 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
......@@ -105,11 +102,24 @@ public:
/// @brief Returns existing IPv4 lease for specified client-id
///
/// @todo Not implemented yet
///
/// @param clientid client identifier
virtual Lease4Collection getLease4(const ClientId& clientid) const;
/// @brief Returns IPv4 lease for specified client-id/hwaddr/subnet-id tuple
///
/// There can be at most one lease for a given client-id/hwaddr tuple
/// in a single pool, so this method with either return a single lease
/// or NULL.
///
/// @param clientid client identifier
/// @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 ClientId& clientid,
const HWAddr& hwaddr,
SubnetID subnet_id) const;
/// @brief Returns existing IPv4 lease for specified client-id
///
/// This function returns a copy of the lease. The modification in the
......@@ -145,7 +155,7 @@ public:
/// @return collection of IPv6 leases
virtual Lease6Collection getLease6(const DUID& duid, uint32_t iaid) const;
/// @brief Returns existing IPv6 lease for a given DUID+IA combination
/// @brief Returns existing IPv6 lease for a given DUID/IA/subnet-id tuple
///
/// This function returns a copy of the lease. The modification in the
/// return lease does not affect the instance held in the lease storage.
......@@ -332,6 +342,35 @@ protected:
// The subnet id is accessed through the subnet_id_ member.
boost::multi_index::member<Lease, uint32_t, &Lease::subnet_id_>
>
>,
// Specification of the fourth index starts here.
boost::multi_index::ordered_unique<
// This is a composite index that uses two values to search for a
// lease: client id and subnet id.
boost::multi_index::composite_key<
Lease4,
// The client id value is not directly accessible through the
// Lease4 object as it is wrapped with the ClientIdPtr object.
// Therefore we use the KeyFromKeyExtractor class to access
// client id through this cascaded structure. The client id
// is used as an index value.
KeyFromKeyExtractor<
// Specify that the vector holding client id value can be obtained
// from the ClientId object.
boost::multi_index::const_mem_fun<ClientId, std::vector<uint8_t>,
&ClientId::getClientId>,
// Specify that the ClientId object (actually pointer to it) can
// be accessed by the client_id_ member of Lease4 class.
boost::multi_index::member<Lease4, ClientIdPtr, &Lease4::client_id_>
>,
// The hardware address is held in the hwaddr_ member of the
// Lease4 object.
boost::multi_index::member<Lease4, std::vector<uint8_t>,
&Lease4::hwaddr_>,
// The subnet id is accessed through the subnet_id_ member.
boost::multi_index::member<Lease, SubnetID, &Lease::subnet_id_>
>
>
>
> Lease4Storage; // Specify the type name for this container.
......
......@@ -18,7 +18,7 @@
#include <dhcp/duid.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/memfile_lease_mgr.h>
#include <dhcpsrv/tests/test_utils.h>
#include <gtest/gtest.h>
#include <iostream>
......@@ -28,10 +28,11 @@ using namespace std;
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
namespace {
// empty class for now, but may be extended once Addr6 becomes bigger
class MemfileLeaseMgrTest : public ::testing::Test {
class MemfileLeaseMgrTest : public GenericLeaseMgrTest {
public:
MemfileLeaseMgrTest() {
}
......@@ -130,6 +131,83 @@ TEST_F(MemfileLeaseMgrTest, addGetDelete6) {
EXPECT_EQ(Lease6Ptr(), x);
}
// TODO: Write more memfile tests
// @todo Write more memfile tests
// Simple test about lease4 retrieval through client id method
TEST_F(MemfileLeaseMgrTest, getLease4ClientId) {
const LeaseMgr::ParameterMap pmap;
boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr(new Memfile_LeaseMgr(pmap));
// Let's initialize a specific lease ...
Lease4Ptr lease = initializeLease4(straddress4_[1]);
EXPECT_TRUE(lease_mgr->addLease(lease));
Lease4Collection returned = lease_mgr->getLease4(*lease->client_id_);
ASSERT_EQ(1, returned.size());
// We should retrieve our lease...
detailCompareLease(lease, *returned.begin());
lease = initializeLease4(straddress4_[2]);
returned = lease_mgr->getLease4(*lease->client_id_);
ASSERT_EQ(0, returned.size());
}
// Checks that lease4 retrieval client id is null is working
TEST_F(MemfileLeaseMgrTest, getLease4NullClientId) {
const LeaseMgr::ParameterMap pmap;
boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr(new Memfile_LeaseMgr(pmap));
// Let's initialize a specific lease ... But this time
// We keep its client id for further lookup and
// We clearly 'reset' it ...
Lease4Ptr lease = initializeLease4(straddress4_[4]);
ClientIdPtr client_id = lease->client_id_;
lease->client_id_ = ClientIdPtr();
EXPECT_TRUE(lease_mgr->addLease(lease));
Lease4Collection returned = lease_mgr->getLease4(*client_id);
// Shouldn't have our previous lease ...
ASSERT_EQ(0, returned.size());
}
// Checks lease4 retrieval through HWAddr
TEST_F(MemfileLeaseMgrTest, getLease4HWAddr) {
const LeaseMgr::ParameterMap pmap;
boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr(new Memfile_LeaseMgr(pmap));
// Let's initialize two different leases 4 and just add the first ...
Lease4Ptr leaseA = initializeLease4(straddress4_[5]);
HWAddr hwaddrA(leaseA->hwaddr_, HTYPE_ETHER);
HWAddr hwaddrB(vector<uint8_t>(6, 0x80), HTYPE_ETHER);
EXPECT_TRUE(lease_mgr->addLease(leaseA));
// we should not have a lease, with this MAC Addr
Lease4Collection returned = lease_mgr->getLease4(hwaddrB);
ASSERT_EQ(0, returned.size());
// But with this one
returned = lease_mgr->getLease4(hwaddrA);
ASSERT_EQ(1, returned.size());
}
// Checks lease4 retrieval with clientId, HWAddr and subnet_id
TEST_F(MemfileLeaseMgrTest, getLease4ClientIdHWAddrSubnetId) {
const LeaseMgr::ParameterMap pmap;
boost::scoped_ptr<Memfile_LeaseMgr> lease_mgr(new Memfile_LeaseMgr(pmap));
Lease4Ptr leaseA = initializeLease4(straddress4_[4]);
Lease4Ptr leaseB = initializeLease4(straddress4_[5]);
HWAddr hwaddrA(leaseA->hwaddr_, HTYPE_ETHER);
HWAddr hwaddrB(leaseB->hwaddr_, HTYPE_ETHER);
EXPECT_TRUE(lease_mgr->addLease(leaseA));
// First case we should retrieve our lease
Lease4Ptr lease = lease_mgr->getLease4(*leaseA->client_id_, hwaddrA, leaseA->subnet_id_);
detailCompareLease(lease, leaseA);
lease = lease_mgr->getLease4(*leaseB->client_id_, hwaddrA, leaseA->subnet_id_);
detailCompareLease(lease, leaseA);
// But not the folowing, with different hwaddr and subnet
lease = lease_mgr->getLease4(*leaseA->client_id_, hwaddrB, leaseA->subnet_id_);
EXPECT_TRUE(lease == Lease4Ptr());
lease = lease_mgr->getLease4(*leaseA->client_id_, hwaddrA, leaseB->subnet_id_);
EXPECT_TRUE(lease == Lease4Ptr());
}
}; // end of anonymous namespace
......@@ -20,6 +20,7 @@
#include <dhcpsrv/tests/test_utils.h>
#include <exceptions/exceptions.h>
#include <gtest/gtest.h>
#include <algorithm>
......@@ -39,18 +40,6 @@ namespace {
// This holds statements to create and destroy the schema.
#include "schema_copy.h"
// IPv4 and IPv6 addresses used in the tests
const char* ADDRESS4[] = {
"192.0.2.0", "192.0.2.1", "192.0.2.2", "192.0.2.3",
"192.0.2.4", "192.0.2.5", "192.0.2.6", "192.0.2.7",
NULL
};
const char* ADDRESS6[] = {
"2001:db8::0", "2001:db8::1", "2001:db8::2", "2001:db8::3",
"2001:db8::4", "2001:db8::5", "2001:db8::6", "2001:db8::7",
NULL
};
// Connection strings.
// Database: keatest
// Host: localhost
......@@ -155,26 +144,12 @@ void createSchema() {
/// Opens the database prior to each test and closes it afterwards.
/// All pending transactions are deleted prior to closure.
class MySqlLeaseMgrTest : public ::testing::Test {
class MySqlLeaseMgrTest : public GenericLeaseMgrTest {
public:
/// @brief Constructor
///
/// Deletes everything from the database and opens it.
MySqlLeaseMgrTest() {
// Initialize address strings and IOAddresses
for (int i = 0; ADDRESS4[i] != NULL; ++i) {
string addr(ADDRESS4[i]);
straddress4_.push_back(addr);
IOAddress ioaddr(addr);
ioaddress4_.push_back(ioaddr);
}
for (int i = 0; ADDRESS6[i] != NULL; ++i) {
string addr(ADDRESS6[i]);
straddress6_.push_back(addr);
IOAddress ioaddr(addr);
ioaddress6_.push_back(ioaddr);
}
// Ensure schema is the correct one.
destroySchema();
......@@ -214,361 +189,6 @@ public:
lmptr_ = &(LeaseMgrFactory::instance());
}
/// @brief Initialize Lease4 Fields
///
/// Returns a pointer to a Lease4 structure. Different values are put into
/// the lease according to the address passed.
///
/// This is just a convenience function for the test methods.
///
/// @param address Address to use for the initialization
///
/// @return Lease4Ptr. This will not point to anything if the
/// initialization failed (e.g. unknown address).
Lease4Ptr initializeLease4(std::string address) {
Lease4Ptr lease(new Lease4());
// Set the address of the lease
lease->addr_ = IOAddress(address);
// Initialize unused fields.
lease->ext_ = 0; // Not saved
lease->t1_ = 0; // Not saved
lease->t2_ = 0; // Not saved
lease->fixed_ = false; // Unused
lease->comments_ = std::string(""); // Unused
// Set other parameters. For historical reasons, address 0 is not used.
if (address == straddress4_[0]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x08);
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x42)));
lease->valid_lft_ = 8677;
lease->cltt_ = 168256;
lease->subnet_id_ = 23;
lease->fqdn_rev_ = true;
lease->fqdn_fwd_ = false;
lease->hostname_ = "myhost.example.com.";
} else if (address == straddress4_[1]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x19);
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53)));
lease->valid_lft_ = 3677;
lease->cltt_ = 123456;
lease->subnet_id_ = 73;
lease->fqdn_rev_ = true;
lease->fqdn_fwd_ = true;
lease->hostname_ = "myhost.example.com.";
} else if (address == straddress4_[2]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x2a);
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x64)));
lease->valid_lft_ = 5412;
lease->cltt_ = 234567;
lease->subnet_id_ = 73; // Same as lease 1
lease->fqdn_rev_ = false;
lease->fqdn_fwd_ = false;
lease->hostname_ = "";
} else if (address == straddress4_[3]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x19); // Same as lease 1
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x75)));
// The times used in the next tests are deliberately restricted - we
// should be able to cope with valid lifetimes up to 0xffffffff.
// However, this will lead to overflows.
// @TODO: test overflow conditions when code has been fixed
lease->valid_lft_ = 7000;
lease->cltt_ = 234567;
lease->subnet_id_ = 37;
lease->fqdn_rev_ = true;
lease->fqdn_fwd_ = true;
lease->hostname_ = "otherhost.example.com.";
} else if (address == straddress4_[4]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x4c);
// Same ClientId as straddr4_[1]
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 7736;
lease->cltt_ = 222456;
lease->subnet_id_ = 85;
lease->fqdn_rev_ = true;
lease->fqdn_fwd_ = true;
lease->hostname_ = "otherhost.example.com.";
} else if (address == straddress4_[5]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x19); // Same as lease 1
// Same ClientId and IAID as straddress4_1
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 7832;
lease->cltt_ = 227476;
lease->subnet_id_ = 175;
lease->fqdn_rev_ = false;
lease->fqdn_fwd_ = false;
lease->hostname_ = "otherhost.example.com.";
} else if (address == straddress4_[6]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x6e);
// Same ClientId as straddress4_1
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 1832;