integrate quic into resolver (untested)

This commit is contained in:
Benjamin Fry 2022-03-29 11:28:45 -07:00
parent 0413acf912
commit 5d22afd88d
13 changed files with 113 additions and 8 deletions

View File

@ -1,4 +1,4 @@
// Copyright 2015-2021 Benjamin Fry <benjaminfry@me.com>
// Copyright 2015-2022 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or

View File

@ -274,11 +274,12 @@ pub enum ProtoErrorKind {
QuinnReadError(#[from] quinn::ReadExactError),
/// A quic message id should always be 0
#[cfg(feature = "quinn")]
#[error("quic messages should always be 0, got: {0}")]
QuicMessageIdNot0(u16),
/// A Rustls error occured
#[cfg(feature = "dns-over-rustls")]
#[cfg(feature = "rustls")]
#[error("rustls construction error: {0}")]
RustlsError(#[from] rustls::Error),
}
@ -442,7 +443,7 @@ impl From<quinn::ReadExactError> for ProtoError {
}
}
#[cfg(feature = "dns-over-rustls")]
#[cfg(feature = "rustls")]
impl From<rustls::Error> for ProtoError {
fn from(e: rustls::Error) -> Self {
ProtoErrorKind::from(e).into()
@ -574,11 +575,17 @@ impl Clone for ProtoErrorKind {
Utf8(ref e) => Utf8(*e),
FromUtf8(ref e) => FromUtf8(e.clone()),
ParseInt(ref e) => ParseInt(e.clone()),
#[cfg(feature = "quinn")]
QuinnConnect(ref e) => QuinnConnect(e.clone()),
#[cfg(feature = "quinn")]
QuinnConnection(ref e) => QuinnConnection(e.clone()),
#[cfg(feature = "quinn")]
QuinnWriteError(ref e) => QuinnWriteError(e.clone()),
#[cfg(feature = "quinn")]
QuicMessageIdNot0(val) => QuicMessageIdNot0(val),
#[cfg(feature = "quinn")]
QuinnReadError(ref e) => QuinnReadError(e.clone()),
#[cfg(feature = "rustls")]
RustlsError(ref e) => RustlsError(e.clone()),
}
}

View File

@ -1,4 +1,4 @@
// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
// Copyright 2015-2022 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or

View File

@ -1,4 +1,4 @@
// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
// Copyright 2015-2022 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
@ -173,11 +173,11 @@ impl QuicClientStreamBuilder {
/// Sets a good set of defaults for the DoQ transport config
pub fn default_transport_config(&mut self) -> &mut Self {
self.set_transport_config(TransportConfig::default())
self.transport_config(TransportConfig::default())
}
/// This will override the max_concurrent_bidi_streams and max_concurrent_uni_streams to 0, as DoQ doesn't support server push
pub fn set_transport_config(&mut self, mut transport_config: TransportConfig) -> &mut Self {
pub fn transport_config(&mut self, mut transport_config: TransportConfig) -> &mut Self {
sanitize_transport_config(&mut transport_config);
self.transport_config = Arc::new(transport_config);

View File

@ -1,3 +1,10 @@
// Copyright 2015-2022 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
use std::{io, net::SocketAddr, sync::Arc};
use futures_util::StreamExt;

View File

@ -1,3 +1,10 @@
// Copyright 2015-2022 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
use std::convert::TryInto;
use bytes::Bytes;

View File

@ -1,3 +1,10 @@
// Copyright 2015-2022 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
use std::{env, net::SocketAddr, path::Path, sync::Arc};
use futures_util::StreamExt;

View File

@ -284,6 +284,10 @@ pub enum Protocol {
#[cfg(feature = "dns-over-https")]
#[cfg_attr(docsrs, doc(cfg(feature = "dns-over-https")))]
Https,
/// Quic for DNS over Quic
#[cfg(feature = "dns-over-quic")]
#[cfg_attr(docsrs, doc(cfg(feature = "dns-over-quic")))]
Quic,
/// mDNS protocol for performing multicast lookups
#[cfg(feature = "mdns")]
#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))]
@ -299,6 +303,8 @@ impl fmt::Display for Protocol {
Protocol::Tls => "tls",
#[cfg(feature = "dns-over-https")]
Protocol::Https => "https",
#[cfg(feature = "dns-over-quic")]
Protocol::Quic => "quic",
#[cfg(feature = "mdns")]
Protocol::Mdns => "mdns",
};
@ -317,6 +323,9 @@ impl Protocol {
Protocol::Tls => false,
#[cfg(feature = "dns-over-https")]
Protocol::Https => false,
// TODO: if you squint, this is true...
#[cfg(feature = "dns-over-quic")]
Protocol::Quic => true,
#[cfg(feature = "mdns")]
Protocol::Mdns => true,
}
@ -336,6 +345,8 @@ impl Protocol {
Protocol::Tls => true,
#[cfg(feature = "dns-over-https")]
Protocol::Https => true,
#[cfg(feature = "dns-over-quic")]
Protocol::Quic => true,
#[cfg(feature = "mdns")]
Protocol::Mdns => false,
}

View File

@ -1,3 +1,10 @@
// Copyright 2015-2022 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
use std::net::SocketAddr;
use crate::name_server::RuntimeProvider;

View File

@ -270,6 +270,8 @@ pub mod lookup;
pub mod lookup_ip;
#[doc(hidden)]
pub mod name_server;
#[cfg(feature = "dns-over-quic")]
mod quic;
#[cfg(feature = "tokio-runtime")]
mod resolver;
pub mod system_conf;

View File

@ -198,6 +198,22 @@ where
);
ConnectionConnect::Https(exchange)
}
#[cfg(feature = "dns-over-quic")]
Protocol::Quic => {
let socket_addr = config.socket_addr;
let bind_addr = config.bind_addr;
let tls_dns_name = config.tls_dns_name.clone().unwrap_or_default();
#[cfg(feature = "dns-over-rustls")]
let client_config = config.tls_config.clone();
let exchange = crate::quic::new_quic_stream(
socket_addr,
bind_addr,
tls_dns_name,
client_config,
);
ConnectionConnect::Quic(exchange)
}
#[cfg(feature = "mdns")]
Protocol::Mdns => {
let socket_addr = config.socket_addr;

View File

@ -0,0 +1,41 @@
// Copyright 2015-2022 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
use rustls::ClientConfig as CryptoConfig;
use std::net::SocketAddr;
use proto::xfer::{DnsExchange, DnsExchangeConnect};
use proto::TokioTime;
use trust_dns_proto::quic::{QuicClientConnect, QuicClientStream};
use crate::config::TlsClientConfig;
use crate::name_server::RuntimeProvider;
use crate::tls::CLIENT_CONFIG;
#[allow(clippy::type_complexity)]
pub(crate) fn new_quic_stream(
socket_addr: SocketAddr,
bind_addr: Option<SocketAddr>,
dns_name: String,
client_config: Option<TlsClientConfig>,
) -> DnsExchangeConnect<QuicClientConnect, QuicClientStream, TokioTime> {
let client_config = client_config.map_or_else(
|| CLIENT_CONFIG.clone(),
|TlsClientConfig(client_config)| client_config,
);
let mut quic_builder = QuicClientStream::builder();
// TODO: normalize the crypto config settings, can we just use common ALPN settings?
let crypto_config: CryptoConfig = (*client_config).clone();
quic_builder.crypto_config(crypto_config);
if let Some(bind_addr) = bind_addr {
quic_builder.bind_addr(bind_addr);
}
DnsExchange::connect(quic_builder.build(socket_addr, dns_name))
}

View File

@ -14,7 +14,7 @@ mod dns_over_rustls;
cfg_if! {
if #[cfg(feature = "dns-over-rustls")] {
pub(crate) use self::dns_over_rustls::new_tls_stream;
#[cfg(feature = "dns-over-https-rustls")]
#[cfg(any(feature = "dns-over-https-rustls", feature = "dns-over-quic"))]
pub(crate) use self::dns_over_rustls::CLIENT_CONFIG;
} else if #[cfg(feature = "dns-over-native-tls")] {
pub(crate) use self::dns_over_native_tls::new_tls_stream;