Commit 5e7e2cb7 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[github22] Several minor changes after another review.

- Updates to the unit tests.
- Improved commentary in unit tests.
- Renamed methods and updated commentary in command_options.h/cc
- Hold the number of relay encapsulations configured with -A.
- Updated perfdhcp man page.
parent 277322dc
......@@ -118,7 +118,7 @@ CommandOptions::reset() {
mac_template_.assign(mac, mac + 6);
duid_template_.clear();
base_.clear();
mac_file_list_.clear();
mac_list_file_.clear();
mac_list_.clear();
num_request_.clear();
period_ = 0;
......@@ -136,7 +136,6 @@ CommandOptions::reset() {
broadcast_ = false;
rapid_commit_ = false;
use_first_ = false;
use_relayed_v6_ = false;
template_file_.clear();
rnd_offset_.clear();
xid_offset_.clear();
......@@ -146,6 +145,7 @@ CommandOptions::reset() {
diags_.clear();
wrapped_.clear();
server_name_.clear();
v6_relay_encapsulation_level_ = 0;
generateDuidTemplate();
}
......@@ -224,16 +224,16 @@ CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) {
use_first_ = true;
break;
// act as a relay Agent (single char option and R/r are taken already).
// Simulate DHCPv6 relayed traffic.
case 'A':
use_relayed_v6_ = true;
// TODO: actually use level, at the moment we support only 1 level.
// @todo: At the moment we only support simulating a single relay
// agent. In the future we should extend it to up to 32.
// See comment in https://github.com/isc-projects/kea/pull/22#issuecomment-243405600
int level;
level = positiveInteger(
" -A<encapusulation_levels> must be a positive integer");
if (level != 1) {
isc_throw(isc::InvalidParameter, "-A only supports 1 at the moment.");
v6_relay_encapsulation_level_ =
static_cast<uint8_t>(positiveInteger("-A<encapusulation-level> must"
" be a positive integer"));
if (v6_relay_encapsulation_level_ != 1) {
isc_throw(isc::InvalidParameter, "-A only supports 1 at the moment.");
}
break;
......@@ -361,7 +361,7 @@ CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) {
case 'M':
check(num_mac_list_files >= 1, "only -M option can be specified");
num_mac_list_files++;
mac_file_list_ = std::string(optarg);
mac_list_file_ = std::string(optarg);
loadMacs();
break;
......@@ -712,7 +712,7 @@ CommandOptions::convertHexString(const std::string& text) const {
void CommandOptions::loadMacs() {
std::string line;
std::ifstream infile(mac_file_list_.c_str());
std::ifstream infile(mac_list_file_.c_str());
while (std::getline(infile, line)) {
check(decodeMacString(line), "invalid mac in input");
}
......@@ -930,8 +930,8 @@ CommandOptions::printCommandLine() const {
if (use_first_) {
std::cout << "use-first" << std::endl;
}
if (!mac_file_list_.empty()) {
std::cout << "mac-file-list=" << mac_file_list_ << std::endl;
if (!mac_list_file_.empty()) {
std::cout << "mac-list-file=" << mac_list_file_ << std::endl;
}
for (size_t i = 0; i < template_file_.size(); ++i) {
std::cout << "template-file[" << i << "]=" << template_file_[i] << std::endl;
......@@ -972,13 +972,13 @@ CommandOptions::printCommandLine() const {
void
CommandOptions::usage() const {
std::cout <<
"perfdhcp [-hv] [-4|-6] [-A<encapusulation_levels>] [-e<lease-type>]"
"perfdhcp [-hv] [-4|-6] [-A<encapusulation-level>] [-e<lease-type>]"
" [-r<rate>] [-f<renew-rate>]\n"
" [-F<release-rate>] [-t<report>] [-R<range>] [-b<base>]\n"
" [-n<num-request>] [-p<test-period>] [-d<drop-time>]\n"
" [-D<max-drop>] [-l<local-addr|interface>] [-P<preload>]\n"
" [-a<aggressivity>] [-L<local-port>] [-s<seed>] [-i] [-B]\n"
" [-c] [-1] [-M<mac_list_file>] [-T<template-file>]\n"
" [-c] [-1] [-M<mac-list-file>] [-T<template-file>]\n"
" [-X<xid-offset>] [-O<random-offset] [-E<time-offset>]\n"
" [-S<srvid-offset>] [-I<ip-offset>] [-x<diagnostic-selector>]\n"
" [-w<wrapped>] [server]\n"
......@@ -1042,10 +1042,11 @@ CommandOptions::usage() const {
" via which exchanges are initiated.\n"
"-L<local-port>: Specify the local port to use\n"
" (the value 0 means to use the default).\n"
"-M<mac-file-list>: A text file containing a list of macs, one per line.\n"
" If provided a random mac will be choosen for every exchange.\n"
" Must not be used in conjunction with the -b parameter.\n"
" In the v6 case MAC addresses are used to generate DUID-LLs.\n"
"-M<mac-list-file>: A text file containing a list of MAC addresses,\n"
" one per line. If provided, a MAC address will be choosen randomly\n"
" from this list for every new exchange. In the DHCPv6 case, MAC\n"
" addresses are used to generate DUID-LLs. This parameter must not be\n"
" used in conjunction with the -b parameter.\n"
"-O<random-offset>: Offset of the last octet to randomize in the template.\n"
"-P<preload>: Initiate first <preload> exchanges back to back at startup.\n"
"-r<rate>: Initiate <rate> DORA/SARR (or if -i is given, DO/SA)\n"
......@@ -1085,8 +1086,12 @@ CommandOptions::usage() const {
" the exchange rate (given by -r<rate>). Furthermore the sum of\n"
" this value and the renew-rate (given by -f<rate) must be equal\n"
" to or less than the exchange rate.\n"
"-A<encapusulation_levels>: When acting in DHCPv6 mode, send out relay packets.\n"
" <encapusulation_levels> specifies how many relays forwarded this message\n"
"-A<encapusulation-level>: Specifies that relayed traffic must be\n"
" generated. The argument specifies the level of encapsulation, i.e.\n"
" how many relay agents are simulated. Currently the only supported\n"
" <encapsulation-level> value is 1, which means that the generated\n"
" traffic is an equivalent of the traffic passing through a single\n"
" relay agent.\n"
"\n"
"The remaining options are used only in conjunction with -r:\n"
"\n"
......
......@@ -24,6 +24,9 @@ namespace perfdhcp {
class CommandOptions : public boost::noncopyable {
public:
/// @brief A vector holding MAC addresses.
typedef std::vector<std::vector<uint8_t> > MacAddrsVector;
/// \brief A class encapsulating the type of lease being requested from the
/// server.
///
......@@ -272,25 +275,27 @@ public:
/// \brief Check if generated DHCPv6 messages shuold appear as relayed.
///
/// \return true if generated traffic should appear as relayed.
bool isUseRelayedV6() const { return use_relayed_v6_; }
bool isUseRelayedV6() const { return (v6_relay_encapsulation_level_ > 0); }
/// \brief Returns template file names.
///
/// \return template file names.
std::vector<std::string> getTemplateFiles() const { return template_file_; }
/// \brief Returns location of the file containing list of MAC addresses
/// \brief Returns location of the file containing list of MAC addresses.
///
/// MAC addresses read from the file are used by the perfdhcp in message
/// exchanges with the DHCP server.
///
/// \return mac_template file name.
std::string getMacListFile() const { return mac_file_list_; }
/// \return Location of the file containing list of MAC addresses.
std::string getMacListFile() const { return mac_list_file_; }
/// \brief Returns the list of macs, every mac is a vector<uint8_t>
/// \brief Returns reference to a vector of MAC addresses read from a file.
///
/// Every MAC address is represented as a vector.
///
/// \return mac_list_ vector of vectors.
const std::vector<std::vector<uint8_t> >& getAllMacs() const { return mac_list_; }
/// \return Reference to a vector of vectors.
const MacAddrsVector& getMacsFromFile() const { return mac_list_; }
/// brief Returns template offsets for xid.
///
......@@ -554,10 +559,13 @@ private:
/// that are used for initiating exchanges. Template packets
/// read from files are later tuned with variable data.
std::vector<std::string> template_file_;
/// A file containing a list of macs, one per line. This can be used if
/// you don't want to genrate Mac starting from a base mac but rather provide
/// the tool with a list of macs it should randomize on.
std::string mac_file_list_;
/// Location of a file containing a list of MAC addresses, one per line.
/// This can be used if you don't want to generate MAC address from a
/// base MAC address, but rather provide the file with a list of MAC
/// addresses to be randomly picked. Note that in DHCPv6 those MAC
/// addresses will be used to generate DUID-LL.
std::string mac_list_file_;
/// List of MAC addresses loaded from a file.
std::vector<std::vector<uint8_t> > mac_list_;
/// Offset of transaction id in template files. First vector
/// element points to offset for DISCOVER/SOLICIT messages,
......@@ -582,8 +590,8 @@ private:
std::string wrapped_;
/// Server name specified as last argument of command line.
std::string server_name_;
/// Controls whether generated dhcpv6 test traffic should be relayed.
bool use_relayed_v6_;
/// Indicates how many DHCPv6 relay agents are simulated.
uint8_t v6_relay_encapsulation_level_;
};
} // namespace perfdhcp
......
......@@ -11,7 +11,7 @@
<refentry>
<refentryinfo>
<date>February 19, 2014</date>
<date>August 31, 2016</date>
</refentryinfo>
<refmeta>
......@@ -27,7 +27,7 @@
<docinfo>
<copyright>
<year>2014</year>
<year>2016</year>
<holder>Internet Systems Consortium, Inc. ("ISC")</holder>
</copyright>
</docinfo>
......@@ -37,7 +37,7 @@
<command>perfdhcp</command>
<arg><option>-1</option></arg>
<arg><option>-4|-6</option></arg>
<arg><option>-A</option></arg>
<arg><option>-A <replaceable class="parameter">encapsulation-level</replaceable></option></arg>
<arg><option>-a <replaceable class="parameter">aggressivity</replaceable></option></arg>
<arg><option>-b <replaceable class="parameter">base</replaceable></option></arg>
<arg><option>-B</option></arg>
......@@ -53,6 +53,7 @@
<arg><option>-I <replaceable class="parameter">ip-offset</replaceable></option></arg>
<arg><option>-l <replaceable class="parameter">local-address|interface</replaceable></option></arg>
<arg><option>-L <replaceable class="parameter">local-port</replaceable></option></arg>
<arg><option>-M <replaceable class="parameter">mac-list-file</replaceable></option></arg>
<arg><option>-n <replaceable class="parameter">num-request</replaceable></option></arg>
<arg><option>-O <replaceable class="parameter">random-offset</replaceable></option></arg>
<arg><option>-p <replaceable class="parameter">test-period</replaceable></option></arg>
......@@ -236,16 +237,6 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>-A</option></term>
<listitem>
<para>
When acting as a DHCPv6 behave like a relay Agent.
Send out packets as if they were relayed from an agent.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-a <replaceable class="parameter">aggressivity</replaceable></option></term>
<listitem>
......@@ -403,6 +394,19 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>-M <replaceable class="parameter">mac-list-file</replaceable></option></term>
<listitem>
<para>
A text file containing a list of MAC addresses,
one per line. If provided, a MAC address will be choosen randomly
from this list for every new exchange. In the DHCPv6 case, MAC
addresses are used to generate DUID-LLs. This parameter must not be
used in conjunction with the -b parameter.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-P <replaceable class="parameter">preload</replaceable></option></term>
<listitem>
......@@ -605,6 +609,20 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>-A <replaceable class="parameter">encapsulation-level</replaceable></option></term>
<listitem>
<para>
Specifies that relayed traffic must be
generated. The argument specifies the level of encapsulation, i.e.
how many relay agents are simulated. Currently the only supported
<replaceable class="parameter">encapsulation-level</replaceable>
value is 1, which means that the generated traffic is an equivalent
of the traffic passing through a single relay agent.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
......
......@@ -81,7 +81,7 @@ TestControl::instance() {
}
TestControl::TestControl()
: number_generator_(0, CommandOptions::instance().getAllMacs().size()) {
: number_generator_(0, CommandOptions::instance().getMacsFromFile().size()) {
reset();
}
......@@ -469,7 +469,7 @@ std::vector<uint8_t>
TestControl::generateMacAddress(uint8_t& randomized) {
CommandOptions& options = CommandOptions::instance();
vector<vector<uint8_t> > macs = options.getAllMacs();
const CommandOptions::MacAddrsVector& macs = options.getMacsFromFile();
// if we are using the -M option return a random one from the list...
if (macs.size() > 0) {
uint16_t r = number_generator_();
......@@ -526,7 +526,7 @@ std::vector<uint8_t>
TestControl::generateDuid(uint8_t& randomized) {
CommandOptions& options = CommandOptions::instance();
std::vector<uint8_t> mac_addr(generateMacAddress(randomized));
vector<vector<uint8_t> > macs = options.getAllMacs();
const CommandOptions::MacAddrsVector& macs = options.getMacsFromFile();
// pick a random mac address if we are using option -M..
if (macs.size() > 0) {
uint16_t r = number_generator_();
......
......@@ -848,13 +848,13 @@ TEST_F(CommandOptionsTest, Server) {
TEST_F(CommandOptionsTest, LoadMacsFromFile) {
CommandOptions &opt = CommandOptions::instance();
std::string mac_list_full_path = getFullPath("mac_list.txt");
std::string mac_list_full_path = getFullPath("mac-list.txt");
std::ostringstream cmd;
cmd << "perfdhcp -M " << mac_list_full_path << " abc";
EXPECT_NO_THROW(process(cmd.str()));
EXPECT_EQ(mac_list_full_path, opt.getMacListFile());
std::vector<std::vector<uint8_t> > m = opt.getAllMacs();
const CommandOptions::MacAddrsVector& m = opt.getMacsFromFile();
EXPECT_EQ(4, m.size());
}
......
......@@ -17,6 +17,7 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/foreach.hpp>
#include <algorithm>
#include <cstddef>
#include <stdint.h>
#include <string>
......@@ -1121,8 +1122,8 @@ TEST_F(TestControlTest, GenerateDuid) {
testDuid();
// Checks that the random mac address returned by generateDuid
// is in the list of mac addresses in the mac_list.txt data file
std::string mac_list_full_path = getFullPath("mac_list.txt");
// is in the list of mac addresses in the mac-list.txt data file
std::string mac_list_full_path = getFullPath("mac-list.txt");
std::ostringstream cmd;
cmd << "perfdhcp -M " << mac_list_full_path << " abc";
ASSERT_NO_THROW(processCmdLine(cmd.str()));
......@@ -1130,22 +1131,22 @@ TEST_F(TestControlTest, GenerateDuid) {
NakedTestControl tc;
uint8_t randomized = 0;
std::vector<uint8_t> generated_duid = tc.generateDuid(randomized);
// check that generated_duid is DUID_LL
// Check that generated_duid is DUID_LL
ASSERT_EQ(10, generated_duid.size());
DuidPtr duid(new DUID(generated_duid));
ASSERT_EQ(duid->getType(), DUID::DUID_LL);
// make sure it's on the list
// Make sure it's on the list
CommandOptions& options = CommandOptions::instance();
vector<vector<uint8_t> > macs = options.getAllMacs();
// duid_ll is made of 2 bytes of duid type, 2 bytes of hardwaretype,
// then 6 bytes of mac
const CommandOptions::MacAddrsVector& macs = options.getMacsFromFile();
// DUID LL comprises 2 bytes of duid type, 2 bytes of hardware type,
// then 6 bytes of HW address.
vector<uint8_t> mac(6);
std::copy(
generated_duid.begin() + 4, generated_duid.begin() + 10, mac.begin());
// check that mac is in macs
ASSERT_TRUE(
std::find(macs.begin(), macs.end(), mac) !=
macs.end()
);
std::copy(generated_duid.begin() + 4, generated_duid.begin() + 10,
mac.begin());
// Check that mac is in macs.
ASSERT_TRUE(std::find(macs.begin(), macs.end(), mac) != macs.end());
}
TEST_F(TestControlTest, MisMatchVerionServer) {
......@@ -1171,19 +1172,22 @@ TEST_F(TestControlTest, GenerateMacAddress) {
testMacAddress();
// Checks that the random mac address returned by generateMacAddress
// is in the list of mac addresses in the mac_list.txt data file
std::string mac_list_full_path = getFullPath("mac_list.txt");
// is in the list of mac addresses in the mac-list.txt data file
std::string mac_list_full_path = getFullPath("mac-list.txt");
std::ostringstream cmd;
cmd << "perfdhcp -M " << mac_list_full_path << " abc";
ASSERT_NO_THROW(processCmdLine(cmd.str()));
// Initialize Test Controller.
NakedTestControl tc;
uint8_t randomized = 0;
// Generate MAC adddress and sanity check its size.
std::vector<uint8_t> mac = tc.generateMacAddress(randomized);
ASSERT_EQ(6, mac.size());
// Make sure that the generated MAC address belongs to the MAC addresses
// read from a file.
CommandOptions& options = CommandOptions::instance();
vector<vector<uint8_t> > macs = options.getAllMacs();
// check that mac is in macs
ASSERT_NE(std::find(macs.begin(), macs.end(), mac), macs.end());
const CommandOptions::MacAddrsVector& macs = options.getMacsFromFile();
ASSERT_TRUE(std::find(macs.begin(), macs.end(), mac) != macs.end());
}
TEST_F(TestControlTest, Options4) {
......@@ -1404,6 +1408,9 @@ TEST_F(TestControlTest, Packet6) {
EXPECT_EQ(DHCP6_SERVER_PORT, pkt6->getRemotePort());
EXPECT_EQ(sock.addr_, pkt6->getLocalAddr());
EXPECT_EQ(asiolink::IOAddress("FF05::1:3"), pkt6->getRemoteAddr());
// Packet must not be relayed.
EXPECT_TRUE(pkt6->relay_info_.empty());
} else {
std::cout << "Unable to find the loopback interface. Skip test. "
<< std::endl;
......@@ -1434,7 +1441,7 @@ TEST_F(TestControlTest, Packet6Relayed) {
EXPECT_EQ(DHCP6_SERVER_PORT, pkt6->getRemotePort());
EXPECT_EQ(sock.addr_, pkt6->getLocalAddr());
EXPECT_EQ(asiolink::IOAddress("FF05::1:3"), pkt6->getRemoteAddr());
// check relay info
// Packet should be relayed.
EXPECT_EQ(pkt6->relay_info_.size(), 1);
EXPECT_EQ(pkt6->relay_info_[0].hop_count_, 1);
EXPECT_EQ(pkt6->relay_info_[0].msg_type_, DHCPV6_RELAY_FORW);
......
......@@ -2,4 +2,4 @@ SUBDIRS = .
EXTRA_DIST = discover-example.hex request4-example.hex
EXTRA_DIST += solicit-example.hex request6-example.hex
EXTRA_DIST += mac_list.txt
EXTRA_DIST += mac-list.txt
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