From: Francis Dupont Date: Fri, 14 Dec 2018 09:28:24 +0000 (+0100) Subject: [283-perfdhcp-sending-thread] Added sender thread X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1aa999ea736b03f8f61e1318777002a621aedc10;p=thirdparty%2Fkea.git [283-perfdhcp-sending-thread] Added sender thread --- diff --git a/src/bin/perfdhcp/command_options.cc b/src/bin/perfdhcp/command_options.cc index d264248236..a4ac684b14 100644 --- a/src/bin/perfdhcp/command_options.cc +++ b/src/bin/perfdhcp/command_options.cc @@ -155,6 +155,7 @@ CommandOptions::reset() { v6_relay_encapsulation_level_ = 0; generateDuidTemplate(); extra_opts_.clear(); + single_thread_mode_ = true; } bool @@ -222,7 +223,7 @@ CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) { // 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(opt); if (optarg) { stream << " " << optarg; @@ -522,6 +523,10 @@ CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) { 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"); } @@ -1016,6 +1021,11 @@ CommandOptions::printCommandLine() const { 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 @@ -1031,7 +1041,7 @@ CommandOptions::usage() const { " [-c] [-1] [-M] [-T]\n" " [-X] [-O]\n" " [-S] [-I] [-x]\n" - " [-w] [server]\n" + " [-w] [-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" @@ -1079,6 +1089,7 @@ CommandOptions::usage() const { " with the exchange rate (given by -r). Furthermore the sum of\n" " this value and the release-rate (given by -F + @@ -346,6 +347,16 @@ + + + + + Toggle between single and multi-thread modes (default + is single-thread mode). + + + + diff --git a/src/bin/perfdhcp/stats_mgr.h b/src/bin/perfdhcp/stats_mgr.h index 371e4cc4b2..fe3b790a2b 100644 --- a/src/bin/perfdhcp/stats_mgr.h +++ b/src/bin/perfdhcp/stats_mgr.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -306,6 +307,7 @@ public: 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); } @@ -320,6 +322,7 @@ public: if (!packet) { isc_throw(BadValue, "Packet is null"); } + isc::util::thread::Mutex::Locker lock(mutex_); rcvd_packets_.push_back(packet); } @@ -467,6 +470,7 @@ public: ++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 @@ -575,6 +579,7 @@ public: // 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); } @@ -790,6 +795,13 @@ public: /// 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 @@ -907,23 +919,24 @@ public: /// \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. @@ -991,6 +1004,7 @@ public: 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. diff --git a/src/bin/perfdhcp/test_control.cc b/src/bin/perfdhcp/test_control.cc index 972eaec5b8..6acf235a4d 100644 --- a/src/bin/perfdhcp/test_control.cc +++ b/src/bin/perfdhcp/test_control.cc @@ -36,6 +36,7 @@ using namespace boost::posix_time; using namespace isc; using namespace isc::dhcp; using namespace isc::asiolink; +using namespace isc::util::thread; namespace isc { namespace perfdhcp { @@ -143,6 +144,10 @@ TestControl::TestControl() reset(); } +TestControl::~TestControl() { + reset(); +} + void TestControl::checkLateMessages(RateControl& rate_control) { // If diagnostics is disabled, there is no need to log late sent messages. @@ -641,15 +646,18 @@ TestControl::getCurrentTimeout() const { 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)) { @@ -916,7 +924,7 @@ TestControl::openSocket() const { if ((ret >= 0) && options.isInterface()) { IfacePtr iface = IfaceMgr::instance().getIface(options.getLocalName()); - if (iface == NULL) { + if (!iface) { isc_throw(Unexpected, "unknown interface " << options.getLocalName()); } @@ -936,8 +944,7 @@ TestControl::openSocket() const { } 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) { @@ -949,26 +956,26 @@ TestControl::sendPackets(const TestControlSocket& socket, // 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); @@ -981,10 +988,9 @@ TestControl::sendPackets(const TestControlSocket& socket, } 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); } } @@ -992,11 +998,10 @@ TestControl::sendMultipleRequests(const TestControlSocket& socket, } 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); } } @@ -1230,8 +1235,7 @@ TestControl::readPacketTemplate(const std::string& file_name) { } 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)); @@ -1239,11 +1243,11 @@ TestControl::processReceivedPacket4(const TestControlSocket& socket, 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) { @@ -1273,8 +1277,7 @@ TestControl::processReceivedPacket4(const TestControlSocket& socket, } 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, @@ -1286,11 +1289,11 @@ TestControl::processReceivedPacket6(const TestControlSocket& socket, // 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) { @@ -1329,7 +1332,7 @@ TestControl::processReceivedPacket6(const TestControlSocket& socket, } uint64_t -TestControl::receivePackets(const TestControlSocket& socket) { +TestControl::receivePackets() { bool receiving = true; uint64_t received = 0; while (receiving) { @@ -1352,7 +1355,7 @@ TestControl::receivePackets(const TestControlSocket& socket) { /// @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; @@ -1373,7 +1376,7 @@ TestControl::receivePackets(const TestControlSocket& socket) { /// @todo: Add packet exception handling here. Right now any /// malformed packet will cause perfdhcp to abort. pkt6->unpack(); - processReceivedPacket6(socket, pkt6); + processReceivedPacket6(pkt6); } } } @@ -1473,6 +1476,14 @@ TestControl::reset() { setMacAddrGenerator(NumberGeneratorPtr()); first_packet_serverid_.clear(); interrupted_ = false; + + if (sender_thread_) { + if (sender_thread_->isRunning()) { + sender_thread_->stop(); + } + sender_thread_.reset(); + } + socket_.reset(); } int @@ -1506,8 +1517,8 @@ TestControl::run() { 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. @@ -1526,7 +1537,7 @@ TestControl::run() { 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 if (!options.getWrapped().empty()) { @@ -1535,35 +1546,48 @@ TestControl::run() { // 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 option was specified we have to check how many @@ -1577,9 +1601,9 @@ TestControl::run() { // 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); } } @@ -1592,7 +1616,7 @@ TestControl::run() { 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 @@ -1647,9 +1671,51 @@ TestControl::run() { } 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(); @@ -1686,8 +1752,7 @@ TestControl::saveFirstPacket(const Pkt6Ptr& pkt) { } void -TestControl::sendDiscover4(const TestControlSocket& socket, - const bool preload /*= false*/) { +TestControl::sendDiscover4(const bool preload /*= false*/) { if (!preload) { basic_rate_control_.updateSendTime(); } @@ -1714,7 +1779,7 @@ TestControl::sendDiscover4(const TestControlSocket& socket, // 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); @@ -1741,8 +1806,7 @@ TestControl::sendDiscover4(const TestControlSocket& socket, } void -TestControl::sendDiscover4(const TestControlSocket& socket, - const std::vector& template_buf, +TestControl::sendDiscover4(const std::vector& template_buf, const bool preload /* = false */) { if (!preload) { basic_rate_control_.updateSendTime(); @@ -1777,7 +1841,7 @@ TestControl::sendDiscover4(const TestControlSocket& socket, // 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)); + setDefaults4(boost::static_pointer_cast(pkt4)); // Pack the input packet buffer to output buffer so as it can // be sent to server. pkt4->rawPack(); @@ -1798,8 +1862,9 @@ TestControl::sendDiscover4(const TestControlSocket& socket, } 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. @@ -1810,7 +1875,7 @@ TestControl::sendRequestFromAck(const TestControlSocket& socket) { // 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); @@ -1823,13 +1888,15 @@ TestControl::sendRequestFromAck(const TestControlSocket& socket) { "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 @@ -1837,8 +1904,10 @@ TestControl::sendMessageFromReply(const uint16_t 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(); @@ -1847,7 +1916,7 @@ TestControl::sendMessageFromReply(const uint16_t msg_type, } // 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); @@ -1859,14 +1928,22 @@ TestControl::sendMessageFromReply(const uint16_t msg_type, 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(); @@ -1907,7 +1984,7 @@ TestControl::sendRequest4(const TestControlSocket& socket, 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); @@ -1931,8 +2008,7 @@ TestControl::sendRequest4(const TestControlSocket& socket, } void -TestControl::sendRequest4(const TestControlSocket& socket, - const std::vector& template_buf, +TestControl::sendRequest4(const std::vector& template_buf, const dhcp::Pkt4Ptr& discover_pkt4, const dhcp::Pkt4Ptr& offer_pkt4) { // Get the second argument if multiple the same arguments specified @@ -2026,7 +2102,7 @@ TestControl::sendRequest4(const TestControlSocket& socket, opt_requested_ip->setUint32(yiaddr.toUint32()); pkt4->addOption(opt_requested_ip); - setDefaults4(socket, boost::static_pointer_cast(pkt4)); + setDefaults4(boost::static_pointer_cast(pkt4)); // Add any extra options that user may have specified. addExtraOpts(pkt4); @@ -2045,8 +2121,7 @@ TestControl::sendRequest4(const TestControlSocket& socket, } 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. @@ -2085,7 +2160,7 @@ TestControl::sendRequest6(const TestControlSocket& socket, copyIaOptions(advertise_pkt6, pkt6); // Set default packet data. - setDefaults6(socket, pkt6); + setDefaults6(pkt6); // Add any extra options that user may have specified. addExtraOpts(pkt6); @@ -2102,8 +2177,7 @@ TestControl::sendRequest6(const TestControlSocket& socket, } void -TestControl::sendRequest6(const TestControlSocket& socket, - const std::vector& template_buf, +TestControl::sendRequest6(const std::vector& 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. @@ -2193,7 +2267,7 @@ TestControl::sendRequest6(const TestControlSocket& socket, 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); @@ -2221,8 +2295,7 @@ TestControl::sendRequest6(const TestControlSocket& socket, } void -TestControl::sendSolicit6(const TestControlSocket& socket, - const bool preload /*= false*/) { +TestControl::sendSolicit6(const bool preload /*= false*/) { if (!preload) { basic_rate_control_.updateSendTime(); } @@ -2256,7 +2329,7 @@ TestControl::sendSolicit6(const TestControlSocket& socket, 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); @@ -2278,8 +2351,7 @@ TestControl::sendSolicit6(const TestControlSocket& socket, } void -TestControl::sendSolicit6(const TestControlSocket& socket, - const std::vector& template_buf, +TestControl::sendSolicit6(const std::vector& template_buf, const bool preload /*= false*/) { if (!preload) { basic_rate_control_.updateSendTime(); @@ -2310,7 +2382,7 @@ TestControl::sendSolicit6(const TestControlSocket& socket, // Prepare on-wire data. pkt6->rawPack(); - setDefaults6(socket, pkt6); + setDefaults6(pkt6); // Add any extra options that user may have specified. addExtraOpts(pkt6); @@ -2333,17 +2405,19 @@ TestControl::sendSolicit6(const TestControlSocket& socket, 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) @@ -2351,31 +2425,33 @@ TestControl::setDefaults4(const TestControlSocket& socket, // 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())); @@ -2386,8 +2462,8 @@ TestControl::setDefaults6(const TestControlSocket& socket, 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); } } diff --git a/src/bin/perfdhcp/test_control.h b/src/bin/perfdhcp/test_control.h index e38fee17a8..507428da58 100644 --- a/src/bin/perfdhcp/test_control.h +++ b/src/bin/perfdhcp/test_control.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -252,7 +253,7 @@ public: /// \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 @@ -264,6 +265,12 @@ public: /// 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. @@ -294,6 +301,11 @@ protected: /// 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_; @@ -452,7 +464,7 @@ protected: /// \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); @@ -593,12 +605,10 @@ protected: /// \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. /// @@ -610,12 +620,10 @@ protected: /// \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. /// @@ -627,11 +635,10 @@ protected: /// \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 /// @@ -707,14 +714,12 @@ protected: /// 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. /// @@ -725,14 +730,12 @@ protected: /// 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& template_buf, + void sendDiscover4(const std::vector& template_buf, const bool preload = false); /// \brief Send number of packets to initiate new exchanges. @@ -750,44 +753,34 @@ protected: /// /// \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. /// @@ -797,12 +790,9 @@ protected: /// /// \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. /// @@ -810,7 +800,6 @@ protected: /// 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. /// @@ -818,8 +807,7 @@ protected: /// \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. @@ -828,14 +816,12 @@ protected: /// 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& template_buf, + void sendRequest4(const std::vector& template_buf, const dhcp::Pkt4Ptr& discover_pkt4, const dhcp::Pkt4Ptr& offer_pkt4); @@ -849,15 +835,13 @@ protected: /// 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. /// @@ -865,13 +849,11 @@ protected: /// 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& template_buf, + void sendRequest6(const std::vector& template_buf, const dhcp::Pkt6Ptr& advertise_pkt6); /// \brief Send DHCPv6 SOLICIT message. @@ -886,13 +868,11 @@ protected: /// 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. /// @@ -900,13 +880,11 @@ protected: /// 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& template_buf, + void sendSolicit6(const std::vector& template_buf, const bool preload = false); /// \brief Set default DHCPv4 packet parameters. @@ -919,10 +897,8 @@ protected: /// - 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. /// @@ -934,10 +910,8 @@ protected: /// - 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. /// @@ -1166,6 +1140,10 @@ protected: std::map template_packets_v6_; static bool interrupted_; ///< Is program interrupted. + + boost::shared_ptr socket_; ///< Socket object. + + util::thread::WatchedThreadPtr sender_thread_; ///< Sender watched thread. }; } // namespace perfdhcp diff --git a/src/bin/perfdhcp/tests/test_control_unittest.cc b/src/bin/perfdhcp/tests/test_control_unittest.cc index 75a9848cd6..343b26a6df 100644 --- a/src/bin/perfdhcp/tests/test_control_unittest.cc +++ b/src/bin/perfdhcp/tests/test_control_unittest.cc @@ -143,6 +143,7 @@ public: 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 ? @@ -493,16 +494,17 @@ public: 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 @@ -510,7 +512,7 @@ public: // packet drops. if (i < receive_num) { boost::shared_ptr 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; @@ -558,25 +560,25 @@ public: 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 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()) { @@ -701,11 +703,11 @@ public: // 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 @@ -717,7 +719,7 @@ public: // 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 @@ -730,7 +732,7 @@ public: // -f 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; @@ -738,7 +740,7 @@ public: // 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); @@ -746,7 +748,7 @@ public: // 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); @@ -754,7 +756,7 @@ public: // 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); @@ -908,11 +910,11 @@ public: // 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 @@ -924,7 +926,7 @@ public: // 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 @@ -937,7 +939,7 @@ public: // -f 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; @@ -945,7 +947,7 @@ public: // 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); @@ -953,7 +955,7 @@ public: // 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); @@ -961,7 +963,7 @@ public: // 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); @@ -1404,21 +1406,22 @@ TEST_F(TestControlTest, Packet4) { // 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(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; @@ -1437,17 +1440,17 @@ TEST_F(TestControlTest, Packet6) { // 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(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()); @@ -1470,24 +1473,24 @@ TEST_F(TestControlTest, Packet6Relayed) { // 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(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; @@ -1958,10 +1961,10 @@ TEST_F(TestControlTest, sendDiscoverExtraOpts) { // 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);