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