Commit 733a15db authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[master] Merge branch 'trac3146' (Abstract LeaseMgr support for PD)

Conflicts:
	ChangeLog
parents 27e895a6 05a05d81
674. [func] tomek
Preparatory work for prefix delegation in LeaseMgr. getLease6()
renamed to getLeases6(). It now can return more than one lease.
(Trac #3146, git 05a05d810be754e7a4d8ca181550867febf6dcc6)
673. [func] tomek
libdhcp: Added support for IA_PD and IAPREFIX options. New class
for IAPREFIX (Option6_IAPrefix) has been added.
......
......@@ -1223,13 +1223,18 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
// will try to honour the hint, but it is just a hint - some other address
// may be used instead. If fake_allocation is set to false, the lease will
// be inserted into the LeaseMgr as well.
Lease6Ptr lease = alloc_engine_->allocateAddress6(subnet, duid,
ia->getIAID(),
hint,
do_fwd, do_rev,
hostname,
fake_allocation,
callout_handle);
Lease6Collection leases = alloc_engine_->allocateAddress6(subnet, duid,
ia->getIAID(),
hint,
do_fwd, do_rev,
hostname,
fake_allocation,
callout_handle);
/// @todo: Handle more than one lease
Lease6Ptr lease;
if (!leases.empty()) {
lease = *leases.begin();
}
// Create IA_NA that we will put in the response.
// Do not use OptionDefinition to create option's instance so
......@@ -1316,7 +1321,8 @@ Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
return (ia_rsp);
}
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(*duid, ia->getIAID(),
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
*duid, ia->getIAID(),
subnet->getID());
if (!lease) {
......@@ -1579,7 +1585,8 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
return (ia_rsp);
}
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(release_addr->getAddress());
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
release_addr->getAddress());
if (!lease) {
// client releasing a lease that we don't know about.
......
......@@ -1024,7 +1024,8 @@ TEST_F(Dhcpv6SrvTest, RenewBasic) {
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Check that the lease is really in the database
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr);
ASSERT_TRUE(l);
// Check that T1, T2, preferred, valid and cltt really set and not using
......@@ -1116,7 +1117,8 @@ TEST_F(Dhcpv6SrvTest, RenewReject) {
OptionPtr clientid = generateClientId();
// Check that the lease is NOT in the database
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr);
ASSERT_FALSE(l);
// Let's create a RENEW
......@@ -1147,7 +1149,7 @@ TEST_F(Dhcpv6SrvTest, RenewReject) {
checkIA_NAStatusCode(ia, STATUS_NoBinding);
// Check that there is no lease added
l = LeaseMgrFactory::instance().getLease6(addr);
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
ASSERT_FALSE(l);
// CASE 2: Lease is known and belongs to this client, but to a different IAID
......@@ -1189,7 +1191,7 @@ TEST_F(Dhcpv6SrvTest, RenewReject) {
ASSERT_TRUE(ia);
checkIA_NAStatusCode(ia, STATUS_NoBinding);
lease = LeaseMgrFactory::instance().getLease6(addr);
lease = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
ASSERT_TRUE(lease);
// Verify that the lease was not updated.
EXPECT_EQ(123, lease->cltt_);
......@@ -1226,7 +1228,8 @@ TEST_F(Dhcpv6SrvTest, ReleaseBasic) {
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Check that the lease is really in the database
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr);
ASSERT_TRUE(l);
// Let's create a RELEASE
......@@ -1265,11 +1268,12 @@ TEST_F(Dhcpv6SrvTest, ReleaseBasic) {
// Check that the lease is really gone in the database
// get lease by address
l = LeaseMgrFactory::instance().getLease6(addr);
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
ASSERT_FALSE(l);
// get lease by subnetid/duid/iaid combination
l = LeaseMgrFactory::instance().getLease6(*duid_, iaid, subnet_->getID());
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, *duid_, iaid,
subnet_->getID());
ASSERT_FALSE(l);
}
......@@ -1301,7 +1305,8 @@ TEST_F(Dhcpv6SrvTest, ReleaseReject) {
OptionPtr clientid = generateClientId();
// Check that the lease is NOT in the database
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr);
ASSERT_FALSE(l);
// Let's create a RELEASE
......@@ -1334,7 +1339,7 @@ TEST_F(Dhcpv6SrvTest, ReleaseReject) {
checkMsgStatusCode(reply, STATUS_NoBinding);
// Check that the lease is not there
l = LeaseMgrFactory::instance().getLease6(addr);
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
ASSERT_FALSE(l);
// CASE 2: Lease is known and belongs to this client, but to a different IAID
......@@ -1356,7 +1361,7 @@ TEST_F(Dhcpv6SrvTest, ReleaseReject) {
checkMsgStatusCode(reply, STATUS_NoBinding);
// Check that the lease is still there
l = LeaseMgrFactory::instance().getLease6(addr);
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
ASSERT_TRUE(l);
// CASE 3: Lease belongs to a client with different client-id
......@@ -1379,7 +1384,7 @@ TEST_F(Dhcpv6SrvTest, ReleaseReject) {
checkMsgStatusCode(reply, STATUS_NoBinding);
// Check that the lease is still there
l = LeaseMgrFactory::instance().getLease6(addr);
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
ASSERT_TRUE(l);
// Finally, let's cleanup the database
......
......@@ -377,7 +377,8 @@ public:
boost::shared_ptr<Option6IAAddr> addr) {
boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(ia_na);
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(addr->getAddress());
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr->getAddress());
if (!lease) {
std::cout << "Lease for " << addr->getAddress().toText()
<< " not found in the database backend.";
......
......@@ -1076,7 +1076,8 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_renew) {
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Check that the lease is really in the database
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr);
ASSERT_TRUE(l);
// Check that T1, T2, preferred, valid and cltt really set and not using
......@@ -1172,7 +1173,8 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdate_lease6_renew) {
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Check that the lease is really in the database
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr);
ASSERT_TRUE(l);
// Check that T1, T2, preferred, valid and cltt really set and not using
......@@ -1262,7 +1264,8 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_renew) {
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Check that the lease is really in the database
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr);
ASSERT_TRUE(l);
// Check that T1, T2, preferred, valid and cltt really set and not using
......@@ -1293,7 +1296,7 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_renew) {
// Check that our callback was called
EXPECT_EQ("lease6_renew", callback_name_);
l = LeaseMgrFactory::instance().getLease6(addr);
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
// Check that the old values are still there and they were not
// updated by the renewal
......@@ -1337,7 +1340,8 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_release) {
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Check that the lease is really in the database
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr);
ASSERT_TRUE(l);
// Let's create a RELEASE
......@@ -1375,11 +1379,12 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_release) {
// Check that the lease is really gone in the database
// get lease by address
l = LeaseMgrFactory::instance().getLease6(addr);
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, addr);
ASSERT_FALSE(l);
// Get lease by subnetid/duid/iaid combination
l = LeaseMgrFactory::instance().getLease6(*duid_, iaid, subnet_->getID());
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, *duid_, iaid,
subnet_->getID());
ASSERT_FALSE(l);
}
......@@ -1416,7 +1421,8 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_release) {
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Check that the lease is really in the database
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(addr);
Lease6Ptr l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr);
ASSERT_TRUE(l);
// Let's create a RELEASE
......@@ -1442,11 +1448,13 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_release) {
// Check that the lease is still there
// get lease by address
l = LeaseMgrFactory::instance().getLease6(addr);
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA,
addr);
ASSERT_TRUE(l);
// Get lease by subnetid/duid/iaid combination
l = LeaseMgrFactory::instance().getLease6(*duid_, iaid, subnet_->getID());
l = LeaseMgrFactory::instance().getLease6(Lease6::LEASE_IA_NA, *duid_, iaid,
subnet_->getID());
ASSERT_TRUE(l);
}
......
......@@ -195,7 +195,7 @@ AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts)
hook_index_lease6_select_ = Hooks.hook_index_lease6_select_;
}
Lease6Ptr
Lease6Collection
AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
const DuidPtr& duid,
uint32_t iaid,
......@@ -222,40 +222,52 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
}
// check if there's existing lease for that subnet/duid/iaid combination.
Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(*duid, iaid, subnet->getID());
if (existing) {
// we have a lease already. This is a returning client, probably after
// his reboot.
/// @todo: Make this generic (cover temp. addrs and prefixes)
Lease6Collection existing = LeaseMgrFactory::instance().getLeases6(
Lease6::LEASE_IA_NA, *duid, iaid, subnet->getID());
if (!existing.empty()) {
// we have at least one lease already. This is a returning client,
// probably after his reboot.
return (existing);
}
// check if the hint is in pool and is available
if (subnet->inPool(hint)) {
existing = LeaseMgrFactory::instance().getLease6(hint);
if (!existing) {
/// @todo: We support only one hint for now
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(
Lease6::LEASE_IA_NA, hint);
if (!lease) {
/// @todo: check if the hint is reserved once we have host support
/// implemented
// the hint is valid and not currently used, let's create a lease for it
Lease6Ptr lease = createLease6(subnet, duid, iaid,
hint,
fwd_dns_update,
rev_dns_update, hostname,
callout_handle,
fake_allocation);
/// @todo: We support only one lease per ia for now
lease = createLease6(subnet, duid, iaid, hint, fwd_dns_update,
rev_dns_update, hostname, callout_handle,
fake_allocation);
// It can happen that the lease allocation failed (we could have lost
// the race condition. That means that the hint is lo longer usable and
// we need to continue the regular allocation path.
if (lease) {
return (lease);
/// @todo: We support only one lease per ia for now
Lease6Collection collection;
collection.push_back(lease);
return (collection);
}
} else {
if (existing->expired()) {
return (reuseExpiredLease(existing, subnet, duid, iaid,
if (lease->expired()) {
/// We found a lease and it is expired, so we can reuse it
/// @todo: We support only one lease per ia for now
lease = reuseExpiredLease(lease, subnet, duid, iaid,
fwd_dns_update, rev_dns_update,
hostname, callout_handle,
fake_allocation));
fake_allocation);
Lease6Collection collection;
collection.push_back(lease);
return (collection);
}
}
......@@ -284,7 +296,8 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
/// @todo: check if the address is reserved once we have host support
/// implemented
Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(candidate);
Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(
Lease6::LEASE_IA_NA, candidate);
if (!existing) {
// there's no existing lease for selected candidate, so it is
// free. Let's allocate it.
......@@ -293,7 +306,9 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
hostname,
callout_handle, fake_allocation);
if (lease) {
return (lease);
Lease6Collection collection;
collection.push_back(lease);
return (collection);
}
// Although the address was free just microseconds ago, it may have
......@@ -301,10 +316,13 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
// allocation attempts.
} else {
if (existing->expired()) {
return (reuseExpiredLease(existing, subnet, duid, iaid,
fwd_dns_update, rev_dns_update,
hostname, callout_handle,
fake_allocation));
existing = reuseExpiredLease(existing, subnet, duid, iaid,
fwd_dns_update, rev_dns_update,
hostname, callout_handle,
fake_allocation);
Lease6Collection collection;
collection.push_back(existing);
return (collection);
}
}
......@@ -322,7 +340,7 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
LOG_ERROR(dhcpsrv_logger, DHCPSRV_ADDRESS6_ALLOC_ERROR).arg(e.what());
}
return (Lease6Ptr());
return (Lease6Collection());
}
Lease4Ptr
......@@ -795,7 +813,8 @@ Lease6Ptr AllocEngine::createLease6(const Subnet6Ptr& subnet,
// It is for advertise only. We should not insert the lease into LeaseMgr,
// but rather check that we could have inserted it.
Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(addr);
Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(
Lease6::LEASE_IA_NA, addr);
if (!existing) {
return (lease);
} else {
......
......@@ -295,8 +295,8 @@ protected:
/// @param callout_handle a callout handle (used in hooks). A lease callouts
/// will be executed if this parameter is passed.
///
/// @return Allocated IPv6 lease (or NULL if allocation failed)
Lease6Ptr
/// @return Allocated IPv6 leases (may be empty if allocation failed)
Lease6Collection
allocateAddress6(const Subnet6Ptr& subnet,
const DuidPtr& duid,
uint32_t iaid,
......
......@@ -76,7 +76,9 @@ CREATE INDEX lease6_by_iaid_subnet_id_duid ON lease6 (iaid, subnet_id, duid);
# ... and a definition of lease6 types. This table is a convenience for
# users of the database - if they want to view the lease table and use the
# type names, they can join this table with the lease6 table
# type names, they can join this table with the lease6 table.
# Make sure those values match Lease6::LeaseType enum (see src/bin/dhcpsrv/
# lease_mgr.h)
CREATE TABLE lease6_types (
lease_type TINYINT PRIMARY KEY NOT NULL, # Lease type code.
name VARCHAR(5) # Name of the lease type
......
......@@ -130,6 +130,23 @@ std::string LeaseMgr::getParameter(const std::string& name) const {
return (param->second);
}
Lease6Ptr
LeaseMgr::getLease6(Lease6::LeaseType type, const DUID& duid,
uint32_t iaid, SubnetID subnet_id) const {
Lease6Collection col = getLeases6(type, duid, iaid, subnet_id);
if (col.size() > 1) {
isc_throw(MultipleRecords, "More than one lease found for type "
<< static_cast<int>(type) << ", duid "
<< duid.toText() << ", iaid " << iaid
<< " and subnet-id " << subnet_id);
}
if (col.empty()) {
return (Lease6Ptr());
}
return (*col.begin());
}
std::string
Lease6::toText() const {
ostringstream stream;
......
......@@ -318,9 +318,9 @@ struct Lease6 : public Lease {
/// @brief Type of lease contents
typedef enum {
LEASE_IA_NA, /// the lease contains non-temporary IPv6 address
LEASE_IA_TA, /// the lease contains temporary IPv6 address
LEASE_IA_PD /// the lease contains IPv6 prefix (for prefix delegation)
LEASE_IA_NA = 0, /// the lease contains non-temporary IPv6 address
LEASE_IA_TA = 1, /// the lease contains temporary IPv6 address
LEASE_IA_PD = 2 /// the lease contains IPv6 prefix (for prefix delegation)
} LeaseType;
/// @brief Lease type
......@@ -533,10 +533,12 @@ public:
/// The assumption here is that there will not be site or link-local
/// addresses used, so there is no way of having address duplication.
///
/// @param type specifies lease type: (NA, TA or PD)
/// @param addr address of the searched lease
///
/// @return smart pointer to the lease (or NULL if a lease is not found)
virtual Lease6Ptr getLease6(const isc::asiolink::IOAddress& addr) const = 0;
virtual Lease6Ptr getLease6(Lease6::LeaseType type,
const isc::asiolink::IOAddress& addr) const = 0;
/// @brief Returns existing IPv6 leases for a given DUID+IA combination
///
......@@ -545,22 +547,54 @@ public:
/// can be more than one. Thus return type is a container, not a single
/// pointer.
///
/// @param type specifies lease type: (NA, TA or PD)
/// @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;
/// @return Lease collection (may be empty if no lease is found)
virtual Lease6Collection getLeases6(Lease6::LeaseType type, const DUID& duid,
uint32_t iaid) const = 0;
/// @brief Returns existing IPv6 lease for a given DUID+IA combination
///
/// There may be more than one address, temp. address or prefix
/// for specified duid/iaid/subnet-id tuple.
///
/// @param type specifies lease type: (NA, TA or PD)
/// @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,
SubnetID subnet_id) const = 0;
/// @return Lease collection (may be empty if no lease is found)
virtual Lease6Collection getLeases6(Lease6::LeaseType type, const DUID& duid,
uint32_t iaid, SubnetID subnet_id) const = 0;
/// @brief returns zero or one IPv6 lease for a given duid+iaid+subnet_id
///
/// This function is mostly intended to be used in unit-tests during the
/// transition from single to multi address per IA. It may also be used
/// in other cases where at most one lease is expected in the database.
///
/// It is a wrapper around getLease6(), which returns a collection of
/// leases. That collection can be converted into a single pointer if
/// there are no leases (NULL pointer) or one lease (use that single lease).
/// If there are more leases in the collection, the function will
/// throw MultipleRecords exception.
///
/// Note: This method is not virtual on purpose. It is common for all
/// backends.
///
/// @param type specifies lease type: (NA, TA or PD)
/// @param duid client DUID
/// @param iaid IA identifier
/// @param subnet_id subnet id of the subnet the lease belongs to
///
/// @throw MultipleRecords if there is more than one lease matching
///
/// @return Lease pointer (or NULL if none is found)
Lease6Ptr getLease6(Lease6::LeaseType type, const DUID& duid,
uint32_t iaid, SubnetID subnet_id) const;
/// @brief Updates IPv4 lease.
///
......
......@@ -46,7 +46,7 @@ Memfile_LeaseMgr::addLease(const Lease6Ptr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_ADD_ADDR6).arg(lease->addr_.toText());
if (getLease6(lease->addr_)) {
if (getLease6(lease->type_, lease->addr_)) {
// there is a lease with specified address already
return (false);
}
......@@ -186,7 +186,8 @@ Memfile_LeaseMgr::getLease4(const ClientId& client_id,
}
Lease6Ptr
Memfile_LeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
Memfile_LeaseMgr::getLease6(Lease6::LeaseType /* not used yet */,
const isc::asiolink::IOAddress& addr) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MEMFILE_GET_ADDR6).arg(addr.toText());
......@@ -199,16 +200,20 @@ Memfile_LeaseMgr::getLease6(const isc::asiolink::IOAddress& addr) const {
}
Lease6Collection
Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid) const {
Memfile_LeaseMgr::getLeases6(Lease6::LeaseType /* not used yet */,
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());
/// @todo Not implemented.
return (Lease6Collection());
}
Lease6Ptr
Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
SubnetID subnet_id) const {
Lease6Collection
Memfile_LeaseMgr::getLeases6(Lease6::LeaseType /* not used yet */,
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());
......@@ -224,10 +229,14 @@ Memfile_LeaseMgr::getLease6(const DUID& duid, uint32_t iaid,
idx.find(boost::make_tuple(duid.getDuid(), iaid, subnet_id));
// Lease was not found. Return empty pointer.
if (lease == idx.end()) {
return (Lease6Ptr());
return (Lease6Collection());
}
// Lease was found, return it to the caller.
return (Lease6Ptr(new Lease6(**lease)));
/// @todo: allow multiple leases for a single duid+iaid+subnet_id tuple
Lease6Collection collection;
collection.push_back(Lease6Ptr(new Lease6(**lease)));
return (collection);
}
void
......
......@@ -140,33 +140,38 @@ public:
/// This function returns a copy of the lease. The modification in the
/// return lease does not affect the instance held in the lease storage.
///
/// @param type specifies lease type: (NA, TA or PD)
/// @param addr An address of the searched lease.
///
/// @return smart pointer to the lease (or NULL if a lease is not found)
virtual Lease6Ptr getLease6(const isc::asiolink::IOAddress& addr) const;
virtual Lease6Ptr getLease6(Lease6::LeaseType type,
const isc::asiolink::IOAddress& addr) const;
/// @brief Returns existing IPv6 lease for a given DUID+IA combination
///
/// @todo Not implemented yet
///
/// @param type specifies lease type: (NA, TA or PD)
/// @param duid client DUID
/// @param iaid IA identifier
///
/// @return collection of IPv6 leases
virtual Lease6Collection getLease6(const DUID& duid, uint32_t iaid) const;
virtual Lease6Collection getLeases6(Lease6::LeaseType type,
const DUID& duid, uint32_t iaid) const;
/// @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.