@@ -35,12 +35,13 @@ use std::io::Read;
3535use std:: net:: { IpAddr , SocketAddr } ;
3636use std:: sync:: { Arc , Mutex } ;
3737use std:: time:: Duration ;
38+ use tokio:: runtime:: Runtime ;
3839use tokio:: sync:: { mpsc, oneshot} ;
3940use tokio:: task;
4041use tokio:: time:: Instant ;
4142use tracing:: { trace, warn} ;
4243use trust_dns_resolver:: config:: * ;
43- use trust_dns_resolver:: Resolver ;
44+ use trust_dns_resolver:: TokioAsyncResolver ;
4445use url:: Url ;
4546
4647pub type RoutesPoWInfo = Arc < Mutex < BTreeMap < String , usize > > > ;
@@ -470,43 +471,73 @@ pub fn generate_random_num(len: usize) -> Vec<u8> {
470471/// ### Arguments
471472///
472473/// * `url_str` - URL string to parse
473- pub fn create_socket_addr ( url_str : & str ) -> Result < SocketAddr , Box < dyn std:: error:: Error > > {
474- if let Ok ( url) = Url :: parse ( url_str) {
475- println ! ( "url: {:?}" , url) ;
476- let host_str = url. host_str ( ) . ok_or ( "Invalid host" ) ?;
477- println ! ( "host_str: {:?}" , host_str) ;
478- let port = url. port ( ) . unwrap_or ( 80 ) ;
479-
480- // Check if the host is an IP address
481- if let Ok ( ip) = host_str. parse :: < IpAddr > ( ) {
482- // Handle as direct IP address
483- Ok ( SocketAddr :: new ( ip, port) )
474+ pub async fn create_socket_addr ( url_str : & str ) -> Result < SocketAddr , Box < dyn std:: error:: Error > > {
475+ let thread_url = url_str. to_owned ( ) ;
476+ let handle = tokio:: task:: spawn_blocking ( move || {
477+ if let Ok ( url) = Url :: parse ( & thread_url. clone ( ) ) {
478+ // println!("url: {:?}", url);
479+ let host_str = match url. host_str ( ) {
480+ Some ( v) => v,
481+ None => return None ,
482+ } ;
483+ // println!("host_str: {:?}", host_str);
484+ let port = url. port ( ) . unwrap_or ( 80 ) ;
485+
486+ // Check if the host is an IP address
487+ if let Ok ( ip) = host_str. parse :: < IpAddr > ( ) {
488+ // Handle as direct IP address
489+ Some ( SocketAddr :: new ( ip, port) )
490+ } else {
491+ let io_loop = Runtime :: new ( ) . unwrap ( ) ;
492+
493+ // Handle as domain name
494+ let resolver = io_loop. block_on ( async {
495+ TokioAsyncResolver :: tokio ( ResolverConfig :: default ( ) , ResolverOpts :: default ( ) )
496+ } ) ;
497+
498+ let lookup_future = resolver. lookup_ip ( host_str) ;
499+ let response = io_loop. block_on ( lookup_future) . unwrap ( ) ;
500+ let ip = match response. iter ( ) . next ( ) {
501+ Some ( ip) => ip,
502+ None => return None ,
503+ } ;
504+ Some ( SocketAddr :: new ( ip, port) )
505+ }
484506 } else {
485- // Handle as domain name
486- let resolver = Resolver :: new ( ResolverConfig :: default ( ) , ResolverOpts :: default ( ) ) ?;
487- let response = resolver. lookup_ip ( host_str) ?;
488- let ip = response. iter ( ) . next ( ) . ok_or ( "No IP addresses found" ) ?;
489- Ok ( SocketAddr :: new ( ip, port) )
507+ // Handle as direct IP address with optional port
508+ let parts: Vec < & str > = thread_url. split ( ':' ) . collect ( ) ;
509+ let ip = match parts[ 0 ] . parse :: < IpAddr > ( ) {
510+ Ok ( ip) => ip,
511+ Err ( _e) => return None ,
512+ } ;
513+ let port = if parts. len ( ) > 1 {
514+ match parts[ 1 ] . parse :: < u16 > ( ) {
515+ Ok ( port) => port,
516+ Err ( _e) => return None ,
517+ }
518+ } else {
519+ 80
520+ } ;
521+ Some ( SocketAddr :: new ( ip, port) )
490522 }
491- } else {
492- // Handle as direct IP address with optional port
493- let parts: Vec < & str > = url_str. split ( ':' ) . collect ( ) ;
494- let ip = parts[ 0 ] . parse :: < IpAddr > ( ) ?;
495- let port = if parts. len ( ) > 1 {
496- parts[ 1 ] . parse :: < u16 > ( ) ?
497- } else {
498- 80
499- } ;
500- Ok ( SocketAddr :: new ( ip, port) )
523+ } ) ;
524+
525+ match handle. await {
526+ Ok ( v) => match v {
527+ Some ( v) => Ok ( v) ,
528+ None => Err ( "Failed to parse URL" . into ( ) ) ,
529+ } ,
530+ Err ( _e) => Err ( "Failed to parse URL" . into ( ) ) ,
501531 }
502532}
503533
504- pub fn create_socket_addr_for_list (
534+ pub async fn create_socket_addr_for_list (
505535 urls : & [ String ] ,
506536) -> Result < Vec < SocketAddr > , Box < dyn std:: error:: Error > > {
507537 let mut result = Vec :: new ( ) ;
508538 for url in urls {
509- result. push ( create_socket_addr ( url) ?) ;
539+ let socket_addr = create_socket_addr ( url) . await ?;
540+ result. push ( socket_addr) ;
510541 }
511542 Ok ( result)
512543}
@@ -1235,16 +1266,16 @@ mod util_tests {
12351266 use super :: * ;
12361267 use std:: net:: Ipv4Addr ;
12371268
1238- #[ test]
1269+ #[ tokio :: test]
12391270 /// Tests whether URL strings can be parsed successfully.
12401271 /// Testing DNS resolution is not possible in unit tests due to the lack of static IPs to test against,
12411272 /// so if you have any, please add them here
1242- fn test_create_socket_addr ( ) {
1273+ async fn test_create_socket_addr ( ) {
12431274 let ip_raw = "0.0.0.0" . to_string ( ) ;
12441275 let ip_with_port = "0.0.0.0:12300" . to_string ( ) ;
12451276
1246- let ip_addr = create_socket_addr ( & ip_raw) . unwrap ( ) ;
1247- let ip_with_port_addr = create_socket_addr ( & ip_with_port) . unwrap ( ) ;
1277+ let ip_addr = create_socket_addr ( & ip_raw) . await . unwrap ( ) ;
1278+ let ip_with_port_addr = create_socket_addr ( & ip_with_port) . await . unwrap ( ) ;
12481279
12491280 assert_eq ! (
12501281 ip_addr,
0 commit comments