Kea  2.1.2-git
perfdhcp Internals

The perfdhcp utility provides a way of measuring the performance of DHCP servers by generating large amounts of traffic.

Written in C++, its use is described in detail in the DHCP Performance Guide.

This document is aimed at people wishing to understand the internals of the perfdhcp program. It describes the major components in the utility and their interaction.

perfdhcp Classes

CommandOptions (Command Options)

isc::perfdhcp::CommandOptions is a singleton class that parses the perfdhcp command line parameters and initializes its members accordingly. If the parameters are invalid, the parser method throws an exception. Usage is simple:

int main(int argc, char* argv[]) {
try {
CommandOptions& command_options = CommandOptions::instance();
command_options.parse(argc, argv);
} catch(const Exception& e) {
...
}

If the argument parsing is successful, the parsed values can be read from the isc::perfdhcp::CommandOptions singleton from any class or function in the program, e.g.

int rate = CommandOptions::instance().getRate();

TestControl (Test Control)

The isc::perfdhcp::TestControl singleton is responsible for test execution coordination. It relies on the isc::perfdhcp::CommandOptions object to get all required test parameters and for this reason, isc::perfdhcp::CommandOptions has to be initialized and isc::perfdhcp::CommandOptions::parse() called prior to calling isc::perfdhcp::TestControl::run().

isc::perfdhcp::TestControl::run() performs initialization of isc::perfdhcp::TestControl then executes the main program loop. In detail, isc::perfdhcp::TestControl::run() performs the following major operations:

  1. check if the command line has been parsed,
  2. print diagnostics if specified from command line,
  3. register DHCP options factory functions,
  4. read packet templates from files,
  5. initialize the isc::perfdhcp::StatisticsManager object,
  6. set interrupt signal handler (handle ^C),
  7. open and close socket for communication with server,
  8. coordinate sending and receiving packets,
  9. coordinate intermediate reporting,
  10. prints test statistics.

isc::perfdhcp::TestControl is a singleton object, so there is one sole instance of it throughout the program. In order to allow the running of unit tests, where a single instance of isc::perfdhcp::TestControl is used multiple times with different command line options, a isc::perfdhcp::TestControl::reset() function is provided to reset the state of the class members. Also, functions that initialize various class members (such as Statistics Manager) will release any objects from previous test runs.

StatsMgr (Statistics Manager)

isc::perfdhcp::StatsMgr is a class that holds all performance statistics gathered throughout the test execution and is created in isc::perfdhcp::TestControl. isc::perfdhcp::TestControl posts all sent and received packets to isc::perfdhcp::StatsMgr: outgoing packets are recorded and incoming packets are matched with the corresponding outgoing packer to calculate calculate round trip time, number of packet drops etc. Apart from the standard counters implemented in isc::perfdhcp::StatsMgr, custom (named) counters can be specified and incremented by the calling class. isc::perfdhcp::StatsMgr also exposes multiple functions that print gathered statistics into the console.

isc::perfdhcp::StatsMgr is a template class that takes an isc::dhcp::Pkt4, isc::dhcp::Pkt6, isc::perfdhcp::PerfPkt4 or isc::perfdhcp::PerfPkt6 as a typename. An instance of isc::perfdhcp::StatsMgr can be created by:

typedef StatsMgr<Pkt4> StatsMgr4; StatsMgr4 stats_mgr4 =
boost::shared_ptr<StatsMgr4>(new StatsMgr4()); try {
stats_mgr->addExchangeStats(StatsMgr4::XCHG_DO);
} catch(const Exception& e) {
std::cout << e.what() << std::endl;
}

The isc::perfdhcp::StatsMgr instance created in the example above will be used for DHCPv4 testing (i.e. to collect DHCPv4 packets) and will be configured to monitor statistics for DISCOVER-OFFER packet exchanges.

PerfPkt4 and PerfPkt6

The isc::perfdhcp::PerfPkt4 and isc::perfdhcp::PerfPkt6 classes are derived from isc::dhcp::Pkt4 and isc::dhcp::Pkt6. They extend the parent class functionality by adding support for template files. Instances of these classes can be created using a raw buffer (read from a packet template file). Once the packet object is initialized, it is possible to replace parts of the on-wire data by using the isc::perfdhcp::LocalizedOption mechanism.

LocalizedOption (Localized Option)

isc::perfdhcp::LocalizedOption derives from the isc::dhcp::Option class. It represents the DHCP option (v4 or v6) to be placed at specified position in the packet buffer (see PerfPkt4 and PerfPkt6). Such an option is added to the option collection in a isc::perfdhcp::PerfPkt4 or isc::perfdhcp::PerfPkt6 object; when any of PerfPktX::rawPack() functions are called their content is stored in the packet output buffer at the position pointed to by the isc::perfdhcp::LocalizedOption object.

isc::perfdhcp::LocalizedOption also allows the reading of the on wire data in received packet at the specified position. In this case, isc::perfdhcp::LocalizedOption has to be created and added to the received packet. When PerfPktX::rawUnpack() is called, the contents of the buffer will be read and stored in a isc::perfdhcp::LocalizedOption object for further processing.

The following code shows how to create a packet from a (template) buffer and replace option data in the buffer with isc::perfdhcp::LocalizedOption.

OptionBuffer buf; // fill buf with data here. ...
boost::scoped_ptr<PerfPkt4> pkt(new PerfPkt4(&buf[0], buf.size());
const size_t offset_hostname = 240;
OptionBuffer vec_hostname;
// fill the hostname vector with data ...
LocalizedOptionPtr opt_hostname(new LocalizedOption(Option::V4,
vec_hostname,
offset_hostname));
pkt->addOption(opt_hostname);
// by calling rawPack() we replace the packet contents with option
// contents at buffer position 240.
pkt->rawPack();

PktTransform (Packet Transform)

The isc::perfdhcp::PktTransform helper class contains the static functions to pack and unpack DHCP options (specifically isc::perfdhcp::LocalizedOption) to and from the packet buffer. This logic has been moved away from isc::perfdhcp::PerfPkt4 and isc::perfdhcp::PerfPkt6 classes to isc::perfdhcp::PktTransform because PerfPktX classes share the logic here.