diff options
Diffstat (limited to 'src/bin/perfdhcp/perf_socket.h')
-rw-r--r-- | src/bin/perfdhcp/perf_socket.h | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/src/bin/perfdhcp/perf_socket.h b/src/bin/perfdhcp/perf_socket.h new file mode 100644 index 0000000..bafe0ec --- /dev/null +++ b/src/bin/perfdhcp/perf_socket.h @@ -0,0 +1,143 @@ +// Copyright (C) 2012-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef PERF_SOCKET_H +#define PERF_SOCKET_H + +#include <perfdhcp/command_options.h> + +#include <dhcp/pkt4.h> +#include <dhcp/pkt6.h> +#include <dhcp/socket_info.h> +#include <dhcp/iface_mgr.h> + +namespace isc { +namespace perfdhcp { + +/// \brief Socket wrapper structure. +/// +/// This is a base class that is inherited by PerfSocket +/// and unit tests derived that. This way it allows mocking +/// out socket operations and avoid using real network +/// interfaces. +class BasePerfSocket : public dhcp::SocketInfo { +public: + /// Interface index. + unsigned int ifindex_; + + /// \brief Default constructor of BasePerfSocket. + BasePerfSocket() : + SocketInfo(asiolink::IOAddress("127.0.0.1"), 0, 0), + ifindex_(0) {} + + /// \brief Destructor of the socket wrapper class. + virtual ~BasePerfSocket() = default; + + /// \brief See description of this method in PerfSocket class below. + virtual dhcp::Pkt4Ptr receive4(uint32_t timeout_sec, uint32_t timeout_usec) = 0; + + /// \brief See description of this method in PerfSocket class below. + virtual dhcp::Pkt6Ptr receive6(uint32_t timeout_sec, uint32_t timeout_usec) = 0; + + /// \brief See description of this method in PerfSocket class below. + virtual bool send(const dhcp::Pkt4Ptr& pkt) = 0; + + /// \brief See description of this method in PerfSocket class below. + virtual bool send(const dhcp::Pkt6Ptr& pkt) = 0; + + /// \brief See description of this method in PerfSocket class below. + virtual dhcp::IfacePtr getIface() = 0; +}; + +/// \brief Socket wrapper structure. +/// +/// This is the wrapper that holds descriptor of the socket +/// used to run DHCP test. The wrapped socket is closed in +/// the destructor. This prevents resource leaks when +/// function that created the socket ends (normally or +/// when exception occurs). This structure extends parent +/// structure with new field ifindex_ that holds interface +/// index where socket is bound to. +class PerfSocket : public BasePerfSocket { +public: + /// \brief Constructor of socket wrapper class. + /// + /// This constructor uses provided socket descriptor to + /// find the name of the interface where socket has been + /// bound to. + PerfSocket(CommandOptions& options); + + /// \brief Destructor of the socket wrapper class. + /// + /// Destructor closes wrapped socket. + virtual ~PerfSocket(); + + /// \brief Receive DHCPv4 packet from interface. + /// + /// \param timeout_sec number of seconds for waiting for a packet, + /// \param timeout_usec number of microseconds for waiting for a packet, + /// \return received packet or nullptr if timed out + virtual dhcp::Pkt4Ptr receive4(uint32_t timeout_sec, uint32_t timeout_usec) override; + + /// \brief Receive DHCPv6 packet from interface. + /// + /// \param timeout_sec number of seconds for waiting for a packet, + /// \param timeout_usec number of microseconds for waiting for a packet, + /// \return received packet or nullptr if timed out + virtual dhcp::Pkt6Ptr receive6(uint32_t timeout_sec, uint32_t timeout_usec) override; + + /// \brief Send DHCPv4 packet through interface. + /// + /// \param pkt a packet for sending + /// \return true if operation succeeded + virtual bool send(const dhcp::Pkt4Ptr& pkt) override; + + /// \brief Send DHCPv6 packet through interface. + /// + /// \param pkt a packet for sending + /// \return true if operation succeeded + virtual bool send(const dhcp::Pkt6Ptr& pkt) override; + + /// \brief Get interface from IfaceMgr. + /// + /// \return shared pointer to Iface. + virtual dhcp::IfacePtr getIface() override; + +protected: + /// \brief Initialize socket data. + /// + /// This method initializes members of the class that Interface + /// Manager holds: interface name, local address. + /// + /// \throw isc::BadValue if interface for specified socket + /// descriptor does not exist. + void initSocketData(); + + /// \brief Open socket to communicate with DHCP server. + /// + /// Method opens socket and binds it to local address. Function will + /// use either interface name, local address or server address + /// to create a socket, depending on what is available (specified + /// from the command line). If socket can't be created for any + /// reason, exception is thrown. + /// If destination address is broadcast (for DHCPv4) or multicast + /// (for DHCPv6) than broadcast or multicast option is set on + /// the socket. Opened socket is registered and managed by IfaceMgr. + /// + /// \throw isc::BadValue if socket can't be created for given + /// interface, local address or remote address. + /// \throw isc::InvalidOperation if broadcast option can't be + /// set for the v4 socket or if multicast option can't be set + /// for the v6 socket. + /// \throw isc::Unexpected if internal unexpected error occurred. + /// \return socket descriptor. + int openSocket(CommandOptions& options) const; +}; + +} +} + +#endif /* PERF_SOCKET_H */ |