mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-08 00:00:13 +02:00
net: perform DNS lookup on connect / bind. (#1499)
A sealed `net::ToSocketAddrs` trait is added. This trait is not intended to be used by users. Instead, it is an argument to `connect` and `bind` functions. The operating system's DNS lookup functionality is used. Blocking operations are performed on a thread pool in order to avoid blocking the runtime.
This commit is contained in:
@@ -4,21 +4,36 @@ use tokio::net::{TcpListener, TcpStream};
|
||||
use tokio::sync::oneshot;
|
||||
use tokio_test::assert_ok;
|
||||
|
||||
#[tokio::test]
|
||||
async fn accept() {
|
||||
let addr = "127.0.0.1:0".parse().unwrap();
|
||||
let mut listener = assert_ok!(TcpListener::bind(&addr));
|
||||
let addr = listener.local_addr().unwrap();
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
macro_rules! test_accept {
|
||||
($(($ident:ident, $target:expr),)*) => {
|
||||
$(
|
||||
#[tokio::test]
|
||||
async fn $ident() {
|
||||
let mut listener = assert_ok!(TcpListener::bind($target).await);
|
||||
let addr = listener.local_addr().unwrap();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let (socket, _) = assert_ok!(listener.accept().await);
|
||||
assert_ok!(tx.send(socket));
|
||||
});
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
let cli = assert_ok!(TcpStream::connect(&addr).await);
|
||||
let srv = assert_ok!(rx.await);
|
||||
tokio::spawn(async move {
|
||||
let (socket, _) = assert_ok!(listener.accept().await);
|
||||
assert_ok!(tx.send(socket));
|
||||
});
|
||||
|
||||
assert_eq!(cli.local_addr().unwrap(), srv.peer_addr().unwrap());
|
||||
let cli = assert_ok!(TcpStream::connect(&addr).await);
|
||||
let srv = assert_ok!(rx.await);
|
||||
|
||||
assert_eq!(cli.local_addr().unwrap(), srv.peer_addr().unwrap());
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
test_accept! {
|
||||
(ip_str, "127.0.0.1:0"),
|
||||
(host_str, "localhost:0"),
|
||||
(socket_addr, "127.0.0.1:0".parse::<SocketAddr>().unwrap()),
|
||||
(str_port_tuple, ("127.0.0.1", 0)),
|
||||
(ip_port_tuple, ("127.0.0.1".parse::<IpAddr>().unwrap(), 0)),
|
||||
}
|
||||
|
||||
@@ -4,11 +4,13 @@ use tokio::net::{TcpListener, TcpStream};
|
||||
use tokio::sync::oneshot;
|
||||
use tokio_test::assert_ok;
|
||||
|
||||
use futures::join;
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect() {
|
||||
let addr = assert_ok!("127.0.0.1:0".parse());
|
||||
let mut srv = assert_ok!(TcpListener::bind(&addr));
|
||||
async fn connect_v4() {
|
||||
let mut srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
let addr = assert_ok!(srv.local_addr());
|
||||
assert!(addr.is_ipv4());
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
@@ -31,6 +33,135 @@ async fn connect() {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect_v6() {
|
||||
let mut srv = assert_ok!(TcpListener::bind("[::1]:0").await);
|
||||
let addr = assert_ok!(srv.local_addr());
|
||||
assert!(addr.is_ipv6());
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let (socket, addr) = assert_ok!(srv.accept().await);
|
||||
assert_eq!(addr, assert_ok!(socket.peer_addr()));
|
||||
assert_ok!(tx.send(socket));
|
||||
});
|
||||
|
||||
let mine = assert_ok!(TcpStream::connect(&addr).await);
|
||||
let theirs = assert_ok!(rx.await);
|
||||
|
||||
assert_eq!(
|
||||
assert_ok!(mine.local_addr()),
|
||||
assert_ok!(theirs.peer_addr())
|
||||
);
|
||||
assert_eq!(
|
||||
assert_ok!(theirs.local_addr()),
|
||||
assert_ok!(mine.peer_addr())
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect_addr_ip_string() {
|
||||
let mut srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
let addr = assert_ok!(srv.local_addr());
|
||||
let addr = format!("127.0.0.1:{}", addr.port());
|
||||
|
||||
let server = async {
|
||||
assert_ok!(srv.accept().await);
|
||||
};
|
||||
|
||||
let client = async {
|
||||
assert_ok!(TcpStream::connect(addr).await);
|
||||
};
|
||||
|
||||
join!(server, client);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect_addr_ip_str_slice() {
|
||||
let mut srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
let addr = assert_ok!(srv.local_addr());
|
||||
let addr = format!("127.0.0.1:{}", addr.port());
|
||||
|
||||
let server = async {
|
||||
assert_ok!(srv.accept().await);
|
||||
};
|
||||
|
||||
let client = async {
|
||||
assert_ok!(TcpStream::connect(&addr[..]).await);
|
||||
};
|
||||
|
||||
join!(server, client);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect_addr_host_string() {
|
||||
let mut srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
let addr = assert_ok!(srv.local_addr());
|
||||
let addr = format!("localhost:{}", addr.port());
|
||||
|
||||
let server = async {
|
||||
assert_ok!(srv.accept().await);
|
||||
};
|
||||
|
||||
let client = async {
|
||||
assert_ok!(TcpStream::connect(addr).await);
|
||||
};
|
||||
|
||||
join!(server, client);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect_addr_ip_port_tuple() {
|
||||
let mut srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
let addr = assert_ok!(srv.local_addr());
|
||||
let addr = (addr.ip(), addr.port());
|
||||
|
||||
let server = async {
|
||||
assert_ok!(srv.accept().await);
|
||||
};
|
||||
|
||||
let client = async {
|
||||
assert_ok!(TcpStream::connect(&addr).await);
|
||||
};
|
||||
|
||||
join!(server, client);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect_addr_ip_str_port_tuple() {
|
||||
let mut srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
let addr = assert_ok!(srv.local_addr());
|
||||
let addr = ("127.0.0.1", addr.port());
|
||||
|
||||
let server = async {
|
||||
assert_ok!(srv.accept().await);
|
||||
};
|
||||
|
||||
let client = async {
|
||||
assert_ok!(TcpStream::connect(&addr).await);
|
||||
};
|
||||
|
||||
join!(server, client);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn connect_addr_host_str_port_tuple() {
|
||||
let mut srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
let addr = assert_ok!(srv.local_addr());
|
||||
let addr = ("localhost", addr.port());
|
||||
|
||||
let server = async {
|
||||
assert_ok!(srv.accept().await);
|
||||
};
|
||||
|
||||
let client = async {
|
||||
assert_ok!(TcpStream::connect(&addr).await);
|
||||
};
|
||||
|
||||
join!(server, client);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: bring this back once TCP exposes HUP again
|
||||
*
|
||||
|
||||
@@ -11,8 +11,7 @@ async fn echo_server() {
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
let addr = assert_ok!("127.0.0.1:0".parse());
|
||||
let mut srv = assert_ok!(TcpListener::bind(&addr));
|
||||
let mut srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
let addr = assert_ok!(srv.local_addr());
|
||||
|
||||
let msg = "foo bar baz";
|
||||
|
||||
@@ -7,8 +7,7 @@ use tokio_test::assert_ok;
|
||||
|
||||
#[tokio::test]
|
||||
async fn shutdown() {
|
||||
let addr = assert_ok!("127.0.0.1:0".parse());
|
||||
let mut srv = assert_ok!(TcpListener::bind(&addr));
|
||||
let mut srv = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
let addr = assert_ok!(srv.local_addr());
|
||||
|
||||
tokio::spawn(async move {
|
||||
|
||||
@@ -2,7 +2,7 @@ use tokio_net::tcp::{TcpListener, TcpStream};
|
||||
|
||||
#[tokio::test]
|
||||
async fn split_reunite() -> std::io::Result<()> {
|
||||
let listener = TcpListener::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await?;
|
||||
let addr = listener.local_addr()?;
|
||||
let stream = TcpStream::connect(&addr).await?;
|
||||
|
||||
@@ -13,7 +13,7 @@ async fn split_reunite() -> std::io::Result<()> {
|
||||
|
||||
#[tokio::test]
|
||||
async fn split_reunite_error() -> std::io::Result<()> {
|
||||
let listener = TcpListener::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await?;
|
||||
let addr = listener.local_addr()?;
|
||||
let stream = TcpStream::connect(&addr).await?;
|
||||
let stream1 = TcpStream::connect(&addr).await?;
|
||||
|
||||
+12
-12
@@ -9,11 +9,11 @@ use std::io;
|
||||
|
||||
#[tokio::test]
|
||||
async fn send_recv() -> std::io::Result<()> {
|
||||
let mut sender = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let mut receiver = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let mut sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let mut receiver = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
|
||||
sender.connect(&receiver.local_addr()?)?;
|
||||
receiver.connect(&sender.local_addr()?)?;
|
||||
sender.connect(receiver.local_addr()?).await?;
|
||||
receiver.connect(sender.local_addr()?).await?;
|
||||
|
||||
let message = b"hello!";
|
||||
sender.send(message).await?;
|
||||
@@ -27,8 +27,8 @@ async fn send_recv() -> std::io::Result<()> {
|
||||
|
||||
#[tokio::test]
|
||||
async fn send_to_recv_from() -> std::io::Result<()> {
|
||||
let mut sender = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let mut receiver = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let mut sender = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let mut receiver = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
|
||||
let message = b"hello!";
|
||||
let receiver_addr = receiver.local_addr()?;
|
||||
@@ -44,7 +44,7 @@ async fn send_to_recv_from() -> std::io::Result<()> {
|
||||
|
||||
#[tokio::test]
|
||||
async fn split() -> std::io::Result<()> {
|
||||
let socket = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let socket = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let (mut r, mut s) = socket.split();
|
||||
|
||||
let msg = b"hello";
|
||||
@@ -60,7 +60,7 @@ async fn split() -> std::io::Result<()> {
|
||||
|
||||
#[tokio::test]
|
||||
async fn reunite() -> std::io::Result<()> {
|
||||
let socket = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let socket = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let (s, r) = socket.split();
|
||||
assert!(s.reunite(r).is_ok());
|
||||
Ok(())
|
||||
@@ -68,8 +68,8 @@ async fn reunite() -> std::io::Result<()> {
|
||||
|
||||
#[tokio::test]
|
||||
async fn reunite_error() -> std::io::Result<()> {
|
||||
let socket = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let socket1 = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let socket = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let socket1 = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let (s, _) = socket.split();
|
||||
let (_, r1) = socket1.split();
|
||||
assert!(s.reunite(r1).is_err());
|
||||
@@ -101,8 +101,8 @@ impl Encoder for ByteCodec {
|
||||
|
||||
#[tokio::test]
|
||||
async fn send_framed() -> std::io::Result<()> {
|
||||
let mut a_soc = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let mut b_soc = UdpSocket::bind(&"127.0.0.1:0".parse().unwrap())?;
|
||||
let mut a_soc = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
let mut b_soc = UdpSocket::bind("127.0.0.1:0").await?;
|
||||
|
||||
let a_addr = a_soc.local_addr()?;
|
||||
let b_addr = b_soc.local_addr()?;
|
||||
|
||||
Reference in New Issue
Block a user