Commit 8f112316 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[3555] Lease4,Lease6 now uses HWAddr structure.

parent 2ab5930b
......@@ -489,8 +489,7 @@ Dhcpv4Srv::computeDhcid(const Lease4Ptr& lease) {
return (D2Dhcid(lease->client_id_->getClientId(), fqdn_wire));
} else {
HWAddrPtr hwaddr(new HWAddr(lease->hwaddr_, HTYPE_ETHER));
return (D2Dhcid(hwaddr, fqdn_wire));
return (D2Dhcid(lease->hwaddr_, fqdn_wire));
}
} catch (const Exception& ex) {
isc_throw(DhcidComputeError, "unable to compute DHCID: "
......@@ -1391,8 +1390,10 @@ Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
}
// Does the hardware address match? We don't want one client releasing
// second client's leases.
if (lease->hwaddr_ != release->getHWAddr()->hwaddr_) {
// second client's leases. Note that we're comparing the hardware
// addresses only, not hardware types or sources of the hardware
// addresses. Thus we don't use HWAddr::equals().
if (lease->hwaddr_->hwaddr_ != release->getHWAddr()->hwaddr_) {
/// @todo: Print hwaddr from lease as part of ticket #2589
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, DHCP4_RELEASE_FAIL_WRONG_HWADDR)
.arg(release->getCiaddr().toText())
......
......@@ -123,8 +123,7 @@ Dhcp4Client::applyConfiguration() {
/// @todo Set the valid lifetime, t1, t2 etc.
config_.lease_ = Lease4(IOAddress(context_.response_->getYiaddr()),
&context_.response_->getHWAddr()->hwaddr_[0],
context_.response_->getHWAddr()->hwaddr_.size(),
context_.response_->getHWAddr(),
0, 0, 0, 0, 0, time(NULL), 0, false, false,
"");
}
......@@ -132,8 +131,7 @@ Dhcp4Client::applyConfiguration() {
void
Dhcp4Client::createLease(const asiolink::IOAddress& addr,
const uint32_t valid_lft) {
Lease4 lease(addr, &hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
0, 0, valid_lft, valid_lft / 2, valid_lft,
Lease4 lease(addr, hwaddr_, 0, 0, valid_lft, valid_lft / 2, valid_lft,
time(NULL), false, false, "");
config_.lease_ = lease;
}
......
......@@ -816,8 +816,9 @@ TEST_F(Dhcpv4SrvTest, RenewBasic) {
ASSERT_TRUE(subnet_->inPool(Lease::TYPE_V4, addr));
// let's create a lease and put it in the LeaseMgr
uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2, sizeof(hwaddr2),
uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER));
Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2,
&client_id_->getDuid()[0], client_id_->getDuid().size(),
temp_valid, temp_t1, temp_t2, temp_timestamp,
subnet_->getID()));
......@@ -983,9 +984,9 @@ TEST_F(Dhcpv4SrvTest, ReleaseBasic) {
ASSERT_TRUE(subnet_->inPool(Lease::TYPE_V4, addr));
// Let's create a lease and put it in the LeaseMgr
uint8_t mac_addr[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
HWAddrPtr hw(new HWAddr(mac_addr, sizeof(mac_addr), HTYPE_ETHER));
Lease4Ptr used(new Lease4(addr, mac_addr, sizeof(mac_addr),
uint8_t hwaddr_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
HWAddrPtr hwaddr(new HWAddr(hwaddr_data, sizeof(hwaddr_data), HTYPE_ETHER));
Lease4Ptr used(new Lease4(addr, hwaddr,
&client_id_->getDuid()[0], client_id_->getDuid().size(),
temp_valid, temp_t1, temp_t2, temp_timestamp,
subnet_->getID()));
......@@ -1002,7 +1003,7 @@ TEST_F(Dhcpv4SrvTest, ReleaseBasic) {
rel->setCiaddr(addr);
rel->addOption(clientid);
rel->addOption(srv->getServerID());
rel->setHWAddr(hw);
rel->setHWAddr(hwaddr);
rel->setIface("eth0");
// Pass it to the server and hope for a REPLY
......@@ -1014,11 +1015,11 @@ TEST_F(Dhcpv4SrvTest, ReleaseBasic) {
EXPECT_FALSE(l);
// Try to get the lease by hardware address
Lease4Collection leases = LeaseMgrFactory::instance().getLease4(hw->hwaddr_);
Lease4Collection leases = LeaseMgrFactory::instance().getLease4(*hwaddr);
EXPECT_EQ(leases.size(), 0);
// Try to get it by hw/subnet_id combination
l = LeaseMgrFactory::instance().getLease4(hw->hwaddr_, subnet_->getID());
l = LeaseMgrFactory::instance().getLease4(*hwaddr, subnet_->getID());
EXPECT_FALSE(l);
// Try by client-id
......@@ -1083,7 +1084,7 @@ TEST_F(Dhcpv4SrvTest, ReleaseReject) {
// Let's create a lease and put it in the LeaseMgr
uint8_t mac_addr[] = { 0, 0x1, 0x2, 0x3, 0x4, 0x5};
HWAddrPtr hw(new HWAddr(mac_addr, sizeof(mac_addr), HTYPE_ETHER));
Lease4Ptr used(new Lease4(addr, mac_addr, sizeof(mac_addr),
Lease4Ptr used(new Lease4(addr, hw,
&client_id_->getDuid()[0], client_id_->getDuid().size(),
valid, t1, t2, timestamp, subnet_->getID()));
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(used));
......@@ -2613,8 +2614,9 @@ TEST_F(HooksDhcpv4SrvTest, lease4RenewSimple) {
ASSERT_TRUE(subnet_->inPool(Lease::TYPE_V4, addr));
// let's create a lease and put it in the LeaseMgr
uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2, sizeof(hwaddr2),
uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER));
Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2,
&client_id_->getDuid()[0], client_id_->getDuid().size(),
temp_valid, temp_t1, temp_t2, temp_timestamp,
subnet_->getID()));
......@@ -2700,8 +2702,9 @@ TEST_F(HooksDhcpv4SrvTest, lease4RenewSkip) {
ASSERT_TRUE(subnet_->inPool(Lease::TYPE_V4, addr));
// let's create a lease and put it in the LeaseMgr
uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2, sizeof(hwaddr2),
uint8_t hwaddr2_data[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
HWAddrPtr hwaddr2(new HWAddr(hwaddr2_data, sizeof(hwaddr2_data), HTYPE_ETHER));
Lease4Ptr used(new Lease4(IOAddress("192.0.2.106"), hwaddr2,
&client_id_->getDuid()[0], client_id_->getDuid().size(),
temp_valid, temp_t1, temp_t2, temp_timestamp,
subnet_->getID()));
......@@ -2769,7 +2772,7 @@ TEST_F(HooksDhcpv4SrvTest, lease4ReleaseSimple) {
// Let's create a lease and put it in the LeaseMgr
uint8_t mac_addr[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
HWAddrPtr hw(new HWAddr(mac_addr, sizeof(mac_addr), HTYPE_ETHER));
Lease4Ptr used(new Lease4(addr, mac_addr, sizeof(mac_addr),
Lease4Ptr used(new Lease4(addr, hw,
&client_id_->getDuid()[0], client_id_->getDuid().size(),
temp_valid, temp_t1, temp_t2, temp_timestamp,
subnet_->getID()));
......@@ -2856,7 +2859,7 @@ TEST_F(HooksDhcpv4SrvTest, lease4ReleaseSkip) {
// Let's create a lease and put it in the LeaseMgr
uint8_t mac_addr[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
HWAddrPtr hw(new HWAddr(mac_addr, sizeof(mac_addr), HTYPE_ETHER));
Lease4Ptr used(new Lease4(addr, mac_addr, sizeof(mac_addr),
Lease4Ptr used(new Lease4(addr, hw,
&client_id_->getDuid()[0], client_id_->getDuid().size(),
temp_valid, temp_t1, temp_t2, temp_timestamp,
subnet_->getID()));
......
......@@ -307,8 +307,9 @@ TEST_F(DirectClientTest, renew) {
// Create a lease for a client that we will later renewed. By explicitly
// creating a lease we will get to know the lease parameters, such as
// leased address etc.
const uint8_t hwaddr[] = { 1, 2, 3, 4, 5, 6 };
Lease4Ptr lease(new Lease4(IOAddress("10.0.0.10"), hwaddr, sizeof(hwaddr),
const uint8_t hwaddr_data[] = { 1, 2, 3, 4, 5, 6 };
HWAddrPtr hwaddr(new HWAddr(hwaddr_data, sizeof(hwaddr_data), HTYPE_ETHER));
Lease4Ptr lease(new Lease4(IOAddress("10.0.0.10"), hwaddr,
&generateClientId()->getData()[0],
generateClientId()->getData().size(),
100, 50, 75, time(NULL),
......@@ -364,8 +365,9 @@ TEST_F(DirectClientTest, rebind) {
classify_);
// Create a lease, which will be later renewed. By explicitly creating a
// lease we will know the lease parameters, such as leased address etc.
const uint8_t hwaddr[] = { 1, 2, 3, 4, 5, 6 };
Lease4Ptr lease(new Lease4(IOAddress("10.0.0.10"), hwaddr, sizeof(hwaddr),
const uint8_t hwaddr_data[] = { 1, 2, 3, 4, 5, 6 };
HWAddrPtr hwaddr(new HWAddr(hwaddr_data, sizeof(hwaddr_data), HTYPE_ETHER));
Lease4Ptr lease(new Lease4(IOAddress("10.0.0.10"), hwaddr,
&generateClientId()->getData()[0],
generateClientId()->getData().size(),
100, 50, 75, time(NULL),
......
......@@ -93,8 +93,9 @@ public:
const std::string& hostname,
const bool fqdn_fwd,
const bool fqdn_rev) {
const uint8_t hwaddr[] = { 0, 1, 2, 3, 4, 5, 6 };
Lease4Ptr lease(new Lease4(addr, hwaddr, sizeof(hwaddr),
const uint8_t hwaddr_data[] = { 0, 1, 2, 3, 4, 5, 6 };
HWAddrPtr hwaddr(new HWAddr(hwaddr_data, sizeof(hwaddr_data), HTYPE_ETHER));
Lease4Ptr lease(new Lease4(addr, hwaddr,
&generateClientId()->getData()[0],
generateClientId()->getData().size(),
100, 50, 75, time(NULL), subnet_->getID()));
......
......@@ -1268,6 +1268,11 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
hostname = fqdn->getDomainName();
}
// Attempt to get MAC address using any of available mechanisms.
// It's ok if there response is NULL. Hardware address is optional in Lease6
/// @todo: Make this configurable after trac 3554 is done.
HWAddrPtr hwaddr = query->getMAC(Pkt::HWADDR_SOURCE_ANY);
// Use allocation engine to pick a lease for this client. Allocation engine
// 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
......@@ -1280,7 +1285,8 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
hostname,
fake_allocation,
callout_handle,
old_leases);
old_leases,
hwaddr);
/// @todo: Handle more than one lease
Lease6Ptr lease;
if (!leases.empty()) {
......@@ -1383,6 +1389,11 @@ Dhcpv6Srv::assignIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid,
hint = hint_opt->getAddress();
}
// Attempt to get MAC address using any of available mechanisms.
// It's ok if there response is NULL. Hardware address is optional in Lease6
/// @todo: Make this configurable after trac 3554 is done.
HWAddrPtr hwaddr = query->getMAC(Pkt::HWADDR_SOURCE_ANY);
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_PROCESS_IA_PD_REQUEST)
.arg(duid ? duid->toText() : "(no-duid)").arg(ia->getIAID())
.arg(hint_opt ? hint.toText() : "(no hint)");
......@@ -1409,7 +1420,7 @@ Dhcpv6Srv::assignIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid,
string(),
fake_allocation,
callout_handle,
old_leases);
old_leases, hwaddr);
if (!leases.empty()) {
......
......@@ -117,6 +117,7 @@ Dhcp6Client::applyRcvdConfiguration(const Pkt6Ptr& reply) {
iaprefix->getPreferred(),
iaprefix->getValid(),
ia->getT1(), ia->getT2(), 0,
HWAddrPtr(),
iaprefix->getLength());
lease_info.lease_.cltt_ = time(NULL);
}
......
......@@ -213,7 +213,7 @@ Dhcpv6SrvTest::testRenewBasic(Lease::Type type, const std::string& existing_addr
// Note that preferred, valid, T1 and T2 timers and CLTT are set to invalid
// value on purpose. They should be updated during RENEW.
Lease6Ptr lease(new Lease6(type, existing, duid_, iaid, 501, 502, 503, 504,
subnet_->getID(), prefix_len));
subnet_->getID(), HWAddrPtr(), prefix_len));
lease->cltt_ = 1234;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
......@@ -358,7 +358,7 @@ Dhcpv6SrvTest::testRenewReject(Lease::Type type, const IOAddress& addr) {
// value on purpose. They should be updated during RENEW.
Lease6Ptr lease(new Lease6(type, addr, duid_, valid_iaid,
501, 502, 503, 504, subnet_->getID(),
prefix_len));
HWAddrPtr(), prefix_len));
lease->cltt_ = 123; // Let's use it as an indicator that the lease
// was NOT updated.
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
......@@ -430,7 +430,7 @@ Dhcpv6SrvTest::testReleaseBasic(Lease::Type type, const IOAddress& existing,
// Let's prepopulate the database
Lease6Ptr lease(new Lease6(type, existing, duid_, iaid,
501, 502, 503, 504, subnet_->getID(),
prefix_len));
HWAddrPtr(), prefix_len));
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Check that the lease is really in the database
......@@ -536,7 +536,7 @@ Dhcpv6SrvTest::testReleaseReject(Lease::Type type, const IOAddress& addr) {
SCOPED_TRACE("CASE 2: Lease is known and belongs to this client, but to a different IAID");
Lease6Ptr lease(new Lease6(type, addr, duid_, valid_iaid, 501, 502, 503,
504, subnet_->getID(), prefix_len));
504, subnet_->getID(), HWAddrPtr(), prefix_len));
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
// Let's create a different RELEASE, with a bogus iaid
......
......@@ -77,7 +77,7 @@ public:
generateClientId();
lease_.reset(new Lease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1"),
duid_, 1234, 501, 502, 503,
504, 1, 0));
504, 1, HWAddrPtr(), 0));
// Config DDNS to be enabled, all controls off
enableD2();
}
......
......@@ -1046,7 +1046,8 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_renew) {
// Note that preferred, valid, T1 and T2 timers and CLTT are set to invalid
// value on purpose. They should be updated during RENEW.
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, duid_, iaid,
501, 502, 503, 504, subnet_->getID(), 0));
501, 502, 503, 504, subnet_->getID(),
HWAddrPtr(), 0));
lease->cltt_ = 1234;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
......@@ -1144,7 +1145,8 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdate_lease6_renew) {
// Note that preferred, valid, T1 and T2 timers and CLTT are set to invalid
// value on purpose. They should be updated during RENEW.
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, duid_, iaid,
501, 502, 503, 504, subnet_->getID(), 0));
501, 502, 503, 504, subnet_->getID(),
HWAddrPtr(), 0));
lease->cltt_ = 1234;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
......@@ -1236,7 +1238,8 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_renew) {
// Note that preferred, valid, T1 and T2 timers and CLTT are set to invalid
// value on purpose. They should be updated during RENEW.
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, duid_, iaid,
501, 502, 503, 504, subnet_->getID(), 0));
501, 502, 503, 504, subnet_->getID(),
HWAddrPtr(), 0));
lease->cltt_ = 1234;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
......@@ -1313,7 +1316,8 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_release) {
// Note that preferred, valid, T1 and T2 timers and CLTT are set to invalid
// value on purpose. They should be updated during RENEW.
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, duid_, iaid,
501, 502, 503, 504, subnet_->getID(), 0));
501, 502, 503, 504, subnet_->getID(),
HWAddrPtr(), 0));
lease->cltt_ = 1234;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
......@@ -1394,7 +1398,8 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_release) {
// Note that preferred, valid, T1 and T2 timers and CLTT are set to invalid
// value on purpose. They should be updated during RENEW.
Lease6Ptr lease(new Lease6(Lease::TYPE_NA, addr, duid_, iaid,
501, 502, 503, 504, subnet_->getID(), 0));
501, 502, 503, 504, subnet_->getID(),
HWAddrPtr(), 0));
lease->cltt_ = 1234;
ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease));
......
......@@ -299,7 +299,7 @@ AllocEngine::allocateLeases6(const Subnet6Ptr& subnet, const DuidPtr& duid,
const bool rev_dns_update,
const std::string& hostname, bool fake_allocation,
const isc::hooks::CalloutHandlePtr& callout_handle,
Lease6Collection& old_leases) {
Lease6Collection& old_leases, const HWAddrPtr& hwaddr) {
try {
AllocatorPtr allocator = getAllocator(type);
......@@ -349,7 +349,7 @@ AllocEngine::allocateLeases6(const Subnet6Ptr& subnet, const DuidPtr& duid,
lease = createLease6(subnet, duid, iaid, hint,
pool->getLength(), type,
fwd_dns_update, rev_dns_update,
hostname, callout_handle, fake_allocation);
hostname, hwaddr, 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
......@@ -429,7 +429,7 @@ AllocEngine::allocateLeases6(const Subnet6Ptr& subnet, const DuidPtr& duid,
Lease6Ptr lease = createLease6(subnet, duid, iaid, candidate,
prefix_len, type, fwd_dns_update,
rev_dns_update, hostname,
rev_dns_update, hostname, hwaddr,
callout_handle, fake_allocation);
if (lease) {
// We are allocating a new lease (not renewing). So, the
......@@ -664,7 +664,7 @@ Lease4Ptr AllocEngine::renewLease4(const SubnetPtr& subnet,
Lease4 old_values = *lease;
lease->subnet_id_ = subnet->getID();
lease->hwaddr_ = hwaddr->hwaddr_;
lease->hwaddr_ = hwaddr;
lease->client_id_ = clientid;
lease->cltt_ = time(NULL);
lease->t1_ = subnet->getT1();
......@@ -819,7 +819,7 @@ Lease4Ptr AllocEngine::reuseExpiredLease(Lease4Ptr& expired,
// address, lease type and prefixlen (0) stay the same
expired->client_id_ = clientid;
expired->hwaddr_ = hwaddr->hwaddr_;
expired->hwaddr_ = hwaddr;
expired->valid_lft_ = subnet->getValid();
expired->t1_ = subnet->getT1();
expired->t2_ = subnet->getT2();
......@@ -893,6 +893,7 @@ Lease6Ptr AllocEngine::createLease6(const Subnet6Ptr& subnet,
const bool fwd_dns_update,
const bool rev_dns_update,
const std::string& hostname,
const HWAddrPtr& hwaddr,
const isc::hooks::CalloutHandlePtr& callout_handle,
bool fake_allocation /*= false */ ) {
......@@ -903,7 +904,7 @@ Lease6Ptr AllocEngine::createLease6(const Subnet6Ptr& subnet,
Lease6Ptr lease(new Lease6(type, addr, duid, iaid,
subnet->getPreferred(), subnet->getValid(),
subnet->getT1(), subnet->getT2(), subnet->getID(),
prefix_len));
hwaddr, prefix_len));
lease->fqdn_fwd_ = fwd_dns_update;
lease->fqdn_rev_ = rev_dns_update;
......@@ -990,10 +991,9 @@ Lease4Ptr AllocEngine::createLease4(const SubnetPtr& subnet,
local_copy = clientid->getDuid();
}
Lease4Ptr lease(new Lease4(addr, &hwaddr->hwaddr_[0], hwaddr->hwaddr_.size(),
&local_copy[0], local_copy.size(), subnet->getValid(),
subnet->getT1(), subnet->getT2(), now,
subnet->getID()));
Lease4Ptr lease(new Lease4(addr, hwaddr, &local_copy[0], local_copy.size(),
subnet->getValid(), subnet->getT1(), subnet->getT2(),
now, subnet->getID()));
// Set FQDN specific lease parameters.
lease->fqdn_fwd_ = fwd_dns_update;
......
......@@ -343,6 +343,7 @@ protected:
/// collection of new leases, being returned. For newly allocated
/// leases (not renewed) the NULL pointers are stored in this
/// collection as old leases.
/// @param hwaddr Hardware address (optional, may be null for Lease6)
///
/// @return Allocated IPv6 leases (may be empty if allocation failed)
Lease6Collection
......@@ -352,7 +353,7 @@ protected:
const bool fwd_dns_update, const bool rev_dns_update,
const std::string& hostname, bool fake_allocation,
const isc::hooks::CalloutHandlePtr& callout_handle,
Lease6Collection& old_leases);
Lease6Collection& old_leases, const HWAddrPtr& hwaddr);
/// @brief returns allocator for a given pool type
/// @param type type of pool (V4, IA, TA or PD)
......@@ -416,6 +417,7 @@ private:
/// responsibility for the reverse DNS Update for this lease
/// (if true).
/// @param hostname A fully qualified domain-name of the client.
/// @param hwaddr Hardware address (optional, may be null for Lease6)
/// @param callout_handle a callout handle (used in hooks). A lease callouts
/// will be executed if this parameter is passed (and there are callouts
/// registered)
......@@ -427,7 +429,7 @@ private:
const uint32_t iaid, const isc::asiolink::IOAddress& addr,
const uint8_t prefix_len, const Lease::Type type,
const bool fwd_dns_update, const bool rev_dns_update,
const std::string& hostname,
const std::string& hostname, const HWAddrPtr& hwaddr,
const isc::hooks::CalloutHandlePtr& callout_handle,
bool fake_allocation = false);
......
......@@ -29,8 +29,10 @@ void
CSVLeaseFile4::append(const Lease4& lease) const {
CSVRow row(getColumnCount());
row.writeAt(getColumnIndex("address"), lease.addr_.toText());
HWAddr hwaddr(lease.hwaddr_, HTYPE_ETHER);
row.writeAt(getColumnIndex("hwaddr"), hwaddr.toText(false));
if (!lease.hwaddr_) {
isc_throw(BadValue, "Lease4 must have hardware address specified.");
}
row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_->toText(false));
// Client id may be unset (NULL).
if (lease.client_id_) {
row.writeAt(getColumnIndex("client_id"), lease.client_id_->toText());
......@@ -74,7 +76,7 @@ CSVLeaseFile4::next(Lease4Ptr& lease) {
// that.
HWAddr hwaddr = readHWAddr(row);
lease.reset(new Lease4(readAddress(row),
&hwaddr.hwaddr_[0], hwaddr.hwaddr_.size(),
HWAddrPtr(new HWAddr(hwaddr)),
client_id_vec.empty() ? NULL : &client_id_vec[0],
client_id_len,
readValid(row),
......
......@@ -12,6 +12,7 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/csv_lease_file6.h>
using namespace isc::asiolink;
......@@ -41,6 +42,10 @@ CSVLeaseFile6::append(const Lease6& lease) const {
row.writeAt(getColumnIndex("fqdn_fwd"), lease.fqdn_fwd_);
row.writeAt(getColumnIndex("fqdn_rev"), lease.fqdn_rev_);
row.writeAt(getColumnIndex("hostname"), lease.hostname_);
if (lease.hwaddr_) {
// We may not have hardware information
row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_);
}
CSVFile::append(row);
}
......@@ -64,6 +69,7 @@ CSVLeaseFile6::next(Lease6Ptr& lease) {
readIAID(row), readPreferred(row),
readValid(row), 0, 0, // t1, t2 = 0
readSubnetID(row),
readHWAddr(row),
readPrefixLen(row)));
lease->cltt_ = readCltt(row);
lease->fqdn_fwd_ = readFqdnFwd(row);
......@@ -94,6 +100,7 @@ CSVLeaseFile6::initColumns() {
addColumn("fqdn_fwd");
addColumn("fqdn_rev");
addColumn("hostname");
addColumn("hwaddr");
}
Lease::Type
......@@ -172,5 +179,35 @@ CSVLeaseFile6::readHostname(const CSVRow& row) {
return (hostname);
}
HWAddrPtr
CSVLeaseFile6::readHWAddr(const CSVRow& row) {
try {
const HWAddr& hwaddr = HWAddr::fromText(row.readAt(getColumnIndex("hwaddr")));
if (hwaddr.hwaddr_.empty()) {
return (HWAddrPtr());
}
/// @todo: HWAddr returns an object, not a pointer. Without HWAddr
/// refactoring, at least one copy is unavoidable.
// Let's return a pointer to new freshly created copy.
return (HWAddrPtr(new HWAddr(hwaddr)));
} catch (const CSVFileError&) {
// That's ok, we may be reading old CSV file that didn't store hwaddr
return (HWAddrPtr());
} catch (const BadValue& ex) {
// That's worse. There was something in the file, but its conversion
// to HWAddr failed. Let's log it on warning and carry on.
LOG_WARN(dhcpsrv_logger, DHCPSRV_MEMFILE_READ_HWADDR_FAIL)
.arg(ex.what());
return (HWAddrPtr());
}
}
} // end of namespace isc::dhcp
} // end of namespace isc
......@@ -160,6 +160,12 @@ private:
///
/// @param row CSV file holding lease values.
std::string readHostname(const util::CSVRow& row);
/// @brief Reads HW address from the CSV file row.
///
/// @param row CSV file holding lease values.
/// @return pointer to the HWAddr structure that was read
HWAddrPtr readHWAddr(const util::CSVRow& row);
//@}
};
......
......@@ -313,6 +313,12 @@ testing but should not be enabled in normal circumstances. Non-persistence
mode is enabled when 'persist4=no persist6=no' parameters are specified
in the database access string.
% DHCPSRV_MEMFILE_READ_HWADDR_FAIL failed to read hardware address from disk: %1
A warning message issued when read attempt of the hardware address stored in
a disk file failed. The parameter should provide the exact nature of the failure.
The database read will continue, but that particular lease will no longer
have hardware address associated with it.
% DHCPSRV_MEMFILE_ROLLBACK rolling back memory file database
The code has issued a rollback call. For the memory file database, this is
a no-op.
......
......@@ -23,10 +23,10 @@ namespace dhcp {
Lease::Lease(const isc::asiolink::IOAddress& addr, uint32_t t1, uint32_t t2,
uint32_t valid_lft, SubnetID subnet_id, time_t cltt,
const bool fqdn_fwd, const bool fqdn_rev,
const std::string& hostname)
const std::string& hostname, const HWAddrPtr& hwaddr)
:addr_(addr), t1_(t1), t2_(t2), valid_lft_(valid_lft), cltt_(cltt),
subnet_id_(subnet_id), fixed_(false), hostname_(hostname),
fqdn_fwd_(fqdn_fwd), fqdn_rev_(fqdn_rev) {
fqdn_fwd_(fqdn_fwd), fqdn_rev_(fqdn_rev), hwaddr_(hwaddr) {
}
std::string
......@@ -66,8 +66,8 @@ Lease::hasIdenticalFqdn(const Lease& other) const {
Lease4::Lease4(const Lease4& other)
: Lease(other.addr_, other.t1_, other.t2_, other.valid_lft_,
other.subnet_id_, other.cltt_, other.fqdn_fwd_,
other.fqdn_rev_, other.hostname_), ext_(other.ext_),
hwaddr_(other.hwaddr_) {
other.fqdn_rev_, other.hostname_, other.hwaddr_),
ext_(other.ext_) {
fixed_ = other.fixed_;
comments_ = other.comments_;
......@@ -91,6 +91,17 @@ Lease4::getClientIdVector() const {
return (client_id_->getClientId());
}
const std::vector<uint8_t>&
Lease4::getRawHWAddr() const {
if (!hwaddr_) {
// something is wrong, very wrong. Hardware address must always
// be present for all IPv4 leases.
isc_throw(BadValue, "Lease4 for address " << addr_.toText()
<< " is missing a hardware address");
}
return (hwaddr_->hwaddr_);
}
bool
Lease4::matches(const Lease4& other) const {
if ((client_id_ && !other.client_id_) ||
......@@ -105,9 +116,13 @@ Lease4::matches(const Lease4& other) const {
return false;
}
// Note that hwaddr_ is now a poiner to the HWAddr structure.
// We can't simply compare smart pointers, we need to compare the
// actual objects they point to. It is ok to not check whether they
// are non-NULL, as every Lease4 must have hardware address.
return (addr_ == other.addr_ &&
ext_ == other.ext_ &&
hwaddr_ == other.hwaddr_);
*hwaddr_ == *other.hwaddr_);
}
......@@ -139,12 +154,13 @@ Lease4::operator=(const Lease4& other) {
Lease6::Lease6(Type type, const isc::asiolink::IOAddress& addr,
DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
uint32_t t1, uint32_t t2, SubnetID subnet_id, uint8_t prefixlen)
: Lease(addr, t1, t2, valid, subnet_id, 0/*cltt*/, false, false, ""),
uint32_t t1, uint32_t t2, SubnetID subnet_id,
const HWAddrPtr& hwaddr, uint8_t prefixlen)
: Lease(addr, t1, t2, valid, subnet_id, 0/*cltt*/, false, false, "", hwaddr),
type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
preferred_lft_(preferred) {
if (!duid) {
isc_throw(InvalidOperation, "DUID must be specified for a lease");
isc_throw(InvalidOperation, "DUID is mandatory for an IPv6 lease");
}
cltt_ = time(NULL);
......@@ -154,22 +170,23 @@ Lease6::Lease6(Type type, const isc::asiolink::IOAddress& addr,
DuidPtr duid, uint32_t iaid, uint32_t preferred, uint32_t valid,
uint32_t t1, uint32_t t2, SubnetID subnet_id,
const bool fqdn_fwd, const bool fqdn_rev,
const std::string& hostname, uint8_t prefixlen)
const std::string& hostname, const HWAddrPtr& hwaddr,
uint8_t prefixlen)
: Lease(addr, t1, t2, valid, subnet_id, 0/*cltt*/,
fqdn_fwd, fqdn_rev, hostname),
fqdn_fwd, fqdn_rev, hostname, hwaddr),
type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid),
preferred_lft_(preferred) {
if (!duid) {
isc_throw(InvalidOperation, "DUID must be specified for a lease");
isc_throw(InvalidOperation, "DUID is mandatory for an IPv6 lease");
}
cltt_ = time(NULL);
}
Lease6::Lease6()
: Lease(isc::asiolink::IOAddress("::"), 0, 0, 0, 0, 0, false, false, ""),
type_(TYPE_NA), prefixlen_(0), iaid_(0), duid_(DuidPtr()),
preferred_lft_(0) {
: Lease(isc::asiolink::IOAddress("::"), 0, 0, 0, 0, 0, false, false, "",
HWAddrPtr()), type_(TYPE_NA), prefixlen_(0), iaid_(0),
duid_(DuidPtr()), preferred_lft_(0) {
}
const std::vector<uint8_t>&
......
......@@ -59,10 +59,12 @@ struct Lease {
/// @param fqdn_fwd If true, forward DNS update is performed for a lease.
/// @param fqdn_rev If true, reverse DNS update is performed for a lease.