Skip to content

Commit

Permalink
rust-lang#68617: prototype UdpSocket::send_to_vectored()
Browse files Browse the repository at this point in the history
  • Loading branch information
frehberg committed Feb 16, 2023
1 parent 639377e commit 022b854
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 1 deletion.
1 change: 1 addition & 0 deletions library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ backtrace = [
'miniz_oxide/rustc-dep-of-std',
]
gimli-symbolize = []
udp_sendmsg = []

panic-unwind = ["panic_unwind"]
profiler = ["profiler_builtins"]
Expand Down
20 changes: 19 additions & 1 deletion library/std/src/net/udp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
mod tests;

use crate::fmt;
use crate::io::{self, ErrorKind};
use crate::io::{self, ErrorKind, IoSliceMut};
use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
use crate::sys_common::net as net_imp;
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::time::Duration;


/// A UDP socket.
///
/// After creating a `UdpSocket` by [`bind`]ing it to a socket address, data can be
Expand Down Expand Up @@ -181,6 +182,20 @@ impl UdpSocket {
}
}

/// Sends data on the socket to the given address. On success, returns the
/// number of bytes written.
///
///
#[stable(feature = "udp_sendmsg", since = "1.70.0")]
pub fn send_to_vectored<A: ToSocketAddrs>(&self, bufs: &mut [IoSliceMut<'_>], addr: A) -> io::Result<usize> {
match addr.to_socket_addrs()?.next() {
Some(addr) => self.0.send_to_vectored(bufs, &addr),
None => {
Err(io::const_io_error!(ErrorKind::InvalidInput, "no addresses to send data to"))
}
}
}

/// Returns the socket address of the remote peer this socket was connected to.
///
/// # Examples
Expand Down Expand Up @@ -667,6 +682,9 @@ impl UdpSocket {
self.0.send(buf)
}

///
///

/// Receives a single datagram message on the socket from the remote address to
/// which it is connected. On success, returns the number of bytes read.
///
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/sys/unix/l4re.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,10 @@ pub mod net {
unimpl!();
}

// pub fn send_to_vectored(&self, _: &mut [IoSliceMut<'_>], _: &SocketAddr) -> io::Result<usize> {
// unimpl!();
// }

pub fn duplicate(&self) -> io::Result<UdpSocket> {
unimpl!();
}
Expand Down
20 changes: 20 additions & 0 deletions library/std/src/sys_common/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ use crate::sys::net::{cvt, cvt_gai, cvt_r, init, wrlen_t, Socket};
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::time::Duration;

use libc;

type IovLen = usize;

use crate::ffi::{c_int, c_void};

cfg_if::cfg_if! {
Expand Down Expand Up @@ -553,6 +557,22 @@ impl UdpSocket {
Ok(ret as usize)
}

pub fn send_to_vectored(&self, bufs: &mut [IoSliceMut<'_>], dst: &SocketAddr) -> io::Result<usize> {
let (dst, dstlen) = dst.into_inner();
let mut msg: libc::msghdr = unsafe { mem::zeroed() };
// Safety: we're creating a `*mut` pointer from a reference, which is UB
// once actually used. However the OS should not write to it in the
// `sendmsg` system call.
msg.msg_name = dst.as_ptr() as *mut _;
msg.msg_namelen = dstlen;
// Safety: Same as above about `*const` -> `*mut`.
msg.msg_iov = bufs.as_ptr() as *mut _;
msg.msg_iovlen = cmp::min(bufs.len(), IovLen::MAX as usize) as IovLen;
// TODO(fr) set flags
let ret = self.inner.send_msg(&mut msg)?;
Ok(ret as usize)
}

pub fn duplicate(&self) -> io::Result<UdpSocket> {
self.inner.duplicate().map(|s| UdpSocket { inner: s })
}
Expand Down

0 comments on commit 022b854

Please sign in to comment.