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"]
use trust_dns_resolver::name_server::{ConnectionProvider, GenericConnector};
#[cfg(feature = "tokio-runtime")]
use {
std::future::Future,
@@ -57,7 +58,7 @@ impl RuntimeProvider for PrintProvider {
}
#[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();
// There can be many addresses associated with the name,
@@ -81,7 +82,7 @@ async fn main() {
let resolver = AsyncResolver::new(
ResolverConfig::google(),
ResolverOpts::default(),
PrintProvider::default(),
GenericConnector::new(PrintProvider::default()),
);
lookup_test(resolver).await;
@@ -90,7 +91,7 @@ async fn main() {
let resolver2 = AsyncResolver::new(
ResolverConfig::cloudflare_https(),
ResolverOpts::default(),
PrintProvider::default(),
GenericConnector::new(PrintProvider::default()),
);
lookup_test(resolver2).await;
}

View File

@@ -1,5 +1,7 @@
#![recursion_limit = "128"]
use trust_dns_resolver::name_server::TokioConnectionProvider;
#[cfg(all(feature = "tokio-runtime", feature = "system-config"))]
fn main() {
tokio::runtime::Builder::new_multi_thread()
@@ -13,7 +15,6 @@ fn main() {
#[cfg(all(feature = "tokio-runtime", feature = "system-config"))]
async fn tokio_main() {
use trust_dns_resolver::name_server::TokioRuntimeProvider;
use trust_dns_resolver::TokioAsyncResolver;
let resolver = {
@@ -21,7 +22,7 @@ async fn tokio_main() {
#[cfg(any(unix, windows))]
{
// 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
@@ -59,7 +60,7 @@ async fn tokio_main() {
}
#[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],
resolver: &trust_dns_resolver::AsyncResolver<P>,
) -> tokio::time::Duration {

View File

@@ -1,5 +1,6 @@
#![recursion_limit = "128"]
use trust_dns_resolver::name_server::TokioConnectionProvider;
#[cfg(all(feature = "tokio-runtime", feature = "system-config"))]
use {
futures_util::future,
@@ -8,7 +9,7 @@ use {
std::io,
std::net::SocketAddr,
std::task::Poll,
trust_dns_resolver::{name_server::TokioRuntimeProvider, TokioAsyncResolver},
trust_dns_resolver::TokioAsyncResolver,
trust_dns_resolver::{IntoName, TryParseIp},
};
@@ -43,7 +44,7 @@ static GLOBAL_DNS_RESOLVER: Lazy<TokioAsyncResolver> = Lazy::new(|| {
#[cfg(any(unix, windows))]
{
// 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

View File

@@ -3,10 +3,11 @@
//! 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.
use trust_dns_resolver::name_server::TokioConnectionProvider;
#[cfg(all(feature = "tokio-runtime", feature = "system-config"))]
fn main() {
use tokio::runtime::Runtime;
use trust_dns_resolver::name_server::TokioRuntimeProvider;
use trust_dns_resolver::TokioAsyncResolver;
tracing_subscriber::fmt::init();
@@ -19,7 +20,7 @@ fn main() {
#[cfg(any(unix, windows))]
{
// 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

View File

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

View File

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

View File

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

View File

@@ -14,8 +14,8 @@ mod name_server_pool;
mod name_server_state;
mod name_server_stats;
pub use self::connection_provider::GenericConnection;
pub use self::connection_provider::{RuntimeProvider, Spawn};
pub use self::connection_provider::{ConnectionProvider, RuntimeProvider, Spawn};
pub use self::connection_provider::{GenericConnection, GenericConnector};
#[cfg(feature = "mdns")]
#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))]
pub(crate) use self::name_server::mdns_nameserver;
@@ -26,4 +26,6 @@ use self::name_server_stats::NameServerStats;
#[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::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")]
use proto::multicast::{MdnsClientConnect, MdnsClientStream, MdnsQueryType};
/// This struct is used to create `DnsHandle` with the help of `P`.
#[derive(Clone)]
pub struct NameServer<
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider,
> {
pub struct NameServer<P: ConnectionProvider> {
config: NameServerConfig,
options: ResolverOpts,
client: Arc<Mutex<Option<C>>>,
client: Arc<Mutex<Option<P::Conn>>>,
state: Arc<NameServerState>,
stats: Arc<NameServerStats>,
runtime_provider: P,
connection_provider: P,
}
/// 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
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + Send,
P: ConnectionProvider + Send,
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "config: {:?}, options: {:?}", self.config, self.options)
}
}
impl<C, P> NameServer<C, P>
impl<P> NameServer<P>
where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + Send,
P: ConnectionProvider + Send,
{
/// 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 {
config,
options,
client: Arc::new(Mutex::new(None)),
state: Arc::new(NameServerState::init(None)),
stats: Arc::new(NameServerStats::default()),
runtime_provider,
connection_provider,
}
}
@@ -74,8 +70,8 @@ where
pub fn from_conn(
config: NameServerConfig,
options: ResolverOpts,
client: C,
runtime_provider: P,
client: P::Conn,
connection_provider: P,
) -> Self {
Self {
config,
@@ -83,7 +79,7 @@ where
client: Arc::new(Mutex::new(Some(client))),
state: Arc::new(NameServerState::init(None)),
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.
///
/// 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;
// if this is in a failure state
@@ -112,11 +108,10 @@ where
// TODO: we need the local EDNS options
self.state.reinit(None);
let new_client = Box::pin(C::new_connection(
&self.runtime_provider,
&self.config,
&self.options,
))
let new_client = Box::pin(
self.connection_provider
.new_connection(&self.config, &self.options),
)
.await?;
// establish a new connection
@@ -177,10 +172,9 @@ where
}
}
impl<C, P> DnsHandle for NameServer<C, P>
impl<P> DnsHandle for NameServer<P>
where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider,
P: ConnectionProvider + Clone,
{
type Response = Pin<Box<dyn Stream<Item = Result<DnsResponse, ResolveError>> + Send>>;
type Error = ResolveError;
@@ -197,10 +191,9 @@ where
}
}
impl<C, P> Ord for NameServer<C, P>
impl<P> Ord for NameServer<P>
where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + Send,
P: ConnectionProvider + Send,
{
/// Custom implementation of Ord for NameServer which incorporates the performance of the connection into it's ranking
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
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + Send,
P: ConnectionProvider + Send,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<C, P> PartialEq for NameServer<C, P>
impl<P> PartialEq for NameServer<P>
where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + Send,
P: ConnectionProvider + Send,
{
/// NameServers are equal if the config (connection information) are equal
fn eq(&self, other: &Self) -> bool {
@@ -234,12 +225,7 @@ where
}
}
impl<C, P> Eq for NameServer<C, P>
where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + Send,
{
}
impl<P> Eq for NameServer<P> where P: ConnectionProvider + Send {}
// TODO: once IPv6 is better understood, also make this a binary keep.
#[cfg(feature = "mdns")]
@@ -249,7 +235,7 @@ pub(crate) fn mdns_nameserver<P>(
trust_negative_responses: bool,
) -> GenericNameServer<P>
where
P: RuntimeProvider,
P: ConnectionProvider,
{
let config = NameServerConfig {
socket_addr: *MDNS_IPV4,
@@ -290,7 +276,7 @@ mod tests {
use super::*;
use crate::config::Protocol;
use crate::name_server::TokioRuntimeProvider;
use crate::name_server::TokioConnectionProvider;
#[test]
fn test_name_server() {
@@ -307,7 +293,11 @@ mod tests {
};
let io_loop = Runtime::new().unwrap();
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();
@@ -340,8 +330,9 @@ mod tests {
bind_addr: None,
};
let io_loop = Runtime::new().unwrap();
let name_server =
future::lazy(|_| GenericNameServer::new(config, options, TokioRuntimeProvider::new()));
let name_server = future::lazy(|_| {
GenericNameServer::new(config, options, TokioConnectionProvider::default())
});
let name = Name::parse("www.example.com.", None).unwrap();
assert!(io_loop

View File

@@ -26,21 +26,19 @@ use crate::config::{NameServerConfigGroup, ResolverConfig, ResolverOpts, ServerO
use crate::error::{ResolveError, ResolveErrorKind};
#[cfg(feature = "mdns")]
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(feature = "tokio-runtime")]
use crate::name_server::TokioRuntimeProvider;
use crate::name_server::{GenericConnection, RuntimeProvider};
/// Abstract interface for mocking purpose
#[derive(Clone)]
pub struct NameServerPool<
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + Send + 'static,
> {
pub struct NameServerPool<P: ConnectionProvider + Send + 'static> {
// TODO: switch to FuturesMutex (Mutex will have some undesirable locking)
datagram_conns: Arc<[NameServer<C, P>]>, /* All NameServers must be the same type */
stream_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<P>]>, /* All NameServers must be the same type */
#[cfg(feature = "mdns")]
mdns_conns: NameServer<P>, /* All NameServers must be the same type */
options: ResolverOpts,
@@ -49,7 +47,7 @@ pub struct NameServerPool<
/// A pool of NameServers
///
/// 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(feature = "tokio-runtime")]
@@ -59,21 +57,20 @@ impl GenericNameServerPool<TokioRuntimeProvider> {
options: &ResolverOpts,
runtime: TokioRuntimeProvider,
) -> 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
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + 'static,
P: ConnectionProvider + 'static,
{
pub(crate) fn from_config_with_provider(
config: &ResolverConfig,
options: &ResolverOpts,
conn_provider: P,
) -> Self {
let datagram_conns: Vec<NameServer<C, P>> = config
let datagram_conns: Vec<NameServer<P>> = config
.name_servers()
.iter()
.filter(|ns_config| ns_config.protocol.is_datagram())
@@ -91,7 +88,7 @@ where
})
.collect();
let stream_conns: Vec<NameServer<C, P>> = config
let stream_conns: Vec<NameServer<P>> = config
.name_servers()
.iter()
.filter(|ns_config| ns_config.protocol.is_stream())
@@ -148,8 +145,8 @@ where
#[cfg(not(feature = "mdns"))]
pub fn from_nameservers(
options: &ResolverOpts,
datagram_conns: Vec<NameServer<C, P>>,
stream_conns: Vec<NameServer<C, P>>,
datagram_conns: Vec<NameServer<P>>,
stream_conns: Vec<NameServer<P>>,
) -> Self {
Self {
datagram_conns: Arc::from(datagram_conns),
@@ -162,9 +159,9 @@ where
#[cfg(feature = "mdns")]
pub fn from_nameservers(
options: &ResolverOpts,
datagram_conns: Vec<NameServer<C, P>>,
stream_conns: Vec<NameServer<C, P>>,
mdns_conns: NameServer<C, P>,
datagram_conns: Vec<NameServer<P>>,
stream_conns: Vec<NameServer<P>>,
mdns_conns: NameServer<P>,
) -> Self {
GenericNameServerPool {
datagram_conns: Arc::from(datagram_conns),
@@ -179,8 +176,8 @@ where
#[allow(dead_code)]
fn from_nameservers_test(
options: &ResolverOpts,
datagram_conns: Arc<[NameServer<C, P>]>,
stream_conns: Arc<[NameServer<C, P>]>,
datagram_conns: Arc<[NameServer<P>]>,
stream_conns: Arc<[NameServer<P>]>,
) -> Self {
Self {
datagram_conns,
@@ -193,25 +190,24 @@ where
#[cfg(feature = "mdns")]
fn from_nameservers_test(
options: &ResolverOpts,
datagram_conns: Arc<[NameServer<C, P>]>,
stream_conns: Arc<[NameServer<C, P>]>,
mdns_conns: NameServer<C, P>,
datagram_conns: Arc<[NameServer<P>]>,
stream_conns: Arc<[NameServer<P>]>,
mdns_conns: NameServer<P>,
) -> Self {
GenericNameServerPool {
datagram_conns,
stream_conns,
mdns_conns,
options: *options,
conn_provider,
}
}
async fn try_send(
opts: ResolverOpts,
conns: Arc<[NameServer<C, P>]>,
conns: Arc<[NameServer<P>]>,
request: DnsRequest,
) -> 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 {
// 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
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + 'static,
P: ConnectionProvider + 'static,
{
type Response = Pin<Box<dyn Stream<Item = Result<DnsResponse, ResolveError>> + Send>>;
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
/// 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>(
mut conns: Vec<NameServer<C, P>>,
async fn parallel_conn_loop<P>(
mut conns: Vec<NameServer<P>>,
request: DnsRequest,
opts: ResolverOpts,
) -> Result<DnsResponse, ResolveError>
where
C: DnsHandle<Error = ResolveError> + Send + Sync + 'static + CreateConnection,
P: RuntimeProvider + 'static,
P: ConnectionProvider + 'static,
{
let mut err = ResolveError::no_connections();
// 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
// to fire than the timeout configured in `ResolverOpts`.
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 {
let request_cont = request.clone();
// 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));
// Shuffe DNS NameServers to avoid overloads to the first configured ones
@@ -353,7 +347,10 @@ where
if par_conns.is_empty() {
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(..));
backoff *= 2;
continue;
@@ -486,8 +483,8 @@ mod tests {
use super::*;
use crate::config::NameServerConfig;
use crate::config::Protocol;
use crate::name_server::GenericNameServer;
use crate::name_server::TokioRuntimeProvider;
use crate::name_server::{GenericNameServer, TokioConnectionProvider};
#[ignore]
// because of there is a real connection that needs a reasonable timeout
@@ -564,7 +561,7 @@ mod tests {
#[test]
fn test_multi_use_conns() {
let io_loop = Runtime::new().unwrap();
let conn_provider = TokioRuntimeProvider::new();
let conn_provider = TokioConnectionProvider::default();
let tcp = NameServerConfig {
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_servers: Arc<[_]> = Arc::from([name_server]);
#[cfg(not(feature = "mdns"))]
let mut pool = GenericNameServerPool::from_nameservers_test(
&opts,
Arc::from([]),
Arc::clone(&name_servers),
);
#[cfg(feature = "mdns")]
name_server::mdns_nameserver(
opts,
TokioConnectionProvider::new(TokioHandle::default()),
),
let mut pool = GenericNameServerPool::from_nameservers_test(
&opts,
Arc::from([]),
Arc::clone(&name_servers),
name_server::mdns_nameserver(opts, TokioConnectionProvider::default(), false),
);
let name = Name::from_str("www.example.com.").unwrap();

View File

@@ -20,7 +20,7 @@ use crate::error::*;
use crate::lookup;
use crate::lookup::Lookup;
use crate::lookup_ip::LookupIp;
use crate::name_server::TokioRuntimeProvider;
use crate::name_server::TokioConnectionProvider;
use crate::AsyncResolver;
/// 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
// 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>,
async_resolver: AsyncResolver<TokioRuntimeProvider>,
async_resolver: AsyncResolver<TokioConnectionProvider>,
}
macro_rules! lookup_fn {
@@ -80,7 +80,8 @@ impl Resolver {
builder.enable_all();
let runtime = builder.build()?;
let async_resolver = AsyncResolver::new(config, options, TokioRuntimeProvider::new());
let async_resolver =
AsyncResolver::new(config, options, TokioConnectionProvider::default());
Ok(Self {
runtime: Mutex::new(runtime),

View File

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