mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Rollup merge of #136699 - joboet:netaddr_from_inner, r=cuviper
std: replace the `FromInner` implementation for addresses with private conversion functions Having these implementation available crate-wide means that platforms not using sockets for their networking code have to stub out the libc definitions required to support them. This PR moves the conversions to private helper functions that are only available where actually needed. I also fixed the signature of the function converting from a C socket address to a Rust one: taking a reference to a `sockaddr_storage` resulted in unsound usage inside `LookupHost::next`, which could create a reference to a structure smaller than `sockaddr_storage`. Thus I've replaced the argument type with a pointer and made the function `unsafe`.
This commit is contained in:
commit
4ce473ccba
@ -8,32 +8,3 @@ pub use core::net::IpAddr;
|
||||
pub use core::net::Ipv6MulticastScope;
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub use core::net::{Ipv4Addr, Ipv6Addr};
|
||||
|
||||
use crate::sys::net::netc as c;
|
||||
use crate::sys_common::{FromInner, IntoInner};
|
||||
|
||||
impl IntoInner<c::in_addr> for Ipv4Addr {
|
||||
#[inline]
|
||||
fn into_inner(self) -> c::in_addr {
|
||||
// `s_addr` is stored as BE on all machines and the array is in BE order.
|
||||
// So the native endian conversion method is used so that it's never swapped.
|
||||
c::in_addr { s_addr: u32::from_ne_bytes(self.octets()) }
|
||||
}
|
||||
}
|
||||
impl FromInner<c::in_addr> for Ipv4Addr {
|
||||
fn from_inner(addr: c::in_addr) -> Ipv4Addr {
|
||||
Ipv4Addr::from(addr.s_addr.to_ne_bytes())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<c::in6_addr> for Ipv6Addr {
|
||||
fn into_inner(self) -> c::in6_addr {
|
||||
c::in6_addr { s6_addr: self.octets() }
|
||||
}
|
||||
}
|
||||
impl FromInner<c::in6_addr> for Ipv6Addr {
|
||||
#[inline]
|
||||
fn from_inner(addr: c::in6_addr) -> Ipv6Addr {
|
||||
Ipv6Addr::from(addr.s6_addr)
|
||||
}
|
||||
}
|
||||
|
@ -6,50 +6,8 @@ mod tests;
|
||||
pub use core::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||
|
||||
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use crate::sys::net::{LookupHost, netc as c};
|
||||
use crate::sys_common::{FromInner, IntoInner};
|
||||
use crate::{io, iter, mem, option, slice, vec};
|
||||
|
||||
impl FromInner<c::sockaddr_in> for SocketAddrV4 {
|
||||
fn from_inner(addr: c::sockaddr_in) -> SocketAddrV4 {
|
||||
SocketAddrV4::new(Ipv4Addr::from_inner(addr.sin_addr), u16::from_be(addr.sin_port))
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<c::sockaddr_in6> for SocketAddrV6 {
|
||||
fn from_inner(addr: c::sockaddr_in6) -> SocketAddrV6 {
|
||||
SocketAddrV6::new(
|
||||
Ipv6Addr::from_inner(addr.sin6_addr),
|
||||
u16::from_be(addr.sin6_port),
|
||||
addr.sin6_flowinfo,
|
||||
addr.sin6_scope_id,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<c::sockaddr_in> for SocketAddrV4 {
|
||||
fn into_inner(self) -> c::sockaddr_in {
|
||||
c::sockaddr_in {
|
||||
sin_family: c::AF_INET as c::sa_family_t,
|
||||
sin_port: self.port().to_be(),
|
||||
sin_addr: self.ip().into_inner(),
|
||||
..unsafe { mem::zeroed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<c::sockaddr_in6> for SocketAddrV6 {
|
||||
fn into_inner(self) -> c::sockaddr_in6 {
|
||||
c::sockaddr_in6 {
|
||||
sin6_family: c::AF_INET6 as c::sa_family_t,
|
||||
sin6_port: self.port().to_be(),
|
||||
sin6_addr: self.ip().into_inner(),
|
||||
sin6_flowinfo: self.flowinfo(),
|
||||
sin6_scope_id: self.scope_id(),
|
||||
..unsafe { mem::zeroed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
use crate::sys::net::LookupHost;
|
||||
use crate::{io, iter, option, slice, vec};
|
||||
|
||||
/// A trait for objects which can be converted or resolved to one or more
|
||||
/// [`SocketAddr`] values.
|
||||
|
@ -122,7 +122,7 @@ impl BorrowedFd<'_> {
|
||||
/// Creates a new `OwnedFd` instance that shares the same underlying file
|
||||
/// description as the existing `BorrowedFd` instance.
|
||||
pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> {
|
||||
let fd = sys::net::cvt(unsafe { sys::net::netc::dup(self.as_raw_fd()) })?;
|
||||
let fd = sys::net::cvt(unsafe { crate::sys::abi::sockets::dup(self.as_raw_fd()) })?;
|
||||
Ok(unsafe { OwnedFd::from_raw_fd(fd) })
|
||||
}
|
||||
}
|
||||
@ -168,7 +168,7 @@ impl FromRawFd for OwnedFd {
|
||||
impl Drop for OwnedFd {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
unsafe { sys::net::netc::close(self.fd.as_inner()) };
|
||||
unsafe { crate::sys::abi::sockets::close(self.fd.as_inner()) };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -499,38 +499,3 @@ impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
|
||||
LookupHost::new(format!("{host}:{port}"))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(bad_style)]
|
||||
pub mod netc {
|
||||
pub const AF_INET: u8 = 0;
|
||||
pub const AF_INET6: u8 = 1;
|
||||
pub type sa_family_t = u8;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in_addr {
|
||||
pub s_addr: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in {
|
||||
#[allow(dead_code)]
|
||||
pub sin_family: sa_family_t,
|
||||
pub sin_port: u16,
|
||||
pub sin_addr: in_addr,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in6_addr {
|
||||
pub s6_addr: [u8; 16],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in6 {
|
||||
#[allow(dead_code)]
|
||||
pub sin6_family: sa_family_t,
|
||||
pub sin6_port: u16,
|
||||
pub sin6_addr: in6_addr,
|
||||
pub sin6_flowinfo: u32,
|
||||
pub sin6_scope_id: u32,
|
||||
}
|
||||
}
|
||||
|
@ -3,9 +3,9 @@ mod tests;
|
||||
|
||||
use crate::ffi::{c_int, c_void};
|
||||
use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut};
|
||||
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr};
|
||||
use crate::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||
use crate::sys::common::small_c_string::run_with_cstr;
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::sys_common::{AsInner, FromInner};
|
||||
use crate::time::Duration;
|
||||
use crate::{cmp, fmt, mem, ptr};
|
||||
|
||||
@ -79,6 +79,111 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// address conversions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
fn ip_v4_addr_to_c(addr: &Ipv4Addr) -> c::in_addr {
|
||||
// `s_addr` is stored as BE on all machines and the array is in BE order.
|
||||
// So the native endian conversion method is used so that it's never swapped.
|
||||
c::in_addr { s_addr: u32::from_ne_bytes(addr.octets()) }
|
||||
}
|
||||
|
||||
fn ip_v6_addr_to_c(addr: &Ipv6Addr) -> c::in6_addr {
|
||||
c::in6_addr { s6_addr: addr.octets() }
|
||||
}
|
||||
|
||||
fn ip_v4_addr_from_c(addr: c::in_addr) -> Ipv4Addr {
|
||||
Ipv4Addr::from(addr.s_addr.to_ne_bytes())
|
||||
}
|
||||
|
||||
fn ip_v6_addr_from_c(addr: c::in6_addr) -> Ipv6Addr {
|
||||
Ipv6Addr::from(addr.s6_addr)
|
||||
}
|
||||
|
||||
fn socket_addr_v4_to_c(addr: &SocketAddrV4) -> c::sockaddr_in {
|
||||
c::sockaddr_in {
|
||||
sin_family: c::AF_INET as c::sa_family_t,
|
||||
sin_port: addr.port().to_be(),
|
||||
sin_addr: ip_v4_addr_to_c(addr.ip()),
|
||||
..unsafe { mem::zeroed() }
|
||||
}
|
||||
}
|
||||
|
||||
fn socket_addr_v6_to_c(addr: &SocketAddrV6) -> c::sockaddr_in6 {
|
||||
c::sockaddr_in6 {
|
||||
sin6_family: c::AF_INET6 as c::sa_family_t,
|
||||
sin6_port: addr.port().to_be(),
|
||||
sin6_addr: ip_v6_addr_to_c(addr.ip()),
|
||||
sin6_flowinfo: addr.flowinfo(),
|
||||
sin6_scope_id: addr.scope_id(),
|
||||
..unsafe { mem::zeroed() }
|
||||
}
|
||||
}
|
||||
|
||||
fn socket_addr_v4_from_c(addr: c::sockaddr_in) -> SocketAddrV4 {
|
||||
SocketAddrV4::new(ip_v4_addr_from_c(addr.sin_addr), u16::from_be(addr.sin_port))
|
||||
}
|
||||
|
||||
fn socket_addr_v6_from_c(addr: c::sockaddr_in6) -> SocketAddrV6 {
|
||||
SocketAddrV6::new(
|
||||
ip_v6_addr_from_c(addr.sin6_addr),
|
||||
u16::from_be(addr.sin6_port),
|
||||
addr.sin6_flowinfo,
|
||||
addr.sin6_scope_id,
|
||||
)
|
||||
}
|
||||
|
||||
/// A type with the same memory layout as `c::sockaddr`. Used in converting Rust level
|
||||
/// SocketAddr* types into their system representation. The benefit of this specific
|
||||
/// type over using `c::sockaddr_storage` is that this type is exactly as large as it
|
||||
/// needs to be and not a lot larger. And it can be initialized more cleanly from Rust.
|
||||
#[repr(C)]
|
||||
union SocketAddrCRepr {
|
||||
v4: c::sockaddr_in,
|
||||
v6: c::sockaddr_in6,
|
||||
}
|
||||
|
||||
impl SocketAddrCRepr {
|
||||
fn as_ptr(&self) -> *const c::sockaddr {
|
||||
self as *const _ as *const c::sockaddr
|
||||
}
|
||||
}
|
||||
|
||||
fn socket_addr_to_c(addr: &SocketAddr) -> (SocketAddrCRepr, c::socklen_t) {
|
||||
match addr {
|
||||
SocketAddr::V4(a) => {
|
||||
let sockaddr = SocketAddrCRepr { v4: socket_addr_v4_to_c(a) };
|
||||
(sockaddr, mem::size_of::<c::sockaddr_in>() as c::socklen_t)
|
||||
}
|
||||
SocketAddr::V6(a) => {
|
||||
let sockaddr = SocketAddrCRepr { v6: socket_addr_v6_to_c(a) };
|
||||
(sockaddr, mem::size_of::<c::sockaddr_in6>() as c::socklen_t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn socket_addr_from_c(
|
||||
storage: *const c::sockaddr_storage,
|
||||
len: usize,
|
||||
) -> io::Result<SocketAddr> {
|
||||
match (*storage).ss_family as c_int {
|
||||
c::AF_INET => {
|
||||
assert!(len >= mem::size_of::<c::sockaddr_in>());
|
||||
Ok(SocketAddr::V4(socket_addr_v4_from_c(unsafe {
|
||||
*(storage as *const _ as *const c::sockaddr_in)
|
||||
})))
|
||||
}
|
||||
c::AF_INET6 => {
|
||||
assert!(len >= mem::size_of::<c::sockaddr_in6>());
|
||||
Ok(SocketAddr::V6(socket_addr_v6_from_c(unsafe {
|
||||
*(storage as *const _ as *const c::sockaddr_in6)
|
||||
})))
|
||||
}
|
||||
_ => Err(io::const_error!(ErrorKind::InvalidInput, "invalid argument")),
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// sockaddr and misc bindings
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -124,25 +229,7 @@ where
|
||||
let mut storage: c::sockaddr_storage = mem::zeroed();
|
||||
let mut len = mem::size_of_val(&storage) as c::socklen_t;
|
||||
cvt(f((&raw mut storage) as *mut _, &mut len))?;
|
||||
sockaddr_to_addr(&storage, len as usize)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sockaddr_to_addr(storage: &c::sockaddr_storage, len: usize) -> io::Result<SocketAddr> {
|
||||
match storage.ss_family as c_int {
|
||||
c::AF_INET => {
|
||||
assert!(len >= mem::size_of::<c::sockaddr_in>());
|
||||
Ok(SocketAddr::V4(FromInner::from_inner(unsafe {
|
||||
*(storage as *const _ as *const c::sockaddr_in)
|
||||
})))
|
||||
}
|
||||
c::AF_INET6 => {
|
||||
assert!(len >= mem::size_of::<c::sockaddr_in6>());
|
||||
Ok(SocketAddr::V6(FromInner::from_inner(unsafe {
|
||||
*(storage as *const _ as *const c::sockaddr_in6)
|
||||
})))
|
||||
}
|
||||
_ => Err(io::const_error!(ErrorKind::InvalidInput, "invalid argument")),
|
||||
socket_addr_from_c(&storage, len as usize)
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,7 +266,7 @@ impl Iterator for LookupHost {
|
||||
unsafe {
|
||||
let cur = self.cur.as_ref()?;
|
||||
self.cur = cur.ai_next;
|
||||
match sockaddr_to_addr(mem::transmute(cur.ai_addr), cur.ai_addrlen as usize) {
|
||||
match socket_addr_from_c(cur.ai_addr.cast(), cur.ai_addrlen as usize) {
|
||||
Ok(addr) => return Some(addr),
|
||||
Err(_) => continue,
|
||||
}
|
||||
@ -432,7 +519,7 @@ impl TcpListener {
|
||||
setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR, 1 as c_int)?;
|
||||
|
||||
// Bind our new socket
|
||||
let (addr, len) = addr.into_inner();
|
||||
let (addr, len) = socket_addr_to_c(addr);
|
||||
cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?;
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
@ -473,7 +560,7 @@ impl TcpListener {
|
||||
let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let mut len = mem::size_of_val(&storage) as c::socklen_t;
|
||||
let sock = self.inner.accept((&raw mut storage) as *mut _, &mut len)?;
|
||||
let addr = sockaddr_to_addr(&storage, len as usize)?;
|
||||
let addr = unsafe { socket_addr_from_c(&storage, len as usize)? };
|
||||
Ok((TcpStream { inner: sock }, addr))
|
||||
}
|
||||
|
||||
@ -542,7 +629,7 @@ impl UdpSocket {
|
||||
init();
|
||||
|
||||
let sock = Socket::new(addr, c::SOCK_DGRAM)?;
|
||||
let (addr, len) = addr.into_inner();
|
||||
let (addr, len) = socket_addr_to_c(addr);
|
||||
cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?;
|
||||
Ok(UdpSocket { inner: sock })
|
||||
}
|
||||
@ -574,7 +661,7 @@ impl UdpSocket {
|
||||
|
||||
pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> {
|
||||
let len = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t;
|
||||
let (dst, dstlen) = dst.into_inner();
|
||||
let (dst, dstlen) = socket_addr_to_c(dst);
|
||||
let ret = cvt(unsafe {
|
||||
c::sendto(
|
||||
self.inner.as_raw(),
|
||||
@ -656,15 +743,15 @@ impl UdpSocket {
|
||||
|
||||
pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
|
||||
let mreq = c::ip_mreq {
|
||||
imr_multiaddr: multiaddr.into_inner(),
|
||||
imr_interface: interface.into_inner(),
|
||||
imr_multiaddr: ip_v4_addr_to_c(multiaddr),
|
||||
imr_interface: ip_v4_addr_to_c(interface),
|
||||
};
|
||||
setsockopt(&self.inner, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq)
|
||||
}
|
||||
|
||||
pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
|
||||
let mreq = c::ipv6_mreq {
|
||||
ipv6mr_multiaddr: multiaddr.into_inner(),
|
||||
ipv6mr_multiaddr: ip_v6_addr_to_c(multiaddr),
|
||||
ipv6mr_interface: to_ipv6mr_interface(interface),
|
||||
};
|
||||
setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq)
|
||||
@ -672,15 +759,15 @@ impl UdpSocket {
|
||||
|
||||
pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
|
||||
let mreq = c::ip_mreq {
|
||||
imr_multiaddr: multiaddr.into_inner(),
|
||||
imr_interface: interface.into_inner(),
|
||||
imr_multiaddr: ip_v4_addr_to_c(multiaddr),
|
||||
imr_interface: ip_v4_addr_to_c(interface),
|
||||
};
|
||||
setsockopt(&self.inner, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq)
|
||||
}
|
||||
|
||||
pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
|
||||
let mreq = c::ipv6_mreq {
|
||||
ipv6mr_multiaddr: multiaddr.into_inner(),
|
||||
ipv6mr_multiaddr: ip_v6_addr_to_c(multiaddr),
|
||||
ipv6mr_interface: to_ipv6mr_interface(interface),
|
||||
};
|
||||
setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq)
|
||||
@ -720,7 +807,7 @@ impl UdpSocket {
|
||||
}
|
||||
|
||||
pub fn connect(&self, addr: io::Result<&SocketAddr>) -> io::Result<()> {
|
||||
let (addr, len) = addr?.into_inner();
|
||||
let (addr, len) = socket_addr_to_c(addr?);
|
||||
cvt_r(|| unsafe { c::connect(self.inner.as_raw(), addr.as_ptr(), len) }).map(drop)
|
||||
}
|
||||
}
|
||||
@ -743,38 +830,3 @@ impl fmt::Debug for UdpSocket {
|
||||
res.field(name, &self.inner.as_raw()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Converting SocketAddr to libc representation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A type with the same memory layout as `c::sockaddr`. Used in converting Rust level
|
||||
/// SocketAddr* types into their system representation. The benefit of this specific
|
||||
/// type over using `c::sockaddr_storage` is that this type is exactly as large as it
|
||||
/// needs to be and not a lot larger. And it can be initialized more cleanly from Rust.
|
||||
#[repr(C)]
|
||||
pub(crate) union SocketAddrCRepr {
|
||||
v4: c::sockaddr_in,
|
||||
v6: c::sockaddr_in6,
|
||||
}
|
||||
|
||||
impl SocketAddrCRepr {
|
||||
pub fn as_ptr(&self) -> *const c::sockaddr {
|
||||
self as *const _ as *const c::sockaddr
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoInner<(SocketAddrCRepr, c::socklen_t)> for &'a SocketAddr {
|
||||
fn into_inner(self) -> (SocketAddrCRepr, c::socklen_t) {
|
||||
match *self {
|
||||
SocketAddr::V4(ref a) => {
|
||||
let sockaddr = SocketAddrCRepr { v4: a.into_inner() };
|
||||
(sockaddr, mem::size_of::<c::sockaddr_in>() as c::socklen_t)
|
||||
}
|
||||
SocketAddr::V6(ref a) => {
|
||||
let sockaddr = SocketAddrCRepr { v6: a.into_inner() };
|
||||
(sockaddr, mem::size_of::<c::sockaddr_in6>() as c::socklen_t)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
use core::ffi::c_int;
|
||||
|
||||
pub(crate) use hermit_abi as netc;
|
||||
pub(super) use hermit_abi as netc;
|
||||
|
||||
use super::{getsockopt, setsockopt, socket_addr_from_c, socket_addr_to_c};
|
||||
use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut};
|
||||
use crate::net::{Shutdown, SocketAddr};
|
||||
use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd};
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::sys::net::{getsockopt, setsockopt, sockaddr_to_addr};
|
||||
use crate::sys::time::Instant;
|
||||
pub use crate::sys::{cvt, cvt_r};
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
@ -55,7 +55,7 @@ impl Socket {
|
||||
}
|
||||
|
||||
pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
|
||||
let (addr, len) = addr.into_inner();
|
||||
let (addr, len) = socket_addr_to_c(addr);
|
||||
cvt_r(|| unsafe { netc::connect(self.as_raw_fd(), addr.as_ptr(), len) })?;
|
||||
Ok(())
|
||||
}
|
||||
@ -63,7 +63,7 @@ impl Socket {
|
||||
pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
|
||||
self.set_nonblocking(true)?;
|
||||
let r = unsafe {
|
||||
let (addr, len) = addr.into_inner();
|
||||
let (addr, len) = socket_addr_to_c(addr);
|
||||
cvt(netc::connect(self.as_raw_fd(), addr.as_ptr(), len))
|
||||
};
|
||||
self.set_nonblocking(false)?;
|
||||
@ -195,7 +195,7 @@ impl Socket {
|
||||
&mut addrlen,
|
||||
)
|
||||
})?;
|
||||
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
||||
Ok((n as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? }))
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
|
@ -1,17 +1,17 @@
|
||||
use libc::{c_int, c_void, size_t};
|
||||
|
||||
use self::netc::{MSG_PEEK, sockaddr, socklen_t};
|
||||
use super::{getsockopt, setsockopt, socket_addr_from_c, socket_addr_to_c};
|
||||
use crate::ffi::CStr;
|
||||
use crate::io::{self, BorrowedBuf, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut};
|
||||
use crate::net::{Shutdown, SocketAddr};
|
||||
use crate::os::solid::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd};
|
||||
use crate::sys::abi;
|
||||
use crate::sys::net::{getsockopt, setsockopt, sockaddr_to_addr};
|
||||
use crate::sys_common::{FromInner, IntoInner};
|
||||
use crate::time::Duration;
|
||||
use crate::{cmp, mem, ptr, str};
|
||||
|
||||
pub mod netc {
|
||||
pub(super) mod netc {
|
||||
pub use crate::sys::abi::sockets::*;
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ impl Socket {
|
||||
}
|
||||
|
||||
pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
|
||||
let (addr, len) = addr.into_inner();
|
||||
let (addr, len) = socket_addr_to_c(addr);
|
||||
cvt(unsafe { netc::connect(self.as_raw_fd(), addr.as_ptr(), len) })?;
|
||||
Ok(())
|
||||
}
|
||||
@ -256,7 +256,7 @@ impl Socket {
|
||||
&mut addrlen,
|
||||
)
|
||||
})?;
|
||||
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
||||
Ok((n as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? }))
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
|
@ -5,7 +5,7 @@ use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut};
|
||||
use crate::net::{Shutdown, SocketAddr};
|
||||
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
|
||||
use crate::sys::fd::FileDesc;
|
||||
use crate::sys::net::{getsockopt, setsockopt, sockaddr_to_addr};
|
||||
use crate::sys::net::{getsockopt, setsockopt};
|
||||
use crate::sys::pal::IsMinusOne;
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::time::{Duration, Instant};
|
||||
@ -19,8 +19,9 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use libc as netc;
|
||||
pub(super) use libc as netc;
|
||||
|
||||
use super::{socket_addr_from_c, socket_addr_to_c};
|
||||
pub use crate::sys::{cvt, cvt_r};
|
||||
|
||||
#[expect(non_camel_case_types)]
|
||||
@ -150,7 +151,7 @@ impl Socket {
|
||||
}
|
||||
|
||||
pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
|
||||
let (addr, len) = addr.into_inner();
|
||||
let (addr, len) = socket_addr_to_c(addr);
|
||||
loop {
|
||||
let result = unsafe { libc::connect(self.as_raw_fd(), addr.as_ptr(), len) };
|
||||
if result.is_minus_one() {
|
||||
@ -168,7 +169,7 @@ impl Socket {
|
||||
pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
|
||||
self.set_nonblocking(true)?;
|
||||
let r = unsafe {
|
||||
let (addr, len) = addr.into_inner();
|
||||
let (addr, len) = socket_addr_to_c(addr);
|
||||
cvt(libc::connect(self.as_raw_fd(), addr.as_ptr(), len))
|
||||
};
|
||||
self.set_nonblocking(false)?;
|
||||
@ -334,7 +335,7 @@ impl Socket {
|
||||
&mut addrlen,
|
||||
)
|
||||
})?;
|
||||
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
||||
Ok((n as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? }))
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
|
@ -1,19 +1,18 @@
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
pub(super) use libc as netc;
|
||||
use libc::{c_int, c_void, size_t};
|
||||
|
||||
use super::{getsockopt, setsockopt, socket_addr_from_c, socket_addr_to_c};
|
||||
use crate::ffi::CStr;
|
||||
use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut};
|
||||
use crate::net::{Shutdown, SocketAddr};
|
||||
use crate::os::wasi::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
|
||||
use crate::sys::net::{getsockopt, setsockopt, sockaddr_to_addr};
|
||||
use crate::sys::unsupported;
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::time::{Duration, Instant};
|
||||
use crate::{cmp, mem, str};
|
||||
|
||||
pub extern crate libc as netc;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type wrlen_t = size_t;
|
||||
|
||||
@ -89,7 +88,7 @@ impl Socket {
|
||||
}
|
||||
|
||||
pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
|
||||
let (addr, len) = addr.into_inner();
|
||||
let (addr, len) = socket_addr_to_c(addr);
|
||||
cvt_r(|| unsafe { netc::connect(self.as_raw_fd(), addr.as_ptr(), len) })?;
|
||||
Ok(())
|
||||
}
|
||||
@ -224,7 +223,7 @@ impl Socket {
|
||||
&mut addrlen,
|
||||
)
|
||||
})?;
|
||||
Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
|
||||
Ok((n as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? }))
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
use core::ffi::{c_int, c_long, c_ulong, c_ushort};
|
||||
|
||||
use super::{getsockopt, setsockopt, socket_addr_from_c, socket_addr_to_c};
|
||||
use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut, Read};
|
||||
use crate::net::{Shutdown, SocketAddr};
|
||||
use crate::os::windows::io::{
|
||||
@ -16,7 +17,7 @@ use crate::{cmp, mem, ptr, sys};
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type wrlen_t = i32;
|
||||
|
||||
pub mod netc {
|
||||
pub(super) mod netc {
|
||||
//! BSD socket compatibility shim
|
||||
//!
|
||||
//! Some Windows API types are not quite what's expected by our cross-platform
|
||||
@ -225,7 +226,7 @@ impl Socket {
|
||||
}
|
||||
|
||||
pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
|
||||
let (addr, len) = addr.into_inner();
|
||||
let (addr, len) = socket_addr_to_c(addr);
|
||||
let result = unsafe { c::connect(self.as_raw(), addr.as_ptr(), len) };
|
||||
cvt(result).map(drop)
|
||||
}
|
||||
@ -401,12 +402,12 @@ impl Socket {
|
||||
let error = unsafe { c::WSAGetLastError() };
|
||||
|
||||
if error == c::WSAESHUTDOWN {
|
||||
Ok((0, super::sockaddr_to_addr(&storage, addrlen as usize)?))
|
||||
Ok((0, unsafe { socket_addr_from_c(&storage, addrlen as usize)? }))
|
||||
} else {
|
||||
Err(io::Error::from_raw_os_error(error))
|
||||
}
|
||||
}
|
||||
_ => Ok((result as usize, super::sockaddr_to_addr(&storage, addrlen as usize)?)),
|
||||
_ => Ok((result as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? })),
|
||||
}
|
||||
}
|
||||
|
||||
@ -451,11 +452,11 @@ impl Socket {
|
||||
}
|
||||
None => 0,
|
||||
};
|
||||
super::setsockopt(self, c::SOL_SOCKET, kind, timeout)
|
||||
setsockopt(self, c::SOL_SOCKET, kind, timeout)
|
||||
}
|
||||
|
||||
pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
|
||||
let raw: u32 = super::getsockopt(self, c::SOL_SOCKET, kind)?;
|
||||
let raw: u32 = getsockopt(self, c::SOL_SOCKET, kind)?;
|
||||
if raw == 0 {
|
||||
Ok(None)
|
||||
} else {
|
||||
@ -488,26 +489,26 @@ impl Socket {
|
||||
l_linger: linger.unwrap_or_default().as_secs() as c_ushort,
|
||||
};
|
||||
|
||||
super::setsockopt(self, c::SOL_SOCKET, c::SO_LINGER, linger)
|
||||
setsockopt(self, c::SOL_SOCKET, c::SO_LINGER, linger)
|
||||
}
|
||||
|
||||
pub fn linger(&self) -> io::Result<Option<Duration>> {
|
||||
let val: c::LINGER = super::getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)?;
|
||||
let val: c::LINGER = getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)?;
|
||||
|
||||
Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64)))
|
||||
}
|
||||
|
||||
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
|
||||
super::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BOOL)
|
||||
setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BOOL)
|
||||
}
|
||||
|
||||
pub fn nodelay(&self) -> io::Result<bool> {
|
||||
let raw: c::BOOL = super::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?;
|
||||
let raw: c::BOOL = getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?;
|
||||
Ok(raw != 0)
|
||||
}
|
||||
|
||||
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
|
||||
let raw: c_int = super::getsockopt(self, c::SOL_SOCKET, c::SO_ERROR)?;
|
||||
let raw: c_int = getsockopt(self, c::SOL_SOCKET, c::SO_ERROR)?;
|
||||
if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) }
|
||||
}
|
||||
|
||||
|
@ -332,38 +332,3 @@ impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(nonstandard_style)]
|
||||
pub mod netc {
|
||||
pub const AF_INET: u8 = 0;
|
||||
pub const AF_INET6: u8 = 1;
|
||||
pub type sa_family_t = u8;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in_addr {
|
||||
pub s_addr: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in {
|
||||
#[allow(dead_code)]
|
||||
pub sin_family: sa_family_t,
|
||||
pub sin_port: u16,
|
||||
pub sin_addr: in_addr,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in6_addr {
|
||||
pub s6_addr: [u8; 16],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in6 {
|
||||
#[allow(dead_code)]
|
||||
pub sin6_family: sa_family_t,
|
||||
pub sin6_port: u16,
|
||||
pub sin6_addr: in6_addr,
|
||||
pub sin6_flowinfo: u32,
|
||||
pub sin6_scope_id: u32,
|
||||
}
|
||||
}
|
||||
|
@ -332,38 +332,3 @@ impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(nonstandard_style)]
|
||||
pub mod netc {
|
||||
pub const AF_INET: u8 = 0;
|
||||
pub const AF_INET6: u8 = 1;
|
||||
pub type sa_family_t = u8;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in_addr {
|
||||
pub s_addr: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in {
|
||||
#[allow(dead_code)]
|
||||
pub sin_family: sa_family_t,
|
||||
pub sin_port: u16,
|
||||
pub sin_addr: in_addr,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in6_addr {
|
||||
pub s6_addr: [u8; 16],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in6 {
|
||||
#[allow(dead_code)]
|
||||
pub sin6_family: sa_family_t,
|
||||
pub sin6_port: u16,
|
||||
pub sin6_addr: in6_addr,
|
||||
pub sin6_flowinfo: u32,
|
||||
pub sin6_scope_id: u32,
|
||||
}
|
||||
}
|
||||
|
@ -505,38 +505,3 @@ impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
|
||||
unsupported()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(nonstandard_style)]
|
||||
pub mod netc {
|
||||
pub const AF_INET: u8 = 0;
|
||||
pub const AF_INET6: u8 = 1;
|
||||
pub type sa_family_t = u8;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in_addr {
|
||||
pub s_addr: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in {
|
||||
#[allow(dead_code)]
|
||||
pub sin_family: sa_family_t,
|
||||
pub sin_port: u16,
|
||||
pub sin_addr: in_addr,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in6_addr {
|
||||
pub s6_addr: [u8; 16],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in6 {
|
||||
#[allow(dead_code)]
|
||||
pub sin6_family: sa_family_t,
|
||||
pub sin6_port: u16,
|
||||
pub sin6_addr: in6_addr,
|
||||
pub sin6_flowinfo: u32,
|
||||
pub sin6_scope_id: u32,
|
||||
}
|
||||
}
|
||||
|
@ -46,38 +46,3 @@ pub struct GetAddress {
|
||||
}
|
||||
|
||||
pub use dns::LookupHost;
|
||||
|
||||
#[allow(nonstandard_style)]
|
||||
pub mod netc {
|
||||
pub const AF_INET: u8 = 0;
|
||||
pub const AF_INET6: u8 = 1;
|
||||
pub type sa_family_t = u8;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in_addr {
|
||||
pub s_addr: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in {
|
||||
#[allow(dead_code)]
|
||||
pub sin_family: sa_family_t,
|
||||
pub sin_port: u16,
|
||||
pub sin_addr: in_addr,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct in6_addr {
|
||||
pub s6_addr: [u8; 16],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct sockaddr_in6 {
|
||||
#[allow(dead_code)]
|
||||
pub sin6_family: sa_family_t,
|
||||
pub sin6_port: u16,
|
||||
pub sin6_addr: in6_addr,
|
||||
pub sin6_flowinfo: u32,
|
||||
pub sin6_scope_id: u32,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user