@@ -25,22 +25,51 @@ super::manager::register_plugin! {
2525
2626#[ derive( Clone ) ]
2727pub ( crate ) struct DNS {
28- resolver : Option < TokioAsyncResolver > ,
28+ ips : Vec < IpAddr > ,
2929 opts : options:: Options ,
30+ core_options : Options ,
3031 hits : Arc < DashMap < IpAddr , usize > > ,
3132 domains : Arc < DashSet < String > > ,
3233}
3334
3435impl DNS {
3536 pub fn new ( ) -> Self {
3637 DNS {
37- resolver : None ,
38+ ips : vec ! [ ] ,
3839 opts : options:: Options :: default ( ) ,
40+ core_options : Options :: default ( ) ,
3941 hits : Arc :: new ( DashMap :: new ( ) ) ,
4042 domains : Arc :: new ( DashSet :: new ( ) ) ,
4143 }
4244 }
4345
46+ async fn get_resolver ( & self , timeout : Duration ) -> Result < TokioAsyncResolver , Error > {
47+ if !self . ips . is_empty ( ) {
48+ let nameserver_group =
49+ NameServerConfigGroup :: from_ips_clear ( & self . ips , self . opts . dns_port , true ) ;
50+
51+ let mut options = ResolverOpts :: default ( ) ;
52+
53+ options. num_concurrent_reqs = self . core_options . concurrency ;
54+ options. attempts = self . opts . dns_attempts ;
55+ options. timeout = timeout;
56+ options. shuffle_dns_servers = true ;
57+
58+ Ok ( AsyncResolver :: tokio (
59+ ResolverConfig :: from_parts ( None , vec ! [ ] , nameserver_group) ,
60+ options,
61+ ) )
62+ } else {
63+ let ( config, mut options) =
64+ trust_dns_resolver:: system_conf:: read_system_conf ( ) . map_err ( |e| e. to_string ( ) ) ?;
65+
66+ options. attempts = self . opts . dns_attempts ;
67+ options. timeout = timeout;
68+
69+ Ok ( AsyncResolver :: tokio ( config, options) )
70+ }
71+ }
72+
4473 async fn filter ( & self , addresses : Vec < IpAddr > ) -> Vec < IpAddr > {
4574 // Some domains are configured to resolve any subdomain, whatever it is, to the same IP. We do
4675 // this filtering in order too many positives for an address and work around this behaviour.
@@ -170,8 +199,9 @@ impl Plugin for DNS {
170199 }
171200
172201 async fn setup ( & mut self , opts : & Options ) -> Result < ( ) , Error > {
202+ self . core_options = opts. clone ( ) ;
173203 self . opts = opts. dns . clone ( ) ;
174- self . resolver = Some ( if let Some ( resolvers) = opts. dns . dns_resolvers . as_ref ( ) {
204+ self . ips = if let Some ( resolvers) = opts. dns . dns_resolvers . as_ref ( ) {
175205 let ips: Vec < IpAddr > = resolvers
176206 . split ( ',' )
177207 . map ( |s| s. trim ( ) )
@@ -181,25 +211,12 @@ impl Plugin for DNS {
181211
182212 log:: info!( "using resolvers: {:?}" , & ips) ;
183213
184- let nameserver_group =
185- NameServerConfigGroup :: from_ips_clear ( & ips, opts. dns . dns_port , true ) ;
186-
187- let mut options = ResolverOpts :: default ( ) ;
188-
189- options. num_concurrent_reqs = opts. concurrency ;
190- options. attempts = opts. dns . dns_attempts ;
191- options. timeout = Duration :: from_millis ( opts. timeout ) ;
192- options. shuffle_dns_servers = true ;
193-
194- AsyncResolver :: tokio (
195- ResolverConfig :: from_parts ( None , vec ! [ ] , nameserver_group) ,
196- options,
197- )
214+ ips
198215 } else {
199216 log:: info!( "using system resolver" ) ;
200217
201- AsyncResolver :: tokio_from_system_conf ( ) . map_err ( |e| e . to_string ( ) ) ?
202- } ) ;
218+ vec ! [ ]
219+ } ;
203220
204221 Ok ( ( ) )
205222 }
@@ -224,10 +241,11 @@ impl Plugin for DNS {
224241 }
225242
226243 // each worker will use its own resolver object instance
227- let resolver = self . resolver . as_ref ( ) . unwrap ( ) . clone ( ) ;
228-
244+ let resolver = self . get_resolver ( timeout ) . await ? ;
245+ let started_at = std :: time :: Instant :: now ( ) ;
229246 // attempt resolving this subdomain to a one or more IP addresses
230247 if let Ok ( response) = resolver. lookup_ip ( & subdomain) . await {
248+ let elapsed = started_at. elapsed ( ) ;
231249 // collect valid IPs
232250 let addresses: Vec < IpAddr > = response. iter ( ) . filter ( |ip| !ip. is_loopback ( ) ) . collect ( ) ;
233251 // Some domains are configured to resolve any subdomain, whatever it is, to the same IP. We do
@@ -259,6 +277,7 @@ impl Plugin for DNS {
259277 } ;
260278
261279 loot_data. push ( ( "addresses" . to_owned ( ) , addr_data) ) ;
280+ loot_data. push ( ( "time_ms" . to_owned ( ) , elapsed. as_millis ( ) . to_string ( ) ) ) ;
262281
263282 let mut loot = vec ! [ Loot :: new( "dns" , & subdomain, loot_data) ] ;
264283
0 commit comments