aboutsummaryrefslogtreecommitdiff
path: root/src/net/udp.rs
diff options
context:
space:
mode:
authorChris Wailes <chriswailes@google.com>2022-12-12 11:43:41 -0800
committerJeff Vander Stoep <jeffv@google.com>2023-01-18 19:48:52 +0100
commitff62579fde0625f6c8923b58c9dc848c97c680e6 (patch)
treec049adb6c0fca041cbb303c8311c1084e4a832cd /src/net/udp.rs
parentb669ae94fdcda726d88936d028d35187bf41b016 (diff)
downloadtokio-ff62579fde0625f6c8923b58c9dc848c97c680e6.tar.gz
Upgrade tokio to 1.23.0
This project was upgraded with external_updater. Usage: tools/external_updater/updater.sh update rust/crates/tokio For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md Test: TreeHugger Change-Id: Id69553d5e858bddcde0de5b9e72d6bb3c08bafb5
Diffstat (limited to 'src/net/udp.rs')
-rw-r--r--src/net/udp.rs136
1 files changed, 130 insertions, 6 deletions
diff --git a/src/net/udp.rs b/src/net/udp.rs
index 504d74e..af343f2 100644
--- a/src/net/udp.rs
+++ b/src/net/udp.rs
@@ -128,6 +128,10 @@ impl UdpSocket {
/// This function will create a new UDP socket and attempt to bind it to
/// the `addr` provided.
///
+ /// Binding with a port number of 0 will request that the OS assigns a port
+ /// to this listener. The port allocated can be queried via the `local_addr`
+ /// method.
+ ///
/// # Example
///
/// ```no_run
@@ -166,6 +170,7 @@ impl UdpSocket {
UdpSocket::new(sys)
}
+ #[track_caller]
fn new(socket: mio::net::UdpSocket) -> io::Result<UdpSocket> {
let io = PollEvented::new(socket)?;
Ok(UdpSocket { io })
@@ -206,6 +211,7 @@ impl UdpSocket {
/// # Ok(())
/// # }
/// ```
+ #[track_caller]
pub fn from_std(socket: net::UdpSocket) -> io::Result<UdpSocket> {
let io = mio::net::UdpSocket::from_std(socket);
UdpSocket::new(io)
@@ -253,6 +259,10 @@ impl UdpSocket {
}
}
+ fn as_socket(&self) -> socket2::SockRef<'_> {
+ socket2::SockRef::from(self)
+ }
+
/// Returns the local address that this socket is bound to.
///
/// # Example
@@ -274,6 +284,28 @@ impl UdpSocket {
self.io.local_addr()
}
+ /// Returns the socket address of the remote peer this socket was connected to.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use tokio::net::UdpSocket;
+ ///
+ /// # use std::{io, net::SocketAddr};
+ /// # #[tokio::main]
+ /// # async fn main() -> io::Result<()> {
+ /// let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
+ /// let peer = "127.0.0.1:11100".parse::<SocketAddr>().unwrap();
+ /// let sock = UdpSocket::bind(addr).await?;
+ /// sock.connect(peer).await?;
+ /// assert_eq!(peer, sock.peer_addr()?);
+ /// # Ok(())
+ /// # }
+ /// ```
+ pub fn peer_addr(&self) -> io::Result<SocketAddr> {
+ self.io.peer_addr()
+ }
+
/// Connects the UDP socket setting the default destination for send() and
/// limiting packets that are read via recv from the address specified in
/// `addr`.
@@ -325,7 +357,9 @@ impl UdpSocket {
///
/// The function may complete without the socket being ready. This is a
/// false-positive and attempting an operation will return with
- /// `io::ErrorKind::WouldBlock`.
+ /// `io::ErrorKind::WouldBlock`. The function can also return with an empty
+ /// [`Ready`] set, so you should always check the returned value and possibly
+ /// wait again if the requested states are not set.
///
/// # Cancel safety
///
@@ -708,7 +742,7 @@ impl UdpSocket {
///
/// # Cancel safety
///
- /// This method is cancel safe. If `recv_from` is used as the event in a
+ /// This method is cancel safe. If `recv` is used as the event in a
/// [`tokio::select!`](crate::select) statement and some other branch
/// completes first, it is guaranteed that no messages were received on this
/// socket.
@@ -893,7 +927,7 @@ impl UdpSocket {
// Safety: We trust `UdpSocket::recv` to have filled up `n` bytes in the
// buffer.
- let n = (&*self.io).recv(dst)?;
+ let n = (*self.io).recv(dst)?;
unsafe {
buf.advance_mut(n);
@@ -957,7 +991,7 @@ impl UdpSocket {
// Safety: We trust `UdpSocket::recv_from` to have filled up `n` bytes in the
// buffer.
- let (n, addr) = (&*self.io).recv_from(dst)?;
+ let (n, addr) = (*self.io).recv_from(dst)?;
unsafe {
buf.advance_mut(n);
@@ -1239,7 +1273,7 @@ impl UdpSocket {
/// Tries to read or write from the socket using a user-provided IO operation.
///
/// If the socket is ready, the provided closure is called. The closure
- /// should attempt to perform IO operation from the socket by manually
+ /// should attempt to perform IO operation on the socket by manually
/// calling the appropriate syscall. If the operation fails because the
/// socket is not actually ready, then the closure should return a
/// `WouldBlock` error and the readiness flag is cleared. The return value
@@ -1258,6 +1292,11 @@ impl UdpSocket {
/// defined on the Tokio `UdpSocket` type, as this will mess with the
/// readiness flag and can cause the socket to behave incorrectly.
///
+ /// This method is not intended to be used with combined interests.
+ /// The closure should perform only one type of IO operation, so it should not
+ /// require more than one ready state. This method may panic or sleep forever
+ /// if it is called with a combined interest.
+ ///
/// Usually, [`readable()`], [`writable()`] or [`ready()`] is used with this function.
///
/// [`readable()`]: UdpSocket::readable()
@@ -1268,7 +1307,9 @@ impl UdpSocket {
interest: Interest,
f: impl FnOnce() -> io::Result<R>,
) -> io::Result<R> {
- self.io.registration().try_io(interest, f)
+ self.io
+ .registration()
+ .try_io(interest, || self.io.try_io(f))
}
/// Receives data from the socket, without removing it from the input queue.
@@ -1480,6 +1521,89 @@ impl UdpSocket {
self.io.set_ttl(ttl)
}
+ /// Gets the value of the `IP_TOS` option for this socket.
+ ///
+ /// For more information about this option, see [`set_tos`].
+ ///
+ /// **NOTE:** On Windows, `IP_TOS` is only supported on [Windows 8+ or
+ /// Windows Server 2012+.](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options)
+ ///
+ /// [`set_tos`]: Self::set_tos
+ // https://docs.rs/socket2/0.4.2/src/socket2/socket.rs.html#1178
+ #[cfg(not(any(
+ target_os = "fuchsia",
+ target_os = "redox",
+ target_os = "solaris",
+ target_os = "illumos",
+ )))]
+ #[cfg_attr(
+ docsrs,
+ doc(cfg(not(any(
+ target_os = "fuchsia",
+ target_os = "redox",
+ target_os = "solaris",
+ target_os = "illumos",
+ ))))
+ )]
+ pub fn tos(&self) -> io::Result<u32> {
+ self.as_socket().tos()
+ }
+
+ /// Sets the value for the `IP_TOS` option on this socket.
+ ///
+ /// This value sets the type-of-service field that is used in every packet
+ /// sent from this socket.
+ ///
+ /// **NOTE:** On Windows, `IP_TOS` is only supported on [Windows 8+ or
+ /// Windows Server 2012+.](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options)
+ // https://docs.rs/socket2/0.4.2/src/socket2/socket.rs.html#1178
+ #[cfg(not(any(
+ target_os = "fuchsia",
+ target_os = "redox",
+ target_os = "solaris",
+ target_os = "illumos",
+ )))]
+ #[cfg_attr(
+ docsrs,
+ doc(cfg(not(any(
+ target_os = "fuchsia",
+ target_os = "redox",
+ target_os = "solaris",
+ target_os = "illumos",
+ ))))
+ )]
+ pub fn set_tos(&self, tos: u32) -> io::Result<()> {
+ self.as_socket().set_tos(tos)
+ }
+
+ /// Gets the value for the `SO_BINDTODEVICE` option on this socket
+ ///
+ /// This value gets the socket-bound device's interface name.
+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",))]
+ #[cfg_attr(
+ docsrs,
+ doc(cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",)))
+ )]
+ pub fn device(&self) -> io::Result<Option<Vec<u8>>> {
+ self.as_socket().device()
+ }
+
+ /// Sets the value for the `SO_BINDTODEVICE` option on this socket
+ ///
+ /// If a socket is bound to an interface, only packets received from that
+ /// particular interface are processed by the socket. Note that this only
+ /// works for some socket types, particularly `AF_INET` sockets.
+ ///
+ /// If `interface` is `None` or an empty string it removes the binding.
+ #[cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux")))]
+ #[cfg_attr(
+ docsrs,
+ doc(cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))))
+ )]
+ pub fn bind_device(&self, interface: Option<&[u8]>) -> io::Result<()> {
+ self.as_socket().bind_device(interface)
+ }
+
/// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
///
/// This function specifies a new multicast group for this socket to join.