mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 05:55:28 +00:00
[3982] Changes after review
- Lease6::decline() implemented - DUID::generateEmpty() implemented - Unit-tests for Decline (not include address, not include IA_NA) implemented - several comments updated - logging corrected and reworded
This commit is contained in:
@@ -222,21 +222,22 @@ received in Decline message. It's expected that the option will contain an
|
||||
address that is being declined. Specific information will be printed in a
|
||||
separate message.
|
||||
|
||||
% DHCP6_DECLINE_FAIL_DUID_MISMATCH Client %1 tried to decline address %2, but it belongs to client with DUID %3
|
||||
% DHCP6_DECLINE_FAIL_DUID_MISMATCH Client %1 sent DECLINE for address %2, but it belongs to client with DUID %3
|
||||
This informational message is printed when a client attempts to decline
|
||||
a lease, but that lease belongs to a different client.
|
||||
a lease, but that lease belongs to a different client. The decline request
|
||||
will be rejected.
|
||||
|
||||
% DHCP6_DECLINE_FAIL_IAID_MISMATCH Client %1 tried to decline address %2, but used a wrong IAID (%3), instead of expected %4
|
||||
% DHCP6_DECLINE_FAIL_IAID_MISMATCH Client %1 sent DECLINE for address %2, but used a wrong IAID (%3), instead of expected %4
|
||||
This informational message is printed when a client attempts to decline
|
||||
a lease. The server has a lease for this address, it belongs to this client,
|
||||
but the recorded IAID does not match what client has sent. This means
|
||||
the server will reject this Decline.
|
||||
|
||||
% DHCP6_DECLINE_FAIL_LEASE_WITHOUT_DUID Client %1 attempted to decline address %2, but the associated lease has no DUID
|
||||
% DHCP6_DECLINE_FAIL_LEASE_WITHOUT_DUID Client %1 sent DECLINE for address %2, but the associated lease has no DUID
|
||||
This error condition likely indicates database corruption, as every IPv6
|
||||
lease is supposed to have a DUID, even if it is an empty one.
|
||||
|
||||
% DHCP6_DECLINE_FAIL_NO_LEASE Client %1 attempted to decline address %2, but there's no lease for it
|
||||
% DHCP6_DECLINE_FAIL_NO_LEASE Client %1 sent DECLINE for address %2, but there's no lease for it
|
||||
This informational message is printed when a client tried to decline an address,
|
||||
but the server has no lease for said address. This means that the server's
|
||||
and client's perception of the leases are different. The likely causes
|
||||
@@ -246,7 +247,7 @@ moved to a different location and didn't notice) or possibly an attack
|
||||
inform the client that his decline request was rejected and client should
|
||||
be able to recover from that.
|
||||
|
||||
% DHCP6_DECLINE_LEASE Address %1 was declined by client %2. The lease will be recovered in %3 seconds.
|
||||
% DHCP6_DECLINE_LEASE Client %1 sent DECLINE for address %2 and the server marked it as declined. The lease will be recovered in %3 seconds.
|
||||
This informational message indicates that the client leased an address, but
|
||||
discovered that it is being used by some other devicea and reported this to the
|
||||
server by sending a Decline message. The server marked the lease as
|
||||
|
@@ -2675,7 +2675,7 @@ Dhcpv6Srv::declineIA(const Pkt6Ptr& decline, const DuidPtr& duid,
|
||||
continue;
|
||||
}
|
||||
Option6IAAddrPtr decline_addr = boost::dynamic_pointer_cast<Option6IAAddr>
|
||||
(ia->getOption(D6O_IAADDR));
|
||||
(opt->second);
|
||||
if (!decline_addr) {
|
||||
continue;
|
||||
}
|
||||
@@ -2739,9 +2739,9 @@ Dhcpv6Srv::declineIA(const Pkt6Ptr& decline, const DuidPtr& duid,
|
||||
LOG_INFO(lease6_logger, DHCP6_DECLINE_FAIL_IAID_MISMATCH)
|
||||
.arg(decline->getLabel())
|
||||
.arg(lease->addr_.toText())
|
||||
.arg(lease->iaid_)
|
||||
.arg(ia->getIAID());
|
||||
ia_rsp->addOption(createStatusCode(*decline, *ia_rsp, STATUS_NoBinding,
|
||||
.arg(ia->getIAID())
|
||||
.arg(lease->iaid_);
|
||||
setStatusCode(ia_rsp, createStatusCode(*decline, *ia_rsp, STATUS_NoBinding,
|
||||
"This is your address, but you used wrong IAID"));
|
||||
|
||||
continue;
|
||||
@@ -2753,9 +2753,8 @@ Dhcpv6Srv::declineIA(const Pkt6Ptr& decline, const DuidPtr& duid,
|
||||
|
||||
if (total_addrs == 0) {
|
||||
setStatusCode(ia_rsp, createStatusCode(*decline, *ia_rsp, STATUS_NoBinding,
|
||||
"No addresses sent in IA_NA."));
|
||||
"No addresses sent in IA_NA"));
|
||||
general_status = STATUS_NoBinding;
|
||||
return (ia_rsp);
|
||||
}
|
||||
|
||||
return (ia_rsp);
|
||||
@@ -2779,32 +2778,24 @@ Dhcpv6Srv::declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease,
|
||||
// the entries. This method does all necessary checks.
|
||||
createRemovalNameChangeRequest(decline, lease);
|
||||
|
||||
// Bump up the statistics.
|
||||
std::stringstream name;
|
||||
name << "subnet[" << lease->subnet_id_ << "].declined-addresses";
|
||||
isc::stats::StatsMgr::instance().addValue(name.str(), static_cast<int64_t>(1));
|
||||
// Bump up the subnet-specific statistic.
|
||||
StatsMgr::instance().addValue(
|
||||
StatsMgr::generateName("subnet", lease->subnet_id_, "declined-addresses"),
|
||||
static_cast<int64_t>(1));
|
||||
|
||||
// Global declined addresses counter.
|
||||
StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
|
||||
|
||||
// @todo: Call hooks.
|
||||
|
||||
// We need to disassociate the lease from the client. Once we move a lease
|
||||
// to declined state, it is no longer associated with the client in any
|
||||
// way.
|
||||
vector<uint8_t> empty_duid(1,0);
|
||||
lease->hwaddr_.reset(new HWAddr());
|
||||
lease->duid_.reset(new DUID(empty_duid));
|
||||
lease->t1_ = 0;
|
||||
lease->t2_ = 0;
|
||||
lease->valid_lft_ = CfgMgr::instance().getCurrentCfg()->getDeclinePeriod();
|
||||
lease->cltt_ = time(NULL);
|
||||
lease->hostname_ = string("");
|
||||
lease->fqdn_fwd_ = false;
|
||||
lease->fqdn_rev_ = false;
|
||||
|
||||
lease->state_ = Lease::STATE_DECLINED;
|
||||
lease->decline(CfgMgr::instance().getCurrentCfg()->getDeclinePeriod());
|
||||
LeaseMgrFactory::instance().updateLease6(lease);
|
||||
|
||||
LOG_INFO(dhcp6_logger, DHCP6_DECLINE_LEASE).arg(lease->addr_.toText())
|
||||
.arg(decline->getLabel()).arg(lease->valid_lft_);
|
||||
LOG_INFO(dhcp6_logger, DHCP6_DECLINE_LEASE).arg(decline->getLabel())
|
||||
.arg(lease->addr_.toText()).arg(lease->valid_lft_);
|
||||
|
||||
ia_rsp->addOption(createStatusCode(*decline, *ia_rsp, STATUS_Success,
|
||||
"Lease declined. Hopefully the next one will be better."));
|
||||
|
@@ -263,7 +263,15 @@ protected:
|
||||
/// @return Reply message to be sent to the client.
|
||||
Pkt6Ptr processRelease(const Pkt6Ptr& release);
|
||||
|
||||
/// @brief Stub function that will handle incoming Decline.
|
||||
/// @brief Process incoming Decline message.
|
||||
///
|
||||
/// This method processes Decline message. It conducts standard sanity
|
||||
/// checks, creates empty reply and copies the necessary options from
|
||||
/// the client's message. Finally, it calls @ref declineLeases, where
|
||||
/// the actual address processing takes place.
|
||||
///
|
||||
/// @throw RFCViolation if Decline message is invalid (lacking mandatory
|
||||
/// options)
|
||||
///
|
||||
/// @param decline message received from client
|
||||
Pkt6Ptr processDecline(const Pkt6Ptr& decline);
|
||||
@@ -705,10 +713,10 @@ protected:
|
||||
declineLeases(const Pkt6Ptr& decline, Pkt6Ptr& reply,
|
||||
AllocEngine::ClientContext6& ctx);
|
||||
|
||||
/// @brief Declines leases in a single IA_NA container
|
||||
/// @brief Declines leases in a single IA_NA option
|
||||
///
|
||||
/// This method iterates over all addresses in this IA_NA, and verifies
|
||||
/// whether it belongs to the client and calls @ref declineLease. If there's
|
||||
/// This method iterates over all addresses in this IA_NA, verifies
|
||||
/// whether they belong to the client and calls @ref declineLease. If there's
|
||||
/// an error, general_status (a status put in the top level scope), will be
|
||||
/// updated.
|
||||
///
|
||||
@@ -716,6 +724,7 @@ protected:
|
||||
/// @param duid client's duid (used to verify if the client owns the lease)
|
||||
/// @param general_status [out] status in top-level message (may be updated)
|
||||
/// @param ia specific IA_NA option to process.
|
||||
/// @return IA_NA option with response (to be included in Reply message)
|
||||
OptionPtr
|
||||
declineIA(const Pkt6Ptr& decline, const DuidPtr& duid, int& general_status,
|
||||
boost::shared_ptr<Option6IA> ia);
|
||||
@@ -724,7 +733,8 @@ protected:
|
||||
///
|
||||
/// This method performs the actual decline and all necessary operations:
|
||||
/// - cleans up DNS, if necessary
|
||||
/// - updates subnet[X].declined-addresses
|
||||
/// - updates subnet[X].declined-addresses (per subnet stat)
|
||||
/// - updates declined-addresses (global stat)
|
||||
/// - deassociates client information from the lease
|
||||
/// - moves the lease to DECLINED state
|
||||
/// - sets lease expiration time to decline-probation-period
|
||||
|
@@ -56,17 +56,19 @@ const char* DECLINE_CONFIGS[] = {
|
||||
class DeclineTest : public Dhcpv6MessageTest {
|
||||
public:
|
||||
|
||||
/// @brief Specifies expected outcome
|
||||
enum ExpectedResult {
|
||||
SHOULD_PASS, // pass = accept decline, move lease to declined state.
|
||||
SHOULD_FAIL // fail = reject the decline
|
||||
};
|
||||
|
||||
/// @brief Performs 4-way exchange to obtain new lease.
|
||||
///
|
||||
/// This is used as a preparatory step for Decline operation.
|
||||
///
|
||||
/// @param client Client to be used to obtain a lease.
|
||||
void acquireLease(Dhcp6Client& client);
|
||||
/// @brief Specifies what address should the client include in its Decline
|
||||
enum AddressInclusion {
|
||||
VALID_ADDR, // Client will include its own, valid address
|
||||
BOGUS_ADDR, // Client will include an address it doesn't own
|
||||
NO_ADDR, // Client will send empty IA_NA (without address)
|
||||
NO_IA // Client will not send IA_NA at all
|
||||
};
|
||||
|
||||
/// @brief Tests if the acquired lease is or is not declined.
|
||||
///
|
||||
@@ -74,9 +76,8 @@ public:
|
||||
/// @param iaid1 IAID used during lease acquisition
|
||||
/// @param duid2 DUID used during Decline exchange
|
||||
/// @param iaid2 IAID used during Decline exchange
|
||||
/// @param declient_correct_address specify if the valid address should
|
||||
/// be used (true = use the address client actually received,
|
||||
/// false = use a different address)
|
||||
/// @param addr_type specify what sort of address the client should
|
||||
/// include (its own, a bogus one or no address at all)
|
||||
/// @param expected_result SHOULD_PASS if the lease is expected to
|
||||
/// be successfully declined, or SHOULD_FAIL if the lease is expected
|
||||
/// to not be declined.
|
||||
@@ -84,9 +85,9 @@ public:
|
||||
const uint32_t iaid1,
|
||||
const std::string& duid2,
|
||||
const uint32_t iaid2,
|
||||
bool decline_correct_address,
|
||||
AddressInclusion addr_type,
|
||||
ExpectedResult expected_result);
|
||||
|
||||
|
||||
/// @brief Constructor.
|
||||
///
|
||||
/// Sets up fake interfaces.
|
||||
@@ -104,8 +105,11 @@ DeclineTest::acquireAndDecline(const std::string& duid1,
|
||||
const uint32_t iaid1,
|
||||
const std::string& duid2,
|
||||
const uint32_t iaid2,
|
||||
bool decline_correct_address,
|
||||
AddressInclusion addr_type,
|
||||
ExpectedResult expected_result) {
|
||||
// Set this global statistic explicitly to zero.
|
||||
StatsMgr::instance().setValue("declined-addresses", static_cast<int64_t>(0));
|
||||
|
||||
Dhcp6Client client;
|
||||
client.setDUID(duid1);
|
||||
client.useNA(iaid1);
|
||||
@@ -117,11 +121,13 @@ DeclineTest::acquireAndDecline(const std::string& duid1,
|
||||
const Subnet6Collection* subnets =
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
|
||||
ASSERT_EQ(1, subnets->size());
|
||||
std::stringstream name;
|
||||
name << "subnet[" << subnets->at(0)->getID() << "].declined-addresses";
|
||||
|
||||
// Let's generate the subnet specific statistic
|
||||
std::string name = StatsMgr::generateName("subnet", subnets->at(0)->getID(),
|
||||
"declined-addresses");
|
||||
|
||||
// Set this statistic explicitly to zero.
|
||||
isc::stats::StatsMgr::instance().setValue(name.str(), static_cast<int64_t>(0));
|
||||
StatsMgr::instance().setValue(name, static_cast<int64_t>(0));
|
||||
|
||||
// Perform 4-way exchange.
|
||||
ASSERT_NO_THROW(client.doSARR());
|
||||
@@ -134,17 +140,34 @@ DeclineTest::acquireAndDecline(const std::string& duid1,
|
||||
// Remember the acquired address.
|
||||
IOAddress acquired_address = leases_client_na[0].addr_;
|
||||
|
||||
// Check the declined-addresses statistic before the Decline operation.
|
||||
ObservationPtr declined_cnt = StatsMgr::instance().getObservation(name.str());
|
||||
// Check the declined-addresses (subnet) before the Decline operation.
|
||||
ObservationPtr declined_cnt = StatsMgr::instance().getObservation(name);
|
||||
ASSERT_TRUE(declined_cnt);
|
||||
uint64_t before = declined_cnt->getInteger().first;
|
||||
|
||||
// Let's tamper with the address if necessary.
|
||||
if (!decline_correct_address) {
|
||||
|
||||
// Check the global declined-addresses statistic before the Decline.
|
||||
ObservationPtr declined_global = StatsMgr::instance()
|
||||
.getObservation("declined-addresses");
|
||||
ASSERT_TRUE(declined_global);
|
||||
uint64_t before_global = declined_cnt->getInteger().first;
|
||||
|
||||
// Let's tamper with the address if necessary.
|
||||
switch (addr_type) {
|
||||
case VALID_ADDR:
|
||||
// Nothing to do, client will do its job correctly by default
|
||||
break;
|
||||
case BOGUS_ADDR:
|
||||
// Simple increase by one.
|
||||
client.config_.leases_[0].addr_ =
|
||||
IOAddress::increase(client.config_.leases_[0].addr_);
|
||||
break;
|
||||
case NO_ADDR:
|
||||
// Tell the client to not include an address in its IA_NA
|
||||
client.includeAddress(false);
|
||||
break;
|
||||
case NO_IA:
|
||||
// Tell the client to not include IA_NA at all
|
||||
client.useNA(false);
|
||||
}
|
||||
|
||||
// Use the second duid
|
||||
@@ -160,11 +183,15 @@ DeclineTest::acquireAndDecline(const std::string& duid1,
|
||||
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
|
||||
acquired_address);
|
||||
ASSERT_TRUE(lease);
|
||||
|
||||
declined_cnt = StatsMgr::instance().getObservation(name.str());
|
||||
|
||||
declined_cnt = StatsMgr::instance().getObservation(name);
|
||||
ASSERT_TRUE(declined_cnt);
|
||||
uint64_t after = declined_cnt->getInteger().first;
|
||||
|
||||
declined_global = StatsMgr::instance().getObservation("declined-addresses");
|
||||
ASSERT_TRUE(declined_global);
|
||||
uint64_t after_global = declined_global->getInteger().first;
|
||||
|
||||
// We check if the decline process was successful by checking if the
|
||||
// lease is in the database and what is its state.
|
||||
if (expected_result == SHOULD_PASS) {
|
||||
@@ -173,6 +200,7 @@ DeclineTest::acquireAndDecline(const std::string& duid1,
|
||||
// The decline succeded, so the declined-addresses statistic should
|
||||
// be increased by one
|
||||
EXPECT_EQ(after, before + 1);
|
||||
EXPECT_EQ(after_global, before_global + 1);
|
||||
} else {
|
||||
// the decline was supposed, to be rejected.
|
||||
EXPECT_EQ(Lease::STATE_DEFAULT, lease->state_);
|
||||
@@ -180,6 +208,7 @@ DeclineTest::acquireAndDecline(const std::string& duid1,
|
||||
// The decline failed, so the declined-addresses should be the same
|
||||
// as before
|
||||
EXPECT_EQ(before, after);
|
||||
EXPECT_EQ(before_global, after_global);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,37 +216,59 @@ DeclineTest::acquireAndDecline(const std::string& duid1,
|
||||
TEST_F(DeclineTest, basic) {
|
||||
acquireAndDecline("01:02:03:04:05:06", 1234,
|
||||
"01:02:03:04:05:06", 1234,
|
||||
true, SHOULD_PASS);
|
||||
VALID_ADDR, SHOULD_PASS);
|
||||
}
|
||||
|
||||
// This test verifies the decline is rejected in the following case:
|
||||
// - Client acquires new lease using duid, iaid
|
||||
// - Client sends the DHCPDECLINE with duid, iaid, but uses wrong address.
|
||||
// - Client sends the DECLINE with duid, iaid, but uses wrong address.
|
||||
// - The server rejects Decline due to address mismatch
|
||||
TEST_F(DeclineTest, addressMismatch) {
|
||||
acquireAndDecline("01:02:03:04:05:06", 1234,
|
||||
"01:02:03:04:05:06", 1234,
|
||||
false, SHOULD_FAIL);
|
||||
BOGUS_ADDR, SHOULD_FAIL);
|
||||
}
|
||||
|
||||
// This test verifies the decline is rejected in the following case:
|
||||
// - Client acquires new lease using duid, iaid1
|
||||
// - Client sends the DHCPDECLINE with duid, iaid2
|
||||
// - Client sends the DECLINE with duid, iaid2
|
||||
// - The server rejects Decline due to IAID mismatch
|
||||
TEST_F(DeclineTest, iaidMismatch) {
|
||||
acquireAndDecline("01:02:03:04:05:06", 1234,
|
||||
"01:02:03:04:05:06", 1235,
|
||||
true, SHOULD_FAIL);
|
||||
VALID_ADDR, SHOULD_FAIL);
|
||||
}
|
||||
|
||||
// This test verifies the decline correctness in the following case:
|
||||
// - Client acquires new lease using duid1, iaid
|
||||
// - Client sends the DHCPDECLINE using duid2, iaid
|
||||
// - Client sends the DECLINE using duid2, iaid
|
||||
// - The server rejects the Decline due to DUID mismatch
|
||||
TEST_F(DeclineTest, duidMismatch) {
|
||||
acquireAndDecline("01:02:03:04:05:06", 1234,
|
||||
"01:02:03:04:05:07", 1234,
|
||||
true, SHOULD_FAIL);
|
||||
VALID_ADDR, SHOULD_FAIL);
|
||||
}
|
||||
|
||||
// This test verifies the decline correctness in the following case:
|
||||
// - Client acquires new lease using duid1, iaid
|
||||
// - Client sends the DECLINE using valid duid/iaid, but does not
|
||||
// include the address in it
|
||||
// - The server rejects the Decline due to missing address
|
||||
TEST_F(DeclineTest, noAddrsSent) {
|
||||
acquireAndDecline("01:02:03:04:05:06", 1234,
|
||||
"01:02:03:04:05:06", 1234,
|
||||
NO_ADDR, SHOULD_FAIL);
|
||||
}
|
||||
|
||||
// This test verifies the decline correctness in the following case:
|
||||
// - Client acquires new lease using duid1, iaid
|
||||
// - Client sends the DECLINE using valid duid, but does not
|
||||
// include IA_NA at all
|
||||
// - The server rejects the Decline due to missing IA_NA
|
||||
TEST_F(DeclineTest, noIAs) {
|
||||
acquireAndDecline("01:02:03:04:05:06", 1234,
|
||||
"01:02:03:04:05:06", 1234,
|
||||
NO_IA, SHOULD_FAIL);
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
@@ -96,7 +96,8 @@ Dhcp6Client::Dhcp6Client() :
|
||||
prefix_hint_(),
|
||||
fqdn_(),
|
||||
na_iaid_(1234),
|
||||
pd_iaid_(5678) {
|
||||
pd_iaid_(5678),
|
||||
include_address_(true) {
|
||||
}
|
||||
|
||||
Dhcp6Client::Dhcp6Client(boost::shared_ptr<NakedDhcpv6Srv>& srv) :
|
||||
@@ -117,7 +118,8 @@ Dhcp6Client::Dhcp6Client(boost::shared_ptr<NakedDhcpv6Srv>& srv) :
|
||||
prefix_hint_(),
|
||||
fqdn_(),
|
||||
na_iaid_(1234),
|
||||
pd_iaid_(5678) {
|
||||
pd_iaid_(5678),
|
||||
include_address_(true) {
|
||||
}
|
||||
|
||||
void
|
||||
@@ -554,6 +556,11 @@ void
|
||||
Dhcp6Client::generateIAFromLeases(const Pkt6Ptr& query) {
|
||||
/// @todo: add support for IAPREFIX here.
|
||||
|
||||
if (!use_na_) {
|
||||
// If we're told to not use IA_NA at all, there's nothing to be done here
|
||||
return;
|
||||
}
|
||||
|
||||
for (std::vector<Lease6>::const_iterator lease = config_.leases_.begin();
|
||||
lease != config_.leases_.end(); ++lease) {
|
||||
if (lease->type_ != Lease::TYPE_NA) {
|
||||
@@ -562,8 +569,10 @@ Dhcp6Client::generateIAFromLeases(const Pkt6Ptr& query) {
|
||||
|
||||
Option6IAPtr ia(new Option6IA(D6O_IA_NA, lease->iaid_));
|
||||
|
||||
ia->addOption(Option6IAAddrPtr(new Option6IAAddr(D6O_IAADDR,
|
||||
lease->addr_, lease->preferred_lft_, lease->valid_lft_)));
|
||||
if (include_address_) {
|
||||
ia->addOption(OptionPtr(new Option6IAAddr(D6O_IAADDR,
|
||||
lease->addr_, lease->preferred_lft_, lease->valid_lft_)));
|
||||
}
|
||||
query->addOption(ia);
|
||||
}
|
||||
}
|
||||
|
@@ -500,6 +500,14 @@ public:
|
||||
use_client_id_ = send;
|
||||
}
|
||||
|
||||
/// @brief Controls whether the client should send an addres in IA_NA
|
||||
///
|
||||
/// @todo: For now, this flag is only used in Decline
|
||||
/// @param send should the address be included?
|
||||
void includeAddress(const bool send) {
|
||||
include_address_ = send;
|
||||
}
|
||||
|
||||
/// @brief Specifies if the Rapid Commit option should be included in
|
||||
/// the Solicit message.
|
||||
///
|
||||
@@ -751,6 +759,12 @@ private:
|
||||
uint32_t na_iaid_;
|
||||
/// @brief IAID used by the client when requesting prefix delegation.
|
||||
uint32_t pd_iaid_;
|
||||
|
||||
/// @brief Determines if the client will include address in the messages
|
||||
/// it sends.
|
||||
///
|
||||
/// @todo this flag is currently supported in Decline only.
|
||||
bool include_address_;
|
||||
};
|
||||
|
||||
} // end of namespace isc::dhcp::test
|
||||
|
@@ -123,6 +123,18 @@ DUID::fromText(const std::string& text) {
|
||||
return DUID(binary);
|
||||
}
|
||||
|
||||
DuidPtr
|
||||
DUID::generateEmpty() {
|
||||
|
||||
// Technically this is a one byte DUID with value of 0. However, we do have
|
||||
// a number of safety checks against invalid duids (too long or empty) and
|
||||
// we should keep them. Therefore "empty" means a single byte with value of 0.
|
||||
std::vector<uint8_t> empty_duid(1,0);
|
||||
|
||||
DuidPtr duid(new DUID(empty_duid));
|
||||
return (duid);
|
||||
}
|
||||
|
||||
std::string DUID::toText() const {
|
||||
std::stringstream tmp;
|
||||
tmp << std::hex;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -25,6 +25,10 @@
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
/// @brief Shared pointer to a DUID
|
||||
class DUID;
|
||||
typedef boost::shared_ptr<DUID> DuidPtr;
|
||||
|
||||
/// @brief Holds DUID (DHCPv6 Unique Identifier)
|
||||
///
|
||||
/// This class holds DUID, that is used in client-id, server-id and
|
||||
@@ -66,6 +70,18 @@ class DUID {
|
||||
/// @return A reference to a vector holding a DUID.
|
||||
const std::vector<uint8_t>& getDuid() const;
|
||||
|
||||
|
||||
/// @brief Returns an instance of empty DUID
|
||||
///
|
||||
/// In general, empty DUID is not allowed. The only case where it is really
|
||||
/// valid is to designate declined IPv6 Leases. We have a broad assumption
|
||||
/// that the Lease->duid_ must always be set. However, declined lease
|
||||
/// doesn't have any DUID associated with it. Hence we need a way to
|
||||
/// indicate that fact.
|
||||
///
|
||||
/// @return a smart pointer to an empty DUID
|
||||
static DuidPtr generateEmpty();
|
||||
|
||||
/// @brief Returns the DUID type
|
||||
DUIDType getType() const;
|
||||
|
||||
@@ -111,9 +127,6 @@ class DUID {
|
||||
std::vector<uint8_t> duid_;
|
||||
};
|
||||
|
||||
/// @brief Shared pointer to a DUID
|
||||
typedef boost::shared_ptr<DUID> DuidPtr;
|
||||
|
||||
/// @brief Forward declaration to the @c ClientId class.
|
||||
class ClientId;
|
||||
/// @brief Shared pointer to a Client ID.
|
||||
|
@@ -165,6 +165,19 @@ TEST(DuidTest, toText) {
|
||||
EXPECT_EQ("00:01:02:03:04:ff:fe", duid.toText());
|
||||
}
|
||||
|
||||
// This test verifies that empty DUID returns proper value
|
||||
TEST(DuidTest, empty) {
|
||||
DuidPtr empty;
|
||||
EXPECT_NO_THROW(empty = DUID::generateEmpty());
|
||||
|
||||
// This method must return something
|
||||
ASSERT_TRUE(empty);
|
||||
|
||||
// Ok, technically empty is not really empty, it's just a single
|
||||
// byte with value of 0.
|
||||
EXPECT_EQ("00", empty->toText());
|
||||
}
|
||||
|
||||
// This test checks if the comparison operators are sane.
|
||||
TEST(DuidTest, operators) {
|
||||
uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6};
|
||||
|
@@ -261,6 +261,21 @@ Lease6::getDuidVector() const {
|
||||
return (duid_->getDuid());
|
||||
}
|
||||
|
||||
void
|
||||
Lease6::decline(uint32_t probation_period) {
|
||||
hwaddr_.reset();
|
||||
duid_ = DUID::generateEmpty();
|
||||
t1_ = 0;
|
||||
t2_ = 0;
|
||||
preferred_lft_ = 0;
|
||||
valid_lft_ = probation_period;
|
||||
cltt_ = time(NULL);
|
||||
hostname_ = string("");
|
||||
fqdn_fwd_ = false;
|
||||
fqdn_rev_ = false;
|
||||
state_ = Lease::STATE_DECLINED;
|
||||
}
|
||||
|
||||
std::string
|
||||
Lease6::toText() const {
|
||||
ostringstream stream;
|
||||
|
@@ -495,6 +495,13 @@ struct Lease6 : public Lease {
|
||||
/// @return A reference to a vector holding a DUID.
|
||||
const std::vector<uint8_t>& getDuidVector() const;
|
||||
|
||||
/// @brief Sets IPv6 lease to declined state.
|
||||
///
|
||||
/// See @ref Lease::decline for detailed description.
|
||||
///
|
||||
/// @param probation_period valid lifetime will be set to this value
|
||||
void decline(uint32_t probation_period);
|
||||
|
||||
/// @brief Compare two leases for equality
|
||||
///
|
||||
/// @param other lease6 object with which to compare
|
||||
|
@@ -415,7 +415,7 @@ TEST_F(Lease4Test, toText) {
|
||||
const time_t current_time = 12345678;
|
||||
Lease4 lease(IOAddress("192.0.2.3"), hwaddr_, clientid_, 3600, 123,
|
||||
456, current_time, 789);
|
||||
|
||||
|
||||
std::stringstream expected;
|
||||
expected << "Address: 192.0.2.3\n"
|
||||
<< "Valid life: 3600\n"
|
||||
@@ -741,6 +741,42 @@ TEST(Lease6Test, getDuidVector) {
|
||||
EXPECT_TRUE(returned_vec == duid_vec);
|
||||
}
|
||||
|
||||
// This test verifies if the IPv6 lease can be declined properly.
|
||||
TEST(Lease6Test, decline) {
|
||||
|
||||
uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
|
||||
DuidPtr duid(new DUID(llt, sizeof(llt)));
|
||||
|
||||
HWAddrPtr hwaddr(new HWAddr(HWADDR, sizeof(HWADDR), HTYPE_ETHER));
|
||||
|
||||
// Let's create a lease for 2001:db8::1, DUID, iaid=1234,
|
||||
// t1=1000, t2=2000, pref=3000, valid=4000, subnet-id = 1
|
||||
Lease6 lease(Lease::TYPE_NA, IOAddress("2001:db8::1"), duid,
|
||||
1234, 3000, 4000, 1000, 2000, 1, hwaddr);
|
||||
lease.cltt_ = 12345678;
|
||||
lease.hostname_ = "foo.example.org";
|
||||
lease.fqdn_fwd_ = true;
|
||||
lease.fqdn_rev_ = true;
|
||||
|
||||
time_t now = time(NULL);
|
||||
|
||||
// Move the lease to declined state and set probation-period to 123 seconds
|
||||
lease.decline(123);
|
||||
|
||||
ASSERT_FALSE(lease.hwaddr_);
|
||||
EXPECT_EQ(0, lease.t1_);
|
||||
EXPECT_EQ(0, lease.t2_);
|
||||
EXPECT_EQ(0, lease.preferred_lft_);
|
||||
|
||||
EXPECT_TRUE(now <= lease.cltt_);
|
||||
EXPECT_TRUE(lease.cltt_ <= now + 1);
|
||||
EXPECT_EQ("", lease.hostname_);
|
||||
EXPECT_FALSE(lease.fqdn_fwd_);
|
||||
EXPECT_FALSE(lease.fqdn_rev_);
|
||||
EXPECT_EQ(Lease::STATE_DECLINED, lease.state_);
|
||||
EXPECT_EQ(123, lease.valid_lft_);
|
||||
}
|
||||
|
||||
// Verify the behavior of the function which checks FQDN data for equality.
|
||||
TEST(Lease6Test, hasIdenticalFqdn) {
|
||||
Lease6 lease = createLease6("myhost.example.com.", true, true);
|
||||
@@ -765,12 +801,12 @@ TEST(Lease6Test, toText) {
|
||||
|
||||
uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
|
||||
DuidPtr duid(new DUID(llt, sizeof(llt)));
|
||||
|
||||
|
||||
Lease6 lease(Lease::TYPE_NA, IOAddress("2001:db8::1"), duid, 123456,
|
||||
400, 800, 100, 200, 5678, hwaddr, 128);
|
||||
lease.cltt_ = 12345678;
|
||||
lease.state_ = Lease::STATE_DECLINED;
|
||||
|
||||
|
||||
std::stringstream expected;
|
||||
expected << "Type: IA_NA(" << static_cast<int>(Lease::TYPE_NA) << ")\n"
|
||||
<< "Address: 2001:db8::1\n"
|
||||
|
Reference in New Issue
Block a user