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