netipmid: move raw sockets to boost::asio sockets
Replacing the raw socket code with boost::asio sockets once again
provides a simple API with fewer lines of code.
Change-Id: Ibdd4b5ecbead947128200f17025c351d9b3ec859
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/socket_channel.hpp b/socket_channel.hpp
index 4b10b9a..ebe0c8f 100644
--- a/socket_channel.hpp
+++ b/socket_channel.hpp
@@ -1,8 +1,7 @@
#pragma once
-#include <arpa/inet.h>
-#include <unistd.h>
-
+#include <boost/asio/ip/udp.hpp>
+#include <memory>
#include <string>
#include <tuple>
#include <vector>
@@ -18,28 +17,24 @@
class Channel
{
public:
- struct SockAddr_t
- {
- union
- {
- sockaddr sockAddr;
- sockaddr_in6 inAddr;
- };
- socklen_t addrSize;
- };
+ Channel() = delete;
+ ~Channel() = default;
+ Channel(const Channel& right) = delete;
+ Channel& operator=(const Channel& right) = delete;
+ Channel(Channel&&) = delete;
+ Channel& operator=(Channel&&) = delete;
/**
* @brief Constructor
*
* Initialize the IPMI socket object with the socket descriptor
*
- * @param [in] File Descriptor for the socket
- * @param [in] Timeout parameter for the select call
+ * @param [in] pointer to a boost::asio udp socket object
*
* @return None
*/
- Channel(int insockfd, timeval& inTimeout) :
- sockfd(insockfd), timeout(inTimeout)
+ explicit Channel(std::shared_ptr<boost::asio::ip::udp::socket> socket) :
+ socket(socket)
{
}
@@ -51,7 +46,10 @@
*
* @return IP address of the remote peer
*/
- std::string getRemoteAddress() const;
+ std::string getRemoteAddress() const
+ {
+ return endpoint.address().to_string();
+ }
/**
* @brief Fetch the port number of the remote peer
@@ -63,7 +61,7 @@
*/
auto getPort() const
{
- return address.inAddr.sin6_port;
+ return endpoint.port();
}
/**
@@ -77,7 +75,19 @@
* In case of error, the return code is < 0 and vector is set
* to size 0.
*/
- std::tuple<int, std::vector<uint8_t>> read();
+ std::tuple<int, std::vector<uint8_t>> read()
+ {
+ std::vector<uint8_t> packet(socket->available());
+ try
+ {
+ socket->receive_from(boost::asio::buffer(packet), endpoint);
+ }
+ catch (const boost::system::system_error& e)
+ {
+ return std::make_tuple(e.code().value(), std::vector<uint8_t>());
+ }
+ return std::make_tuple(0, packet);
+ }
/**
* @brief Write the outgoing packet
@@ -90,33 +100,30 @@
* @return In case of success the return code is 0 and return code is
* < 0 in case of failure.
*/
- int write(const std::vector<uint8_t>& inBuffer);
+ int write(const std::vector<uint8_t>& inBuffer)
+ {
+ try
+ {
+ socket->send_to(boost::asio::buffer(inBuffer), endpoint);
+ }
+ catch (const boost::system::system_error& e)
+ {
+ return e.code().value();
+ }
+ return 0;
+ }
/**
* @brief Returns file descriptor for the socket
*/
auto getHandle(void) const
{
- return sockfd;
+ return socket->native_handle();
}
- ~Channel() = default;
- Channel(const Channel& right) = delete;
- Channel& operator=(const Channel& right) = delete;
- Channel(Channel&&) = default;
- Channel& operator=(Channel&&) = default;
-
private:
- /*
- * The socket descriptor is the UDP server socket for the IPMI port.
- * The same socket descriptor is used for multiple ipmi clients and the
- * life of the descriptor is lifetime of the net-ipmid server. So we
- * do not need to close the socket descriptor in the cleanup of the
- * udpsocket class.
- */
- int sockfd;
- SockAddr_t address;
- timeval timeout;
+ std::shared_ptr<boost::asio::ip::udp::socket> socket;
+ boost::asio::ip::udp::endpoint endpoint{};
};
} // namespace udpsocket