Skip to content

Commit

Permalink
Replace ip(v6)_mreq structs with libc equivalent
Browse files Browse the repository at this point in the history
  • Loading branch information
Bryant Mairs committed Dec 9, 2017
1 parent 310d205 commit a9022b5
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 64 deletions.
87 changes: 73 additions & 14 deletions src/sys/socket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/*
Expand All @@ -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)]
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
40 changes: 0 additions & 40 deletions src/sys/socket/multicast.rs

This file was deleted.

26 changes: 16 additions & 10 deletions src/sys/socket/sockopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit a9022b5

Please sign in to comment.