Browse Source

[master] Merge branch 'trac1824'

Marcin Siodelski 11 years ago
parent
commit
39c9499d00
2 changed files with 18 additions and 5 deletions
  1. 13 3
      src/lib/dhcp/iface_mgr.cc
  2. 5 2
      src/lib/dhcp/pkt_filter_inet.cc

+ 13 - 3
src/lib/dhcp/iface_mgr.cc

@@ -26,7 +26,8 @@
 #include <exceptions/exceptions.h>
 #include <util/io/pktinfo_utilities.h>
 
-
+#include <cstring>
+#include <errno.h>
 #include <fstream>
 #include <sstream>
 
@@ -892,13 +893,22 @@ IfaceMgr::send(const Pkt6Ptr& pkt) {
     struct in6_pktinfo *pktinfo = convertPktInfo6(CMSG_DATA(cmsg));
     memset(pktinfo, 0, sizeof(struct in6_pktinfo));
     pktinfo->ipi6_ifindex = pkt->getIndex();
-    m.msg_controllen = cmsg->cmsg_len;
+    // According to RFC3542, section 20.2, the msg_controllen field
+    // may be set using CMSG_SPACE (which includes padding) or
+    // using CMSG_LEN. Both forms appear to work fine on Linux, FreeBSD,
+    // NetBSD, but OpenBSD appears to have a bug, discussed here:
+    // http://www.archivum.info/mailing.openbsd.bugs/2009-02/00017/
+    // kernel-6080-msg_controllen-of-IPV6_PKTINFO.html
+    // which causes sendmsg to return EINVAL if the CMSG_LEN is
+    // used to set the msg_controllen value.
+    m.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
 
     pkt->updateTimestamp();
 
     result = sendmsg(getSocket(*pkt), &m, 0);
     if (result < 0) {
-        isc_throw(SocketWriteError, "Pkt6 send failed: sendmsg() returned " << result);
+        isc_throw(SocketWriteError, "pkt6 send failed: sendmsg() returned"
+                  " with an error: " << strerror(errno));
     }
 
     return (result);

+ 5 - 2
src/lib/dhcp/pkt_filter_inet.cc

@@ -16,6 +16,8 @@
 #include <dhcp/iface_mgr.h>
 #include <dhcp/pkt4.h>
 #include <dhcp/pkt_filter_inet.h>
+#include <errno.h>
+#include <cstring>
 
 using namespace isc::asiolink;
 
@@ -235,14 +237,15 @@ PktFilterInet::send(const Iface&, uint16_t sockfd,
     struct in_pktinfo* pktinfo =(struct in_pktinfo *)CMSG_DATA(cmsg);
     memset(pktinfo, 0, sizeof(struct in_pktinfo));
     pktinfo->ipi_ifindex = pkt->getIndex();
-    m.msg_controllen = cmsg->cmsg_len;
+    m.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo));
 #endif
 
     pkt->updateTimestamp();
 
     int result = sendmsg(sockfd, &m, 0);
     if (result < 0) {
-        isc_throw(SocketWriteError, "pkt4 send failed");
+        isc_throw(SocketWriteError, "pkt4 send failed: sendmsg() returned "
+                  " with an error: " << strerror(errno));
     }
 
     return (result);