Skip to content

Commit 8554139

Browse files
committed
Introduce a SocketAddrLen type and use it for SocketAddrOpaque sizes.
1 parent 7eebda1 commit 8554139

File tree

10 files changed

+80
-57
lines changed

10 files changed

+80
-57
lines changed

src/backend/libc/net/addr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ impl SocketAddrUnix {
169169

170170
#[inline]
171171
fn bytes(&self) -> Option<&[u8]> {
172-
let len = self.len() as usize;
172+
let len = self.len();
173173
if len != 0 {
174174
let bytes = &self.unix.sun_path[..len - offsetof_sun_path()];
175175
// SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`.

src/backend/libc/net/msghdr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub(crate) fn with_msghdr<R>(
7373
f({
7474
let mut h = zero_msghdr();
7575
h.msg_name = addr_ptr as *mut _;
76-
h.msg_namelen = addr_len as c::socklen_t;
76+
h.msg_namelen = addr_len;
7777
h.msg_iov = iov.as_ptr() as _;
7878
h.msg_iovlen = msg_iov_len(iov.len());
7979
h.msg_control = control.as_control_ptr().cast();

src/backend/libc/net/read_sockaddr.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,12 @@ unsafe fn read_sun_path0(storage: *const c::sockaddr) -> u8 {
113113
///
114114
/// `storage` must point to a valid socket address returned from the OS.
115115
#[inline]
116-
pub(crate) unsafe fn sockaddr_nonempty(storage: *const c::sockaddr, len: usize) -> bool {
116+
pub(crate) unsafe fn sockaddr_nonempty(storage: *const c::sockaddr, len: c::socklen_t) -> bool {
117117
if len == 0 {
118118
return false;
119119
}
120120

121-
assert!(len >= size_of::<c::sa_family_t>());
121+
assert!(len as usize >= size_of::<c::sa_family_t>());
122122
let family: c::c_int = read_sa_family(storage.cast::<c::sockaddr>()).into();
123123
if family == c::AF_UNSPEC {
124124
return false;
@@ -145,7 +145,7 @@ pub(crate) fn read_sockaddr_v4(addr: &SocketAddrAny) -> Result<SocketAddrV4, Err
145145
if addr.address_family() != AddressFamily::INET {
146146
return Err(Errno::AFNOSUPPORT);
147147
}
148-
assert!(addr.len() >= size_of::<c::sockaddr_in>());
148+
assert!(addr.len() as usize >= size_of::<c::sockaddr_in>());
149149
let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_in>() };
150150
Ok(SocketAddrV4::new(
151151
Ipv4Addr::from(u32::from_be(in_addr_s_addr(decode.sin_addr))),
@@ -158,7 +158,7 @@ pub(crate) fn read_sockaddr_v6(addr: &SocketAddrAny) -> Result<SocketAddrV6, Err
158158
if addr.address_family() != AddressFamily::INET6 {
159159
return Err(Errno::AFNOSUPPORT);
160160
}
161-
assert!(addr.len() >= size_of::<c::sockaddr_in6>());
161+
assert!(addr.len() as usize >= size_of::<c::sockaddr_in6>());
162162
let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_in6>() };
163163
Ok(SocketAddrV6::new(
164164
Ipv6Addr::from(in6_addr_s6_addr(decode.sin6_addr)),
@@ -176,7 +176,7 @@ pub(crate) fn read_sockaddr_unix(addr: &SocketAddrAny) -> Result<SocketAddrUnix,
176176
}
177177

178178
let offsetof_sun_path = super::addr::offsetof_sun_path();
179-
let len = addr.len();
179+
let len = addr.len() as usize;
180180

181181
assert!(len >= offsetof_sun_path);
182182

@@ -232,7 +232,7 @@ pub(crate) fn read_sockaddr_xdp(addr: &SocketAddrAny) -> Result<SocketAddrXdp, E
232232
if addr.address_family() != AddressFamily::XDP {
233233
return Err(Errno::AFNOSUPPORT);
234234
}
235-
assert!(addr.len() >= size_of::<c::sockaddr_xdp>());
235+
assert!(addr.len() as usize >= size_of::<c::sockaddr_xdp>());
236236
let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_xdp>() };
237237
Ok(SocketAddrXdp::new(
238238
SockaddrXdpFlags::from_bits_retain(decode.sxdp_flags),
@@ -248,7 +248,7 @@ pub(crate) fn read_sockaddr_netlink(addr: &SocketAddrAny) -> Result<SocketAddrNe
248248
if addr.address_family() != AddressFamily::NETLINK {
249249
return Err(Errno::AFNOSUPPORT);
250250
}
251-
assert!(addr.len() >= size_of::<c::sockaddr_nl>());
251+
assert!(addr.len() as usize >= size_of::<c::sockaddr_nl>());
252252
let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_nl>() };
253253
Ok(SocketAddrNetlink::new(decode.nl_pid, decode.nl_groups))
254254
}

src/backend/libc/net/syscalls.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub(crate) fn sendto(
8585
send_recv_len(buf.len()),
8686
bitflags_bits!(flags),
8787
addr_ptr.cast(),
88-
addr_len as c::socklen_t,
88+
addr_len,
8989
))
9090
})
9191
}
@@ -131,23 +131,15 @@ pub(crate) fn socket_with(
131131
pub(crate) fn bind(sockfd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Result<()> {
132132
unsafe {
133133
addr.with_sockaddr(|addr_ptr, addr_len| {
134-
ret(c::bind(
135-
borrowed_fd(sockfd),
136-
addr_ptr.cast(),
137-
addr_len as c::socklen_t,
138-
))
134+
ret(c::bind(borrowed_fd(sockfd), addr_ptr.cast(), addr_len))
139135
})
140136
}
141137
}
142138

143139
pub(crate) fn connect(sockfd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Result<()> {
144140
unsafe {
145141
addr.with_sockaddr(|addr_ptr, addr_len| {
146-
ret(c::connect(
147-
borrowed_fd(sockfd),
148-
addr_ptr.cast(),
149-
addr_len as c::socklen_t,
150-
))
142+
ret(c::connect(borrowed_fd(sockfd), addr_ptr.cast(), addr_len))
151143
})
152144
}
153145
}

src/backend/linux_raw/net/addr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl SocketAddrUnix {
132132

133133
#[inline]
134134
fn bytes(&self) -> Option<&[u8]> {
135-
let len = self.len() as usize;
135+
let len = self.len();
136136
if len != 0 {
137137
let bytes = &self.unix.sun_path[..len - offsetof_sun_path()];
138138
// SAFETY: `from_raw_parts` to convert from `&[c_char]` to `&[u8]`.

src/backend/linux_raw/net/read_sockaddr.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub(crate) unsafe fn initialize_family_to_unspec(storage: *mut c::sockaddr) {
5050

5151
/// Check if a socket address returned from the OS is considered non-empty.
5252
#[inline]
53-
pub(crate) unsafe fn sockaddr_nonempty(_storage: *const c::sockaddr, len: usize) -> bool {
53+
pub(crate) unsafe fn sockaddr_nonempty(_storage: *const c::sockaddr, len: c::socklen_t) -> bool {
5454
len != 0
5555
}
5656

@@ -59,7 +59,7 @@ pub(crate) fn read_sockaddr_v4(addr: &SocketAddrAny) -> Result<SocketAddrV4, Err
5959
if addr.address_family() != AddressFamily::INET {
6060
return Err(Errno::AFNOSUPPORT);
6161
}
62-
assert!(addr.len() >= size_of::<c::sockaddr_in>());
62+
assert!(addr.len() as usize >= size_of::<c::sockaddr_in>());
6363
let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_in>() };
6464
Ok(SocketAddrV4::new(
6565
Ipv4Addr::from(u32::from_be(decode.sin_addr.s_addr)),
@@ -72,7 +72,7 @@ pub(crate) fn read_sockaddr_v6(addr: &SocketAddrAny) -> Result<SocketAddrV6, Err
7272
if addr.address_family() != AddressFamily::INET6 {
7373
return Err(Errno::AFNOSUPPORT);
7474
}
75-
assert!(addr.len() >= size_of::<c::sockaddr_in6>());
75+
assert!(addr.len() as usize >= size_of::<c::sockaddr_in6>());
7676
let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_in6>() };
7777
Ok(SocketAddrV6::new(
7878
Ipv6Addr::from(unsafe { decode.sin6_addr.in6_u.u6_addr8 }),
@@ -88,7 +88,7 @@ pub(crate) fn read_sockaddr_unix(addr: &SocketAddrAny) -> Result<SocketAddrUnix,
8888
return Err(Errno::AFNOSUPPORT);
8989
}
9090
let offsetof_sun_path = super::addr::offsetof_sun_path();
91-
let len = addr.len();
91+
let len = addr.len() as usize;
9292

9393
assert!(len >= offsetof_sun_path);
9494

@@ -125,7 +125,7 @@ pub(crate) fn read_sockaddr_xdp(addr: &SocketAddrAny) -> Result<SocketAddrXdp, E
125125
if addr.address_family() != AddressFamily::XDP {
126126
return Err(Errno::AFNOSUPPORT);
127127
}
128-
assert!(addr.len() >= size_of::<c::sockaddr_xdp>());
128+
assert!(addr.len() as usize >= size_of::<c::sockaddr_xdp>());
129129
let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_xdp>() };
130130
Ok(SocketAddrXdp::new(
131131
SockaddrXdpFlags::from_bits_retain(decode.sxdp_flags),
@@ -140,7 +140,7 @@ pub(crate) fn read_sockaddr_netlink(addr: &SocketAddrAny) -> Result<SocketAddrNe
140140
if addr.address_family() != AddressFamily::NETLINK {
141141
return Err(Errno::AFNOSUPPORT);
142142
}
143-
assert!(addr.len() >= size_of::<c::sockaddr_nl>());
143+
assert!(addr.len() as usize >= size_of::<c::sockaddr_nl>());
144144
let decode = unsafe { &*addr.as_ptr().cast::<c::sockaddr_nl>() };
145145
Ok(SocketAddrNetlink::new(decode.nl_pid, decode.nl_groups))
146146
}

src/backend/linux_raw/net/syscalls.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use crate::net::{
2121
addr::SocketAddrArg, AddressFamily, Protocol, RecvAncillaryBuffer, RecvMsg,
2222
SendAncillaryBuffer, Shutdown, SocketAddrAny, SocketFlags, SocketType,
2323
};
24-
use c::socklen_t;
2524
use core::mem::MaybeUninit;
2625
#[cfg(target_arch = "x86")]
2726
use {
@@ -421,7 +420,7 @@ pub(crate) fn sendto(
421420
buf_len,
422421
flags,
423422
raw_arg(addr_ptr as *mut _),
424-
socklen_t(addr_len as socklen_t)
423+
socklen_t(addr_len)
425424
))
426425
}
427426
#[cfg(target_arch = "x86")]
@@ -435,7 +434,7 @@ pub(crate) fn sendto(
435434
buf_len,
436435
flags.into(),
437436
raw_arg(addr_ptr as *mut _),
438-
socklen_t(addr_len as socklen_t)
437+
socklen_t(addr_len)
439438
])
440439
))
441440
}
@@ -603,7 +602,7 @@ pub(crate) fn bind(fd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Result<
603602
__NR_bind,
604603
fd,
605604
raw_arg(addr_ptr as *mut _),
606-
socklen_t(addr_len as socklen_t)
605+
socklen_t(addr_len)
607606
))
608607
}
609608
#[cfg(target_arch = "x86")]
@@ -614,7 +613,7 @@ pub(crate) fn bind(fd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Result<
614613
slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[
615614
fd.into(),
616615
raw_arg(addr_ptr as *mut _),
617-
socklen_t(addr_len as socklen_t)
616+
socklen_t(addr_len)
618617
])
619618
))
620619
}
@@ -630,7 +629,7 @@ pub(crate) fn connect(fd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Resu
630629
__NR_connect,
631630
fd,
632631
raw_arg(addr_ptr as *mut _),
633-
socklen_t(addr_len as socklen_t)
632+
socklen_t(addr_len)
634633
))
635634
}
636635
#[cfg(target_arch = "x86")]
@@ -641,7 +640,7 @@ pub(crate) fn connect(fd: BorrowedFd<'_>, addr: &impl SocketAddrArg) -> io::Resu
641640
slice_just_addr::<ArgReg<'_, SocketArg>, _>(&[
642641
fd.into(),
643642
raw_arg(addr_ptr as *mut _),
644-
socklen_t(addr_len as socklen_t)
643+
socklen_t(addr_len)
645644
])
646645
))
647646
}

src/net/addr.rs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ pub struct SocketAddrOpaque {
2828
_data: [u8; 0],
2929
}
3030

31+
/// A type for the length of a socket address.
32+
///
33+
/// This type will always be big enough to hold any socket address, but never
34+
/// bigger than `usize`.
35+
pub type SocketAddrLen = u32;
36+
3137
/// A trait abstracting over the types that can be passed as a `sockaddr`.
3238
///
3339
/// # Safety
@@ -44,13 +50,17 @@ pub unsafe trait SocketAddrArg {
4450
/// C type can pass it directly without a copy.
4551
/// * Other socket types can construct their C-compatible struct on the
4652
/// stack and call the closure with a pointer to it.
47-
fn with_sockaddr<R>(&self, f: impl FnOnce(*const SocketAddrOpaque, usize) -> R) -> R;
53+
fn with_sockaddr<R>(&self, f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R) -> R;
4854

4955
/// Convert to `SocketAddrAny`.
5056
fn as_any(&self) -> SocketAddrAny {
5157
self.with_sockaddr(|ptr, len| unsafe {
5258
let mut storage = MaybeUninit::<SocketAddrStorage>::uninit();
53-
ptr::copy_nonoverlapping(ptr.cast::<u8>(), storage.as_mut_ptr().cast::<u8>(), len);
59+
ptr::copy_nonoverlapping(
60+
ptr.cast::<u8>(),
61+
storage.as_mut_ptr().cast::<u8>(),
62+
len as usize,
63+
);
5464
SocketAddrAny::new(storage, len)
5565
})
5666
}
@@ -59,15 +69,15 @@ pub unsafe trait SocketAddrArg {
5969
/// Helper for implementing SocketAddrArg::with_sockaddr
6070
pub(crate) fn call_with_sockaddr<A, R>(
6171
addr: &A,
62-
f: impl FnOnce(*const SocketAddrOpaque, usize) -> R,
72+
f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R,
6373
) -> R {
6474
let ptr = (addr as *const A).cast();
65-
let len = size_of::<A>();
75+
let len = size_of::<A>() as SocketAddrLen;
6676
f(ptr, len)
6777
}
6878

6979
unsafe impl SocketAddrArg for super::SocketAddr {
70-
fn with_sockaddr<R>(&self, f: impl FnOnce(*const SocketAddrOpaque, usize) -> R) -> R {
80+
fn with_sockaddr<R>(&self, f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R) -> R {
7181
match self {
7282
SocketAddr::V4(v4) => v4.with_sockaddr(f),
7383
SocketAddr::V6(v6) => v6.with_sockaddr(f),
@@ -76,23 +86,39 @@ unsafe impl SocketAddrArg for super::SocketAddr {
7686
}
7787

7888
unsafe impl SocketAddrArg for SocketAddrV4 {
79-
fn with_sockaddr<R>(&self, f: impl FnOnce(*const SocketAddrOpaque, usize) -> R) -> R {
89+
fn with_sockaddr<R>(&self, f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R) -> R {
8090
call_with_sockaddr(&encode_sockaddr_v4(self), f)
8191
}
8292
}
8393

8494
unsafe impl SocketAddrArg for SocketAddrV6 {
85-
fn with_sockaddr<R>(&self, f: impl FnOnce(*const SocketAddrOpaque, usize) -> R) -> R {
95+
fn with_sockaddr<R>(&self, f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R) -> R {
8696
call_with_sockaddr(&encode_sockaddr_v6(self), f)
8797
}
8898
}
8999

90100
#[cfg(unix)]
91101
unsafe impl SocketAddrArg for SocketAddrUnix {
92-
fn with_sockaddr<R>(&self, f: impl FnOnce(*const SocketAddrOpaque, usize) -> R) -> R {
102+
fn with_sockaddr<R>(&self, f: impl FnOnce(*const SocketAddrOpaque, SocketAddrLen) -> R) -> R {
93103
f(
94104
(&self.unix as *const crate::backend::c::sockaddr_un).cast(),
95-
self.addr_len() as usize,
105+
self.addr_len(),
96106
)
97107
}
98108
}
109+
110+
#[cfg(test)]
111+
mod tests {
112+
use super::*;
113+
use crate::backend::c;
114+
115+
#[test]
116+
fn test_layouts() {
117+
assert_eq_size!(SocketAddrLen, c::socklen_t);
118+
assert_eq!(
119+
memoffset::span_of!(c::msghdr, msg_namelen).len(),
120+
size_of::<SocketAddrLen>()
121+
);
122+
assert!(size_of::<SocketAddrLen>() <= size_of::<usize>());
123+
}
124+
}

0 commit comments

Comments
 (0)