From 78347d1618492ee9930a036fd835710b616ccd15 Mon Sep 17 00:00:00 2001 From: Perry Lorier Date: Sun, 26 Apr 2020 13:16:21 +0100 Subject: Add Ipv{4,6}PacketInfo support to ControlMessage for send{m,}msg This adds Ipv4PacketInfo and Ipv6PacketInfo to ControlMessage, allowing these to be used with sendmsg/sendmmsg. This change contains the following squashed commits: Add Ipv{4,6}PacketInfo to ControlMessage. Add documentation links to Ipv{4,6}PacketInfo Add changelog entry for Ipv{4,6}PacketInfo Add link to PR in the Changelog. Add extra build environments. Add tests for Ipv{4,6}PacketInfo. Swap #[test] and #[cfg] The CI appears to be running the test, even though it's not cfg'd for that platform. I _think_ this might be due to these being in the wrong order. So lets try swapping them. s/freebsd/netbsd/ for Ipv4PacketInfo netbsd supports in_pktinfo, not freebsd. Fix the cfg for Ipv{4,6}PacketInfo usage. Ah, I see what I did wrong. I had fixed the definitions, but I had the wrong cfg() in the usage. This has the usage match the definitions. Change SOL_IPV6 to IPPROTO_IPV6. FreeBSD doesn't have SOL_IPV6, but does have IPPROTO_IPV6, and the two constants are defined as being equal. So change to use IPPROTO_IPV6. Skip Ipv6PacketInfo test if v6 is not available. If IPv6 is not available, then when we try and bind to ip6-localhost, we'll get a EADDRNOTAVAIL, so skip the test. This should mean that the test will run on any machine that has a v6 loopback address. More architecture cfg() fixes. These all need to be the same, and they were not. Make them them all the same. Attempt III. Fix up mismatched cfg's again. Take IV. Make sure the cfg's that use a enum variant match the enum definition. --- src/sys/socket/mod.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'src/sys/socket/mod.rs') diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 6909c154..b972835f 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -717,6 +717,25 @@ pub enum ControlMessage<'a> { /// following one by one, and the last, possibly smaller one. #[cfg(target_os = "linux")] UdpGsoSegments(&'a u16), + + /// Configure the sending addressing and interface for v4 + /// + /// For further information, please refer to the + /// [`ip(7)`](http://man7.org/linux/man-pages/man7/ip.7.html) man page. + #[cfg(any(target_os = "linux", + target_os = "macos", + target_os = "netbsd"))] + Ipv4PacketInfo(&'a libc::in_pktinfo), + + /// Configure the sending addressing and interface for v6 + /// + /// For further information, please refer to the + /// [`ipv6(7)`](http://man7.org/linux/man-pages/man7/ipv6.7.html) man page. + #[cfg(any(target_os = "linux", + target_os = "macos", + target_os = "netbsd", + target_os = "freebsd"))] + Ipv6PacketInfo(&'a libc::in6_pktinfo), } // An opaque structure used to prevent cmsghdr from being a public type @@ -798,6 +817,12 @@ impl<'a> ControlMessage<'a> { ControlMessage::UdpGsoSegments(gso_size) => { gso_size as *const _ as *const u8 }, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd"))] + ControlMessage::Ipv4PacketInfo(info) => info as *const _ as *const u8, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "freebsd"))] + ControlMessage::Ipv6PacketInfo(info) => info as *const _ as *const u8, }; unsafe { ptr::copy_nonoverlapping( @@ -838,6 +863,12 @@ impl<'a> ControlMessage<'a> { ControlMessage::UdpGsoSegments(gso_size) => { mem::size_of_val(gso_size) }, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd"))] + ControlMessage::Ipv4PacketInfo(info) => mem::size_of_val(info), + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "freebsd"))] + ControlMessage::Ipv6PacketInfo(info) => mem::size_of_val(info), } } @@ -854,6 +885,12 @@ impl<'a> ControlMessage<'a> { ControlMessage::AlgSetAeadAssoclen(_) => libc::SOL_ALG, #[cfg(target_os = "linux")] ControlMessage::UdpGsoSegments(_) => libc::SOL_UDP, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd"))] + ControlMessage::Ipv4PacketInfo(_) => libc::IPPROTO_IP, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "freebsd"))] + ControlMessage::Ipv6PacketInfo(_) => libc::IPPROTO_IPV6, } } @@ -881,6 +918,12 @@ impl<'a> ControlMessage<'a> { ControlMessage::UdpGsoSegments(_) => { libc::UDP_SEGMENT }, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd"))] + ControlMessage::Ipv4PacketInfo(_) => libc::IP_PKTINFO, + #[cfg(any(target_os = "linux", target_os = "macos", + target_os = "netbsd", target_os = "freebsd"))] + ControlMessage::Ipv6PacketInfo(_) => libc::IPV6_PKTINFO, } } -- cgit v1.2.3