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}