Is there a "better" way for dns resolving of an IP and connect?

Hi.

I try to make some network measurements for DNS resolving and tcp connect. This program works but what I'm asking me isn't here an easier way then "php.net:80".to_socket_addrs() and let php_addr = SocketAddr::new(dest.ip(), 80); . It looks to me that I create a socket addr and convert it to IP and again to socket addr, this makes no sense to me.
Here is the program and the playground link

use std::time::Duration;
use std::net::{IpAddr, Ipv4Addr, SocketAddr,TcpStream, Shutdown, ToSocketAddrs};
use std::time::Instant;

fn main() {
    let timeout = Duration::from_millis(500);
    let mut dest = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);

    match "php.net:80".to_socket_addrs() {
        Ok(addrs_iter) => {
            println!("addrs_iter {:?}",addrs_iter);
            for addr in addrs_iter {
                if addr.is_ipv4() {
                    println!("IP {:?}",addr.ip());
                    dest = addr;
                }
                println!("addr {:?}",addr);
            }
        }
        Err(err)  => println!("addrs_iter nok: {:?}",err)
    }

    // dig +short php.net
    let php_addr = SocketAddr::new(dest.ip(), 80);
    println!("connect to {:?}",dest.ip());

    let start = Instant::now();
    match TcpStream::connect_timeout(&php_addr,timeout) {
        Ok(stream) => {
            println!("Connected to the server!");
            println!("Stream {:?}.", stream);
            println!("duration: {:?}", start.elapsed());
            match stream.shutdown(Shutdown::Both) {
                Ok(res) => println!("shutdown  ok: {:?}",res),
                Err(err) => println!("shutdown nok: {:?}",err)
            }
        }
        Err(err) => {
            println!("Couldn't connect to server.... Error: {:?}",err);
            println!("Timeout: {:?}", start.elapsed());
        }
    }
    println!("timeout {:?}.", timeout);
}

There is also an implementation of ToSocketAddrs for (&str, u16) which will preserve the port number.

That means you should be able to do something like this:

let php_addr = ("php.net", 80_u16)
    .to_socket_addrs()
    .expect("Unable to resolve the IP address")
    .next()
    .expect("DNS resolution returned no IP addresses");

Note that I'm using expect() to handle the errors by killing the program. Your original code was printing error messages and continuing on with a bad SocketAddr, which is probably not what you want to do.

1 Like

Great, thanks for the hint. code is now in playground and here.

use std::time::Duration;
use std::net::{IpAddr, Ipv4Addr, SocketAddr,TcpStream, Shutdown, ToSocketAddrs};
use std::time::Instant;
use std::process::exit;

fn main() {
    let timeout = Duration::from_millis(500);
    let mut dest = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);

    // change from "php.net:80"
    match ("php.net",80_u16).to_socket_addrs() {
        Ok(addrs_iter) => {
            println!("addrs_iter {:?}",addrs_iter);
            for addr in addrs_iter {
                if addr.is_ipv4() {
                    println!("IP {:?}",addr.ip());
                    dest = addr;
                }
                println!("addr {:?}",addr);
            }
        }
        Err(err)  => {
            println!("addrs_iter nok: {:?}",err);
            exit(-1)
        }
    }

    println!("connect to {:?}",dest.ip());

    let start = Instant::now();
    // change from &php_addr
    match TcpStream::connect_timeout(&dest,timeout) {
        Ok(stream) => {
            println!("duration: {:?}", start.elapsed());
            println!("Connected to the server!");
            println!("Stream {:?}.", stream);
            match stream.shutdown(Shutdown::Both) {
                Ok(res) => println!("shutdown  ok: {:?}",res),
                Err(err) => println!("shutdown nok: {:?}",err)
            }
        }
        Err(err) => {
            println!("Couldn't connect to server.... Error: {:?}",err);
            println!("Timeout: {:?}", start.elapsed());
        }
    }
    println!("timeout {:?}.", timeout);
}