mirror of
https://github.com/jiangcuo/nix.git
synced 2026-01-17 15:51:07 +00:00
Nuke deprecated net APIs
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
This commit is contained in:
parent
05f925a888
commit
f3aa1affb0
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user