]> git.lizzy.rs Git - rust.git/blob - src/libstd/io/net/udp.rs
Ignore tests broken by failing on ICE
[rust.git] / src / libstd / io / net / udp.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! UDP (User Datagram Protocol) network connections.
12 //!
13 //! This module contains the ability to open a UDP stream to a socket address.
14 //! The destination and binding addresses can either be an IPv4 or IPv6
15 //! address. There is no corresponding notion of a server because UDP is a
16 //! datagram protocol.
17
18 use clone::Clone;
19 use io::net::ip::SocketAddr;
20 use io::{Reader, Writer, IoResult};
21 use kinds::Send;
22 use result::{Ok, Err};
23 use rt::rtio::{RtioSocket, RtioUdpSocket, IoFactory, LocalIo};
24
25 /// A User Datagram Protocol socket.
26 ///
27 /// This is an implementation of a bound UDP socket. This supports both IPv4 and
28 /// IPv6 addresses, and there is no corresponding notion of a server because UDP
29 /// is a datagram protocol.
30 ///
31 /// # Example
32 ///
33 /// ```rust,no_run
34 /// # #![allow(unused_must_use)]
35 /// use std::io::net::udp::UdpSocket;
36 /// use std::io::net::ip::{Ipv4Addr, SocketAddr};
37 ///
38 /// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 34254 };
39 /// let mut socket = match UdpSocket::bind(addr) {
40 ///     Ok(s) => s,
41 ///     Err(e) => fail!("couldn't bind socket: {}", e),
42 /// };
43 ///
44 /// let mut buf = [0, ..10];
45 /// match socket.recvfrom(buf) {
46 ///     Ok((amt, src)) => {
47 ///         // Send a reply to the socket we received data from
48 ///         let buf = buf.mut_slice_to(amt);
49 ///         buf.reverse();
50 ///         socket.sendto(buf, src);
51 ///     }
52 ///     Err(e) => println!("couldn't receive a datagram: {}", e)
53 /// }
54 /// drop(socket); // close the socket
55 /// ```
56 pub struct UdpSocket {
57     obj: ~RtioUdpSocket:Send
58 }
59
60 impl UdpSocket {
61     /// Creates a UDP socket from the given socket address.
62     pub fn bind(addr: SocketAddr) -> IoResult<UdpSocket> {
63         LocalIo::maybe_raise(|io| {
64             io.udp_bind(addr).map(|s| UdpSocket { obj: s })
65         })
66     }
67
68     /// Receives data from the socket. On success, returns the number of bytes
69     /// read and the address from whence the data came.
70     pub fn recvfrom(&mut self, buf: &mut [u8])
71                     -> IoResult<(uint, SocketAddr)> {
72         self.obj.recvfrom(buf)
73     }
74
75     /// Sends data on the socket to the given address. Returns nothing on
76     /// success.
77     pub fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()> {
78         self.obj.sendto(buf, dst)
79     }
80
81     /// Creates a `UdpStream`, which allows use of the `Reader` and `Writer`
82     /// traits to receive and send data from the same address. This transfers
83     /// ownership of the socket to the stream.
84     ///
85     /// Note that this call does not perform any actual network communication,
86     /// because UDP is a datagram protocol.
87     pub fn connect(self, other: SocketAddr) -> UdpStream {
88         UdpStream {
89             socket: self,
90             connected_to: other,
91         }
92     }
93
94     /// Returns the socket address that this socket was created from.
95     pub fn socket_name(&mut self) -> IoResult<SocketAddr> {
96         self.obj.socket_name()
97     }
98 }
99
100 impl Clone for UdpSocket {
101     /// Creates a new handle to this UDP socket, allowing for simultaneous
102     /// reads and writes of the socket.
103     ///
104     /// The underlying UDP socket will not be closed until all handles to the
105     /// socket have been deallocated. Two concurrent reads will not receive
106     /// the same data. Instead, the first read will receive the first packet
107     /// received, and the second read will receive the second packet.
108     fn clone(&self) -> UdpSocket {
109         UdpSocket {
110             obj: self.obj.clone(),
111         }
112     }
113 }
114
115 /// A type that allows convenient usage of a UDP stream connected to one
116 /// address via the `Reader` and `Writer` traits.
117 pub struct UdpStream {
118     socket: UdpSocket,
119     connected_to: SocketAddr
120 }
121
122 impl UdpStream {
123     /// Allows access to the underlying UDP socket owned by this stream. This
124     /// is useful to, for example, use the socket to send data to hosts other
125     /// than the one that this stream is connected to.
126     pub fn as_socket<T>(&mut self, f: |&mut UdpSocket| -> T) -> T {
127         f(&mut self.socket)
128     }
129
130     /// Consumes this UDP stream and returns out the underlying socket.
131     pub fn disconnect(self) -> UdpSocket {
132         self.socket
133     }
134 }
135
136 impl Reader for UdpStream {
137     fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
138         let peer = self.connected_to;
139         self.as_socket(|sock| {
140             match sock.recvfrom(buf) {
141                 Ok((_nread, src)) if src != peer => Ok(0),
142                 Ok((nread, _src)) => Ok(nread),
143                 Err(e) => Err(e),
144             }
145         })
146     }
147 }
148
149 impl Writer for UdpStream {
150     fn write(&mut self, buf: &[u8]) -> IoResult<()> {
151         let connected_to = self.connected_to;
152         self.as_socket(|sock| sock.sendto(buf, connected_to))
153     }
154 }
155
156 #[cfg(test)]
157 mod test {
158     use super::*;
159     use io::net::ip::{SocketAddr};
160
161     // FIXME #11530 this fails on android because tests are run as root
162     iotest!(fn bind_error() {
163         let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 };
164         match UdpSocket::bind(addr) {
165             Ok(..) => fail!(),
166             Err(e) => assert_eq!(e.kind, PermissionDenied),
167         }
168     } #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))])
169
170     iotest!(fn socket_smoke_test_ip4() {
171         let server_ip = next_test_ip4();
172         let client_ip = next_test_ip4();
173         let (tx1, rx1) = channel();
174         let (tx2, rx2) = channel();
175
176         spawn(proc() {
177             match UdpSocket::bind(client_ip) {
178                 Ok(ref mut client) => {
179                     rx1.recv();
180                     client.sendto([99], server_ip).unwrap()
181                 }
182                 Err(..) => fail!()
183             }
184             tx2.send(());
185         });
186
187         match UdpSocket::bind(server_ip) {
188             Ok(ref mut server) => {
189                 tx1.send(());
190                 let mut buf = [0];
191                 match server.recvfrom(buf) {
192                     Ok((nread, src)) => {
193                         assert_eq!(nread, 1);
194                         assert_eq!(buf[0], 99);
195                         assert_eq!(src, client_ip);
196                     }
197                     Err(..) => fail!()
198                 }
199             }
200             Err(..) => fail!()
201         }
202         rx2.recv();
203     })
204
205     iotest!(fn socket_smoke_test_ip6() {
206         let server_ip = next_test_ip6();
207         let client_ip = next_test_ip6();
208         let (tx, rx) = channel::<()>();
209
210         spawn(proc() {
211             match UdpSocket::bind(client_ip) {
212                 Ok(ref mut client) => {
213                     rx.recv();
214                     client.sendto([99], server_ip).unwrap()
215                 }
216                 Err(..) => fail!()
217             }
218         });
219
220         match UdpSocket::bind(server_ip) {
221             Ok(ref mut server) => {
222                 tx.send(());
223                 let mut buf = [0];
224                 match server.recvfrom(buf) {
225                     Ok((nread, src)) => {
226                         assert_eq!(nread, 1);
227                         assert_eq!(buf[0], 99);
228                         assert_eq!(src, client_ip);
229                     }
230                     Err(..) => fail!()
231                 }
232             }
233             Err(..) => fail!()
234         }
235     })
236
237     iotest!(fn stream_smoke_test_ip4() {
238         let server_ip = next_test_ip4();
239         let client_ip = next_test_ip4();
240         let (tx1, rx1) = channel();
241         let (tx2, rx2) = channel();
242
243         spawn(proc() {
244             match UdpSocket::bind(client_ip) {
245                 Ok(client) => {
246                     let client = box client;
247                     let mut stream = client.connect(server_ip);
248                     rx1.recv();
249                     stream.write([99]).unwrap();
250                 }
251                 Err(..) => fail!()
252             }
253             tx2.send(());
254         });
255
256         match UdpSocket::bind(server_ip) {
257             Ok(server) => {
258                 let server = box server;
259                 let mut stream = server.connect(client_ip);
260                 tx1.send(());
261                 let mut buf = [0];
262                 match stream.read(buf) {
263                     Ok(nread) => {
264                         assert_eq!(nread, 1);
265                         assert_eq!(buf[0], 99);
266                     }
267                     Err(..) => fail!()
268                 }
269             }
270             Err(..) => fail!()
271         }
272         rx2.recv();
273     })
274
275     iotest!(fn stream_smoke_test_ip6() {
276         let server_ip = next_test_ip6();
277         let client_ip = next_test_ip6();
278         let (tx1, rx1) = channel();
279         let (tx2, rx2) = channel();
280
281         spawn(proc() {
282             match UdpSocket::bind(client_ip) {
283                 Ok(client) => {
284                     let client = box client;
285                     let mut stream = client.connect(server_ip);
286                     rx1.recv();
287                     stream.write([99]).unwrap();
288                 }
289                 Err(..) => fail!()
290             }
291             tx2.send(());
292         });
293
294         match UdpSocket::bind(server_ip) {
295             Ok(server) => {
296                 let server = box server;
297                 let mut stream = server.connect(client_ip);
298                 tx1.send(());
299                 let mut buf = [0];
300                 match stream.read(buf) {
301                     Ok(nread) => {
302                         assert_eq!(nread, 1);
303                         assert_eq!(buf[0], 99);
304                     }
305                     Err(..) => fail!()
306                 }
307             }
308             Err(..) => fail!()
309         }
310         rx2.recv();
311     })
312
313     pub fn socket_name(addr: SocketAddr) {
314         let server = UdpSocket::bind(addr);
315
316         assert!(server.is_ok());
317         let mut server = server.unwrap();
318
319         // Make sure socket_name gives
320         // us the socket we binded to.
321         let so_name = server.socket_name();
322         assert!(so_name.is_ok());
323         assert_eq!(addr, so_name.unwrap());
324     }
325
326     iotest!(fn socket_name_ip4() {
327         socket_name(next_test_ip4());
328     })
329
330     iotest!(fn socket_name_ip6() {
331         socket_name(next_test_ip6());
332     })
333
334     iotest!(fn udp_clone_smoke() {
335         let addr1 = next_test_ip4();
336         let addr2 = next_test_ip4();
337         let mut sock1 = UdpSocket::bind(addr1).unwrap();
338         let sock2 = UdpSocket::bind(addr2).unwrap();
339
340         spawn(proc() {
341             let mut sock2 = sock2;
342             let mut buf = [0, 0];
343             assert_eq!(sock2.recvfrom(buf), Ok((1, addr1)));
344             assert_eq!(buf[0], 1);
345             sock2.sendto([2], addr1).unwrap();
346         });
347
348         let sock3 = sock1.clone();
349
350         let (tx1, rx1) = channel();
351         let (tx2, rx2) = channel();
352         spawn(proc() {
353             let mut sock3 = sock3;
354             rx1.recv();
355             sock3.sendto([1], addr2).unwrap();
356             tx2.send(());
357         });
358         tx1.send(());
359         let mut buf = [0, 0];
360         assert_eq!(sock1.recvfrom(buf), Ok((1, addr2)));
361         rx2.recv();
362     })
363
364     iotest!(fn udp_clone_two_read() {
365         let addr1 = next_test_ip4();
366         let addr2 = next_test_ip4();
367         let mut sock1 = UdpSocket::bind(addr1).unwrap();
368         let sock2 = UdpSocket::bind(addr2).unwrap();
369         let (tx1, rx) = channel();
370         let tx2 = tx1.clone();
371
372         spawn(proc() {
373             let mut sock2 = sock2;
374             sock2.sendto([1], addr1).unwrap();
375             rx.recv();
376             sock2.sendto([2], addr1).unwrap();
377             rx.recv();
378         });
379
380         let sock3 = sock1.clone();
381
382         let (done, rx) = channel();
383         spawn(proc() {
384             let mut sock3 = sock3;
385             let mut buf = [0, 0];
386             sock3.recvfrom(buf).unwrap();
387             tx2.send(());
388             done.send(());
389         });
390         let mut buf = [0, 0];
391         sock1.recvfrom(buf).unwrap();
392         tx1.send(());
393
394         rx.recv();
395     })
396
397     iotest!(fn udp_clone_two_write() {
398         let addr1 = next_test_ip4();
399         let addr2 = next_test_ip4();
400         let mut sock1 = UdpSocket::bind(addr1).unwrap();
401         let sock2 = UdpSocket::bind(addr2).unwrap();
402
403         let (tx, rx) = channel();
404         let (serv_tx, serv_rx) = channel();
405
406         spawn(proc() {
407             let mut sock2 = sock2;
408             let mut buf = [0, 1];
409
410             rx.recv();
411             match sock2.recvfrom(buf) {
412                 Ok(..) => {}
413                 Err(e) => fail!("failed receive: {}", e),
414             }
415             serv_tx.send(());
416         });
417
418         let sock3 = sock1.clone();
419
420         let (done, rx) = channel();
421         let tx2 = tx.clone();
422         spawn(proc() {
423             let mut sock3 = sock3;
424             match sock3.sendto([1], addr2) {
425                 Ok(..) => { let _ = tx2.send_opt(()); }
426                 Err(..) => {}
427             }
428             done.send(());
429         });
430         match sock1.sendto([2], addr2) {
431             Ok(..) => { let _ = tx.send_opt(()); }
432             Err(..) => {}
433         }
434         drop(tx);
435
436         rx.recv();
437         serv_rx.recv();
438     })
439 }