diff options
author | Wlodek Wencel <wlodek@isc.org> | 2019-11-19 13:36:48 +0100 |
---|---|---|
committer | Tomek Mrugalski <tomasz@isc.org> | 2019-11-20 07:52:57 +0100 |
commit | 9fb8b373e6bf9036f3937a456bd8f15347009b12 (patch) | |
tree | c4fee959f5a74fbc8b4d8168c5845cc25f7d5a2b /src | |
parent | [985-relax-timings-in-new-config-backend-pull-unit-tests] Relaxed timings and... (diff) | |
download | kea-9fb8b373e6bf9036f3937a456bd8f15347009b12.tar.xz kea-9fb8b373e6bf9036f3937a456bd8f15347009b12.zip |
[#572] perfdhcp counting rejected leases
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/perfdhcp/stats_mgr.cc | 2 | ||||
-rw-r--r-- | src/bin/perfdhcp/stats_mgr.h | 31 | ||||
-rw-r--r-- | src/bin/perfdhcp/test_control.cc | 75 | ||||
-rw-r--r-- | src/bin/perfdhcp/test_control.h | 9 | ||||
-rw-r--r-- | src/bin/perfdhcp/tests/avalanche_scen_unittest.cc | 6 | ||||
-rw-r--r-- | src/bin/perfdhcp/tests/basic_scen_unittest.cc | 9 | ||||
-rw-r--r-- | src/bin/perfdhcp/tests/test_control_unittest.cc | 79 |
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) { |