The attached patch fixes running the test suite under FreeBSD. It seems that IP_SENDSRCADDR doesn't like the situation where the interface is bound to a specific address, even if the passed in address is the same.

It runs fine if the interface is bound to INADDR_ANY

It also tries to fix bug 3525233.

Any votes for applying it?

/Niels

--
Niels Baggesen -- @home -- Ã…rhus -- Denmark -- ni...@baggesen.net
The purpose of computing is insight, not numbers  --  R W Hamming

diff --git a/include/net-snmp/library/snmpUDPBaseDomain.h b/include/net-snmp/library/snmpUDPBaseDomain.h
index e61cdc8..0a09f52 100644
--- a/include/net-snmp/library/snmpUDPBaseDomain.h
+++ b/include/net-snmp/library/snmpUDPBaseDomain.h
@@ -9,6 +9,24 @@ config_require(SocketBase)
 extern          "C" {
 #endif
 
+#ifdef  MSG_DONTWAIT
+#define NETSNMP_DONTWAIT MSG_DONTWAIT
+#else
+#define NETSNMP_DONTWAIT 0
+#endif
+
+#ifdef  MSG_NOSIGNAL
+#define NETSNMP_NOSIGNAL MSG_NOSIGNAL
+#else
+#define NETSNMP_NOSIGNAL 0
+#endif
+
+#if defined(IP_RECVDSTADDR) && defined(__DragonFly__)
+# ifndef IP_SENDSRCADDR
+#  define IP_SENDSRCADDR IP_RECVDSTADDR /* DragonFly BSD */
+# endif
+#endif
+
 /*
  * Prototypes
  */
diff --git a/snmplib/transports/snmpUDPBaseDomain.c b/snmplib/transports/snmpUDPBaseDomain.c
index 5e680da..16e8581 100644
--- a/snmplib/transports/snmpUDPBaseDomain.c
+++ b/snmplib/transports/snmpUDPBaseDomain.c
@@ -3,9 +3,6 @@
 
 #include <net-snmp/net-snmp-config.h>
 
-#include <net-snmp/types.h>
-#include <net-snmp/library/snmpUDPBaseDomain.h>
-
 #include <stddef.h>
 #include <stdio.h>
 #include <sys/types.h>
@@ -37,6 +34,7 @@
 
 #include <net-snmp/types.h>
 #include <net-snmp/library/snmpSocketBaseDomain.h>
+#include <net-snmp/library/snmpUDPBaseDomain.h>
 #include <net-snmp/library/snmpUDPDomain.h>
 #include <net-snmp/library/snmp_debug.h>
 #include <net-snmp/library/tools.h>
@@ -92,15 +90,7 @@ _netsnmp_udp_sockopt_set(int fd, int local)
     netsnmp_sock_buffer_set(fd, SO_RCVBUF, local, 0);
 }
 
-#if (defined(linux) && defined(IP_PKTINFO)) \
-    || defined(IP_RECVDSTADDR) && HAVE_STRUCT_MSGHDR_MSG_CONTROL \
-                               && HAVE_STRUCT_MSGHDR_MSG_FLAGS
-#if  defined(linux) && defined(IP_PKTINFO)
-#elif defined(IP_RECVDSTADDR)
-# ifndef IP_SENDSRCADDR
-#  define IP_SENDSRCADDR IP_RECVDSTADDR /* DragonFly BSD */
-# endif
-#endif
+#if (defined(linux) && defined(IP_PKTINFO)) || defined(IP_SENDSRCADDR)
 
 #define netsnmp_udpbase_recvfrom_sendto_defined
 
@@ -179,6 +169,7 @@ int netsnmp_udpbase_sendto(int fd, struct in_addr *srcip, int if_index,
     struct iovec iov;
     struct msghdr m = { 0 };
     char          cmsg[CMSG_SPACE(cmsg_data_size)];
+    int           rc;
 
     iov.iov_base = data;
     iov.iov_len  = len;
@@ -213,17 +204,9 @@ int netsnmp_udpbase_sendto(int fd, struct in_addr *srcip, int if_index,
             memcpy(CMSG_DATA(cm), &ipi, sizeof(ipi));
         }
 
-        {
-            errno = 0;
-#ifdef MSG_NOSIGNAL
-            const int rc = sendmsg(fd, &m, MSG_NOSIGNAL|MSG_DONTWAIT);
-#else
-            const int rc = sendmsg(fd, &m, MSG_DONTWAIT);
-#endif
-
-            if (rc >= 0 || errno != EINVAL)
-                return rc;
-        }
+        rc = sendmsg(fd, &m, NETSNMP_NOSIGNAL|NETSNMP_DONTWAIT);
+        if (rc >= 0 || errno != EINVAL)
+            return rc;
 
         /*
          * The error might be caused by broadcast srcip (i.e. we're responding
@@ -244,15 +227,18 @@ int netsnmp_udpbase_sendto(int fd, struct in_addr *srcip, int if_index,
         cm->cmsg_type = IP_SENDSRCADDR;
         memcpy((struct in_addr *)CMSG_DATA(cm), srcip, sizeof(struct in_addr));
 #endif
+        rc = sendmsg(fd, &m, NETSNMP_NOSIGNAL|NETSNMP_DONTWAIT);
+        if (rc >= 0 || errno != EINVAL)
+            return rc;
+
+        DEBUGMSGTL(("udpbase:sendto", "re-sending without source address\n"));
+        m.msg_control = NULL;
+        m.msg_controllen = 0;
     }
 
-#ifdef MSG_NOSIGNAL
-    return sendmsg(fd, &m, MSG_NOSIGNAL|MSG_DONTWAIT);
-#else
-    return sendmsg(fd, &m, MSG_DONTWAIT);
-#endif
+    return sendmsg(fd, &m, NETSNMP_NOSIGNAL|NETSNMP_DONTWAIT);
 }
-#endif /* (linux && IP_PKTINFO) || IP_RECVDSTADDR */
+#endif /* (linux && IP_PKTINFO) || IP_SENDSRCADDR */
 
 /*
  * You can write something into opaque that will subsequently get passed back 
diff --git a/snmplib/transports/snmpUDPDomain.c b/snmplib/transports/snmpUDPDomain.c
index 638c2b1..1700ae0 100644
--- a/snmplib/transports/snmpUDPDomain.c
+++ b/snmplib/transports/snmpUDPDomain.c
@@ -11,10 +11,6 @@
 
 #include <net-snmp/net-snmp-config.h>
 
-#include <net-snmp/types.h>
-#include <net-snmp/library/snmpUDPDomain.h>
-#include <net-snmp/library/snmpUDPIPv4BaseDomain.h>
-
 #include <stddef.h>
 #include <stdio.h>
 #include <sys/types.h>
@@ -57,6 +53,8 @@
 #include <net-snmp/config_api.h>
 
 #include <net-snmp/library/snmp_transport.h>
+#include <net-snmp/library/snmpUDPDomain.h>
+#include <net-snmp/library/snmpUDPIPv4BaseDomain.h>
 #include <net-snmp/library/snmpSocketBaseDomain.h>
 #include <net-snmp/library/system.h>
 #include <net-snmp/library/tools.h>
@@ -102,9 +100,7 @@ netsnmp_udp_fmtaddr(netsnmp_transport *t, void *data, int len)
 
 
 
-#if (defined(linux) && defined(IP_PKTINFO)) \
-    || defined(IP_RECVDSTADDR) && HAVE_STRUCT_MSGHDR_MSG_CONTROL \
-                               && HAVE_STRUCT_MSGHDR_MSG_FLAGS
+#if (defined(linux) && defined(IP_PKTINFO)) || defined(IP_SENDSRCADDR)
 
 int netsnmp_udp_recvfrom(int s, void *buf, int len, struct sockaddr *from, socklen_t *fromlen, struct sockaddr *dstip, socklen_t *dstlen, int *if_index)
 {
diff --git a/snmplib/transports/snmpUDPIPv4BaseDomain.c b/snmplib/transports/snmpUDPIPv4BaseDomain.c
index 10dd491..db86150 100644
--- a/snmplib/transports/snmpUDPIPv4BaseDomain.c
+++ b/snmplib/transports/snmpUDPIPv4BaseDomain.c
@@ -3,9 +3,6 @@
 
 #include <net-snmp/net-snmp-config.h>
 
-#include <net-snmp/types.h>
-#include <net-snmp/library/snmpUDPIPv4BaseDomain.h>
-
 #include <stddef.h>
 #include <stdio.h>
 #include <sys/types.h>
@@ -39,10 +36,10 @@
 #include <net-snmp/library/default_store.h>
 
 #include <net-snmp/library/snmpSocketBaseDomain.h>
+#include <net-snmp/library/snmpUDPIPv4BaseDomain.h>
+#include <net-snmp/library/snmpUDPBaseDomain.h>
 
-#if (defined(linux) && defined(IP_PKTINFO)) \
-    || defined(IP_RECVDSTADDR) && HAVE_STRUCT_MSGHDR_MSG_CONTROL \
-                               && HAVE_STRUCT_MSGHDR_MSG_FLAGS
+#if (defined(linux) && defined(IP_PKTINFO)) || defined(IP_SENDSRCADDR)
 
 int netsnmp_udpipv4_recvfrom(int s, void *buf, int len, struct sockaddr *from,
                              socklen_t *fromlen, struct sockaddr *dstip,
@@ -57,7 +54,7 @@ int netsnmp_udpipv4_sendto(int fd, struct in_addr *srcip, int if_index,
 {
     return netsnmp_udpbase_sendto(fd, srcip, if_index, remote, data, len);
 }
-#endif /* (linux && IP_PKTINFO) || IP_RECVDSTADDR */
+#endif /* (linux && IP_PKTINFO) || IP_SENDSRCADDR */
 
 netsnmp_transport *
 netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local)
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Net-snmp-coders mailing list
Net-snmp-coders@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to