Change the send Buffer size dynamically

On a Linux system the send buffer size has defaulted
to around 90k, and when a pldm message is sent via
the pldm_send() that is bigger than 90k, we get an error
ENOBUFS (No buffer space avilable).

This commit would dynamically change the socket parameter
(SO_SNDBUF) to set the new maximum socket send buffer size
so that we can successfully send the message.

Tested By:

1. hard coded the current buffer size value to 10 and forced
   the buffer size to be increase for mutiple commands & was able
   to power on the host with out any problems.

Signed-off-by: Manojkiran Eda <manojkiran.eda@gmail.com>
Change-Id: I5f7a3948ea019b4dc983cf5e1926cfc128c02084
diff --git a/pldmd/pldmd.cpp b/pldmd/pldmd.cpp
index d23acf8..d48844f 100644
--- a/pldmd/pldmd.cpp
+++ b/pldmd/pldmd.cpp
@@ -177,7 +177,19 @@
         std::cerr << "Failed to create the socket, RC= " << returnCode << "\n";
         exit(EXIT_FAILURE);
     }
+    socklen_t optlen;
+    int currentSendbuffSize;
 
+    // Get Current send buffer size
+    optlen = sizeof(currentSendbuffSize);
+
+    int res = getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &currentSendbuffSize,
+                         &optlen);
+    if (res == -1)
+    {
+        std::cerr << "Error in obtaining the default send buffer size, Error : "
+                  << strerror(errno) << std::endl;
+    }
     auto event = Event::get_default();
     auto& bus = pldm::utils::DBusHandler::getBus();
     sdbusplus::server::manager::manager objManager(
@@ -185,8 +197,9 @@
     dbus_api::Requester dbusImplReq(bus, "/xyz/openbmc_project/pldm");
 
     Invoker invoker{};
-    requester::Handler<requester::Request> reqHandler(sockfd, event,
-                                                      dbusImplReq, verbose);
+    requester::Handler<requester::Request> reqHandler(
+        sockfd, event, dbusImplReq, currentSendbuffSize, verbose);
+
 #ifdef LIBPLDMRESPONDER
     using namespace pldm::state_sensor;
     dbus_api::Host dbusImplHost(bus, "/xyz/openbmc_project/pldm");
@@ -299,8 +312,8 @@
     std::unique_ptr<MctpDiscovery> mctpDiscoveryHandler =
         std::make_unique<MctpDiscovery>(bus, fwManager.get());
 
-    auto callback = [verbose, &invoker, &reqHandler,
-                     &fwManager](IO& io, int fd, uint32_t revents) {
+    auto callback = [verbose, &invoker, &reqHandler, currentSendbuffSize,
+                     &fwManager](IO& io, int fd, uint32_t revents) mutable {
         if (!(revents & EPOLLIN))
         {
             return;
@@ -366,6 +379,26 @@
 
                         msg.msg_iov = iov;
                         msg.msg_iovlen = sizeof(iov) / sizeof(iov[0]);
+                        if (currentSendbuffSize >= 0 &&
+                            (size_t)currentSendbuffSize < (*response).size())
+                        {
+                            int oldBuffSize = currentSendbuffSize;
+                            currentSendbuffSize = (*response).size();
+                            int res = setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
+                                                 &currentSendbuffSize,
+                                                 sizeof(currentSendbuffSize));
+                            if (res == -1)
+                            {
+                                std::cerr
+                                    << "Responder : Failed to set the new send buffer size [bytes] : "
+                                    << currentSendbuffSize
+                                    << " from current size [bytes] : "
+                                    << oldBuffSize
+                                    << ", Error : " << strerror(errno)
+                                    << std::endl;
+                                return;
+                            }
+                        }
 
                         int result = sendmsg(fd, &msg, 0);
                         if (-1 == result)