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:
@@ -45,12 +45,11 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let state = Lock::new(Shared::new());
|
||||
|
||||
let addr = env::args().nth(1).unwrap_or("127.0.0.1:6142".to_string());
|
||||
let addr = addr.parse::<SocketAddr>()?;
|
||||
|
||||
// Bind a TCP listener to the socket address.
|
||||
//
|
||||
// Note that this is the Tokio TcpListener, which is fully async.
|
||||
let mut listener = TcpListener::bind(&addr)?;
|
||||
let mut listener = TcpListener::bind(&addr).await?;
|
||||
|
||||
println!("server running on {}", addr);
|
||||
|
||||
|
||||
@@ -126,13 +126,13 @@ mod udp {
|
||||
// We'll bind our UDP socket to a local IP/port, but for now we
|
||||
// basically let the OS pick both of those.
|
||||
let bind_addr = if addr.ip().is_ipv4() {
|
||||
"0.0.0.0:0".parse()?
|
||||
"0.0.0.0:0"
|
||||
} else {
|
||||
"[::]:0".parse()?
|
||||
"[::]:0"
|
||||
};
|
||||
|
||||
let socket = UdpSocket::bind(&bind_addr)?;
|
||||
socket.connect(addr)?;
|
||||
let socket = UdpSocket::bind(&bind_addr).await?;
|
||||
socket.connect(addr).await?;
|
||||
let (mut r, mut w) = socket.split();
|
||||
|
||||
future::try_join(send(stdin, &mut w), recv(stdout, &mut r)).await?;
|
||||
|
||||
@@ -52,9 +52,8 @@ impl Server {
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
|
||||
let addr = addr.parse::<SocketAddr>()?;
|
||||
|
||||
let socket = UdpSocket::bind(&addr)?;
|
||||
let socket = UdpSocket::bind(&addr).await?;
|
||||
println!("Listening on: {}", socket.local_addr()?);
|
||||
|
||||
let server = Server {
|
||||
|
||||
@@ -27,7 +27,6 @@ use tokio::net::TcpListener;
|
||||
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
@@ -35,12 +34,11 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
// program, but otherwise we'll just set up our TCP listener on
|
||||
// 127.0.0.1:8080 for connections.
|
||||
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
|
||||
let addr = addr.parse::<SocketAddr>()?;
|
||||
|
||||
// Next up we create a TCP listener which will listen for incoming
|
||||
// connections. This TCP listener is bound to the address we determined
|
||||
// above and must be associated with an event loop.
|
||||
let mut listener = TcpListener::bind(&addr)?;
|
||||
let mut listener = TcpListener::bind(&addr).await?;
|
||||
println!("Listening on: {}", addr);
|
||||
|
||||
loop {
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use tokio;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
@@ -21,12 +20,10 @@ use std::error::Error;
|
||||
|
||||
#[tokio::main]
|
||||
pub async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let addr = "127.0.0.1:6142".parse()?;
|
||||
|
||||
// Open a TCP stream to the socket address.
|
||||
//
|
||||
// Note that this is the Tokio TcpStream, which is fully async.
|
||||
let mut stream = TcpStream::connect(&addr).await?;
|
||||
let mut stream = TcpStream::connect("127.0.0.1:6142").await?;
|
||||
println!("created stream");
|
||||
|
||||
let result = stream.write(b"hello world\n").await;
|
||||
|
||||
@@ -54,28 +54,26 @@
|
||||
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use std::env;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use tokio;
|
||||
use tokio::codec::{BytesCodec, Decoder};
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::prelude::*;
|
||||
|
||||
use std::env;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Allow passing an address to listen on as the first argument of this
|
||||
// program, but otherwise we'll just set up our TCP listener on
|
||||
// 127.0.0.1:8080 for connections.
|
||||
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
|
||||
let addr = addr.parse::<SocketAddr>()?;
|
||||
|
||||
// Next up we create a TCP listener which will listen for incoming
|
||||
// connections. This TCP listener is bound to the address we determined
|
||||
// above and must be associated with an event loop, so we pass in a handle
|
||||
// to our event loop. After the socket's created we inform that we're ready
|
||||
// to go and start accepting connections.
|
||||
let mut listener = TcpListener::bind(&addr)?;
|
||||
let mut listener = TcpListener::bind(&addr).await?;
|
||||
println!("Listening on: {}", addr);
|
||||
|
||||
loop {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use futures::{future::try_join, FutureExt, StreamExt};
|
||||
use std::{env, error::Error, net::SocketAddr};
|
||||
use std::{env, error::Error};
|
||||
use tokio::{
|
||||
io::AsyncReadExt,
|
||||
net::{TcpListener, TcpStream},
|
||||
@@ -32,18 +32,15 @@ use tokio::{
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let listen_addr = env::args().nth(1).unwrap_or("127.0.0.1:8081".to_string());
|
||||
let listen_addr = listen_addr.parse::<SocketAddr>()?;
|
||||
|
||||
let server_addr = env::args().nth(2).unwrap_or("127.0.0.1:8080".to_string());
|
||||
let server_addr = server_addr.parse::<SocketAddr>()?;
|
||||
|
||||
println!("Listening on: {}", listen_addr);
|
||||
println!("Proxying to: {}", server_addr);
|
||||
|
||||
let mut incoming = TcpListener::bind(&listen_addr)?.incoming();
|
||||
let mut incoming = TcpListener::bind(listen_addr).await?.incoming();
|
||||
|
||||
while let Some(Ok(inbound)) = incoming.next().await {
|
||||
let transfer = transfer(inbound, server_addr).map(|r| {
|
||||
let transfer = transfer(inbound, server_addr.clone()).map(|r| {
|
||||
if let Err(e) = r {
|
||||
println!("Failed to transfer; error={}", e);
|
||||
}
|
||||
@@ -55,8 +52,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn transfer(inbound: TcpStream, proxy_addr: SocketAddr) -> Result<(), Box<dyn Error>> {
|
||||
let outbound = TcpStream::connect(&proxy_addr).await?;
|
||||
async fn transfer(inbound: TcpStream, proxy_addr: String) -> Result<(), Box<dyn Error>> {
|
||||
let outbound = TcpStream::connect(proxy_addr).await?;
|
||||
|
||||
let (mut ri, mut wi) = inbound.split();
|
||||
let (mut ro, mut wo) = outbound.split();
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use tokio;
|
||||
@@ -88,8 +87,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
// Parse the address we're going to run this server on
|
||||
// and set up our TCP listener to accept connections.
|
||||
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
|
||||
let addr = addr.parse::<SocketAddr>()?;
|
||||
let mut listener = TcpListener::bind(&addr)?;
|
||||
|
||||
let mut listener = TcpListener::bind(&addr).await?;
|
||||
println!("Listening on: {}", addr);
|
||||
|
||||
// Create the shared state of this server that will be shared amongst all
|
||||
|
||||
@@ -17,7 +17,7 @@ use bytes::BytesMut;
|
||||
use futures::{SinkExt, StreamExt};
|
||||
use http::{header::HeaderValue, Request, Response, StatusCode};
|
||||
use serde::Serialize;
|
||||
use std::{env, error::Error, fmt, io, net::SocketAddr};
|
||||
use std::{env, error::Error, fmt, io};
|
||||
use tokio::{
|
||||
codec::{Decoder, Encoder, Framed},
|
||||
net::{TcpListener, TcpStream},
|
||||
@@ -28,9 +28,8 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
// Parse the arguments, bind the TCP socket we'll be listening to, spin up
|
||||
// our worker threads, and start shipping sockets to those worker threads.
|
||||
let addr = env::args().nth(1).unwrap_or("127.0.0.1:8080".to_string());
|
||||
let addr = addr.parse::<SocketAddr>()?;
|
||||
|
||||
let mut incoming = TcpListener::bind(&addr)?.incoming();
|
||||
let mut incoming = TcpListener::bind(&addr).await?.incoming();
|
||||
println!("Listening on: {}", addr);
|
||||
|
||||
while let Some(Ok(stream)) = incoming.next().await {
|
||||
|
||||
@@ -55,9 +55,9 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
.parse()?;
|
||||
|
||||
let mut socket = UdpSocket::bind(&local_addr)?;
|
||||
let mut socket = UdpSocket::bind(local_addr).await?;
|
||||
const MAX_DATAGRAM_SIZE: usize = 65_507;
|
||||
socket.connect(&remote_addr)?;
|
||||
socket.connect(&remote_addr).await?;
|
||||
let data = get_stdin_data()?;
|
||||
socket.send(&data).await?;
|
||||
let mut data = vec![0u8; MAX_DATAGRAM_SIZE];
|
||||
|
||||
@@ -27,11 +27,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
let _ = env_logger::init();
|
||||
|
||||
let addr = env::args().nth(1).unwrap_or("127.0.0.1:0".to_string());
|
||||
let addr = addr.parse::<SocketAddr>()?;
|
||||
|
||||
// Bind both our sockets and then figure out what ports we got.
|
||||
let a = UdpSocket::bind(&addr)?;
|
||||
let b = UdpSocket::bind(&addr)?;
|
||||
let a = UdpSocket::bind(&addr).await?;
|
||||
let b = UdpSocket::bind(&addr).await?;
|
||||
|
||||
let b_addr = b.local_addr()?;
|
||||
|
||||
|
||||
@@ -73,8 +73,7 @@ pub struct Spawn(());
|
||||
///
|
||||
/// # async fn process<T>(t: T) {}
|
||||
/// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
|
||||
/// let addr = "127.0.0.1:8080".parse()?;
|
||||
/// let mut listener = TcpListener::bind(&addr).unwrap();
|
||||
/// let mut listener = TcpListener::bind("127.0.0.1:8080").await?;
|
||||
///
|
||||
/// loop {
|
||||
/// let (socket, _) = listener.accept().await?;
|
||||
@@ -84,7 +83,6 @@ pub struct Spawn(());
|
||||
/// process(socket).await
|
||||
/// });
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
|
||||
+1
-2
@@ -35,8 +35,7 @@
|
||||
//!
|
||||
//! #[tokio::main]
|
||||
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! let addr = "127.0.0.1:8080".parse()?;
|
||||
//! let mut listener = TcpListener::bind(&addr).unwrap();
|
||||
//! let mut listener = TcpListener::bind("127.0.0.1:8080").await?;
|
||||
//!
|
||||
//! loop {
|
||||
//! let (mut socket, _) = listener.accept().await?;
|
||||
|
||||
@@ -39,8 +39,7 @@
|
||||
//!
|
||||
//! #[tokio::main]
|
||||
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! let addr = "127.0.0.1:8080".parse()?;
|
||||
//! let mut listener = TcpListener::bind(&addr).unwrap();
|
||||
//! let mut listener = TcpListener::bind("127.0.0.1:8080").await?;
|
||||
//!
|
||||
//! loop {
|
||||
//! let (mut socket, _) = listener.accept().await?;
|
||||
@@ -87,12 +86,11 @@
|
||||
//!
|
||||
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // Create the runtime
|
||||
//! let mut rt = Runtime::new().unwrap();
|
||||
//! let mut rt = Runtime::new()?;
|
||||
//!
|
||||
//! // Spawn the root task
|
||||
//! rt.block_on(async {
|
||||
//! let addr = "127.0.0.1:8080".parse()?;
|
||||
//! let mut listener = TcpListener::bind(&addr).unwrap();
|
||||
//! let mut listener = TcpListener::bind("127.0.0.1:8080").await?;
|
||||
//!
|
||||
//! loop {
|
||||
//! let (mut socket, _) = listener.accept().await?;
|
||||
|
||||
@@ -13,8 +13,7 @@ use std::thread;
|
||||
async fn echo_server() {
|
||||
const N: usize = 1024;
|
||||
|
||||
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";
|
||||
|
||||
@@ -50,9 +50,8 @@ fn test_drop_on_notify() {
|
||||
|
||||
// Define a task that just drains the listener
|
||||
let task = Arc::new(Task::new(async move {
|
||||
let addr = assert_ok!("127.0.0.1:0".parse());
|
||||
// Create a listener
|
||||
let mut listener = assert_ok!(TcpListener::bind(&addr));
|
||||
let mut listener = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
|
||||
// Send the address
|
||||
let addr = listener.local_addr().unwrap();
|
||||
|
||||
@@ -13,8 +13,7 @@ use std::time::{Duration, Instant};
|
||||
use tokio::timer::delay;
|
||||
|
||||
async fn client_server(tx: mpsc::Sender<()>) {
|
||||
let addr = assert_ok!("127.0.0.1:0".parse());
|
||||
let mut server = assert_ok!(TcpListener::bind(&addr));
|
||||
let mut server = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
|
||||
// Get the assigned address
|
||||
let addr = assert_ok!(server.local_addr());
|
||||
|
||||
@@ -15,8 +15,7 @@ use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
async fn client_server(tx: mpsc::Sender<()>) {
|
||||
let addr = assert_ok!("127.0.0.1:0".parse());
|
||||
let mut server = assert_ok!(TcpListener::bind(&addr));
|
||||
let mut server = assert_ok!(TcpListener::bind("127.0.0.1:0").await);
|
||||
|
||||
// Get the assigned address
|
||||
let addr = assert_ok!(server.local_addr());
|
||||
@@ -78,11 +77,9 @@ fn block_on_socket() {
|
||||
let rt = Runtime::new().unwrap();
|
||||
|
||||
rt.block_on(async move {
|
||||
let addr = "127.0.0.1:0".parse().unwrap();
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
let mut listener = TcpListener::bind(&addr).unwrap();
|
||||
let mut listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
|
||||
let addr = listener.local_addr().unwrap();
|
||||
|
||||
tokio::spawn(async move {
|
||||
|
||||
Reference in New Issue
Block a user