1 #![warn(rust_2018_idioms)]
2 #![cfg(all(feature = "full", not(target_os = "wasi"), not(miri)))] // Wasi doesn't support bind
3                                                                    // No `socket` on miri.
4 
5 use tokio::net::{TcpListener, TcpStream};
6 use tokio::sync::oneshot;
7 use tokio_test::assert_ok;
8 
9 use futures::join;
10 
11 #[tokio::test]
connect_v4()12 async fn connect_v4() {
13     let srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
14     let addr = assert_ok!(srv.local_addr());
15     assert!(addr.is_ipv4());
16 
17     let (tx, rx) = oneshot::channel();
18 
19     tokio::spawn(async move {
20         let (socket, addr) = assert_ok!(srv.accept().await);
21         assert_eq!(addr, assert_ok!(socket.peer_addr()));
22         assert_ok!(tx.send(socket));
23     });
24 
25     let mine = assert_ok!(TcpStream::connect(&addr).await);
26     let theirs = assert_ok!(rx.await);
27 
28     assert_eq!(
29         assert_ok!(mine.local_addr()),
30         assert_ok!(theirs.peer_addr())
31     );
32     assert_eq!(
33         assert_ok!(theirs.local_addr()),
34         assert_ok!(mine.peer_addr())
35     );
36 }
37 
38 #[tokio::test]
connect_v6()39 async fn connect_v6() {
40     let srv = assert_ok!(TcpListener::bind("[::1]:0").await);
41     let addr = assert_ok!(srv.local_addr());
42     assert!(addr.is_ipv6());
43 
44     let (tx, rx) = oneshot::channel();
45 
46     tokio::spawn(async move {
47         let (socket, addr) = assert_ok!(srv.accept().await);
48         assert_eq!(addr, assert_ok!(socket.peer_addr()));
49         assert_ok!(tx.send(socket));
50     });
51 
52     let mine = assert_ok!(TcpStream::connect(&addr).await);
53     let theirs = assert_ok!(rx.await);
54 
55     assert_eq!(
56         assert_ok!(mine.local_addr()),
57         assert_ok!(theirs.peer_addr())
58     );
59     assert_eq!(
60         assert_ok!(theirs.local_addr()),
61         assert_ok!(mine.peer_addr())
62     );
63 }
64 
65 #[tokio::test]
connect_addr_ip_string()66 async fn connect_addr_ip_string() {
67     let srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
68     let addr = assert_ok!(srv.local_addr());
69     let addr = format!("127.0.0.1:{}", addr.port());
70 
71     let server = async {
72         assert_ok!(srv.accept().await);
73     };
74 
75     let client = async {
76         assert_ok!(TcpStream::connect(addr).await);
77     };
78 
79     join!(server, client);
80 }
81 
82 #[tokio::test]
connect_addr_ip_str_slice()83 async fn connect_addr_ip_str_slice() {
84     let srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
85     let addr = assert_ok!(srv.local_addr());
86     let addr = format!("127.0.0.1:{}", addr.port());
87 
88     let server = async {
89         assert_ok!(srv.accept().await);
90     };
91 
92     let client = async {
93         assert_ok!(TcpStream::connect(&addr[..]).await);
94     };
95 
96     join!(server, client);
97 }
98 
99 #[tokio::test]
connect_addr_host_string()100 async fn connect_addr_host_string() {
101     let srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
102     let addr = assert_ok!(srv.local_addr());
103     let addr = format!("localhost:{}", addr.port());
104 
105     let server = async {
106         assert_ok!(srv.accept().await);
107     };
108 
109     let client = async {
110         assert_ok!(TcpStream::connect(addr).await);
111     };
112 
113     join!(server, client);
114 }
115 
116 #[tokio::test]
connect_addr_ip_port_tuple()117 async fn connect_addr_ip_port_tuple() {
118     let srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
119     let addr = assert_ok!(srv.local_addr());
120     let addr = (addr.ip(), addr.port());
121 
122     let server = async {
123         assert_ok!(srv.accept().await);
124     };
125 
126     let client = async {
127         assert_ok!(TcpStream::connect(&addr).await);
128     };
129 
130     join!(server, client);
131 }
132 
133 #[tokio::test]
connect_addr_ip_str_port_tuple()134 async fn connect_addr_ip_str_port_tuple() {
135     let srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
136     let addr = assert_ok!(srv.local_addr());
137     let addr = ("127.0.0.1", addr.port());
138 
139     let server = async {
140         assert_ok!(srv.accept().await);
141     };
142 
143     let client = async {
144         assert_ok!(TcpStream::connect(&addr).await);
145     };
146 
147     join!(server, client);
148 }
149 
150 #[tokio::test]
connect_addr_host_str_port_tuple()151 async fn connect_addr_host_str_port_tuple() {
152     let srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
153     let addr = assert_ok!(srv.local_addr());
154     let addr = ("localhost", addr.port());
155 
156     let server = async {
157         assert_ok!(srv.accept().await);
158     };
159 
160     let client = async {
161         assert_ok!(TcpStream::connect(&addr).await);
162     };
163 
164     join!(server, client);
165 }
166 
167 /*
168  * TODO: bring this back once TCP exposes HUP again
169  *
170 #[cfg(target_os = "linux")]
171 mod linux {
172     use tokio::net::{TcpListener, TcpStream};
173     use tokio::io::{AsyncReadExt, AsyncWriteExt};
174     use tokio_test::assert_ok;
175 
176     use mio::unix::UnixReady;
177 
178     use futures_util::future::poll_fn;
179     use std::io::Write;
180     use std::time::Duration;
181     use std::{net, thread};
182 
183     #[tokio::test]
184     fn poll_hup() {
185         let addr = assert_ok!("127.0.0.1:0".parse());
186         let mut srv = assert_ok!(TcpListener::bind(&addr));
187         let addr = assert_ok!(srv.local_addr());
188 
189         tokio::spawn(async move {
190             let (mut client, _) = assert_ok!(srv.accept().await);
191             assert_ok!(client.set_linger(Some(Duration::from_millis(0))));
192             assert_ok!(client.write_all(b"hello world").await);
193 
194             // TODO: Drop?
195         });
196 
197         /*
198         let t = thread::spawn(move || {
199             let mut client = assert_ok!(srv.accept()).0;
200             client.set_linger(Some(Duration::from_millis(0))).unwrap();
201             client.write(b"hello world").unwrap();
202             thread::sleep(Duration::from_millis(200));
203         });
204         */
205 
206         let mut stream = assert_ok!(TcpStream::connect(&addr).await);
207 
208         // Poll for HUP before reading.
209         future::poll_fn(|| stream.poll_read_ready(UnixReady::hup().into()))
210             .wait()
211             .unwrap();
212 
213         // Same for write half
214         future::poll_fn(|| stream.poll_write_ready())
215             .wait()
216             .unwrap();
217 
218         let mut buf = vec![0; 11];
219 
220         // Read the data
221         future::poll_fn(|| stream.poll_read(&mut buf))
222             .wait()
223             .unwrap();
224 
225         assert_eq!(b"hello world", &buf[..]);
226 
227         t.join().unwrap();
228     }
229 }
230 */
231