Skip to content

std: replace the FromInner implementation for addresses with private conversion functions #136699

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 13, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 0 additions & 29 deletions library/std/src/net/ip_addr.rs
Original file line number Diff line number Diff line change
@@ -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)
}
}
46 changes: 2 additions & 44 deletions library/std/src/net/socket_addr.rs
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 2 additions & 2 deletions library/std/src/os/solid/io.rs
Original file line number Diff line number Diff line change
@@ -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()) };
}
}

35 changes: 0 additions & 35 deletions library/std/src/sys/net/connection/sgx.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}
188 changes: 120 additions & 68 deletions library/std/src/sys/net/connection/socket.rs
Original file line number Diff line number Diff line change
@@ -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,31 +743,31 @@ 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)
}

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)
}
}
}
}
10 changes: 5 additions & 5 deletions library/std/src/sys/net/connection/socket/hermit.rs
Original file line number Diff line number Diff line change
@@ -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,15 +55,15 @@ 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(())
}

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)> {
8 changes: 4 additions & 4 deletions library/std/src/sys/net/connection/socket/solid.rs
Original file line number Diff line number Diff line change
@@ -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)> {
11 changes: 6 additions & 5 deletions library/std/src/sys/net/connection/socket/unix.rs
Original file line number Diff line number Diff line change
@@ -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)> {
9 changes: 4 additions & 5 deletions library/std/src/sys/net/connection/socket/wasip2.rs
Original file line number Diff line number Diff line change
@@ -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)> {
23 changes: 12 additions & 11 deletions library/std/src/sys/net/connection/socket/windows.rs
Original file line number Diff line number Diff line change
@@ -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))) }
}

35 changes: 0 additions & 35 deletions library/std/src/sys/net/connection/uefi/mod.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}
35 changes: 0 additions & 35 deletions library/std/src/sys/net/connection/unsupported.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}
35 changes: 0 additions & 35 deletions library/std/src/sys/net/connection/wasip1.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}
35 changes: 0 additions & 35 deletions library/std/src/sys/net/connection/xous/mod.rs
Original file line number Diff line number Diff line change
@@ -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,
}
}