[AGENT++] Prevent inheriting file descriptor of the opened sockets to child processes

Isaac Nickaein isaac at aut.ac.ir
Thu Jul 27 16:40:39 CEST 2017


Hi,

An application that uses SNMP++ can have problems when spawning new
processes. The child process(es) inherit file descriptor of the
currently running SNMP agent.

To fix this set *FD_CLOEXEC* flag while opening the sockets. The
following patch performs this on SNMP++-3.3.9.

Is this a reasonable way to fix this?

A similar patch would be needed for AgentX++ where it opens a TCP/Unix
socket to subagents.

Bests,
Isaac

diff -up sources/snmp++-3.3.9/src/notifyqueue.cpp
source_patched/snmp++-3.3.9/src/notifyqueue.cpp
--- sources/snmp++-3.3.9/src/notifyqueue.cpp 2013-05-10 12:43:53.000000000 +0430
+++ source_patched/snmp++-3.3.9/src/notifyqueue.cpp 2017-04-09
09:17:41.436480261 +0430
@@ -66,6 +66,10 @@ char notifyqueue_version[]="#(@) SNMP++
 #include <sockLib.h>
 #endif

+#ifndef WIN32
+#include <fcntl.h>
+#endif
+
 //----[ snmp++ includes ]----------------------------------------------

 #include "snmp_pp/config_snmp_pp.h"
@@ -367,6 +371,16 @@ int CNotifyEventQueue::AddEntry(Snmp *sn
         return status;
       }

+#ifndef WIN32
+      // set FD_CLOEXEC to prevent inheriting the file
+      // descriptor of the socket to the child processes
+      {
+        int socket_fd_flags = fcntl(m_notify_fd, F_GETFD, 0);
+        socket_fd_flags |= FD_CLOEXEC;
+        fcntl(m_notify_fd, F_SETFD, socket_fd_flags);
+      }
+#endif
+
       // set up the manager socket attributes
       unsigned long inaddr =
inet_addr(IpAddress(m_notify_addr).get_printable());
       memset(&mgr_addr, 0, sizeof(mgr_addr));
@@ -449,6 +463,16 @@ int CNotifyEventQueue::AddEntry(Snmp *sn
         return status;
       }

+#ifndef WIN32
+      // set FD_CLOEXEC to prevent inheriting the file
+      // descriptor of the socket to the child processes
+      {
+        int socket_fd_flags = fcntl(m_notify_fd, F_GETFD, 0);
+        socket_fd_flags |= FD_CLOEXEC;
+        fcntl(m_notify_fd, F_SETFD, socket_fd_flags);
+      }
+#endif
+
 #ifdef NOTIFY_SET_IPV6_V6ONLY
       int on = 1;
       if (setsockopt(m_notify_fd, IPPROTO_IPV6, IPV6_V6ONLY,
diff -up sources/snmp++-3.3.9/src/uxsnmp.cpp
source_patched/snmp++-3.3.9/src/uxsnmp.cpp
--- sources/snmp++-3.3.9/src/uxsnmp.cpp 2016-10-24 02:43:54.000000000 +0330
+++ source_patched/snmp++-3.3.9/src/uxsnmp.cpp 2017-04-09
09:17:50.140480308 +0430
@@ -48,6 +48,10 @@ char snmp_cpp_version[]="#(@) SNMP++ $Id
 #include <taskLib.h>
 #endif

+#ifndef WIN32
+#include <fcntl.h>
+#endif
+
 //----[ snmp++ includes ]----------------------------------------------
 #include "snmp_pp/config_snmp_pp.h"
 #include "snmp_pp/uxsnmp.h"        // class def for this module
@@ -735,6 +739,16 @@ void Snmp::init(int& status, IpAddress *
       mgr_addr.sin_len = sizeof(mgr_addr);
 #endif

+#ifndef WIN32
+      // set FD_CLOEXEC to prevent inheriting the file
+      // descriptor of the socket to the child processes
+      {
+        int socket_fd_flags = fcntl (iv_snmp_session, F_GETFD, 0);
+        socket_fd_flags |= FD_CLOEXEC;
+        fcntl(iv_snmp_session, F_SETFD, socket_fd_flags);
+      }
+#endif
+
       // bind the socket
       if (bind(iv_snmp_session, (struct sockaddr*)&mgr_addr,
                sizeof(mgr_addr)) < 0)
@@ -816,6 +830,17 @@ void Snmp::init(int& status, IpAddress *
     }
     else
     {
+
+#ifndef WIN32
+      // set FD_CLOEXEC to prevent inheriting the file
+      // descriptor of the socket to the child processes
+      {
+        int socket_fd_flags = fcntl(iv_snmp_session_ipv6, F_GETFD, 0);
+        socket_fd_flags |= FD_CLOEXEC;
+        fcntl(iv_snmp_session_ipv6, F_SETFD, socket_fd_flags);
+      }
+#endif
+
       // set up the manager socket attributes
       struct sockaddr_in6 mgr_addr;
       memset(&mgr_addr, 0, sizeof(mgr_addr));


More information about the AGENTPP mailing list