Nuke deprecated net APIs

Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
This commit is contained in:
Alex Saveau 2022-11-11 19:47:39 -08:00
parent 05f925a888
commit f3aa1affb0
No known key found for this signature in database
GPG Key ID: 3F8D5B16EB169D48
4 changed files with 17 additions and 846 deletions

View File

@ -16,6 +16,8 @@ This project adheres to [Semantic Versioning](https://semver.org/).
- Removed deprecated IoVec API.
([#1855](https://github.com/nix-rust/nix/pull/1855))
- Removed deprecated net APIs.
([#1861](https://github.com/nix-rust/nix/pull/1861))
## [0.26.1] - 2022-11-29
### Fixed

View File

@ -33,8 +33,6 @@ use std::convert::TryInto;
use std::ffi::OsStr;
use std::hash::{Hash, Hasher};
use std::os::unix::ffi::OsStrExt;
#[cfg(any(target_os = "ios", target_os = "macos"))]
use std::os::unix::io::RawFd;
use std::path::Path;
use std::{fmt, mem, net, ptr, slice};
@ -445,308 +443,6 @@ impl AddressFamily {
}
}
feature! {
#![feature = "net"]
#[deprecated(
since = "0.24.0",
note = "use SockaddrIn, SockaddrIn6, or SockaddrStorage instead"
)]
#[allow(missing_docs)] // Since they're all deprecated anyway
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum InetAddr {
V4(libc::sockaddr_in),
V6(libc::sockaddr_in6),
}
#[allow(missing_docs)] // It's deprecated anyway
#[allow(deprecated)]
impl InetAddr {
#[allow(clippy::needless_update)] // It isn't needless on all OSes
pub fn from_std(std: &net::SocketAddr) -> InetAddr {
match *std {
net::SocketAddr::V4(ref addr) => {
InetAddr::V4(libc::sockaddr_in {
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
target_os = "haiku", target_os = "hermit",
target_os = "ios", target_os = "macos",
target_os = "netbsd", target_os = "openbsd"))]
sin_len: mem::size_of::<libc::sockaddr_in>() as u8,
sin_family: AddressFamily::Inet as sa_family_t,
sin_port: addr.port().to_be(), // network byte order
sin_addr: Ipv4Addr::from_std(addr.ip()).0,
.. unsafe { mem::zeroed() }
})
}
net::SocketAddr::V6(ref addr) => {
InetAddr::V6(libc::sockaddr_in6 {
#[cfg(any(target_os = "dragonfly", target_os = "freebsd",
target_os = "haiku", target_os = "hermit",
target_os = "ios", target_os = "macos",
target_os = "netbsd", target_os = "openbsd"))]
sin6_len: mem::size_of::<libc::sockaddr_in6>() as u8,
sin6_family: AddressFamily::Inet6 as sa_family_t,
sin6_port: addr.port().to_be(), // network byte order
sin6_addr: Ipv6Addr::from_std(addr.ip()).0,
sin6_flowinfo: addr.flowinfo(), // host byte order
sin6_scope_id: addr.scope_id(), // host byte order
.. unsafe { mem::zeroed() }
})
}
}
}
#[allow(clippy::needless_update)] // It isn't needless on all OSes
pub fn new(ip: IpAddr, port: u16) -> InetAddr {
match ip {
IpAddr::V4(ref ip) => {
InetAddr::V4(libc::sockaddr_in {
sin_family: AddressFamily::Inet as sa_family_t,
sin_port: port.to_be(),
sin_addr: ip.0,
.. unsafe { mem::zeroed() }
})
}
IpAddr::V6(ref ip) => {
InetAddr::V6(libc::sockaddr_in6 {
sin6_family: AddressFamily::Inet6 as sa_family_t,
sin6_port: port.to_be(),
sin6_addr: ip.0,
.. unsafe { mem::zeroed() }
})
}
}
}
/// Gets the IP address associated with this socket address.
pub const fn ip(&self) -> IpAddr {
match *self {
InetAddr::V4(ref sa) => IpAddr::V4(Ipv4Addr(sa.sin_addr)),
InetAddr::V6(ref sa) => IpAddr::V6(Ipv6Addr(sa.sin6_addr)),
}
}
/// Gets the port number associated with this socket address
pub const fn port(&self) -> u16 {
match *self {
InetAddr::V6(ref sa) => u16::from_be(sa.sin6_port),
InetAddr::V4(ref sa) => u16::from_be(sa.sin_port),
}
}
pub fn to_std(&self) -> net::SocketAddr {
match *self {
InetAddr::V4(ref sa) => net::SocketAddr::V4(
net::SocketAddrV4::new(
Ipv4Addr(sa.sin_addr).to_std(),
self.port())),
InetAddr::V6(ref sa) => net::SocketAddr::V6(
net::SocketAddrV6::new(
Ipv6Addr(sa.sin6_addr).to_std(),
self.port(),
sa.sin6_flowinfo,
sa.sin6_scope_id)),
}
}
#[deprecated(since = "0.23.0", note = "use .to_string() instead")]
pub fn to_str(&self) -> String {
format!("{}", self)
}
}
#[allow(deprecated)]
impl fmt::Display for InetAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
InetAddr::V4(_) => write!(f, "{}:{}", self.ip(), self.port()),
InetAddr::V6(_) => write!(f, "[{}]:{}", self.ip(), self.port()),
}
}
}
/*
*
* ===== IpAddr =====
*
*/
#[allow(missing_docs)] // Since they're all deprecated anyway
#[allow(deprecated)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[deprecated(
since = "0.24.0",
note = "Use std::net::IpAddr instead"
)]
pub enum IpAddr {
V4(Ipv4Addr),
V6(Ipv6Addr),
}
#[allow(deprecated)]
#[allow(missing_docs)] // Since they're all deprecated anyway
impl IpAddr {
/// Create a new IpAddr that contains an IPv4 address.
///
/// The result will represent the IP address a.b.c.d
pub const fn new_v4(a: u8, b: u8, c: u8, d: u8) -> IpAddr {
IpAddr::V4(Ipv4Addr::new(a, b, c, d))
}
/// Create a new IpAddr that contains an IPv6 address.
///
/// The result will represent the IP address a:b:c:d:e:f
#[allow(clippy::many_single_char_names)]
#[allow(clippy::too_many_arguments)]
pub const fn new_v6(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> IpAddr {
IpAddr::V6(Ipv6Addr::new(a, b, c, d, e, f, g, h))
}
pub fn from_std(std: &net::IpAddr) -> IpAddr {
match *std {
net::IpAddr::V4(ref std) => IpAddr::V4(Ipv4Addr::from_std(std)),
net::IpAddr::V6(ref std) => IpAddr::V6(Ipv6Addr::from_std(std)),
}
}
pub const fn to_std(&self) -> net::IpAddr {
match *self {
IpAddr::V4(ref ip) => net::IpAddr::V4(ip.to_std()),
IpAddr::V6(ref ip) => net::IpAddr::V6(ip.to_std()),
}
}
}
#[allow(deprecated)]
impl fmt::Display for IpAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
IpAddr::V4(ref v4) => v4.fmt(f),
IpAddr::V6(ref v6) => v6.fmt(f)
}
}
}
/*
*
* ===== Ipv4Addr =====
*
*/
#[deprecated(
since = "0.24.0",
note = "Use std::net::Ipv4Addr instead"
)]
#[allow(missing_docs)] // Since they're all deprecated anyway
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(transparent)]
pub struct Ipv4Addr(pub libc::in_addr);
#[allow(deprecated)]
#[allow(missing_docs)] // Since they're all deprecated anyway
impl Ipv4Addr {
#[allow(clippy::identity_op)] // More readable this way
pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
let ip = (((a as u32) << 24) |
((b as u32) << 16) |
((c as u32) << 8) |
((d as u32) << 0)).to_be();
Ipv4Addr(libc::in_addr { s_addr: ip })
}
// Use pass by reference for symmetry with Ipv6Addr::from_std
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn from_std(std: &net::Ipv4Addr) -> Ipv4Addr {
let bits = std.octets();
Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3])
}
pub const fn any() -> Ipv4Addr {
Ipv4Addr(libc::in_addr { s_addr: libc::INADDR_ANY })
}
pub const fn octets(self) -> [u8; 4] {
let bits = u32::from_be(self.0.s_addr);
[(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
}
pub const fn to_std(self) -> net::Ipv4Addr {
let bits = self.octets();
net::Ipv4Addr::new(bits[0], bits[1], bits[2], bits[3])
}
}
#[allow(deprecated)]
impl fmt::Display for Ipv4Addr {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let octets = self.octets();
write!(fmt, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3])
}
}
/*
*
* ===== Ipv6Addr =====
*
*/
#[deprecated(
since = "0.24.0",
note = "Use std::net::Ipv6Addr instead"
)]
#[allow(missing_docs)] // Since they're all deprecated anyway
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[repr(transparent)]
pub struct Ipv6Addr(pub libc::in6_addr);
// Note that IPv6 addresses are stored in big endian order on all architectures.
// See https://tools.ietf.org/html/rfc1700 or consult your favorite search
// engine.
macro_rules! to_u8_array {
($($num:ident),*) => {
[ $(($num>>8) as u8, ($num&0xff) as u8,)* ]
}
}
macro_rules! to_u16_array {
($slf:ident, $($first:expr, $second:expr),*) => {
[$( (($slf.0.s6_addr[$first] as u16) << 8) + $slf.0.s6_addr[$second] as u16,)*]
}
}
#[allow(deprecated)]
#[allow(missing_docs)] // Since they're all deprecated anyway
impl Ipv6Addr {
#[allow(clippy::many_single_char_names)]
#[allow(clippy::too_many_arguments)]
pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
Ipv6Addr(libc::in6_addr{s6_addr: to_u8_array!(a,b,c,d,e,f,g,h)})
}
pub fn from_std(std: &net::Ipv6Addr) -> Ipv6Addr {
let s = std.segments();
Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7])
}
/// Return the eight 16-bit segments that make up this address
pub const fn segments(&self) -> [u16; 8] {
to_u16_array!(self, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
}
pub const fn to_std(&self) -> net::Ipv6Addr {
let s = self.segments();
net::Ipv6Addr::new(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7])
}
}
#[allow(deprecated)]
impl fmt::Display for Ipv6Addr {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self.to_std().fmt(fmt)
}
}
}
/// A wrapper around `sockaddr_un`.
#[derive(Clone, Copy, Debug)]
#[repr(C)]
@ -1982,358 +1678,6 @@ mod private {
}
}
/// Represents a socket address
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[deprecated(
since = "0.24.0",
note = "use SockaddrLike or SockaddrStorage instead"
)]
#[allow(missing_docs)] // Since they're all deprecated anyway
#[allow(deprecated)]
#[non_exhaustive]
pub enum SockAddr {
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Inet(InetAddr),
Unix(UnixAddr),
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
Netlink(NetlinkAddr),
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
Alg(AlgAddr),
#[cfg(all(
feature = "ioctl",
any(target_os = "ios", target_os = "macos")
))]
#[cfg_attr(docsrs, doc(cfg(feature = "ioctl")))]
SysControl(SysControlAddr),
/// Datalink address (MAC)
#[cfg(any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "illumos",
target_os = "netbsd",
target_os = "openbsd"
))]
#[cfg(feature = "net")]
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
Link(LinkAddr),
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
Vsock(VsockAddr),
}
#[allow(missing_docs)] // Since they're all deprecated anyway
#[allow(deprecated)]
impl SockAddr {
feature! {
#![feature = "net"]
pub fn new_inet(addr: InetAddr) -> SockAddr {
SockAddr::Inet(addr)
}
}
pub fn new_unix<P: ?Sized + NixPath>(path: &P) -> Result<SockAddr> {
Ok(SockAddr::Unix(UnixAddr::new(path)?))
}
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn new_netlink(pid: u32, groups: u32) -> SockAddr {
SockAddr::Netlink(NetlinkAddr::new(pid, groups))
}
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn new_alg(alg_type: &str, alg_name: &str) -> SockAddr {
SockAddr::Alg(AlgAddr::new(alg_type, alg_name))
}
feature! {
#![feature = "ioctl"]
#[cfg(any(target_os = "ios", target_os = "macos"))]
pub fn new_sys_control(sockfd: RawFd, name: &str, unit: u32) -> Result<SockAddr> {
SysControlAddr::from_name(sockfd, name, unit).map(SockAddr::SysControl)
}
}
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub fn new_vsock(cid: u32, port: u32) -> SockAddr {
SockAddr::Vsock(VsockAddr::new(cid, port))
}
pub fn family(&self) -> AddressFamily {
match *self {
#[cfg(feature = "net")]
SockAddr::Inet(InetAddr::V4(..)) => AddressFamily::Inet,
#[cfg(feature = "net")]
SockAddr::Inet(InetAddr::V6(..)) => AddressFamily::Inet6,
SockAddr::Unix(..) => AddressFamily::Unix,
#[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(..) => AddressFamily::Netlink,
#[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Alg(..) => AddressFamily::Alg,
#[cfg(all(
feature = "ioctl",
any(target_os = "ios", target_os = "macos")
))]
SockAddr::SysControl(..) => AddressFamily::System,
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg(feature = "net")]
SockAddr::Link(..) => AddressFamily::Packet,
#[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "illumos",
target_os = "openbsd"
))]
#[cfg(feature = "net")]
SockAddr::Link(..) => AddressFamily::Link,
#[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Vsock(..) => AddressFamily::Vsock,
}
}
#[deprecated(since = "0.23.0", note = "use .to_string() instead")]
pub fn to_str(&self) -> String {
format!("{}", self)
}
/// Creates a `SockAddr` struct from libc's sockaddr.
///
/// Supports only the following address families: Unix, Inet (v4 & v6), Netlink and System.
/// Returns None for unsupported families.
///
/// # Safety
///
/// unsafe because it takes a raw pointer as argument. The caller must
/// ensure that the pointer is valid.
#[cfg(not(target_os = "fuchsia"))]
#[cfg(feature = "net")]
pub(crate) unsafe fn from_libc_sockaddr(
addr: *const libc::sockaddr,
) -> Option<SockAddr> {
if addr.is_null() {
None
} else {
match AddressFamily::from_i32(i32::from((*addr).sa_family)) {
Some(AddressFamily::Unix) => None,
#[cfg(feature = "net")]
Some(AddressFamily::Inet) => Some(SockAddr::Inet(
InetAddr::V4(ptr::read_unaligned(addr as *const _)),
)),
#[cfg(feature = "net")]
Some(AddressFamily::Inet6) => Some(SockAddr::Inet(
InetAddr::V6(ptr::read_unaligned(addr as *const _)),
)),
#[cfg(any(target_os = "android", target_os = "linux"))]
Some(AddressFamily::Netlink) => Some(SockAddr::Netlink(
NetlinkAddr(ptr::read_unaligned(addr as *const _)),
)),
#[cfg(all(
feature = "ioctl",
any(target_os = "ios", target_os = "macos")
))]
Some(AddressFamily::System) => Some(SockAddr::SysControl(
SysControlAddr(ptr::read_unaligned(addr as *const _)),
)),
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg(feature = "net")]
Some(AddressFamily::Packet) => Some(SockAddr::Link(LinkAddr(
ptr::read_unaligned(addr as *const _),
))),
#[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "netbsd",
target_os = "illumos",
target_os = "openbsd"
))]
#[cfg(feature = "net")]
Some(AddressFamily::Link) => {
let ether_addr =
LinkAddr(ptr::read_unaligned(addr as *const _));
if ether_addr.is_empty() {
None
} else {
Some(SockAddr::Link(ether_addr))
}
}
#[cfg(any(target_os = "android", target_os = "linux"))]
Some(AddressFamily::Vsock) => Some(SockAddr::Vsock(VsockAddr(
ptr::read_unaligned(addr as *const _),
))),
// Other address families are currently not supported and simply yield a None
// entry instead of a proper conversion to a `SockAddr`.
Some(_) | None => None,
}
}
}
/// Conversion from nix's SockAddr type to the underlying libc sockaddr type.
///
/// This is useful for interfacing with other libc functions that don't yet have nix wrappers.
/// Returns a reference to the underlying data type (as a sockaddr reference) along
/// with the size of the actual data type. sockaddr is commonly used as a proxy for
/// a superclass as C doesn't support inheritance, so many functions that take
/// a sockaddr * need to take the size of the underlying type as well and then internally cast it back.
pub fn as_ffi_pair(&self) -> (&libc::sockaddr, libc::socklen_t) {
match *self {
#[cfg(feature = "net")]
SockAddr::Inet(InetAddr::V4(ref addr)) => (
// This cast is always allowed in C
unsafe {
&*(addr as *const libc::sockaddr_in
as *const libc::sockaddr)
},
mem::size_of_val(addr) as libc::socklen_t,
),
#[cfg(feature = "net")]
SockAddr::Inet(InetAddr::V6(ref addr)) => (
// This cast is always allowed in C
unsafe {
&*(addr as *const libc::sockaddr_in6
as *const libc::sockaddr)
},
mem::size_of_val(addr) as libc::socklen_t,
),
SockAddr::Unix(ref unix_addr) => (
// This cast is always allowed in C
unsafe {
&*(&unix_addr.sun as *const libc::sockaddr_un
as *const libc::sockaddr)
},
unix_addr.sun_len() as libc::socklen_t,
),
#[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(NetlinkAddr(ref sa)) => (
// This cast is always allowed in C
unsafe {
&*(sa as *const libc::sockaddr_nl as *const libc::sockaddr)
},
mem::size_of_val(sa) as libc::socklen_t,
),
#[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Alg(AlgAddr(ref sa)) => (
// This cast is always allowed in C
unsafe {
&*(sa as *const libc::sockaddr_alg as *const libc::sockaddr)
},
mem::size_of_val(sa) as libc::socklen_t,
),
#[cfg(all(
feature = "ioctl",
any(target_os = "ios", target_os = "macos")
))]
SockAddr::SysControl(SysControlAddr(ref sa)) => (
// This cast is always allowed in C
unsafe {
&*(sa as *const libc::sockaddr_ctl as *const libc::sockaddr)
},
mem::size_of_val(sa) as libc::socklen_t,
),
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg(feature = "net")]
SockAddr::Link(LinkAddr(ref addr)) => (
// This cast is always allowed in C
unsafe {
&*(addr as *const libc::sockaddr_ll
as *const libc::sockaddr)
},
mem::size_of_val(addr) as libc::socklen_t,
),
#[cfg(any(
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "macos",
target_os = "illumos",
target_os = "netbsd",
target_os = "openbsd"
))]
#[cfg(feature = "net")]
SockAddr::Link(LinkAddr(ref addr)) => (
// This cast is always allowed in C
unsafe {
&*(addr as *const libc::sockaddr_dl
as *const libc::sockaddr)
},
mem::size_of_val(addr) as libc::socklen_t,
),
#[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Vsock(VsockAddr(ref sa)) => (
// This cast is always allowed in C
unsafe {
&*(sa as *const libc::sockaddr_vm as *const libc::sockaddr)
},
mem::size_of_val(sa) as libc::socklen_t,
),
}
}
}
#[allow(deprecated)]
impl fmt::Display for SockAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
#[cfg(feature = "net")]
SockAddr::Inet(ref inet) => inet.fmt(f),
SockAddr::Unix(ref unix) => unix.fmt(f),
#[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Netlink(ref nl) => nl.fmt(f),
#[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Alg(ref nl) => nl.fmt(f),
#[cfg(all(
feature = "ioctl",
any(target_os = "ios", target_os = "macos")
))]
SockAddr::SysControl(ref sc) => sc.fmt(f),
#[cfg(any(
target_os = "android",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "netbsd",
target_os = "illumos",
target_os = "openbsd"
))]
#[cfg(feature = "net")]
SockAddr::Link(ref ether_addr) => ether_addr.fmt(f),
#[cfg(any(target_os = "android", target_os = "linux"))]
SockAddr::Vsock(ref svm) => svm.fmt(f),
}
}
}
#[cfg(not(target_os = "fuchsia"))]
#[cfg(feature = "net")]
#[allow(deprecated)]
impl private::SockaddrLikePriv for SockAddr {}
#[cfg(not(target_os = "fuchsia"))]
#[cfg(feature = "net")]
#[allow(deprecated)]
impl SockaddrLike for SockAddr {
unsafe fn from_raw(
addr: *const libc::sockaddr,
_len: Option<libc::socklen_t>,
) -> Option<Self> {
Self::from_libc_sockaddr(addr)
}
}
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(all())))]
pub mod netlink {

View File

@ -12,7 +12,7 @@ use libc::{
self, c_int, c_void, iovec, size_t, socklen_t, CMSG_DATA, CMSG_FIRSTHDR,
CMSG_LEN, CMSG_NXTHDR,
};
use std::convert::{TryFrom, TryInto};
use std::convert::TryFrom;
use std::io::{IoSlice, IoSliceMut};
#[cfg(feature = "net")]
use std::net;
@ -32,32 +32,24 @@ pub mod sockopt;
pub use self::addr::{SockaddrLike, SockaddrStorage};
#[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
#[allow(deprecated)]
pub use self::addr::{AddressFamily, SockAddr, UnixAddr};
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
#[allow(deprecated)]
pub use self::addr::{AddressFamily, SockAddr, UnixAddr};
#[allow(deprecated)]
pub use self::addr::{AddressFamily, UnixAddr};
#[cfg(not(any(target_os = "illumos", target_os = "solaris")))]
pub use self::addr::{AddressFamily, UnixAddr};
#[cfg(not(any(
target_os = "illumos",
target_os = "solaris",
target_os = "haiku"
)))]
#[cfg(feature = "net")]
pub use self::addr::{
InetAddr, IpAddr, Ipv4Addr, Ipv6Addr, LinkAddr, SockaddrIn, SockaddrIn6,
};
#[allow(deprecated)]
pub use self::addr::{LinkAddr, SockaddrIn, SockaddrIn6};
#[cfg(any(
target_os = "illumos",
target_os = "solaris",
target_os = "haiku"
))]
#[cfg(feature = "net")]
pub use self::addr::{
InetAddr, IpAddr, Ipv4Addr, Ipv6Addr, SockaddrIn, SockaddrIn6,
};
pub use self::addr::{SockaddrIn, SockaddrIn6};
#[cfg(any(target_os = "android", target_os = "linux"))]
pub use crate::sys::socket::addr::alg::AlgAddr;
@ -121,7 +113,7 @@ impl TryFrom<i32> for SockType {
libc::SOCK_RAW => Ok(Self::Raw),
#[cfg(not(any(target_os = "haiku")))]
libc::SOCK_RDM => Ok(Self::Rdm),
_ => Err(Errno::EINVAL)
_ => Err(Errno::EINVAL),
}
}
}
@ -2376,81 +2368,6 @@ pub fn getsockname<T: SockaddrLike>(fd: RawFd) -> Result<T> {
}
}
/// Return the appropriate `SockAddr` type from a `sockaddr_storage` of a
/// certain size.
///
/// In C this would usually be done by casting. The `len` argument
/// should be the number of bytes in the `sockaddr_storage` that are actually
/// allocated and valid. It must be at least as large as all the useful parts
/// of the structure. Note that in the case of a `sockaddr_un`, `len` need not
/// include the terminating null.
#[deprecated(
since = "0.24.0",
note = "use SockaddrLike or SockaddrStorage instead"
)]
#[allow(deprecated)]
pub fn sockaddr_storage_to_addr(
addr: &sockaddr_storage,
len: usize,
) -> Result<SockAddr> {
assert!(len <= mem::size_of::<sockaddr_storage>());
if len < mem::size_of_val(&addr.ss_family) {
return Err(Errno::ENOTCONN);
}
match c_int::from(addr.ss_family) {
#[cfg(feature = "net")]
libc::AF_INET => {
assert!(len >= mem::size_of::<sockaddr_in>());
let sin = unsafe {
*(addr as *const sockaddr_storage as *const sockaddr_in)
};
Ok(SockAddr::Inet(InetAddr::V4(sin)))
}
#[cfg(feature = "net")]
libc::AF_INET6 => {
assert!(len >= mem::size_of::<sockaddr_in6>());
let sin6 = unsafe { *(addr as *const _ as *const sockaddr_in6) };
Ok(SockAddr::Inet(InetAddr::V6(sin6)))
}
libc::AF_UNIX => unsafe {
let sun = *(addr as *const _ as *const sockaddr_un);
let sun_len = len.try_into().unwrap();
Ok(SockAddr::Unix(UnixAddr::from_raw_parts(sun, sun_len)))
},
#[cfg(any(target_os = "android", target_os = "linux"))]
#[cfg(feature = "net")]
libc::AF_PACKET => {
use libc::sockaddr_ll;
// Don't assert anything about the size.
// Apparently the Linux kernel can return smaller sizes when
// the value in the last element of sockaddr_ll (`sll_addr`) is
// smaller than the declared size of that field
let sll = unsafe { *(addr as *const _ as *const sockaddr_ll) };
Ok(SockAddr::Link(LinkAddr(sll)))
}
#[cfg(any(target_os = "android", target_os = "linux"))]
libc::AF_NETLINK => {
use libc::sockaddr_nl;
let snl = unsafe { *(addr as *const _ as *const sockaddr_nl) };
Ok(SockAddr::Netlink(NetlinkAddr(snl)))
}
#[cfg(any(target_os = "android", target_os = "linux"))]
libc::AF_ALG => {
use libc::sockaddr_alg;
let salg = unsafe { *(addr as *const _ as *const sockaddr_alg) };
Ok(SockAddr::Alg(AlgAddr(salg)))
}
#[cfg(any(target_os = "android", target_os = "linux"))]
libc::AF_VSOCK => {
use libc::sockaddr_vm;
let svm = unsafe { *(addr as *const _ as *const sockaddr_vm) };
Ok(SockAddr::Vsock(VsockAddr(svm)))
}
af => panic!("unexpected address family {}", af),
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Shutdown {
/// Further receptions will be disallowed.
@ -2485,7 +2402,11 @@ mod tests {
let _ = cmsg_space!(u8);
}
#[cfg(not(any(target_os = "redox", target_os = "linux", target_os = "android")))]
#[cfg(not(any(
target_os = "redox",
target_os = "linux",
target_os = "android"
)))]
#[test]
fn can_open_routing_socket() {
let _ = super::socket(

View File

@ -1,73 +1,15 @@
#[cfg(any(target_os = "linux", target_os = "android"))]
use crate::*;
use libc::{c_char, sockaddr_storage};
#[allow(deprecated)]
use nix::sys::socket::InetAddr;
use nix::sys::socket::{
getsockname, sockaddr, sockaddr_in6, AddressFamily, UnixAddr,
};
use libc::c_char;
use nix::sys::socket::{getsockname, AddressFamily, UnixAddr};
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::mem::{self, MaybeUninit};
use std::net::{self, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use std::net::{SocketAddrV4, SocketAddrV6};
use std::os::unix::io::RawFd;
use std::path::Path;
use std::slice;
use std::str::FromStr;
#[allow(deprecated)]
#[test]
pub fn test_inetv4_addr_to_sock_addr() {
let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap();
let addr = InetAddr::from_std(&actual);
match addr {
InetAddr::V4(addr) => {
let ip: u32 = 0x7f00_0001;
let port: u16 = 3000;
let saddr = addr.sin_addr.s_addr;
assert_eq!(saddr, ip.to_be());
assert_eq!(addr.sin_port, port.to_be());
}
_ => panic!("nope"),
}
assert_eq!(addr.to_string(), "127.0.0.1:3000");
let inet = addr.to_std();
assert_eq!(actual, inet);
}
#[allow(deprecated)]
#[test]
pub fn test_inetv4_addr_roundtrip_sockaddr_storage_to_addr() {
use nix::sys::socket::{sockaddr_storage_to_addr, SockAddr};
let actual: net::SocketAddr = FromStr::from_str("127.0.0.1:3000").unwrap();
let addr = InetAddr::from_std(&actual);
let sockaddr = SockAddr::new_inet(addr);
let (storage, ffi_size) = {
let mut storage = MaybeUninit::<sockaddr_storage>::zeroed();
let storage_ptr = storage.as_mut_ptr().cast::<sockaddr>();
let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair();
assert_eq!(mem::size_of::<sockaddr>(), ffi_size as usize);
unsafe {
storage_ptr.copy_from_nonoverlapping(ffi_ptr as *const sockaddr, 1);
(storage.assume_init(), ffi_size)
}
};
let from_storage =
sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap();
assert_eq!(from_storage, sockaddr);
let from_storage =
sockaddr_storage_to_addr(&storage, mem::size_of::<sockaddr_storage>())
.unwrap();
assert_eq!(from_storage, sockaddr);
}
#[cfg(any(target_os = "linux"))]
#[cfg_attr(qemu, ignore)]
#[test]
@ -128,44 +70,6 @@ pub fn test_timestamping() {
assert!(std::time::Duration::from(diff).as_secs() < 60);
}
#[allow(deprecated)]
#[test]
pub fn test_inetv6_addr_roundtrip_sockaddr_storage_to_addr() {
use nix::sys::socket::{sockaddr_storage_to_addr, SockAddr};
let port: u16 = 3000;
let flowinfo: u32 = 1;
let scope_id: u32 = 2;
let ip: Ipv6Addr = "fe80::1".parse().unwrap();
let actual =
SocketAddr::V6(SocketAddrV6::new(ip, port, flowinfo, scope_id));
let addr = InetAddr::from_std(&actual);
let sockaddr = SockAddr::new_inet(addr);
let (storage, ffi_size) = {
let mut storage = MaybeUninit::<sockaddr_storage>::zeroed();
let storage_ptr = storage.as_mut_ptr().cast::<sockaddr_in6>();
let (ffi_ptr, ffi_size) = sockaddr.as_ffi_pair();
assert_eq!(mem::size_of::<sockaddr_in6>(), ffi_size as usize);
unsafe {
storage_ptr.copy_from_nonoverlapping(
(ffi_ptr as *const sockaddr).cast::<sockaddr_in6>(),
1,
);
(storage.assume_init(), ffi_size)
}
};
let from_storage =
sockaddr_storage_to_addr(&storage, ffi_size as usize).unwrap();
assert_eq!(from_storage, sockaddr);
let from_storage =
sockaddr_storage_to_addr(&storage, mem::size_of::<sockaddr_storage>())
.unwrap();
assert_eq!(from_storage, sockaddr);
}
#[test]
pub fn test_path_to_sock_addr() {
let path = "/foo/bar";