Skip to content

Commit

Permalink
Don't assume representation of SocketAddr
Browse files Browse the repository at this point in the history
  • Loading branch information
est31 committed Jan 26, 2021
1 parent badc801 commit bb0f3b1
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 7 deletions.
1 change: 1 addition & 0 deletions quinn/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ codecov = { repository = "djc/quinn" }
maintenance = { status = "experimental" }

[dependencies]
socket2 = "0.3"
bytes = "1"
futures = "0.3.8"
libc = "0.2.69"
Expand Down
27 changes: 20 additions & 7 deletions quinn/src/platform/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,18 @@ fn send(io: &mio::net::UdpSocket, transmits: &[Transmit]) -> io::Result<usize> {
let mut msgs: [libc::mmsghdr; BATCH_SIZE] = unsafe { mem::zeroed() };
let mut iovecs: [libc::iovec; BATCH_SIZE] = unsafe { mem::zeroed() };
let mut cmsgs = [cmsg::Aligned([0u8; CMSG_LEN]); BATCH_SIZE];
let mut addrs: [MaybeUninit<socket2::SockAddr>; BATCH_SIZE] = unsafe {
MaybeUninit::uninit().assume_init()
};
for (i, transmit) in transmits.iter().enumerate().take(BATCH_SIZE) {
let dest_addr = unsafe {
std::ptr::write(addrs[i].as_mut_ptr(),
socket2::SockAddr::from(transmit.destination));
&mut *(&mut addrs[i] as * mut _ as * mut _)
};
prepare_msg(
transmit,
dest_addr,
&mut msgs[i].msg_hdr,
&mut iovecs[i],
&mut cmsgs[i],
Expand Down Expand Up @@ -233,7 +242,8 @@ fn send(io: &mio::net::UdpSocket, transmits: &[Transmit]) -> io::Result<usize> {
let mut ctrl = cmsg::Aligned([0u8; CMSG_LEN]);
let mut sent = 0;
while sent < transmits.len() {
prepare_msg(&transmits[sent], &mut hdr, &mut iov, &mut ctrl);
let addr = socket2::SockAddr::from(transmits[sent].destination);
prepare_msg(&transmits[sent], &addr, &mut hdr, &mut iov, &mut ctrl);
let n = unsafe { libc::sendmsg(io.as_raw_fd(), &hdr, 0) };
if n == -1 {
let e = io::Error::last_os_error();
Expand Down Expand Up @@ -340,19 +350,22 @@ fn in_addr(addr: &Ipv4Addr) -> libc::in_addr {

fn prepare_msg(
transmit: &Transmit,
dest_addr: &socket2::SockAddr,
hdr: &mut libc::msghdr,
iov: &mut libc::iovec,
ctrl: &mut cmsg::Aligned<[u8; CMSG_LEN]>,
) {
iov.iov_base = transmit.contents.as_ptr() as *const _ as *mut _;
iov.iov_len = transmit.contents.len();

let (name, namelen) = match transmit.destination {
SocketAddr::V4(ref addr) => (addr as *const _ as _, mem::size_of::<libc::sockaddr_in>()),
SocketAddr::V6(ref addr) => (addr as *const _ as _, mem::size_of::<libc::sockaddr_in6>()),
};
hdr.msg_name = name;
hdr.msg_namelen = namelen as _;
// SAFETY: Casting the pointer to a mutable one is legal,
// as sendmsg is guaranteed to not alter the mutable pointer.
// The type is only mutable in the first place because it is reused
// by recvmsg as well.
let name = dest_addr.as_ptr() as * mut libc::c_void;
let namelen = dest_addr.len();
hdr.msg_name = name as *mut _;
hdr.msg_namelen = namelen;
hdr.msg_iov = iov;
hdr.msg_iovlen = 1;

Expand Down

0 comments on commit bb0f3b1

Please sign in to comment.