1 // Copyright (C) 2018-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 PERFDHCP_RECEIVER_H 8 #define PERFDHCP_RECEIVER_H 9 10 #include <perfdhcp/perf_socket.h> 11 #include <perfdhcp/command_options.h> 12 13 #include <dhcp/pkt.h> 14 15 #include <queue> 16 #include <thread> 17 #include <mutex> 18 #include <atomic> 19 20 namespace isc { 21 namespace perfdhcp { 22 23 /// \brief A receiving DHCP packets class. 24 /// 25 /// Receiver can be used in two modes: single-thread and multi-thread. 26 /// 27 /// In single-thread mode the class directly reads packets from socket 28 /// and returns them to consumer using getPkt method. 29 /// 30 /// In case of multi-thread mode the class starts a thread in the background. 31 /// The thread reads the packets and pushes them to pkt_queue_. Then 32 /// in main thread packets can be consumed from the queue using getPkt 33 /// method. 34 class Receiver { 35 private: 36 /// \brief Flag indicating if thread should run (true) or not (false). 37 std::atomic_flag run_flag_; 38 39 /// \brief Thread for receiving packets. 40 std::unique_ptr<std::thread> recv_thread_; 41 42 /// \brief Queue for passing packets from receiver thread to main thread. 43 std::queue<dhcp::PktPtr> pkt_queue_; 44 45 /// \brief Mutex for controlling access to the queue. 46 std::mutex pkt_queue_mutex_; 47 48 BasePerfSocket &socket_; 49 50 /// \brief Single- or thread-mode indicator. 51 bool single_threaded_; 52 53 uint8_t ip_version_; 54 55 public: 56 /// \brief Receiver constructor. 57 /// 58 /// \param socket A socket for receiving packets. 59 /// \param single_threaded A flag indicating running mode. 60 /// \param ip_version An IP version: 4 or 6 Receiver(BasePerfSocket & socket,bool single_threaded,uint8_t ip_version)61 Receiver(BasePerfSocket &socket, bool single_threaded, uint8_t ip_version) : 62 socket_(socket), 63 single_threaded_(single_threaded), 64 ip_version_(ip_version) { 65 run_flag_.clear(); 66 } 67 68 /// \brief Destructor. 69 ~Receiver(); 70 71 /// \brief Start a receiving thread in multi-thread mode. 72 /// 73 /// In single-thread mode it does nothing. 74 void start(); 75 76 /// \brief Stop a receiving thread in multi-thread mode. 77 /// 78 /// In single-thread mode it does nothing. 79 void stop(); 80 81 /// \brief Get DHCP packet. 82 /// 83 /// In single-thread mode it reads directly from the socket. 84 /// In multi-thread mode it reads packets from the queue. 85 dhcp::PktPtr getPkt(); 86 87 private: 88 /// \brief Receiving thread main function. 89 void run(); 90 91 /// \brief Receive packets from sockets and pushes them to the queue. 92 /// 93 /// It runs in a loop until socket is empty. 94 void receivePackets(); 95 96 /// \brief Read a packet directly from the socket. 97 dhcp::PktPtr readPktFromSocket(); 98 }; 99 100 } 101 } 102 103 #endif /* PERFDHCP_RECEIVER_H */ 104