Skip to content

Commit c070715

Browse files
committed
Don't assume representation of SocketAddr
1 parent badc801 commit c070715

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

quinn/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ codecov = { repository = "djc/quinn" }
2727
maintenance = { status = "experimental" }
2828

2929
[dependencies]
30+
socket2 = "0.3"
3031
bytes = "1"
3132
futures = "0.3.8"
3233
libc = "0.2.69"

quinn/src/platform/unix.rs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,19 @@ fn send(io: &mio::net::UdpSocket, transmits: &[Transmit]) -> io::Result<usize> {
198198
let mut msgs: [libc::mmsghdr; BATCH_SIZE] = unsafe { mem::zeroed() };
199199
let mut iovecs: [libc::iovec; BATCH_SIZE] = unsafe { mem::zeroed() };
200200
let mut cmsgs = [cmsg::Aligned([0u8; CMSG_LEN]); BATCH_SIZE];
201+
let mut addrs: [MaybeUninit<socket2::SockAddr>; BATCH_SIZE] =
202+
unsafe { MaybeUninit::uninit().assume_init() };
201203
for (i, transmit) in transmits.iter().enumerate().take(BATCH_SIZE) {
204+
let dest_addr = unsafe {
205+
std::ptr::write(
206+
addrs[i].as_mut_ptr(),
207+
socket2::SockAddr::from(transmit.destination),
208+
);
209+
&mut *(&mut addrs[i] as *mut _ as *mut _)
210+
};
202211
prepare_msg(
203212
transmit,
213+
dest_addr,
204214
&mut msgs[i].msg_hdr,
205215
&mut iovecs[i],
206216
&mut cmsgs[i],
@@ -233,7 +243,8 @@ fn send(io: &mio::net::UdpSocket, transmits: &[Transmit]) -> io::Result<usize> {
233243
let mut ctrl = cmsg::Aligned([0u8; CMSG_LEN]);
234244
let mut sent = 0;
235245
while sent < transmits.len() {
236-
prepare_msg(&transmits[sent], &mut hdr, &mut iov, &mut ctrl);
246+
let addr = socket2::SockAddr::from(transmits[sent].destination);
247+
prepare_msg(&transmits[sent], &addr, &mut hdr, &mut iov, &mut ctrl);
237248
let n = unsafe { libc::sendmsg(io.as_raw_fd(), &hdr, 0) };
238249
if n == -1 {
239250
let e = io::Error::last_os_error();
@@ -340,19 +351,22 @@ fn in_addr(addr: &Ipv4Addr) -> libc::in_addr {
340351

341352
fn prepare_msg(
342353
transmit: &Transmit,
354+
dest_addr: &socket2::SockAddr,
343355
hdr: &mut libc::msghdr,
344356
iov: &mut libc::iovec,
345357
ctrl: &mut cmsg::Aligned<[u8; CMSG_LEN]>,
346358
) {
347359
iov.iov_base = transmit.contents.as_ptr() as *const _ as *mut _;
348360
iov.iov_len = transmit.contents.len();
349361

350-
let (name, namelen) = match transmit.destination {
351-
SocketAddr::V4(ref addr) => (addr as *const _ as _, mem::size_of::<libc::sockaddr_in>()),
352-
SocketAddr::V6(ref addr) => (addr as *const _ as _, mem::size_of::<libc::sockaddr_in6>()),
353-
};
354-
hdr.msg_name = name;
355-
hdr.msg_namelen = namelen as _;
362+
// SAFETY: Casting the pointer to a mutable one is legal,
363+
// as sendmsg is guaranteed to not alter the mutable pointer.
364+
// The type is only mutable in the first place because it is reused
365+
// by recvmsg as well.
366+
let name = dest_addr.as_ptr() as *mut libc::c_void;
367+
let namelen = dest_addr.len();
368+
hdr.msg_name = name as *mut _;
369+
hdr.msg_namelen = namelen;
356370
hdr.msg_iov = iov;
357371
hdr.msg_iovlen = 1;
358372

0 commit comments

Comments
 (0)