1#![warn(rust_2018_idioms)]
2#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi doesn't support bind
3
4use tokio::net::{TcpListener, TcpStream};
5use tokio::sync::oneshot;
6use tokio_test::assert_ok;
7
8use futures::join;
9
10#[tokio::test]
11async 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]
38async 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]
65async 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]
82async 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]
99async 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]
116async 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]
133async 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]
150async 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")]
170mod 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