|
@@ -2,7 +2,7 @@
|
|
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
|
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
|
|
<!ENTITY mdash "—" >
|
|
|
-<!ENTITY % version SYSTEM "version.ent">
|
|
|
+<!ENTITY % version SYSTEM "../../../doc/version.ent">
|
|
|
%version;
|
|
|
]>
|
|
|
|
|
@@ -22,7 +22,7 @@
|
|
|
- PERFORMANCE OF THIS SOFTWARE.
|
|
|
-->
|
|
|
|
|
|
-<?xml-stylesheet href="bind10-guide.css" type="text/css"?>
|
|
|
+<?xml-stylesheet href="../../../doc/guide/bind10-guide.css" type="text/css"?>
|
|
|
|
|
|
<book>
|
|
|
<bookinfo>
|
|
@@ -47,35 +47,170 @@
|
|
|
|
|
|
</bookinfo>
|
|
|
|
|
|
+ <chapter id="perfdhcp-refactoring">
|
|
|
+ <title>Introduction</title>
|
|
|
+ <para>
|
|
|
+ The source code of perfdhcp tool has been refactored from C to C++.
|
|
|
+ There is a bunch of new C++ classes. in the refactored code.
|
|
|
+ All of them are well documented in Doxygen. This document is
|
|
|
+ limited to brief overview of major classes to help understand
|
|
|
+ their purpose.
|
|
|
+ </para>
|
|
|
+ </chapter>
|
|
|
<chapter id="perfdhcp-classes">
|
|
|
<title>Classes</title>
|
|
|
<section id="command-options">
|
|
|
- <title>CommandOptions (command_options (.h, cc)</title>
|
|
|
+ <title>CommandOptions (command_options.h .cc)</title>
|
|
|
<para>
|
|
|
CommandOptions is a singleton class that parses perfdhcp command line
|
|
|
parameters and initializes its members accordingly. If parsed parameters
|
|
|
are invalid the parser function throws exception.
|
|
|
<screen>
|
|
|
<![CDATA[main(int argc, char* argv[]) {
|
|
|
- try {
|
|
|
- CommandOptions& command_options = CommandOptions::instance();
|
|
|
- command_options.parse(argc, argv);
|
|
|
- catch(const Exception& e) {
|
|
|
- ...
|
|
|
- }
|
|
|
+try {
|
|
|
+ CommandOptions& command_options = CommandOptions::instance();
|
|
|
+ command_options.parse(argc, argv);
|
|
|
+catch(const Exception& e) {
|
|
|
...
|
|
|
+}
|
|
|
+...
|
|
|
}]]>
|
|
|
</screen>
|
|
|
If argument parsing is successful than parsed values can be read from
|
|
|
CommandOptions singleton from any class or function in the program:
|
|
|
<screen>
|
|
|
<![CDATA[
|
|
|
- ...
|
|
|
- int rate = CommandOptions::instance().getRate();
|
|
|
- ...
|
|
|
+...
|
|
|
+int rate = CommandOptions::instance().getRate();
|
|
|
+...
|
|
|
+]]>
|
|
|
+ </screen>
|
|
|
+ </para>
|
|
|
+ </section>
|
|
|
+ <section id="test-control">
|
|
|
+ <title>TestControl (test_control.h .cc)</title>
|
|
|
+ <para>
|
|
|
+ TestControl singleton is responsible for test execution coordination.
|
|
|
+ It relies on CommandOptions object to get all required test parameters. For
|
|
|
+ this reason CommandOptions has to be initialized and CommandOptions::parse()
|
|
|
+ has to be called prior to calling TestControl::run(). The latter function
|
|
|
+ performs initialization of TestControl internals and execues the main program
|
|
|
+ loop. The TestControl::run() function performs the following major operations:
|
|
|
+ <orderedlist>
|
|
|
+ <listitem><para>check if command line has been parsed,</para></listitem>
|
|
|
+ <listitem><para>prints diagnostics if specified from command line,</para></listitem>
|
|
|
+ <listitem><para>register DHCP options factory functions,</para></listitem>
|
|
|
+ <listitem><para>read packet templates from files,</para></listitem>
|
|
|
+ <listitem><para>initialize Statistics Manager object,</para></listitem>
|
|
|
+ <listitem><para>set interrupt signal handler (handle ^C),</para></listitem>
|
|
|
+ <listitem><para>open and close socket for communication with server,</para></listitem>
|
|
|
+ <listitem><para>coordinate sending and receiving packets,</para></listitem>
|
|
|
+ <listitem><para>coordinate intermediate reporting,</para></listitem>
|
|
|
+ <listitem><para>prints test statistics.</para></listitem>
|
|
|
+ </orderedlist>
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ TestControl is a singleton object so there is one sole instance of
|
|
|
+ it throughout the program. In order to allow running performance test
|
|
|
+ multiple times (using different command line options) with single instance
|
|
|
+ of the TestControl object it uses TestControl::reset() function internally
|
|
|
+ to reset state of the class members. Also, functions that initialize
|
|
|
+ various class members like Statistics Manager will release any objects
|
|
|
+ existing from previous test runs.
|
|
|
+ </para>
|
|
|
+ </section>
|
|
|
+ <section id="stats-mgr">
|
|
|
+ <title>StatsMgr (stats_mgr.h)</title>
|
|
|
+ <para>
|
|
|
+ StatsMgr is a class that holds all performance statistics gathered throughout
|
|
|
+ the test execution. Statistics Manager is created in TestControl. The
|
|
|
+ TestControl class posts all sent and received packets to StatsMgr.
|
|
|
+ Collected packets are used to match packets received from the server with
|
|
|
+ corresponding sent packets, calculate round trip time, number of packet
|
|
|
+ drops etc. Apart from the standard counters implemented in StatsMgr,
|
|
|
+ custom (named) counters can be specified and incremented by the calling
|
|
|
+ class. StatsMgr also exposes multiple functions that print gathered
|
|
|
+ statistics into the console.
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ The StatsMgr is a template class that takes Pkt4, Pkt6, PerfPkt4 or
|
|
|
+ PerfPkt6 as a typename. The instance of the StatsMgr can be created
|
|
|
+ as follows:
|
|
|
+ <screen>
|
|
|
+<![CDATA[
|
|
|
+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;
|
|
|
+}
|
|
|
+]]>
|
|
|
+ </screen>
|
|
|
+ The StatsMgr instance created in the example above will be used for
|
|
|
+ DHCPv4 testing (collect DHCPv4 packets) and will be configured to
|
|
|
+ monitor statistics for DISCOVER-OFFER packet exchanges.
|
|
|
+ </para>
|
|
|
+ </section>
|
|
|
+ <section id="perf-pkt">
|
|
|
+ <title>PerfPkt4, PerfPkt6 (perf_pkt4.h .cc, perf_pkt6.h .cc)</title>
|
|
|
+ <para>
|
|
|
+ The PerfPkt4 and PerfPkt6 classes are derived from dhcp::Pkt4 and
|
|
|
+ dhcp::Pkt6 (src/lib/dhcp). They extend parent class functionality
|
|
|
+ by adding support for template files. The instance of these classes
|
|
|
+ can be created using raw buffer (read from packet template file).
|
|
|
+ Once packet object is initialized it is possible to replace
|
|
|
+ parts of the on-wire data by using LocalizedOption mechanism.
|
|
|
+ </para>
|
|
|
+ </section>
|
|
|
+ <section id="localized-option">
|
|
|
+ <title>LocalizedOption (localized_option.h)</title>
|
|
|
+ <para>
|
|
|
+ LocalizedOption derives from dhcp::Option class. It represents the
|
|
|
+ DHCP option (v4 or v6) to be placed at specified position in the
|
|
|
+ packet buffer (see <xref linkend="perf-pkt"/>). Such option is added
|
|
|
+ to option collection in PerfPkt4 or PerfPkt6 object and when any of
|
|
|
+ PerfPktX::rawPack() function is called their content is stored in
|
|
|
+ the packet output buffer at the position pointed to by
|
|
|
+ LocalizedOption object. The LocalizedOption also allows to read the
|
|
|
+ on wire data in received packet at the specified position. In this
|
|
|
+ case LocalizedOption has to be created and added to recived packet.
|
|
|
+ When PerfPktX::rawUnpack() is called the contents of the buffer
|
|
|
+ will be read and stored in LocalizedOption object for further
|
|
|
+ processing.
|
|
|
+ </para>
|
|
|
+ <para>
|
|
|
+ The following code shows how to create a packet from (template)
|
|
|
+ buffer and replace option data in the buffer with LocalizedOption.
|
|
|
+ <screen>
|
|
|
+<![CDATA[
|
|
|
+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, DHO_HOST_NAME, vec_hostname,
|
|
|
+ offset_hostname));
|
|
|
+pkt->addOption(opt_hostname);
|
|
|
+// by calling rawPack() we replace packet contents with option contents at
|
|
|
+// buffer position 240.
|
|
|
+pkt->rawPack();
|
|
|
]]>
|
|
|
</screen>
|
|
|
</para>
|
|
|
</section>
|
|
|
+ <section id="pkt-transform.h">
|
|
|
+ <title>PktTransform (pkt_transform.h .cc)</title>
|
|
|
+ <para>
|
|
|
+ This helper class contains the static functions to pack and unpack
|
|
|
+ DHCP options (specifically LocalizedOption) to and from the packet
|
|
|
+ buffer. This logic has been moved away from PerfPkt4 and PerfPkt6
|
|
|
+ classes to PktTransform because PerfPktX classes share the logic
|
|
|
+ here.
|
|
|
+ </para>
|
|
|
+ </section>
|
|
|
</chapter>
|
|
|
</book>
|