1- use hickory_resolver:: { Resolver , system_conf:: read_system_conf} ;
1+ use hickory_resolver:: {
2+ TokioResolver , name_server:: TokioConnectionProvider , system_conf:: read_system_conf,
3+ } ;
24use local_ip_address:: list_afinet_netifas;
35use serde:: Serialize ;
46use std:: {
57 collections:: { BTreeSet , HashMap } ,
68 net:: IpAddr ,
9+ sync:: LazyLock ,
710 time:: Duration ,
811} ;
12+ use tokio:: task:: JoinSet ;
13+
14+ static GLOBAL_DNS_RESOLVER : LazyLock < TokioResolver > = LazyLock :: new ( || {
15+ let ( resolver_config, mut resolver_opts) =
16+ read_system_conf ( ) . expect ( "failed to read system resolv config" ) ;
17+ resolver_opts. timeout = Duration :: from_secs ( 5 ) ;
18+
19+ TokioResolver :: builder_with_config ( resolver_config, TokioConnectionProvider :: default ( ) )
20+ . with_options ( resolver_opts)
21+ . build ( )
22+ } ) ;
923
1024/// Captures all system network information, including network interfaces,
1125/// and the results of reverse and forward DNS lookups.
@@ -18,16 +32,7 @@ pub struct SystemNetworkInfo {
1832
1933impl SystemNetworkInfo {
2034 #[ tracing:: instrument( name = "SystemNetworkInfo::collect" ) ]
21- pub fn collect ( ) -> SystemNetworkInfo {
22- /*
23- let resolver = Resolver::from_system_conf()
24- .map_err(|e| e.to_string())
25- .unwrap();
26- */
27- let ( resolver_config, mut resolver_opts) = read_system_conf ( ) . unwrap ( ) ;
28- resolver_opts. timeout = Duration :: from_secs ( 5 ) ;
29- let resolver = Resolver :: new ( resolver_config, resolver_opts) . unwrap ( ) ;
30-
35+ pub async fn collect ( ) -> SystemNetworkInfo {
3136 let interfaces = match list_afinet_netifas ( ) {
3237 Ok ( netifs) => {
3338 let mut interface_map = std:: collections:: HashMap :: new ( ) ;
@@ -56,12 +61,19 @@ impl SystemNetworkInfo {
5661 }
5762 } ;
5863
59- let ip_set : BTreeSet < IpAddr > = interfaces. values ( ) . flatten ( ) . copied ( ) . collect ( ) ;
60- tracing:: info!( network. addresses. ip = ?ip_set , "ip addresses" ) ;
64+ let ips : BTreeSet < IpAddr > = interfaces. values ( ) . flatten ( ) . copied ( ) . collect ( ) ;
65+ tracing:: info!( network. addresses. ip = ?ips , "ip addresses" ) ;
6166
62- let reverse_lookups: HashMap < IpAddr , Vec < String > > = ip_set
67+ let mut reverse_lookups = JoinSet :: new ( ) ;
68+ for ip in ips {
69+ reverse_lookups
70+ . spawn ( async move { ( ip, GLOBAL_DNS_RESOLVER . reverse_lookup ( ip) . await ) } ) ;
71+ }
72+ let reverse_lookups: HashMap < IpAddr , Vec < String > > = reverse_lookups
73+ . join_all ( )
74+ . await
6375 . into_iter ( )
64- . filter_map ( |ip | match resolver . reverse_lookup ( ip ) {
76+ . filter_map ( |( ip , reverse_lookup ) | match reverse_lookup {
6577 Ok ( result) => {
6678 let hostnames = result
6779 . into_iter ( )
@@ -84,9 +96,20 @@ impl SystemNetworkInfo {
8496 let hostname_set: BTreeSet < String > = reverse_lookups. values ( ) . flatten ( ) . cloned ( ) . collect ( ) ;
8597 tracing:: info!( network. addresses. hostname = ?hostname_set, "hostnames" ) ;
8698
87- let forward_lookups: HashMap < String , Vec < IpAddr > > = hostname_set
99+ let mut forward_lookups = JoinSet :: new ( ) ;
100+ for hostname in hostname_set {
101+ forward_lookups. spawn ( async move {
102+ (
103+ hostname. clone ( ) ,
104+ GLOBAL_DNS_RESOLVER . lookup_ip ( hostname) . await ,
105+ )
106+ } ) ;
107+ }
108+ let forward_lookups: HashMap < String , Vec < IpAddr > > = forward_lookups
109+ . join_all ( )
110+ . await
88111 . into_iter ( )
89- . filter_map ( |hostname| match resolver . lookup_ip ( hostname . clone ( ) ) {
112+ . filter_map ( |( hostname, forward_lookup ) | match forward_lookup {
90113 Ok ( result) => {
91114 let ips = result. iter ( ) . collect ( ) ;
92115 tracing:: info!( hostname, ?ips, "performed forward DNS lookup for hostname" ) ;
0 commit comments