]> git.lizzy.rs Git - rust.git/blob - library/std/src/net/udp.rs
Auto merge of #73176 - LeSeulArtichaut:tyctxtat-err, r=eddyb
[rust.git] / library / std / src / net / udp.rs
1 use crate::fmt;
2 use crate::io::{self, Error, ErrorKind};
3 use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
4 use crate::sys_common::net as net_imp;
5 use crate::sys_common::{AsInner, FromInner, IntoInner};
6 use crate::time::Duration;
7
8 /// A UDP socket.
9 ///
10 /// After creating a `UdpSocket` by [`bind`]ing it to a socket address, data can be
11 /// [sent to] and [received from] any other socket address.
12 ///
13 /// Although UDP is a connectionless protocol, this implementation provides an interface
14 /// to set an address where data should be sent and received from. After setting a remote
15 /// address with [`connect`], data can be sent to and received from that address with
16 /// [`send`] and [`recv`].
17 ///
18 /// As stated in the User Datagram Protocol's specification in [IETF RFC 768], UDP is
19 /// an unordered, unreliable protocol; refer to [`TcpListener`] and [`TcpStream`] for TCP
20 /// primitives.
21 ///
22 /// [`bind`]: UdpSocket::bind
23 /// [`connect`]: UdpSocket::connect
24 /// [IETF RFC 768]: https://tools.ietf.org/html/rfc768
25 /// [`recv`]: UdpSocket::recv
26 /// [received from]: UdpSocket::recv_from
27 /// [`send`]: UdpSocket::send
28 /// [sent to]: UdpSocket::send_to
29 /// [`TcpListener`]: crate::net::TcpListener
30 /// [`TcpStream`]: crate::net::TcpStream
31 ///
32 /// # Examples
33 ///
34 /// ```no_run
35 /// use std::net::UdpSocket;
36 ///
37 /// fn main() -> std::io::Result<()> {
38 ///     {
39 ///         let mut socket = UdpSocket::bind("127.0.0.1:34254")?;
40 ///
41 ///         // Receives a single datagram message on the socket. If `buf` is too small to hold
42 ///         // the message, it will be cut off.
43 ///         let mut buf = [0; 10];
44 ///         let (amt, src) = socket.recv_from(&mut buf)?;
45 ///
46 ///         // Redeclare `buf` as slice of the received data and send reverse data back to origin.
47 ///         let buf = &mut buf[..amt];
48 ///         buf.reverse();
49 ///         socket.send_to(buf, &src)?;
50 ///     } // the socket is closed here
51 ///     Ok(())
52 /// }
53 /// ```
54 #[stable(feature = "rust1", since = "1.0.0")]
55 pub struct UdpSocket(net_imp::UdpSocket);
56
57 impl UdpSocket {
58     /// Creates a UDP socket from the given address.
59     ///
60     /// The address type can be any implementor of [`ToSocketAddrs`] trait. See
61     /// its documentation for concrete examples.
62     ///
63     /// If `addr` yields multiple addresses, `bind` will be attempted with
64     /// each of the addresses until one succeeds and returns the socket. If none
65     /// of the addresses succeed in creating a socket, the error returned from
66     /// the last attempt (the last address) is returned.
67     ///
68     /// # Examples
69     ///
70     /// Creates a UDP socket bound to `127.0.0.1:3400`:
71     ///
72     /// ```no_run
73     /// use std::net::UdpSocket;
74     ///
75     /// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
76     /// ```
77     ///
78     /// Creates a UDP socket bound to `127.0.0.1:3400`. If the socket cannot be
79     /// bound to that address, create a UDP socket bound to `127.0.0.1:3401`:
80     ///
81     /// ```no_run
82     /// use std::net::{SocketAddr, UdpSocket};
83     ///
84     /// let addrs = [
85     ///     SocketAddr::from(([127, 0, 0, 1], 3400)),
86     ///     SocketAddr::from(([127, 0, 0, 1], 3401)),
87     /// ];
88     /// let socket = UdpSocket::bind(&addrs[..]).expect("couldn't bind to address");
89     /// ```
90     #[stable(feature = "rust1", since = "1.0.0")]
91     pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
92         super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
93     }
94
95     /// Receives a single datagram message on the socket. On success, returns the number
96     /// of bytes read and the origin.
97     ///
98     /// The function must be called with valid byte array `buf` of sufficient size to
99     /// hold the message bytes. If a message is too long to fit in the supplied buffer,
100     /// excess bytes may be discarded.
101     ///
102     /// # Examples
103     ///
104     /// ```no_run
105     /// use std::net::UdpSocket;
106     ///
107     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
108     /// let mut buf = [0; 10];
109     /// let (number_of_bytes, src_addr) = socket.recv_from(&mut buf)
110     ///                                         .expect("Didn't receive data");
111     /// let filled_buf = &mut buf[..number_of_bytes];
112     /// ```
113     #[stable(feature = "rust1", since = "1.0.0")]
114     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
115         self.0.recv_from(buf)
116     }
117
118     /// Receives a single datagram message on the socket, without removing it from the
119     /// queue. On success, returns the number of bytes read and the origin.
120     ///
121     /// The function must be called with valid byte array `buf` of sufficient size to
122     /// hold the message bytes. If a message is too long to fit in the supplied buffer,
123     /// excess bytes may be discarded.
124     ///
125     /// Successive calls return the same data. This is accomplished by passing
126     /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
127     ///
128     /// Do not use this function to implement busy waiting, instead use `libc::poll` to
129     /// synchronize IO events on one or more sockets.
130     ///
131     /// # Examples
132     ///
133     /// ```no_run
134     /// use std::net::UdpSocket;
135     ///
136     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
137     /// let mut buf = [0; 10];
138     /// let (number_of_bytes, src_addr) = socket.peek_from(&mut buf)
139     ///                                         .expect("Didn't receive data");
140     /// let filled_buf = &mut buf[..number_of_bytes];
141     /// ```
142     #[stable(feature = "peek", since = "1.18.0")]
143     pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
144         self.0.peek_from(buf)
145     }
146
147     /// Sends data on the socket to the given address. On success, returns the
148     /// number of bytes written.
149     ///
150     /// Address type can be any implementor of [`ToSocketAddrs`] trait. See its
151     /// documentation for concrete examples.
152     ///
153     /// It is possible for `addr` to yield multiple addresses, but `send_to`
154     /// will only send data to the first address yielded by `addr`.
155     ///
156     /// This will return an error when the IP version of the local socket
157     /// does not match that returned from [`ToSocketAddrs`].
158     ///
159     /// See issue #34202 for more details.
160     ///
161     /// # Examples
162     ///
163     /// ```no_run
164     /// use std::net::UdpSocket;
165     ///
166     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
167     /// socket.send_to(&[0; 10], "127.0.0.1:4242").expect("couldn't send data");
168     /// ```
169     #[stable(feature = "rust1", since = "1.0.0")]
170     pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A) -> io::Result<usize> {
171         match addr.to_socket_addrs()?.next() {
172             Some(addr) => self.0.send_to(buf, &addr),
173             None => Err(Error::new(ErrorKind::InvalidInput, "no addresses to send data to")),
174         }
175     }
176
177     /// Returns the socket address of the remote peer this socket was connected to.
178     ///
179     /// # Examples
180     ///
181     /// ```no_run
182     /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
183     ///
184     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
185     /// socket.connect("192.168.0.1:41203").expect("couldn't connect to address");
186     /// assert_eq!(socket.peer_addr().unwrap(),
187     ///            SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 41203)));
188     /// ```
189     ///
190     /// If the socket isn't connected, it will return a [`NotConnected`] error.
191     ///
192     /// [`NotConnected`]: io::ErrorKind::NotConnected
193     ///
194     /// ```no_run
195     /// use std::net::UdpSocket;
196     ///
197     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
198     /// assert_eq!(socket.peer_addr().unwrap_err().kind(),
199     ///            std::io::ErrorKind::NotConnected);
200     /// ```
201     #[stable(feature = "udp_peer_addr", since = "1.40.0")]
202     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
203         self.0.peer_addr()
204     }
205
206     /// Returns the socket address that this socket was created from.
207     ///
208     /// # Examples
209     ///
210     /// ```no_run
211     /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
212     ///
213     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
214     /// assert_eq!(socket.local_addr().unwrap(),
215     ///            SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 34254)));
216     /// ```
217     #[stable(feature = "rust1", since = "1.0.0")]
218     pub fn local_addr(&self) -> io::Result<SocketAddr> {
219         self.0.socket_addr()
220     }
221
222     /// Creates a new independently owned handle to the underlying socket.
223     ///
224     /// The returned `UdpSocket` is a reference to the same socket that this
225     /// object references. Both handles will read and write the same port, and
226     /// options set on one socket will be propagated to the other.
227     ///
228     /// # Examples
229     ///
230     /// ```no_run
231     /// use std::net::UdpSocket;
232     ///
233     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
234     /// let socket_clone = socket.try_clone().expect("couldn't clone the socket");
235     /// ```
236     #[stable(feature = "rust1", since = "1.0.0")]
237     pub fn try_clone(&self) -> io::Result<UdpSocket> {
238         self.0.duplicate().map(UdpSocket)
239     }
240
241     /// Sets the read timeout to the timeout specified.
242     ///
243     /// If the value specified is [`None`], then [`read`] calls will block
244     /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
245     /// passed to this method.
246     ///
247     /// # Platform-specific behavior
248     ///
249     /// Platforms may return a different error code whenever a read times out as
250     /// a result of setting this option. For example Unix typically returns an
251     /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
252     ///
253     /// [`read`]: io::Read::read
254     /// [`WouldBlock`]: io::ErrorKind::WouldBlock
255     /// [`TimedOut`]: io::ErrorKind::TimedOut
256     ///
257     /// # Examples
258     ///
259     /// ```no_run
260     /// use std::net::UdpSocket;
261     ///
262     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
263     /// socket.set_read_timeout(None).expect("set_read_timeout call failed");
264     /// ```
265     ///
266     /// An [`Err`] is returned if the zero [`Duration`] is passed to this
267     /// method:
268     ///
269     /// ```no_run
270     /// use std::io;
271     /// use std::net::UdpSocket;
272     /// use std::time::Duration;
273     ///
274     /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
275     /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
276     /// let err = result.unwrap_err();
277     /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
278     /// ```
279     #[stable(feature = "socket_timeout", since = "1.4.0")]
280     pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
281         self.0.set_read_timeout(dur)
282     }
283
284     /// Sets the write timeout to the timeout specified.
285     ///
286     /// If the value specified is [`None`], then [`write`] calls will block
287     /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
288     /// passed to this method.
289     ///
290     /// # Platform-specific behavior
291     ///
292     /// Platforms may return a different error code whenever a write times out
293     /// as a result of setting this option. For example Unix typically returns
294     /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
295     ///
296     /// [`write`]: io::Write::write
297     /// [`WouldBlock`]: io::ErrorKind::WouldBlock
298     /// [`TimedOut`]: io::ErrorKind::TimedOut
299     ///
300     /// # Examples
301     ///
302     /// ```no_run
303     /// use std::net::UdpSocket;
304     ///
305     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
306     /// socket.set_write_timeout(None).expect("set_write_timeout call failed");
307     /// ```
308     ///
309     /// An [`Err`] is returned if the zero [`Duration`] is passed to this
310     /// method:
311     ///
312     /// ```no_run
313     /// use std::io;
314     /// use std::net::UdpSocket;
315     /// use std::time::Duration;
316     ///
317     /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
318     /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
319     /// let err = result.unwrap_err();
320     /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
321     /// ```
322     #[stable(feature = "socket_timeout", since = "1.4.0")]
323     pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
324         self.0.set_write_timeout(dur)
325     }
326
327     /// Returns the read timeout of this socket.
328     ///
329     /// If the timeout is [`None`], then [`read`] calls will block indefinitely.
330     ///
331     /// [`read`]: io::Read::read
332     ///
333     /// # Examples
334     ///
335     /// ```no_run
336     /// use std::net::UdpSocket;
337     ///
338     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
339     /// socket.set_read_timeout(None).expect("set_read_timeout call failed");
340     /// assert_eq!(socket.read_timeout().unwrap(), None);
341     /// ```
342     #[stable(feature = "socket_timeout", since = "1.4.0")]
343     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
344         self.0.read_timeout()
345     }
346
347     /// Returns the write timeout of this socket.
348     ///
349     /// If the timeout is [`None`], then [`write`] calls will block indefinitely.
350     ///
351     /// [`write`]: io::Write::write
352     ///
353     /// # Examples
354     ///
355     /// ```no_run
356     /// use std::net::UdpSocket;
357     ///
358     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
359     /// socket.set_write_timeout(None).expect("set_write_timeout call failed");
360     /// assert_eq!(socket.write_timeout().unwrap(), None);
361     /// ```
362     #[stable(feature = "socket_timeout", since = "1.4.0")]
363     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
364         self.0.write_timeout()
365     }
366
367     /// Sets the value of the `SO_BROADCAST` option for this socket.
368     ///
369     /// When enabled, this socket is allowed to send packets to a broadcast
370     /// address.
371     ///
372     /// # Examples
373     ///
374     /// ```no_run
375     /// use std::net::UdpSocket;
376     ///
377     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
378     /// socket.set_broadcast(false).expect("set_broadcast call failed");
379     /// ```
380     #[stable(feature = "net2_mutators", since = "1.9.0")]
381     pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
382         self.0.set_broadcast(broadcast)
383     }
384
385     /// Gets the value of the `SO_BROADCAST` option for this socket.
386     ///
387     /// For more information about this option, see [`UdpSocket::set_broadcast`].
388     ///
389     /// # Examples
390     ///
391     /// ```no_run
392     /// use std::net::UdpSocket;
393     ///
394     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
395     /// socket.set_broadcast(false).expect("set_broadcast call failed");
396     /// assert_eq!(socket.broadcast().unwrap(), false);
397     /// ```
398     #[stable(feature = "net2_mutators", since = "1.9.0")]
399     pub fn broadcast(&self) -> io::Result<bool> {
400         self.0.broadcast()
401     }
402
403     /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
404     ///
405     /// If enabled, multicast packets will be looped back to the local socket.
406     /// Note that this may not have any effect on IPv6 sockets.
407     ///
408     /// # Examples
409     ///
410     /// ```no_run
411     /// use std::net::UdpSocket;
412     ///
413     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
414     /// socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
415     /// ```
416     #[stable(feature = "net2_mutators", since = "1.9.0")]
417     pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
418         self.0.set_multicast_loop_v4(multicast_loop_v4)
419     }
420
421     /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
422     ///
423     /// For more information about this option, see [`UdpSocket::set_multicast_loop_v4`].
424     ///
425     /// # Examples
426     ///
427     /// ```no_run
428     /// use std::net::UdpSocket;
429     ///
430     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
431     /// socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
432     /// assert_eq!(socket.multicast_loop_v4().unwrap(), false);
433     /// ```
434     #[stable(feature = "net2_mutators", since = "1.9.0")]
435     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
436         self.0.multicast_loop_v4()
437     }
438
439     /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
440     ///
441     /// Indicates the time-to-live value of outgoing multicast packets for
442     /// this socket. The default value is 1 which means that multicast packets
443     /// don't leave the local network unless explicitly requested.
444     ///
445     /// Note that this may not have any effect on IPv6 sockets.
446     ///
447     /// # Examples
448     ///
449     /// ```no_run
450     /// use std::net::UdpSocket;
451     ///
452     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
453     /// socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
454     /// ```
455     #[stable(feature = "net2_mutators", since = "1.9.0")]
456     pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
457         self.0.set_multicast_ttl_v4(multicast_ttl_v4)
458     }
459
460     /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
461     ///
462     /// For more information about this option, see [`UdpSocket::set_multicast_ttl_v4`].
463     ///
464     /// # Examples
465     ///
466     /// ```no_run
467     /// use std::net::UdpSocket;
468     ///
469     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
470     /// socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
471     /// assert_eq!(socket.multicast_ttl_v4().unwrap(), 42);
472     /// ```
473     #[stable(feature = "net2_mutators", since = "1.9.0")]
474     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
475         self.0.multicast_ttl_v4()
476     }
477
478     /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
479     ///
480     /// Controls whether this socket sees the multicast packets it sends itself.
481     /// Note that this may not have any affect on IPv4 sockets.
482     ///
483     /// # Examples
484     ///
485     /// ```no_run
486     /// use std::net::UdpSocket;
487     ///
488     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
489     /// socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
490     /// ```
491     #[stable(feature = "net2_mutators", since = "1.9.0")]
492     pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
493         self.0.set_multicast_loop_v6(multicast_loop_v6)
494     }
495
496     /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
497     ///
498     /// For more information about this option, see [`UdpSocket::set_multicast_loop_v6`].
499     ///
500     /// # Examples
501     ///
502     /// ```no_run
503     /// use std::net::UdpSocket;
504     ///
505     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
506     /// socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
507     /// assert_eq!(socket.multicast_loop_v6().unwrap(), false);
508     /// ```
509     #[stable(feature = "net2_mutators", since = "1.9.0")]
510     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
511         self.0.multicast_loop_v6()
512     }
513
514     /// Sets the value for the `IP_TTL` option on this socket.
515     ///
516     /// This value sets the time-to-live field that is used in every packet sent
517     /// from this socket.
518     ///
519     /// # Examples
520     ///
521     /// ```no_run
522     /// use std::net::UdpSocket;
523     ///
524     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
525     /// socket.set_ttl(42).expect("set_ttl call failed");
526     /// ```
527     #[stable(feature = "net2_mutators", since = "1.9.0")]
528     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
529         self.0.set_ttl(ttl)
530     }
531
532     /// Gets the value of the `IP_TTL` option for this socket.
533     ///
534     /// For more information about this option, see [`UdpSocket::set_ttl`].
535     ///
536     /// # Examples
537     ///
538     /// ```no_run
539     /// use std::net::UdpSocket;
540     ///
541     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
542     /// socket.set_ttl(42).expect("set_ttl call failed");
543     /// assert_eq!(socket.ttl().unwrap(), 42);
544     /// ```
545     #[stable(feature = "net2_mutators", since = "1.9.0")]
546     pub fn ttl(&self) -> io::Result<u32> {
547         self.0.ttl()
548     }
549
550     /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
551     ///
552     /// This function specifies a new multicast group for this socket to join.
553     /// The address must be a valid multicast address, and `interface` is the
554     /// address of the local interface with which the system should join the
555     /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
556     /// interface is chosen by the system.
557     #[stable(feature = "net2_mutators", since = "1.9.0")]
558     pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
559         self.0.join_multicast_v4(multiaddr, interface)
560     }
561
562     /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
563     ///
564     /// This function specifies a new multicast group for this socket to join.
565     /// The address must be a valid multicast address, and `interface` is the
566     /// index of the interface to join/leave (or 0 to indicate any interface).
567     #[stable(feature = "net2_mutators", since = "1.9.0")]
568     pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
569         self.0.join_multicast_v6(multiaddr, interface)
570     }
571
572     /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
573     ///
574     /// For more information about this option, see [`UdpSocket::join_multicast_v4`].
575     #[stable(feature = "net2_mutators", since = "1.9.0")]
576     pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
577         self.0.leave_multicast_v4(multiaddr, interface)
578     }
579
580     /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
581     ///
582     /// For more information about this option, see [`UdpSocket::join_multicast_v6`].
583     #[stable(feature = "net2_mutators", since = "1.9.0")]
584     pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
585         self.0.leave_multicast_v6(multiaddr, interface)
586     }
587
588     /// Gets the value of the `SO_ERROR` option on this socket.
589     ///
590     /// This will retrieve the stored error in the underlying socket, clearing
591     /// the field in the process. This can be useful for checking errors between
592     /// calls.
593     ///
594     /// # Examples
595     ///
596     /// ```no_run
597     /// use std::net::UdpSocket;
598     ///
599     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
600     /// match socket.take_error() {
601     ///     Ok(Some(error)) => println!("UdpSocket error: {:?}", error),
602     ///     Ok(None) => println!("No error"),
603     ///     Err(error) => println!("UdpSocket.take_error failed: {:?}", error),
604     /// }
605     /// ```
606     #[stable(feature = "net2_mutators", since = "1.9.0")]
607     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
608         self.0.take_error()
609     }
610
611     /// Connects this UDP socket to a remote address, allowing the `send` and
612     /// `recv` syscalls to be used to send data and also applies filters to only
613     /// receive data from the specified address.
614     ///
615     /// If `addr` yields multiple addresses, `connect` will be attempted with
616     /// each of the addresses until the underlying OS function returns no
617     /// error. Note that usually, a successful `connect` call does not specify
618     /// that there is a remote server listening on the port, rather, such an
619     /// error would only be detected after the first send. If the OS returns an
620     /// error for each of the specified addresses, the error returned from the
621     /// last connection attempt (the last address) is returned.
622     ///
623     /// # Examples
624     ///
625     /// Creates a UDP socket bound to `127.0.0.1:3400` and connect the socket to
626     /// `127.0.0.1:8080`:
627     ///
628     /// ```no_run
629     /// use std::net::UdpSocket;
630     ///
631     /// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
632     /// socket.connect("127.0.0.1:8080").expect("connect function failed");
633     /// ```
634     ///
635     /// Unlike in the TCP case, passing an array of addresses to the `connect`
636     /// function of a UDP socket is not a useful thing to do: The OS will be
637     /// unable to determine whether something is listening on the remote
638     /// address without the application sending data.
639     #[stable(feature = "net2_mutators", since = "1.9.0")]
640     pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
641         super::each_addr(addr, |addr| self.0.connect(addr))
642     }
643
644     /// Sends data on the socket to the remote address to which it is connected.
645     ///
646     /// [`UdpSocket::connect`] will connect this socket to a remote address. This
647     /// method will fail if the socket is not connected.
648     ///
649     /// # Examples
650     ///
651     /// ```no_run
652     /// use std::net::UdpSocket;
653     ///
654     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
655     /// socket.connect("127.0.0.1:8080").expect("connect function failed");
656     /// socket.send(&[0, 1, 2]).expect("couldn't send message");
657     /// ```
658     #[stable(feature = "net2_mutators", since = "1.9.0")]
659     pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
660         self.0.send(buf)
661     }
662
663     /// Receives a single datagram message on the socket from the remote address to
664     /// which it is connected. On success, returns the number of bytes read.
665     ///
666     /// The function must be called with valid byte array `buf` of sufficient size to
667     /// hold the message bytes. If a message is too long to fit in the supplied buffer,
668     /// excess bytes may be discarded.
669     ///
670     /// [`UdpSocket::connect`] will connect this socket to a remote address. This
671     /// method will fail if the socket is not connected.
672     ///
673     /// # Examples
674     ///
675     /// ```no_run
676     /// use std::net::UdpSocket;
677     ///
678     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
679     /// socket.connect("127.0.0.1:8080").expect("connect function failed");
680     /// let mut buf = [0; 10];
681     /// match socket.recv(&mut buf) {
682     ///     Ok(received) => println!("received {} bytes {:?}", received, &buf[..received]),
683     ///     Err(e) => println!("recv function failed: {:?}", e),
684     /// }
685     /// ```
686     #[stable(feature = "net2_mutators", since = "1.9.0")]
687     pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
688         self.0.recv(buf)
689     }
690
691     /// Receives single datagram on the socket from the remote address to which it is
692     /// connected, without removing the message from input queue. On success, returns
693     /// the number of bytes peeked.
694     ///
695     /// The function must be called with valid byte array `buf` of sufficient size to
696     /// hold the message bytes. If a message is too long to fit in the supplied buffer,
697     /// excess bytes may be discarded.
698     ///
699     /// Successive calls return the same data. This is accomplished by passing
700     /// `MSG_PEEK` as a flag to the underlying `recv` system call.
701     ///
702     /// Do not use this function to implement busy waiting, instead use `libc::poll` to
703     /// synchronize IO events on one or more sockets.
704     ///
705     /// [`UdpSocket::connect`] will connect this socket to a remote address. This
706     /// method will fail if the socket is not connected.
707     ///
708     /// # Errors
709     ///
710     /// This method will fail if the socket is not connected. The `connect` method
711     /// will connect this socket to a remote address.
712     ///
713     /// # Examples
714     ///
715     /// ```no_run
716     /// use std::net::UdpSocket;
717     ///
718     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
719     /// socket.connect("127.0.0.1:8080").expect("connect function failed");
720     /// let mut buf = [0; 10];
721     /// match socket.peek(&mut buf) {
722     ///     Ok(received) => println!("received {} bytes", received),
723     ///     Err(e) => println!("peek function failed: {:?}", e),
724     /// }
725     /// ```
726     #[stable(feature = "peek", since = "1.18.0")]
727     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
728         self.0.peek(buf)
729     }
730
731     /// Moves this UDP socket into or out of nonblocking mode.
732     ///
733     /// This will result in `recv`, `recv_from`, `send`, and `send_to`
734     /// operations becoming nonblocking, i.e., immediately returning from their
735     /// calls. If the IO operation is successful, `Ok` is returned and no
736     /// further action is required. If the IO operation could not be completed
737     /// and needs to be retried, an error with kind
738     /// [`io::ErrorKind::WouldBlock`] is returned.
739     ///
740     /// On Unix platforms, calling this method corresponds to calling `fcntl`
741     /// `FIONBIO`. On Windows calling this method corresponds to calling
742     /// `ioctlsocket` `FIONBIO`.
743     ///
744     /// # Examples
745     ///
746     /// Creates a UDP socket bound to `127.0.0.1:7878` and read bytes in
747     /// nonblocking mode:
748     ///
749     /// ```no_run
750     /// use std::io;
751     /// use std::net::UdpSocket;
752     ///
753     /// let socket = UdpSocket::bind("127.0.0.1:7878").unwrap();
754     /// socket.set_nonblocking(true).unwrap();
755     ///
756     /// # fn wait_for_fd() { unimplemented!() }
757     /// let mut buf = [0; 10];
758     /// let (num_bytes_read, _) = loop {
759     ///     match socket.recv_from(&mut buf) {
760     ///         Ok(n) => break n,
761     ///         Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
762     ///             // wait until network socket is ready, typically implemented
763     ///             // via platform-specific APIs such as epoll or IOCP
764     ///             wait_for_fd();
765     ///         }
766     ///         Err(e) => panic!("encountered IO error: {}", e),
767     ///     }
768     /// };
769     /// println!("bytes: {:?}", &buf[..num_bytes_read]);
770     /// ```
771     #[stable(feature = "net2_mutators", since = "1.9.0")]
772     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
773         self.0.set_nonblocking(nonblocking)
774     }
775 }
776
777 impl AsInner<net_imp::UdpSocket> for UdpSocket {
778     fn as_inner(&self) -> &net_imp::UdpSocket {
779         &self.0
780     }
781 }
782
783 impl FromInner<net_imp::UdpSocket> for UdpSocket {
784     fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket {
785         UdpSocket(inner)
786     }
787 }
788
789 impl IntoInner<net_imp::UdpSocket> for UdpSocket {
790     fn into_inner(self) -> net_imp::UdpSocket {
791         self.0
792     }
793 }
794
795 #[stable(feature = "rust1", since = "1.0.0")]
796 impl fmt::Debug for UdpSocket {
797     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
798         self.0.fmt(f)
799     }
800 }
801
802 #[cfg(all(test, not(any(target_os = "cloudabi", target_os = "emscripten", target_env = "sgx"))))]
803 mod tests {
804     use crate::io::ErrorKind;
805     use crate::net::test::{next_test_ip4, next_test_ip6};
806     use crate::net::*;
807     use crate::sync::mpsc::channel;
808     use crate::sys_common::AsInner;
809     use crate::thread;
810     use crate::time::{Duration, Instant};
811
812     fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) {
813         f(next_test_ip4(), next_test_ip4());
814         f(next_test_ip6(), next_test_ip6());
815     }
816
817     macro_rules! t {
818         ($e:expr) => {
819             match $e {
820                 Ok(t) => t,
821                 Err(e) => panic!("received error for `{}`: {}", stringify!($e), e),
822             }
823         };
824     }
825
826     #[test]
827     fn bind_error() {
828         match UdpSocket::bind("1.1.1.1:9999") {
829             Ok(..) => panic!(),
830             Err(e) => assert_eq!(e.kind(), ErrorKind::AddrNotAvailable),
831         }
832     }
833
834     #[test]
835     fn socket_smoke_test_ip4() {
836         each_ip(&mut |server_ip, client_ip| {
837             let (tx1, rx1) = channel();
838             let (tx2, rx2) = channel();
839
840             let _t = thread::spawn(move || {
841                 let client = t!(UdpSocket::bind(&client_ip));
842                 rx1.recv().unwrap();
843                 t!(client.send_to(&[99], &server_ip));
844                 tx2.send(()).unwrap();
845             });
846
847             let server = t!(UdpSocket::bind(&server_ip));
848             tx1.send(()).unwrap();
849             let mut buf = [0];
850             let (nread, src) = t!(server.recv_from(&mut buf));
851             assert_eq!(nread, 1);
852             assert_eq!(buf[0], 99);
853             assert_eq!(src, client_ip);
854             rx2.recv().unwrap();
855         })
856     }
857
858     #[test]
859     fn socket_name() {
860         each_ip(&mut |addr, _| {
861             let server = t!(UdpSocket::bind(&addr));
862             assert_eq!(addr, t!(server.local_addr()));
863         })
864     }
865
866     #[test]
867     fn socket_peer() {
868         each_ip(&mut |addr1, addr2| {
869             let server = t!(UdpSocket::bind(&addr1));
870             assert_eq!(server.peer_addr().unwrap_err().kind(), ErrorKind::NotConnected);
871             t!(server.connect(&addr2));
872             assert_eq!(addr2, t!(server.peer_addr()));
873         })
874     }
875
876     #[test]
877     fn udp_clone_smoke() {
878         each_ip(&mut |addr1, addr2| {
879             let sock1 = t!(UdpSocket::bind(&addr1));
880             let sock2 = t!(UdpSocket::bind(&addr2));
881
882             let _t = thread::spawn(move || {
883                 let mut buf = [0, 0];
884                 assert_eq!(sock2.recv_from(&mut buf).unwrap(), (1, addr1));
885                 assert_eq!(buf[0], 1);
886                 t!(sock2.send_to(&[2], &addr1));
887             });
888
889             let sock3 = t!(sock1.try_clone());
890
891             let (tx1, rx1) = channel();
892             let (tx2, rx2) = channel();
893             let _t = thread::spawn(move || {
894                 rx1.recv().unwrap();
895                 t!(sock3.send_to(&[1], &addr2));
896                 tx2.send(()).unwrap();
897             });
898             tx1.send(()).unwrap();
899             let mut buf = [0, 0];
900             assert_eq!(sock1.recv_from(&mut buf).unwrap(), (1, addr2));
901             rx2.recv().unwrap();
902         })
903     }
904
905     #[test]
906     fn udp_clone_two_read() {
907         each_ip(&mut |addr1, addr2| {
908             let sock1 = t!(UdpSocket::bind(&addr1));
909             let sock2 = t!(UdpSocket::bind(&addr2));
910             let (tx1, rx) = channel();
911             let tx2 = tx1.clone();
912
913             let _t = thread::spawn(move || {
914                 t!(sock2.send_to(&[1], &addr1));
915                 rx.recv().unwrap();
916                 t!(sock2.send_to(&[2], &addr1));
917                 rx.recv().unwrap();
918             });
919
920             let sock3 = t!(sock1.try_clone());
921
922             let (done, rx) = channel();
923             let _t = thread::spawn(move || {
924                 let mut buf = [0, 0];
925                 t!(sock3.recv_from(&mut buf));
926                 tx2.send(()).unwrap();
927                 done.send(()).unwrap();
928             });
929             let mut buf = [0, 0];
930             t!(sock1.recv_from(&mut buf));
931             tx1.send(()).unwrap();
932
933             rx.recv().unwrap();
934         })
935     }
936
937     #[test]
938     fn udp_clone_two_write() {
939         each_ip(&mut |addr1, addr2| {
940             let sock1 = t!(UdpSocket::bind(&addr1));
941             let sock2 = t!(UdpSocket::bind(&addr2));
942
943             let (tx, rx) = channel();
944             let (serv_tx, serv_rx) = channel();
945
946             let _t = thread::spawn(move || {
947                 let mut buf = [0, 1];
948                 rx.recv().unwrap();
949                 t!(sock2.recv_from(&mut buf));
950                 serv_tx.send(()).unwrap();
951             });
952
953             let sock3 = t!(sock1.try_clone());
954
955             let (done, rx) = channel();
956             let tx2 = tx.clone();
957             let _t = thread::spawn(move || {
958                 match sock3.send_to(&[1], &addr2) {
959                     Ok(..) => {
960                         let _ = tx2.send(());
961                     }
962                     Err(..) => {}
963                 }
964                 done.send(()).unwrap();
965             });
966             match sock1.send_to(&[2], &addr2) {
967                 Ok(..) => {
968                     let _ = tx.send(());
969                 }
970                 Err(..) => {}
971             }
972             drop(tx);
973
974             rx.recv().unwrap();
975             serv_rx.recv().unwrap();
976         })
977     }
978
979     #[test]
980     fn debug() {
981         let name = if cfg!(windows) { "socket" } else { "fd" };
982         let socket_addr = next_test_ip4();
983
984         let udpsock = t!(UdpSocket::bind(&socket_addr));
985         let udpsock_inner = udpsock.0.socket().as_inner();
986         let compare =
987             format!("UdpSocket {{ addr: {:?}, {}: {:?} }}", socket_addr, name, udpsock_inner);
988         assert_eq!(format!("{:?}", udpsock), compare);
989     }
990
991     // FIXME: re-enabled openbsd/netbsd tests once their socket timeout code
992     //        no longer has rounding errors.
993     // VxWorks ignores SO_SNDTIMEO.
994     #[cfg_attr(any(target_os = "netbsd", target_os = "openbsd", target_os = "vxworks"), ignore)]
995     #[test]
996     fn timeouts() {
997         let addr = next_test_ip4();
998
999         let stream = t!(UdpSocket::bind(&addr));
1000         let dur = Duration::new(15410, 0);
1001
1002         assert_eq!(None, t!(stream.read_timeout()));
1003
1004         t!(stream.set_read_timeout(Some(dur)));
1005         assert_eq!(Some(dur), t!(stream.read_timeout()));
1006
1007         assert_eq!(None, t!(stream.write_timeout()));
1008
1009         t!(stream.set_write_timeout(Some(dur)));
1010         assert_eq!(Some(dur), t!(stream.write_timeout()));
1011
1012         t!(stream.set_read_timeout(None));
1013         assert_eq!(None, t!(stream.read_timeout()));
1014
1015         t!(stream.set_write_timeout(None));
1016         assert_eq!(None, t!(stream.write_timeout()));
1017     }
1018
1019     #[test]
1020     fn test_read_timeout() {
1021         let addr = next_test_ip4();
1022
1023         let stream = t!(UdpSocket::bind(&addr));
1024         t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
1025
1026         let mut buf = [0; 10];
1027
1028         let start = Instant::now();
1029         loop {
1030             let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
1031             if kind != ErrorKind::Interrupted {
1032                 assert!(
1033                     kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
1034                     "unexpected_error: {:?}",
1035                     kind
1036                 );
1037                 break;
1038             }
1039         }
1040         assert!(start.elapsed() > Duration::from_millis(400));
1041     }
1042
1043     #[test]
1044     fn test_read_with_timeout() {
1045         let addr = next_test_ip4();
1046
1047         let stream = t!(UdpSocket::bind(&addr));
1048         t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));
1049
1050         t!(stream.send_to(b"hello world", &addr));
1051
1052         let mut buf = [0; 11];
1053         t!(stream.recv_from(&mut buf));
1054         assert_eq!(b"hello world", &buf[..]);
1055
1056         let start = Instant::now();
1057         loop {
1058             let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
1059             if kind != ErrorKind::Interrupted {
1060                 assert!(
1061                     kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut,
1062                     "unexpected_error: {:?}",
1063                     kind
1064                 );
1065                 break;
1066             }
1067         }
1068         assert!(start.elapsed() > Duration::from_millis(400));
1069     }
1070
1071     // Ensure the `set_read_timeout` and `set_write_timeout` calls return errors
1072     // when passed zero Durations
1073     #[test]
1074     fn test_timeout_zero_duration() {
1075         let addr = next_test_ip4();
1076
1077         let socket = t!(UdpSocket::bind(&addr));
1078
1079         let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
1080         let err = result.unwrap_err();
1081         assert_eq!(err.kind(), ErrorKind::InvalidInput);
1082
1083         let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
1084         let err = result.unwrap_err();
1085         assert_eq!(err.kind(), ErrorKind::InvalidInput);
1086     }
1087
1088     #[test]
1089     fn connect_send_recv() {
1090         let addr = next_test_ip4();
1091
1092         let socket = t!(UdpSocket::bind(&addr));
1093         t!(socket.connect(addr));
1094
1095         t!(socket.send(b"hello world"));
1096
1097         let mut buf = [0; 11];
1098         t!(socket.recv(&mut buf));
1099         assert_eq!(b"hello world", &buf[..]);
1100     }
1101
1102     #[test]
1103     fn connect_send_peek_recv() {
1104         each_ip(&mut |addr, _| {
1105             let socket = t!(UdpSocket::bind(&addr));
1106             t!(socket.connect(addr));
1107
1108             t!(socket.send(b"hello world"));
1109
1110             for _ in 1..3 {
1111                 let mut buf = [0; 11];
1112                 let size = t!(socket.peek(&mut buf));
1113                 assert_eq!(b"hello world", &buf[..]);
1114                 assert_eq!(size, 11);
1115             }
1116
1117             let mut buf = [0; 11];
1118             let size = t!(socket.recv(&mut buf));
1119             assert_eq!(b"hello world", &buf[..]);
1120             assert_eq!(size, 11);
1121         })
1122     }
1123
1124     #[test]
1125     fn peek_from() {
1126         each_ip(&mut |addr, _| {
1127             let socket = t!(UdpSocket::bind(&addr));
1128             t!(socket.send_to(b"hello world", &addr));
1129
1130             for _ in 1..3 {
1131                 let mut buf = [0; 11];
1132                 let (size, _) = t!(socket.peek_from(&mut buf));
1133                 assert_eq!(b"hello world", &buf[..]);
1134                 assert_eq!(size, 11);
1135             }
1136
1137             let mut buf = [0; 11];
1138             let (size, _) = t!(socket.recv_from(&mut buf));
1139             assert_eq!(b"hello world", &buf[..]);
1140             assert_eq!(size, 11);
1141         })
1142     }
1143
1144     #[test]
1145     fn ttl() {
1146         let ttl = 100;
1147
1148         let addr = next_test_ip4();
1149
1150         let stream = t!(UdpSocket::bind(&addr));
1151
1152         t!(stream.set_ttl(ttl));
1153         assert_eq!(ttl, t!(stream.ttl()));
1154     }
1155
1156     #[test]
1157     fn set_nonblocking() {
1158         each_ip(&mut |addr, _| {
1159             let socket = t!(UdpSocket::bind(&addr));
1160
1161             t!(socket.set_nonblocking(true));
1162             t!(socket.set_nonblocking(false));
1163
1164             t!(socket.connect(addr));
1165
1166             t!(socket.set_nonblocking(false));
1167             t!(socket.set_nonblocking(true));
1168
1169             let mut buf = [0];
1170             match socket.recv(&mut buf) {
1171                 Ok(_) => panic!("expected error"),
1172                 Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
1173                 Err(e) => panic!("unexpected error {}", e),
1174             }
1175         })
1176     }
1177 }