summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWlodek Wencel <wlodek@isc.org>2019-11-19 13:36:48 +0100
committerTomek Mrugalski <tomasz@isc.org>2019-11-20 07:52:57 +0100
commit9fb8b373e6bf9036f3937a456bd8f15347009b12 (patch)
treec4fee959f5a74fbc8b4d8168c5845cc25f7d5a2b /src
parent[985-relax-timings-in-new-config-backend-pull-unit-tests] Relaxed timings and... (diff)
downloadkea-9fb8b373e6bf9036f3937a456bd8f15347009b12.tar.xz
kea-9fb8b373e6bf9036f3937a456bd8f15347009b12.zip
[#572] perfdhcp counting rejected leases
Diffstat (limited to 'src')
-rw-r--r--src/bin/perfdhcp/stats_mgr.cc2
-rw-r--r--src/bin/perfdhcp/stats_mgr.h31
-rw-r--r--src/bin/perfdhcp/test_control.cc75
-rw-r--r--src/bin/perfdhcp/test_control.h9
-rw-r--r--src/bin/perfdhcp/tests/avalanche_scen_unittest.cc6
-rw-r--r--src/bin/perfdhcp/tests/basic_scen_unittest.cc9
-rw-r--r--src/bin/perfdhcp/tests/test_control_unittest.cc79
7 files changed, 189 insertions, 22 deletions
diff --git a/src/bin/perfdhcp/stats_mgr.cc b/src/bin/perfdhcp/stats_mgr.cc
index 056b9c045f..19109fc40d 100644
--- a/src/bin/perfdhcp/stats_mgr.cc
+++ b/src/bin/perfdhcp/stats_mgr.cc
@@ -54,12 +54,12 @@ ExchangeStats::ExchangeStats(const ExchangeType xchg_type,
ordered_lookups_(0),
sent_packets_num_(0),
rcvd_packets_num_(0),
+ rejected_leases_num_(0),
boot_time_(boot_time)
{
next_sent_ = sent_packets_.begin();
}
-
void
ExchangeStats::updateDelays(const dhcp::PktPtr& sent_packet,
const dhcp::PktPtr& rcvd_packet) {
diff --git a/src/bin/perfdhcp/stats_mgr.h b/src/bin/perfdhcp/stats_mgr.h
index d4cba5787f..efbd75c040 100644
--- a/src/bin/perfdhcp/stats_mgr.h
+++ b/src/bin/perfdhcp/stats_mgr.h
@@ -459,6 +459,13 @@ public:
return(drops);
}
+ /// \brief Return total number of rejected leases.
+ ///
+ /// Method returns total number of rejected leases.
+ ///
+ /// \return number of rejected leases.
+ uint64_t getRejLeasesNum() const { return(rejected_leases_num_); }
+ void updateRejLeases() { ++rejected_leases_num_; }
/// \brief Print main statistics for packet exchange.
///
/// Method prints main statistics for particular exchange.
@@ -482,7 +489,8 @@ public:
<< "received packets: " << getRcvdPacketsNum() << endl
<< "drops: " << drops << endl
<< "drops ratio: " << drops_ratio << " %" << endl
- << "orphans: " << getOrphans() << endl;
+ << "orphans: " << getOrphans() << endl
+ << "rejected leases: " << getRejLeasesNum() << endl;
}
/// \brief Print round trip time packets statistics.
@@ -619,6 +627,8 @@ private:
uint64_t sent_packets_num_; ///< Total number of sent packets.
uint64_t rcvd_packets_num_; ///< Total number of received packets.
+
+ uint64_t rejected_leases_num_; ///< Total number of rejected leases (e.g. NoAddrAvail)
boost::posix_time::ptime boot_time_; ///< Time when test is started.
};
@@ -962,7 +972,21 @@ public:
return(xchg_stats->getCollectedNum());
}
-
+ /// \brief Return total number of rejected leases
+ ///
+ /// Method returns total number of rejected leases for specified
+ /// exchange type.
+ ///
+ /// \param xchg_type exchange type.
+ /// \throw isc::BadValue if invalid exchange type specified.
+ /// \return number of received packets.
+ uint64_t getRejLeasesNum(const ExchangeType xchg_type) const {
+ ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
+ return(xchg_stats->getRejLeasesNum());
+ }
+ void updateRejLeases(const ExchangeType xchg_type) {
+ ExchangeStatsPtr xchg_stats = getExchangeStats(xchg_type);
+ xchg_stats->updateRejLeases(); }
/// \brief Get time period since the start of test.
///
/// Calculate dna return period since the test start. This
@@ -1017,6 +1041,7 @@ public:
std::ostringstream stream_sent;
std::ostringstream stream_rcvd;
std::ostringstream stream_drops;
+ std::ostringstream stream_reject;
std::string sep("");
for (ExchangesMapIterator it = exchanges_.begin();
it != exchanges_.end(); ++it) {
@@ -1027,10 +1052,12 @@ public:
stream_sent << sep << it->second->getSentPacketsNum();
stream_rcvd << sep << it->second->getRcvdPacketsNum();
stream_drops << sep << it->second->getDroppedPacketsNum();
+ stream_reject << sep << it->second->getRejLeasesNum();
}
std::cout << "sent: " << stream_sent.str()
<< "; received: " << stream_rcvd.str()
<< "; drops: " << stream_drops.str()
+ << "; rejected: " << stream_reject.str()
<< std::endl;
}
diff --git a/src/bin/perfdhcp/test_control.cc b/src/bin/perfdhcp/test_control.cc
index 19ed5cbeab..7e0e9330e1 100644
--- a/src/bin/perfdhcp/test_control.cc
+++ b/src/bin/perfdhcp/test_control.cc
@@ -17,6 +17,8 @@
#include <dhcp/iface_mgr.h>
#include <dhcp/dhcp4.h>
#include <dhcp/option6_ia.h>
+#include <dhcp/option6_iaaddr.h>
+#include <dhcp/option6_iaprefix.h>
#include <util/unittests/check_valgrind.h>
#include <boost/date_time/posix_time/posix_time.hpp>
@@ -795,6 +797,41 @@ TestControl::processReceivedPacket4(const Pkt4Ptr& pkt4) {
}
}
+bool
+TestControl::validateIA(const Pkt6Ptr& pkt6) {
+ // check if iaaddr exists - if it does, we can continue sending request
+ // if not we will update statistics about rejected leases
+ // @todo it's checking just one iaaddress option for now it's ok
+ // but when perfdhcp will be extended to create message with multiple IA
+ // this will have to be iterate on:
+ // OptionCollection ias = pkt6->getOptions(D6O_IA_NA);
+ Option6IAPrefixPtr iapref;
+ Option6IAAddrPtr iaaddr;
+ if (pkt6->getOption(D6O_IA_PD)){
+ iapref = boost::dynamic_pointer_cast<
+ Option6IAPrefix>(pkt6->getOption(D6O_IA_PD)->getOption(D6O_IAPREFIX));
+ }
+ if (pkt6->getOption(D6O_IA_NA)){
+ iaaddr = boost::dynamic_pointer_cast<
+ Option6IAAddr>(pkt6->getOption(D6O_IA_NA)->getOption(D6O_IAADDR));
+ }
+ if ((options_.getLeaseType()
+ .includes(CommandOptions::LeaseType::ADDRESS_AND_PREFIX) && iapref && iaaddr)
+ || (options_.getLeaseType()
+ .includes(CommandOptions::LeaseType::PREFIX) && iapref
+ && !options_.getLeaseType()
+ .includes(CommandOptions::LeaseType::ADDRESS_AND_PREFIX))
+ || (options_.getLeaseType()
+ .includes(CommandOptions::LeaseType::ADDRESS) && iaaddr
+ && !options_.getLeaseType()
+ .includes(CommandOptions::LeaseType::ADDRESS_AND_PREFIX))) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
void
TestControl::processReceivedPacket6(const Pkt6Ptr& pkt6) {
uint8_t packet_type = pkt6->getType();
@@ -803,15 +840,17 @@ TestControl::processReceivedPacket6(const Pkt6Ptr& pkt6) {
Pkt6Ptr solicit_pkt6(boost::dynamic_pointer_cast<Pkt6>(pkt));
CommandOptions::ExchangeMode xchg_mode = options_.getExchangeMode();
if ((xchg_mode == CommandOptions::DORA_SARR) && solicit_pkt6) {
- /// @todo check whether received ADVERTISE packet is sane.
- /// We might want to check if STATUS_CODE option is non-zero
- /// and if there is IAADR option in IA_NA.
- if (template_buffers_.size() < 2) {
- sendRequest6(pkt6);
- } else {
- /// @todo add defines for packet type index that can be
- /// used to access template_buffers_.
- sendRequest6(template_buffers_[1], pkt6);
+ if (validateIA(pkt6)) {
+ if (template_buffers_.size() < 2) {
+ sendRequest6(pkt6);
+ } else {
+ /// @todo add defines for packet type index that can be
+ /// used to access template_buffers_.
+ sendRequest6(template_buffers_[1], pkt6);
+ }
+ }
+ else {
+ stats_mgr_.updateRejLeases(ExchangeType::SA);
}
}
} else if (packet_type == DHCPV6_REPLY) {
@@ -825,12 +864,18 @@ TestControl::processReceivedPacket6(const Pkt6Ptr& pkt6) {
// being sent. Note that, Reply messages hold the information about
// leases assigned. We use this information to construct Renew and
// Release messages.
- if (stats_mgr_.hasExchangeStats(ExchangeType::RN) ||
- stats_mgr_.hasExchangeStats(ExchangeType::RL)) {
- // Renew or Release messages are sent, because StatsMgr has the
- // specific exchange type specified. Let's append the Reply
- // message to a storage.
- reply_storage_.append(pkt6);
+ if (validateIA(pkt6)) {
+ // check if there is correct IA to continue with Renew/Release
+ if (stats_mgr_.hasExchangeStats(ExchangeType::RN) ||
+ stats_mgr_.hasExchangeStats(ExchangeType::RL)) {
+ // Renew or Release messages are sent, because StatsMgr has the
+ // specific exchange type specified. Let's append the Reply
+ // message to a storage.
+ reply_storage_.append(pkt6);
+ }
+ }
+ else {
+ stats_mgr_.updateRejLeases(ExchangeType::RR);
}
// The Reply message is not a server's response to the Request message
// sent within the 4-way exchange. It may be a response to the Renew
diff --git a/src/bin/perfdhcp/test_control.h b/src/bin/perfdhcp/test_control.h
index 0f75f72aac..9b05076a18 100644
--- a/src/bin/perfdhcp/test_control.h
+++ b/src/bin/perfdhcp/test_control.h
@@ -536,6 +536,15 @@ protected:
/// \throw isc::Unexpected if unexpected error occurred.
void processReceivedPacket4(const dhcp::Pkt4Ptr& pkt4);
+ /// \brief Process IA in received DHCPv6 packet.
+ ///
+ /// Process IA in received message to check if it contain proper
+ /// address and/or prefix
+ ///
+ /// \param [in] pkt6 object representing DHCPv6 packet received.
+ /// \return true if the message include correct IA, false otherwise.
+ bool validateIA(const dhcp::Pkt6Ptr& pkt6);
+
/// \brief Process received DHCPv6 packet.
///
/// Method performs processing of the received DHCPv6 packet,
diff --git a/src/bin/perfdhcp/tests/avalanche_scen_unittest.cc b/src/bin/perfdhcp/tests/avalanche_scen_unittest.cc
index cce3965b7b..7fcd4e67c6 100644
--- a/src/bin/perfdhcp/tests/avalanche_scen_unittest.cc
+++ b/src/bin/perfdhcp/tests/avalanche_scen_unittest.cc
@@ -14,6 +14,8 @@
#include <dhcp/dhcp4.h>
#include <dhcp/pkt4.h>
#include <dhcp/iface_mgr.h>
+#include <dhcp/option6_iaaddr.h>
+#include <dhcp/option6_iaprefix.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/foreach.hpp>
@@ -114,11 +116,15 @@ public:
// Add IA_NA if requested by the client.
if (opt_.getLeaseType().includes(CommandOptions::LeaseType::ADDRESS)) {
OptionPtr opt_ia_na = Option::factory(Option::V6, D6O_IA_NA);
+ OptionPtr iaaddr(new Option6IAAddr(D6O_IAADDR, isc::asiolink::IOAddress("fe80::abcd"), 300, 500));
+ opt_ia_na->addOption(iaaddr);
pkt->addOption(opt_ia_na);
}
// Add IA_PD if requested by the client.
if (opt_.getLeaseType().includes(CommandOptions::LeaseType::PREFIX)) {
OptionPtr opt_ia_pd = Option::factory(Option::V6, D6O_IA_PD);
+ OptionPtr iapref(new Option6IAPrefix(D6O_IAPREFIX, isc::asiolink::IOAddress("fe80::"), 64, 300, 500));
+ opt_ia_pd->addOption(iapref);
pkt->addOption(opt_ia_pd);
}
OptionPtr opt_serverid(new Option(Option::V6, D6O_SERVERID));
diff --git a/src/bin/perfdhcp/tests/basic_scen_unittest.cc b/src/bin/perfdhcp/tests/basic_scen_unittest.cc
index 24b743c791..a5bde10d7d 100644
--- a/src/bin/perfdhcp/tests/basic_scen_unittest.cc
+++ b/src/bin/perfdhcp/tests/basic_scen_unittest.cc
@@ -14,7 +14,8 @@
#include <dhcp/dhcp4.h>
#include <dhcp/pkt4.h>
#include <dhcp/iface_mgr.h>
-
+#include <dhcp/option6_iaaddr.h>
+#include <dhcp/option6_iaprefix.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/foreach.hpp>
@@ -99,11 +100,17 @@ public:
// Add IA_NA if requested by the client.
if (opt_.getLeaseType().includes(CommandOptions::LeaseType::ADDRESS)) {
OptionPtr opt_ia_na = Option::factory(Option::V6, D6O_IA_NA);
+ OptionPtr iaaddr(new Option6IAAddr(D6O_IAADDR,
+ isc::asiolink::IOAddress("fe80::abcd"), 300, 500));
+ opt_ia_na->addOption(iaaddr);
pkt->addOption(opt_ia_na);
}
// Add IA_PD if requested by the client.
if (opt_.getLeaseType().includes(CommandOptions::LeaseType::PREFIX)) {
OptionPtr opt_ia_pd = Option::factory(Option::V6, D6O_IA_PD);
+ OptionPtr iapref(new Option6IAPrefix(D6O_IAPREFIX,
+ isc::asiolink::IOAddress("fe80::"), 64, 300, 500));
+ opt_ia_pd->addOption(iapref);
pkt->addOption(opt_ia_pd);
}
OptionPtr opt_serverid(new Option(Option::V6, D6O_SERVERID));
diff --git a/src/bin/perfdhcp/tests/test_control_unittest.cc b/src/bin/perfdhcp/tests/test_control_unittest.cc
index aef88599c8..4a31f98b78 100644
--- a/src/bin/perfdhcp/tests/test_control_unittest.cc
+++ b/src/bin/perfdhcp/tests/test_control_unittest.cc
@@ -14,6 +14,8 @@
#include <dhcp/dhcp4.h>
#include <dhcp/pkt4.h>
#include <dhcp/iface_mgr.h>
+#include <dhcp/option6_iaaddr.h>
+#include <dhcp/option6_iaprefix.h>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/foreach.hpp>
@@ -887,7 +889,7 @@ public:
// transaction ids from the range from 11 to 20 (the range of
// 1 to 10 has been used by Solicit-Advertise).
tc.processReceivedPacket6(advertise);
- }
+ }
// Requests have been sent, so now let's simulate responses from the
// server. Generate corresponding Reply messages with the transaction
@@ -924,6 +926,49 @@ public:
}
+ /// \brief Test counting rejected leases in Solicit-Advertise.
+ ///
+ /// This function simulates acquiring 4 leases from the server and
+ /// rejecting allocating of 6 leases
+
+ void testCountRejectedLeasesSolAdv() {
+ // Build a command line.
+ CommandOptions opt;
+ std::ostringstream s;
+ s << "perfdhcp -6 -l fake -r 10 -R 10 -L 10547 -n 10 ::1";
+ processCmdLine(opt, s.str());
+ // Create a test controller class.
+ NakedTestControl tc(opt);
+ // Set the transaction id generator to sequential to control to
+ // guarantee that transaction ids are predictable.
+ boost::shared_ptr<NakedTestControl::IncrementalGenerator>
+ generator(new NakedTestControl::IncrementalGenerator());
+ tc.setTransidGenerator(generator);
+
+ // Send a number of Solicit messages. Each generated Solicit will be
+ // assigned a different transaction id, starting from 1 to 10.
+ tc.sendPackets(10);
+
+ // Simulate Advertise responses from the server. Each advertise is
+ // assigned a transaction id from the range of 1 to 6 with incorrect IA
+ // included in the message
+ for (unsigned i = generator->getNext() - 10; i < 7; ++i) {
+ Pkt6Ptr advertise(createAdvertisePkt6(tc, i, false));
+ tc.processReceivedPacket6(advertise);
+ }
+ // counter of rejected leases has to be 6
+ EXPECT_EQ(tc.stats_mgr_.getRejLeasesNum(ExchangeType::SA), 6);
+ // Simulate Advertise responses from the server. Each advertise is
+ // assigned a transaction id from the range of 7 to 10 with correct IA
+ // included in the message
+ for (unsigned i = generator->getNext() - 7; i < 11; ++i) {
+ Pkt6Ptr advertise(createAdvertisePkt6(tc, i));
+ tc.processReceivedPacket6(advertise);
+ }
+ // counter of rejected leases can't change at this point
+ EXPECT_EQ(tc.stats_mgr_.getRejLeasesNum(ExchangeType::SA), 6);
+ }
+
/// \brief Parse command line string with CommandOptions.
///
/// \param cmdline command line string to be parsed.
@@ -975,16 +1020,27 @@ public:
/// \param transid transaction id.
/// \return instance of the packet.
Pkt6Ptr
- createAdvertisePkt6(NakedTestControl &tc, const uint32_t transid) const {
+ createAdvertisePkt6(NakedTestControl &tc, const uint32_t transid,
+ const bool validIA = true) const {
boost::shared_ptr<Pkt6> advertise(new Pkt6(DHCPV6_ADVERTISE, transid));
// Add IA_NA if requested by the client.
if (tc.options_.getLeaseType().includes(CommandOptions::LeaseType::ADDRESS)) {
OptionPtr opt_ia_na = Option::factory(Option::V6, D6O_IA_NA);
+ if (validIA) {
+ OptionPtr iaaddr(new Option6IAAddr(D6O_IAADDR,
+ isc::asiolink::IOAddress("fe80::abcd"), 300, 500));
+ opt_ia_na->addOption(iaaddr);
+ }
advertise->addOption(opt_ia_na);
}
// Add IA_PD if requested by the client.
if (tc.options_.getLeaseType().includes(CommandOptions::LeaseType::PREFIX)) {
OptionPtr opt_ia_pd = Option::factory(Option::V6, D6O_IA_PD);
+ if (validIA) {
+ OptionPtr iapref(new Option6IAPrefix(D6O_IAPREFIX,
+ isc::asiolink::IOAddress("fe80::"), 64, 300, 500));
+ opt_ia_pd->addOption(iapref);
+ }
advertise->addOption(opt_ia_pd);
}
OptionPtr opt_serverid(new Option(Option::V6, D6O_SERVERID));
@@ -998,16 +1054,27 @@ public:
}
Pkt6Ptr
- createReplyPkt6(NakedTestControl &tc, const uint32_t transid) const {
+ createReplyPkt6(NakedTestControl &tc, const uint32_t transid,
+ const bool validIA = true) const {
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, transid));
// Add IA_NA if requested by the client.
if (tc.options_.getLeaseType().includes(CommandOptions::LeaseType::ADDRESS)) {
OptionPtr opt_ia_na = Option::factory(Option::V6, D6O_IA_NA);
+ if (validIA) {
+ OptionPtr iaaddr(new Option6IAAddr(D6O_IAADDR,
+ isc::asiolink::IOAddress("fe80::abcd"), 300, 500));
+ opt_ia_na->addOption(iaaddr);
+ }
reply->addOption(opt_ia_na);
}
// Add IA_PD if requested by the client.
if (tc.options_.getLeaseType().includes(CommandOptions::LeaseType::PREFIX)) {
OptionPtr opt_ia_pd = Option::factory(Option::V6, D6O_IA_PD);
+ if (validIA) {
+ OptionPtr iapref(new Option6IAPrefix(D6O_IAPREFIX,
+ isc::asiolink::IOAddress("fe80::"), 64, 300, 500));
+ opt_ia_pd->addOption(iapref);
+ }
reply->addOption(opt_ia_pd);
}
OptionPtr opt_serverid(new Option(Option::V6, D6O_SERVERID));
@@ -1623,6 +1690,12 @@ TEST_F(TestControlTest, createRenew) {
testCreateRenewRelease(DHCPV6_RENEW);
}
+// This test verifies that the counter of rejected leases in
+// Solicit-Advertise message exchange works correctly
+TEST_F(TestControlTest, rejectedLeasesAdv) {
+ testCountRejectedLeasesSolAdv();
+}
+
// This test verifies that the DHCPv6 Release message is created correctly
// and that it comprises all required options.
TEST_F(TestControlTest, createRelease) {