async_net/udp.rs
1use std::io;
2use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
3#[cfg(unix)]
4use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd};
5use std::sync::Arc;
6
7use async_io::Async;
8
9use crate::addr::AsyncToSocketAddrs;
10
11/// A UDP socket.
12///
13/// After creating a [`UdpSocket`] by [`bind`][`UdpSocket::bind()`]ing it to a socket address, data
14/// can be [sent to] and [received from] any other socket address.
15///
16/// Cloning a [`UdpSocket`] creates another handle to the same socket. The socket will be closed
17/// when all handles to it are dropped.
18///
19/// Although UDP is a connectionless protocol, this implementation provides an interface to set an
20/// address where data should be sent and received from. After setting a remote address with
21/// [`connect()`][`UdpSocket::connect()`], data can be sent to and received from that address with
22/// [`send()`][`UdpSocket::send()`] and [`recv()`][`UdpSocket::recv()`].
23///
24/// As stated in the User Datagram Protocol's specification in [IETF RFC 768], UDP is an unordered,
25/// unreliable protocol. Refer to [`TcpListener`][`super::TcpListener`] and
26/// [`TcpStream`][`super::TcpStream`] for TCP primitives.
27///
28/// [received from]: UdpSocket::recv_from()
29/// [sent to]: UdpSocket::send_to()
30/// [IETF RFC 768]: https://tools.ietf.org/html/rfc768
31///
32/// # Examples
33///
34/// ```no_run
35/// use async_net::UdpSocket;
36///
37/// # futures_lite::future::block_on(async {
38/// let socket = UdpSocket::bind("127.0.0.1:8080").await?;
39/// let mut buf = vec![0u8; 20];
40///
41/// loop {
42/// // Receive a single datagram message.
43/// // If `buf` is too small to hold the entire message, it will be cut off.
44/// let (n, addr) = socket.recv_from(&mut buf).await?;
45///
46/// // Send the message back to the same address that has sent it.
47/// socket.send_to(&buf[..n], &addr).await?;
48/// }
49/// # std::io::Result::Ok(()) });
50/// ```
51#[derive(Clone, Debug)]
52pub struct UdpSocket {
53 inner: Arc<Async<std::net::UdpSocket>>,
54}
55
56impl UdpSocket {
57 fn new(inner: Arc<Async<std::net::UdpSocket>>) -> UdpSocket {
58 UdpSocket { inner }
59 }
60
61 /// Creates a new [`UdpSocket`] bound to the given address.
62 ///
63 /// Binding with a port number of 0 will request that the operating system assigns an available
64 /// port to this socket. The assigned port can be queried via the
65 /// [`local_addr()`][`UdpSocket::local_addr()`] method.
66 ///
67 /// If `addr` yields multiple addresses, binding will be attempted with each of the addresses
68 /// until one succeeds and returns the socket. If none of the addresses succeed in creating a
69 /// socket, the error from the last attempt is returned.
70 ///
71 /// # Examples
72 ///
73 /// Create a UDP socket bound to `127.0.0.1:3400`:
74 ///
75 /// ```no_run
76 /// use async_net::UdpSocket;
77 ///
78 /// # futures_lite::future::block_on(async {
79 /// let socket = UdpSocket::bind("127.0.0.1:3400").await?;
80 /// # std::io::Result::Ok(()) });
81 /// ```
82 ///
83 /// Create a UDP socket bound to `127.0.0.1:3400`. If that address is unavailable, then try
84 /// binding to `127.0.0.1:3401`:
85 ///
86 /// ```no_run
87 /// use async_net::{SocketAddr, UdpSocket};
88 ///
89 /// # futures_lite::future::block_on(async {
90 /// let addrs = [
91 /// SocketAddr::from(([127, 0, 0, 1], 3400)),
92 /// SocketAddr::from(([127, 0, 0, 1], 3401)),
93 /// ];
94 /// let socket = UdpSocket::bind(&addrs[..]).await?;
95 /// # std::io::Result::Ok(()) });
96 /// ```
97 pub async fn bind<A: AsyncToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
98 let mut last_err = None;
99
100 for addr in addr.to_socket_addrs().await? {
101 match Async::<std::net::UdpSocket>::bind(addr) {
102 Ok(socket) => return Ok(UdpSocket::new(Arc::new(socket))),
103 Err(err) => last_err = Some(err),
104 }
105 }
106
107 Err(last_err.unwrap_or_else(|| {
108 io::Error::new(
109 io::ErrorKind::InvalidInput,
110 "could not bind to any of the addresses",
111 )
112 }))
113 }
114
115 /// Returns the local address this socket is bound to.
116 ///
117 /// This can be useful, for example, when binding to port 0 to figure out which port was
118 /// actually bound.
119 ///
120 /// # Examples
121 ///
122 /// Bind to port 0 and then see which port was assigned by the operating system:
123 ///
124 /// ```no_run
125 /// use async_net::{SocketAddr, UdpSocket};
126 ///
127 /// # futures_lite::future::block_on(async {
128 /// let socket = UdpSocket::bind("127.0.0.1:0").await?;
129 /// println!("Bound to {}", socket.local_addr()?);
130 /// # std::io::Result::Ok(()) });
131 /// ```
132 pub fn local_addr(&self) -> io::Result<SocketAddr> {
133 self.inner.get_ref().local_addr()
134 }
135
136 /// Returns the remote address this socket is connected to.
137 ///
138 /// # Examples
139 ///
140 /// ```no_run
141 /// use async_net::UdpSocket;
142 ///
143 /// # futures_lite::future::block_on(async {
144 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
145 /// socket.connect("192.168.0.1:41203").await?;
146 /// println!("Connected to {}", socket.peer_addr()?);
147 /// # std::io::Result::Ok(()) });
148 /// ```
149 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
150 self.inner.get_ref().peer_addr()
151 }
152
153 /// Connects the UDP socket to an address.
154 ///
155 /// When connected, methods [`send()`][`UdpSocket::send()`] and [`recv()`][`UdpSocket::recv()`]
156 /// will use the specified address for sending and receiving messages. Additionally, a filter
157 /// will be applied to [`recv_from()`][`UdpSocket::recv_from()`] so that it only receives
158 /// messages from that same address.
159 ///
160 /// If `addr` yields multiple addresses, connecting will be attempted with each of the
161 /// addresses until the operating system accepts one. If none of the addresses are accepted,
162 /// the error from the last attempt is returned.
163 ///
164 /// # Examples
165 ///
166 /// ```no_run
167 /// use async_net::UdpSocket;
168 ///
169 /// # futures_lite::future::block_on(async {
170 /// let socket = UdpSocket::bind("127.0.0.1:3400").await?;
171 /// socket.connect("127.0.0.1:8080").await?;
172 /// # std::io::Result::Ok(()) });
173 /// ```
174 pub async fn connect<A: AsyncToSocketAddrs>(&self, addr: A) -> io::Result<()> {
175 let mut last_err = None;
176
177 for addr in addr.to_socket_addrs().await? {
178 match self.inner.get_ref().connect(addr) {
179 Ok(()) => return Ok(()),
180 Err(err) => last_err = Some(err),
181 }
182 }
183
184 Err(last_err.unwrap_or_else(|| {
185 io::Error::new(
186 io::ErrorKind::InvalidInput,
187 "could not connect to any of the addresses",
188 )
189 }))
190 }
191
192 /// Receives a single datagram message.
193 ///
194 /// On success, returns the number of bytes received and the address message came from.
195 ///
196 /// This method must be called with a valid byte buffer of sufficient size to hold a message.
197 /// If the received message is too long to fit into the buffer, it may be truncated.
198 ///
199 /// # Examples
200 ///
201 /// ```no_run
202 /// use async_net::UdpSocket;
203 ///
204 /// # futures_lite::future::block_on(async {
205 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
206 ///
207 /// let mut buf = vec![0u8; 1024];
208 /// let (n, addr) = socket.recv_from(&mut buf).await?;
209 /// println!("Received {} bytes from {}", n, addr);
210 /// # std::io::Result::Ok(()) });
211 /// ```
212 pub async fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
213 self.inner.recv_from(buf).await
214 }
215
216 /// Receives a single datagram message without removing it from the queue.
217 ///
218 /// On success, returns the number of bytes peeked and the address message came from.
219 ///
220 /// This method must be called with a valid byte buffer of sufficient size to hold a message.
221 /// If the received message is too long to fit into the buffer, it may be truncated.
222 ///
223 /// Successive calls return the same message. This is accomplished by passing `MSG_PEEK` as a
224 /// flag to the underlying `recvfrom` system call.
225 ///
226 /// # Examples
227 ///
228 /// ```no_run
229 /// use async_net::UdpSocket;
230 ///
231 /// # futures_lite::future::block_on(async {
232 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
233 ///
234 /// let mut buf = vec![0u8; 1024];
235 /// let (n, addr) = socket.peek_from(&mut buf).await?;
236 /// println!("Peeked {} bytes from {}", n, addr);
237 /// # std::io::Result::Ok(()) });
238 /// ```
239 pub async fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
240 self.inner.peek_from(buf).await
241 }
242
243 /// Sends data to the given address.
244 ///
245 /// On success, returns the number of bytes sent.
246 ///
247 /// If `addr` yields multiple addresses, the message will only be sent to the first address.
248 ///
249 /// # Examples
250 ///
251 /// ```no_run
252 /// use async_net::UdpSocket;
253 ///
254 /// # futures_lite::future::block_on(async {
255 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
256 /// socket.send_to(b"hello", "127.0.0.1:4242").await?;
257 /// # std::io::Result::Ok(()) });
258 /// ```
259 pub async fn send_to<A: AsyncToSocketAddrs>(&self, buf: &[u8], addr: A) -> io::Result<usize> {
260 let addr = match addr.to_socket_addrs().await?.next() {
261 Some(addr) => addr,
262 None => {
263 return Err(io::Error::new(
264 io::ErrorKind::InvalidInput,
265 "no addresses to send data to",
266 ))
267 }
268 };
269
270 self.inner.send_to(buf, addr).await
271 }
272
273 /// Receives a single datagram message from the connected address.
274 ///
275 /// On success, returns the number of bytes received.
276 ///
277 /// This method must be called with a valid byte buffer of sufficient size to hold a message.
278 /// If the received message is too long to fit into the buffer, it may be truncated.
279 ///
280 /// The [`connect()`][`UdpSocket::connect()`] method connects this socket to an address. This
281 /// method will fail if the socket is not connected.
282 ///
283 /// # Examples
284 ///
285 /// ```no_run
286 /// use async_net::UdpSocket;
287 ///
288 /// # futures_lite::future::block_on(async {
289 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
290 /// socket.connect("127.0.0.1:8080").await?;
291 ///
292 /// let mut buf = vec![0u8; 1024];
293 /// let n = socket.recv(&mut buf).await?;
294 /// println!("Received {} bytes", n);
295 /// # std::io::Result::Ok(()) });
296 /// ```
297 pub async fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
298 self.inner.recv(buf).await
299 }
300
301 /// Receives a single datagram from the connected address without removing it from the queue.
302 ///
303 /// On success, returns the number of bytes peeked.
304 ///
305 /// This method must be called with a valid byte buffer of sufficient size to hold a message.
306 /// If the received message is too long to fit into the buffer, it may be truncated.
307 ///
308 /// Successive calls return the same message. This is accomplished by passing `MSG_PEEK` as a
309 /// flag to the underlying `recv` system call.
310 ///
311 /// The [`connect()`][`UdpSocket::connect()`] method connects this socket to an address. This
312 /// method will fail if the socket is not connected.
313 ///
314 /// # Examples
315 ///
316 /// ```no_run
317 /// use async_net::UdpSocket;
318 ///
319 /// # futures_lite::future::block_on(async {
320 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
321 /// socket.connect("127.0.0.1:8080").await?;
322 ///
323 /// let mut buf = vec![0u8; 1024];
324 /// let n = socket.peek(&mut buf).await?;
325 /// println!("Peeked {} bytes", n);
326 /// # std::io::Result::Ok(()) });
327 /// ```
328 pub async fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
329 self.inner.peek(buf).await
330 }
331
332 /// Sends data to the connected address.
333 ///
334 /// The [`connect()`][`UdpSocket::connect()`] method connects this socket to an address. This
335 /// method will fail if the socket is not connected.
336 ///
337 /// # Examples
338 ///
339 /// ```no_run
340 /// use async_net::UdpSocket;
341 ///
342 /// # futures_lite::future::block_on(async {
343 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
344 /// socket.connect("127.0.0.1:8080").await?;
345 /// socket.send(b"hello").await?;
346 /// # std::io::Result::Ok(()) });
347 /// ```
348 pub async fn send(&self, buf: &[u8]) -> io::Result<usize> {
349 self.inner.send(buf).await
350 }
351
352 /// Gets the value of the `SO_BROADCAST` option for this socket.
353 ///
354 /// If set to `true`, this socket is allowed to send packets to a broadcast address.
355 ///
356 /// # Examples
357 ///
358 /// ```no_run
359 /// use async_net::UdpSocket;
360 ///
361 /// # futures_lite::future::block_on(async {
362 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
363 /// println!("SO_BROADCAST is set to {}", socket.broadcast()?);
364 /// # std::io::Result::Ok(()) });
365 /// ```
366 pub fn broadcast(&self) -> io::Result<bool> {
367 self.inner.get_ref().broadcast()
368 }
369
370 /// Sets the value of the `SO_BROADCAST` option for this socket.
371 ///
372 /// If set to `true`, this socket is allowed to send packets to a broadcast address.
373 ///
374 /// # Examples
375 ///
376 /// ```no_run
377 /// use async_net::UdpSocket;
378 ///
379 /// # futures_lite::future::block_on(async {
380 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
381 /// socket.set_broadcast(true)?;
382 /// # std::io::Result::Ok(()) });
383 /// ```
384 pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
385 self.inner.get_ref().set_broadcast(broadcast)
386 }
387
388 /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
389 ///
390 /// If set to `true`, multicast packets will be looped back to the local socket.
391 ///
392 /// Note that this option may not have any affect on IPv6 sockets.
393 ///
394 /// # Examples
395 ///
396 /// ```no_run
397 /// use async_net::UdpSocket;
398 ///
399 /// # futures_lite::future::block_on(async {
400 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
401 /// println!("IP_MULTICAST_LOOP is set to {}", socket.multicast_loop_v4()?);
402 /// # std::io::Result::Ok(()) });
403 /// ```
404 pub fn multicast_loop_v4(&self) -> io::Result<bool> {
405 self.inner.get_ref().multicast_loop_v4()
406 }
407
408 /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
409 ///
410 /// If set to `true`, multicast packets will be looped back to the local socket.
411 ///
412 /// Note that this option may not have any affect on IPv6 sockets.
413 ///
414 /// # Examples
415 ///
416 /// ```no_run
417 /// use async_net::UdpSocket;
418 ///
419 /// # futures_lite::future::block_on(async {
420 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
421 /// socket.set_multicast_loop_v4(true)?;
422 /// # std::io::Result::Ok(()) });
423 /// ```
424 pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
425 self.inner
426 .get_ref()
427 .set_multicast_loop_v4(multicast_loop_v4)
428 }
429
430 /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
431 ///
432 /// Indicates the time-to-live value of outgoing multicast packets for this socket. The default
433 /// value is 1, which means that multicast packets don't leave the local network unless
434 /// explicitly requested.
435 ///
436 /// Note that this option may not have any effect on IPv6 sockets.
437 ///
438 /// # Examples
439 ///
440 /// ```no_run
441 /// use async_net::UdpSocket;
442 ///
443 /// # futures_lite::future::block_on(async {
444 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
445 /// println!("IP_MULTICAST_TTL is set to {}", socket.multicast_loop_v4()?);
446 /// # std::io::Result::Ok(()) });
447 /// ```
448 pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
449 self.inner.get_ref().multicast_ttl_v4()
450 }
451
452 /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
453 ///
454 /// Indicates the time-to-live value of outgoing multicast packets for this socket. The default
455 /// value is 1, which means that multicast packets don't leave the local network unless
456 /// explicitly requested.
457 ///
458 /// Note that this option may not have any effect on IPv6 sockets.
459 ///
460 /// # Examples
461 ///
462 /// ```no_run
463 /// use async_net::UdpSocket;
464 ///
465 /// # futures_lite::future::block_on(async {
466 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
467 /// socket.set_multicast_ttl_v4(10)?;
468 /// # std::io::Result::Ok(()) });
469 /// ```
470 pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
471 self.inner.get_ref().set_multicast_ttl_v4(ttl)
472 }
473
474 /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
475 ///
476 /// Controls whether this socket sees the multicast packets it sends itself.
477 ///
478 /// Note that this option may not have any effect on IPv4 sockets.
479 ///
480 /// # Examples
481 ///
482 /// ```no_run
483 /// use async_net::UdpSocket;
484 ///
485 /// # futures_lite::future::block_on(async {
486 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
487 /// println!("IPV6_MULTICAST_LOOP is set to {}", socket.multicast_loop_v6()?);
488 /// # std::io::Result::Ok(()) });
489 /// ```
490 pub fn multicast_loop_v6(&self) -> io::Result<bool> {
491 self.inner.get_ref().multicast_loop_v6()
492 }
493
494 /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
495 ///
496 /// Controls whether this socket sees the multicast packets it sends itself.
497 ///
498 /// Note that this option may not have any effect on IPv4 sockets.
499 ///
500 /// # Examples
501 ///
502 /// ```no_run
503 /// use async_net::UdpSocket;
504 ///
505 /// # futures_lite::future::block_on(async {
506 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
507 /// socket.set_multicast_loop_v6(true)?;
508 /// # std::io::Result::Ok(()) });
509 /// ```
510 pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
511 self.inner
512 .get_ref()
513 .set_multicast_loop_v6(multicast_loop_v6)
514 }
515
516 /// Gets the value of the `IP_TTL` option for this socket.
517 ///
518 /// This option configures the time-to-live field that is used in every packet sent from this
519 /// socket.
520 ///
521 /// # Examples
522 ///
523 /// ```no_run
524 /// use async_net::UdpSocket;
525 ///
526 /// # futures_lite::future::block_on(async {
527 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
528 /// println!("IP_TTL is set to {}", socket.ttl()?);
529 /// # std::io::Result::Ok(()) });
530 /// ```
531 pub fn ttl(&self) -> io::Result<u32> {
532 self.inner.get_ref().ttl()
533 }
534
535 /// Sets the value of the `IP_TTL` option for this socket.
536 ///
537 /// This option configures the time-to-live field that is used in every packet sent from this
538 /// socket.
539 ///
540 /// # Examples
541 ///
542 /// ```no_run
543 /// use async_net::UdpSocket;
544 ///
545 /// # futures_lite::future::block_on(async {
546 /// let socket = UdpSocket::bind("127.0.0.1:34254").await?;
547 /// socket.set_ttl(100)?;
548 /// # std::io::Result::Ok(()) });
549 /// ```
550 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
551 self.inner.get_ref().set_ttl(ttl)
552 }
553
554 /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
555 ///
556 /// This method specifies a new multicast group for this socket to join. Argument `multiaddr`
557 /// must be a valid multicast address, and `interface` is the address of the local interface
558 /// with which the system should join the multicast group. If it's equal to `INADDR_ANY` then
559 /// an appropriate interface is chosen by the system.
560 pub fn join_multicast_v4(&self, multiaddr: Ipv4Addr, interface: Ipv4Addr) -> io::Result<()> {
561 self.inner
562 .get_ref()
563 .join_multicast_v4(&multiaddr, &interface)
564 }
565
566 /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
567 ///
568 /// This method leaves a multicast group. Argument `multiaddr` must be a valid multicast
569 /// address, and `interface` is the index of the interface to leave.
570 pub fn leave_multicast_v4(&self, multiaddr: Ipv4Addr, interface: Ipv4Addr) -> io::Result<()> {
571 self.inner
572 .get_ref()
573 .leave_multicast_v4(&multiaddr, &interface)
574 }
575
576 /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
577 ///
578 /// This method specifies a new multicast group for this socket to join. Argument `multiaddr`
579 /// must be a valid multicast address, and `interface` is the index of the interface to join
580 /// (or 0 to indicate any interface).
581 pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
582 self.inner.get_ref().join_multicast_v6(multiaddr, interface)
583 }
584
585 /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
586 ///
587 /// This method leaves a multicast group. Argument `multiaddr` must be a valid multicast
588 /// address, and `interface` is the index of the interface to leave.
589 pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
590 self.inner
591 .get_ref()
592 .leave_multicast_v6(multiaddr, interface)
593 }
594}
595
596impl From<Async<std::net::UdpSocket>> for UdpSocket {
597 fn from(socket: Async<std::net::UdpSocket>) -> UdpSocket {
598 UdpSocket::new(Arc::new(socket))
599 }
600}
601
602impl TryFrom<std::net::UdpSocket> for UdpSocket {
603 type Error = io::Error;
604
605 fn try_from(socket: std::net::UdpSocket) -> io::Result<UdpSocket> {
606 Ok(UdpSocket::new(Arc::new(Async::new(socket)?)))
607 }
608}
609
610impl From<UdpSocket> for Arc<Async<std::net::UdpSocket>> {
611 fn from(val: UdpSocket) -> Self {
612 val.inner
613 }
614}
615
616#[cfg(unix)]
617impl AsRawFd for UdpSocket {
618 fn as_raw_fd(&self) -> RawFd {
619 self.inner.as_raw_fd()
620 }
621}
622
623#[cfg(unix)]
624impl AsFd for UdpSocket {
625 fn as_fd(&self) -> BorrowedFd<'_> {
626 self.inner.get_ref().as_fd()
627 }
628}
629
630#[cfg(unix)]
631impl TryFrom<OwnedFd> for UdpSocket {
632 type Error = io::Error;
633
634 fn try_from(value: OwnedFd) -> Result<Self, Self::Error> {
635 Self::try_from(std::net::UdpSocket::from(value))
636 }
637}