v6_relay_encapsulation_level_ = 0;
generateDuidTemplate();
extra_opts_.clear();
+ single_thread_mode_ = true;
}
bool
// In this section we collect argument values from command line
// they will be tuned and validated elsewhere
while((opt = getopt(argc, argv, "hv46A:r:t:R:b:n:p:d:D:l:P:a:L:M:"
- "s:iBc1T:X:O:o:E:S:I:x:W:w:e:f:F:")) != -1) {
+ "s:iBc1T:X:O:o:E:S:I:x:W:w:e:f:F:g")) != -1) {
stream << " -" << static_cast<char>(opt);
if (optarg) {
stream << " " << optarg;
xid_offset_.push_back(offset_arg);
break;
+ case 'g':
+ single_thread_mode_ = !single_thread_mode_;
+ break;
+
default:
isc_throw(isc::InvalidParameter, "unknown command line option");
}
if (!server_name_.empty()) {
std::cout << "server=" << server_name_ << std::endl;
}
+ if (single_thread_mode_) {
+ std::cout << "single-thread mode" << std::endl;
+ } else {
+ std::cout << "multi-thread mode" << std::endl;
+ }
}
void
" [-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"
+ " [-w<wrapped>] [-g] [server]\n"
"\n"
"The [server] argument is the name/address of the DHCP server to\n"
"contact. For DHCPv4 operation, exchanges are initiated by\n"
" with the exchange rate (given by -r<rate>). Furthermore the sum of\n"
" this value and the release-rate (given by -F<rate) must be equal\n"
" to or less than the exchange rate.\n"
+ "-g: Toggle between single and multi-thread modes (default is single).\n"
"-h: Print this help.\n"
"-i: Do only the initial part of an exchange: DO or SA, depending on\n"
" whether -6 is given.\n"
/// @return container with options
const isc::dhcp::OptionCollection& getExtraOpts() const { return extra_opts_; }
+ /// \brief Check if single-threaded mode is enabled.
+ ///
+ /// \return true if single-threaded mode is enabled.
+ bool isSingleThreaded() const { return single_thread_mode_; }
+
/// \brief Returns server name.
///
/// \return server name.
/// @brief Extra options to be sent in each packet.
isc::dhcp::OptionCollection extra_opts_;
+
+ /// @brief Option to switch modes between single and multi-threaded.
+ bool single_thread_mode_;
};
} // namespace perfdhcp
<arg choice="opt" rep="norepeat"><option>-E <replaceable class="parameter">time-offset</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-f <replaceable class="parameter">renew-rate</replaceable></option></arg>
<arg choice="opt" rep="norepeat"><option>-F <replaceable class="parameter">release-rate</replaceable></option></arg>
+ <arg choice="opt" rep="repeat"><option>-g</option></arg>
<arg choice="opt" rep="norepeat"><option>-h</option></arg>
<arg choice="opt" rep="norepeat"><option>-i</option></arg>
<arg choice="opt" rep="norepeat"><option>-I <replaceable class="parameter">ip-offset</replaceable></option></arg>
</varlistentry>
+ <varlistentry>
+ <term><option>-g</option></term>
+ <listitem>
+ <para>
+ Toggle between single and multi-thread modes (default
+ is single-thread mode).
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>-h</option></term>
<listitem>
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
+#include <util/threads/sync.h>
#include <exceptions/exceptions.h>
#include <boost/noncopyable.hpp>
if (!packet) {
isc_throw(BadValue, "Packet is null");
}
+ isc::util::thread::Mutex::Locker lock(mutex_);
++sent_packets_num_;
sent_packets_.template get<0>().push_back(packet);
}
if (!packet) {
isc_throw(BadValue, "Packet is null");
}
+ isc::util::thread::Mutex::Locker lock(mutex_);
rcvd_packets_.push_back(packet);
}
++ordered_lookups_;
packet_found = true;
} else {
+ isc::util::thread::Mutex::Locker lock(mutex_);
// If we are here, it means that we were unable to match the
// next incoming packet with next sent packet so we need to
// take a little more expensive approach to look packets using
// If packet was found, we assume it will be never searched
// again. We want to delete this packet from the list to
// improve performance of future searches.
+ isc::util::thread::Mutex::Locker lock(mutex_);
next_sent_ = eraseSent(next_sent_);
return(sent_packet);
}
/// sending queries.
void printSentStats() const {
using namespace std;
+ try {
+ if (getAvgSentDelay() == 0) {
+ return;
+ }
+ } catch (const Exception&) {
+ return;
+ }
try {
cout << fixed << setprecision(3)
<< "min sending delay: " << getMinSentDelay() * 1e3
/// \brief Erase packet from the list of sent packets.
///
/// Method erases packet from the list of sent packets.
+ /// Lock must be held by caller.
///
/// \param it iterator pointing to packet to be erased.
/// \return iterator pointing to packet following erased
/// packet or sent_packets_.end() if packet not found.
PktListIterator eraseSent(const PktListIterator it) {
- if (archive_enabled_) {
- // We don't want to keep list of all sent packets
- // because it will affect packet lookup performance.
- // If packet is matched with received packet we
- // move it to list of archived packets. List of
- // archived packets may be used for diagnostics
- // when test is completed.
- archived_packets_.push_back(*it);
- }
- // get<0>() template returns sequential index to
- // container.
- return(sent_packets_.template get<0>().erase(it));
+ if (archive_enabled_) {
+ // We don't want to keep list of all sent packets
+ // because it will affect packet lookup performance.
+ // If packet is matched with received packet we
+ // move it to list of archived packets. List of
+ // archived packets may be used for diagnostics
+ // when test is completed.
+ archived_packets_.push_back(*it);
+ }
+ // get<0>() template returns sequential index to
+ // container.
+ return(sent_packets_.template get<0>().erase(it));
}
ExchangeType xchg_type_; ///< Packet exchange type.
uint64_t sent_packets_num_; ///< Total number of sent packets.
uint64_t rcvd_packets_num_; ///< Total number of received packets.
boost::posix_time::ptime boot_time_; ///< Time when test is started.
+ isc::util::thread::Mutex mutex_; ///< Mutex for concurrent access.
};
/// Pointer to ExchangeStats.
using namespace isc;
using namespace isc::dhcp;
using namespace isc::asiolink;
+using namespace isc::util::thread;
namespace isc {
namespace perfdhcp {
reset();
}
+TestControl::~TestControl() {
+ reset();
+}
+
void
TestControl::checkLateMessages(RateControl& rate_control) {
// If diagnostics is disabled, there is no need to log late sent messages.
ptime now(microsec_clock::universal_time());
// Check that we haven't passed the moment to send the next set of
// packets.
- if (now >= basic_rate_control_.getDue() ||
+ if ((!sender_thread_ && now >= basic_rate_control_.getDue()) ||
(options.getRenewRate() != 0 && now >= renew_rate_control_.getDue()) ||
(options.getReleaseRate() != 0 &&
now >= release_rate_control_.getDue())) {
return (0);
}
+ ptime due = now + microseconds(100);
// Let's assume that the due time for Solicit is the soonest.
- ptime due = basic_rate_control_.getDue();
+ if (!sender_thread_) {
+ due = basic_rate_control_.getDue();
+ }
// If we are sending Renews and due time for Renew occurs sooner,
// set the due time to Renew due time.
if ((options.getRenewRate()) != 0 && (renew_rate_control_.getDue() < due)) {
if ((ret >= 0) && options.isInterface()) {
IfacePtr iface =
IfaceMgr::instance().getIface(options.getLocalName());
- if (iface == NULL) {
+ if (!iface) {
isc_throw(Unexpected, "unknown interface "
<< options.getLocalName());
}
}
void
-TestControl::sendPackets(const TestControlSocket& socket,
- const uint64_t packets_num,
+TestControl::sendPackets(const uint64_t packets_num,
const bool preload /* = false */) {
CommandOptions& options = CommandOptions::instance();
for (uint64_t i = packets_num; i > 0; --i) {
// No template packets means that no -T option was specified.
// We have to build packets ourselves.
if (template_buffers_.empty()) {
- sendDiscover4(socket, preload);
+ sendDiscover4(preload);
} else {
// @todo add defines for packet type index that can be
// used to access template_buffers_.
- sendDiscover4(socket, template_buffers_[0], preload);
+ sendDiscover4(template_buffers_[0], preload);
}
} else {
// No template packets means that no -T option was specified.
// We have to build packets ourselves.
if (template_buffers_.empty()) {
- sendSolicit6(socket, preload);
+ sendSolicit6(preload);
} else {
// @todo add defines for packet type index that can be
// used to access template_buffers_.
- sendSolicit6(socket, template_buffers_[0], preload);
+ sendSolicit6(template_buffers_[0], preload);
}
}
// If we preload server we don't want to receive any packets.
- if (!preload) {
- uint64_t latercvd = receivePackets(socket);
+ if (!preload && !sender_thread_) {
+ uint64_t latercvd = receivePackets();
if (testDiags('i')) {
if (options.getIpVersion() == 4) {
stats_mgr4_->incrementCounter("latercvd", latercvd);
}
uint64_t
-TestControl::sendMultipleRequests(const TestControlSocket& socket,
- const uint64_t msg_num) {
+TestControl::sendMultipleRequests(const uint64_t msg_num) {
for (uint64_t i = 0; i < msg_num; ++i) {
- if (!sendRequestFromAck(socket)) {
+ if (!sendRequestFromAck()) {
return (i);
}
}
}
uint64_t
-TestControl::sendMultipleMessages6(const TestControlSocket& socket,
- const uint32_t msg_type,
+TestControl::sendMultipleMessages6(const uint32_t msg_type,
const uint64_t msg_num) {
for (uint64_t i = 0; i < msg_num; ++i) {
- if (!sendMessageFromReply(msg_type, socket)) {
+ if (!sendMessageFromReply(msg_type)) {
return (i);
}
}
}
void
-TestControl::processReceivedPacket4(const TestControlSocket& socket,
- const Pkt4Ptr& pkt4) {
+TestControl::processReceivedPacket4(const Pkt4Ptr& pkt4) {
if (pkt4->getType() == DHCPOFFER) {
Pkt4Ptr discover_pkt4(stats_mgr4_->passRcvdPacket(StatsMgr4::XCHG_DO,
pkt4));
CommandOptions::instance().getExchangeMode();
if ((xchg_mode == CommandOptions::DORA_SARR) && discover_pkt4) {
if (template_buffers_.size() < 2) {
- sendRequest4(socket, discover_pkt4, pkt4);
+ sendRequest4(discover_pkt4, pkt4);
} else {
// @todo add defines for packet type index that can be
// used to access template_buffers_.
- sendRequest4(socket, template_buffers_[1], discover_pkt4, pkt4);
+ sendRequest4(template_buffers_[1], discover_pkt4, pkt4);
}
}
} else if (pkt4->getType() == DHCPACK) {
}
void
-TestControl::processReceivedPacket6(const TestControlSocket& socket,
- const Pkt6Ptr& pkt6) {
+TestControl::processReceivedPacket6(const Pkt6Ptr& pkt6) {
uint8_t packet_type = pkt6->getType();
if (packet_type == DHCPV6_ADVERTISE) {
Pkt6Ptr solicit_pkt6(stats_mgr6_->passRcvdPacket(StatsMgr6::XCHG_SA,
// We might want to check if STATUS_CODE option is non-zero
// and if there is IAADR option in IA_NA.
if (template_buffers_.size() < 2) {
- sendRequest6(socket, pkt6);
+ sendRequest6(pkt6);
} else {
// @todo add defines for packet type index that can be
// used to access template_buffers_.
- sendRequest6(socket, template_buffers_[1], pkt6);
+ sendRequest6(template_buffers_[1], pkt6);
}
}
} else if (packet_type == DHCPV6_REPLY) {
}
uint64_t
-TestControl::receivePackets(const TestControlSocket& socket) {
+TestControl::receivePackets() {
bool receiving = true;
uint64_t received = 0;
while (receiving) {
/// @todo: Add packet exception handling here. Right now any
/// malformed packet will cause perfdhcp to abort.
pkt4->unpack();
- processReceivedPacket4(socket, pkt4);
+ processReceivedPacket4(pkt4);
}
} else if (CommandOptions::instance().getIpVersion() == 6) {
Pkt6Ptr pkt6;
/// @todo: Add packet exception handling here. Right now any
/// malformed packet will cause perfdhcp to abort.
pkt6->unpack();
- processReceivedPacket6(socket, pkt6);
+ processReceivedPacket6(pkt6);
}
}
}
setMacAddrGenerator(NumberGeneratorPtr());
first_packet_serverid_.clear();
interrupted_ = false;
+
+ if (sender_thread_) {
+ if (sender_thread_->isRunning()) {
+ sender_thread_->stop();
+ }
+ sender_thread_.reset();
+ }
+ socket_.reset();
}
int
printDiagnostics();
// Option factories have to be registered.
registerOptionFactories();
- TestControlSocket socket(openSocket());
- if (!socket.valid_) {
+ socket_.reset(new TestControlSocket(openSocket()));
+ if (!socket_ || !socket_->valid_) {
isc_throw(Unexpected, "invalid socket descriptor");
}
// Initialize packet templates.
signal(SIGINT, TestControl::handleInterrupt);
// Preload server with the number of packets.
- sendPackets(socket, options.getPreload(), true);
+ sendPackets(options.getPreload(), true);
// Fork and run command specified with -w<wrapped-command>
if (!options.getWrapped().empty()) {
// Initialize Statistics Manager. Release previous if any.
initializeStatsMgr();
+
+ // Start sender thread
+ if (!options.isSingleThreaded()) {
+ sender_thread_.reset(new WatchedThread());
+ sender_thread_->start(boost::bind(&TestControl::runSender, this));
+ }
+
for (;;) {
// Calculate number of packets to be sent to stay
// catch up with rate.
- uint64_t packets_due = basic_rate_control_.getOutboundMessageCount();
- if (packets_due > 0) {
- checkLateMessages(basic_rate_control_);
- }
- if ((packets_due == 0) && testDiags('i')) {
- if (options.getIpVersion() == 4) {
- stats_mgr4_->incrementCounter("shortwait");
- } else if (options.getIpVersion() == 6) {
- stats_mgr6_->incrementCounter("shortwait");
+ uint64_t packets_due = 0;
+ if (!sender_thread_) {
+ packets_due = basic_rate_control_.getOutboundMessageCount();
+ if (packets_due > 0) {
+ checkLateMessages(basic_rate_control_);
+ }
+ if ((packets_due == 0) && testDiags('i')) {
+ if (options.getIpVersion() == 4) {
+ stats_mgr4_->incrementCounter("shortwait");
+ } else if (options.getIpVersion() == 6) {
+ stats_mgr6_->incrementCounter("shortwait");
+ }
}
}
// @todo: set non-zero timeout for packets once we implement
// microseconds timeout in IfaceMgr.
- receivePackets(socket);
+ receivePackets();
// If test period finished, maximum number of packet drops
// has been reached or test has been interrupted we have to
// finish the test.
if (checkExitConditions()) {
+ if (sender_thread_ && sender_thread_->isRunning()) {
+ sender_thread_->stop();
+ }
break;
}
if ((packets_due > 0) && !hasLateExitCommenced()) {
// Initiate new DHCP packet exchanges.
- sendPackets(socket, packets_due);
+ sendPackets(packets_due);
}
// If -f<renew-rate> option was specified we have to check how many
// Send multiple renews to satisfy the desired rate.
if (options.getIpVersion() == 4) {
- sendMultipleRequests(socket, renew_packets_due);
+ sendMultipleRequests(renew_packets_due);
} else {
- sendMultipleMessages6(socket, DHCPV6_RENEW, renew_packets_due);
+ sendMultipleMessages6(DHCPV6_RENEW, renew_packets_due);
}
}
checkLateMessages(release_rate_control_);
}
// Send Release messages.
- sendMultipleMessages6(socket, DHCPV6_RELEASE, release_packets_due);
+ sendMultipleMessages6(DHCPV6_RELEASE, release_packets_due);
}
// Report delay means that user requested printing number
} else if (options.getIpVersion() == 6) {
ret_code = stats_mgr6_->droppedPackets() ? 3 : 0;
}
+
+ // Do not wait object destruction.
+ reset();
return (ret_code);
}
+void
+TestControl::runSender() {
+ // Add terminate watch socket.
+ int fd = sender_thread_->getWatchFd(WatchedThread::READY);
+
+ for (;;) {
+ if (sender_thread_->shouldTerminate()) {
+ return;
+ }
+ uint64_t packets_due = basic_rate_control_.getOutboundMessageCount();
+ if (packets_due > 1) {
+ checkLateMessages(basic_rate_control_);
+ }
+ if (packets_due > 0) {
+ try {
+ sendPackets(packets_due);
+ } catch (const std::exception& ex) {
+ cerr << "sendPackets failed with " << ex.what() << endl;
+ }
+ continue;
+ }
+
+ // Wait for next due or terminate.
+ ptime now(microsec_clock::universal_time());
+ ptime due = basic_rate_control_.getDue();
+ if (now >= due) {
+ continue;
+ }
+ fd_set rdset;
+ FD_ZERO(&rdset);
+ FD_SET(fd, &rdset);
+ struct timeval select_timeout;
+ select_timeout.tv_sec = 0;
+ select_timeout.tv_usec =
+ time_period(now, due).length().total_microseconds();
+ (void) select(fd + 1, &rdset, NULL, NULL, &select_timeout);
+ }
+}
+
void
TestControl::runWrapped(bool do_stop /*= false */) const {
CommandOptions& options = CommandOptions::instance();
}
void
-TestControl::sendDiscover4(const TestControlSocket& socket,
- const bool preload /*= false*/) {
+TestControl::sendDiscover4(const bool preload /*= false*/) {
if (!preload) {
basic_rate_control_.updateSendTime();
}
// Set client's and server's ports as well as server's address,
// and local (relay) address.
- setDefaults4(socket, pkt4);
+ setDefaults4(pkt4);
// Set hardware address
pkt4->setHWAddr(HTYPE_ETHER, mac_address.size(), mac_address);
}
void
-TestControl::sendDiscover4(const TestControlSocket& socket,
- const std::vector<uint8_t>& template_buf,
+TestControl::sendDiscover4(const std::vector<uint8_t>& template_buf,
const bool preload /* = false */) {
if (!preload) {
basic_rate_control_.updateSendTime();
// Replace MAC address in the template with actual MAC address.
pkt4->writeAt(rand_offset, mac_address.begin(), mac_address.end());
// Create a packet from the temporary buffer.
- setDefaults4(socket, boost::static_pointer_cast<Pkt4>(pkt4));
+ setDefaults4(boost::static_pointer_cast<Pkt4>(pkt4));
// Pack the input packet buffer to output buffer so as it can
// be sent to server.
pkt4->rawPack();
}
bool
-TestControl::sendRequestFromAck(const TestControlSocket& socket) {
- // Update timestamp of last sent renewal.
+TestControl::sendRequestFromAck() {
+ // Update timestamps of last sent renewal.
+ renew_rate_control_.updateSendDue();
renew_rate_control_.updateSendTime();
// Get one of the recorded DHCPACK messages.
// Create message of the specified type.
Pkt4Ptr msg = createRequestFromAck(ack);
- setDefaults4(socket, msg);
+ setDefaults4(msg);
// Add any extra options that user may have specified.
addExtraOpts(msg);
"hasn't been initialized");
}
stats_mgr4_->passSentPacket(StatsMgr4::XCHG_RNA, msg);
+ stats_mgr4_->passSentTimes(StatsMgr4::XCHG_RNA,
+ renew_rate_control_.getDue(),
+ renew_rate_control_.getLast());
return (true);
}
bool
-TestControl::sendMessageFromReply(const uint16_t msg_type,
- const TestControlSocket& socket) {
+TestControl::sendMessageFromReply(const uint16_t msg_type) {
// We only permit Release or Renew messages to be sent using this function.
if (msg_type != DHCPV6_RENEW && msg_type != DHCPV6_RELEASE) {
isc_throw(isc::BadValue, "invalid message type " << msg_type
}
// We track the timestamp of last Release and Renew in different variables.
if (msg_type == DHCPV6_RENEW) {
+ renew_rate_control_.updateSendDue();
renew_rate_control_.updateSendTime();
} else {
+ release_rate_control_.updateSendDue();
release_rate_control_.updateSendTime();
}
Pkt6Ptr reply = reply_storage_.getRandom();
}
// Prepare the message of the specified type.
Pkt6Ptr msg = createMessageFromReply(msg_type, reply);
- setDefaults6(socket, msg);
+ setDefaults6(msg);
// Add any extra options that user may have specified.
addExtraOpts(msg);
isc_throw(Unexpected, "Statistics Manager for DHCPv6 "
"hasn't been initialized");
}
- stats_mgr6_->passSentPacket((msg_type == DHCPV6_RENEW ? StatsMgr6::XCHG_RN
- : StatsMgr6::XCHG_RL), msg);
+ if (msg_type == DHCPV6_RENEW) {
+ stats_mgr6_->passSentPacket(StatsMgr6::XCHG_RN, msg);
+ stats_mgr6_->passSentTimes(StatsMgr6::XCHG_RN,
+ renew_rate_control_.getDue(),
+ renew_rate_control_.getLast());
+ } else {
+ stats_mgr6_->passSentPacket(StatsMgr6::XCHG_RL, msg);
+ stats_mgr6_->passSentTimes(StatsMgr6::XCHG_RL,
+ release_rate_control_.getDue(),
+ release_rate_control_.getLast());
+ }
return (true);
}
void
-TestControl::sendRequest4(const TestControlSocket& socket,
- const dhcp::Pkt4Ptr& discover_pkt4,
+TestControl::sendRequest4(const dhcp::Pkt4Ptr& discover_pkt4,
const dhcp::Pkt4Ptr& offer_pkt4) {
// Use the same transaction id as the one used in the discovery packet.
const uint32_t transid = discover_pkt4->getTransid();
pkt4->addOption(opt_parameter_list);
// Set client's and server's ports as well as server's address,
// and local (relay) address.
- setDefaults4(socket, pkt4);
+ setDefaults4(pkt4);
// Add any extra options that user may have specified.
addExtraOpts(pkt4);
}
void
-TestControl::sendRequest4(const TestControlSocket& socket,
- const std::vector<uint8_t>& template_buf,
+TestControl::sendRequest4(const std::vector<uint8_t>& template_buf,
const dhcp::Pkt4Ptr& discover_pkt4,
const dhcp::Pkt4Ptr& offer_pkt4) {
// Get the second argument if multiple the same arguments specified
opt_requested_ip->setUint32(yiaddr.toUint32());
pkt4->addOption(opt_requested_ip);
- setDefaults4(socket, boost::static_pointer_cast<Pkt4>(pkt4));
+ setDefaults4(boost::static_pointer_cast<Pkt4>(pkt4));
// Add any extra options that user may have specified.
addExtraOpts(pkt4);
}
void
-TestControl::sendRequest6(const TestControlSocket& socket,
- const Pkt6Ptr& advertise_pkt6) {
+TestControl::sendRequest6(const Pkt6Ptr& advertise_pkt6) {
const uint32_t transid = generateTransid();
Pkt6Ptr pkt6(new Pkt6(DHCPV6_REQUEST, transid));
// Set elapsed time.
copyIaOptions(advertise_pkt6, pkt6);
// Set default packet data.
- setDefaults6(socket, pkt6);
+ setDefaults6(pkt6);
// Add any extra options that user may have specified.
addExtraOpts(pkt6);
}
void
-TestControl::sendRequest6(const TestControlSocket& socket,
- const std::vector<uint8_t>& template_buf,
+TestControl::sendRequest6(const std::vector<uint8_t>& template_buf,
const Pkt6Ptr& advertise_pkt6) {
// Get the second argument if multiple the same arguments specified
// in the command line. Second one refers to REQUEST packets.
rand_offset));
pkt6->addOption(opt_clientid);
// Set default packet data.
- setDefaults6(socket, pkt6);
+ setDefaults6(pkt6);
// Add any extra options that user may have specified.
addExtraOpts(pkt6);
}
void
-TestControl::sendSolicit6(const TestControlSocket& socket,
- const bool preload /*= false*/) {
+TestControl::sendSolicit6(const bool preload /*= false*/) {
if (!preload) {
basic_rate_control_.updateSendTime();
}
pkt6->addOption(Option::factory(Option::V6, D6O_IA_PD));
}
- setDefaults6(socket, pkt6);
+ setDefaults6(pkt6);
// Add any extra options that user may have specified.
addExtraOpts(pkt6);
}
void
-TestControl::sendSolicit6(const TestControlSocket& socket,
- const std::vector<uint8_t>& template_buf,
+TestControl::sendSolicit6(const std::vector<uint8_t>& template_buf,
const bool preload /*= false*/) {
if (!preload) {
basic_rate_control_.updateSendTime();
// Prepare on-wire data.
pkt6->rawPack();
- setDefaults6(socket, pkt6);
+ setDefaults6(pkt6);
// Add any extra options that user may have specified.
addExtraOpts(pkt6);
void
-TestControl::setDefaults4(const TestControlSocket& socket,
- const Pkt4Ptr& pkt) {
+TestControl::setDefaults4(const Pkt4Ptr& pkt) {
CommandOptions& options = CommandOptions::instance();
+ if (!socket_) {
+ isc_throw(BadValue, "NULL socket");
+ }
// Interface name.
- IfacePtr iface = IfaceMgr::instance().getIface(socket.ifindex_);
- if (iface == NULL) {
+ IfacePtr iface = IfaceMgr::instance().getIface(socket_->ifindex_);
+ if (!iface) {
isc_throw(BadValue, "unable to find interface with given index");
}
pkt->setIface(iface->getName());
// Interface index.
- pkt->setIndex(socket.ifindex_);
+ pkt->setIndex(socket_->ifindex_);
// Local client's port (68)
pkt->setLocalPort(DHCP4_CLIENT_PORT);
// Server's port (67)
// The remote server's name or IP.
pkt->setRemoteAddr(IOAddress(options.getServerName()));
// Set local address.
- pkt->setLocalAddr(IOAddress(socket.addr_));
+ pkt->setLocalAddr(IOAddress(socket_->addr_));
// Set relay (GIADDR) address to local address.
- pkt->setGiaddr(IOAddress(socket.addr_));
+ pkt->setGiaddr(IOAddress(socket_->addr_));
// Pretend that we have one relay (which is us).
pkt->setHops(1);
}
void
-TestControl::setDefaults6(const TestControlSocket& socket,
- const Pkt6Ptr& pkt) {
+TestControl::setDefaults6(const Pkt6Ptr& pkt) {
CommandOptions& options = CommandOptions::instance();
+ if (!socket_) {
+ isc_throw(BadValue, "NULL socket");
+ }
// Interface name.
- IfacePtr iface = IfaceMgr::instance().getIface(socket.ifindex_);
- if (iface == NULL) {
+ IfacePtr iface = IfaceMgr::instance().getIface(socket_->ifindex_);
+ if (!iface) {
isc_throw(BadValue, "unable to find interface with given index");
}
pkt->setIface(iface->getName());
// Interface index.
- pkt->setIndex(socket.ifindex_);
+ pkt->setIndex(socket_->ifindex_);
// Local client's port (547)
pkt->setLocalPort(DHCP6_CLIENT_PORT);
// Server's port (548)
pkt->setRemotePort(DHCP6_SERVER_PORT);
// Set local address.
- pkt->setLocalAddr(socket.addr_);
+ pkt->setLocalAddr(socket_->addr_);
// The remote server's name or IP.
pkt->setRemoteAddr(IOAddress(options.getServerName()));
Pkt6::RelayInfo relay_info;
relay_info.msg_type_ = DHCPV6_RELAY_FORW;
relay_info.hop_count_ = 1;
- relay_info.linkaddr_ = IOAddress(socket.addr_);
- relay_info.peeraddr_ = IOAddress(socket.addr_);
+ relay_info.linkaddr_ = IOAddress(socket_->addr_);
+ relay_info.peeraddr_ = IOAddress(socket_->addr_);
pkt->addRelayInfo(relay_info);
}
}
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
#include <util/random/random_number_generator.h>
+#include <util/threads/watched_thread.h>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
/// \return the only existing instance of test control
static TestControl& instance();
- /// brief\ Run performance test.
+ /// \brief Run performance test.
///
/// Method runs whole performance test. Command line options must
/// be parsed prior to running this function. Otherwise function will
/// to number of sent packets, 0 if everything is ok.
int run();
+ /// \brief Run sender thread.
+ ///
+ /// The sender thread runs this method which sends at the wanted rate
+ /// solicits or advertises.
+ void runSender();
+
/// \brief Set new transaction id generator.
///
/// \param generator generator object to be used.
/// only via \ref instance method.
TestControl();
+ /// \brief Destructor.
+ ///
+ /// Call reset() for cleanup.
+ virtual ~TestControl();
+
/// Generate uniformly distributed integers in range of [min, max]
isc::util::random::UniformRandomIntegerGenerator number_generator_;
/// \param type option-type (ignored).
/// \param buf option-buffer (ignored).
/// \return instance o the generic option.
- static dhcp::OptionPtr factoryRequestList4(dhcp::Option::Universe u,
+ static dhcp::OptionPtr factoryRequestList4(dhcp::Option::Universe u,
uint16_t type,
const dhcp::OptionBuffer& buf);
/// \warning this method does not check if provided socket is
/// valid (specifically if v4 socket for received v4 packet).
///
- /// \param [in] socket socket to be used.
/// \param [in] pkt4 object representing DHCPv4 packet received.
/// \throw isc::BadValue if unknown message type received.
/// \throw isc::Unexpected if unexpected error occurred.
- void processReceivedPacket4(const TestControlSocket& socket,
- const dhcp::Pkt4Ptr& pkt4);
+ void processReceivedPacket4(const dhcp::Pkt4Ptr& pkt4);
/// \brief Process received DHCPv6 packet.
///
/// \warning this method does not check if provided socket is
/// valid (specifically if v4 socket for received v4 packet).
///
- /// \param [in] socket socket to be used.
/// \param [in] pkt6 object representing DHCPv6 packet received.
/// \throw isc::BadValue if unknown message type received.
/// \throw isc::Unexpected if unexpected error occurred.
- void processReceivedPacket6(const TestControlSocket& socket,
- const dhcp::Pkt6Ptr& pkt6);
+ void processReceivedPacket6(const dhcp::Pkt6Ptr& pkt6);
/// \brief Receive DHCPv4 or DHCPv6 packets from the server.
///
/// \warning this method does not check if provided socket is
/// valid. Ensure that it is valid prior to calling it.
///
- /// \param socket socket to be used.
/// \throw isc::BadValue if unknown message type received.
/// \throw isc::Unexpected if unexpected error occurred.
/// \return number of received packets.
- uint64_t receivePackets(const TestControlSocket& socket);
+ uint64_t receivePackets();
/// \brief Register option factory functions for DHCPv4
///
/// Copy of sent packet is stored in the stats_mgr4_ object to
/// update statistics.
///
- /// \param socket socket to be used to send the message.
/// \param preload preload mode, packets not included in statistics.
///
/// \throw isc::Unexpected if failed to create new packet instance.
/// \throw isc::BadValue if MAC address has invalid length.
/// \throw isc::dhcp::SocketWriteError if failed to send the packet.
- void sendDiscover4(const TestControlSocket& socket,
- const bool preload = false);
+ void sendDiscover4(const bool preload = false);
/// \brief Send DHCPv4 DISCOVER message from template.
///
/// Copy of sent packet is stored in the stats_mgr4_ object to
/// update statistics.
///
- /// \param socket socket to be used to send the message.
/// \param template_buf buffer holding template packet.
/// \param preload preload mode, packets not included in statistics.
///
/// \throw isc::OutOfRange if randomization offset is out of bounds.
/// \throw isc::dhcp::SocketWriteError if failed to send the packet.
- void sendDiscover4(const TestControlSocket& socket,
- const std::vector<uint8_t>& template_buf,
+ void sendDiscover4(const std::vector<uint8_t>& template_buf,
const bool preload = false);
/// \brief Send number of packets to initiate new exchanges.
///
/// \todo do not count responses in preload mode as orphans.
///
- /// \param socket socket to be used to send packets.
/// \param packets_num number of packets to be sent.
/// \param preload preload mode, packets not included in statistics.
/// \throw isc::Unexpected if thrown by packet sending method.
/// \throw isc::InvalidOperation if thrown by packet sending method.
/// \throw isc::OutOfRange if thrown by packet sending method.
- void sendPackets(const TestControlSocket &socket,
- const uint64_t packets_num,
- const bool preload = false);
+ void sendPackets(const uint64_t packets_num, const bool preload = false);
/// \brief Send number of DHCPREQUEST (renew) messages to a server.
///
- /// \param socket An object representing socket to be used to send packets.
/// \param msg_num A number of messages to be sent.
///
/// \return A number of messages actually sent.
- uint64_t sendMultipleRequests(const TestControlSocket& socket,
- const uint64_t msg_num);
+ uint64_t sendMultipleRequests(const uint64_t msg_num);
/// \brief Send number of DHCPv6 Renew or Release messages to the server.
///
- /// \param socket An object representing socket to be used to send packets.
/// \param msg_type A type of the messages to be sent (DHCPV6_RENEW or
/// DHCPV6_RELEASE).
/// \param msg_num A number of messages to be sent.
///
/// \return A number of messages actually sent.
- uint64_t sendMultipleMessages6(const TestControlSocket& socket,
- const uint32_t msg_type,
+ uint64_t sendMultipleMessages6(const uint32_t msg_type,
const uint64_t msg_num);
/// \brief Send DHCPv4 renew (DHCPREQUEST) using specified socket.
///
- /// \param socket An object encapsulating socket to be used to send
- /// a packet.
- ///
/// \return true if the message has been sent, false otherwise.
- bool sendRequestFromAck(const TestControlSocket& socket);
+ bool sendRequestFromAck();
/// \brief Send DHCPv6 Renew or Release message using specified socket.
///
///
/// \param msg_type A type of the message to be sent (DHCPV6_RENEW or
/// DHCPV6_RELEASE).
- /// \param socket An object encapsulating socket to be used to send
- /// a packet.
///
/// \return true if the message has been sent, false otherwise.
- bool sendMessageFromReply(const uint16_t msg_type,
- const TestControlSocket& socket);
+ bool sendMessageFromReply(const uint16_t msg_type);
/// \brief Send DHCPv4 REQUEST message.
///
/// Copy of sent packet is stored in the stats_mgr4_ object to
/// update statistics.
///
- /// \param socket socket to be used to send message.
/// \param discover_pkt4 DISCOVER packet sent.
/// \param offer_pkt4 OFFER packet object.
///
/// \throw isc::InvalidOperation if Statistics Manager has not been
/// initialized.
/// \throw isc::dhcp::SocketWriteError if failed to send the packet.
- void sendRequest4(const TestControlSocket& socket,
- const dhcp::Pkt4Ptr& discover_pkt4,
+ void sendRequest4(const dhcp::Pkt4Ptr& discover_pkt4,
const dhcp::Pkt4Ptr& offer_pkt4);
/// \brief Send DHCPv4 REQUEST message from template.
/// Copy of sent packet is stored in the stats_mgr4_ object to
/// update statistics.
///
- /// \param socket socket to be used to send message.
/// \param template_buf buffer holding template packet.
/// \param discover_pkt4 DISCOVER packet sent.
/// \param offer_pkt4 OFFER packet received.
///
/// \throw isc::dhcp::SocketWriteError if failed to send the packet.
- void sendRequest4(const TestControlSocket& socket,
- const std::vector<uint8_t>& template_buf,
+ void sendRequest4(const std::vector<uint8_t>& template_buf,
const dhcp::Pkt4Ptr& discover_pkt4,
const dhcp::Pkt4Ptr& offer_pkt4);
/// Copy of sent packet is stored in the stats_mgr6_ object to
/// update statistics.
///
- /// \param socket socket to be used to send message.
/// \param advertise_pkt6 ADVERTISE packet object.
/// \throw isc::Unexpected if unexpected error occurred.
/// \throw isc::InvalidOperation if Statistics Manager has not been
/// initialized.
///
/// \throw isc::dhcp::SocketWriteError if failed to send the packet.
- void sendRequest6(const TestControlSocket& socket,
- const dhcp::Pkt6Ptr& advertise_pkt6);
+ void sendRequest6(const dhcp::Pkt6Ptr& advertise_pkt6);
/// \brief Send DHCPv6 REQUEST message from template.
///
/// Copy of sent packet is stored in the stats_mgr6_ object to
/// update statistics.
///
- /// \param socket socket to be used to send message.
/// \param template_buf packet template buffer.
/// \param advertise_pkt6 ADVERTISE packet object.
///
/// \throw isc::dhcp::SocketWriteError if failed to send the packet.
- void sendRequest6(const TestControlSocket& socket,
- const std::vector<uint8_t>& template_buf,
+ void sendRequest6(const std::vector<uint8_t>& template_buf,
const dhcp::Pkt6Ptr& advertise_pkt6);
/// \brief Send DHCPv6 SOLICIT message.
/// Copy of sent packet is stored in the stats_mgr6_ object to
/// update statistics.
///
- /// \param socket socket to be used to send the message.
/// \param preload mode, packets not included in statistics.
///
/// \throw isc::Unexpected if failed to create new packet instance.
/// \throw isc::dhcp::SocketWriteError if failed to send the packet.
- void sendSolicit6(const TestControlSocket& socket,
- const bool preload = false);
+ void sendSolicit6(const bool preload = false);
/// \brief Send DHCPv6 SOLICIT message from template.
///
/// Copy of sent packet is stored in the stats_mgr6_ object to
/// update statistics.
///
- /// \param socket socket to be used to send the message.
/// \param template_buf packet template buffer.
/// \param preload mode, packets not included in statistics.
///
/// \throw isc::dhcp::SocketWriteError if failed to send the packet.
- void sendSolicit6(const TestControlSocket& socket,
- const std::vector<uint8_t>& template_buf,
+ void sendSolicit6(const std::vector<uint8_t>& template_buf,
const bool preload = false);
/// \brief Set default DHCPv4 packet parameters.
/// - GIADDR = local address where socket is bound to,
/// - hops = 1 (pretending that we are a relay)
///
- /// \param socket socket used to send the packet.
/// \param pkt reference to packet to be configured.
- void setDefaults4(const TestControlSocket& socket,
- const dhcp::Pkt4Ptr& pkt);
+ void setDefaults4(const dhcp::Pkt4Ptr& pkt);
/// \brief Set default DHCPv6 packet parameters.
///
/// - local address,
/// - remote address (server).
///
- /// \param socket socket used to send the packet.
/// \param pkt reference to packet to be configured.
- void setDefaults6(const TestControlSocket& socket,
- const dhcp::Pkt6Ptr& pkt);
+ void setDefaults6(const dhcp::Pkt6Ptr& pkt);
/// @brief Inserts extra options specified by user.
///
std::map<uint8_t, dhcp::Pkt6Ptr> template_packets_v6_;
static bool interrupted_; ///< Is program interrupted.
+
+ boost::shared_ptr<TestControlSocket> socket_; ///< Socket object.
+
+ util::thread::WatchedThreadPtr sender_thread_; ///< Sender watched thread.
};
} // namespace perfdhcp
using TestControl::template_packets_v6_;
using TestControl::ack_storage_;
using TestControl::sendRequestFromAck;
+ using TestControl::socket_;
NakedTestControl() : TestControl() {
uint32_t clients_num = CommandOptions::instance().getClientsNum() == 0 ?
generator(new NakedTestControl::IncrementalGenerator());
tc.setTransidGenerator(generator);
// Socket is needed to send packets through the interface.
+ ASSERT_NO_THROW(tc.socket_.reset());
ASSERT_NO_THROW(sock_handle = tc.openSocket());
- TestControl::TestControlSocket sock(sock_handle);
+ tc.socket_.reset(new TestControl::TestControlSocket(sock_handle));
for (int i = 0; i < iterations_num; ++i) {
// Get next transaction id, without actually using it. The same
// id wll be used by the TestControl class for DHCPDISCOVER.
uint32_t transid = generator->getNext();
if (use_templates) {
- ASSERT_NO_THROW(tc.sendDiscover4(sock, tc.getTemplateBuffer(0)));
+ ASSERT_NO_THROW(tc.sendDiscover4(tc.getTemplateBuffer(0)));
} else {
- ASSERT_NO_THROW(tc.sendDiscover4(sock));
+ ASSERT_NO_THROW(tc.sendDiscover4());
}
// Do not simulate responses for packets later
// packet drops.
if (i < receive_num) {
boost::shared_ptr<Pkt4> offer_pkt4(createOfferPkt4(transid));
- ASSERT_NO_THROW(tc.processReceivedPacket4(sock, offer_pkt4));
+ ASSERT_NO_THROW(tc.processReceivedPacket4(offer_pkt4));
}
if (tc.checkExitConditions()) {
iterations_performed = i + 1;
generator(new NakedTestControl::IncrementalGenerator());
tc.setTransidGenerator(generator);
// Socket is needed to send packets through the interface.
+ ASSERT_NO_THROW(tc.socket_.reset());
ASSERT_NO_THROW(sock_handle = tc.openSocket());
- TestControl::TestControlSocket sock(sock_handle);
+ tc.socket_.reset(new TestControl::TestControlSocket(sock_handle));
uint32_t transid = 0;
for (int i = 0; i < iterations_num; ++i) {
// Do not simulate responses for packets later
// that specified as receive_num. This simulates
// packet drops.
if (use_templates) {
- ASSERT_NO_THROW(tc.sendSolicit6(sock, tc.getTemplateBuffer(0)));
+ ASSERT_NO_THROW(tc.sendSolicit6(tc.getTemplateBuffer(0)));
} else {
- ASSERT_NO_THROW(tc.sendSolicit6(sock));
+ ASSERT_NO_THROW(tc.sendSolicit6());
}
++transid;
if (i < receive_num) {
boost::shared_ptr<Pkt6>
advertise_pkt6(createAdvertisePkt6(transid));
// Receive ADVERTISE and send REQUEST.
- ASSERT_NO_THROW(tc.processReceivedPacket6(sock,
- advertise_pkt6));
+ ASSERT_NO_THROW(tc.processReceivedPacket6(advertise_pkt6));
++transid;
}
if (tc.checkExitConditions()) {
// Socket has to be created so as we can actually send packets.
int sock_handle = 0;
ASSERT_NO_THROW(sock_handle = tc.openSocket());
- TestControl::TestControlSocket sock(sock_handle);
+ tc.socket_.reset(new TestControl::TestControlSocket(sock_handle));
// Send a number of DHCPDISCOVER messages. Each generated message will
// be assigned a different transaction id, starting from 1 to 10.
- tc.sendPackets(sock, 10);
+ tc.sendPackets(10);
// Simulate DHCPOFFER responses from the server. Each DHCPOFFER is
// assigned a transaction id from the range of 1 to 10, so as they
// will trigger a corresponding DHCPREQUEST. They will be assigned
// transaction ids from the range from 11 to 20 (the range of
// 1 to 10 has been used by DHCPDISCOVER-DHCPOFFER).
- ASSERT_NO_THROW(tc.processReceivedPacket4(sock, offer));
+ ASSERT_NO_THROW(tc.processReceivedPacket4(offer));
}
// Requests have been sent, so now let's simulate responses from the
// -f<renew-rate> option has been specified, received Reply
// messages are held so as renew messages can be sent for
// existing leases.
- ASSERT_NO_THROW(tc.processReceivedPacket4(sock, ack));
+ ASSERT_NO_THROW(tc.processReceivedPacket4(ack));
}
uint64_t msg_num;
// DHCPREQUEST messages has been received. For each of them we
// should be able to send renewal.
ASSERT_NO_THROW(
- msg_num = tc.sendMultipleRequests(sock, 5)
+ msg_num = tc.sendMultipleRequests(5)
);
// Make sure that we have sent 5 messages.
EXPECT_EQ(5, msg_num);
// Try to do it again. We should still have 5 Reply packets for
// which renews haven't been sent yet.
ASSERT_NO_THROW(
- msg_num = tc.sendMultipleRequests(sock, 5)
+ msg_num = tc.sendMultipleRequests(5)
);
EXPECT_EQ(5, msg_num);
// them already). Therefore, no further renew messages should be sent
// before we acquire new leases.
ASSERT_NO_THROW(
- msg_num = tc.sendMultipleRequests(sock, 5)
+ msg_num = tc.sendMultipleRequests(5)
);
// Make sure that no message has been sent.
EXPECT_EQ(0, msg_num);
// Socket has to be created so as we can actually send packets.
int sock_handle = 0;
ASSERT_NO_THROW(sock_handle = tc.openSocket());
- TestControl::TestControlSocket sock(sock_handle);
+ tc.socket_.reset(new TestControl::TestControlSocket(sock_handle));
// Send a number of Solicit messages. Each generated Solicit will be
// assigned a different transaction id, starting from 1 to 10.
- tc.sendPackets(sock, 10);
+ tc.sendPackets(10);
// Simulate Advertise responses from the server. Each advertise is
// assigned a transaction id from the range of 1 to 10, so as they
// trigger a corresponding Request. They will be assigned
// transaction ids from the range from 11 to 20 (the range of
// 1 to 10 has been used by Solicit-Advertise).
- ASSERT_NO_THROW(tc.processReceivedPacket6(sock, advertise));
+ ASSERT_NO_THROW(tc.processReceivedPacket6(advertise));
}
// Requests have been sent, so now let's simulate responses from the
// -f<renew-rate> option has been specified, received Reply
// messages are held so as Renew messages can be sent for
// existing leases.
- ASSERT_NO_THROW(tc.processReceivedPacket6(sock, reply));
+ ASSERT_NO_THROW(tc.processReceivedPacket6(reply));
}
uint64_t msg_num;
// messages has been received. For each of them we should be able to
// send Renew or Release.
ASSERT_NO_THROW(
- msg_num = tc.sendMultipleMessages6(sock, msg_type, 5)
+ msg_num = tc.sendMultipleMessages6(msg_type, 5)
);
// Make sure that we have sent 5 messages.
EXPECT_EQ(5, msg_num);
// Try to do it again. We should still have 5 Reply packets for
// which Renews or Releases haven't been sent yet.
ASSERT_NO_THROW(
- msg_num = tc.sendMultipleMessages6(sock, msg_type, 5)
+ msg_num = tc.sendMultipleMessages6(msg_type, 5)
);
EXPECT_EQ(5, msg_num);
// them already). Therefore, no further Renew or Release messages should
// be sent before we acquire new leases.
ASSERT_NO_THROW(
- msg_num = tc.sendMultipleMessages6(sock, msg_type, 5)
+ msg_num = tc.sendMultipleMessages6(msg_type, 5)
);
// Make sure that no message has been sent.
EXPECT_EQ(0, msg_num);
// We have to create the socket to setup some parameters of
// outgoing packet.
ASSERT_NO_THROW(sock_handle = tc.openSocket());
- TestControl::TestControlSocket sock(sock_handle);
+ tc.socket_.reset(new TestControl::TestControlSocket(sock_handle));
uint32_t transid = 123;
boost::shared_ptr<Pkt4> pkt4(new Pkt4(DHCPDISCOVER, transid));
// Set parameters on outgoing packet.
- ASSERT_NO_THROW(tc.setDefaults4(sock, pkt4));
+ ASSERT_NO_THROW(tc.setDefaults4(pkt4));
// Validate that packet has been setup correctly.
EXPECT_EQ(loopback_iface, pkt4->getIface());
- EXPECT_EQ(sock.ifindex_, pkt4->getIndex());
+ EXPECT_EQ(tc.socket_->ifindex_, pkt4->getIndex());
EXPECT_EQ(DHCP4_CLIENT_PORT, pkt4->getLocalPort());
EXPECT_EQ(DHCP4_SERVER_PORT, pkt4->getRemotePort());
EXPECT_EQ(1, pkt4->getHops());
EXPECT_EQ(asiolink::IOAddress("255.255.255.255"),
pkt4->getRemoteAddr());
- EXPECT_EQ(asiolink::IOAddress(sock.addr_), pkt4->getLocalAddr());
- EXPECT_EQ(asiolink::IOAddress(sock.addr_), pkt4->getGiaddr());
+ EXPECT_EQ(asiolink::IOAddress(tc.socket_->addr_),
+ pkt4->getLocalAddr());
+ EXPECT_EQ(asiolink::IOAddress(tc.socket_->addr_), pkt4->getGiaddr());
} else {
std::cout << "Unable to find the loopback interface. Skip test. "
<< std::endl;
// Create the socket. It will be needed to set packet's
// parameters.
ASSERT_NO_THROW(sock_handle = tc.openSocket());
- TestControl::TestControlSocket sock(sock_handle);
+ tc.socket_.reset(new TestControl::TestControlSocket(sock_handle));
uint32_t transid = 123;
boost::shared_ptr<Pkt6> pkt6(new Pkt6(DHCPV6_SOLICIT, transid));
// Set packet's parameters.
- ASSERT_NO_THROW(tc.setDefaults6(sock, pkt6));
+ ASSERT_NO_THROW(tc.setDefaults6(pkt6));
// Validate if parameters have been set correctly.
EXPECT_EQ(loopback_iface, pkt6->getIface());
- EXPECT_EQ(sock.ifindex_, pkt6->getIndex());
+ EXPECT_EQ(tc.socket_->ifindex_, pkt6->getIndex());
EXPECT_EQ(DHCP6_CLIENT_PORT, pkt6->getLocalPort());
EXPECT_EQ(DHCP6_SERVER_PORT, pkt6->getRemotePort());
- EXPECT_EQ(sock.addr_, pkt6->getLocalAddr());
+ EXPECT_EQ(tc.socket_->addr_, pkt6->getLocalAddr());
EXPECT_EQ(asiolink::IOAddress("FF05::1:3"), pkt6->getRemoteAddr());
// Packet must not be relayed.
EXPECT_TRUE(pkt6->relay_info_.empty());
// Create the socket. It will be needed to set packet's
// parameters.
ASSERT_NO_THROW(sock_handle = tc.openSocket());
- TestControl::TestControlSocket sock(sock_handle);
+ tc.socket_.reset(new TestControl::TestControlSocket(sock_handle));
uint32_t transid = 123;
boost::shared_ptr<Pkt6> pkt6(new Pkt6(DHCPV6_SOLICIT, transid));
// Set packet's parameters.
- ASSERT_NO_THROW(tc.setDefaults6(sock, pkt6));
+ ASSERT_NO_THROW(tc.setDefaults6(pkt6));
// Validate if parameters have been set correctly.
EXPECT_EQ(loopback_iface, pkt6->getIface());
- EXPECT_EQ(sock.ifindex_, pkt6->getIndex());
+ EXPECT_EQ(tc.socket_->ifindex_, pkt6->getIndex());
EXPECT_EQ(DHCP6_CLIENT_PORT, pkt6->getLocalPort());
EXPECT_EQ(DHCP6_SERVER_PORT, pkt6->getRemotePort());
- EXPECT_EQ(sock.addr_, pkt6->getLocalAddr());
+ EXPECT_EQ(tc.socket_->addr_, pkt6->getLocalAddr());
EXPECT_EQ(asiolink::IOAddress("FF05::1:3"), pkt6->getRemoteAddr());
// 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);
- EXPECT_EQ(pkt6->relay_info_[0].linkaddr_, sock.addr_);
- EXPECT_EQ(pkt6->relay_info_[0].peeraddr_, sock.addr_);
+ EXPECT_EQ(pkt6->relay_info_[0].linkaddr_, tc.socket_->addr_);
+ EXPECT_EQ(pkt6->relay_info_[0].peeraddr_, tc.socket_->addr_);
} else {
std::cout << "Unable to find the loopback interface. Skip test. "
<< std::endl;
// Socket is needed to send packets through the interface.
int sock_handle = 0;
ASSERT_NO_THROW(sock_handle = tc.openSocket());
- TestControl::TestControlSocket sock(sock_handle);
+ tc.socket_.reset(new TestControl::TestControlSocket(sock_handle));
// Make tc send the packet. The first packet of each type is saved in templates.
- ASSERT_NO_THROW(tc.sendDiscover4(sock));
+ ASSERT_NO_THROW(tc.sendDiscover4());
// Let's find the packet and see if it includes the right option.
auto pkt_it = tc.template_packets_v4_.find(DHCPDISCOVER);