refactor(udp): drop cmsghdr from the payload unions

It was there when the union carried the buffer's alignment, since the buffer
holds headers as well as payloads, the C `union { struct cmsghdr hdr; char
buf[N]; }` idiom. The alignment now comes from a `usize`, which is at least as
strict as any platform's `cmsghdr`, so all the member did was feed
`size_of::<Payload>()` a header that `CMSG_SPACE` already accounts for.

No constant moves on any target we build: `in6_pktinfo` is the largest payload
everywhere `cmsghdr` is not. A union named for payloads now holds only those.
This commit is contained in:
dignifiedquire
2026-07-29 16:54:22 +02:00
parent f317ebc7d6
commit ec969f124a
2 changed files with 4 additions and 4 deletions
+2 -2
View File
@@ -15,7 +15,6 @@ use crate::imp::IpTosTy;
#[repr(C)]
#[allow(dead_code)] // the fields are here for their size, nothing reads them
pub(crate) union Payload {
hdr: libc::cmsghdr,
#[cfg(not(target_os = "netbsd"))]
ecn_v4: IpTosTy,
ecn_v6: c_int,
@@ -75,7 +74,8 @@ pub(crate) const RECV_LEN: usize = 4 * MESSAGE_LEN;
#[derive(Copy, Clone)]
#[repr(C)]
pub(crate) struct ControlBuf<const N: usize> {
/// Aligns the buffer like the `size_t` the `CMSG_*` macros round offsets to.
/// Aligns the buffer like the `size_t` the `CMSG_*` macros round offsets to, which
/// covers the headers too: no platform aligns `cmsghdr` more strictly than that.
/// Zero sized: `repr(align)` takes a literal, not an expression.
_align: [usize; 0],
bytes: [MaybeUninit<u8>; N],
+2 -2
View File
@@ -18,7 +18,6 @@ use super::{CMsgHdr, Encoder, MsgHdr};
#[repr(C)]
#[allow(dead_code)] // the fields are here for their size, nothing reads them
pub(crate) union Payload {
hdr: WinSock::CMSGHDR,
ecn: c_int,
segment_size: u32,
pktinfo_v4: WinSock::IN_PKTINFO,
@@ -75,7 +74,8 @@ pub(crate) const RECV_LEN: usize = 3 * MESSAGE_LEN;
#[derive(Copy, Clone)]
#[repr(C)]
pub(crate) struct ControlBuf<const N: usize> {
/// Aligns the buffer like the `usize` `WSA_CMSGDATA_ALIGN` rounds to.
/// Aligns the buffer like the `usize` `WSA_CMSGDATA_ALIGN` rounds to, which covers
/// the headers too: `CMSGHDR` is a `SIZE_T` and two `INT`s.
/// Zero sized: `repr(align)` takes a literal, not an expression.
_align: [usize; 0],
bytes: [MaybeUninit<u8>; N],