@@ -5,18 +5,24 @@ extern crate terminal_size;
55
66extern crate tokio;
77
8+ extern crate dnsclient;
9+
810use std:: error:: Error ;
11+ use std:: net:: { IpAddr , Ipv4Addr , SocketAddr } ;
912use std:: path:: Path ;
1013use std:: process:: { self , Command } ;
14+ use std:: str:: FromStr ;
1115use std:: time:: Duration ;
1216
1317#[ cfg( unix) ]
1418use tokio:: net:: UnixStream ;
1519
1620use tokio:: net:: TcpStream ;
17-
1821use tokio:: time:: { self , sleep, Instant } ;
1922
23+ use dnsclient:: r#async:: DNSClient ;
24+ use dnsclient:: UpstreamServer ;
25+
2026use clap:: { App , Arg , ArgMatches , SubCommand , Values } ;
2127use terminal_size:: terminal_size;
2228
@@ -46,23 +52,55 @@ async fn tcp(
4652 command : Vec < & str > ,
4753) -> Result < ( ) , Box < dyn Error > > {
4854 {
49- let host_with_port = format ! ( "{}:{}" , host, port) ;
55+ let ips = match IpAddr :: from_str ( host) {
56+ Ok ( ip) => vec ! [ SocketAddr :: new( ip, port) ] ,
57+ Err ( _) => {
58+ let client = match DNSClient :: new_with_system_resolvers ( ) {
59+ Ok ( client) => client,
60+ Err ( _) => {
61+ DNSClient :: new ( vec ! [
62+ UpstreamServer :: new( SocketAddr :: new(
63+ IpAddr :: V4 ( Ipv4Addr :: new( 1 , 1 , 1 , 1 ) ) ,
64+ 53 ,
65+ ) ) ,
66+ UpstreamServer :: new( SocketAddr :: new(
67+ IpAddr :: V4 ( Ipv4Addr :: new( 8 , 8 , 8 , 8 ) ) ,
68+ 53 ,
69+ ) ) ,
70+ UpstreamServer :: new( SocketAddr :: new(
71+ IpAddr :: V4 ( Ipv4Addr :: new( 4 , 4 , 4 , 4 ) ) ,
72+ 53 ,
73+ ) ) ,
74+ ] )
75+ }
76+ } ;
77+
78+ let host_with_port = format ! ( "{}:{}" , host, port) ;
79+
80+ client
81+ . query_addrs ( & host_with_port)
82+ . await ?
83+ . into_iter ( )
84+ . map ( |ip| SocketAddr :: new ( ip, port) )
85+ . collect ( )
86+ }
87+ } ;
5088
5189 let start = Instant :: now ( ) ;
5290
53- if timeout. is_zero ( ) {
54- while TcpStream :: connect ( host_with_port. as_str ( ) ) . await . is_err ( ) {
55- sleep ( SLEEP_INTERVAL ) . await ;
56- }
57- } else {
58- while let Err ( err) =
59- time:: timeout ( timeout, TcpStream :: connect ( host_with_port. as_str ( ) ) ) . await ?
60- {
61- if Instant :: now ( ) - start > timeout {
62- return Err ( err. into ( ) ) ;
63- } else {
91+ for ip in ips {
92+ if timeout. is_zero ( ) {
93+ while TcpStream :: connect ( ip) . await . is_err ( ) {
6494 sleep ( SLEEP_INTERVAL ) . await ;
6595 }
96+ } else {
97+ while let Err ( err) = time:: timeout ( timeout, TcpStream :: connect ( ip) ) . await ? {
98+ if Instant :: now ( ) - start > timeout {
99+ return Err ( err. into ( ) ) ;
100+ } else {
101+ sleep ( SLEEP_INTERVAL ) . await ;
102+ }
103+ }
66104 }
67105 }
68106 }
0 commit comments