cap_async_std/net/
udp_socket.rs

1use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
2#[cfg(unix)]
3use async_std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
4use async_std::{io, net};
5#[cfg(not(windows))]
6use io_lifetimes::{AsFd, BorrowedFd, OwnedFd};
7#[cfg(windows)]
8use io_lifetimes::{AsSocket, BorrowedSocket, OwnedSocket};
9use std::fmt;
10#[cfg(windows)]
11use {
12    async_std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket},
13    io_extras::os::windows::{
14        AsHandleOrSocket, AsRawHandleOrSocket, BorrowedHandleOrSocket, IntoRawHandleOrSocket,
15        OwnedHandleOrSocket, RawHandleOrSocket,
16    },
17};
18
19/// A UDP socket.
20///
21/// This corresponds to [`async_std::net::UdpSocket`].
22///
23/// This `UdpSocket` has no `bind`, `connect`, or `send_to` methods. To create
24/// a `UdpSocket` bound to an address or to send a message to an address, first
25/// obtain a [`Pool`] permitting the address, and then call
26/// [`Pool::bind_udp_socket`], or [`Pool::connect_udp_socket`], or
27/// [`Pool::send_to_udp_socket_addr`].
28///
29/// [`Pool`]: struct.Pool.html
30/// [`Pool::bind_udp_socket`]: struct.Pool.html#method.bind_udp_socket
31/// [`Pool::connect_udp_socket`]: struct.Pool.html#method.connect_udp_socket
32/// [`Pool::send_to_udp_socket_addr`]: struct.Pool.html#method.send_to_udp_socket_addr
33pub struct UdpSocket {
34    pub(crate) std: net::UdpSocket,
35}
36
37impl UdpSocket {
38    /// Constructs a new instance of `Self` from the given
39    /// `async_std::net::UdpSocket`.
40    ///
41    /// This grants access the resources the `async_std::net::UdpSocket`
42    /// instance already has access to.
43    #[inline]
44    pub fn from_std(std: net::UdpSocket) -> Self {
45        Self { std }
46    }
47
48    /// Receives a single datagram message on the socket.
49    ///
50    /// This corresponds to [`async_std::net::UdpSocket::recv_from`].
51    #[inline]
52    pub async fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
53        self.std.recv_from(buf).await
54    }
55
56    // async_std doesn't have `peek_from`.
57
58    /// Returns the socket address of the remote peer this socket was connected
59    /// to.
60    ///
61    /// This corresponds to [`async_std::net::UdpSocket::peer_addr`].
62    #[inline]
63    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
64        self.std.peer_addr()
65    }
66
67    /// Returns the socket address that this socket was created from.
68    ///
69    /// This corresponds to [`async_std::net::UdpSocket::local_addr`].
70    #[inline]
71    pub fn local_addr(&self) -> io::Result<SocketAddr> {
72        self.std.local_addr()
73    }
74
75    // async_std doesn't have `try_clone`.
76
77    // async_std doesn't have `set_read_timeout`.
78
79    // async_std doesn't have `set_write_timeout`.
80
81    // async_std doesn't have `read_timeout`.
82
83    // async_std doesn't have `write_timeout`.
84
85    /// Sets the value of the `SO_BROADCAST` option for this socket.
86    ///
87    /// This corresponds to [`async_std::net::UdpSocket::set_broadcast`].
88    #[inline]
89    pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
90        self.std.set_broadcast(broadcast)
91    }
92
93    /// Gets the value of the `SO_BROADCAST` option for this socket.
94    ///
95    /// This corresponds to [`async_std::net::UdpSocket::broadcast`].
96    #[inline]
97    pub fn broadcast(&self) -> io::Result<bool> {
98        self.std.broadcast()
99    }
100
101    /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
102    ///
103    /// This corresponds to
104    /// [`async_std::net::UdpSocket::set_multicast_loop_v4`].
105    #[inline]
106    pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
107        self.std.set_multicast_loop_v4(multicast_loop_v4)
108    }
109
110    /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
111    ///
112    /// This corresponds to [`async_std::net::UdpSocket::multicast_loop_v4`].
113    #[inline]
114    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
115        self.std.multicast_loop_v4()
116    }
117
118    /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
119    ///
120    /// This corresponds to
121    /// [`async_std::net::UdpSocket::set_multicast_ttl_v4`].
122    #[inline]
123    pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
124        self.std.set_multicast_ttl_v4(multicast_ttl_v4)
125    }
126
127    /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
128    ///
129    /// This corresponds to [`async_std::net::UdpSocket::multicast_ttl_v4`].
130    #[inline]
131    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
132        self.std.multicast_ttl_v4()
133    }
134
135    /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
136    ///
137    /// This corresponds to
138    /// [`async_std::net::UdpSocket::set_multicast_loop_v6`].
139    #[inline]
140    pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
141        self.std.set_multicast_loop_v6(multicast_loop_v6)
142    }
143
144    /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
145    ///
146    /// This corresponds to [`async_std::net::UdpSocket::multicast_loop_v6`].
147    #[inline]
148    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
149        self.std.multicast_loop_v6()
150    }
151
152    /// Sets the value for the `IP_TTL` option on this socket.
153    ///
154    /// This corresponds to [`async_std::net::UdpSocket::set_ttl`].
155    #[inline]
156    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
157        self.std.set_ttl(ttl)
158    }
159
160    /// Gets the value of the `IP_TTL` option for this socket.
161    ///
162    /// This corresponds to [`async_std::net::UdpSocket::ttl`].
163    #[inline]
164    pub fn ttl(&self) -> io::Result<u32> {
165        self.std.ttl()
166    }
167
168    /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
169    ///
170    /// This corresponds to [`async_std::net::UdpSocket::join_multicast_v4`].
171    #[allow(clippy::trivially_copy_pass_by_ref)]
172    #[inline]
173    pub fn join_multicast_v4(&self, multiaddr: Ipv4Addr, interface: Ipv4Addr) -> io::Result<()> {
174        self.std.join_multicast_v4(multiaddr, interface)
175    }
176
177    /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
178    ///
179    /// This corresponds to [`async_std::net::UdpSocket::join_multicast_v6`].
180    #[allow(clippy::trivially_copy_pass_by_ref)]
181    #[inline]
182    pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
183        self.std.join_multicast_v6(multiaddr, interface)
184    }
185
186    /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
187    ///
188    /// This corresponds to [`async_std::net::UdpSocket::leave_multicast_v4`].
189    #[allow(clippy::trivially_copy_pass_by_ref)]
190    #[inline]
191    pub fn leave_multicast_v4(&self, multiaddr: Ipv4Addr, interface: Ipv4Addr) -> io::Result<()> {
192        self.std.leave_multicast_v4(multiaddr, interface)
193    }
194
195    /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
196    ///
197    /// This corresponds to [`async_std::net::UdpSocket::leave_multicast_v6`].
198    #[allow(clippy::trivially_copy_pass_by_ref)]
199    #[inline]
200    pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
201        self.std.leave_multicast_v6(multiaddr, interface)
202    }
203
204    // async_std doesn't have `take_error`.
205
206    /// Sends data on the socket to the remote address to which it is
207    /// connected.
208    ///
209    /// This corresponds to [`async_std::net::UdpSocket::send`].
210    #[inline]
211    pub async fn send(&self, buf: &[u8]) -> io::Result<usize> {
212        self.std.send(buf).await
213    }
214
215    /// Receives a single datagram message on the socket from the remote
216    /// address to which it is connected.
217    ///
218    /// This corresponds to [`async_std::net::UdpSocket::recv`].
219    #[inline]
220    pub async fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
221        self.std.recv(buf).await
222    }
223
224    // async_std doesn't have `UdpSocket::peek`.
225
226    // async_std doesn't have `set_nonblocking`.
227}
228
229// Safety: `SocketlikeViewType` is implemented for `std`'s socket types.
230unsafe impl io_lifetimes::views::SocketlikeViewType for UdpSocket {}
231
232#[cfg(not(windows))]
233impl FromRawFd for UdpSocket {
234    #[inline]
235    unsafe fn from_raw_fd(fd: RawFd) -> Self {
236        Self::from_std(net::UdpSocket::from_raw_fd(fd))
237    }
238}
239
240#[cfg(not(windows))]
241impl From<OwnedFd> for UdpSocket {
242    #[inline]
243    fn from(fd: OwnedFd) -> Self {
244        Self::from_std(net::UdpSocket::from(fd))
245    }
246}
247
248#[cfg(windows)]
249impl FromRawSocket for UdpSocket {
250    #[inline]
251    unsafe fn from_raw_socket(socket: RawSocket) -> Self {
252        Self::from_std(net::UdpSocket::from_raw_socket(socket))
253    }
254}
255
256#[cfg(windows)]
257impl From<OwnedSocket> for UdpSocket {
258    #[inline]
259    fn from(socket: OwnedSocket) -> Self {
260        Self::from_std(net::UdpSocket::from(socket))
261    }
262}
263
264#[cfg(not(windows))]
265impl AsRawFd for UdpSocket {
266    #[inline]
267    fn as_raw_fd(&self) -> RawFd {
268        self.std.as_raw_fd()
269    }
270}
271
272#[cfg(not(windows))]
273impl AsFd for UdpSocket {
274    #[inline]
275    fn as_fd(&self) -> BorrowedFd<'_> {
276        self.std.as_fd()
277    }
278}
279
280#[cfg(windows)]
281impl AsRawSocket for UdpSocket {
282    #[inline]
283    fn as_raw_socket(&self) -> RawSocket {
284        self.std.as_raw_socket()
285    }
286}
287
288#[cfg(windows)]
289impl AsSocket for UdpSocket {
290    #[inline]
291    fn as_socket(&self) -> BorrowedSocket<'_> {
292        self.std.as_socket()
293    }
294}
295
296#[cfg(windows)]
297impl AsRawHandleOrSocket for UdpSocket {
298    #[inline]
299    fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
300        self.std.as_raw_handle_or_socket()
301    }
302}
303
304#[cfg(windows)]
305impl AsHandleOrSocket for UdpSocket {
306    #[inline]
307    fn as_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
308        self.std.as_handle_or_socket()
309    }
310}
311
312#[cfg(not(windows))]
313impl IntoRawFd for UdpSocket {
314    #[inline]
315    fn into_raw_fd(self) -> RawFd {
316        self.std.into_raw_fd()
317    }
318}
319
320#[cfg(not(windows))]
321impl From<UdpSocket> for OwnedFd {
322    #[inline]
323    fn from(socket: UdpSocket) -> OwnedFd {
324        socket.std.into()
325    }
326}
327
328#[cfg(windows)]
329impl IntoRawSocket for UdpSocket {
330    #[inline]
331    fn into_raw_socket(self) -> RawSocket {
332        self.std.into_raw_socket()
333    }
334}
335
336#[cfg(windows)]
337impl From<UdpSocket> for OwnedSocket {
338    #[inline]
339    fn from(socket: UdpSocket) -> OwnedSocket {
340        socket.std.into()
341    }
342}
343
344#[cfg(windows)]
345impl IntoRawHandleOrSocket for UdpSocket {
346    #[inline]
347    fn into_raw_handle_or_socket(self) -> RawHandleOrSocket {
348        self.std.into_raw_handle_or_socket()
349    }
350}
351
352#[cfg(windows)]
353impl From<UdpSocket> for OwnedHandleOrSocket {
354    #[inline]
355    fn from(socket: UdpSocket) -> Self {
356        socket.std.into()
357    }
358}
359
360impl fmt::Debug for UdpSocket {
361    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
362        self.std.fmt(f)
363    }
364}