Ensure cmsg buffer alignment

This commit is contained in:
Benjamin Saunders
2019-02-13 18:38:00 -08:00
committed by Dirkjan Ochtman
parent feafacbf45
commit f6563b26b9
2 changed files with 13 additions and 4 deletions
+3
View File
@@ -1,5 +1,8 @@
use std::{mem, ptr};
#[repr(align(8))] // Conservative bound for align_of<cmsghdr>
pub struct Aligned<T>(pub T);
/// Helper to encode a series of control messages ("cmsgs") to a buffer for use in `sendmsg`.
///
/// The operation must be "finished" for the msghdr to be usable, either by calling `finish`
+10 -4
View File
@@ -25,6 +25,10 @@ impl super::UdpExt for UdpSocket {
assert_eq!(CMSG_LEN, unsafe {
libc::CMSG_SPACE(mem::size_of::<libc::c_int>() as _) as usize
});
assert!(
mem::align_of::<libc::cmsghdr>() <= mem::align_of::<cmsg::Aligned<[u8; 0]>>(),
"control message buffers will be misaligned"
);
let addr = self.local_addr()?;
@@ -88,12 +92,13 @@ impl super::UdpExt for UdpSocket {
msg_controllen: 0,
msg_flags: 0,
};
let mut ctrl: [u8; CMSG_LEN] = unsafe { mem::uninitialized() };
let mut ctrl: cmsg::Aligned<[u8; CMSG_LEN]> =
cmsg::Aligned(unsafe { mem::uninitialized() });
let is_ipv4 = match remote {
SocketAddr::V4(_) => true,
SocketAddr::V6(ref addr) => addr.ip().segments().starts_with(&[0, 0, 0, 0, 0, 0xffff]),
};
let mut encoder = cmsg::Encoder::new(&mut hdr, &mut ctrl);
let mut encoder = unsafe { cmsg::Encoder::new(&mut hdr, &mut ctrl.0) };
if is_ipv4 {
encoder.push(libc::IPPROTO_IP, libc::IP_TOS, ecn);
} else {
@@ -119,13 +124,14 @@ impl super::UdpExt for UdpSocket {
iov_base: buf.as_ptr() as *mut _,
iov_len: buf.len(),
};
let mut ctrl: [u8; CMSG_LEN] = unsafe { mem::uninitialized() };
let mut ctrl: cmsg::Aligned<[u8; CMSG_LEN]> =
cmsg::Aligned(unsafe { mem::uninitialized() });
let mut hdr = libc::msghdr {
msg_name: &mut name as *mut _ as _,
msg_namelen: mem::size_of::<libc::sockaddr_storage>() as _,
msg_iov: &mut iov,
msg_iovlen: 1,
msg_control: ctrl.as_mut_ptr() as _,
msg_control: ctrl.0.as_mut_ptr() as _,
msg_controllen: CMSG_LEN as _,
msg_flags: 0,
};