Kea  1.5.0
test_control.h
Go to the documentation of this file.
1 // Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #ifndef TEST_CONTROL_H
8 #define TEST_CONTROL_H
9 
10 #include "packet_storage.h"
11 #include "rate_control.h"
12 #include "stats_mgr.h"
13 
14 #include <dhcp/iface_mgr.h>
15 #include <dhcp/dhcp6.h>
16 #include <dhcp/pkt4.h>
17 #include <dhcp/pkt6.h>
19 
20 #include <boost/noncopyable.hpp>
21 #include <boost/shared_ptr.hpp>
22 #include <boost/function.hpp>
23 #include <boost/date_time/posix_time/posix_time.hpp>
24 
25 #include <string>
26 #include <vector>
27 
28 namespace isc {
29 namespace perfdhcp {
30 
32 static const size_t DHCPV4_TRANSID_OFFSET = 4;
34 static const size_t DHCPV4_RANDOMIZATION_OFFSET = 35;
36 static const size_t DHCPV4_ELAPSED_TIME_OFFSET = 8;
38 static const size_t DHCPV4_SERVERID_OFFSET = 54;
40 static const size_t DHCPV4_REQUESTED_IP_OFFSET = 240;
42 static const size_t DHCPV6_TRANSID_OFFSET = 1;
45 static const size_t DHCPV6_RANDOMIZATION_OFFSET = 21;
47 static const size_t DHCPV6_ELAPSED_TIME_OFFSET = 84;
49 static const size_t DHCPV6_SERVERID_OFFSET = 22;
51 static const size_t DHCPV6_IA_NA_OFFSET = 40;
52 
54 class OptionNotFound : public Exception {
55 public:
56  OptionNotFound(const char* file, size_t line, const char* what) :
57  isc::Exception(file, line, what) { };
58 };
59 
121 class TestControl : public boost::noncopyable {
122 public:
123 
127  typedef boost::shared_ptr<StatsMgr4> StatsMgr4Ptr;
131  typedef boost::shared_ptr<StatsMgr6> StatsMgr6Ptr;
135  typedef std::vector<uint8_t> TemplateBuffer;
137  typedef std::vector<TemplateBuffer> TemplateBufferCollection;
138 
142  bool waitToExit() const;
143 
146  bool hasLateExitCommenced() const;
147 
149  bool haveAllPacketsBeenReceived() const;
150 
162  uint16_t ifindex_;
165  bool valid_;
166 
175  TestControlSocket(const int socket);
176 
181 
182  private:
190  void initSocketData();
191  };
192 
200  public:
201 
203  virtual ~NumberGenerator() { }
204 
208  virtual uint32_t generate() = 0;
209  };
210 
212  typedef boost::shared_ptr<NumberGenerator> NumberGeneratorPtr;
213 
216  public:
221  SequentialGenerator(uint32_t range = 0xFFFFFFFF) :
222  NumberGenerator(),
223  num_(0),
224  range_(range) {
225  if (range_ == 0) {
226  range_ = 0xFFFFFFFF;
227  }
228  }
229 
233  virtual uint32_t generate() {
234  uint32_t num = num_;
235  num_ = (num_ + 1) % range_;
236  return (num);
237  }
238  private:
239  uint32_t num_;
240  uint32_t range_;
241  };
242 
247  static const uint8_t HW_ETHER_LEN = 6;
248 
253  static TestControl& instance();
254 
265  int run();
266 
270  void setTransidGenerator(const NumberGeneratorPtr& generator) {
271  transid_gen_.reset();
272  transid_gen_ = generator;
273  }
274 
281  void setMacAddrGenerator(const NumberGeneratorPtr& generator) {
282  macaddr_gen_.reset();
283  macaddr_gen_ = generator;
284  }
285 
286  // We would really like following methods and members to be private but
287  // they have to be accessible for unit-testing. Another, possibly better,
288  // solution is to make this class friend of test class but this is not
289  // what's followed in other classes.
290 protected:
295  TestControl();
296 
299 
310  bool checkExitConditions() const;
311 
323  void cleanCachedPackets();
324 
332 
348  dhcp::Pkt6Ptr createMessageFromReply(const uint16_t msg_type,
349  const dhcp::Pkt6Ptr& reply);
350 
364  static dhcp::OptionPtr
366  uint16_t type,
367  const dhcp::OptionBuffer& buf);
368 
380  uint16_t type,
381  const dhcp::OptionBuffer& buf);
382 
394  uint16_t type,
395  const dhcp::OptionBuffer& buf);
396 
405  uint16_t type,
406  const dhcp::OptionBuffer& buf);
407 
419  static dhcp::OptionPtr
421  uint16_t type,
422  const dhcp::OptionBuffer& buf);
423 
435  uint16_t type,
436  const dhcp::OptionBuffer& buf);
437 
438 
456  uint16_t type,
457  const dhcp::OptionBuffer& buf);
458 
467  dhcp::OptionPtr generateClientId(const dhcp::HWAddrPtr& hwaddr) const;
468 
484  std::vector<uint8_t> generateDuid(uint8_t& randomized);
485 
500  std::vector<uint8_t> generateMacAddress(uint8_t& randomized);
501 
508  uint32_t generateTransid() {
509  return (transid_gen_->generate());
510  }
511 
519  uint32_t getCurrentTimeout() const;
520 
528  TemplateBuffer getTemplateBuffer(const size_t idx) const;
529 
540  void initPacketTemplates();
541 
546  void initializeStatsMgr();
547 
566  int openSocket() const;
567 
572  void printIntermediateStats();
573 
577  void printRate() const;
578 
584  void printStats() const;
585 
600  void processReceivedPacket4(const TestControlSocket& socket,
601  const dhcp::Pkt4Ptr& pkt4);
602 
617  void processReceivedPacket6(const TestControlSocket& socket,
618  const dhcp::Pkt6Ptr& pkt6);
619 
634  uint64_t receivePackets(const TestControlSocket& socket);
635 
643  void registerOptionFactories4() const;
644 
652  void registerOptionFactories6() const;
653 
658  void registerOptionFactories() const;
659 
660 
665  void reset();
666 
680  inline void saveFirstPacket(const dhcp::Pkt4Ptr& pkt);
681 
695  inline void saveFirstPacket(const dhcp::Pkt6Ptr& pkt);
696 
716  void sendDiscover4(const TestControlSocket& socket,
717  const bool preload = false);
718 
734  void sendDiscover4(const TestControlSocket& socket,
735  const std::vector<uint8_t>& template_buf,
736  const bool preload = false);
737 
759  void sendPackets(const TestControlSocket &socket,
760  const uint64_t packets_num,
761  const bool preload = false);
762 
769  uint64_t sendMultipleRequests(const TestControlSocket& socket,
770  const uint64_t msg_num);
771 
780  uint64_t sendMultipleMessages6(const TestControlSocket& socket,
781  const uint32_t msg_type,
782  const uint64_t msg_num);
783 
790  bool sendRequestFromAck(const TestControlSocket& socket);
791 
804  bool sendMessageFromReply(const uint16_t msg_type,
805  const TestControlSocket& socket);
806 
821  void sendRequest4(const TestControlSocket& socket,
822  const dhcp::Pkt4Ptr& discover_pkt4,
823  const dhcp::Pkt4Ptr& offer_pkt4);
824 
837  void sendRequest4(const TestControlSocket& socket,
838  const std::vector<uint8_t>& template_buf,
839  const dhcp::Pkt4Ptr& discover_pkt4,
840  const dhcp::Pkt4Ptr& offer_pkt4);
841 
859  void sendRequest6(const TestControlSocket& socket,
860  const dhcp::Pkt6Ptr& advertise_pkt6);
861 
873  void sendRequest6(const TestControlSocket& socket,
874  const std::vector<uint8_t>& template_buf,
875  const dhcp::Pkt6Ptr& advertise_pkt6);
876 
894  void sendSolicit6(const TestControlSocket& socket,
895  const bool preload = false);
896 
908  void sendSolicit6(const TestControlSocket& socket,
909  const std::vector<uint8_t>& template_buf,
910  const bool preload = false);
911 
924  void setDefaults4(const TestControlSocket& socket,
925  const dhcp::Pkt4Ptr& pkt);
926 
939  void setDefaults6(const TestControlSocket& socket,
940  const dhcp::Pkt6Ptr& pkt);
941 
950  void addExtraOpts(const dhcp::Pkt4Ptr& pkt4);
951 
960  void addExtraOpts(const dhcp::Pkt6Ptr& pkt6);
961 
966  bool testDiags(const char diag) const;
967 
968 protected:
969 
979  void checkLateMessages(RateControl& rate_control);
980 
997  void copyIaOptions(const dhcp::Pkt6Ptr& pkt_from, dhcp::Pkt6Ptr& pkt_to);
998 
1005  std::string byte2Hex(const uint8_t b) const;
1006 
1019  template<class T>
1020  uint32_t getElapsedTime(const T& pkt1, const T& pkt2);
1021 
1025  int getElapsedTimeOffset() const;
1026 
1030  int getRandomOffset(const int arg_idx) const;
1031 
1035  int getRequestedIpOffset() const;
1036 
1040  int getServerIdOffset() const;
1041 
1048  int getTransactionIdOffset(const int arg_idx) const;
1049 
1063  uint64_t getRcvdPacketsNum(ExchangeType xchg_type) const;
1064 
1078  uint64_t getSentPacketsNum(ExchangeType xchg_type) const;
1079 
1086  static void handleChild(int sig);
1087 
1094  static void handleInterrupt(int sig);
1095 
1099  void printDiagnostics() const;
1100 
1104  void printTemplate(const uint8_t packet_type) const;
1105 
1110  void printTemplates() const;
1111 
1123  void readPacketTemplate(const std::string& file_name);
1124 
1128  void runWrapped(bool do_stop = false) const;
1129 
1136  std::string vector2Hex(const std::vector<uint8_t>& vec,
1137  const std::string& separator = "") const;
1138 
1145 
1146  boost::posix_time::ptime last_report_;
1147 
1150 
1153 
1156 
1159 
1162 
1165  std::map<uint8_t, dhcp::Pkt4Ptr> template_packets_v4_;
1166  std::map<uint8_t, dhcp::Pkt6Ptr> template_packets_v6_;
1167 
1168  static bool interrupted_;
1169 };
1170 
1171 } // namespace perfdhcp
1172 } // namespace isc
1173 
1174 #endif // TEST_CONTROL_H
NumberGeneratorPtr transid_gen_
Transaction id generator.
static dhcp::OptionPtr factoryGeneric(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create generic option.
boost::shared_ptr< NumberGenerator > NumberGeneratorPtr
The default generator pointer.
Definition: test_control.h:212
static bool interrupted_
Is program interrupted.
uint32_t generateTransid()
generate transaction id.
Definition: test_control.h:508
bool sendRequestFromAck(const TestControlSocket &socket)
Send DHCPv4 renew (DHCPREQUEST) using specified socket.
void printTemplates() const
Print templates information.
void printStats() const
Print performance statistics.
static dhcp::OptionPtr factoryIana6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create IA_NA option.
virtual uint32_t generate()=0
Generate number.
Exception thrown when the required option is not found in a packet.
Definition: test_control.h:54
RateControl release_rate_control_
A rate control class for Release messages.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
PacketStorage< dhcp::Pkt4 > ack_storage_
A storage for DHCPACK messages.
void setDefaults4(const TestControlSocket &socket, const dhcp::Pkt4Ptr &pkt)
Set default DHCPv4 packet parameters.
std::vector< uint8_t > generateDuid(uint8_t &randomized)
Generate DUID.
void registerOptionFactories4() const
Register option factory functions for DHCPv4.
static TestControl & instance()
TestControl is a singleton class.
ExchangeType
DHCP packet exchange types.
int run()
brief\ Run performance test.
uint32_t getCurrentTimeout() const
Returns a timeout for packet reception.
bool checkExitConditions() const
Check if test exit conditions fulfilled.
void processReceivedPacket6(const TestControlSocket &socket, const dhcp::Pkt6Ptr &pkt6)
Process received DHCPv6 packet.
boost::shared_ptr< Option > OptionPtr
Definition: option.h:37
void setTransidGenerator(const NumberGeneratorPtr &generator)
Set new transaction id generator.
Definition: test_control.h:270
void checkLateMessages(RateControl &rate_control)
Increments counter of late sent messages if required.
StatsMgr4Ptr stats_mgr4_
Statistics Manager 4.
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:67
void printIntermediateStats()
Print intermediate statistics.
boost::shared_ptr< StatsMgr6 > StatsMgr6Ptr
Pointer to Statistics Manager for DHCPv6.
Definition: test_control.h:131
static dhcp::OptionPtr factoryRapidCommit6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 RAPID_COMMIT option instance.
TestControl()
Default constructor.
StatsMgr< dhcp::Pkt4 > StatsMgr4
Statistics Manager for DHCPv4.
Definition: test_control.h:125
A message sending rate control class for perfdhcp.
Definition: rate_control.h:38
void initPacketTemplates()
Reads packet templates from files.
dhcp::OptionPtr generateClientId(const dhcp::HWAddrPtr &hwaddr) const
Generate DHCPv4 client identifier from HW address.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
RateControl renew_rate_control_
A rate control class for Renew messages.
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition: option.h:25
std::vector< TemplateBuffer > TemplateBufferCollection
Packet template buffers list.
Definition: test_control.h:137
bool testDiags(const char diag) const
Find if diagnostic flag has been set.
static dhcp::OptionPtr factoryElapsedTime6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 ELAPSED_TIME option.
TemplateBufferCollection template_buffers_
Packet template buffers.
StatsMgr6Ptr stats_mgr6_
Statistics Manager 6.
dhcp::Pkt4Ptr createRequestFromAck(const dhcp::Pkt4Ptr &ack)
Creates DHCPREQUEST from a DHCPACK message.
void printRate() const
Print rate statistics.
uint64_t sendMultipleRequests(const TestControlSocket &socket, const uint64_t msg_num)
Send number of DHCPREQUEST (renew) messages to a server.
StatsMgr ::ExchangeType ExchangeType
Packet exchange type.
Definition: test_control.h:133
std::vector< uint8_t > TemplateBuffer
Packet template buffer.
Definition: test_control.h:135
int openSocket() const
Open socket to communicate with DHCP server.
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition: pkt6.h:28
uint64_t getSentPacketsNum(ExchangeType xchg_type) const
Get number of sent packets.
bool hasLateExitCommenced() const
Check if the program is in that period where the program was bound to exit, but was delayed by lateEx...
Definition: test_control.cc:48
int getRandomOffset(const int arg_idx) const
Return randomization offset in a packet.
void runWrapped(bool do_stop=false) const
Run wrapped command.
StatsMgr< dhcp::Pkt6 > StatsMgr6
Statistics Manager for DHCPv6.
Definition: test_control.h:129
void processReceivedPacket4(const TestControlSocket &socket, const dhcp::Pkt4Ptr &pkt4)
Process received DHCPv4 packet.
bool haveAllPacketsBeenReceived() const
Checks if all expected packets were already received.
Definition: test_control.cc:76
boost::posix_time::ptime last_report_
Last intermediate report time.
std::map< uint8_t, dhcp::Pkt6Ptr > template_packets_v6_
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Definition: pkt4.h:546
void sendRequest6(const TestControlSocket &socket, const dhcp::Pkt6Ptr &advertise_pkt6)
Send DHCPv6 REQUEST message.
void sendPackets(const TestControlSocket &socket, const uint64_t packets_num, const bool preload=false)
Send number of packets to initiate new exchanges.
TemplateBuffer getTemplateBuffer(const size_t idx) const
Return template buffer.
int getTransactionIdOffset(const int arg_idx) const
Return transaction id offset in a packet.
std::string vector2Hex(const std::vector< uint8_t > &vec, const std::string &separator="") const
Convert vector in hexadecimal string.
void sendDiscover4(const TestControlSocket &socket, const bool preload=false)
Send DHCPv4 DISCOVER message.
uint64_t receivePackets(const TestControlSocket &socket)
Receive DHCPv4 or DHCPv6 packets from the server.
bool sendMessageFromReply(const uint16_t msg_type, const TestControlSocket &socket)
Send DHCPv6 Renew or Release message using specified socket.
OptionNotFound(const char *file, size_t line, const char *what)
Definition: test_control.h:56
void initializeStatsMgr()
Initializes Statistics Manager.
TestControlSocket(const int socket)
Constructor of socket wrapper class.
std::vector< uint8_t > generateMacAddress(uint8_t &randomized)
Generate MAC address.
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-dhcp-ddns.
static dhcp::OptionPtr factoryRequestList4(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv4 Request List option.
void copyIaOptions(const dhcp::Pkt6Ptr &pkt_from, dhcp::Pkt6Ptr &pkt_to)
Copies IA_NA or IA_PD option from one packet to another.
boost::shared_ptr< StatsMgr4 > StatsMgr4Ptr
Pointer to Statistics Manager for DHCPv4;.
Definition: test_control.h:127
static void handleChild(int sig)
Handle child signal.
void sendSolicit6(const TestControlSocket &socket, const bool preload=false)
Send DHCPv6 SOLICIT message.
void cleanCachedPackets()
Removes cached DHCPv6 Reply packets every second.
PacketStorage< dhcp::Pkt6 > reply_storage_
A storage for reply messages.
void saveFirstPacket(const dhcp::Pkt4Ptr &pkt)
Save the first DHCPv4 sent packet of the specified type.
void registerOptionFactories() const
Register option factory functions for DHCPv4 or DHCPv6.
void sendRequest4(const TestControlSocket &socket, const dhcp::Pkt4Ptr &discover_pkt4, const dhcp::Pkt4Ptr &offer_pkt4)
Send DHCPv4 REQUEST message.
void registerOptionFactories6() const
Register option factory functions for DHCPv6.
void printTemplate(const uint8_t packet_type) const
Print template information.
void readPacketTemplate(const std::string &file_name)
Read DHCP message template from file.
Test Control class.
Definition: test_control.h:121
SequentialGenerator(uint32_t range=0xFFFFFFFF)
Constructor.
Definition: test_control.h:221
NumberGeneratorPtr macaddr_gen_
Numbers generator for MAC address.
isc::util::random::UniformRandomIntegerGenerator number_generator_
Generate uniformly distributed integers in range of [min, max].
Definition: test_control.h:298
static dhcp::OptionPtr factoryOptionRequestOption6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 ORO option.
static const uint8_t HW_ETHER_LEN
Length of the Ethernet HW address (MAC) in bytes.
Definition: test_control.h:247
dhcp::OptionBuffer first_packet_serverid_
Buffer holding server id received in first packet.
static dhcp::OptionPtr factoryIapd6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create IA_PD option.
dhcp::Pkt6Ptr createMessageFromReply(const uint16_t msg_type, const dhcp::Pkt6Ptr &reply)
Creates DHCPv6 message from the Reply packet.
void printDiagnostics() const
Print main diagnostics data.
~TestControlSocket()
Destructor of the socket wrapper class.
uint32_t getElapsedTime(const T &pkt1, const T &pkt2)
Calculate elapsed time between two packets.
void setDefaults6(const TestControlSocket &socket, const dhcp::Pkt6Ptr &pkt)
Set default DHCPv6 packet parameters.
void setMacAddrGenerator(const NumberGeneratorPtr &generator)
Set new MAC address generator.
Definition: test_control.h:281
uint64_t getRcvdPacketsNum(ExchangeType xchg_type) const
Get number of received packets.
std::string byte2Hex(const uint8_t b) const
Convert binary value to hex string.
RateControl basic_rate_control_
A rate control class for Discover and Solicit messages.
std::map< uint8_t, dhcp::Pkt4Ptr > template_packets_v4_
First packets send.
int getRequestedIpOffset() const
Return requested ip offset in a packet.
virtual uint32_t generate()
Generate number sequentially.
Definition: test_control.h:233
int getElapsedTimeOffset() const
Return elapsed time offset in a packet.
uint64_t sendMultipleMessages6(const TestControlSocket &socket, const uint32_t msg_type, const uint64_t msg_num)
Send number of DHCPv6 Renew or Release messages to the server.
int getServerIdOffset() const
Return server id offset in a packet.
bool waitToExit() const
Delay the exit by a fixed given time to catch up to all exchanges that were already started.
Definition: test_control.cc:53
void reset()
Resets internal state of the object.
Represents a list of packets with a sequential and random access to list elements.
Holds information about socket.
Definition: socket_info.h:19
static void handleInterrupt(int sig)
Handle interrupt signal.
Sequential numbers generator class.
Definition: test_control.h:215
void addExtraOpts(const dhcp::Pkt4Ptr &pkt4)
Inserts extra options specified by user.