Skip to content

Commit 1468514

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

File tree

1 file changed

+48
-5
lines changed

1 file changed

+48
-5
lines changed

quinn/src/platform/unix.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,12 @@ 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: [CSocketAddr; BATCH_SIZE] = unsafe { mem::zeroed() };
201202
for (i, transmit) in transmits.iter().enumerate().take(BATCH_SIZE) {
203+
addrs[i] = CSocketAddr::from_socket_addr(transmit.destination);
202204
prepare_msg(
203205
transmit,
206+
&mut addrs[i],
204207
&mut msgs[i].msg_hdr,
205208
&mut iovecs[i],
206209
&mut cmsgs[i],
@@ -233,7 +236,8 @@ fn send(io: &mio::net::UdpSocket, transmits: &[Transmit]) -> io::Result<usize> {
233236
let mut ctrl = cmsg::Aligned([0u8; CMSG_LEN]);
234237
let mut sent = 0;
235238
while sent < transmits.len() {
236-
prepare_msg(&transmits[sent], &mut hdr, &mut iov, &mut ctrl);
239+
let mut addr = CSocketAddr::from_socket_addr(transmits[sent].destination);
240+
prepare_msg(&transmits[sent], &mut addr, &mut hdr, &mut iov, &mut ctrl);
237241
let n = unsafe { libc::sendmsg(io.as_raw_fd(), &hdr, 0) };
238242
if n == -1 {
239243
let e = io::Error::last_os_error();
@@ -338,19 +342,58 @@ fn in_addr(addr: &Ipv4Addr) -> libc::in_addr {
338342
}
339343
}
340344

345+
enum CSocketAddr {
346+
V4(libc::sockaddr_in),
347+
V6(libc::sockaddr_in6),
348+
}
349+
350+
impl CSocketAddr {
351+
fn from_socket_addr(addr: SocketAddr) -> Self {
352+
match addr {
353+
SocketAddr::V4(s) => CSocketAddr::V4(libc::sockaddr_in {
354+
sin_family: libc::AF_INET as _,
355+
sin_port: s.port().to_be(),
356+
sin_addr: in_addr(s.ip()),
357+
sin_zero: [0; 8],
358+
#[cfg(any(target_os = "freebsd", target_os = "ios", target_os = "macos"))]
359+
sin_len: 0,
360+
}),
361+
SocketAddr::V6(s) => CSocketAddr::V6(libc::sockaddr_in6 {
362+
sin6_family: libc::AF_INET6 as _,
363+
sin6_port: s.port().to_be(),
364+
sin6_flowinfo: s.flowinfo(),
365+
sin6_addr: libc::in6_addr {
366+
s6_addr: s.ip().octets(),
367+
},
368+
sin6_scope_id: s.scope_id(),
369+
}),
370+
}
371+
}
372+
fn ptr_and_len(&mut self) -> (*mut libc::c_void, usize) {
373+
match self {
374+
CSocketAddr::V4(ref mut addr) => (
375+
addr as *mut _ as *mut _,
376+
mem::size_of::<libc::sockaddr_in>(),
377+
),
378+
CSocketAddr::V6(ref mut addr) => (
379+
addr as *mut _ as *mut _,
380+
mem::size_of::<libc::sockaddr_in6>(),
381+
),
382+
}
383+
}
384+
}
385+
341386
fn prepare_msg(
342387
transmit: &Transmit,
388+
dest_addr: &mut CSocketAddr,
343389
hdr: &mut libc::msghdr,
344390
iov: &mut libc::iovec,
345391
ctrl: &mut cmsg::Aligned<[u8; CMSG_LEN]>,
346392
) {
347393
iov.iov_base = transmit.contents.as_ptr() as *const _ as *mut _;
348394
iov.iov_len = transmit.contents.len();
349395

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-
};
396+
let (name, namelen) = dest_addr.ptr_and_len();
354397
hdr.msg_name = name;
355398
hdr.msg_namelen = namelen as _;
356399
hdr.msg_iov = iov;

0 commit comments

Comments
 (0)