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