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 extern crate rustls;
12 extern crate webpki_roots;
13
14 use std::net::SocketAddr;
15 use std::pin::Pin;
16 use std::sync::Arc;
17
18 use self::rustls::{ClientConfig, ProtocolVersion, RootCertStore};
19 use futures::Future;
20
21 use proto::error::ProtoError;
22 use proto::BufDnsStreamHandle;
23 use trust_dns_rustls::{tls_client_connect, TlsClientStream};
24
25 use crate::config::TlsClientConfig;
26
27 const ALPN_H2: &[u8] = b"h2";
28
29 lazy_static! {
30 // using the mozilla default root store
31 pub(crate) static ref CLIENT_CONFIG: Arc<ClientConfig> = {
32 let mut root_store = RootCertStore::empty();
33 root_store.add_server_trust_anchors(&self::webpki_roots::TLS_SERVER_ROOTS);
34 let versions = vec![ProtocolVersion::TLSv1_2];
35
36 let mut client_config = ClientConfig::new();
37 client_config.root_store = root_store;
38 client_config.versions = versions;
39 client_config.alpn_protocols.push(ALPN_H2.to_vec());
40
41 Arc::new(client_config)
42 };
43 }
44
45 #[allow(clippy::type_complexity)]
new_tls_stream( socket_addr: SocketAddr, dns_name: String, client_config: Option<TlsClientConfig>, ) -> ( Pin<Box<dyn Future<Output = Result<TlsClientStream, ProtoError>> + Send>>, BufDnsStreamHandle, )46 pub(crate) fn new_tls_stream(
47 socket_addr: SocketAddr,
48 dns_name: String,
49 client_config: Option<TlsClientConfig>,
50 ) -> (
51 Pin<Box<dyn Future<Output = Result<TlsClientStream, ProtoError>> + Send>>,
52 BufDnsStreamHandle,
53 ) {
54 let client_config = client_config.map_or_else(
55 || CLIENT_CONFIG.clone(),
56 |TlsClientConfig(client_config)| client_config,
57 );
58 let (stream, handle) = tls_client_connect(socket_addr, dns_name, client_config);
59 (Box::pin(stream), handle)
60 }
61