Browse Source

[1824] Use CMSG_SPACE instead of CMSG_LEN to set msg_controllen.

Both macros should be accepted, but CMSG_LEN appears not to work on
OpenBSD.
Marcin Siodelski 11 years ago
parent
commit
5862eb4c98
2 changed files with 10 additions and 2 deletions
  1. 9 1
      src/lib/dhcp/iface_mgr.cc
  2. 1 1
      src/lib/dhcp/pkt_filter_inet.cc

+ 9 - 1
src/lib/dhcp/iface_mgr.cc

@@ -892,7 +892,15 @@ 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();
 

+ 1 - 1
src/lib/dhcp/pkt_filter_inet.cc

@@ -235,7 +235,7 @@ 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();