@@ -41,14 +41,14 @@ struct InvalidSrv(rdata::SRV);
4141
4242#[ derive( Debug , Error ) ]
4343#[ error( "failed to resolve A record: {0}" ) ]
44- struct ARecordError ( #[ from] hickory_resolver:: ResolveError ) ;
44+ struct ARecordError ( #[ from] hickory_resolver:: net :: NetError ) ;
4545
4646#[ derive( Debug , Error ) ]
4747enum SrvRecordError {
4848 #[ error( "{0}" ) ]
4949 Invalid ( #[ from] InvalidSrv ) ,
5050 #[ error( "failed to resolve SRV record: {0}" ) ]
51- Resolve ( #[ from] hickory_resolver:: ResolveError ) ,
51+ Resolve ( #[ from] hickory_resolver:: net :: NetError ) ,
5252}
5353
5454#[ derive( Debug , Error ) ]
@@ -67,32 +67,30 @@ impl Resolver {
6767 ///
6868 /// Either a new `Resolver` or an error if the system configuration
6969 /// could not be parsed.
70- ///
71- /// TODO: This should be infallible like it is in the `domain` crate.
72- pub fn from_system_config_with < C : ConfigureResolver > ( c : & C ) -> std :: io :: Result < Self > {
70+ pub fn from_system_config_with < C : ConfigureResolver > (
71+ c : & C ,
72+ ) -> Result < Self , hickory_resolver :: net :: NetError > {
7373 let ( config, mut opts) = system_conf:: read_system_conf ( ) ?;
7474 c. configure_resolver ( & mut opts) ;
7575 trace ! ( "DNS config: {:?}" , & config) ;
7676 trace ! ( "DNS opts: {:?}" , & opts) ;
77- Ok ( Self :: new ( config, opts) )
77+ Self :: new ( config, opts)
7878 }
7979
80- pub fn new ( config : ResolverConfig , mut opts : ResolverOpts ) -> Self {
80+ pub fn new (
81+ config : ResolverConfig ,
82+ mut opts : ResolverOpts ,
83+ ) -> Result < Self , hickory_resolver:: net:: NetError > {
8184 // Disable Hickory-resolver's caching.
8285 opts. cache_size = 0 ;
8386 // This function is synchronous, but needs to be called within the Tokio
8487 // 0.2 runtime context, since it gets a handle.
85- let provider = hickory_resolver:: name_server:: TokioConnectionProvider :: default ( ) ;
86- let mut builder = hickory_resolver:: Resolver :: builder_with_config ( config, provider) ;
87- * builder. options_mut ( ) = opts;
88- let dns = builder. build ( ) ;
89- /* TODO(kate): this can be used if/when hickory-dns/hickory-dns#2877 is released.
88+ let provider = hickory_resolver:: net:: runtime:: TokioRuntimeProvider :: default ( ) ;
9089 let dns = hickory_resolver:: Resolver :: builder_with_config ( config, provider)
9190 . with_options ( opts)
92- .build();
93- */
91+ . build ( ) ?;
9492
95- Resolver { dns, metrics : None }
93+ Ok ( Resolver { dns, metrics : None } )
9694 }
9795
9896 /// Installs a counter tracking the number of A/AAAA records resolved.
@@ -157,11 +155,18 @@ impl Resolver {
157155 debug ! ( %name, "Resolving a SRV record" ) ;
158156 let srv = self . dns . srv_lookup ( name. as_str ( ) ) . await ?;
159157
160- let valid_until = Instant :: from_std ( srv. as_lookup ( ) . valid_until ( ) ) ;
158+ let valid_until = Instant :: from_std ( srv. valid_until ( ) ) ;
161159 let addrs = srv
162- . into_iter ( )
160+ . answers ( )
161+ . iter ( )
162+ . map ( |record| & record. data )
163+ . filter_map ( |rdata| match rdata {
164+ hickory_resolver:: proto:: rr:: RData :: SRV ( srv) => Some ( srv) ,
165+ _ => None ,
166+ } )
163167 . map ( Self :: srv_to_socket_addr)
164168 . collect :: < Result < _ , InvalidSrv > > ( ) ?;
169+
165170 debug ! ( ttl = ?valid_until - Instant :: now( ) , ?addrs) ;
166171
167172 Ok ( ( addrs, valid_until) )
@@ -174,19 +179,19 @@ impl Resolver {
174179 // instead of dots/colons. We can alternatively do another lookup
175180 // on the pod's DNS but it seems unnecessary since the pod's
176181 // ip is in the target of the SRV record.
177- fn srv_to_socket_addr ( srv : rdata:: SRV ) -> Result < net:: SocketAddr , InvalidSrv > {
178- if let Some ( first_label) = srv. target ( ) . iter ( ) . next ( ) {
182+ fn srv_to_socket_addr ( srv : & rdata:: SRV ) -> Result < net:: SocketAddr , InvalidSrv > {
183+ if let Some ( first_label) = srv. target . iter ( ) . next ( ) {
179184 if let Ok ( utf8) = std:: str:: from_utf8 ( first_label) {
180185 let mut res = utf8. replace ( '-' , "." ) . parse :: < std:: net:: IpAddr > ( ) ;
181186 if res. is_err ( ) {
182187 res = utf8. replace ( '-' , ":" ) . parse :: < std:: net:: IpAddr > ( ) ;
183188 }
184189 if let Ok ( ip) = res {
185- return Ok ( net:: SocketAddr :: new ( ip, srv. port ( ) ) ) ;
190+ return Ok ( net:: SocketAddr :: new ( ip, srv. port ) ) ;
186191 }
187192 }
188193 }
189- Err ( InvalidSrv ( srv) )
194+ Err ( InvalidSrv ( srv. clone ( ) ) )
190195 }
191196}
192197
@@ -220,16 +225,16 @@ impl ResolveError {
220225 }
221226 }
222227
223- /// Returns the negative TTL [`time::Duration`] of a [`hickory_resolver::ResolveError `].
228+ /// Returns the negative TTL [`time::Duration`] of a [`hickory_resolver::net::NetError `].
224229 ///
225230 /// This function will defensively enforce a minimum negative TTL.
226- fn negative_ttl_of ( error : & hickory_resolver:: ResolveError ) -> Option < time:: Duration > {
227- use hickory_resolver:: proto :: { ProtoError , ProtoErrorKind } ;
231+ fn negative_ttl_of ( error : & hickory_resolver:: net :: NetError ) -> Option < time:: Duration > {
232+ use hickory_resolver:: net :: { DnsError , NetError , NoRecords } ;
228233
229- let Some ( ProtoErrorKind :: NoRecordsFound {
234+ let NetError :: Dns ( DnsError :: NoRecordsFound ( NoRecords {
230235 negative_ttl : Some ( ttl_secs) ,
231236 ..
232- } ) = error. proto ( ) . map ( ProtoError :: kind )
237+ } ) ) = error
233238 else {
234239 return None ;
235240 } ;
@@ -373,7 +378,7 @@ mod tests {
373378 let name = "foobar.linkerd-dst-headless.linkerd.svc.cluster.local." ;
374379 let target = domain:: Name :: from_str ( name) . unwrap ( ) ;
375380 let srv = rdata:: SRV :: new ( 1 , 1 , 8086 , target) ;
376- assert ! ( Resolver :: srv_to_socket_addr( srv) . is_err( ) ) ;
381+ assert ! ( Resolver :: srv_to_socket_addr( & srv) . is_err( ) ) ;
377382 }
378383
379384 #[ test]
@@ -399,15 +404,15 @@ mod tests {
399404 ] {
400405 let target = domain:: Name :: from_str ( case. input ) . unwrap ( ) ;
401406 let srv = rdata:: SRV :: new ( 1 , 1 , 8086 , target) ;
402- let socket = Resolver :: srv_to_socket_addr ( srv) . unwrap ( ) ;
407+ let socket = Resolver :: srv_to_socket_addr ( & srv) . unwrap ( ) ;
403408 assert_eq ! ( socket. ip( ) , net:: IpAddr :: from_str( case. output) . unwrap( ) ) ;
404409 }
405410 }
406411
407412 #[ test]
408413 fn srv_record_reports_cause_correctly ( ) {
409414 let srv = "foobar.linkerd-dst-headless.linkerd.svc.cluster.local."
410- . parse :: < hickory_resolver :: Name > ( )
415+ . parse :: < domain :: Name > ( )
411416 . map ( |name| rdata:: SRV :: new ( 1 , 1 , 8086 , name) )
412417 . expect ( "a valid domain name" ) ;
413418
0 commit comments