| 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 | |