summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorBryant Mairs <bryantmairs@google.com>2017-12-05 20:06:23 -0800
committerBryant Mairs <bryantmairs@google.com>2017-12-10 20:47:59 -0800
commit2c4315ac4f81c1ed60ae96ec4a58dc52689b6def (patch)
treee65d173ded42c411ab30bb6350542a03a2daefc0 /src/sys
parent0d78c04d80feb8db1f70a3150e40cd3d29426c01 (diff)
downloadnix-2c4315ac4f81c1ed60ae96ec4a58dc52689b6def.zip
Replace ip(v6)_mreq structs with libc equivalent
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/socket/mod.rs87
-rw-r--r--src/sys/socket/multicast.rs40
-rw-r--r--src/sys/socket/sockopt.rs26
3 files changed, 89 insertions, 64 deletions
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index e456ee53..6292bb02 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -5,14 +5,13 @@ use {Error, Result};
use errno::Errno;
use features;
use libc::{self, c_void, c_int, socklen_t, size_t};
-use std::{mem, ptr, slice};
+use std::{fmt, mem, ptr, slice};
use std::os::unix::io::RawFd;
use sys::time::TimeVal;
use sys::uio::IoVec;
mod addr;
mod ffi;
-mod multicast;
pub mod sockopt;
/*
@@ -34,22 +33,14 @@ pub use self::addr::{
pub use ::sys::socket::addr::netlink::NetlinkAddr;
pub use libc::{
- in_addr,
- in6_addr,
+ sa_family_t,
sockaddr,
sockaddr_in,
sockaddr_in6,
+ sockaddr_storage,
sockaddr_un,
- sa_family_t,
-};
-
-pub use self::multicast::{
- ip_mreq,
- ipv6_mreq,
};
-pub use libc::sockaddr_storage;
-
/// These constants are used to specify the communication semantics
/// when creating a socket with [`socket()`](fn.socket.html)
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -177,8 +168,6 @@ libc_bitflags!{
cfg_if! {
if #[cfg(all(target_os = "linux", not(target_arch = "arm")))] {
- use std::fmt;
-
/// Unix credentials of the sending process.
///
/// This struct is used with the `SO_PEERCRED` ancillary message for UNIX sockets.
@@ -222,6 +211,76 @@ cfg_if! {
}
}
+/// Request for multicast socket operations
+///
+/// This is a wrapper type around `ip_mreq`.
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct IpMembershipRequest(libc::ip_mreq);
+
+impl IpMembershipRequest {
+ /// Instantiate a new `IpMembershipRequest`
+ ///
+ /// If `interface` is `None`, then `Ipv4Addr::any()` will be used for the interface.
+ pub fn new(group: Ipv4Addr, interface: Option<Ipv4Addr>) -> Self {
+ IpMembershipRequest(libc::ip_mreq {
+ imr_multiaddr: group.0,
+ imr_interface: interface.unwrap_or(Ipv4Addr::any()).0,
+ })
+ }
+}
+
+impl PartialEq for IpMembershipRequest {
+ fn eq(&self, other: &Self) -> bool {
+ self.0.imr_multiaddr.s_addr == other.0.imr_multiaddr.s_addr
+ && self.0.imr_interface.s_addr == other.0.imr_interface.s_addr
+ }
+}
+impl Eq for IpMembershipRequest {}
+
+impl fmt::Debug for IpMembershipRequest {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("IpMembershipRequest")
+ .field("imr_multiaddr", &self.0.imr_multiaddr.s_addr)
+ .field("imr_interface", &self.0.imr_interface.s_addr)
+ .finish()
+ }
+}
+
+/// Request for ipv6 multicast socket operations
+///
+/// This is a wrapper type around `ipv6_mreq`.
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct Ipv6MembershipRequest(libc::ipv6_mreq);
+
+impl Ipv6MembershipRequest {
+ /// Instantiate a new `Ipv6MembershipRequest`
+ pub fn new(group: Ipv6Addr) -> Self {
+ Ipv6MembershipRequest(libc::ipv6_mreq {
+ ipv6mr_multiaddr: group.0,
+ ipv6mr_interface: 0,
+ })
+ }
+}
+
+impl PartialEq for Ipv6MembershipRequest {
+ fn eq(&self, other: &Self) -> bool {
+ self.0.ipv6mr_multiaddr.s6_addr == other.0.ipv6mr_multiaddr.s6_addr &&
+ self.0.ipv6mr_interface == other.0.ipv6mr_interface
+ }
+}
+impl Eq for Ipv6MembershipRequest {}
+
+impl fmt::Debug for Ipv6MembershipRequest {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Ipv6MembershipRequest")
+ .field("ipv6mr_multiaddr", &self.0.ipv6mr_multiaddr.s6_addr)
+ .field("ipv6mr_interface", &self.0.ipv6mr_interface)
+ .finish()
+ }
+}
+
/// Copy the in-memory representation of src into the byte slice dst,
/// updating the slice to point to the remainder of dst only. Unsafe
/// because it exposes all bytes in src, which may be UB if some of them
diff --git a/src/sys/socket/multicast.rs b/src/sys/socket/multicast.rs
deleted file mode 100644
index 7561bb35..00000000
--- a/src/sys/socket/multicast.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use super::addr::{Ipv4Addr, Ipv6Addr};
-use libc::{in_addr, in6_addr, c_uint};
-use std::fmt;
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct ip_mreq {
- pub imr_multiaddr: in_addr,
- pub imr_interface: in_addr,
-}
-
-impl fmt::Debug for ip_mreq {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- write!(fmt, "ip_mreq {{ imr_multiaddr: {{ s_addr: 0x{:x} }}, imr_interface: {{ s_addr: 0x{:x} }} }}",
- self.imr_multiaddr.s_addr, self.imr_interface.s_addr)
- }
-}
-
-impl ip_mreq {
- pub fn new(group: Ipv4Addr, interface: Option<Ipv4Addr>) -> ip_mreq {
- ip_mreq {
- imr_multiaddr: group.0,
- imr_interface: interface.unwrap_or(Ipv4Addr::any()).0
- }
- }
-}
-
-pub struct ipv6_mreq {
- pub ipv6mr_multiaddr: in6_addr,
- pub ipv6mr_interface: c_uint,
-}
-
-impl ipv6_mreq {
- pub fn new(group: Ipv6Addr) -> ipv6_mreq {
- ipv6_mreq {
- ipv6mr_multiaddr: group.0,
- ipv6mr_interface: 0,
- }
- }
-}
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index 6737433f..065d3101 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -133,16 +133,22 @@ sockopt_impl!(Both, ReuseAddr, libc::SOL_SOCKET, libc::SO_REUSEADDR, bool);
sockopt_impl!(Both, ReusePort, libc::SOL_SOCKET, libc::SO_REUSEPORT, bool);
sockopt_impl!(Both, TcpNoDelay, libc::IPPROTO_TCP, libc::TCP_NODELAY, bool);
sockopt_impl!(Both, Linger, libc::SOL_SOCKET, libc::SO_LINGER, libc::linger);
-sockopt_impl!(SetOnly, IpAddMembership, libc::IPPROTO_IP, libc::IP_ADD_MEMBERSHIP, super::ip_mreq);
-sockopt_impl!(SetOnly, IpDropMembership, libc::IPPROTO_IP, libc::IP_DROP_MEMBERSHIP, super::ip_mreq);
-#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd")))]
-sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, super::ipv6_mreq);
-#[cfg(not(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd")))]
-sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::ipv6_mreq);
-#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd"))]
-sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_JOIN_GROUP, super::ipv6_mreq);
-#[cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "ios", target_os = "macos", target_os = "netbsd", target_os = "openbsd"))]
-sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_LEAVE_GROUP, super::ipv6_mreq);
+sockopt_impl!(SetOnly, IpAddMembership, libc::IPPROTO_IP, libc::IP_ADD_MEMBERSHIP, super::IpMembershipRequest);
+sockopt_impl!(SetOnly, IpDropMembership, libc::IPPROTO_IP, libc::IP_DROP_MEMBERSHIP, super::IpMembershipRequest);
+cfg_if! {
+ if #[cfg(any(target_os = "android", target_os = "linux"))] {
+ sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_ADD_MEMBERSHIP, super::Ipv6MembershipRequest);
+ sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_DROP_MEMBERSHIP, super::Ipv6MembershipRequest);
+ } else if #[cfg(any(target_os = "dragonfly",
+ target_os = "freebsd",
+ target_os = "ios",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd"))] {
+ sockopt_impl!(SetOnly, Ipv6AddMembership, libc::IPPROTO_IPV6, libc::IPV6_JOIN_GROUP, super::Ipv6MembershipRequest);
+ sockopt_impl!(SetOnly, Ipv6DropMembership, libc::IPPROTO_IPV6, libc::IPV6_LEAVE_GROUP, super::Ipv6MembershipRequest);
+ }
+}
sockopt_impl!(Both, IpMulticastTtl, libc::IPPROTO_IP, libc::IP_MULTICAST_TTL, u8);
sockopt_impl!(Both, IpMulticastLoop, libc::IPPROTO_IP, libc::IP_MULTICAST_LOOP, bool);
sockopt_impl!(Both, ReceiveTimeout, libc::SOL_SOCKET, libc::SO_RCVTIMEO, TimeVal);