futures_net/udp/
mod.rs

1//! A UDP socket.
2//!
3//! This module contains the UDP networking types, similar to those found in
4//! `std::net`, but suitable for async programming via futures and
5//! `async`/`await`.
6//!
7//! After creating a `UdpSocket` by [`bind`]ing it to a socket address, data can be
8//! [sent to] and [received from] any other socket address.
9//!
10//! [`bind`]: #method.bind
11//! [received from]: #method.poll_recv_from
12//! [sent to]: #method.poll_send_to
13
14use async_datagram::AsyncDatagram;
15use async_ready::{AsyncReadReady, AsyncWriteReady};
16use futures_core::Future;
17use futures_util::ready;
18use std::fmt;
19use std::io;
20use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
21use std::pin::Pin;
22use std::task::{Context, Poll};
23
24use crate::driver::sys;
25use crate::driver::PollEvented;
26
27/// A UDP socket.
28pub struct UdpSocket {
29    io: PollEvented<sys::net::UdpSocket>,
30}
31
32impl UdpSocket {
33    /// Creates a UDP socket from the given address.
34    ///
35    /// Binding with a port number of 0 will request that the OS assigns a port
36    /// to this socket. The port allocated can be queried via the
37    /// [`local_addr`] method.
38    ///
39    /// [`local_addr`]: #method.local_addr
40    ///
41    /// # Examples
42    ///
43    /// ```rust,no_run
44    /// use futures_net::udp::UdpSocket;
45    ///
46    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
47    /// let socket_addr = "127.0.0.1:0".parse()?;
48    /// let socket = UdpSocket::bind(&socket_addr)?;
49    /// # Ok(())
50    /// # }
51    /// ```
52    pub fn bind(addr: &SocketAddr) -> io::Result<UdpSocket> {
53        sys::net::UdpSocket::bind(addr).map(UdpSocket::new)
54    }
55
56    fn new(socket: sys::net::UdpSocket) -> UdpSocket {
57        let io = PollEvented::new(socket);
58        UdpSocket { io: io }
59    }
60
61    /// Returns the local address that this listener is bound to.
62    ///
63    /// This can be useful, for example, when binding to port 0 to figure out
64    /// which port was actually bound.
65    ///
66    /// # Examples
67    ///
68    /// ```rust
69    ///	use futures_net::udp::UdpSocket;
70    ///
71    ///	# fn main() -> Result<(), Box<dyn std::error::Error>> {
72    /// # let socket_addr = "127.0.0.1:0".parse()?;
73    /// # let socket = UdpSocket::bind(&socket_addr)?;
74    /// println!("Socket addr: {:?}", socket.local_addr());
75    /// # Ok(())
76    /// # }
77    /// ```
78    pub fn local_addr(&self) -> io::Result<SocketAddr> {
79        self.io.get_ref().local_addr()
80    }
81
82    /// Sends data on the socket to the given address. On success, returns the
83    /// number of bytes written.
84    ///
85    /// # Examples
86    ///
87    /// ```rust,no_run
88    /// # use std::error::Error;
89    /// use futures_net::udp::UdpSocket;
90    ///
91    /// const THE_MERCHANT_OF_VENICE: &[u8] = b"
92    ///     If you prick us, do we not bleed?
93    ///     If you tickle us, do we not laugh?
94    ///     If you poison us, do we not die?
95    ///     And if you wrong us, shall we not revenge?
96    /// ";
97    ///
98    /// # async fn send_data() -> Result<(), Box<dyn Error + 'static>> {
99    /// let addr = "127.0.0.1:0".parse()?;
100    /// let target = "127.0.0.1:7878".parse()?;
101    /// let mut socket = UdpSocket::bind(&addr)?;
102    ///
103    /// socket.send_to(THE_MERCHANT_OF_VENICE, &target).await?;
104    /// # Ok(())
105    /// # }
106    /// ```
107    pub fn send_to<'a, 'b>(
108        &'a mut self,
109        buf: &'b [u8],
110        target: &'b SocketAddr,
111    ) -> SendTo<'a, 'b> {
112        SendTo {
113            buf,
114            target,
115            socket: self,
116        }
117    }
118
119    /// Receives data from the socket. On success, returns the number of bytes
120    /// read and the address from whence the data came.
121    ///
122    /// # Exampes
123    ///
124    /// ```rust,no_run
125    /// # use std::error::Error;
126    /// use futures_net::udp::UdpSocket;
127    ///
128    /// # async fn recv_data() -> Result<Vec<u8>, Box<dyn Error + 'static>> {
129    /// let addr = "127.0.0.1:0".parse()?;
130    /// let mut socket = UdpSocket::bind(&addr)?;
131    /// let mut buf = vec![0; 1024];
132    ///
133    /// socket.recv_from(&mut buf).await?;
134    /// # Ok(buf)
135    /// # }
136    /// ```
137    pub fn recv_from<'a, 'b>(&'a mut self, buf: &'b mut [u8]) -> RecvFrom<'a, 'b> {
138        RecvFrom { buf, socket: self }
139    }
140
141    /// Gets the value of the `SO_BROADCAST` option for this socket.
142    ///
143    /// For more information about this option, see [`set_broadcast`].
144    ///
145    /// [`set_broadcast`]: #method.set_broadcast
146    pub fn broadcast(&self) -> io::Result<bool> {
147        self.io.get_ref().broadcast()
148    }
149
150    /// Sets the value of the `SO_BROADCAST` option for this socket.
151    ///
152    /// When enabled, this socket is allowed to send packets to a broadcast
153    /// address.
154    pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
155        self.io.get_ref().set_broadcast(on)
156    }
157
158    /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
159    ///
160    /// For more information about this option, see [`set_multicast_loop_v4`].
161    ///
162    /// [`set_multicast_loop_v4`]: #method.set_multicast_loop_v4
163    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
164        self.io.get_ref().multicast_loop_v4()
165    }
166
167    /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
168    ///
169    /// If enabled, multicast packets will be looped back to the local socket.
170    ///
171    /// # Note
172    ///
173    /// This may not have any affect on IPv6 sockets.
174    pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> {
175        self.io.get_ref().set_multicast_loop_v4(on)
176    }
177
178    /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
179    ///
180    /// For more information about this option, see [`set_multicast_ttl_v4`].
181    ///
182    /// [`set_multicast_ttl_v4`]: #method.set_multicast_ttl_v4
183    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
184        self.io.get_ref().multicast_ttl_v4()
185    }
186
187    /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
188    ///
189    /// Indicates the time-to-live value of outgoing multicast packets for
190    /// this socket. The default value is 1 which means that multicast packets
191    /// don't leave the local network unless explicitly requested.
192    ///
193    /// # Note
194    ///
195    /// This may not have any affect on IPv6 sockets.
196    pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
197        self.io.get_ref().set_multicast_ttl_v4(ttl)
198    }
199
200    /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
201    ///
202    /// For more information about this option, see [`set_multicast_loop_v6`].
203    ///
204    /// [`set_multicast_loop_v6`]: #method.set_multicast_loop_v6
205    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
206        self.io.get_ref().multicast_loop_v6()
207    }
208
209    /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
210    ///
211    /// Controls whether this socket sees the multicast packets it sends itself.
212    ///
213    /// # Note
214    ///
215    /// This may not have any affect on IPv4 sockets.
216    pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> {
217        self.io.get_ref().set_multicast_loop_v6(on)
218    }
219
220    /// Gets the value of the `IP_TTL` option for this socket.
221    ///
222    /// For more information about this option, see [`set_ttl`].
223    ///
224    /// [`set_ttl`]: #method.set_ttl
225    pub fn ttl(&self) -> io::Result<u32> {
226        self.io.get_ref().ttl()
227    }
228
229    /// Sets the value for the `IP_TTL` option on this socket.
230    ///
231    /// This value sets the time-to-live field that is used in every packet sent
232    /// from this socket.
233    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
234        self.io.get_ref().set_ttl(ttl)
235    }
236
237    /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
238    ///
239    /// This function specifies a new multicast group for this socket to join.
240    /// The address must be a valid multicast address, and `interface` is the
241    /// address of the local interface with which the system should join the
242    /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
243    /// interface is chosen by the system.
244    ///
245    /// # Examples
246    ///
247    /// ```rust,no_run
248    /// use futures_net::udp::UdpSocket;
249    /// use std::net::Ipv4Addr;
250    ///
251    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
252    /// let socket_addr = "127.0.0.1:0".parse()?;
253    /// let interface = Ipv4Addr::new(0, 0, 0, 0);
254    /// let mdns_addr = Ipv4Addr::new(224, 0, 0, 123);
255    ///
256    /// let socket = UdpSocket::bind(&socket_addr)?;
257    /// socket.join_multicast_v4(&mdns_addr, &interface)?;
258    /// # Ok(()) }
259    /// ```
260    pub fn join_multicast_v4(
261        &self,
262        multiaddr: &Ipv4Addr,
263        interface: &Ipv4Addr,
264    ) -> io::Result<()> {
265        self.io.get_ref().join_multicast_v4(multiaddr, interface)
266    }
267
268    /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
269    ///
270    /// This function specifies a new multicast group for this socket to join.
271    /// The address must be a valid multicast address, and `interface` is the
272    /// index of the interface to join/leave (or 0 to indicate any interface).
273    ///
274    /// # Examples
275    ///
276    /// ```rust,no_run
277    /// use futures_net::udp::UdpSocket;
278    /// use std::net::{Ipv6Addr, SocketAddr};
279    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
280    /// let socket_addr = SocketAddr::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).into(), 0);
281    /// let mdns_addr = Ipv6Addr::new(0xFF02, 0, 0, 0, 0, 0, 0, 0x0123) ;
282    /// let socket = UdpSocket::bind(&socket_addr)?;
283    ///
284    /// socket.join_multicast_v6(&mdns_addr, 0)?;
285    /// # Ok(()) }
286    /// ```
287    pub fn join_multicast_v6(
288        &self,
289        multiaddr: &Ipv6Addr,
290        interface: u32,
291    ) -> io::Result<()> {
292        self.io.get_ref().join_multicast_v6(multiaddr, interface)
293    }
294
295    /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
296    ///
297    /// For more information about this option, see [`join_multicast_v4`].
298    ///
299    /// [`join_multicast_v4`]: #method.join_multicast_v4
300    pub fn leave_multicast_v4(
301        &self,
302        multiaddr: &Ipv4Addr,
303        interface: &Ipv4Addr,
304    ) -> io::Result<()> {
305        self.io.get_ref().leave_multicast_v4(multiaddr, interface)
306    }
307
308    /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
309    ///
310    /// For more information about this option, see [`join_multicast_v6`].
311    ///
312    /// [`join_multicast_v6`]: #method.join_multicast_v6
313    pub fn leave_multicast_v6(
314        &self,
315        multiaddr: &Ipv6Addr,
316        interface: u32,
317    ) -> io::Result<()> {
318        self.io.get_ref().leave_multicast_v6(multiaddr, interface)
319    }
320}
321
322impl AsyncDatagram for UdpSocket {
323    type Sender = SocketAddr;
324    type Receiver = SocketAddr;
325    type Err = io::Error;
326
327    fn poll_send_to(
328        mut self: Pin<&mut Self>,
329        cx: &mut Context<'_>,
330        buf: &[u8],
331        receiver: &Self::Receiver,
332    ) -> Poll<io::Result<usize>> {
333        ready!(self.io.poll_write_ready(cx)?);
334
335        match self.io.get_ref().send_to(buf, receiver) {
336            Ok(n) => Poll::Ready(Ok(n)),
337            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
338                Pin::new(&mut self.io).clear_write_ready(cx)?;
339                Poll::Pending
340            }
341            Err(e) => Poll::Ready(Err(e)),
342        }
343    }
344
345    fn poll_recv_from(
346        mut self: Pin<&mut Self>,
347        cx: &mut Context<'_>,
348        buf: &mut [u8],
349    ) -> Poll<io::Result<(usize, Self::Sender)>> {
350        ready!(Pin::new(&mut self.io).poll_read_ready(cx)?);
351
352        match self.io.get_ref().recv_from(buf) {
353            Ok(n) => Poll::Ready(Ok(n)),
354            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
355                Pin::new(&mut self.io).clear_read_ready(cx)?;
356                Poll::Pending
357            }
358            Err(e) => Poll::Ready(Err(e)),
359        }
360    }
361}
362
363impl AsyncReadReady for UdpSocket
364where
365    Self: Unpin,
366{
367    type Ok = sys::event::Ready;
368    type Err = io::Error;
369
370    /// Check the UDP socket's read readiness state.
371    ///
372    /// If the socket is not ready for receiving then `Poll::Pending` is
373    /// returned and the current task is notified once a new event is received.
374    ///
375    /// The socket will remain in a read-ready state until calls to `poll_recv`
376    /// return `Pending`.
377    fn poll_read_ready(
378        mut self: Pin<&mut Self>,
379        cx: &mut Context<'_>,
380    ) -> Poll<Result<Self::Ok, Self::Err>> {
381        Pin::new(&mut self.io).poll_read_ready(cx)
382    }
383}
384
385impl AsyncWriteReady for UdpSocket {
386    type Ok = sys::event::Ready;
387    type Err = io::Error;
388
389    /// Check the UDP socket's write readiness state.
390    ///
391    /// If the socket is not ready for sending then `Poll::Pending` is
392    /// returned and the current task is notified once a new event is received.
393    ///
394    /// The I/O resource will remain in a write-ready state until calls to
395    /// `poll_send` return `Pending`.
396    fn poll_write_ready(
397        self: Pin<&mut Self>,
398        cx: &mut Context<'_>,
399    ) -> Poll<Result<Self::Ok, Self::Err>> {
400        self.io.poll_write_ready(cx)
401    }
402}
403
404impl fmt::Debug for UdpSocket {
405    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
406        self.io.get_ref().fmt(f)
407    }
408}
409
410/// The future returned by `UdpSocket::send_to`
411#[derive(Debug)]
412pub struct SendTo<'a, 'b> {
413    socket: &'a mut UdpSocket,
414    buf: &'b [u8],
415    target: &'b SocketAddr,
416}
417
418impl<'a, 'b> Future for SendTo<'a, 'b> {
419    type Output = io::Result<usize>;
420
421    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
422        let SendTo {
423            socket,
424            buf,
425            target,
426        } = &mut *self;
427        Pin::new(&mut **socket).poll_send_to(cx, buf, target)
428    }
429}
430
431/// The future returned by `UdpSocket::recv_from`
432#[derive(Debug)]
433pub struct RecvFrom<'a, 'b> {
434    socket: &'a mut UdpSocket,
435    buf: &'b mut [u8],
436}
437
438impl<'a, 'b> Future for RecvFrom<'a, 'b> {
439    type Output = io::Result<(usize, SocketAddr)>;
440
441    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
442        let RecvFrom { socket, buf } = &mut *self;
443        Pin::new(&mut **socket).poll_recv_from(cx, buf)
444    }
445}
446
447use std::os::unix::prelude::*;
448
449impl AsRawFd for UdpSocket {
450    fn as_raw_fd(&self) -> RawFd {
451        self.io.get_ref().as_raw_fd()
452    }
453}