Skip to content

Commit f430d29

Browse files
committed
feat(net,cmsg): add CMsgRef wrapper, remove space_of
1 parent 9f3b1db commit f430d29

File tree

3 files changed

+51
-50
lines changed

3 files changed

+51
-50
lines changed

compio-net/src/cmsg/mod.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,36 @@ cfg_if::cfg_if! {
1010
}
1111
}
1212

13-
pub use sys::CMsgRef;
13+
/// Reference to a control message.
14+
pub struct CMsgRef<'a>(sys::CMsgRef<'a>);
15+
16+
impl<'a> CMsgRef<'a> {
17+
/// Returns the level of the control message.
18+
pub fn level(&self) -> i32 {
19+
self.0.level()
20+
}
21+
22+
/// Returns the type of the control message.
23+
pub fn ty(&self) -> i32 {
24+
self.0.ty()
25+
}
26+
27+
/// Returns the length of the control message.
28+
#[allow(clippy::len_without_is_empty)]
29+
pub fn len(&self) -> usize {
30+
self.0.len() as _
31+
}
32+
33+
/// Returns a reference to the data of the control message.
34+
///
35+
/// # Safety
36+
///
37+
/// The data part must be properly aligned and contains an initialized
38+
/// instance of `T`.
39+
pub unsafe fn data<T>(&self) -> &T {
40+
self.0.data()
41+
}
42+
}
1443

1544
/// An iterator for control messages.
1645
pub struct CMsgIter<'a> {
@@ -44,7 +73,7 @@ impl<'a> Iterator for CMsgIter<'a> {
4473
unsafe {
4574
let cmsg = self.inner.current();
4675
self.inner.next();
47-
cmsg
76+
cmsg.map(CMsgRef)
4877
}
4978
}
5079
}
@@ -91,10 +120,9 @@ impl<'a> CMsgBuilder<'a> {
91120
let mut cmsg = self.inner.current_mut()?;
92121
cmsg.set_level(level);
93122
cmsg.set_ty(ty);
94-
cmsg.set_data(value);
123+
self.len += cmsg.set_data(value);
95124

96125
self.inner.next();
97-
self.len += sys::space_of::<T>();
98126
}
99127

100128
Some(())

compio-net/src/cmsg/unix.rs

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,21 @@
11
use libc::{c_int, cmsghdr, msghdr, CMSG_DATA, CMSG_FIRSTHDR, CMSG_LEN, CMSG_NXTHDR, CMSG_SPACE};
22

3-
/// Reference to a control message.
4-
pub struct CMsgRef<'a>(&'a cmsghdr);
3+
pub(crate) struct CMsgRef<'a>(&'a cmsghdr);
54

65
impl<'a> CMsgRef<'a> {
7-
/// Returns the level of the control message.
8-
pub fn level(&self) -> c_int {
6+
pub(crate) fn level(&self) -> c_int {
97
self.0.cmsg_level
108
}
119

12-
/// Returns the type of the control message.
13-
pub fn ty(&self) -> c_int {
10+
pub(crate) fn ty(&self) -> c_int {
1411
self.0.cmsg_type
1512
}
1613

17-
/// Returns the length of the control message.
18-
#[allow(clippy::len_without_is_empty)]
19-
pub fn len(&self) -> usize {
14+
pub(crate) fn len(&self) -> usize {
2015
self.0.cmsg_len as _
2116
}
2217

23-
/// Returns a reference to the data of the control message.
24-
///
25-
/// # Safety
26-
///
27-
/// The data part must be properly aligned and contains an initialized
28-
/// instance of `T`.
29-
pub unsafe fn data<T>(&self) -> &T {
18+
pub(crate) unsafe fn data<T>(&self) -> &T {
3019
let data_ptr = CMSG_DATA(self.0);
3120
data_ptr.cast::<T>().as_ref().unwrap()
3221
}
@@ -43,10 +32,11 @@ impl<'a> CMsgMut<'a> {
4332
self.0.cmsg_type = ty;
4433
}
4534

46-
pub(crate) unsafe fn set_data<T>(&mut self, data: T) {
35+
pub(crate) unsafe fn set_data<T>(&mut self, data: T) -> usize {
4736
self.0.cmsg_len = CMSG_LEN(std::mem::size_of::<T>() as _) as _;
4837
let data_ptr = CMSG_DATA(self.0);
4938
std::ptr::write(data_ptr.cast::<T>(), data);
39+
CMSG_SPACE(std::mem::size_of::<T>() as _) as _
5040
}
5141
}
5242

@@ -97,7 +87,3 @@ impl CMsgIter {
9787
}
9888
}
9989
}
100-
101-
pub(crate) fn space_of<T>() -> usize {
102-
unsafe { CMSG_SPACE(std::mem::size_of::<T>() as _) as _ }
103-
}

compio-net/src/cmsg/windows.rs

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
use std::ptr::null_mut;
1+
use std::{
2+
mem::{align_of, size_of},
3+
ptr::null_mut,
4+
};
25

36
use windows_sys::Win32::Networking::WinSock::{CMSGHDR, WSABUF, WSAMSG};
47

58
// Macros from https://github.com/microsoft/win32metadata/blob/main/generation/WinSDK/RecompiledIdlHeaders/shared/ws2def.h
69
#[inline]
710
const fn wsa_cmsghdr_align(length: usize) -> usize {
8-
(length + std::mem::align_of::<CMSGHDR>() - 1) & !(std::mem::align_of::<CMSGHDR>() - 1)
11+
(length + align_of::<CMSGHDR>() - 1) & !(align_of::<CMSGHDR>() - 1)
912
}
1013

1114
// WSA_CMSGDATA_ALIGN(sizeof(CMSGHDR))
1215
const WSA_CMSGDATA_OFFSET: usize =
13-
(std::mem::size_of::<CMSGHDR>() + std::mem::align_of::<usize>() - 1) & !(std::mem::align_of::<usize>() - 1);
16+
(size_of::<CMSGHDR>() + align_of::<usize>() - 1) & !(align_of::<usize>() - 1);
1417

1518
#[inline]
1619
unsafe fn wsa_cmsg_firsthdr(msg: *const WSAMSG) -> *mut CMSGHDR {
17-
if (*msg).Control.len as usize >= std::mem::size_of::<CMSGHDR>() {
20+
if (*msg).Control.len as usize >= size_of::<CMSGHDR>() {
1821
(*msg).Control.buf as _
1922
} else {
2023
null_mut()
@@ -27,9 +30,7 @@ unsafe fn wsa_cmsg_nxthdr(msg: *const WSAMSG, cmsg: *const CMSGHDR) -> *mut CMSG
2730
wsa_cmsg_firsthdr(msg)
2831
} else {
2932
let next = cmsg as usize + wsa_cmsghdr_align((*cmsg).cmsg_len);
30-
if next + std::mem::size_of::<CMSGHDR>()
31-
> (*msg).Control.buf as usize + (*msg).Control.len as usize
32-
{
33+
if next + size_of::<CMSGHDR>() > (*msg).Control.buf as usize + (*msg).Control.len as usize {
3334
null_mut()
3435
} else {
3536
next as _
@@ -52,32 +53,21 @@ const fn wsa_cmsg_len(length: usize) -> usize {
5253
WSA_CMSGDATA_OFFSET + length
5354
}
5455

55-
/// Reference to a control message.
5656
pub struct CMsgRef<'a>(&'a CMSGHDR);
5757

5858
impl<'a> CMsgRef<'a> {
59-
/// Returns the level of the control message.
6059
pub fn level(&self) -> i32 {
6160
self.0.cmsg_level
6261
}
6362

64-
/// Returns the type of the control message.
6563
pub fn ty(&self) -> i32 {
6664
self.0.cmsg_type
6765
}
6866

69-
/// Returns the length of the control message.
70-
#[allow(clippy::len_without_is_empty)]
7167
pub fn len(&self) -> usize {
7268
self.0.cmsg_len
7369
}
7470

75-
/// Returns a reference to the data of the control message.
76-
///
77-
/// # Safety
78-
///
79-
/// The data part must be properly aligned and contains an initialized
80-
/// instance of `T`.
8171
pub unsafe fn data<T>(&self) -> &T {
8272
let data_ptr = wsa_cmsg_data(self.0);
8373
data_ptr.cast::<T>().as_ref().unwrap()
@@ -95,10 +85,11 @@ impl<'a> CMsgMut<'a> {
9585
self.0.cmsg_type = ty;
9686
}
9787

98-
pub(crate) unsafe fn set_data<T>(&mut self, data: T) {
99-
self.0.cmsg_len = wsa_cmsg_len(std::mem::size_of::<T>() as _) as _;
88+
pub(crate) unsafe fn set_data<T>(&mut self, data: T) -> usize {
89+
self.0.cmsg_len = wsa_cmsg_len(size_of::<T>() as _) as _;
10090
let data_ptr = wsa_cmsg_data(self.0);
10191
std::ptr::write(data_ptr.cast::<T>(), data);
92+
wsa_cmsg_space(size_of::<T>() as _)
10293
}
10394
}
10495

@@ -142,15 +133,11 @@ impl CMsgIter {
142133

143134
pub(crate) fn is_space_enough<T>(&self) -> bool {
144135
if !self.cmsg.is_null() {
145-
let space = wsa_cmsg_space(std::mem::size_of::<T>() as _);
136+
let space = wsa_cmsg_space(size_of::<T>() as _);
146137
let max = self.msg.Control.buf as usize + self.msg.Control.len as usize;
147138
self.cmsg as usize + space <= max
148139
} else {
149140
false
150141
}
151142
}
152143
}
153-
154-
pub(crate) fn space_of<T>() -> usize {
155-
wsa_cmsg_space(std::mem::size_of::<T>() as _)
156-
}

0 commit comments

Comments
 (0)