Kea 2.0.3
test_control.h
Go to the documentation of this file.
1// Copyright (C) 2012-2021 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
12#include <perfdhcp/stats_mgr.h>
13#include <perfdhcp/receiver.h>
17
18#include <dhcp/iface_mgr.h>
19#include <dhcp/dhcp4.h>
20#include <dhcp/dhcp6.h>
21#include <dhcp/pkt4.h>
22#include <dhcp/pkt6.h>
23
24#include <boost/noncopyable.hpp>
25#include <boost/shared_ptr.hpp>
26#include <boost/date_time/posix_time/posix_time.hpp>
27
28#include <string>
29#include <vector>
30#include <unordered_map>
31
32namespace isc {
33namespace perfdhcp {
34
36static const size_t DHCPV4_TRANSID_OFFSET = 4;
38static const size_t DHCPV4_RANDOMIZATION_OFFSET = 35;
40static const size_t DHCPV4_ELAPSED_TIME_OFFSET = 8;
42static const size_t DHCPV4_SERVERID_OFFSET = 54;
44static const size_t DHCPV4_REQUESTED_IP_OFFSET = 240;
46static const size_t DHCPV6_TRANSID_OFFSET = 1;
49static const size_t DHCPV6_RANDOMIZATION_OFFSET = 21;
51static const size_t DHCPV6_ELAPSED_TIME_OFFSET = 84;
53static const size_t DHCPV6_SERVERID_OFFSET = 22;
55static const size_t DHCPV6_IA_NA_OFFSET = 40;
56
118class TestControl : public boost::noncopyable {
119public:
121 TestControl(CommandOptions& options, BasePerfSocket& socket);
122
124 typedef std::vector<uint8_t> TemplateBuffer;
126 typedef std::vector<TemplateBuffer> TemplateBufferCollection;
127
131 bool waitToExit();
132
134 bool haveAllPacketsBeenReceived() const;
135
143 public:
144
146 virtual ~NumberGenerator() { }
147
151 virtual uint32_t generate() = 0;
152 };
153
155 typedef boost::shared_ptr<NumberGenerator> NumberGeneratorPtr;
156
159 public:
164 SequentialGenerator(uint32_t range = 0xFFFFFFFF) :
166 num_(0),
167 range_(range) {
168 if (range_ == 0) {
169 range_ = 0xFFFFFFFF;
170 }
171 }
172
176 virtual uint32_t generate() {
177 uint32_t num = num_;
178 num_ = (num_ + 1) % range_;
179 return (num);
180 }
181 private:
182 uint32_t num_;
183 uint32_t range_;
184 };
185
190 static const uint8_t HW_ETHER_LEN = 6;
191
196 transid_gen_.reset();
197 transid_gen_ = generator;
198 }
199
207 macaddr_gen_.reset();
208 macaddr_gen_ = generator;
209 }
210
222 void cleanCachedPackets();
223
225 bool interrupted() const { return interrupted_; }
226
229
231 void start() { receiver_.start(); }
232
234 void stop() { receiver_.stop(); }
235
239 void runWrapped(bool do_stop = false) const;
240
242 bool serverIdReceived() const { return first_packet_serverid_.size() > 0; }
243
245 std::string getServerId() const { return vector2Hex(first_packet_serverid_); }
246
267 void sendPackets(const uint64_t packets_num,
268 const bool preload = false);
269
277 uint64_t sendMultipleMessages4(const uint32_t msg_type,
278 const uint64_t msg_num);
279
287 uint64_t sendMultipleMessages6(const uint32_t msg_type,
288 const uint64_t msg_num);
289
293 unsigned int consumeReceivedPackets();
294
300
306 void printStats() const;
307
312 void printTemplates() const;
313
315 std::set<std::string>& getAllUniqueAddrReply() {
317 }
318
320 std::set<std::string>& getAllUniqueAddrAdvert() {
321 return unique_address_;
322 }
323
330 static std::string byte2Hex(const uint8_t b);
331
338 static std::string vector2Hex(const std::vector<uint8_t>& vec,
339 const std::string& separator = "");
340
343 boost::posix_time::ptime exit_time_;
344
345 // We would really like following methods and members to be private but
346 // they have to be accessible for unit-testing. Another, possibly better,
347 // solution is to make this class friend of test class but this is not
348 // what's followed in other classes.
349protected:
352
359 dhcp::Pkt4Ptr createMessageFromAck(const uint16_t msg_type,
360 const dhcp::Pkt4Ptr& ack);
361
377 dhcp::Pkt6Ptr createMessageFromReply(const uint16_t msg_type,
378 const dhcp::Pkt6Ptr& reply);
379
393 static dhcp::OptionPtr
395 uint16_t type,
396 const dhcp::OptionBuffer& buf);
397
409 uint16_t type,
410 const dhcp::OptionBuffer& buf);
411
423 uint16_t type,
424 const dhcp::OptionBuffer& buf);
425
434 uint16_t type,
435 const dhcp::OptionBuffer& buf);
436
448 static dhcp::OptionPtr
450 uint16_t type,
451 const dhcp::OptionBuffer& buf);
452
464 uint16_t type,
465 const dhcp::OptionBuffer& buf);
466
467
485 uint16_t type,
486 const dhcp::OptionBuffer& buf);
487
497
513 std::vector<uint8_t> generateDuid(uint8_t& randomized);
514
529 std::vector<uint8_t> generateMacAddress(uint8_t& randomized);
530
537 uint32_t generateTransid() {
538 return (transid_gen_->generate());
539 }
540
548 TemplateBuffer getTemplateBuffer(const size_t idx) const;
549
560 void initPacketTemplates();
561
565 void printRate() const;
566
580 void processReceivedPacket4(const dhcp::Pkt4Ptr& pkt4);
581
589 bool validateIA(const dhcp::Pkt6Ptr& pkt6);
590
597 void address6Uniqueness(const dhcp::Pkt6Ptr& pkt6, ExchangeType xchg_type);
598
605 void address4Uniqueness(const dhcp::Pkt4Ptr& pkt4, ExchangeType xchg_type);
606
614 void addUniqeAddr(const std::set<std::string>& current, ExchangeType xchg_type) {
615 switch(xchg_type) {
616 case ExchangeType::SA: {
617 for (auto current_it = current.begin();
618 current_it != current.end(); ++current_it) {
619 // addresses should be unique cross packets
620 auto ret = unique_address_.emplace(*current_it);
621 if (!ret.second) {
623 }
624 }
625 break;
626 }
627 case ExchangeType::RR: {
628 for (auto current_it = current.begin();
629 current_it != current.end(); ++current_it) {
630 // addresses should be unique cross packets
631 auto ret = unique_reply_address_.emplace(*current_it);
632 if (!ret.second) {
634 }
635 }
636 break;
637 }
639 case ExchangeType::RL: {
640 removeUniqueAddr(current);
641 break;
642 }
643 case ExchangeType::DO: {
644 for (auto current_it = current.begin();
645 current_it != current.end(); ++current_it) {
646 // addresses should be unique cross packets
647 auto ret = unique_address_.emplace(*current_it);
648 if (!ret.second) {
650 }
651 }
652 break;
653 }
654 case ExchangeType::RA: {
655 for (auto current_it = current.begin();
656 current_it != current.end(); ++current_it) {
657 // addresses should be unique cross packets
658 auto ret = unique_reply_address_.emplace(*current_it);
659 if (!ret.second) {
661 }
662 }
663 break;
664 }
666 case ExchangeType::RN:
667 default:
668 break;
669 }
670 }
671
678 void removeUniqueAddr(const std::set<std::string>& addr) {
679 for (auto addr_it = addr.begin(); addr_it != addr.end(); ++addr_it) {
680 auto it = unique_address_.find(*addr_it);
681 if (it != unique_address_.end()) {
682 unique_address_.erase(it);
683 }
684
685 auto it2 = unique_reply_address_.find(*addr_it);
686 if (it2 != unique_reply_address_.end()) {
687 unique_reply_address_.erase(it2);
688 }
689 }
690 }
691
702 void processReceivedPacket6(const dhcp::Pkt6Ptr& pkt6);
703
711 void registerOptionFactories4() const;
712
720 void registerOptionFactories6() const;
721
726 void registerOptionFactories() const;
727
732 void reset();
733
747 inline void saveFirstPacket(const dhcp::Pkt4Ptr& pkt);
748
762 inline void saveFirstPacket(const dhcp::Pkt6Ptr& pkt);
763
782 void sendDiscover4(const bool preload = false);
783
798 void sendDiscover4(const std::vector<uint8_t>& template_buf,
799 const bool preload = false);
800
807 bool sendMessageFromAck(const uint16_t msg_type);
808
819 bool sendMessageFromReply(const uint16_t msg_type);
820
834 void sendRequest4(const dhcp::Pkt4Ptr& discover_pkt4,
835 const dhcp::Pkt4Ptr& offer_pkt4);
836
848 void sendRequest4(const std::vector<uint8_t>& template_buf,
849 const dhcp::Pkt4Ptr& discover_pkt4,
850 const dhcp::Pkt4Ptr& offer_pkt4);
851
868 void sendRequest6(const dhcp::Pkt6Ptr& advertise_pkt6);
869
880 void sendRequest6(const std::vector<uint8_t>& template_buf,
881 const dhcp::Pkt6Ptr& advertise_pkt6);
882
899 void sendSolicit6(const bool preload = false);
900
911 void sendSolicit6(const std::vector<uint8_t>& template_buf,
912 const bool preload = false);
913
925 void setDefaults4(const dhcp::Pkt4Ptr& pkt);
926
938 void setDefaults6(const dhcp::Pkt6Ptr& pkt);
939
948 void addExtraOpts(const dhcp::Pkt4Ptr& pkt4);
949
958 void addExtraOpts(const dhcp::Pkt6Ptr& pkt6);
959
976 void copyIaOptions(const dhcp::Pkt6Ptr& pkt_from, dhcp::Pkt6Ptr& pkt_to);
977
990 template<class T>
991 uint32_t getElapsedTime(const T& pkt1, const T& pkt2);
992
996 int getElapsedTimeOffset() const;
997
1001 int getRandomOffset(const int arg_idx) const;
1002
1006 int getRequestedIpOffset() const;
1007
1011 int getServerIdOffset() const;
1012
1019 int getTransactionIdOffset(const int arg_idx) const;
1020
1027 static void handleChild(int sig);
1028
1035 static void handleInterrupt(int sig);
1036
1040 void printDiagnostics() const;
1041
1045 void printTemplate(const uint8_t packet_type) const;
1046
1058 void readPacketTemplate(const std::string& file_name);
1059
1061 std::set<std::string> unique_address_;
1062
1064 std::set<std::string> unique_reply_address_;
1065
1068
1071
1073 boost::posix_time::ptime last_report_;
1074
1077
1080
1083
1086
1089
1092
1095
1098
1100 std::map<uint8_t, dhcp::Pkt4Ptr> template_packets_v4_;
1101
1103 std::map<uint8_t, dhcp::Pkt6Ptr> template_packets_v6_;
1104
1106 static bool interrupted_;
1107
1110};
1111
1112} // namespace perfdhcp
1113} // namespace isc
1114
1115#endif // TEST_CONTROL_H
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:82
Socket wrapper structure.
Definition: perf_socket.h:26
Represents a list of packets with a sequential and random access to list elements.
A receiving DHCP packets class.
Definition: receiver.h:34
void start()
Start a receiving thread in multi-thread mode.
Definition: receiver.cc:24
void stop()
Stop a receiving thread in multi-thread mode.
Definition: receiver.cc:36
void updateNonUniqueAddrNum(const ExchangeType xchg_type)
Increase total number of non unique addresses.
virtual uint32_t generate()=0
Generate number.
Sequential numbers generator class.
Definition: test_control.h:158
virtual uint32_t generate()
Generate number sequentially.
Definition: test_control.h:176
SequentialGenerator(uint32_t range=0xFFFFFFFF)
Constructor.
Definition: test_control.h:164
Test Control class.
Definition: test_control.h:118
void saveFirstPacket(const dhcp::Pkt4Ptr &pkt)
Save the first DHCPv4 sent packet of the specified type.
void address6Uniqueness(const dhcp::Pkt6Ptr &pkt6, ExchangeType xchg_type)
Process received v6 addresses uniqueness.
static const uint8_t HW_ETHER_LEN
Length of the Ethernet HW address (MAC) in bytes.
Definition: test_control.h:190
bool waitToExit()
Delay the exit by a fixed given time to catch up to all exchanges that were already started.
Definition: test_control.cc:48
std::map< uint8_t, dhcp::Pkt4Ptr > template_packets_v4_
First packets send.
bool sendMessageFromReply(const uint16_t msg_type)
Send DHCPv6 Renew or Release message.
void addExtraOpts(const dhcp::Pkt4Ptr &pkt4)
Inserts extra options specified by user.
void printDiagnostics() const
Print main diagnostics data.
static void handleChild(int sig)
Handle child signal.
void registerOptionFactories4() const
Register option factory functions for DHCPv4.
bool interrupted() const
Get interrupted flag.
Definition: test_control.h:225
NumberGeneratorPtr transid_gen_
Transaction id generator.
NumberGeneratorPtr macaddr_gen_
Numbers generator for MAC address.
int getRequestedIpOffset() const
Return requested ip offset in a packet.
std::set< std::string > & getAllUniqueAddrReply()
Get set of unique replied addresses.
Definition: test_control.h:315
boost::shared_ptr< NumberGenerator > NumberGeneratorPtr
The default generator pointer.
Definition: test_control.h:155
std::string getServerId() const
Get received server id.
Definition: test_control.h:245
uint64_t sendMultipleMessages4(const uint32_t msg_type, const uint64_t msg_num)
Send number of DHCPREQUEST (renew) messages to a server.
bool validateIA(const dhcp::Pkt6Ptr &pkt6)
Process IA in received DHCPv6 packet.
dhcp::Pkt4Ptr createMessageFromAck(const uint16_t msg_type, const dhcp::Pkt4Ptr &ack)
Creates DHCPREQUEST from a DHCPACK message.
static bool interrupted_
Program interrupted flag.
void readPacketTemplate(const std::string &file_name)
Read DHCP message template from file.
TemplateBuffer getTemplateBuffer(const size_t idx) const
Return template buffer.
std::vector< uint8_t > generateMacAddress(uint8_t &randomized)
Generate MAC address.
void setDefaults4(const dhcp::Pkt4Ptr &pkt)
Set default DHCPv4 packet parameters.
boost::posix_time::ptime exit_time_
Initialized at first exit condition with the time perfdhcp should exit.
Definition: test_control.h:343
CommandOptions & options_
Command options.
Receiver receiver_
Receiver used to receive DHCP traffic.
static std::string vector2Hex(const std::vector< uint8_t > &vec, const std::string &separator="")
Convert vector in hexadecimal string.
uint64_t sendMultipleMessages6(const uint32_t msg_type, const uint64_t msg_num)
Send number of DHCPv6 Renew or Release messages to the server.
void start()
Start receiver.
Definition: test_control.h:231
void setMacAddrGenerator(const NumberGeneratorPtr &generator)
Set new MAC address generator.
Definition: test_control.h:206
void setDefaults6(const dhcp::Pkt6Ptr &pkt)
Set default DHCPv6 packet parameters.
boost::posix_time::ptime last_report_
Last intermediate report time.
bool haveAllPacketsBeenReceived() const
Checks if all expected packets were already received.
Definition: test_control.cc:69
void cleanCachedPackets()
Removes cached DHCPv6 Reply packets every second.
Definition: test_control.cc:96
void processReceivedPacket4(const dhcp::Pkt4Ptr &pkt4)
Process received DHCPv4 packet.
std::vector< TemplateBuffer > TemplateBufferCollection
Packet template buffers list.
Definition: test_control.h:126
void sendRequest6(const dhcp::Pkt6Ptr &advertise_pkt6)
Send DHCPv6 REQUEST message.
TestControl(CommandOptions &options, BasePerfSocket &socket)
Default constructor.
StatsMgr & getStatsMgr()
Get stats manager.
Definition: test_control.h:228
std::set< std::string > & getAllUniqueAddrAdvert()
Get set of unique advertised addresses.
Definition: test_control.h:320
static dhcp::OptionPtr factoryOptionRequestOption6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 ORO option.
void sendSolicit6(const bool preload=false)
Send DHCPv6 SOLICIT message.
static dhcp::OptionPtr factoryIapd6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create IA_PD option.
std::map< uint8_t, dhcp::Pkt6Ptr > template_packets_v6_
Template for v6.
static dhcp::OptionPtr factoryRapidCommit6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 RAPID_COMMIT option instance.
PacketStorage< dhcp::Pkt6 > reply_storage_
Storage for reply messages.
void registerOptionFactories6() const
Register option factory functions for DHCPv6.
void sendPackets(const uint64_t packets_num, const bool preload=false)
Send number of packets to initiate new exchanges.
void registerOptionFactories() const
Register option factory functions for DHCPv4 or DHCPv6.
UniformRandomIntegerGenerator number_generator_
Generate uniformly distributed integers in range of [min, max].
Definition: test_control.h:351
void stop()
Stop receiver.
Definition: test_control.h:234
std::vector< uint8_t > TemplateBuffer
Packet template buffer.
Definition: test_control.h:124
bool sendMessageFromAck(const uint16_t msg_type)
Send DHCPv4 renew (DHCPREQUEST).
void runWrapped(bool do_stop=false) const
Run wrapped command.
void processReceivedPacket6(const dhcp::Pkt6Ptr &pkt6)
Process received DHCPv6 packet.
uint32_t getElapsedTime(const T &pkt1, const T &pkt2)
Calculate elapsed time between two packets.
BasePerfSocket & socket_
Socket used for DHCP traffic.
void reset()
Resets internal state of the object.
void addUniqeAddr(const std::set< std::string > &current, ExchangeType xchg_type)
add unique address to already assigned list.
Definition: test_control.h:614
void address4Uniqueness(const dhcp::Pkt4Ptr &pkt4, ExchangeType xchg_type)
Process received v4 addresses uniqueness.
int getRandomOffset(const int arg_idx) const
Return randomization offset in a packet.
dhcp::Pkt6Ptr createMessageFromReply(const uint16_t msg_type, const dhcp::Pkt6Ptr &reply)
Creates DHCPv6 message from the Reply packet.
int getElapsedTimeOffset() const
Return elapsed time offset in a packet.
static std::string byte2Hex(const uint8_t b)
Convert binary value to hex string.
void printTemplates() const
Print templates information.
void sendRequest4(const dhcp::Pkt4Ptr &discover_pkt4, const dhcp::Pkt4Ptr &offer_pkt4)
Send DHCPv4 REQUEST message.
unsigned int consumeReceivedPackets()
Pull packets from receiver and process them.
TemplateBufferCollection template_buffers_
Packet template buffers.
StatsMgr stats_mgr_
Statistics Manager.
void printStats() const
Print performance statistics.
PacketStorage< dhcp::Pkt4 > ack_storage_
Storage for DHCPACK messages.
void copyIaOptions(const dhcp::Pkt6Ptr &pkt_from, dhcp::Pkt6Ptr &pkt_to)
Copies IA_NA or IA_PD option from one packet to another.
std::set< std::string > unique_reply_address_
Keep addresses and prefixes from reply msg for uniqueness checks.
void setTransidGenerator(const NumberGeneratorPtr &generator)
Set new transaction id generator.
Definition: test_control.h:195
static dhcp::OptionPtr factoryGeneric(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create generic option.
bool serverIdReceived() const
Get received server id flag.
Definition: test_control.h:242
static dhcp::OptionPtr factoryRequestList4(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv4 Request List option.
static dhcp::OptionPtr factoryElapsedTime6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create DHCPv6 ELAPSED_TIME option.
static void handleInterrupt(int sig)
Handle interrupt signal.
int getTransactionIdOffset(const int arg_idx) const
Return transaction id offset in a packet.
void initPacketTemplates()
Reads packet templates from files.
void printRate() const
Print rate statistics.
void printIntermediateStats()
Print intermediate statistics.
void printTemplate(const uint8_t packet_type) const
Print template information.
int getServerIdOffset() const
Return server id offset in a packet.
std::vector< uint8_t > generateDuid(uint8_t &randomized)
Generate DUID.
std::set< std::string > unique_address_
Keep addresses and prefixes from advertise msg for uniqueness checks.
void sendDiscover4(const bool preload=false)
Send DHCPv4 DISCOVER message.
dhcp::OptionPtr generateClientId(const dhcp::HWAddrPtr &hwaddr) const
Generate DHCPv4 client identifier from HW address.
void removeUniqueAddr(const std::set< std::string > &addr)
remove unique address from list.
Definition: test_control.h:678
dhcp::OptionBuffer first_packet_serverid_
Buffer holding server id received in first packet.
uint32_t generateTransid()
generate transaction id.
Definition: test_control.h:537
static dhcp::OptionPtr factoryIana6(dhcp::Option::Universe u, uint16_t type, const dhcp::OptionBuffer &buf)
Factory function to create IA_NA option.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Definition: pkt4.h:544
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition: hwaddr.h:154
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition: pkt6.h:28
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition: option.h:24
boost::shared_ptr< Option > OptionPtr
Definition: option.h:36
ExchangeType
DHCP packet exchange types.
@ RA
DHCPv4 REQUEST-ACK.
@ SA
DHCPv6 SOLICIT-ADVERTISE.
@ RNA
DHCPv4 REQUEST-ACK (renewal)
@ RL
DHCPv6 RELEASE-REPLY.
@ RN
DHCPv6 RENEW-REPLY.
@ DO
DHCPv4 DISCOVER-OFFER.
@ RR
DHCPv6 REQUEST-REPLY.
Defines the logger used by the top-level component of kea-lfc.