feat(WIP): change relevant types

This commit is contained in:
XOR-op
2023-05-19 16:34:31 +08:00
committed by Benjamin Fry
parent 0901b1d591
commit 5ab85e297d
13 changed files with 198 additions and 194 deletions

View File

@@ -1,5 +1,6 @@
#![recursion_limit = "128"] #![recursion_limit = "128"]
use trust_dns_resolver::name_server::{ConnectionProvider, GenericConnector};
#[cfg(feature = "tokio-runtime")] #[cfg(feature = "tokio-runtime")]
use { use {
std::future::Future, std::future::Future,
@@ -57,7 +58,7 @@ impl RuntimeProvider for PrintProvider {
} }
#[cfg(feature = "tokio-runtime")] #[cfg(feature = "tokio-runtime")]
async fn lookup_test<R: RuntimeProvider>(resolver: AsyncResolver<R>) { async fn lookup_test<R: ConnectionProvider>(resolver: AsyncResolver<R>) {
let response = resolver.lookup_ip("www.example.com.").await.unwrap(); let response = resolver.lookup_ip("www.example.com.").await.unwrap();
// There can be many addresses associated with the name, // There can be many addresses associated with the name,
@@ -81,7 +82,7 @@ async fn main() {
let resolver = AsyncResolver::new( let resolver = AsyncResolver::new(
ResolverConfig::google(), ResolverConfig::google(),
ResolverOpts::default(), ResolverOpts::default(),
PrintProvider::default(), GenericConnector::new(PrintProvider::default()),
); );
lookup_test(resolver).await; lookup_test(resolver).await;
@@ -90,7 +91,7 @@ async fn main() {
let resolver2 = AsyncResolver::new( let resolver2 = AsyncResolver::new(
ResolverConfig::cloudflare_https(), ResolverConfig::cloudflare_https(),
ResolverOpts::default(), ResolverOpts::default(),
PrintProvider::default(), GenericConnector::new(PrintProvider::default()),
); );
lookup_test(resolver2).await; lookup_test(resolver2).await;
} }

View File

@@ -1,5 +1,7 @@
#![recursion_limit = "128"] #![recursion_limit = "128"]
use trust_dns_resolver::name_server::TokioConnectionProvider;
#[cfg(all(feature = "tokio-runtime", feature = "system-config"))] #[cfg(all(feature = "tokio-runtime", feature = "system-config"))]
fn main() { fn main() {
tokio::runtime::Builder::new_multi_thread() tokio::runtime::Builder::new_multi_thread()
@@ -13,7 +15,6 @@ fn main() {
#[cfg(all(feature = "tokio-runtime", feature = "system-config"))] #[cfg(all(feature = "tokio-runtime", feature = "system-config"))]
async fn tokio_main() { async fn tokio_main() {
use trust_dns_resolver::name_server::TokioRuntimeProvider;
use trust_dns_resolver::TokioAsyncResolver; use trust_dns_resolver::TokioAsyncResolver;
let resolver = { let resolver = {
@@ -21,7 +22,7 @@ async fn tokio_main() {
#[cfg(any(unix, windows))] #[cfg(any(unix, windows))]
{ {
// use the system resolver configuration // use the system resolver configuration
TokioAsyncResolver::from_system_conf(TokioRuntimeProvider::new()) TokioAsyncResolver::from_system_conf(TokioConnectionProvider::default())
} }
// For other operating systems, we can use one of the preconfigured definitions // For other operating systems, we can use one of the preconfigured definitions
@@ -59,7 +60,7 @@ async fn tokio_main() {
} }
#[cfg(all(feature = "tokio-runtime", feature = "system-config"))] #[cfg(all(feature = "tokio-runtime", feature = "system-config"))]
async fn resolve_list<P: trust_dns_resolver::name_server::RuntimeProvider>( async fn resolve_list<P: trust_dns_resolver::name_server::ConnectionProvider>(
names: &[&str], names: &[&str],
resolver: &trust_dns_resolver::AsyncResolver<P>, resolver: &trust_dns_resolver::AsyncResolver<P>,
) -> tokio::time::Duration { ) -> tokio::time::Duration {

View File

@@ -1,5 +1,6 @@
#![recursion_limit = "128"] #![recursion_limit = "128"]
use trust_dns_resolver::name_server::TokioConnectionProvider;
#[cfg(all(feature = "tokio-runtime", feature = "system-config"))] #[cfg(all(feature = "tokio-runtime", feature = "system-config"))]
use { use {
futures_util::future, futures_util::future,
@@ -8,7 +9,7 @@ use {
std::io, std::io,
std::net::SocketAddr, std::net::SocketAddr,
std::task::Poll, std::task::Poll,
trust_dns_resolver::{name_server::TokioRuntimeProvider, TokioAsyncResolver}, trust_dns_resolver::TokioAsyncResolver,
trust_dns_resolver::{IntoName, TryParseIp}, trust_dns_resolver::{IntoName, TryParseIp},
}; };
@@ -43,7 +44,7 @@ static GLOBAL_DNS_RESOLVER: Lazy<TokioAsyncResolver> = Lazy::new(|| {
#[cfg(any(unix, windows))] #[cfg(any(unix, windows))]
{ {
// use the system resolver configuration // use the system resolver configuration
TokioAsyncResolver::from_system_conf(TokioRuntimeProvider::new()) TokioAsyncResolver::from_system_conf(TokioConnectionProvider::default())
} }
// For other operating systems, we can use one of the preconfigured definitions // For other operating systems, we can use one of the preconfigured definitions

View File

@@ -3,10 +3,11 @@
//! This example shows how to create a resolver that uses the tokio multithreaded runtime. This is how //! This example shows how to create a resolver that uses the tokio multithreaded runtime. This is how
//! you might integrate the resolver into a more complex application. //! you might integrate the resolver into a more complex application.
use trust_dns_resolver::name_server::TokioConnectionProvider;
#[cfg(all(feature = "tokio-runtime", feature = "system-config"))] #[cfg(all(feature = "tokio-runtime", feature = "system-config"))]
fn main() { fn main() {
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use trust_dns_resolver::name_server::TokioRuntimeProvider;
use trust_dns_resolver::TokioAsyncResolver; use trust_dns_resolver::TokioAsyncResolver;
tracing_subscriber::fmt::init(); tracing_subscriber::fmt::init();
@@ -19,7 +20,7 @@ fn main() {
#[cfg(any(unix, windows))] #[cfg(any(unix, windows))]
{ {
// use the system resolver configuration // use the system resolver configuration
TokioAsyncResolver::from_system_conf(TokioRuntimeProvider::new()) TokioAsyncResolver::from_system_conf(TokioConnectionProvider::default())
} }
// For other operating systems, we can use one of the preconfigured definitions // For other operating systems, we can use one of the preconfigured definitions

View File

@@ -25,8 +25,7 @@ use crate::error::*;
use crate::lookup::{self, Lookup, LookupEither, LookupFuture}; use crate::lookup::{self, Lookup, LookupEither, LookupFuture};
use crate::lookup_ip::{LookupIp, LookupIpFuture}; use crate::lookup_ip::{LookupIp, LookupIpFuture};
#[cfg(feature = "tokio-runtime")] #[cfg(feature = "tokio-runtime")]
use crate::name_server::TokioRuntimeProvider; use crate::name_server::{ConnectionProvider, NameServerPool, TokioConnectionProvider};
use crate::name_server::{NameServerPool, RuntimeProvider};
use crate::Hosts; use crate::Hosts;
@@ -57,7 +56,7 @@ use crate::Hosts;
/// linked to it. When all of its [`AsyncResolver`]s have been dropped, the /// linked to it. When all of its [`AsyncResolver`]s have been dropped, the
/// background future will finish. /// background future will finish.
#[derive(Clone)] #[derive(Clone)]
pub struct AsyncResolver<P: RuntimeProvider> { pub struct AsyncResolver<P: ConnectionProvider> {
config: ResolverConfig, config: ResolverConfig,
options: ResolverOpts, options: ResolverOpts,
client_cache: CachingClient<LookupEither<P>, ResolveError>, client_cache: CachingClient<LookupEither<P>, ResolveError>,
@@ -67,7 +66,7 @@ pub struct AsyncResolver<P: RuntimeProvider> {
/// An AsyncResolver used with Tokio /// An AsyncResolver used with Tokio
#[cfg(feature = "tokio-runtime")] #[cfg(feature = "tokio-runtime")]
#[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))] #[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))]
pub type TokioAsyncResolver = AsyncResolver<TokioRuntimeProvider>; pub type TokioAsyncResolver = AsyncResolver<TokioConnectionProvider>;
macro_rules! lookup_fn { macro_rules! lookup_fn {
($p:ident, $l:ty, $r:path) => { ($p:ident, $l:ty, $r:path) => {
@@ -119,7 +118,7 @@ impl TokioAsyncResolver {
/// documentation for `AsyncResolver` for more information on how to use /// documentation for `AsyncResolver` for more information on how to use
/// the background future. /// the background future.
pub fn tokio(config: ResolverConfig, options: ResolverOpts) -> Self { pub fn tokio(config: ResolverConfig, options: ResolverOpts) -> Self {
Self::new(config, options, TokioRuntimeProvider::new()) Self::new(config, options, TokioConnectionProvider::default())
} }
/// Constructs a new Tokio based Resolver with the system configuration. /// Constructs a new Tokio based Resolver with the system configuration.
@@ -132,11 +131,11 @@ impl TokioAsyncResolver {
doc(cfg(all(feature = "system-config", any(unix, target_os = "windows")))) doc(cfg(all(feature = "system-config", any(unix, target_os = "windows"))))
)] )]
pub fn tokio_from_system_conf() -> Result<Self, ResolveError> { pub fn tokio_from_system_conf() -> Result<Self, ResolveError> {
Self::from_system_conf(TokioRuntimeProvider::new()) Self::from_system_conf(TokioConnectionProvider::default())
} }
} }
impl<R: RuntimeProvider> AsyncResolver<R> { impl<R: ConnectionProvider> AsyncResolver<R> {
/// Construct a new generic `AsyncResolver` with the provided configuration. /// Construct a new generic `AsyncResolver` with the provided configuration.
/// ///
/// see [TokioAsyncResolver::tokio(..)] instead. /// see [TokioAsyncResolver::tokio(..)] instead.
@@ -177,7 +176,7 @@ impl<R: RuntimeProvider> AsyncResolver<R> {
} }
} }
impl<P: RuntimeProvider> AsyncResolver<P> { impl<P: ConnectionProvider> AsyncResolver<P> {
/// Construct a new `AsyncResolver` with the provided configuration. /// Construct a new `AsyncResolver` with the provided configuration.
/// ///
/// # Arguments /// # Arguments
@@ -441,7 +440,7 @@ impl<P: RuntimeProvider> AsyncResolver<P> {
lookup_fn!(txt_lookup, lookup::TxtLookup, RecordType::TXT); lookup_fn!(txt_lookup, lookup::TxtLookup, RecordType::TXT);
} }
impl<P: RuntimeProvider> fmt::Debug for AsyncResolver<P> { impl<P: ConnectionProvider> fmt::Debug for AsyncResolver<P> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("AsyncResolver") f.debug_struct("AsyncResolver")
.field("request_tx", &"...") .field("request_tx", &"...")
@@ -457,12 +456,12 @@ pub mod testing {
use std::{net::*, str::FromStr}; use std::{net::*, str::FromStr};
use crate::config::{LookupIpStrategy, NameServerConfig, ResolverConfig, ResolverOpts}; use crate::config::{LookupIpStrategy, NameServerConfig, ResolverConfig, ResolverOpts};
use crate::name_server::RuntimeProvider; use crate::name_server::ConnectionProvider;
use crate::AsyncResolver; use crate::AsyncResolver;
use proto::{rr::Name, Executor}; use proto::{rr::Name, Executor};
/// Test IP lookup from URLs. /// Test IP lookup from URLs.
pub fn lookup_test<E: Executor, R: RuntimeProvider>( pub fn lookup_test<E: Executor, R: ConnectionProvider>(
config: ResolverConfig, config: ResolverConfig,
mut exec: E, mut exec: E,
handle: R, handle: R,
@@ -489,7 +488,7 @@ pub mod testing {
} }
/// Test IP lookup from IP literals. /// Test IP lookup from IP literals.
pub fn ip_lookup_test<E: Executor, R: RuntimeProvider>(mut exec: E, handle: R) { pub fn ip_lookup_test<E: Executor, R: ConnectionProvider>(mut exec: E, handle: R) {
let resolver = let resolver =
AsyncResolver::<R>::new(ResolverConfig::default(), ResolverOpts::default(), handle); AsyncResolver::<R>::new(ResolverConfig::default(), ResolverOpts::default(), handle);
@@ -515,7 +514,7 @@ pub mod testing {
} }
/// Test IP lookup from IP literals across threads. /// Test IP lookup from IP literals across threads.
pub fn ip_lookup_across_threads_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn ip_lookup_across_threads_test<E: Executor + Send + 'static, R: ConnectionProvider>(
handle: R, handle: R,
) { ) {
// Test ensuring that running the background task on a separate // Test ensuring that running the background task on a separate
@@ -567,7 +566,7 @@ pub mod testing {
/// Test IP lookup from URLs with DNSSEC validation. /// Test IP lookup from URLs with DNSSEC validation.
#[cfg(feature = "dnssec")] #[cfg(feature = "dnssec")]
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))] #[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
pub fn sec_lookup_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn sec_lookup_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -607,7 +606,7 @@ pub mod testing {
#[allow(deprecated)] #[allow(deprecated)]
#[cfg(feature = "dnssec")] #[cfg(feature = "dnssec")]
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))] #[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
pub fn sec_lookup_fails_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn sec_lookup_fails_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -650,7 +649,7 @@ pub mod testing {
/// Test AsyncResolver created from system configuration with IP lookup. /// Test AsyncResolver created from system configuration with IP lookup.
#[cfg(feature = "system-config")] #[cfg(feature = "system-config")]
#[cfg_attr(docsrs, doc(cfg(feature = "system-config")))] #[cfg_attr(docsrs, doc(cfg(feature = "system-config")))]
pub fn system_lookup_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn system_lookup_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -679,7 +678,7 @@ pub mod testing {
/// Test AsyncResolver created from system configuration with host lookups. /// Test AsyncResolver created from system configuration with host lookups.
#[cfg(feature = "system-config")] #[cfg(feature = "system-config")]
#[cfg_attr(docsrs, doc(cfg(feature = "system-config")))] #[cfg_attr(docsrs, doc(cfg(feature = "system-config")))]
pub fn hosts_lookup_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn hosts_lookup_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -701,7 +700,7 @@ pub mod testing {
} }
/// Test fqdn. /// Test fqdn.
pub fn fqdn_test<E: Executor + Send + 'static, R: RuntimeProvider>(mut exec: E, handle: R) { pub fn fqdn_test<E: Executor + Send + 'static, R: ConnectionProvider>(mut exec: E, handle: R) {
let domain = Name::from_str("incorrect.example.com.").unwrap(); let domain = Name::from_str("incorrect.example.com.").unwrap();
let search = vec![ let search = vec![
Name::from_str("bad.example.com.").unwrap(), Name::from_str("bad.example.com.").unwrap(),
@@ -734,7 +733,7 @@ pub mod testing {
} }
/// Test ndots with non-fqdn. /// Test ndots with non-fqdn.
pub fn ndots_test<E: Executor + Send + 'static, R: RuntimeProvider>(mut exec: E, handle: R) { pub fn ndots_test<E: Executor + Send + 'static, R: ConnectionProvider>(mut exec: E, handle: R) {
let domain = Name::from_str("incorrect.example.com.").unwrap(); let domain = Name::from_str("incorrect.example.com.").unwrap();
let search = vec![ let search = vec![
Name::from_str("bad.example.com.").unwrap(), Name::from_str("bad.example.com.").unwrap(),
@@ -770,7 +769,7 @@ pub mod testing {
} }
/// Test large ndots with non-fqdn. /// Test large ndots with non-fqdn.
pub fn large_ndots_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn large_ndots_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -809,7 +808,7 @@ pub mod testing {
} }
/// Test domain search. /// Test domain search.
pub fn domain_search_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn domain_search_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -849,7 +848,7 @@ pub mod testing {
} }
/// Test search lists. /// Test search lists.
pub fn search_list_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn search_list_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -888,7 +887,7 @@ pub mod testing {
} }
/// Test idna. /// Test idna.
pub fn idna_test<E: Executor + Send + 'static, R: RuntimeProvider>(mut exec: E, handle: R) { pub fn idna_test<E: Executor + Send + 'static, R: ConnectionProvider>(mut exec: E, handle: R) {
let resolver = let resolver =
AsyncResolver::<R>::new(ResolverConfig::default(), ResolverOpts::default(), handle); AsyncResolver::<R>::new(ResolverConfig::default(), ResolverOpts::default(), handle);
@@ -902,7 +901,7 @@ pub mod testing {
} }
/// Test ipv4 localhost. /// Test ipv4 localhost.
pub fn localhost_ipv4_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn localhost_ipv4_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -927,7 +926,7 @@ pub mod testing {
} }
/// Test ipv6 localhost. /// Test ipv6 localhost.
pub fn localhost_ipv6_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn localhost_ipv6_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -952,7 +951,7 @@ pub mod testing {
} }
/// Test ipv4 search with large ndots. /// Test ipv4 search with large ndots.
pub fn search_ipv4_large_ndots_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn search_ipv4_large_ndots_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -981,7 +980,7 @@ pub mod testing {
} }
/// Test ipv6 search with large ndots. /// Test ipv6 search with large ndots.
pub fn search_ipv6_large_ndots_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn search_ipv6_large_ndots_test<E: Executor + Send + 'static, R: ConnectionProvider>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -1010,7 +1009,10 @@ pub mod testing {
} }
/// Test ipv6 name parse fails. /// Test ipv6 name parse fails.
pub fn search_ipv6_name_parse_fails_test<E: Executor + Send + 'static, R: RuntimeProvider>( pub fn search_ipv6_name_parse_fails_test<
E: Executor + Send + 'static,
R: ConnectionProvider,
>(
mut exec: E, mut exec: E,
handle: R, handle: R,
) { ) {
@@ -1046,7 +1048,7 @@ mod tests {
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use crate::config::{ResolverConfig, ResolverOpts}; use crate::config::{ResolverConfig, ResolverOpts};
use crate::name_server::{GenericConnection, TokioRuntimeProvider}; use crate::name_server::GenericConnection;
use super::*; use super::*;
@@ -1065,8 +1067,8 @@ mod tests {
assert!(is_send_t::<ResolverOpts>()); assert!(is_send_t::<ResolverOpts>());
assert!(is_sync_t::<ResolverOpts>()); assert!(is_sync_t::<ResolverOpts>());
assert!(is_send_t::<AsyncResolver<TokioRuntimeProvider>>()); assert!(is_send_t::<AsyncResolver<TokioConnectionProvider>>());
assert!(is_sync_t::<AsyncResolver<TokioRuntimeProvider>>()); assert!(is_sync_t::<AsyncResolver<TokioConnectionProvider>>());
assert!(is_send_t::<DnsRequest>()); assert!(is_send_t::<DnsRequest>());
assert!(is_send_t::<LookupIpFuture<GenericConnection, ResolveError>>()); assert!(is_send_t::<LookupIpFuture<GenericConnection, ResolveError>>());
@@ -1077,40 +1079,44 @@ mod tests {
fn test_lookup_google() { fn test_lookup_google() {
use super::testing::lookup_test; use super::testing::lookup_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime"); let io_loop = Runtime::new().expect("failed to create tokio runtime");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
lookup_test::<Runtime, TokioRuntimeProvider>(ResolverConfig::google(), io_loop, handle) lookup_test::<Runtime, TokioConnectionProvider>(ResolverConfig::google(), io_loop, handle)
} }
#[test] #[test]
fn test_lookup_cloudflare() { fn test_lookup_cloudflare() {
use super::testing::lookup_test; use super::testing::lookup_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime"); let io_loop = Runtime::new().expect("failed to create tokio runtime");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
lookup_test::<Runtime, TokioRuntimeProvider>(ResolverConfig::cloudflare(), io_loop, handle) lookup_test::<Runtime, TokioConnectionProvider>(
ResolverConfig::cloudflare(),
io_loop,
handle,
)
} }
#[test] #[test]
fn test_lookup_quad9() { fn test_lookup_quad9() {
use super::testing::lookup_test; use super::testing::lookup_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime"); let io_loop = Runtime::new().expect("failed to create tokio runtime");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
lookup_test::<Runtime, TokioRuntimeProvider>(ResolverConfig::quad9(), io_loop, handle) lookup_test::<Runtime, TokioConnectionProvider>(ResolverConfig::quad9(), io_loop, handle)
} }
#[test] #[test]
fn test_ip_lookup() { fn test_ip_lookup() {
use super::testing::ip_lookup_test; use super::testing::ip_lookup_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime"); let io_loop = Runtime::new().expect("failed to create tokio runtime");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
ip_lookup_test::<Runtime, TokioRuntimeProvider>(io_loop, handle) ip_lookup_test::<Runtime, TokioConnectionProvider>(io_loop, handle)
} }
#[test] #[test]
fn test_ip_lookup_across_threads() { fn test_ip_lookup_across_threads() {
use super::testing::ip_lookup_across_threads_test; use super::testing::ip_lookup_across_threads_test;
let _io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let _io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
ip_lookup_across_threads_test::<Runtime, TokioRuntimeProvider>(handle) ip_lookup_across_threads_test::<Runtime, TokioConnectionProvider>(handle)
} }
#[test] #[test]
@@ -1118,8 +1124,8 @@ mod tests {
fn test_sec_lookup() { fn test_sec_lookup() {
use super::testing::sec_lookup_test; use super::testing::sec_lookup_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
sec_lookup_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); sec_lookup_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
@@ -1127,8 +1133,8 @@ mod tests {
fn test_sec_lookup_fails() { fn test_sec_lookup_fails() {
use super::testing::sec_lookup_fails_test; use super::testing::sec_lookup_fails_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
sec_lookup_fails_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); sec_lookup_fails_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
@@ -1138,8 +1144,8 @@ mod tests {
fn test_system_lookup() { fn test_system_lookup() {
use super::testing::system_lookup_test; use super::testing::system_lookup_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
system_lookup_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); system_lookup_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
@@ -1150,105 +1156,105 @@ mod tests {
fn test_hosts_lookup() { fn test_hosts_lookup() {
use super::testing::hosts_lookup_test; use super::testing::hosts_lookup_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
hosts_lookup_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); hosts_lookup_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_fqdn() { fn test_fqdn() {
use super::testing::fqdn_test; use super::testing::fqdn_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
fqdn_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); fqdn_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_ndots() { fn test_ndots() {
use super::testing::ndots_test; use super::testing::ndots_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
ndots_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); ndots_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_large_ndots() { fn test_large_ndots() {
use super::testing::large_ndots_test; use super::testing::large_ndots_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
large_ndots_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); large_ndots_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_domain_search() { fn test_domain_search() {
use super::testing::domain_search_test; use super::testing::domain_search_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
domain_search_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); domain_search_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_search_list() { fn test_search_list() {
use super::testing::search_list_test; use super::testing::search_list_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
search_list_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); search_list_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_idna() { fn test_idna() {
use super::testing::idna_test; use super::testing::idna_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
idna_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); idna_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_localhost_ipv4() { fn test_localhost_ipv4() {
use super::testing::localhost_ipv4_test; use super::testing::localhost_ipv4_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
localhost_ipv4_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); localhost_ipv4_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_localhost_ipv6() { fn test_localhost_ipv6() {
use super::testing::localhost_ipv6_test; use super::testing::localhost_ipv6_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
localhost_ipv6_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); localhost_ipv6_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_search_ipv4_large_ndots() { fn test_search_ipv4_large_ndots() {
use super::testing::search_ipv4_large_ndots_test; use super::testing::search_ipv4_large_ndots_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
search_ipv4_large_ndots_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); search_ipv4_large_ndots_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_search_ipv6_large_ndots() { fn test_search_ipv6_large_ndots() {
use super::testing::search_ipv6_large_ndots_test; use super::testing::search_ipv6_large_ndots_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
search_ipv6_large_ndots_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); search_ipv6_large_ndots_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_search_ipv6_name_parse_fails() { fn test_search_ipv6_name_parse_fails() {
use super::testing::search_ipv6_name_parse_fails_test; use super::testing::search_ipv6_name_parse_fails_test;
let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop"); let io_loop = Runtime::new().expect("failed to create tokio runtime io_loop");
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
search_ipv6_name_parse_fails_test::<Runtime, TokioRuntimeProvider>(io_loop, handle); search_ipv6_name_parse_fails_test::<Runtime, TokioConnectionProvider>(io_loop, handle);
} }
#[test] #[test]
fn test_build_names_onion() { fn test_build_names_onion() {
let handle = TokioRuntimeProvider::new(); let handle = TokioConnectionProvider::default();
let mut config = ResolverConfig::default(); let mut config = ResolverConfig::default();
config.add_search(Name::from_ascii("example.com.").unwrap()); config.add_search(Name::from_ascii("example.com.").unwrap());
let resolver = let resolver =
AsyncResolver::<TokioRuntimeProvider>::new(config, ResolverOpts::default(), handle); AsyncResolver::<TokioConnectionProvider>::new(config, ResolverOpts::default(), handle);
let tor_address = [ let tor_address = [
Name::from_ascii("2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion") Name::from_ascii("2gzyxa5ihm7nsggfxnu52rck2vv4rvmdlkiu3zzui5du4xyclen53wid.onion")
.unwrap(), .unwrap(),

View File

@@ -71,7 +71,7 @@ mod tests {
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use crate::config::{ResolverConfig, ResolverOpts}; use crate::config::{ResolverConfig, ResolverOpts};
use crate::name_server::TokioRuntimeProvider; use crate::name_server::TokioConnectionProvider;
use crate::TokioAsyncResolver; use crate::TokioAsyncResolver;
fn https_test(config: ResolverConfig) { fn https_test(config: ResolverConfig) {
@@ -83,7 +83,7 @@ mod tests {
try_tcp_on_error: true, try_tcp_on_error: true,
..ResolverOpts::default() ..ResolverOpts::default()
}, },
TokioRuntimeProvider::default(), TokioConnectionProvider::default(),
); );
let response = io_loop let response = io_loop

View File

@@ -28,7 +28,6 @@ use crate::{
dns_lru::MAX_TTL, dns_lru::MAX_TTL,
error::*, error::*,
lookup_ip::LookupIpIter, lookup_ip::LookupIpIter,
name_server::{GenericNameServerPool, RuntimeProvider},
proto::{ proto::{
error::ProtoError, error::ProtoError,
op::Query, op::Query,
@@ -41,6 +40,7 @@ use crate::{
}, },
}; };
use crate::name_server::{ConnectionProvider, NameServerPool};
#[cfg(feature = "dnssec")] #[cfg(feature = "dnssec")]
use proto::DnssecDnsHandle; use proto::DnssecDnsHandle;
@@ -185,14 +185,14 @@ impl Iterator for LookupIntoIter {
/// Different lookup options for the lookup attempts and validation /// Different lookup options for the lookup attempts and validation
#[derive(Clone)] #[derive(Clone)]
#[doc(hidden)] #[doc(hidden)]
pub enum LookupEither<P: RuntimeProvider + Send> { pub enum LookupEither<P: ConnectionProvider + Send> {
Retry(RetryDnsHandle<GenericNameServerPool<P>>), Retry(RetryDnsHandle<NameServerPool<P>>),
#[cfg(feature = "dnssec")] #[cfg(feature = "dnssec")]
#[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))] #[cfg_attr(docsrs, doc(cfg(feature = "dnssec")))]
Secure(DnssecDnsHandle<RetryDnsHandle<GenericNameServerPool<P>>>), Secure(DnssecDnsHandle<RetryDnsHandle<NameServerPool<P>>>),
} }
impl<P: RuntimeProvider> DnsHandle for LookupEither<P> { impl<P: ConnectionProvider> DnsHandle for LookupEither<P> {
type Response = Pin<Box<dyn Stream<Item = Result<DnsResponse, ResolveError>> + Send>>; type Response = Pin<Box<dyn Stream<Item = Result<DnsResponse, ResolveError>> + Send>>;
type Error = ResolveError; type Error = ResolveError;

View File

@@ -14,8 +14,8 @@ mod name_server_pool;
mod name_server_state; mod name_server_state;
mod name_server_stats; mod name_server_stats;
pub use self::connection_provider::GenericConnection; pub use self::connection_provider::{ConnectionProvider, RuntimeProvider, Spawn};
pub use self::connection_provider::{RuntimeProvider, Spawn}; pub use self::connection_provider::{GenericConnection, GenericConnector};
#[cfg(feature = "mdns")] #[cfg(feature = "mdns")]
#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] #[cfg_attr(docsrs, doc(cfg(feature = "mdns")))]
pub(crate) use self::name_server::mdns_nameserver; pub(crate) use self::name_server::mdns_nameserver;
@@ -26,4 +26,6 @@ use self::name_server_stats::NameServerStats;
#[cfg(feature = "tokio-runtime")] #[cfg(feature = "tokio-runtime")]
#[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))] #[cfg_attr(docsrs, doc(cfg(feature = "tokio-runtime")))]
pub use self::connection_provider::tokio_runtime::{TokioHandle, TokioRuntimeProvider}; pub use self::connection_provider::tokio_runtime::{
TokioConnectionProvider, TokioHandle, TokioRuntimeProvider,
};

View File

@@ -22,51 +22,47 @@ use tracing::debug;
use crate::config::{NameServerConfig, ResolverOpts}; use crate::config::{NameServerConfig, ResolverOpts};
use crate::error::ResolveError; use crate::error::ResolveError;
use crate::name_server::{GenericConnection, NameServerState, NameServerStats, RuntimeProvider}; use crate::name_server::connection_provider::{ConnectionProvider, GenericConnector};
use crate::name_server::{NameServerState, NameServerStats, RuntimeProvider};
#[cfg(feature = "mdns")] #[cfg(feature = "mdns")]
use proto::multicast::{MdnsClientConnect, MdnsClientStream, MdnsQueryType}; use proto::multicast::{MdnsClientConnect, MdnsClientStream, MdnsQueryType};
/// This struct is used to create `DnsHandle` with the help of `P`. /// This struct is used to create `DnsHandle` with the help of `P`.
#[derive(Clone)] #[derive(Clone)]
pub struct NameServer< pub struct NameServer<P: ConnectionProvider> {
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider,
> {
config: NameServerConfig, config: NameServerConfig,
options: ResolverOpts, options: ResolverOpts,
client: Arc<Mutex<Option<C>>>, client: Arc<Mutex<Option<P::Conn>>>,
state: Arc<NameServerState>, state: Arc<NameServerState>,
stats: Arc<NameServerStats>, stats: Arc<NameServerStats>,
runtime_provider: P, connection_provider: P,
} }
/// Specifies the details of a remote NameServer used for lookups /// Specifies the details of a remote NameServer used for lookups
pub type GenericNameServer<P> = NameServer<GenericConnection, P>; pub type GenericNameServer<R> = NameServer<GenericConnector<R>>;
impl<C, P> Debug for NameServer<C, P> impl<P> Debug for NameServer<P>
where where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection, P: ConnectionProvider + Send,
P: RuntimeProvider + Send,
{ {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "config: {:?}, options: {:?}", self.config, self.options) write!(f, "config: {:?}, options: {:?}", self.config, self.options)
} }
} }
impl<C, P> NameServer<C, P> impl<P> NameServer<P>
where where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection, P: ConnectionProvider + Send,
P: RuntimeProvider + Send,
{ {
/// Construct a new Nameserver with the configuration and options. The connection provider will create UDP and TCP sockets /// Construct a new Nameserver with the configuration and options. The connection provider will create UDP and TCP sockets
pub fn new(config: NameServerConfig, options: ResolverOpts, runtime_provider: P) -> Self { pub fn new(config: NameServerConfig, options: ResolverOpts, connection_provider: P) -> Self {
Self { Self {
config, config,
options, options,
client: Arc::new(Mutex::new(None)), client: Arc::new(Mutex::new(None)),
state: Arc::new(NameServerState::init(None)), state: Arc::new(NameServerState::init(None)),
stats: Arc::new(NameServerStats::default()), stats: Arc::new(NameServerStats::default()),
runtime_provider, connection_provider,
} }
} }
@@ -74,8 +70,8 @@ where
pub fn from_conn( pub fn from_conn(
config: NameServerConfig, config: NameServerConfig,
options: ResolverOpts, options: ResolverOpts,
client: C, client: P::Conn,
runtime_provider: P, connection_provider: P,
) -> Self { ) -> Self {
Self { Self {
config, config,
@@ -83,7 +79,7 @@ where
client: Arc::new(Mutex::new(Some(client))), client: Arc::new(Mutex::new(Some(client))),
state: Arc::new(NameServerState::init(None)), state: Arc::new(NameServerState::init(None)),
stats: Arc::new(NameServerStats::default()), stats: Arc::new(NameServerStats::default()),
runtime_provider, connection_provider,
} }
} }
@@ -102,7 +98,7 @@ where
/// This will return a mutable client to allows for sending messages. /// This will return a mutable client to allows for sending messages.
/// ///
/// If the connection is in a failed state, then this will establish a new connection /// If the connection is in a failed state, then this will establish a new connection
async fn connected_mut_client(&mut self) -> Result<C, ResolveError> { async fn connected_mut_client(&mut self) -> Result<P::Conn, ResolveError> {
let mut client = self.client.lock().await; let mut client = self.client.lock().await;
// if this is in a failure state // if this is in a failure state
@@ -112,11 +108,10 @@ where
// TODO: we need the local EDNS options // TODO: we need the local EDNS options
self.state.reinit(None); self.state.reinit(None);
let new_client = Box::pin(C::new_connection( let new_client = Box::pin(
&self.runtime_provider, self.connection_provider
&self.config, .new_connection(&self.config, &self.options),
&self.options, )
))
.await?; .await?;
// establish a new connection // establish a new connection
@@ -177,10 +172,9 @@ where
} }
} }
impl<C, P> DnsHandle for NameServer<C, P> impl<P> DnsHandle for NameServer<P>
where where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection, P: ConnectionProvider + Clone,
P: RuntimeProvider,
{ {
type Response = Pin<Box<dyn Stream<Item = Result<DnsResponse, ResolveError>> + Send>>; type Response = Pin<Box<dyn Stream<Item = Result<DnsResponse, ResolveError>> + Send>>;
type Error = ResolveError; type Error = ResolveError;
@@ -197,10 +191,9 @@ where
} }
} }
impl<C, P> Ord for NameServer<C, P> impl<P> Ord for NameServer<P>
where where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection, P: ConnectionProvider + Send,
P: RuntimeProvider + Send,
{ {
/// Custom implementation of Ord for NameServer which incorporates the performance of the connection into it's ranking /// Custom implementation of Ord for NameServer which incorporates the performance of the connection into it's ranking
fn cmp(&self, other: &Self) -> Ordering { fn cmp(&self, other: &Self) -> Ordering {
@@ -213,20 +206,18 @@ where
} }
} }
impl<C, P> PartialOrd for NameServer<C, P> impl<P> PartialOrd for NameServer<P>
where where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection, P: ConnectionProvider + Send,
P: RuntimeProvider + Send,
{ {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other)) Some(self.cmp(other))
} }
} }
impl<C, P> PartialEq for NameServer<C, P> impl<P> PartialEq for NameServer<P>
where where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection, P: ConnectionProvider + Send,
P: RuntimeProvider + Send,
{ {
/// NameServers are equal if the config (connection information) are equal /// NameServers are equal if the config (connection information) are equal
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
@@ -234,12 +225,7 @@ where
} }
} }
impl<C, P> Eq for NameServer<C, P> impl<P> Eq for NameServer<P> where P: ConnectionProvider + Send {}
where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + Send,
{
}
// TODO: once IPv6 is better understood, also make this a binary keep. // TODO: once IPv6 is better understood, also make this a binary keep.
#[cfg(feature = "mdns")] #[cfg(feature = "mdns")]
@@ -249,7 +235,7 @@ pub(crate) fn mdns_nameserver<P>(
trust_negative_responses: bool, trust_negative_responses: bool,
) -> GenericNameServer<P> ) -> GenericNameServer<P>
where where
P: RuntimeProvider, P: ConnectionProvider,
{ {
let config = NameServerConfig { let config = NameServerConfig {
socket_addr: *MDNS_IPV4, socket_addr: *MDNS_IPV4,
@@ -290,7 +276,7 @@ mod tests {
use super::*; use super::*;
use crate::config::Protocol; use crate::config::Protocol;
use crate::name_server::TokioRuntimeProvider; use crate::name_server::TokioConnectionProvider;
#[test] #[test]
fn test_name_server() { fn test_name_server() {
@@ -307,7 +293,11 @@ mod tests {
}; };
let io_loop = Runtime::new().unwrap(); let io_loop = Runtime::new().unwrap();
let name_server = future::lazy(|_| { let name_server = future::lazy(|_| {
GenericNameServer::new(config, ResolverOpts::default(), TokioRuntimeProvider::new()) GenericNameServer::new(
config,
ResolverOpts::default(),
TokioConnectionProvider::default(),
)
}); });
let name = Name::parse("www.example.com.", None).unwrap(); let name = Name::parse("www.example.com.", None).unwrap();
@@ -340,8 +330,9 @@ mod tests {
bind_addr: None, bind_addr: None,
}; };
let io_loop = Runtime::new().unwrap(); let io_loop = Runtime::new().unwrap();
let name_server = let name_server = future::lazy(|_| {
future::lazy(|_| GenericNameServer::new(config, options, TokioRuntimeProvider::new())); GenericNameServer::new(config, options, TokioConnectionProvider::default())
});
let name = Name::parse("www.example.com.", None).unwrap(); let name = Name::parse("www.example.com.", None).unwrap();
assert!(io_loop assert!(io_loop

View File

@@ -26,21 +26,19 @@ use crate::config::{NameServerConfigGroup, ResolverConfig, ResolverOpts, ServerO
use crate::error::{ResolveError, ResolveErrorKind}; use crate::error::{ResolveError, ResolveErrorKind};
#[cfg(feature = "mdns")] #[cfg(feature = "mdns")]
use crate::name_server; use crate::name_server;
use crate::name_server::name_server::{CreateConnection, NameServer}; use crate::name_server::connection_provider::{ConnectionProvider, GenericConnector};
use crate::name_server::name_server::NameServer;
use crate::name_server::RuntimeProvider;
#[cfg(test)] #[cfg(test)]
#[cfg(feature = "tokio-runtime")] #[cfg(feature = "tokio-runtime")]
use crate::name_server::TokioRuntimeProvider; use crate::name_server::TokioRuntimeProvider;
use crate::name_server::{GenericConnection, RuntimeProvider};
/// Abstract interface for mocking purpose /// Abstract interface for mocking purpose
#[derive(Clone)] #[derive(Clone)]
pub struct NameServerPool< pub struct NameServerPool<P: ConnectionProvider + Send + 'static> {
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + Send + 'static,
> {
// TODO: switch to FuturesMutex (Mutex will have some undesirable locking) // TODO: switch to FuturesMutex (Mutex will have some undesirable locking)
datagram_conns: Arc<[NameServer<C, P>]>, /* All NameServers must be the same type */ datagram_conns: Arc<[NameServer<P>]>, /* All NameServers must be the same type */
stream_conns: Arc<[NameServer<C, P>]>, /* All NameServers must be the same type */ stream_conns: Arc<[NameServer<P>]>, /* All NameServers must be the same type */
#[cfg(feature = "mdns")] #[cfg(feature = "mdns")]
mdns_conns: NameServer<P>, /* All NameServers must be the same type */ mdns_conns: NameServer<P>, /* All NameServers must be the same type */
options: ResolverOpts, options: ResolverOpts,
@@ -49,7 +47,7 @@ pub struct NameServerPool<
/// A pool of NameServers /// A pool of NameServers
/// ///
/// This is not expected to be used directly, see [crate::AsyncResolver]. /// This is not expected to be used directly, see [crate::AsyncResolver].
pub type GenericNameServerPool<P> = NameServerPool<GenericConnection, P>; pub type GenericNameServerPool<P> = NameServerPool<GenericConnector<P>>;
#[cfg(test)] #[cfg(test)]
#[cfg(feature = "tokio-runtime")] #[cfg(feature = "tokio-runtime")]
@@ -59,21 +57,20 @@ impl GenericNameServerPool<TokioRuntimeProvider> {
options: &ResolverOpts, options: &ResolverOpts,
runtime: TokioRuntimeProvider, runtime: TokioRuntimeProvider,
) -> Self { ) -> Self {
Self::from_config_with_provider(config, options, runtime) Self::from_config_with_provider(config, options, GenericConnector::new(runtime))
} }
} }
impl<C, P> NameServerPool<C, P> impl<P> NameServerPool<P>
where where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection, P: ConnectionProvider + 'static,
P: RuntimeProvider + 'static,
{ {
pub(crate) fn from_config_with_provider( pub(crate) fn from_config_with_provider(
config: &ResolverConfig, config: &ResolverConfig,
options: &ResolverOpts, options: &ResolverOpts,
conn_provider: P, conn_provider: P,
) -> Self { ) -> Self {
let datagram_conns: Vec<NameServer<C, P>> = config let datagram_conns: Vec<NameServer<P>> = config
.name_servers() .name_servers()
.iter() .iter()
.filter(|ns_config| ns_config.protocol.is_datagram()) .filter(|ns_config| ns_config.protocol.is_datagram())
@@ -91,7 +88,7 @@ where
}) })
.collect(); .collect();
let stream_conns: Vec<NameServer<C, P>> = config let stream_conns: Vec<NameServer<P>> = config
.name_servers() .name_servers()
.iter() .iter()
.filter(|ns_config| ns_config.protocol.is_stream()) .filter(|ns_config| ns_config.protocol.is_stream())
@@ -148,8 +145,8 @@ where
#[cfg(not(feature = "mdns"))] #[cfg(not(feature = "mdns"))]
pub fn from_nameservers( pub fn from_nameservers(
options: &ResolverOpts, options: &ResolverOpts,
datagram_conns: Vec<NameServer<C, P>>, datagram_conns: Vec<NameServer<P>>,
stream_conns: Vec<NameServer<C, P>>, stream_conns: Vec<NameServer<P>>,
) -> Self { ) -> Self {
Self { Self {
datagram_conns: Arc::from(datagram_conns), datagram_conns: Arc::from(datagram_conns),
@@ -162,9 +159,9 @@ where
#[cfg(feature = "mdns")] #[cfg(feature = "mdns")]
pub fn from_nameservers( pub fn from_nameservers(
options: &ResolverOpts, options: &ResolverOpts,
datagram_conns: Vec<NameServer<C, P>>, datagram_conns: Vec<NameServer<P>>,
stream_conns: Vec<NameServer<C, P>>, stream_conns: Vec<NameServer<P>>,
mdns_conns: NameServer<C, P>, mdns_conns: NameServer<P>,
) -> Self { ) -> Self {
GenericNameServerPool { GenericNameServerPool {
datagram_conns: Arc::from(datagram_conns), datagram_conns: Arc::from(datagram_conns),
@@ -179,8 +176,8 @@ where
#[allow(dead_code)] #[allow(dead_code)]
fn from_nameservers_test( fn from_nameservers_test(
options: &ResolverOpts, options: &ResolverOpts,
datagram_conns: Arc<[NameServer<C, P>]>, datagram_conns: Arc<[NameServer<P>]>,
stream_conns: Arc<[NameServer<C, P>]>, stream_conns: Arc<[NameServer<P>]>,
) -> Self { ) -> Self {
Self { Self {
datagram_conns, datagram_conns,
@@ -193,25 +190,24 @@ where
#[cfg(feature = "mdns")] #[cfg(feature = "mdns")]
fn from_nameservers_test( fn from_nameservers_test(
options: &ResolverOpts, options: &ResolverOpts,
datagram_conns: Arc<[NameServer<C, P>]>, datagram_conns: Arc<[NameServer<P>]>,
stream_conns: Arc<[NameServer<C, P>]>, stream_conns: Arc<[NameServer<P>]>,
mdns_conns: NameServer<C, P>, mdns_conns: NameServer<P>,
) -> Self { ) -> Self {
GenericNameServerPool { GenericNameServerPool {
datagram_conns, datagram_conns,
stream_conns, stream_conns,
mdns_conns, mdns_conns,
options: *options, options: *options,
conn_provider,
} }
} }
async fn try_send( async fn try_send(
opts: ResolverOpts, opts: ResolverOpts,
conns: Arc<[NameServer<C, P>]>, conns: Arc<[NameServer<P>]>,
request: DnsRequest, request: DnsRequest,
) -> Result<DnsResponse, ResolveError> { ) -> Result<DnsResponse, ResolveError> {
let mut conns: Vec<NameServer<C, P>> = conns.to_vec(); let mut conns: Vec<NameServer<P>> = conns.to_vec();
match opts.server_ordering_strategy { match opts.server_ordering_strategy {
// select the highest priority connection // select the highest priority connection
@@ -226,10 +222,9 @@ where
} }
} }
impl<C, P> DnsHandle for NameServerPool<C, P> impl<P> DnsHandle for NameServerPool<P>
where where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection, P: ConnectionProvider + 'static,
P: RuntimeProvider + 'static,
{ {
type Response = Pin<Box<dyn Stream<Item = Result<DnsResponse, ResolveError>> + Send>>; type Response = Pin<Box<dyn Stream<Item = Result<DnsResponse, ResolveError>> + Send>>;
type Error = ResolveError; type Error = ResolveError;
@@ -305,14 +300,13 @@ where
// TODO: we should be able to have a self-referential future here with Pin and not require cloned conns // TODO: we should be able to have a self-referential future here with Pin and not require cloned conns
/// An async function that will loop over all the conns with a max parallel request count of ops.num_concurrent_req /// An async function that will loop over all the conns with a max parallel request count of ops.num_concurrent_req
async fn parallel_conn_loop<C, P>( async fn parallel_conn_loop<P>(
mut conns: Vec<NameServer<C, P>>, mut conns: Vec<NameServer<P>>,
request: DnsRequest, request: DnsRequest,
opts: ResolverOpts, opts: ResolverOpts,
) -> Result<DnsResponse, ResolveError> ) -> Result<DnsResponse, ResolveError>
where where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection, P: ConnectionProvider + 'static,
P: RuntimeProvider + 'static,
{ {
let mut err = ResolveError::no_connections(); let mut err = ResolveError::no_connections();
// If the name server we're trying is giving us backpressure by returning ProtoErrorKind::Busy, // If the name server we're trying is giving us backpressure by returning ProtoErrorKind::Busy,
@@ -326,13 +320,13 @@ where
// close to the connection, which means the top level resolution might take substantially longer // close to the connection, which means the top level resolution might take substantially longer
// to fire than the timeout configured in `ResolverOpts`. // to fire than the timeout configured in `ResolverOpts`.
let mut backoff = Duration::from_millis(20); let mut backoff = Duration::from_millis(20);
let mut busy = SmallVec::<[NameServer<C, P>; 2]>::new(); let mut busy = SmallVec::<[NameServer<P>; 2]>::new();
loop { loop {
let request_cont = request.clone(); let request_cont = request.clone();
// construct the parallel requests, 2 is the default // construct the parallel requests, 2 is the default
let mut par_conns = SmallVec::<[NameServer<C, P>; 2]>::new(); let mut par_conns = SmallVec::<[NameServer<P>; 2]>::new();
let count = conns.len().min(opts.num_concurrent_reqs.max(1)); let count = conns.len().min(opts.num_concurrent_reqs.max(1));
// Shuffe DNS NameServers to avoid overloads to the first configured ones // Shuffe DNS NameServers to avoid overloads to the first configured ones
@@ -353,7 +347,10 @@ where
if par_conns.is_empty() { if par_conns.is_empty() {
if !busy.is_empty() && backoff < Duration::from_millis(300) { if !busy.is_empty() && backoff < Duration::from_millis(300) {
P::Timer::delay_for(backoff).await; <<P as ConnectionProvider>::RuntimeProvider as RuntimeProvider>::Timer::delay_for(
backoff,
)
.await;
conns.extend(busy.drain(..)); conns.extend(busy.drain(..));
backoff *= 2; backoff *= 2;
continue; continue;
@@ -486,8 +483,8 @@ mod tests {
use super::*; use super::*;
use crate::config::NameServerConfig; use crate::config::NameServerConfig;
use crate::config::Protocol; use crate::config::Protocol;
use crate::name_server::GenericNameServer;
use crate::name_server::TokioRuntimeProvider; use crate::name_server::TokioRuntimeProvider;
use crate::name_server::{GenericNameServer, TokioConnectionProvider};
#[ignore] #[ignore]
// because of there is a real connection that needs a reasonable timeout // because of there is a real connection that needs a reasonable timeout
@@ -564,7 +561,7 @@ mod tests {
#[test] #[test]
fn test_multi_use_conns() { fn test_multi_use_conns() {
let io_loop = Runtime::new().unwrap(); let io_loop = Runtime::new().unwrap();
let conn_provider = TokioRuntimeProvider::new(); let conn_provider = TokioConnectionProvider::default();
let tcp = NameServerConfig { let tcp = NameServerConfig {
socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)), 53), socket_addr: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)), 53),
@@ -584,15 +581,18 @@ mod tests {
let name_server = GenericNameServer::new(ns_config, opts, conn_provider); let name_server = GenericNameServer::new(ns_config, opts, conn_provider);
let name_servers: Arc<[_]> = Arc::from([name_server]); let name_servers: Arc<[_]> = Arc::from([name_server]);
#[cfg(not(feature = "mdns"))]
let mut pool = GenericNameServerPool::from_nameservers_test( let mut pool = GenericNameServerPool::from_nameservers_test(
&opts, &opts,
Arc::from([]), Arc::from([]),
Arc::clone(&name_servers), Arc::clone(&name_servers),
);
#[cfg(feature = "mdns")] #[cfg(feature = "mdns")]
name_server::mdns_nameserver( let mut pool = GenericNameServerPool::from_nameservers_test(
opts, &opts,
TokioConnectionProvider::new(TokioHandle::default()), Arc::from([]),
), Arc::clone(&name_servers),
name_server::mdns_nameserver(opts, TokioConnectionProvider::default(), false),
); );
let name = Name::from_str("www.example.com.").unwrap(); let name = Name::from_str("www.example.com.").unwrap();

View File

@@ -20,7 +20,7 @@ use crate::error::*;
use crate::lookup; use crate::lookup;
use crate::lookup::Lookup; use crate::lookup::Lookup;
use crate::lookup_ip::LookupIp; use crate::lookup_ip::LookupIp;
use crate::name_server::TokioRuntimeProvider; use crate::name_server::TokioConnectionProvider;
use crate::AsyncResolver; use crate::AsyncResolver;
/// The Resolver is used for performing DNS queries. /// The Resolver is used for performing DNS queries.
@@ -35,7 +35,7 @@ pub struct Resolver {
// drawbacks. One major issues, is if this Resolver is shared across threads, it will cause all to block on any // drawbacks. One major issues, is if this Resolver is shared across threads, it will cause all to block on any
// query. A TLS on the other hand would not, at the cost of only allowing a Resolver to be configured once per Thread // query. A TLS on the other hand would not, at the cost of only allowing a Resolver to be configured once per Thread
runtime: Mutex<Runtime>, runtime: Mutex<Runtime>,
async_resolver: AsyncResolver<TokioRuntimeProvider>, async_resolver: AsyncResolver<TokioConnectionProvider>,
} }
macro_rules! lookup_fn { macro_rules! lookup_fn {
@@ -80,7 +80,8 @@ impl Resolver {
builder.enable_all(); builder.enable_all();
let runtime = builder.build()?; let runtime = builder.build()?;
let async_resolver = AsyncResolver::new(config, options, TokioRuntimeProvider::new()); let async_resolver =
AsyncResolver::new(config, options, TokioConnectionProvider::default());
Ok(Self { Ok(Self {
runtime: Mutex::new(runtime), runtime: Mutex::new(runtime),

View File

@@ -33,7 +33,7 @@ mod tests {
use tokio::runtime::Runtime; use tokio::runtime::Runtime;
use crate::config::{ResolverConfig, ResolverOpts}; use crate::config::{ResolverConfig, ResolverOpts};
use crate::name_server::TokioRuntimeProvider; use crate::name_server::TokioConnectionProvider;
use crate::TokioAsyncResolver; use crate::TokioAsyncResolver;
fn tls_test(config: ResolverConfig) { fn tls_test(config: ResolverConfig) {
@@ -45,7 +45,7 @@ mod tests {
try_tcp_on_error: true, try_tcp_on_error: true,
..ResolverOpts::default() ..ResolverOpts::default()
}, },
TokioRuntimeProvider::default(), TokioConnectionProvider::default(),
); );
let response = io_loop let response = io_loop