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/sd_event_loop.cpp b/sd_event_loop.cpp
index 3e42d6c..990426f 100644
--- a/sd_event_loop.cpp
+++ b/sd_event_loop.cpp
@@ -16,45 +16,49 @@
{
using namespace phosphor::logging;
-static int udp623Handler(sd_event_source* es, int fd, uint32_t revents,
- void* userdata)
+void EventLoop::handleRmcpPacket()
{
- std::shared_ptr<udpsocket::Channel> channelPtr;
- struct timeval timeout;
- timeout.tv_sec = SELECT_CALL_TIMEOUT;
- timeout.tv_usec = 0;
-
try
{
- channelPtr.reset(new udpsocket::Channel(fd, timeout));
+ auto channelPtr = std::make_shared<udpsocket::Channel>(udpSocket);
// Initialize the Message Handler with the socket channel
- message::Handler msgHandler(channelPtr);
+ auto msgHandler = std::make_shared<message::Handler>(channelPtr);
// Read the incoming IPMI packet
- std::shared_ptr<message::Message> inMessage(msgHandler.receive());
+ std::shared_ptr<message::Message> inMessage(msgHandler->receive());
if (inMessage == nullptr)
{
- return 0;
+ return;
}
// Execute the Command
- auto outMessage = msgHandler.executeCommand(inMessage);
+ std::shared_ptr<message::Message> outMessage =
+ msgHandler->executeCommand(inMessage);
if (outMessage == nullptr)
{
- return 0;
+ return;
}
-
// Send the response IPMI Message
- msgHandler.send(outMessage);
+ msgHandler->send(outMessage);
}
- catch (std::exception& e)
+ catch (const std::exception& e)
{
- log<level::ERR>("Executing the IPMI message failed");
- log<level::ERR>(e.what());
+ log<level::ERR>("Executing the IPMI message failed",
+ entry("EXCEPTION=%s", e.what()));
}
+}
- return 0;
+void EventLoop::startRmcpReceive()
+{
+ udpSocket->async_wait(boost::asio::socket_base::wait_read,
+ [this](const boost::system::error_code& ec) {
+ if (!ec)
+ {
+ io->post([this]() { startRmcpReceive(); });
+ handleRmcpPacket();
+ }
+ });
}
static int consoleInputHandler(sd_event_source* es, int fd, uint32_t revents,
@@ -174,62 +178,45 @@
int EventLoop::startEventLoop()
{
- int fd = -1;
- int r = 0;
- int listenFd;
- sd_event_source* source = nullptr;
-
sdbusplus::asio::sd_event_wrapper sdEvents(*io);
event = sdEvents.get();
// set up boost::asio signal handling
boost::asio::signal_set signals(*io, SIGINT, SIGTERM);
- signals.async_wait([this](const boost::system::error_code& error,
- int signalNumber) { io->stop(); });
+ signals.async_wait(
+ [this](const boost::system::error_code& error, int signalNumber) {
+ udpSocket->cancel();
+ udpSocket->close();
+ io->stop();
+ });
// Create our own socket if SysD did not supply one.
- listenFd = sd_listen_fds(0);
- if (listenFd == 1)
+ int listensFdCount = sd_listen_fds(0);
+ if (listensFdCount == 1)
{
- fd = SD_LISTEN_FDS_START;
+ if (sd_is_socket(SD_LISTEN_FDS_START, AF_UNSPEC, SOCK_DGRAM, -1))
+ {
+ udpSocket = std::make_shared<boost::asio::ip::udp::socket>(
+ *io, boost::asio::ip::udp::v6(), SD_LISTEN_FDS_START);
+ }
}
- else if (listenFd > 1)
+ else if (listensFdCount > 1)
{
log<level::ERR>("Too many file descriptors received");
- return 1;
- }
- else
- {
- struct sockaddr_in address;
- if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == 0)
- {
- r = -errno;
- log<level::ERR>("Unable to manually open socket");
- return EXIT_FAILURE;
- }
-
- address.sin_family = AF_INET;
- address.sin_addr.s_addr = INADDR_ANY;
- address.sin_port = htons(IPMI_STD_PORT);
-
- if (bind(fd, (struct sockaddr*)&address, sizeof(address)) < 0)
- {
- r = -errno;
- log<level::ERR>("Unable to bind socket");
- close(fd);
- return EXIT_FAILURE;
- }
- }
-
- r = sd_event_add_io(event, &source, fd, EPOLLIN, udp623Handler, nullptr);
- if (r < 0)
- {
- close(fd);
return EXIT_FAILURE;
}
-
- udpIPMI.reset(source);
- source = nullptr;
+ if (!udpSocket)
+ {
+ udpSocket = std::make_shared<boost::asio::ip::udp::socket>(
+ *io, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v6(),
+ IPMI_STD_PORT));
+ if (!udpSocket)
+ {
+ log<level::ERR>("Failed to start listening on RMCP socket");
+ return EXIT_FAILURE;
+ }
+ }
+ startRmcpReceive();
io->run();