Skip to content
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

Add trait to reduce duplicated code between socket address types, implement netlink addresses #1004

Merged
merged 10 commits into from
Feb 11, 2025
10 changes: 6 additions & 4 deletions src/backend/libc/net/addr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use core::slice;
use {
crate::ffi::CStr,
crate::io,
crate::net::addr::SocketAddrLen,
crate::path,
core::cmp::Ordering,
core::fmt,
Expand Down Expand Up @@ -151,14 +152,14 @@ impl SocketAddrUnix {
}

#[inline]
pub(crate) fn addr_len(&self) -> c::socklen_t {
pub(crate) fn addr_len(&self) -> SocketAddrLen {
#[cfg(not(any(bsd, target_os = "haiku")))]
{
self.len
self.len as _
}
#[cfg(any(bsd, target_os = "haiku"))]
{
c::socklen_t::from(self.unix.sun_len)
c::socklen_t::from(self.unix.sun_len) as _
}
}

Expand All @@ -169,7 +170,7 @@ impl SocketAddrUnix {

#[inline]
fn bytes(&self) -> Option<&[u8]> {
let len = self.len() as usize;
let len = self.len();
if len != 0 {
let bytes = &self.unix.sun_path[..len - offsetof_sun_path()];
// SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`.
Expand Down Expand Up @@ -238,6 +239,7 @@ impl fmt::Debug for SocketAddrUnix {

/// `struct sockaddr_storage`.
#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct SocketAddrStorage(c::sockaddr_storage);

impl SocketAddrStorage {
Expand Down
111 changes: 22 additions & 89 deletions src/backend/libc/net/msghdr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,26 @@

use crate::backend::c;
use crate::backend::conv::{msg_control_len, msg_iov_len};
#[cfg(target_os = "linux")]
use crate::backend::net::write_sockaddr::encode_sockaddr_xdp;
use crate::backend::net::write_sockaddr::{encode_sockaddr_v4, encode_sockaddr_v6};

use crate::io::{self, IoSlice, IoSliceMut};
#[cfg(target_os = "linux")]
use crate::net::xdp::SocketAddrXdp;
use crate::net::{RecvAncillaryBuffer, SendAncillaryBuffer, SocketAddrV4, SocketAddrV6};
use crate::utils::as_ptr;
use crate::net::SocketAddrBuf;
use crate::net::{addr::SocketAddrArg, RecvAncillaryBuffer, SendAncillaryBuffer};

use core::mem::{size_of, zeroed, MaybeUninit};
use core::mem::zeroed;

/// Create a message header intended to receive a datagram.
pub(crate) fn with_recv_msghdr<R>(
name: &mut MaybeUninit<c::sockaddr_storage>,
name: &mut SocketAddrBuf,
iov: &mut [IoSliceMut<'_>],
control: &mut RecvAncillaryBuffer<'_>,
f: impl FnOnce(&mut c::msghdr) -> io::Result<R>,
) -> io::Result<R> {
control.clear();

let namelen = size_of::<c::sockaddr_storage>() as c::socklen_t;
let mut msghdr = {
let mut h = zero_msghdr();
h.msg_name = name.as_mut_ptr().cast();
h.msg_namelen = namelen;
h.msg_name = name.storage.as_mut_ptr().cast();
h.msg_namelen = name.len;
h.msg_iov = iov.as_mut_ptr().cast();
h.msg_iovlen = msg_iov_len(iov.len());
h.msg_control = control.as_control_ptr().cast();
Expand All @@ -47,6 +41,8 @@ pub(crate) fn with_recv_msghdr<R>(
}
}

name.len = msghdr.msg_namelen;

res
}

Expand All @@ -66,87 +62,24 @@ pub(crate) fn with_noaddr_msghdr<R>(
})
}

/// Create a message header intended to send with an IPv4 address.
pub(crate) fn with_v4_msghdr<R>(
addr: &SocketAddrV4,
iov: &[IoSlice<'_>],
control: &mut SendAncillaryBuffer<'_, '_, '_>,
f: impl FnOnce(c::msghdr) -> R,
) -> R {
let encoded = encode_sockaddr_v4(addr);

f({
let mut h = zero_msghdr();
h.msg_name = as_ptr(&encoded) as _;
h.msg_namelen = size_of::<SocketAddrV4>() as _;
h.msg_iov = iov.as_ptr() as _;
h.msg_iovlen = msg_iov_len(iov.len());
h.msg_control = control.as_control_ptr().cast();
h.msg_controllen = msg_control_len(control.control_len());
h
})
}

/// Create a message header intended to send with an IPv6 address.
pub(crate) fn with_v6_msghdr<R>(
addr: &SocketAddrV6,
iov: &[IoSlice<'_>],
control: &mut SendAncillaryBuffer<'_, '_, '_>,
f: impl FnOnce(c::msghdr) -> R,
) -> R {
let encoded = encode_sockaddr_v6(addr);

f({
let mut h = zero_msghdr();
h.msg_name = as_ptr(&encoded) as _;
h.msg_namelen = size_of::<SocketAddrV6>() as _;
h.msg_iov = iov.as_ptr() as _;
h.msg_iovlen = msg_iov_len(iov.len());
h.msg_control = control.as_control_ptr().cast();
h.msg_controllen = msg_control_len(control.control_len());
h
})
}

/// Create a message header intended to send with a Unix address.
#[cfg(all(unix, not(target_os = "redox")))]
pub(crate) fn with_unix_msghdr<R>(
addr: &crate::net::SocketAddrUnix,
/// Create a message header intended to send with the specified address.
pub(crate) fn with_msghdr<R>(
addr: &impl SocketAddrArg,
iov: &[IoSlice<'_>],
control: &mut SendAncillaryBuffer<'_, '_, '_>,
f: impl FnOnce(c::msghdr) -> R,
) -> R {
f({
let mut h = zero_msghdr();
h.msg_name = as_ptr(&addr.unix) as _;
h.msg_namelen = addr.addr_len();
h.msg_iov = iov.as_ptr() as _;
h.msg_iovlen = msg_iov_len(iov.len());
h.msg_control = control.as_control_ptr().cast();
h.msg_controllen = msg_control_len(control.control_len());
h
})
}

/// Create a message header intended to send with an IPv6 address.
#[cfg(target_os = "linux")]
pub(crate) fn with_xdp_msghdr<R>(
addr: &SocketAddrXdp,
iov: &[IoSlice<'_>],
control: &mut SendAncillaryBuffer<'_, '_, '_>,
f: impl FnOnce(c::msghdr) -> R,
) -> R {
let encoded = encode_sockaddr_xdp(addr);

f({
let mut h = zero_msghdr();
h.msg_name = as_ptr(&encoded) as _;
h.msg_namelen = size_of::<SocketAddrXdp>() as _;
h.msg_iov = iov.as_ptr() as _;
h.msg_iovlen = msg_iov_len(iov.len());
h.msg_control = control.as_control_ptr().cast();
h.msg_controllen = msg_control_len(control.control_len());
h
addr.with_sockaddr(|addr_ptr, addr_len| {
f({
let mut h = zero_msghdr();
h.msg_name = addr_ptr as *mut _;
h.msg_namelen = addr_len as _;
h.msg_iov = iov.as_ptr() as _;
h.msg_iovlen = msg_iov_len(iov.len());
h.msg_control = control.as_control_ptr().cast();
h.msg_controllen = msg_control_len(control.control_len());
h
})
})
}

Expand Down
Loading
Loading