Commit 00e8a3eb authored by Marcin Siodelski's avatar Marcin Siodelski

[1959] Use StatsMgr to track packet exchanges.

parent e34ad6d4
......@@ -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<double>::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
......
......@@ -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<uint8_t> mac_address = generateMacAddress();
// Generate trasnaction id to be set for the new exchange.
const uint32_t transid = static_cast<uint32_t>(random());
const uint32_t transid = static_cast<uint32_t>(random() % 0x00FFFFFF);
boost::shared_ptr<Pkt4> 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<uint8_t> duid = generateDuid();
// Generate trasnaction id to be set for the new exchange.
const uint32_t transid = static_cast<uint32_t>(random());
const uint32_t transid = static_cast<uint32_t>(random() % 0x00FFFFFF);
boost::shared_ptr<Pkt6> 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
......
......@@ -19,12 +19,15 @@
#include <vector>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <dhcp/dhcp6.h>
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
#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<dhcp::Pkt4> StatsMgr4;
// Pointer to Statistics Manager for DHCPv4;
typedef boost::shared_ptr<StatsMgr4> StatsMgr4Ptr;
// Statictics Manager for DHCPv6.
typedef StatsMgr<dhcp::Pkt6> StatsMgr6;
// Pointer to Statistics Manager for DHCPv6.
typedef boost::shared_ptr<StatsMgr6> 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_;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment