1 //! Primitives for working with UDP.
2 //!
3 //! The types provided in this module are non-blocking by default and are
4 //! designed to be portable across all supported Mio platforms. As long as the
5 //! [portability guidelines] are followed, the behavior should be identical no
6 //! matter the target platform.
7 //!
8 //! [portability guidelines]: ../struct.Poll.html#portability
9 
10 use crate::io_source::IoSource;
11 use crate::{event, sys, Interest, Registry, Token};
12 
13 use std::fmt;
14 use std::io;
15 use std::net;
16 use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
17 #[cfg(unix)]
18 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
19 #[cfg(windows)]
20 use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
21 
22 /// A User Datagram Protocol socket.
23 ///
24 /// This is an implementation of a bound UDP socket. This supports both IPv4 and
25 /// IPv6 addresses, and there is no corresponding notion of a server because UDP
26 /// is a datagram protocol.
27 ///
28 /// # Examples
29 ///
30 #[cfg_attr(feature = "os-poll", doc = "```")]
31 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
32 /// # use std::error::Error;
33 /// #
34 /// # fn main() -> Result<(), Box<dyn Error>> {
35 /// // An Echo program:
36 /// // SENDER -> sends a message.
37 /// // ECHOER -> listens and prints the message received.
38 ///
39 /// use mio::net::UdpSocket;
40 /// use mio::{Events, Interest, Poll, Token};
41 /// use std::time::Duration;
42 ///
43 /// const SENDER: Token = Token(0);
44 /// const ECHOER: Token = Token(1);
45 ///
46 /// // This operation will fail if the address is in use, so we select different ports for each
47 /// // socket.
48 /// let mut sender_socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
49 /// let mut echoer_socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
50 ///
51 /// // If we do not use connect here, SENDER and ECHOER would need to call send_to and recv_from
52 /// // respectively.
53 /// sender_socket.connect(echoer_socket.local_addr()?)?;
54 ///
55 /// // We need a Poll to check if SENDER is ready to be written into, and if ECHOER is ready to be
56 /// // read from.
57 /// let mut poll = Poll::new()?;
58 ///
59 /// // We register our sockets here so that we can check if they are ready to be written/read.
60 /// poll.registry().register(&mut sender_socket, SENDER, Interest::WRITABLE)?;
61 /// poll.registry().register(&mut echoer_socket, ECHOER, Interest::READABLE)?;
62 ///
63 /// let msg_to_send = [9; 9];
64 /// let mut buffer = [0; 9];
65 ///
66 /// let mut events = Events::with_capacity(128);
67 /// loop {
68 ///     poll.poll(&mut events, Some(Duration::from_millis(100)))?;
69 ///     for event in events.iter() {
70 ///         match event.token() {
71 ///             // Our SENDER is ready to be written into.
72 ///             SENDER => {
73 ///                 let bytes_sent = sender_socket.send(&msg_to_send)?;
74 ///                 assert_eq!(bytes_sent, 9);
75 ///                 println!("sent {:?} -> {:?} bytes", msg_to_send, bytes_sent);
76 ///             },
77 ///             // Our ECHOER is ready to be read from.
78 ///             ECHOER => {
79 ///                 let num_recv = echoer_socket.recv(&mut buffer)?;
80 ///                 println!("echo {:?} -> {:?}", buffer, num_recv);
81 ///                 buffer = [0; 9];
82 ///                 # drop(buffer); // Silence unused assignment warning.
83 ///                 # return Ok(());
84 ///             }
85 ///             _ => unreachable!()
86 ///         }
87 ///     }
88 /// }
89 /// # }
90 /// ```
91 pub struct UdpSocket {
92     inner: IoSource<net::UdpSocket>,
93 }
94 
95 impl UdpSocket {
96     /// Creates a UDP socket from the given address.
97     ///
98     /// # Examples
99     ///
100     #[cfg_attr(feature = "os-poll", doc = "```")]
101     #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
102     /// # use std::error::Error;
103     /// #
104     /// # fn main() -> Result<(), Box<dyn Error>> {
105     /// use mio::net::UdpSocket;
106     ///
107     /// // We must bind it to an open address.
108     /// let socket = match UdpSocket::bind("127.0.0.1:0".parse()?) {
109     ///     Ok(new_socket) => new_socket,
110     ///     Err(fail) => {
111     ///         // We panic! here, but you could try to bind it again on another address.
112     ///         panic!("Failed to bind socket. {:?}", fail);
113     ///     }
114     /// };
115     ///
116     /// // Our socket was created, but we should not use it before checking it's readiness.
117     /// #    drop(socket); // Silence unused variable warning.
118     /// #    Ok(())
119     /// # }
120     /// ```
bind(addr: SocketAddr) -> io::Result<UdpSocket>121     pub fn bind(addr: SocketAddr) -> io::Result<UdpSocket> {
122         sys::udp::bind(addr).map(UdpSocket::from_std)
123     }
124 
125     /// Creates a new `UdpSocket` from a standard `net::UdpSocket`.
126     ///
127     /// This function is intended to be used to wrap a UDP socket from the
128     /// standard library in the Mio equivalent. The conversion assumes nothing
129     /// about the underlying socket; it is left up to the user to set it in
130     /// non-blocking mode.
from_std(socket: net::UdpSocket) -> UdpSocket131     pub fn from_std(socket: net::UdpSocket) -> UdpSocket {
132         UdpSocket {
133             inner: IoSource::new(socket),
134         }
135     }
136 
137     /// Returns the socket address that this socket was created from.
138     ///
139     /// # Examples
140     ///
141     // This assertion is almost, but not quite, universal.  It fails on
142     // shared-IP FreeBSD jails.  It's hard for mio to know whether we're jailed,
143     // so simply disable the test on FreeBSD.
144     #[cfg_attr(all(feature = "os-poll", not(target_os = "freebsd")), doc = "```")]
145     #[cfg_attr(
146         any(not(feature = "os-poll"), target_os = "freebsd"),
147         doc = "```ignore"
148     )]
149     /// # use std::error::Error;
150     /// #
151     /// # fn main() -> Result<(), Box<dyn Error>> {
152     /// use mio::net::UdpSocket;
153     ///
154     /// let addr = "127.0.0.1:0".parse()?;
155     /// let socket = UdpSocket::bind(addr)?;
156     /// assert_eq!(socket.local_addr()?.ip(), addr.ip());
157     /// #    Ok(())
158     /// # }
159     /// ```
local_addr(&self) -> io::Result<SocketAddr>160     pub fn local_addr(&self) -> io::Result<SocketAddr> {
161         self.inner.local_addr()
162     }
163 
164     /// Sends data on the socket to the given address. On success, returns the
165     /// number of bytes written.
166     ///
167     /// Address type can be any implementor of `ToSocketAddrs` trait. See its
168     /// documentation for concrete examples.
169     ///
170     /// # Examples
171     ///
172     /// ```no_run
173     /// # use std::error::Error;
174     /// # fn main() -> Result<(), Box<dyn Error>> {
175     /// use mio::net::UdpSocket;
176     ///
177     /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
178     ///
179     /// // We must check if the socket is writable before calling send_to,
180     /// // or we could run into a WouldBlock error.
181     ///
182     /// let bytes_sent = socket.send_to(&[9; 9], "127.0.0.1:11100".parse()?)?;
183     /// assert_eq!(bytes_sent, 9);
184     /// #
185     /// #    Ok(())
186     /// # }
187     /// ```
send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize>188     pub fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {
189         self.inner.do_io(|inner| inner.send_to(buf, target))
190     }
191 
192     /// Receives data from the socket. On success, returns the number of bytes
193     /// read and the address from whence the data came.
194     ///
195     /// # Notes
196     ///
197     /// On Windows, if the data is larger than the buffer specified, the buffer
198     /// is filled with the first part of the data, and recv_from returns the error
199     /// WSAEMSGSIZE(10040). The excess data is lost.
200     /// Make sure to always use a sufficiently large buffer to hold the
201     /// maximum UDP packet size, which can be up to 65536 bytes in size.
202     ///
203     /// # Examples
204     ///
205     /// ```no_run
206     /// # use std::error::Error;
207     /// #
208     /// # fn main() -> Result<(), Box<dyn Error>> {
209     /// use mio::net::UdpSocket;
210     ///
211     /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
212     ///
213     /// // We must check if the socket is readable before calling recv_from,
214     /// // or we could run into a WouldBlock error.
215     ///
216     /// let mut buf = [0; 9];
217     /// let (num_recv, from_addr) = socket.recv_from(&mut buf)?;
218     /// println!("Received {:?} -> {:?} bytes from {:?}", buf, num_recv, from_addr);
219     /// #
220     /// #    Ok(())
221     /// # }
222     /// ```
recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)>223     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
224         self.inner.do_io(|inner| inner.recv_from(buf))
225     }
226 
227     /// Receives data from the socket, without removing it from the input queue.
228     /// On success, returns the number of bytes read and the address from whence
229     /// the data came.
230     ///
231     /// # Notes
232     ///
233     /// On Windows, if the data is larger than the buffer specified, the buffer
234     /// is filled with the first part of the data, and peek_from returns the error
235     /// WSAEMSGSIZE(10040). The excess data is lost.
236     /// Make sure to always use a sufficiently large buffer to hold the
237     /// maximum UDP packet size, which can be up to 65536 bytes in size.
238     ///
239     /// # Examples
240     ///
241     /// ```no_run
242     /// # use std::error::Error;
243     /// #
244     /// # fn main() -> Result<(), Box<dyn Error>> {
245     /// use mio::net::UdpSocket;
246     ///
247     /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
248     ///
249     /// // We must check if the socket is readable before calling recv_from,
250     /// // or we could run into a WouldBlock error.
251     ///
252     /// let mut buf = [0; 9];
253     /// let (num_recv, from_addr) = socket.peek_from(&mut buf)?;
254     /// println!("Received {:?} -> {:?} bytes from {:?}", buf, num_recv, from_addr);
255     /// #
256     /// #    Ok(())
257     /// # }
258     /// ```
peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)>259     pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
260         self.inner.do_io(|inner| inner.peek_from(buf))
261     }
262 
263     /// Sends data on the socket to the address previously bound via connect(). On success,
264     /// returns the number of bytes written.
send(&self, buf: &[u8]) -> io::Result<usize>265     pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
266         self.inner.do_io(|inner| inner.send(buf))
267     }
268 
269     /// Receives data from the socket previously bound with connect(). On success, returns
270     /// the number of bytes read.
271     ///
272     /// # Notes
273     ///
274     /// On Windows, if the data is larger than the buffer specified, the buffer
275     /// is filled with the first part of the data, and recv returns the error
276     /// WSAEMSGSIZE(10040). The excess data is lost.
277     /// Make sure to always use a sufficiently large buffer to hold the
278     /// maximum UDP packet size, which can be up to 65536 bytes in size.
recv(&self, buf: &mut [u8]) -> io::Result<usize>279     pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
280         self.inner.do_io(|inner| inner.recv(buf))
281     }
282 
283     /// Receives data from the socket, without removing it from the input queue.
284     /// On success, returns the number of bytes read.
285     ///
286     /// # Notes
287     ///
288     /// On Windows, if the data is larger than the buffer specified, the buffer
289     /// is filled with the first part of the data, and peek returns the error
290     /// WSAEMSGSIZE(10040). The excess data is lost.
291     /// Make sure to always use a sufficiently large buffer to hold the
292     /// maximum UDP packet size, which can be up to 65536 bytes in size.
peek(&self, buf: &mut [u8]) -> io::Result<usize>293     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
294         self.inner.do_io(|inner| inner.peek(buf))
295     }
296 
297     /// Connects the UDP socket setting the default destination for `send()`
298     /// and limiting packets that are read via `recv` from the address specified
299     /// in `addr`.
connect(&self, addr: SocketAddr) -> io::Result<()>300     pub fn connect(&self, addr: SocketAddr) -> io::Result<()> {
301         self.inner.connect(addr)
302     }
303 
304     /// Sets the value of the `SO_BROADCAST` option for this socket.
305     ///
306     /// When enabled, this socket is allowed to send packets to a broadcast
307     /// address.
308     ///
309     /// # Examples
310     ///
311     #[cfg_attr(feature = "os-poll", doc = "```")]
312     #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
313     /// # use std::error::Error;
314     /// #
315     /// # fn main() -> Result<(), Box<dyn Error>> {
316     /// use mio::net::UdpSocket;
317     ///
318     /// let broadcast_socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
319     /// if broadcast_socket.broadcast()? == false {
320     ///     broadcast_socket.set_broadcast(true)?;
321     /// }
322     ///
323     /// assert_eq!(broadcast_socket.broadcast()?, true);
324     /// #
325     /// #    Ok(())
326     /// # }
327     /// ```
set_broadcast(&self, on: bool) -> io::Result<()>328     pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
329         self.inner.set_broadcast(on)
330     }
331 
332     /// Gets the value of the `SO_BROADCAST` option for this socket.
333     ///
334     /// For more information about this option, see
335     /// [`set_broadcast`][link].
336     ///
337     /// [link]: #method.set_broadcast
338     ///
339     /// # Examples
340     ///
341     #[cfg_attr(feature = "os-poll", doc = "```")]
342     #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
343     /// # use std::error::Error;
344     /// #
345     /// # fn main() -> Result<(), Box<dyn Error>> {
346     /// use mio::net::UdpSocket;
347     ///
348     /// let broadcast_socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
349     /// assert_eq!(broadcast_socket.broadcast()?, false);
350     /// #
351     /// #    Ok(())
352     /// # }
353     /// ```
broadcast(&self) -> io::Result<bool>354     pub fn broadcast(&self) -> io::Result<bool> {
355         self.inner.broadcast()
356     }
357 
358     /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
359     ///
360     /// If enabled, multicast packets will be looped back to the local socket.
361     /// Note that this may not have any affect on IPv6 sockets.
set_multicast_loop_v4(&self, on: bool) -> io::Result<()>362     pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> {
363         self.inner.set_multicast_loop_v4(on)
364     }
365 
366     /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
367     ///
368     /// For more information about this option, see
369     /// [`set_multicast_loop_v4`][link].
370     ///
371     /// [link]: #method.set_multicast_loop_v4
multicast_loop_v4(&self) -> io::Result<bool>372     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
373         self.inner.multicast_loop_v4()
374     }
375 
376     /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
377     ///
378     /// Indicates the time-to-live value of outgoing multicast packets for
379     /// this socket. The default value is 1 which means that multicast packets
380     /// don't leave the local network unless explicitly requested.
381     ///
382     /// Note that this may not have any affect on IPv6 sockets.
set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()>383     pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
384         self.inner.set_multicast_ttl_v4(ttl)
385     }
386 
387     /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
388     ///
389     /// For more information about this option, see
390     /// [`set_multicast_ttl_v4`][link].
391     ///
392     /// [link]: #method.set_multicast_ttl_v4
multicast_ttl_v4(&self) -> io::Result<u32>393     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
394         self.inner.multicast_ttl_v4()
395     }
396 
397     /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
398     ///
399     /// Controls whether this socket sees the multicast packets it sends itself.
400     /// Note that this may not have any affect on IPv4 sockets.
set_multicast_loop_v6(&self, on: bool) -> io::Result<()>401     pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> {
402         self.inner.set_multicast_loop_v6(on)
403     }
404 
405     /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
406     ///
407     /// For more information about this option, see
408     /// [`set_multicast_loop_v6`][link].
409     ///
410     /// [link]: #method.set_multicast_loop_v6
multicast_loop_v6(&self) -> io::Result<bool>411     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
412         self.inner.multicast_loop_v6()
413     }
414 
415     /// Sets the value for the `IP_TTL` option on this socket.
416     ///
417     /// This value sets the time-to-live field that is used in every packet sent
418     /// from this socket.
419     ///
420     /// # Examples
421     ///
422     #[cfg_attr(feature = "os-poll", doc = "```")]
423     #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
424     /// # use std::error::Error;
425     /// #
426     /// # fn main() -> Result<(), Box<dyn Error>> {
427     /// use mio::net::UdpSocket;
428     ///
429     /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
430     /// if socket.ttl()? < 255 {
431     ///     socket.set_ttl(255)?;
432     /// }
433     ///
434     /// assert_eq!(socket.ttl()?, 255);
435     /// #
436     /// #    Ok(())
437     /// # }
438     /// ```
set_ttl(&self, ttl: u32) -> io::Result<()>439     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
440         self.inner.set_ttl(ttl)
441     }
442 
443     /// Gets the value of the `IP_TTL` option for this socket.
444     ///
445     /// For more information about this option, see [`set_ttl`][link].
446     ///
447     /// [link]: #method.set_ttl
448     ///
449     /// # Examples
450     ///
451     #[cfg_attr(feature = "os-poll", doc = "```")]
452     #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
453     /// # use std::error::Error;
454     /// #
455     /// # fn main() -> Result<(), Box<dyn Error>> {
456     /// use mio::net::UdpSocket;
457     ///
458     /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
459     /// socket.set_ttl(255)?;
460     ///
461     /// assert_eq!(socket.ttl()?, 255);
462     /// #
463     /// #    Ok(())
464     /// # }
465     /// ```
ttl(&self) -> io::Result<u32>466     pub fn ttl(&self) -> io::Result<u32> {
467         self.inner.ttl()
468     }
469 
470     /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
471     ///
472     /// This function specifies a new multicast group for this socket to join.
473     /// The address must be a valid multicast address, and `interface` is the
474     /// address of the local interface with which the system should join the
475     /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
476     /// interface is chosen by the system.
477     #[allow(clippy::trivially_copy_pass_by_ref)]
join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>478     pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
479         self.inner.join_multicast_v4(multiaddr, interface)
480     }
481 
482     /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
483     ///
484     /// This function specifies a new multicast group for this socket to join.
485     /// The address must be a valid multicast address, and `interface` is the
486     /// index of the interface to join/leave (or 0 to indicate any interface).
487     #[allow(clippy::trivially_copy_pass_by_ref)]
join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>488     pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
489         self.inner.join_multicast_v6(multiaddr, interface)
490     }
491 
492     /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
493     ///
494     /// For more information about this option, see
495     /// [`join_multicast_v4`][link].
496     ///
497     /// [link]: #method.join_multicast_v4
498     #[allow(clippy::trivially_copy_pass_by_ref)]
leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>499     pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
500         self.inner.leave_multicast_v4(multiaddr, interface)
501     }
502 
503     /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
504     ///
505     /// For more information about this option, see
506     /// [`join_multicast_v6`][link].
507     ///
508     /// [link]: #method.join_multicast_v6
509     #[allow(clippy::trivially_copy_pass_by_ref)]
leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>510     pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
511         self.inner.leave_multicast_v6(multiaddr, interface)
512     }
513 
514     /// Get the value of the `IPV6_V6ONLY` option on this socket.
515     #[allow(clippy::trivially_copy_pass_by_ref)]
only_v6(&self) -> io::Result<bool>516     pub fn only_v6(&self) -> io::Result<bool> {
517         sys::udp::only_v6(&self.inner)
518     }
519 
520     /// Get the value of the `SO_ERROR` option on this socket.
521     ///
522     /// This will retrieve the stored error in the underlying socket, clearing
523     /// the field in the process. This can be useful for checking errors between
524     /// calls.
take_error(&self) -> io::Result<Option<io::Error>>525     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
526         self.inner.take_error()
527     }
528 }
529 
530 impl event::Source for UdpSocket {
register( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>531     fn register(
532         &mut self,
533         registry: &Registry,
534         token: Token,
535         interests: Interest,
536     ) -> io::Result<()> {
537         self.inner.register(registry, token, interests)
538     }
539 
reregister( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>540     fn reregister(
541         &mut self,
542         registry: &Registry,
543         token: Token,
544         interests: Interest,
545     ) -> io::Result<()> {
546         self.inner.reregister(registry, token, interests)
547     }
548 
deregister(&mut self, registry: &Registry) -> io::Result<()>549     fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
550         self.inner.deregister(registry)
551     }
552 }
553 
554 impl fmt::Debug for UdpSocket {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result555     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
556         self.inner.fmt(f)
557     }
558 }
559 
560 #[cfg(unix)]
561 impl IntoRawFd for UdpSocket {
into_raw_fd(self) -> RawFd562     fn into_raw_fd(self) -> RawFd {
563         self.inner.into_inner().into_raw_fd()
564     }
565 }
566 
567 #[cfg(unix)]
568 impl AsRawFd for UdpSocket {
as_raw_fd(&self) -> RawFd569     fn as_raw_fd(&self) -> RawFd {
570         self.inner.as_raw_fd()
571     }
572 }
573 
574 #[cfg(unix)]
575 impl FromRawFd for UdpSocket {
576     /// Converts a `RawFd` to a `UdpSocket`.
577     ///
578     /// # Notes
579     ///
580     /// The caller is responsible for ensuring that the socket is in
581     /// non-blocking mode.
from_raw_fd(fd: RawFd) -> UdpSocket582     unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
583         UdpSocket::from_std(FromRawFd::from_raw_fd(fd))
584     }
585 }
586 
587 #[cfg(windows)]
588 impl IntoRawSocket for UdpSocket {
into_raw_socket(self) -> RawSocket589     fn into_raw_socket(self) -> RawSocket {
590         self.inner.into_inner().into_raw_socket()
591     }
592 }
593 
594 #[cfg(windows)]
595 impl AsRawSocket for UdpSocket {
as_raw_socket(&self) -> RawSocket596     fn as_raw_socket(&self) -> RawSocket {
597         self.inner.as_raw_socket()
598     }
599 }
600 
601 #[cfg(windows)]
602 impl FromRawSocket for UdpSocket {
603     /// Converts a `RawSocket` to a `UdpSocket`.
604     ///
605     /// # Notes
606     ///
607     /// The caller is responsible for ensuring that the socket is in
608     /// non-blocking mode.
from_raw_socket(socket: RawSocket) -> UdpSocket609     unsafe fn from_raw_socket(socket: RawSocket) -> UdpSocket {
610         UdpSocket::from_std(FromRawSocket::from_raw_socket(socket))
611     }
612 }
613