From: Marcin Siodelski Date: Thu, 16 Aug 2012 15:04:39 +0000 (+0200) Subject: [1959] Use StatsMgr to track packet exchanges. X-Git-Tag: trac2351_base~47^2~11^2~24 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=00e8a3ebd6c42824b0bfdd0ca96a6acd179a1194;p=thirdparty%2Fkea.git [1959] Use StatsMgr to track packet exchanges. --- diff --git a/tests/tools/perfdhcp/stats_mgr.h b/tests/tools/perfdhcp/stats_mgr.h index 245c69e3cf..7ade910192 100644 --- a/tests/tools/perfdhcp/stats_mgr.h +++ b/tests/tools/perfdhcp/stats_mgr.h @@ -243,20 +243,21 @@ public: /// In this mode all packets are stored throughout the test execution. ExchangeStats(const ExchangeType xchg_type, const bool archive_enabled) : xchg_type_(xchg_type), + sent_packets_(), + rcvd_packets_(), + archived_packets_(), + archive_enabled_(archive_enabled), min_delay_(std::numeric_limits::max()), max_delay_(0.), sum_delay_(0.), - orphans_(0), sum_delay_squared_(0.), - ordered_lookups_(0), + orphans_(0), unordered_lookup_size_sum_(0), unordered_lookups_(0), + ordered_lookups_(0), sent_packets_num_(0), - rcvd_packets_num_(0), - sent_packets_(), - rcvd_packets_(), - archived_packets_(), - archive_enabled_(archive_enabled) { + rcvd_packets_num_(0) + { next_sent_ = sent_packets_.begin(); } @@ -555,7 +556,10 @@ public: /// number of dropped packets and number of orphans. void printMainStats() const { using namespace std; - uint64_t drops = getRcvdPacketsNum() - getSentPacketsNum(); + uint64_t drops = 0; + if (getRcvdPacketsNum() >= getSentPacketsNum()) { + drops = getRcvdPacketsNum() - getSentPacketsNum(); + } cout << "sent packets: " << getSentPacketsNum() << endl << "received packets: " << getRcvdPacketsNum() << endl << "drops: " << drops << endl diff --git a/tests/tools/perfdhcp/test_control.cc b/tests/tools/perfdhcp/test_control.cc index 9f4bd5c493..286fc823e7 100644 --- a/tests/tools/perfdhcp/test_control.cc +++ b/tests/tools/perfdhcp/test_control.cc @@ -268,6 +268,27 @@ TestControl::getNextExchangesNum() const { return (0); } +void +TestControl::initializeStatsMgr() { + CommandOptions& options = CommandOptions::instance(); + if (options.getIpVersion() == 4) { + stats_mgr4_.reset(); + stats_mgr4_ = StatsMgr4Ptr(new StatsMgr4()); + stats_mgr4_->addExchangeStats(StatsMgr4::XCHG_DO); + if (options.getExchangeMode() == CommandOptions::DO_SA) { + stats_mgr4_->addExchangeStats(StatsMgr4::XCHG_RA); + } + + } else if (options.getIpVersion() == 6) { + stats_mgr6_.reset(); + stats_mgr6_ = StatsMgr6Ptr(new StatsMgr6()); + stats_mgr6_->addExchangeStats(StatsMgr6::XCHG_SA); + if (options.getExchangeMode() == CommandOptions::DO_SA) { + stats_mgr6_->addExchangeStats(StatsMgr6::XCHG_RR); + } + } +} + int TestControl::openSocket(uint16_t port) const { CommandOptions& options = CommandOptions::instance(); @@ -278,9 +299,9 @@ TestControl::openSocket(uint16_t port) const { IOAddress remoteaddr(servername); if (port == 0) { if (options.getIpVersion() == 6) { - port = 547; - } else if (port == 0) { - port = 67; + port = DHCP6_CLIENT_PORT; + } else if (options.getIpVersion() == 4) { + port = 67; // TODO: find out why port 68 is wrong here. } } if (options.getIpVersion() == 6) { @@ -351,9 +372,59 @@ TestControl::openSocket(uint16_t port) const { } } } + return(sock); } +void +TestControl::printStats() const { + CommandOptions& options = CommandOptions::instance(); + if (options.getIpVersion() == 4) { + if (!stats_mgr4_) { + isc_throw(InvalidOperation, "Statistics Manager for DHCPv4 " + "hasn't been initialized"); + } + stats_mgr4_->printStats(); + } else if (options.getIpVersion() == 6) { + if (!stats_mgr6_) { + isc_throw(InvalidOperation, "Statistics Manager for DHCPv6 " + "hasn't been initialized"); + } + stats_mgr6_->printStats(); + } +} + +void +TestControl::receivePacket4(Pkt4Ptr& pkt4) { + switch(pkt4->getType()) { + case DHCPOFFER : + stats_mgr4_->passRcvdPacket(StatsMgr4::XCHG_DO, pkt4); + break; + case DHCPACK : + stats_mgr4_->passRcvdPacket(StatsMgr4::XCHG_RA, pkt4); + break; + default: + isc_throw(BadValue, "unknown type " << pkt4->getType() + << " of received DHCPv4 packet"); + } +} + +void +TestControl::receivePacket6(Pkt6Ptr& pkt6) { + switch(pkt6->getType()) { + case DHCPV6_ADVERTISE : + stats_mgr6_->passRcvdPacket(StatsMgr6::XCHG_SA, pkt6); + break; + case DHCPV6_REPLY : + stats_mgr6_->passRcvdPacket(StatsMgr6::XCHG_RR, pkt6); + break; + default: + isc_throw(BadValue, "unknown type " << pkt6->getType() + << " of received DHCPv6 packet"); + } + +} + void TestControl::receivePackets() { int timeout = 0; @@ -364,17 +435,17 @@ TestControl::receivePackets() { if (!pkt4) { receiving = false; } else { - // TODO: replace this with use of StatsMgr to increase - // number of received packets. This can be done once - // the 1958 ticket is reviewed and checked-in. - std::cout << "Received packet" << std::endl; + pkt4->unpack(); + receivePacket4(pkt4); } } else if (CommandOptions::instance().getIpVersion() == 6) { Pkt6Ptr pkt6 = IfaceMgr::instance().receive6(timeout); if (!pkt6) { receiving = false; } else { - std::cout << "Received DHCPv6 packet" << std::endl; + if (pkt6->unpack()) { + receivePacket6(pkt6); + } } } } @@ -453,6 +524,8 @@ TestControl::run() { } registerOptionFactories(); TestControlSocket socket(openSocket()); + + initializeStatsMgr(); uint64_t packets_sent = 0; for (;;) { updateSendDue(); @@ -470,9 +543,9 @@ TestControl::run() { sendSolicit6(socket); } ++packets_sent; - cout << "Packets sent " << packets_sent << endl; } } + printStats(); } void @@ -482,7 +555,7 @@ TestControl::sendDiscover4(const TestControlSocket& socket) { // Generate the MAC address to be passed in the packet. std::vector mac_address = generateMacAddress(); // Generate trasnaction id to be set for the new exchange. - const uint32_t transid = static_cast(random()); + const uint32_t transid = static_cast(random() % 0x00FFFFFF); boost::shared_ptr pkt4(new Pkt4(DHCPDISCOVER, transid)); if (!pkt4) { isc_throw(Unexpected, "failed to create DISCOVER packet"); @@ -500,6 +573,11 @@ TestControl::sendDiscover4(const TestControlSocket& socket) { setDefaults4(socket, pkt4); pkt4->pack(); IfaceMgr::instance().send(pkt4); + if (!stats_mgr4_) { + isc_throw(InvalidOperation, "Statistics Manager for DHCPv4 " + "hasn't been initialized"); + } + stats_mgr4_->passSentPacket(StatsMgr4::XCHG_DO, pkt4); } void @@ -511,7 +589,7 @@ TestControl::sendSolicit6(const TestControlSocket& socket) { // Generate DUID to be passed to the packet std::vector duid = generateDuid(); // Generate trasnaction id to be set for the new exchange. - const uint32_t transid = static_cast(random()); + const uint32_t transid = static_cast(random() % 0x00FFFFFF); boost::shared_ptr pkt6(new Pkt6(DHCPV6_SOLICIT, transid)); if (!pkt6) { isc_throw(Unexpected, "failed to create SOLICIT packet"); @@ -525,6 +603,11 @@ TestControl::sendSolicit6(const TestControlSocket& socket) { setDefaults6(socket, pkt6); pkt6->pack(); IfaceMgr::instance().send(pkt6); + if (!stats_mgr6_) { + isc_throw(InvalidOperation, "Statistics Manager for DHCPv6 " + "hasn't been initialized"); + } + stats_mgr6_->passSentPacket(StatsMgr6::XCHG_SA, pkt6); } void diff --git a/tests/tools/perfdhcp/test_control.h b/tests/tools/perfdhcp/test_control.h index de3b942ade..c153fac3b6 100644 --- a/tests/tools/perfdhcp/test_control.h +++ b/tests/tools/perfdhcp/test_control.h @@ -19,12 +19,15 @@ #include #include +#include #include #include #include #include +#include "stats_mgr.h" + namespace isc { namespace perfdhcp { @@ -44,6 +47,15 @@ namespace perfdhcp { class TestControl : public boost::noncopyable { public: + // Statistics Manager for DHCPv4. + typedef StatsMgr StatsMgr4; + // Pointer to Statistics Manager for DHCPv4; + typedef boost::shared_ptr StatsMgr4Ptr; + // Statictics Manager for DHCPv6. + typedef StatsMgr StatsMgr6; + // Pointer to Statistics Manager for DHCPv6. + typedef boost::shared_ptr StatsMgr6Ptr; + /// \brief Socket wrapper class. /// /// This is wrapper class that holds descriptor of the socket @@ -152,7 +164,6 @@ protected: /// \return true if any of the exit conditions is fulfiled. bool checkExitConditions() const; - /// \brief Factory function to create DHCPv6 ELAPSED_TIME option. /// /// This factory function creates DHCPv6 ELAPSED_TIME option instance. @@ -284,6 +295,12 @@ protected: /// \return number of exchanges to be started immediatelly. uint64_t getNextExchangesNum() const; + /// \brief Initializes Statistics Manager. + /// + /// This function initializes Statistics Manager. If there is + /// the one initialized already it is released. + void initializeStatsMgr(); + /// \brief Open socket to communicate with DHCP server. /// /// Method opens socket and binds it to local address. Function will @@ -305,6 +322,17 @@ protected: /// \return socket descriptor. int openSocket(uint16_t port = 0) const; + /// \brief Print performance statistics. + /// + /// Method prints performance statistics. + /// \throws isc::InvalidOperation if Statistics Manager was + /// not initialized. + void printStats() const; + + void receivePacket4(dhcp::Pkt4Ptr& pkt4); + + void receivePacket6(dhcp::Pkt6Ptr& pkt4); + /// \brief Receive DHCPv4 or DHCPv6 packets from the server. /// /// Method receives DHCPv4 or DHCPv6 packets from the server. @@ -408,6 +436,9 @@ private: boost::posix_time::ptime last_sent_; ///< Indicates when the last exchange /// was initiated. + StatsMgr4Ptr stats_mgr4_; /// Statistics Manager 4. + StatsMgr6Ptr stats_mgr6_; /// Statistics Manager 6. + uint64_t sent_packets_0_; uint64_t sent_packets_1_; };