Commit 4c182262 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[2592] getLease4(clientid,hwaddr,subnetid) implemented in memfile LeaseMgr

- Patch by David Carlier
parent 96ad7421
......@@ -204,6 +204,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
......
......@@ -124,11 +124,7 @@ Memfile_LeaseMgr::getLease4(const ClientId& clientid) const {
// 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_) {
continue;
}
if(*(*lease)->client_id_ == clientid) {
if((*lease)->client_id_ && *(*lease)->client_id_ == clientid) {
collection.push_back((* lease));
}
}
......@@ -138,7 +134,36 @@ Memfile_LeaseMgr::getLease4(const ClientId& clientid) const {
Lease4Ptr
Memfile_LeaseMgr::getLease4(const ClientId& client_id,
SubnetID subnet_id) const {
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());
......
......@@ -107,6 +107,21 @@ public:
/// @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
///
/// There can be at most one lease for a given HW address in a single
......@@ -321,6 +336,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.
......
......@@ -145,6 +145,10 @@ TEST_F(MemfileLeaseMgrTest, getLease4ClientId) {
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
......@@ -170,9 +174,8 @@ TEST_F(MemfileLeaseMgrTest, getLease4HWAddr) {
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]);
Lease4Ptr leaseB = initializeLease4(straddress4_[6]);
HWAddr hwaddrA(leaseA->hwaddr_, HTYPE_ETHER);
HWAddr hwaddrB(leaseB->hwaddr_, HTYPE_ETHER);
HWAddr hwaddrB(vector<uint8_t>(6, 0x80), HTYPE_ETHER);
EXPECT_TRUE(lease_mgr->addLease(leaseA));
......@@ -185,4 +188,26 @@ TEST_F(MemfileLeaseMgrTest, getLease4HWAddr) {
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
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