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