Kea 2.5.5
test_control.h
Go to the documentation of this file.
1// Copyright (C) 2012-2022 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
360 dhcp::Pkt4Ptr createMessageFromAck(const uint16_t msg_type,
361 const dhcp::Pkt4Ptr& ack);
362
378 dhcp::Pkt6Ptr createMessageFromReply(const uint16_t msg_type,
379 const dhcp::Pkt6Ptr& reply);
380
394 static dhcp::OptionPtr
396 uint16_t type,
397 const dhcp::OptionBuffer& buf);
398
410 uint16_t type,
411 const dhcp::OptionBuffer& buf);
412
424 uint16_t type,
425 const dhcp::OptionBuffer& buf);
426
435 uint16_t type,
436 const dhcp::OptionBuffer& buf);
437
449 static dhcp::OptionPtr
451 uint16_t type,
452 const dhcp::OptionBuffer& buf);
453
465 uint16_t type,
466 const dhcp::OptionBuffer& buf);
467
468
486 uint16_t type,
487 const dhcp::OptionBuffer& buf);
488
498
514 std::vector<uint8_t> generateDuid(uint8_t& randomized);
515
530 std::vector<uint8_t> generateMacAddress(uint8_t& randomized);
531
538 uint32_t generateTransid() {
539 return (transid_gen_->generate());
540 }
541
549 TemplateBuffer getTemplateBuffer(const size_t idx) const;
550
561 void initPacketTemplates();
562
566 void printRate() const;
567
581 void processReceivedPacket4(const dhcp::Pkt4Ptr& pkt4);
582
590 bool validateIA(const dhcp::Pkt6Ptr& pkt6);
591
598 void address6Uniqueness(const dhcp::Pkt6Ptr& pkt6, ExchangeType xchg_type);
599
606 void address4Uniqueness(const dhcp::Pkt4Ptr& pkt4, ExchangeType xchg_type);
607
615 void addUniqeAddr(const std::set<std::string>& current, ExchangeType xchg_type) {
616 switch(xchg_type) {
617 case ExchangeType::SA: {
618 for (auto current_it = current.begin();
619 current_it != current.end(); ++current_it) {
620 // addresses should be unique cross packets
621 auto ret = unique_address_.emplace(*current_it);
622 if (!ret.second) {
624 }
625 }
626 break;
627 }
628 case ExchangeType::RR: {
629 for (auto current_it = current.begin();
630 current_it != current.end(); ++current_it) {
631 // addresses should be unique cross packets
632 auto ret = unique_reply_address_.emplace(*current_it);
633 if (!ret.second) {
635 }
636 }
637 break;
638 }
640 case ExchangeType::RL: {
641 removeUniqueAddr(current);
642 break;
643 }
644 case ExchangeType::DO: {
645 for (auto current_it = current.begin();
646 current_it != current.end(); ++current_it) {
647 // addresses should be unique cross packets
648 auto ret = unique_address_.emplace(*current_it);
649 if (!ret.second) {
651 }
652 }
653 break;
654 }
655 case ExchangeType::RA: {
656 for (auto current_it = current.begin();
657 current_it != current.end(); ++current_it) {
658 // addresses should be unique cross packets
659 auto ret = unique_reply_address_.emplace(*current_it);
660 if (!ret.second) {
662 }
663 }
664 break;
665 }
667 case ExchangeType::RN:
668 default:
669 break;
670 }
671 }
672
679 void removeUniqueAddr(const std::set<std::string>& addr) {
680 for (auto addr_it = addr.begin(); addr_it != addr.end(); ++addr_it) {
681 auto it = unique_address_.find(*addr_it);
682 if (it != unique_address_.end()) {
683 unique_address_.erase(it);
684 }
685
686 auto it2 = unique_reply_address_.find(*addr_it);
687 if (it2 != unique_reply_address_.end()) {
688 unique_reply_address_.erase(it2);
689 }
690 }
691 }
692
703 void processReceivedPacket6(const dhcp::Pkt6Ptr& pkt6);
704
712 void registerOptionFactories4() const;
713
721 void registerOptionFactories6() const;
722
727 void registerOptionFactories() const;
728
733 void reset();
734
748 inline void saveFirstPacket(const dhcp::Pkt4Ptr& pkt);
749
763 inline void saveFirstPacket(const dhcp::Pkt6Ptr& pkt);
764
783 void sendDiscover4(const bool preload = false);
784
799 void sendDiscover4(const std::vector<uint8_t>& template_buf,
800 const bool preload = false);
801
808 bool sendMessageFromAck(const uint16_t msg_type);
809
820 bool sendMessageFromReply(const uint16_t msg_type);
821
835 void sendRequest4(const dhcp::Pkt4Ptr& discover_pkt4,
836 const dhcp::Pkt4Ptr& offer_pkt4);
837
849 void sendRequest4(const std::vector<uint8_t>& template_buf,
850 const dhcp::Pkt4Ptr& discover_pkt4,
851 const dhcp::Pkt4Ptr& offer_pkt4);
852
869 void sendRequest6(const dhcp::Pkt6Ptr& advertise_pkt6);
870
881 void sendRequest6(const std::vector<uint8_t>& template_buf,
882 const dhcp::Pkt6Ptr& advertise_pkt6);
883
900 void sendSolicit6(const bool preload = false);
901
912 void sendSolicit6(const std::vector<uint8_t>& template_buf,
913 const bool preload = false);
914
926 void setDefaults4(const dhcp::Pkt4Ptr& pkt);
927
939 void setDefaults6(const dhcp::Pkt6Ptr& pkt);
940
949 void addExtraOpts(const dhcp::Pkt4Ptr& pkt4);
950
959 void addExtraOpts(const dhcp::Pkt6Ptr& pkt6);
960
977 void copyIaOptions(const dhcp::Pkt6Ptr& pkt_from, dhcp::Pkt6Ptr& pkt_to);
978
991 template<class T>
992 uint32_t getElapsedTime(const T& pkt1, const T& pkt2);
993
997 int getElapsedTimeOffset() const;
998
1002 int getRandomOffset(const int arg_idx) const;
1003
1007 int getRequestedIpOffset() const;
1008
1012 int getServerIdOffset() const;
1013
1020 int getTransactionIdOffset(const int arg_idx) const;
1021
1028 static void handleChild(int sig);
1029
1036 static void handleInterrupt(int sig);
1037
1041 void printDiagnostics() const;
1042
1046 void printTemplate(const uint8_t packet_type) const;
1047
1059 void readPacketTemplate(const std::string& file_name);
1060
1062 std::set<std::string> unique_address_;
1063
1065 std::set<std::string> unique_reply_address_;
1066
1069
1072
1074 boost::posix_time::ptime last_report_;
1075
1078
1081
1084
1087
1090
1093
1096
1099
1101 std::map<uint8_t, dhcp::Pkt4Ptr> template_packets_v4_;
1102
1104 std::map<uint8_t, dhcp::Pkt6Ptr> template_packets_v6_;
1105
1107 static bool interrupted_;
1108
1111};
1112
1113} // namespace perfdhcp
1114} // namespace isc
1115
1116#endif // TEST_CONTROL_H
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:83
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:615
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:679
dhcp::OptionBuffer first_packet_serverid_
Buffer holding server id received in first packet.
uint32_t generateTransid()
generate transaction id.
Definition: test_control.h:538
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:555
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:31
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition: option.h:24
boost::shared_ptr< Option > OptionPtr
Definition: option.h:37
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.