@@ -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.
@@ -150,18 +148,26 @@ impl Resolver {
150148 Ok ( ( ips, valid_until) )
151149 }
152150
151+ #[ allow( unused, unreachable_code, reason = "XXX(kate)" ) ]
153152 async fn resolve_srv (
154153 & self ,
155154 name : NameRef < ' _ > ,
156155 ) -> Result < ( Vec < net:: SocketAddr > , Instant ) , SrvRecordError > {
157156 debug ! ( %name, "Resolving a SRV record" ) ;
158157 let srv = self . dns . srv_lookup ( name. as_str ( ) ) . await ?;
159158
160- let valid_until = Instant :: from_std ( srv. as_lookup ( ) . valid_until ( ) ) ;
159+ let valid_until = Instant :: from_std ( srv. valid_until ( ) ) ;
161160 let addrs = srv
162- . into_iter ( )
161+ . answers ( )
162+ . iter ( )
163+ . map ( |record| & record. data )
164+ . filter_map ( |rdata| match rdata {
165+ hickory_resolver:: proto:: rr:: RData :: SRV ( srv) => Some ( srv) ,
166+ _ => None ,
167+ } )
163168 . map ( Self :: srv_to_socket_addr)
164169 . collect :: < Result < _ , InvalidSrv > > ( ) ?;
170+
165171 debug ! ( ttl = ?valid_until - Instant :: now( ) , ?addrs) ;
166172
167173 Ok ( ( addrs, valid_until) )
@@ -174,19 +180,19 @@ impl Resolver {
174180 // instead of dots/colons. We can alternatively do another lookup
175181 // on the pod's DNS but it seems unnecessary since the pod's
176182 // 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 ( ) {
183+ fn srv_to_socket_addr ( srv : & rdata:: SRV ) -> Result < net:: SocketAddr , InvalidSrv > {
184+ if let Some ( first_label) = srv. target . iter ( ) . next ( ) {
179185 if let Ok ( utf8) = std:: str:: from_utf8 ( first_label) {
180186 let mut res = utf8. replace ( '-' , "." ) . parse :: < std:: net:: IpAddr > ( ) ;
181187 if res. is_err ( ) {
182188 res = utf8. replace ( '-' , ":" ) . parse :: < std:: net:: IpAddr > ( ) ;
183189 }
184190 if let Ok ( ip) = res {
185- return Ok ( net:: SocketAddr :: new ( ip, srv. port ( ) ) ) ;
191+ return Ok ( net:: SocketAddr :: new ( ip, srv. port ) ) ;
186192 }
187193 }
188194 }
189- Err ( InvalidSrv ( srv) )
195+ Err ( InvalidSrv ( srv. clone ( ) ) )
190196 }
191197}
192198
@@ -223,13 +229,13 @@ impl ResolveError {
223229 /// Returns the negative TTL [`time::Duration`] of a [`hickory_resolver::ResolveError`].
224230 ///
225231 /// 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 } ;
232+ fn negative_ttl_of ( error : & hickory_resolver:: net :: NetError ) -> Option < time:: Duration > {
233+ use hickory_resolver:: net :: { DnsError , NetError , NoRecords } ;
228234
229- let Some ( ProtoErrorKind :: NoRecordsFound {
235+ let NetError :: Dns ( DnsError :: NoRecordsFound ( NoRecords {
230236 negative_ttl : Some ( ttl_secs) ,
231237 ..
232- } ) = error. proto ( ) . map ( ProtoError :: kind )
238+ } ) ) = error
233239 else {
234240 return None ;
235241 } ;
@@ -373,7 +379,7 @@ mod tests {
373379 let name = "foobar.linkerd-dst-headless.linkerd.svc.cluster.local." ;
374380 let target = domain:: Name :: from_str ( name) . unwrap ( ) ;
375381 let srv = rdata:: SRV :: new ( 1 , 1 , 8086 , target) ;
376- assert ! ( Resolver :: srv_to_socket_addr( srv) . is_err( ) ) ;
382+ assert ! ( Resolver :: srv_to_socket_addr( & srv) . is_err( ) ) ;
377383 }
378384
379385 #[ test]
@@ -399,15 +405,15 @@ mod tests {
399405 ] {
400406 let target = domain:: Name :: from_str ( case. input ) . unwrap ( ) ;
401407 let srv = rdata:: SRV :: new ( 1 , 1 , 8086 , target) ;
402- let socket = Resolver :: srv_to_socket_addr ( srv) . unwrap ( ) ;
408+ let socket = Resolver :: srv_to_socket_addr ( & srv) . unwrap ( ) ;
403409 assert_eq ! ( socket. ip( ) , net:: IpAddr :: from_str( case. output) . unwrap( ) ) ;
404410 }
405411 }
406412
407413 #[ test]
408414 fn srv_record_reports_cause_correctly ( ) {
409415 let srv = "foobar.linkerd-dst-headless.linkerd.svc.cluster.local."
410- . parse :: < hickory_resolver :: Name > ( )
416+ . parse :: < domain :: Name > ( )
411417 . map ( |name| rdata:: SRV :: new ( 1 , 1 , 8086 , name) )
412418 . expect ( "a valid domain name" ) ;
413419
0 commit comments