1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 //! `Resolver` trait and `DefaultDnsResolver` implementation. 15 16 use std::future::Future; 17 use std::io; 18 use std::io::Error; 19 use std::net::{SocketAddr, ToSocketAddrs}; 20 use std::pin::Pin; 21 use std::task::{Context, Poll}; 22 use std::vec::IntoIter; 23 24 use crate::runtime::JoinHandle; 25 26 /// `SocketAddr` resolved by `Resolver`. 27 pub type Addrs = Box<dyn Iterator<Item = SocketAddr> + Sync + Send>; 28 /// Possible errors that this resolver may generate when attempting to 29 /// resolve. 30 pub type StdError = Box<dyn std::error::Error + Send + Sync>; 31 /// Futures generated by this resolve when attempting to resolve an address. 32 pub type SocketFuture = Pin<Box<dyn Future<Output = Result<Addrs, StdError>> + Sync + Send>>; 33 34 /// `Resolver` trait used by `async_impl::connector::HttpConnector`. `Resolver` 35 /// provides asynchronous dns resolve interfaces. 36 pub trait Resolver: Send + Sync + 'static { 37 /// resolve domain to a `SocketAddr` `Future`. resolve(&self, domain: &str) -> SocketFuture38 fn resolve(&self, domain: &str) -> SocketFuture; 39 } 40 41 /// `SocketAddr` resolved by `DefaultDnsResolver`. 42 pub struct ResolvedAddrs { 43 iter: IntoIter<SocketAddr>, 44 } 45 46 impl ResolvedAddrs { new(iter: IntoIter<SocketAddr>) -> Self47 pub(super) fn new(iter: IntoIter<SocketAddr>) -> Self { 48 Self { iter } 49 } 50 51 // The first ip in the dns record is the preferred addrs type. split_preferred_addrs(self) -> (Vec<SocketAddr>, Vec<SocketAddr>)52 pub(super) fn split_preferred_addrs(self) -> (Vec<SocketAddr>, Vec<SocketAddr>) { 53 // get preferred address family type. 54 let is_ipv6 = self 55 .iter 56 .as_slice() 57 .first() 58 .map(SocketAddr::is_ipv6) 59 .unwrap_or(false); 60 self.iter 61 .partition::<Vec<_>, _>(|addr| addr.is_ipv6() == is_ipv6) 62 } 63 } 64 65 impl Iterator for ResolvedAddrs { 66 type Item = SocketAddr; 67 next(&mut self) -> Option<Self::Item>68 fn next(&mut self) -> Option<Self::Item> { 69 self.iter.next() 70 } 71 } 72 73 /// Futures generated by `DefaultDnsResolver`. 74 pub struct DefaultDnsFuture { 75 inner: JoinHandle<Result<ResolvedAddrs, Error>>, 76 } 77 78 impl Future for DefaultDnsFuture { 79 type Output = Result<Addrs, StdError>; 80 poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>81 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { 82 Pin::new(&mut self.inner).poll(cx).map(|res| match res { 83 Ok(Ok(addrs)) => Ok(Box::new(addrs) as Addrs), 84 Ok(Err(err)) => Err(Box::new(err) as StdError), 85 Err(err) => Err(Box::new(Error::new(io::ErrorKind::Interrupted, err)) as StdError), 86 }) 87 } 88 } 89 90 /// Default dns resolver used by the `Client`。 91 #[derive(Default)] 92 pub struct DefaultDnsResolver {} 93 94 impl Resolver for DefaultDnsResolver { resolve(&self, domain: &str) -> SocketFuture95 fn resolve(&self, domain: &str) -> SocketFuture { 96 let domain: Box<str> = domain.into(); 97 let blocking = crate::runtime::spawn_blocking(move || { 98 (*domain) 99 .to_socket_addrs() 100 .map(|iter| ResolvedAddrs { iter }) 101 }); 102 Box::pin(DefaultDnsFuture { inner: blocking }) 103 } 104 } 105