-
-
Notifications
You must be signed in to change notification settings - Fork 396
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
046a228
commit 3e81595
Showing
7 changed files
with
416 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
use std::ffi::{c_int, c_uchar}; | ||
|
||
use windows_sys::Win32::Networking::WinSock; | ||
|
||
use super::{CMsgHdr, MsgHdr}; | ||
|
||
#[derive(Copy, Clone)] | ||
#[repr(align(8))] // Conservative bound for align_of<WinSock::CMSGHDR> | ||
pub(crate) struct Aligned<T>(pub(crate) T); | ||
|
||
/// Helpers for [`WinSock::WSAMSG`] | ||
// https://learn.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-wsamsg | ||
// https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/struct.WSAMSG.html | ||
impl MsgHdr for WinSock::WSAMSG { | ||
type ControlMessage = WinSock::CMSGHDR; | ||
|
||
fn control_len(&self) -> usize { | ||
self.Control.len as _ | ||
} | ||
|
||
fn set_control_len(&mut self, len: usize) { | ||
self.Control.len = len as _; | ||
} | ||
|
||
fn cmsg_firsthdr(&self) -> *mut Self::ControlMessage { | ||
unsafe { self::wsa2::cmsg_firsthdr(self) } | ||
} | ||
|
||
fn cmsg_nxthdr(&self, cmsg: &Self::ControlMessage) -> *mut Self::ControlMessage { | ||
unsafe { self::wsa2::cmsg_nxthdr(self, cmsg) } | ||
} | ||
} | ||
|
||
/// Helpers for [`WinSock::CMSGHDR`] | ||
// https://learn.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-wsacmsghdr | ||
// https://microsoft.github.io/windows-docs-rs/doc/windows/Win32/Networking/WinSock/struct.CMSGHDR.html | ||
impl CMsgHdr for WinSock::CMSGHDR { | ||
fn set(&mut self, level: c_int, ty: c_int, len: usize) { | ||
self.cmsg_level = level as _; | ||
self.cmsg_type = ty as _; | ||
self.cmsg_len = len as _; | ||
} | ||
|
||
fn len(&self) -> usize { | ||
self.cmsg_len as _ | ||
} | ||
|
||
fn cmsg_space(length: usize) -> usize { | ||
self::wsa2::cmsg_space(length) | ||
} | ||
|
||
fn cmsg_len(length: usize) -> usize { | ||
self::wsa2::cmsg_len(length) | ||
} | ||
|
||
fn cmsg_data(&self) -> *mut c_uchar { | ||
unsafe { self::wsa2::cmsg_data(self) } | ||
} | ||
} | ||
|
||
mod wsa2 { | ||
use std::{mem, ptr}; | ||
|
||
use windows_sys::Win32::Networking::WinSock; | ||
|
||
// Helpers functions based on C macros from | ||
// https://github.com/microsoft/win32metadata/blob/main/generation/WinSDK/RecompiledIdlHeaders/shared/ws2def.h#L741 | ||
fn cmsghdr_align(length: usize) -> usize { | ||
(length + mem::align_of::<WinSock::CMSGHDR>() - 1) | ||
& !(mem::align_of::<WinSock::CMSGHDR>() - 1) | ||
} | ||
|
||
fn cmsgdata_align(length: usize) -> usize { | ||
(length + mem::align_of::<usize>() - 1) & !(mem::align_of::<usize>() - 1) | ||
} | ||
|
||
pub(crate) unsafe fn cmsg_firsthdr(msg: *const WinSock::WSAMSG) -> *mut WinSock::CMSGHDR { | ||
if (*msg).Control.len as usize >= mem::size_of::<WinSock::CMSGHDR>() { | ||
(*msg).Control.buf as *mut WinSock::CMSGHDR | ||
} else { | ||
ptr::null_mut::<WinSock::CMSGHDR>() | ||
} | ||
} | ||
|
||
pub(crate) unsafe fn cmsg_nxthdr( | ||
hdr: &WinSock::WSAMSG, | ||
cmsg: *const WinSock::CMSGHDR, | ||
) -> *mut WinSock::CMSGHDR { | ||
if cmsg.is_null() { | ||
return cmsg_firsthdr(hdr); | ||
} | ||
let next = (cmsg as usize + cmsghdr_align((*cmsg).cmsg_len)) as *mut WinSock::CMSGHDR; | ||
let max = hdr.Control.buf as usize + hdr.Control.len as usize; | ||
if (next.offset(1)) as usize > max { | ||
ptr::null_mut() | ||
} else { | ||
next | ||
} | ||
} | ||
|
||
pub(crate) unsafe fn cmsg_data(cmsg: *const WinSock::CMSGHDR) -> *mut u8 { | ||
(cmsg as usize + cmsgdata_align(mem::size_of::<WinSock::CMSGHDR>())) as *mut u8 | ||
} | ||
|
||
pub(crate) fn cmsg_space(length: usize) -> usize { | ||
cmsgdata_align(mem::size_of::<WinSock::CMSGHDR>() + cmsghdr_align(length)) | ||
} | ||
|
||
pub(crate) fn cmsg_len(length: usize) -> usize { | ||
cmsgdata_align(mem::size_of::<WinSock::CMSGHDR>()) + length | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.