1 // Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
2 //
3 // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4 // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5 // http://opensource.org/licenses/MIT>, at your option. This file may not be
6 // copied, modified, or distributed except according to those terms.
7
8 #![cfg(feature = "dns-over-rustls")]
9 #![allow(dead_code)]
10
11 use std::net::SocketAddr;
12 use std::pin::Pin;
13 use std::sync::Arc;
14
15 use futures_util::future::Future;
16 use rustls::{ClientConfig, ProtocolVersion, RootCertStore};
17
18 use proto::error::ProtoError;
19 use proto::BufDnsStreamHandle;
20 use trust_dns_rustls::{tls_client_connect, TlsClientStream};
21
22 use crate::config::TlsClientConfig;
23 use crate::name_server::RuntimeProvider;
24
25 const ALPN_H2: &[u8] = b"h2";
26
27 lazy_static! {
28 // using the mozilla default root store
29 pub(crate) static ref CLIENT_CONFIG: Arc<ClientConfig> = {
30 let mut root_store = RootCertStore::empty();
31 root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);
32 let versions = vec![ProtocolVersion::TLSv1_2];
33
34 let mut client_config = ClientConfig::new();
35 client_config.root_store = root_store;
36 client_config.versions = versions;
37 client_config.alpn_protocols.push(ALPN_H2.to_vec());
38
39 Arc::new(client_config)
40 };
41 }
42
43 #[allow(clippy::type_complexity)]
new_tls_stream<R: RuntimeProvider>( socket_addr: SocketAddr, dns_name: String, client_config: Option<TlsClientConfig>, ) -> ( Pin<Box<dyn Future<Output = Result<TlsClientStream<R::Tcp>, ProtoError>> + Send>>, BufDnsStreamHandle, )44 pub(crate) fn new_tls_stream<R: RuntimeProvider>(
45 socket_addr: SocketAddr,
46 dns_name: String,
47 client_config: Option<TlsClientConfig>,
48 ) -> (
49 Pin<Box<dyn Future<Output = Result<TlsClientStream<R::Tcp>, ProtoError>> + Send>>,
50 BufDnsStreamHandle,
51 ) {
52 let client_config = client_config.map_or_else(
53 || CLIENT_CONFIG.clone(),
54 |TlsClientConfig(client_config)| client_config,
55 );
56 let (stream, handle) = tls_client_connect(socket_addr, dns_name, client_config);
57 (Box::pin(stream), handle)
58 }
59