summaryrefslogtreecommitdiffstats
path: root/src/bin/perfdhcp/perf_socket.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/perfdhcp/perf_socket.h')
-rw-r--r--src/bin/perfdhcp/perf_socket.h143
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..56a8551
--- /dev/null
+++ b/src/bin/perfdhcp/perf_socket.h
@@ -0,0 +1,143 @@
+// Copyright (C) 2012-2019 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.
+ uint16_t 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 */