Commit 5de74693 authored by Marcin Siodelski's avatar Marcin Siodelski

[3977] Name change requests are now generated when lease is reused.

This change triggered a lot of code refactoring for generating the
NameChangeRequests. Long story short is that the functions responsible
for generating NCRs from the lease information have been moved to
the libdhcpsrv where they better fit and where they may be used
by both allocation engine and the servers.
parent 6c1f7669
......@@ -200,11 +200,6 @@ as declined (i.e. used by unknown entity). The server has information about
a lease for that address, but the client's hardware address or client identifier
does not match the server's stored information. The client's request will be ignored.
% DHCP4_DHCID_COMPUTE_ERROR failed to compute the DHCID for lease: %1, reason: %2
This error message is logged when the attempt to compute DHCID for a specified
lease has failed. The lease details and reason for failure is logged in the
message.
% DHCP4_DISCOVER_CLASS_PROCESSING_FAILED %1: client class specific processing failed for DHCPDISCOVER
This debug message means that the server processing that is unique for each
client class has reported a failure. The response packet will not be sent.
......@@ -528,11 +523,6 @@ A debug message printing the details of the received packet. The first
argument includes the client and the transaction identification
information.
% DHCP4_QUEUE_NCR name change request to %1 DNS entry queued: %2
A debug message which is logged when the NameChangeRequest to add or remove
a DNS entries for a particular lease has been queued. The first parameter of
this log message indicates whether the DNS entry is to be added or removed.
The second parameter carries the details of the NameChangeRequest.
% DHCP4_RELEASE %1: address %2 was released properly.
This debug message indicates that an address was released properly. It
......
......@@ -33,6 +33,7 @@
#include <dhcpsrv/cfg_subnets4.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/ncr_generator.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/subnet_selector.h>
#include <dhcpsrv/utils.h>
......@@ -1136,76 +1137,13 @@ Dhcpv4Srv::createNameChangeRequests(const Lease4Ptr& lease,
if (!lease) {
isc_throw(isc::Unexpected,
"NULL lease specified when creating NameChangeRequest");
}
// If old lease is not NULL, it is an indication that the lease has
// just been renewed. In such case we may need to generate the
// additional NameChangeRequest to remove an existing entry before
// we create a NameChangeRequest to add the entry for an updated lease.
// We may also decide not to generate any requests at all. This is when
// we discover that nothing has changed in the client's FQDN data.
if (old_lease) {
// There will be a NameChangeRequest generated to remove existing
// DNS entries if the following conditions are met:
// - The hostname is set for the existing lease, we can't generate
// removal request for non-existent hostname.
// - A server has performed reverse, forward or both updates.
// - FQDN data between the new and old lease do not match.
if (!lease->hasIdenticalFqdn(*old_lease)) {
queueNameChangeRequest(isc::dhcp_ddns::CHG_REMOVE, old_lease);
// If FQDN data from both leases match, there is no need to update.
} else if (lease->hasIdenticalFqdn(*old_lease)) {
return;
}
}
// We may need to generate the NameChangeRequest for the new lease. It
// will be generated only if hostname is set and if forward or reverse
// update has been requested.
queueNameChangeRequest(isc::dhcp_ddns::CHG_ADD, lease);
}
void
Dhcpv4Srv::
queueNameChangeRequest(const isc::dhcp_ddns::NameChangeType chg_type,
const Lease4Ptr& lease) {
// The hostname must not be empty, and at least one type of update
// should be requested.
if (!lease || lease->hostname_.empty() ||
(!lease->fqdn_rev_ && !lease->fqdn_fwd_)) {
return;
}
// Create the DHCID for the NameChangeRequest.
D2Dhcid dhcid;
try {
dhcid = computeDhcid(lease);
} catch (const DhcidComputeError& ex) {
LOG_ERROR(ddns4_logger, DHCP4_DHCID_COMPUTE_ERROR)
.arg(lease->toText())
.arg(ex.what());
return;
} else if (!old_lease || (old_lease && !lease->hasIdenticalFqdn(*old_lease))) {
// We may need to generate the NameChangeRequest for the new lease. It
// will be generated only if hostname is set and if forward or reverse
// update has been requested.
queueNCR(CHG_ADD, lease);
}
// Create NameChangeRequest
NameChangeRequestPtr ncr(new NameChangeRequest(chg_type, lease->fqdn_fwd_,
lease->fqdn_rev_,
lease->hostname_,
lease->addr_.toText(),
dhcid,
(lease->cltt_ +
lease->valid_lft_),
lease->valid_lft_));
LOG_DEBUG(ddns4_logger, DBG_DHCP4_DETAIL_DATA, DHCP4_QUEUE_NCR)
.arg(chg_type == CHG_ADD ? "add" : "remove")
.arg(ncr->toText());
// And pass it to the the manager.
CfgMgr::instance().getD2ClientMgr().sendRequest(ncr);
}
void
......@@ -1830,10 +1768,9 @@ Dhcpv4Srv::processRelease(Pkt4Ptr& release) {
StatsMgr::generateName("subnet", lease->subnet_id_, "assigned-addresses"),
static_cast<int64_t>(-1));
if (CfgMgr::instance().ddnsEnabled()) {
// Remove existing DNS entries for the lease, if any.
queueNameChangeRequest(isc::dhcp_ddns::CHG_REMOVE, lease);
}
// Remove existing DNS entries for the lease, if any.
queueNCR(CHG_REMOVE, lease);
} else {
// Release failed
LOG_ERROR(lease4_logger, DHCP4_RELEASE_FAIL)
......@@ -1952,13 +1889,9 @@ Dhcpv4Srv::declineLease(const Lease4Ptr& lease, const Pkt4Ptr& decline) {
}
}
// Clean up DDNS, if needed.
if (CfgMgr::instance().ddnsEnabled()) {
// Remove existing DNS entries for the lease, if any.
// queueNameChangeRequest will do the necessary checks and will
// skip the update, if not needed.
queueNameChangeRequest(isc::dhcp_ddns::CHG_REMOVE, lease);
}
// Remove existing DNS entries for the lease, if any.
// queueNCR will do the necessary checks and will skip the update, if not needed.
queueNCR(CHG_REMOVE, lease);
// Bump up the statistics.
......
......@@ -572,20 +572,6 @@ protected:
void createNameChangeRequests(const Lease4Ptr& lease,
const Lease4Ptr& old_lease);
/// @brief Creates the NameChangeRequest and adds to the queue for
/// processing.
///
/// This creates the @c isc::dhcp_ddns::NameChangeRequest; emits a
/// the debug message which indicates whether the request being added is
/// to remove DNS entry or add a new entry; and then sends the request
/// to the D2ClientMgr for transmission to kea-dhcp-ddns.
///
/// @param chg_type A type of the NameChangeRequest (ADD or REMOVE).
/// @param lease A lease for which the NameChangeRequest is created and
/// queued.
void queueNameChangeRequest(const isc::dhcp_ddns::NameChangeType chg_type,
const Lease4Ptr& lease);
/// @brief Attempts to renew received addresses
///
/// Attempts to renew existing lease. This typically includes finding a lease that
......
......@@ -745,58 +745,6 @@ TEST_F(NameDhcpv4SrvTest, createNameChangeRequestsRenewNoChange) {
ASSERT_EQ(0, d2_mgr_.getQueueSize());
}
// Test that no NameChangeRequest is generated when forward and reverse
// DNS update flags are not set in the lease.
TEST_F(NameDhcpv4SrvTest, createNameChangeRequestsNoUpdate) {
Lease4Ptr lease1 = createLease(IOAddress("192.0.2.3"),
"lease1.example.com.",
true, true);
Lease4Ptr lease2 = createLease(IOAddress("192.0.2.3"),
"lease2.example.com.",
false, false);
ASSERT_NO_THROW(srv_->createNameChangeRequests(lease2, lease1));
EXPECT_EQ(1, d2_mgr_.getQueueSize());
verifyNameChangeRequest(isc::dhcp_ddns::CHG_REMOVE, true, true,
"192.0.2.3", "lease1.example.com.",
"0001013A5B311F5B9FB10DDF8E53689B874F25D"
"62CC147C2FF237A64C90E5A597C9B7A",
lease1->cltt_, 100);
lease2->hostname_ = "";
lease2->fqdn_rev_ = true;
lease2->fqdn_fwd_ = true;
ASSERT_NO_THROW(srv_->createNameChangeRequests(lease2, lease1));
EXPECT_EQ(1, d2_mgr_.getQueueSize());
}
// Test that two NameChangeRequests are generated when the lease is being
// renewed and the new lease has updated FQDN data.
TEST_F(NameDhcpv4SrvTest, createNameChangeRequestsRenew) {
Lease4Ptr lease1 = createLease(IOAddress("192.0.2.3"),
"lease1.example.com.",
true, true);
Lease4Ptr lease2 = createLease(IOAddress("192.0.2.3"),
"lease2.example.com.",
true, true);
ASSERT_NO_THROW(srv_->createNameChangeRequests(lease2, lease1));
ASSERT_EQ(2, d2_mgr_.getQueueSize());
verifyNameChangeRequest(isc::dhcp_ddns::CHG_REMOVE, true, true,
"192.0.2.3", "lease1.example.com.",
"0001013A5B311F5B9FB10DDF8E53689B874F25D"
"62CC147C2FF237A64C90E5A597C9B7A",
lease1->cltt_, 100);
verifyNameChangeRequest(isc::dhcp_ddns::CHG_ADD, true, true,
"192.0.2.3", "lease2.example.com.",
"000101F906D2BB752E1B2EECC5FF2BF434C0B2D"
"D6D7F7BD873F4F280165DB8C9DBA7CB",
lease2->cltt_, 100);
}
// Test that the OFFER message generated as a result of the DISCOVER message
// processing will not result in generation of the NameChangeRequests.
TEST_F(NameDhcpv4SrvTest, processDiscover) {
......
......@@ -135,12 +135,6 @@ lease and other information.
This debug message is logged when the new Name Change Request has been created
to perform the DNS Update, which adds new RRs.
% DHCP6_DDNS_CREATE_REMOVE_NAME_CHANGE_REQUEST %1: created name change request: %2
This debug message is logged when the new Name Change Request has been created
to perform the DNS Update, which removes RRs from the DNS. The first argument
includes the client and transaction identification information. The second
argument specifies the details of the generated name change request.
% DHCP6_DDNS_FQDN_GENERATED %1: generated FQDN for the client: %2
This debug message is logged when the server generated FQDN (name)
for the client which message is processed. The names may be
......@@ -179,13 +173,6 @@ sent by a client and started processing it. The first argument includes the
client and transaction identification information. The second argument
includes the received FQDN.
% DHCP6_DDNS_REMOVE_INVALID_HOSTNAME %1: invalid FQDN %2 for the lease: %3 when removing DNS bindings
This error message is issued when a lease being deleted contains an indication
that the DNS Update has been performed for it, but the FQDN held in the lease
database has invalid format and can't be transformed to the canonical on-wire
format. The first argument includes the client and transaction identification
information.
% DHCP6_DDNS_REQUEST_SEND_FAILED failed sending a request to kea-dhcp-ddns, error: %1, ncr: %2
This error message indicates that IPv6 DHCP server failed to send a DDNS
update request to the DHCP-DDNS server. This is most likely a configuration or
......@@ -203,14 +190,6 @@ the lease is acquired for the client.
This debug message is logged when server includes an DHCPv6 Client FQDN Option
in its response to the client.
% DHCP6_DDNS_SKIP_REMOVE_NAME_CHANGE_REQUEST %1: name change request creation skipped for lease: %2
This debug message is logged when the server determines that removal
name change request should not be sent to the DNS, because the DNS
updates are disabled on the DHCP server, or no DNS update has been
performed for the processed lease. The first argument includes the
client and the transaction identification information. The second
argument provides the details of the lease.
% DHCP6_DEACTIVATE_INTERFACE deactivate interface %1
This message is printed when DHCPv6 server disables an interface from being
used to receive DHCPv6 traffic. Sockets on this interface will not be opened
......
......@@ -38,6 +38,7 @@
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/ncr_generator.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/subnet_selector.h>
#include <dhcpsrv/utils.h>
......@@ -1306,64 +1307,6 @@ Dhcpv6Srv::createNameChangeRequests(const Pkt6Ptr& answer) {
}
}
void
Dhcpv6Srv::createRemovalNameChangeRequest(const Pkt6Ptr& query, const Lease6Ptr& lease) {
// Don't create NameChangeRequests if DNS updates are disabled
// or DNS update hasn't been performed.
if (!CfgMgr::instance().ddnsEnabled() || (!lease->fqdn_fwd_ && !lease->fqdn_rev_)) {
LOG_DEBUG(ddns6_logger, DBG_DHCP6_DETAIL_DATA,
DHCP6_DDNS_SKIP_REMOVE_NAME_CHANGE_REQUEST)
.arg(query->getLabel())
.arg(lease->toText());
return;
}
// If hostname is non-empty, try to convert it to wire format so as
// DHCID can be computed from it. This may throw an exception if hostname
// has invalid format or is empty. Again, this should be only possible
// in case of manual intervention in the database. Note that the last
// parameter passed to the writeFqdn function forces conversion of the FQDN
// to lower case. This is required by the RFC4701, section 3.5.
// The DHCID computation is further in this function.
std::vector<uint8_t> hostname_wire;
try {
OptionDataTypeUtil::writeFqdn(lease->hostname_, hostname_wire, true);
} catch (const Exception& ex) {
LOG_ERROR(ddns6_logger, DHCP6_DDNS_REMOVE_INVALID_HOSTNAME)
.arg(query->getLabel())
.arg(lease->hostname_.empty() ? "(empty)" : lease->hostname_)
.arg(lease->addr_.toText());
return;
}
// DUID must have been checked already by the caller of this function.
// Let's be on the safe side and make sure it is non-NULL and throw
// an exception if it is NULL.
if (!lease->duid_) {
isc_throw(isc::Unexpected, "DUID must be set when creating"
<< " NameChangeRequest for DNS records removal for "
<< lease->addr_);
}
isc::dhcp_ddns::D2Dhcid dhcid(*lease->duid_, hostname_wire);
// Create a NameChangeRequest to remove the entry.
NameChangeRequestPtr ncr;
ncr.reset(new NameChangeRequest(isc::dhcp_ddns::CHG_REMOVE,
lease->fqdn_fwd_, lease->fqdn_rev_,
lease->hostname_,
lease->addr_.toText(),
dhcid, 0, lease->valid_lft_));
LOG_DEBUG(ddns6_logger, DBG_DHCP6_DETAIL,
DHCP6_DDNS_CREATE_REMOVE_NAME_CHANGE_REQUEST)
.arg(query->getLabel())
.arg(ncr->toText());
// Post the NCR to the D2ClientMgr.
CfgMgr::instance().getD2ClientMgr().sendRequest(ncr);
}
HWAddrPtr
Dhcpv6Srv::getMAC(const Pkt6Ptr& pkt) {
CfgMACSources mac_sources = CfgMgr::instance().getCurrentCfg()->
......@@ -1504,17 +1447,17 @@ Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
// have to check that the FQDN settings we provided are the same
// that were set. If they aren't, we will have to remove existing
// DNS records and update the lease with the new settings.
conditionalNCRRemoval(query, old_lease, lease, ctx.hostname_,
do_fwd, do_rev);
// conditionalNCRRemoval(query, old_lease, lease, ctx.hostname_,
// do_fwd, do_rev);
}
// We need to repeat that check for leases that used to be used, but
// are no longer valid.
if (!ctx.old_leases_.empty()) {
/* if (!ctx.old_leases_.empty()) {
old_lease = *ctx.old_leases_.begin();
conditionalNCRRemoval(query, old_lease, lease, ctx.hostname_,
do_fwd, do_rev);
}
} */
}
} else {
// Allocation engine did not allocate a lease. The engine logged
......@@ -1547,7 +1490,7 @@ Dhcpv6Srv::conditionalNCRRemoval(const Pkt6Ptr& query, Lease6Ptr& old_lease,
.arg(do_fwd ? "true" : "false");
// Schedule removal of the existing lease.
createRemovalNameChangeRequest(query, old_lease);
queueNCR(CHG_REMOVE, old_lease);
}
}
......@@ -1784,7 +1727,7 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
.arg(do_rev ? "true" : "false")
.arg(do_fwd ? "true" : "false");
createRemovalNameChangeRequest(query, *l);
queueNCR(CHG_REMOVE, *l);
}
}
......@@ -2199,7 +2142,7 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
// Check if a lease has flags indicating that the FQDN update has
// been performed. If so, create NameChangeRequest which removes
// the entries.
createRemovalNameChangeRequest(query, lease);
queueNCR(CHG_REMOVE, lease);
return (ia_rsp);
}
......@@ -2770,7 +2713,7 @@ Dhcpv6Srv::declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease,
// Check if a lease has flags indicating that the FQDN update has
// been performed. If so, create NameChangeRequest which removes
// the entries. This method does all necessary checks.
createRemovalNameChangeRequest(decline, lease);
queueNCR(CHG_REMOVE, lease);
// Bump up the subnet-specific statistic.
StatsMgr::instance().addValue(
......
......@@ -528,9 +528,8 @@ protected:
/// server intents to perform for the DNS client. Based on this, the
/// function will create zero or more @c isc::dhcp_ddns::NameChangeRequest
/// objects and store them in the internal queue. Requests created by this
/// function are only adding or updating DNS records. In order to generate
/// requests for DNS records removal, use @c createRemovalNameChangeRequest.
/// If ddns updates are disabled, this method returns immediately.
/// function are only adding or updating DNS records. If DNS updates are
/// disabled, this method returns immediately.
///
/// @todo Add support for multiple IAADDR options in the IA_NA.
///
......@@ -538,25 +537,6 @@ protected:
/// Client FQDN option, this option is used to create NameChangeRequests.
void createNameChangeRequests(const Pkt6Ptr& answer);
/// @brief Creates a @c isc::dhcp_ddns::NameChangeRequest which requests
/// removal of DNS entries for a particular lease.
///
/// This function should be called upon removal of the lease from the lease
/// database, i.e, when client sent Release or Decline message. It will
/// create a single @c isc::dhcp_ddns::NameChangeRequest which removes the
/// existing DNS records for the lease, which server is responsible for.
/// Note that this function will not remove the entries which server hadn't
/// added. This is the case, when client performs forward DNS update on its
/// own.
/// If ddns updates are disabled, this method returns immediately.
///
/// @param query A pointer to the packet sent by the client for which the
/// name change request should be sent.
/// @param lease A lease for which the the removal of corresponding DNS
/// records will be performed.
void createRemovalNameChangeRequest(const Pkt6Ptr& query,
const Lease6Ptr& lease);
/// @brief Attempts to extend the lifetime of IAs.
///
/// This function is called when a client sends Renew or Rebind message.
......
......@@ -105,7 +105,6 @@ public:
using Dhcpv6Srv::processInfRequest;
using Dhcpv6Srv::processClientFqdn;
using Dhcpv6Srv::createNameChangeRequests;
using Dhcpv6Srv::createRemovalNameChangeRequest;
using Dhcpv6Srv::selectSubnet;
using Dhcpv6Srv::testServerID;
using Dhcpv6Srv::testUnicast;
......
......@@ -24,8 +24,10 @@
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_status_code.h>
#include <dhcp/option_int_array.h>
#include <dhcpsrv/lease.h>
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcpsrv/lease.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/ncr_generator.h>
#include <dhcp6/tests/dhcp6_test_utils.h>
#include <boost/pointer_cast.hpp>
......@@ -485,7 +487,7 @@ public:
const bool reverse, const bool forward,
const std::string& addr,
const std::string& dhcid,
const uint16_t expires,
const uint64_t expires,
const uint16_t len,
const std::string& fqdn="") {
NameChangeRequestPtr ncr;
......@@ -725,15 +727,14 @@ TEST_F(FqdnDhcpv6SrvTest, createRemovalNameChangeRequestFwdRev) {
// as if we typed domain-name in lower case.
lease_->hostname_ = "MYHOST.example.com.";
Pkt6Ptr pkt(new Pkt6(DHCPREQUEST, 1234));
ASSERT_NO_THROW(srv_->createRemovalNameChangeRequest(pkt, lease_));
ASSERT_NO_THROW(queueNCR(CHG_REMOVE, lease_));
ASSERT_EQ(1, d2_mgr_.getQueueSize());
verifyNameChangeRequest(isc::dhcp_ddns::CHG_REMOVE, true, true,
"2001:db8:1::1",
"000201415AA33D1187D148275136FA30300478"
"FAAAA3EBD29826B5C907B2C9268A6F52",
0, 502);
lease_->cltt_ + lease_->valid_lft_, 502);
}
......@@ -751,8 +752,7 @@ TEST_F(FqdnDhcpv6SrvTest, noRemovalsWhenDisabled) {
lease_->hostname_ = "MYHOST.example.com.";
// When DDNS is disabled an attempt to send a request will throw.
Pkt6Ptr pkt(new Pkt6(DHCPREQUEST, 1234));
ASSERT_NO_THROW(srv_->createRemovalNameChangeRequest(pkt, lease_));
ASSERT_NO_THROW(queueNCR(CHG_REMOVE, lease_));
}
......@@ -763,8 +763,7 @@ TEST_F(FqdnDhcpv6SrvTest, createRemovalNameChangeRequestRev) {
lease_->fqdn_rev_ = true;
lease_->hostname_ = "myhost.example.com.";
Pkt6Ptr pkt(new Pkt6(DHCPREQUEST, 1234));
ASSERT_NO_THROW(srv_->createRemovalNameChangeRequest(pkt, lease_));
ASSERT_NO_THROW(queueNCR(CHG_REMOVE, lease_));
ASSERT_EQ(1, d2_mgr_.getQueueSize());
......@@ -772,7 +771,7 @@ TEST_F(FqdnDhcpv6SrvTest, createRemovalNameChangeRequestRev) {
"2001:db8:1::1",
"000201415AA33D1187D148275136FA30300478"
"FAAAA3EBD29826B5C907B2C9268A6F52",
0, 502);
lease_->cltt_ + lease_->valid_lft_, 502);
}
......@@ -782,8 +781,7 @@ TEST_F(FqdnDhcpv6SrvTest, createRemovalNameChangeRequestNoUpdate) {
lease_->fqdn_fwd_ = false;
lease_->fqdn_rev_ = false;
Pkt6Ptr pkt(new Pkt6(DHCPREQUEST, 1234));
ASSERT_NO_THROW(srv_->createRemovalNameChangeRequest(pkt, lease_));
ASSERT_NO_THROW(queueNCR(CHG_REMOVE, lease_));
ASSERT_EQ(0, d2_mgr_.getQueueSize());
......@@ -797,7 +795,7 @@ TEST_F(FqdnDhcpv6SrvTest, createRemovalNameChangeRequestNoHostname) {
lease_->hostname_ = "";
Pkt6Ptr pkt(new Pkt6(DHCPREQUEST, 1234));
ASSERT_NO_THROW(srv_->createRemovalNameChangeRequest(pkt, lease_));
ASSERT_NO_THROW(queueNCR(CHG_REMOVE, lease_));
ASSERT_EQ(0, d2_mgr_.getQueueSize());
......@@ -811,8 +809,7 @@ TEST_F(FqdnDhcpv6SrvTest, createRemovalNameChangeRequestWrongHostname) {
lease_->fqdn_rev_ = true;
lease_->hostname_ = "myhost..example.com.";
Pkt6Ptr pkt(new Pkt6(DHCPREQUEST, 1234));
ASSERT_NO_THROW(srv_->createRemovalNameChangeRequest(pkt, lease_));
ASSERT_NO_THROW(queueNCR(CHG_REMOVE, lease_));
ASSERT_EQ(0, d2_mgr_.getQueueSize());
......@@ -845,7 +842,7 @@ TEST_F(FqdnDhcpv6SrvTest, DISABLED_processTwoRequests) {
"2001:db8:1:1::dead:beef",
"000201415AA33D1187D148275136FA30300478"
"FAAAA3EBD29826B5C907B2C9268A6F52",
0, 4000);
lease_->cltt_ + lease_->valid_lft_, 4000);
// Client may send another request message with a new domain-name. In this
// case the same lease will be returned. The existing DNS entry needs to
......@@ -950,6 +947,12 @@ TEST_F(FqdnDhcpv6SrvTest, processRequestRelease) {
// to add both reverse and forward mapping to DNS.
testProcessMessage(DHCPV6_REQUEST, "myhost.example.com",
"myhost.example.com.");
// The lease should have been recorded in the database.
lease_ = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
IOAddress("2001:db8:1:1::dead:beef"));
ASSERT_TRUE(lease_);
ASSERT_EQ(1, d2_mgr_.getQueueSize());
verifyNameChangeRequest(isc::dhcp_ddns::CHG_ADD, true, true,
"2001:db8:1:1::dead:beef",
......@@ -968,7 +971,7 @@ TEST_F(FqdnDhcpv6SrvTest, processRequestRelease) {
"2001:db8:1:1::dead:beef",
"000201415AA33D1187D148275136FA30300478"
"FAAAA3EBD29826B5C907B2C9268A6F52",
0, 4000);
lease_->cltt_ + lease_->valid_lft_, 4000);
}
......@@ -1028,15 +1031,16 @@ TEST_F(FqdnDhcpv6SrvTest, processRequestReuseExpiredLease) {
"myhost.example.com.");
// Test that the appropriate NameChangeRequest has been generated.
ASSERT_EQ(1, d2_mgr_.getQueueSize());
verifyNameChangeRequest(isc::dhcp_ddns::CHG_ADD, true, true,
"2001:db8:1:1::dead:beef",
"000201415AA33D1187D148275136FA30300478"
"FAAAA3EBD29826B5C907B2C9268A6F52",
0, 4);
// Get the lease acquired and modify it. In particular, expire it.
// Get the lease acquired.
Lease6Ptr lease =
LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA, addr);
ASSERT_TRUE(lease);
verifyNameChangeRequest(isc::dhcp_ddns::CHG_ADD, true, true,
"2001:db8:1:1::dead:beef",
"000201415AA33D1187D148275136FA30300478"
"FAAAA3EBD29826B5C907B2C9268A6F52", 0, 4);
// One of the following: IAID, DUID or subnet identifier has to be changed
// because otherwise the allocation engine will treat the lease as
// being renewed by the same client. If we at least change subnet identifier
......@@ -1066,14 +1070,13 @@ TEST_F(FqdnDhcpv6SrvTest, processRequestReuseExpiredLease) {
"2001:db8:1:1::dead:beef",
"000201D422AA463306223D269B6CB7AFE7AAD2"
"65FCEA97F93623019B2E0D14E5323D5A",
0, 5);
lease->cltt_ + lease->valid_lft_, 5);
// The second name change request should add a DNS mapping for
// a new lease.
verifyNameChangeRequest(isc::dhcp_ddns::CHG_ADD, true, true,
"2001:db8:1:1::dead:beef",
"000201415AA33D1187D148275136FA30300478"
"FAAAA3EBD29826B5C907B2C9268A6F52",
0, 4);
"FAAAA3EBD29826B5C907B2C9268A6F52", 0, 4);
}
......
......@@ -114,6 +114,9 @@ if HAVE_MYSQL
libkea_dhcpsrv_la_SOURCES += mysql_lease_mgr.cc mysql_lease_mgr.h
libkea_dhcpsrv_la_SOURCES += mysql_connection.cc mysql_connection.h
endif
libkea_dhcpsrv_la_SOURCES += ncr_generator.cc ncr_generator.h
if HAVE_PGSQL
libkea_dhcpsrv_la_SOURCES += pgsql_lease_mgr.cc pgsql_lease_mgr.h
endif
......
This diff is collapsed.
......@@ -781,20 +781,76 @@ private:
/// @param lease IPv6 lease to be extended.
void extendLease6(ClientContext6& ctx, Lease6Ptr lease);
/// @brief Sends removal name change reuqest to D2.
/// @brief Reclamation mode used by the variants of @c reclaimExpiredLease
/// methods.
///
/// The following operations are supported:
/// - remove lease upon reclamation,
/// - update lease's state upon reclamation to 'expired-reclaimed',
/// - leave the lease in the database unchanged.
enum DbReclaimMode {
DB_RECLAIM_REMOVE,
DB_RECLAIM_UPDATE,
DB_RECLAIM_LEAVE_UNCHANGED
};
/// @brief Reclaim DHCPv4 or DHCPv6 lease with updating lease database.
///
/// This method is called by the lease reclamation routine to reclaim the
/// lease and update the lease database according to the value of the
/// @c remove_lease parameter.
///
/// This method is exception safe.
/// @param lease Pointer to the DHCPv4 or DHCPv6 lease.
/// @param remove_lease A boolean flag indicating if the lease should be
/// remove from the lease database (if true) upon reclamation.
/// @param callout_handle Pointer to the callout handle.