From 30b3818a9e31b0ebe96d4a32aa9bceb16610f994 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 26 Jan 2022 10:53:06 -0500 Subject: [PATCH] Make the native-tls crate optional. This commit puts the native-tls crate behind a feature. The feature is off-by-default in the tor-rtcompat crate, but can be enabled either from arti or arti-client. There is an included script that I used to test that tor-rtcompat could build and run its tests with all subsets of its features. Closes #300 --- crates/arti-bench/Cargo.toml | 2 +- crates/arti-client/Cargo.toml | 6 +- crates/arti-client/src/client.rs | 16 +++--- crates/arti/Cargo.toml | 4 +- crates/arti/src/main.rs | 4 +- crates/tor-chanmgr/Cargo.toml | 2 +- crates/tor-circmgr/Cargo.toml | 2 +- crates/tor-dirclient/Cargo.toml | 2 +- crates/tor-dirmgr/Cargo.toml | 4 +- crates/tor-guardmgr/Cargo.toml | 2 +- crates/tor-proto/Cargo.toml | 4 +- crates/tor-rtcompat/Cargo.toml | 14 ++++- crates/tor-rtcompat/misc/matrix.py | 26 +++++++++ crates/tor-rtcompat/src/async_std.rs | 11 +++- crates/tor-rtcompat/src/impls.rs | 1 + crates/tor-rtcompat/src/impls/native_tls.rs | 1 + crates/tor-rtcompat/src/lib.rs | 61 +++++++++++++++++---- crates/tor-rtcompat/src/task.rs | 6 +- crates/tor-rtcompat/src/test.rs | 5 +- crates/tor-rtcompat/src/tokio.rs | 13 ++++- crates/tor-rtmock/Cargo.toml | 2 +- 21 files changed, 143 insertions(+), 45 deletions(-) create mode 100755 crates/tor-rtcompat/misc/matrix.py diff --git a/crates/arti-bench/Cargo.toml b/crates/arti-bench/Cargo.toml index cfb3241e0..c2e742c5a 100644 --- a/crates/arti-bench/Cargo.toml +++ b/crates/arti-bench/Cargo.toml @@ -21,7 +21,7 @@ serde_json = "1.0.50" tracing = "0.1.18" tracing-subscriber = { version = "0.3.0", features = ["env-filter"] } tokio = { version = "1.4", features = ["full"] } -tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features = ["tokio"] } +tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features = ["tokio", "native-tls"] } arti-config = { path="../arti-config", version = "0.0.3"} arti-client = { package="arti-client", path = "../arti-client", version = "0.0.3"} tokio-socks = "0.5" diff --git a/crates/arti-client/Cargo.toml b/crates/arti-client/Cargo.toml index c9d9f57b0..d9c5276cb 100644 --- a/crates/arti-client/Cargo.toml +++ b/crates/arti-client/Cargo.toml @@ -11,9 +11,11 @@ categories = [ "network-programming", "cryptography" ] repository="https://gitlab.torproject.org/tpo/core/arti.git/" [features] -default = [ "tokio" ] +default = [ "tokio", "native-tls" ] async-std = [ "tor-rtcompat/async-std" ] tokio = [ "tor-rtcompat/tokio", "tor-proto/tokio" ] +native-tls = [ "tor-rtcompat/native-tls" ] +rustls = [ "tor-rtcompat/rustls" ] static = [ "tor-rtcompat/static", "tor-dirmgr/static" ] # Enable experimental APIs that are not yet officially supported. @@ -42,7 +44,7 @@ serde = { version = "1.0.103", features = ["derive"] } thiserror = "1" [dev-dependencies] -tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio"] } +tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio", "native-tls" ] } tokio-crate = { package = "tokio", version = "1.4", features = ["rt", "rt-multi-thread", "io-util", "net", "time", "macros" ] } hyper = { version = "0.14", features = ["http1", "client", "runtime"] } pin-project = "1" diff --git a/crates/arti-client/src/client.rs b/crates/arti-client/src/client.rs index e1e634b2f..84e5c74c3 100644 --- a/crates/arti-client/src/client.rs +++ b/crates/arti-client/src/client.rs @@ -24,9 +24,9 @@ use std::time::Duration; use crate::{status, Error, Result}; #[cfg(feature = "async-std")] -use tor_rtcompat::async_std::AsyncStdNativeTlsRuntime; +use tor_rtcompat::async_std::PreferredRuntime as PreferredAsyncStdRuntime; #[cfg(feature = "tokio")] -use tor_rtcompat::tokio::TokioNativeTlsRuntime; +use tor_rtcompat::tokio::PreferredRuntime as PreferredTokioRuntime; use tracing::{debug, error, info, warn}; /// An active client session on the Tor network. @@ -246,7 +246,7 @@ impl StreamPrefs { } #[cfg(feature = "tokio")] -impl TorClient { +impl TorClient { /// Bootstrap a connection to the Tor network, using the current Tokio runtime. /// /// Returns a client once there is enough directory material to @@ -259,14 +259,14 @@ impl TorClient { /// Panics if called outside of the context of a Tokio runtime. pub async fn bootstrap_with_tokio( config: TorClientConfig, - ) -> Result> { - let rt = TokioNativeTlsRuntime::current().expect("called outside of Tokio runtime"); + ) -> Result> { + let rt = PreferredTokioRuntime::current().expect("called outside of Tokio runtime"); Self::bootstrap(rt, config).await } } #[cfg(feature = "async-std")] -impl TorClient { +impl TorClient { /// Bootstrap a connection to the Tor network, using the current async-std runtime. /// /// Returns a client once there is enough directory material to @@ -275,9 +275,9 @@ impl TorClient { /// This is a convenience wrapper around [`TorClient::bootstrap`]. pub async fn bootstrap_with_async_std( config: TorClientConfig, - ) -> Result> { + ) -> Result> { // FIXME(eta): not actually possible for this to fail - let rt = AsyncStdNativeTlsRuntime::current().expect("failed to get async-std runtime"); + let rt = PreferredAsyncStdRuntime::current().expect("failed to get async-std runtime"); Self::bootstrap(rt, config).await } } diff --git a/crates/arti/Cargo.toml b/crates/arti/Cargo.toml index 790141bb2..363ba76d3 100644 --- a/crates/arti/Cargo.toml +++ b/crates/arti/Cargo.toml @@ -11,9 +11,11 @@ categories = [ "command-line-utilities", "cryptography" ] repository="https://gitlab.torproject.org/tpo/core/arti.git/" [features] -default = [ "tokio" ] +default = [ "tokio", "native-tls" ] async-std = [ "arti-client/async-std", "tor-rtcompat/async-std", "async-ctrlc", "once_cell" ] tokio = [ "tokio-crate", "arti-client/tokio", "tor-rtcompat/tokio" ] +native-tls = [ "arti-client/native-tls", "tor-rtcompat/native-tls" ] +rustls = [ "arti-client/rustls", "tor-rtcompat/rustls" ] static = [ "arti-client/static" ] journald = [ "tracing-journald" ] diff --git a/crates/arti/src/main.rs b/crates/arti/src/main.rs index 0a5a33ce2..c6d36eee9 100644 --- a/crates/arti/src/main.rs +++ b/crates/arti/src/main.rs @@ -230,9 +230,9 @@ fn main() -> Result<()> { process::use_max_file_limit(); #[cfg(all(feature = "async-std", not(feature = "tokio")))] - use tor_rtcompat::tokio::AsyncStdNativeTlsRuntime as ChosenRuntime; + use tor_rtcompat::tokio::PreferredRuntime as ChosenRuntime; #[cfg(feature = "tokio")] - use tor_rtcompat::tokio::TokioNativeTlsRuntime as ChosenRuntime; + use tor_rtcompat::tokio::PreferredRuntime as ChosenRuntime; let runtime = ChosenRuntime::create()?; diff --git a/crates/tor-chanmgr/Cargo.toml b/crates/tor-chanmgr/Cargo.toml index 5bc4a3189..e16221412 100644 --- a/crates/tor-chanmgr/Cargo.toml +++ b/crates/tor-chanmgr/Cargo.toml @@ -30,4 +30,4 @@ float_eq = "0.7" futures-await-test = "0.3.0" hex-literal = "0.3" tor-rtmock = { path="../tor-rtmock", version = "0.0.3"} -tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio"] } +tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio", "native-tls"] } diff --git a/crates/tor-circmgr/Cargo.toml b/crates/tor-circmgr/Cargo.toml index 3783d0a90..3f16aa018 100644 --- a/crates/tor-circmgr/Cargo.toml +++ b/crates/tor-circmgr/Cargo.toml @@ -50,4 +50,4 @@ tor-guardmgr = { path="../tor-guardmgr", version = "0.0.3", features=["testing"] tor-llcrypto = { path="../tor-llcrypto", version = "0.0.3"} tor-netdir = { path="../tor-netdir", version = "0.0.3", features=["testing"] } tor-persist = { path="../tor-persist", version = "0.0.3", features=["testing"] } -tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio"] } +tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio", "native-tls" ] } diff --git a/crates/tor-dirclient/Cargo.toml b/crates/tor-dirclient/Cargo.toml index 264d86ded..f4fb49f54 100644 --- a/crates/tor-dirclient/Cargo.toml +++ b/crates/tor-dirclient/Cargo.toml @@ -38,5 +38,5 @@ thiserror = "1" [dev-dependencies] futures-await-test = "0.3.0" tor-rtmock = { path="../tor-rtmock", version = "0.0.3"} -tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio"] } +tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio", "native-tls" ] } diff --git a/crates/tor-dirmgr/Cargo.toml b/crates/tor-dirmgr/Cargo.toml index 7eba19e5a..ac6903fcd 100644 --- a/crates/tor-dirmgr/Cargo.toml +++ b/crates/tor-dirmgr/Cargo.toml @@ -56,7 +56,5 @@ humantime-serde = "1" futures-await-test = "0.3.0" hex-literal = "0.3" tempfile = "3" -tor-rtcompat = { path = "../tor-rtcompat", version = "0.0.3", features = [ - "tokio", -] } +tor-rtcompat = { path = "../tor-rtcompat", version = "0.0.3", features = [ "tokio", "native-tls" ] } float_eq = "0.7" diff --git a/crates/tor-guardmgr/Cargo.toml b/crates/tor-guardmgr/Cargo.toml index 66e6dfc0f..d6d2521ee 100644 --- a/crates/tor-guardmgr/Cargo.toml +++ b/crates/tor-guardmgr/Cargo.toml @@ -42,5 +42,5 @@ tracing = "0.1.18" tor-netdir = { path="../tor-netdir", version = "0.0.3", features=["testing"]} tor-netdoc = { path="../tor-netdoc", version = "0.0.3"} tor-persist = { path="../tor-persist", version = "0.0.3", features=["testing"]} -tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio"]} +tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio", "native-tls"]} tor-rtmock = { path="../tor-rtmock", version = "0.0.3"} diff --git a/crates/tor-proto/Cargo.toml b/crates/tor-proto/Cargo.toml index 3e814b48e..6c07f5674 100644 --- a/crates/tor-proto/Cargo.toml +++ b/crates/tor-proto/Cargo.toml @@ -49,8 +49,6 @@ tokio-util = { version = "0.6", features = ["compat"], optional = true } coarsetime = { version = "0.1.20", optional = true } [dev-dependencies] -tor-rtcompat = { path = "../tor-rtcompat", version = "0.0.3", features = [ - "tokio", -] } +tor-rtcompat = { path = "../tor-rtcompat", version = "0.0.3", features = [ "tokio", "native-tls" ] } hex-literal = "0.3" hex = "0.4" diff --git a/crates/tor-rtcompat/Cargo.toml b/crates/tor-rtcompat/Cargo.toml index 3770ca925..133f55ebd 100644 --- a/crates/tor-rtcompat/Cargo.toml +++ b/crates/tor-rtcompat/Cargo.toml @@ -15,7 +15,10 @@ repository="https://gitlab.torproject.org/tpo/core/arti.git/" default = [ ] async-std = [ "async-std-crate", "async-io", "async_executors/async_std" ] tokio = [ "tokio-crate", "tokio-util", "async_executors/tokio_tp" ] -static = [ "native-tls/vendored" ] +# TODO: This feature makes us link native-tls statically even if we +# don't want to use native-tls in the first place. That's not so clever! +static = [ "native-tls-crate/vendored" ] +native-tls = [ "native-tls-crate", "async-native-tls" ] rustls = [ "rustls-crate", "async-rustls", "x509-signature" ] [dependencies] @@ -24,15 +27,20 @@ async_executors = { version = "0.4", default_features = false } async-trait = "0.1.2" futures = "0.3" pin-project = "1" -native-tls = "0.2" +native-tls-crate = { package = "native-tls", version = "0.2", optional = true } rustls-crate = { package = "rustls", version = "0.19", optional = true, features = [ "dangerous_configuration" ] } async-std-crate = { package = "async-std", version = "1.7.0", optional = true } async-io = { version = "1.4.1", optional = true } -async-native-tls = { version = "0.4.0" } +async-native-tls = { version = "0.4.0", optional = true } tokio-crate = { package = "tokio", version = "1.4", optional = true, features = ["rt", "rt-multi-thread", "io-util", "net", "time" ] } tokio-util = { version = "0.6", features = ["compat"], optional = true } async-rustls = { version = "0.2.0", optional = true } x509-signature = { version = "0.5.0", optional = true } + +[dev-dependencies] +# Used for testing our TLS implementation. +native-tls-crate = { package = "native-tls", version = "0.2" } + diff --git a/crates/tor-rtcompat/misc/matrix.py b/crates/tor-rtcompat/misc/matrix.py new file mode 100755 index 000000000..4031a2490 --- /dev/null +++ b/crates/tor-rtcompat/misc/matrix.py @@ -0,0 +1,26 @@ +#!/usr/bin/python +# +# Run a provided command over all possible subsets of important +# tor-rtcompat features. + +import sys, subprocess + +if sys.argv[1:] == []: + print("You need to name a program to run with different features") + sys.exit(1) + +FEATURES = [ "tokio", "async-std", "native-tls", "rustls" ] + +COMBINATIONS = [ [] ] + +# Generate all combinations of features. +for feature in FEATURES: + new_combinations = [ c + [ feature ] for c in COMBINATIONS ] + COMBINATIONS.extend(new_combinations) + +for c in COMBINATIONS: + arg = "--features={}".format(",".join(c)) + commandline = sys.argv[1:] + [arg] + print(" ".join(commandline)) + subprocess.check_call(commandline) + diff --git a/crates/tor-rtcompat/src/async_std.rs b/crates/tor-rtcompat/src/async_std.rs index c8127f319..23c00a3ea 100644 --- a/crates/tor-rtcompat/src/async_std.rs +++ b/crates/tor-rtcompat/src/async_std.rs @@ -3,8 +3,8 @@ pub use crate::impls::async_std::create_runtime as create_runtime_impl; use crate::{compound::CompoundRuntime, SpawnBlocking}; use std::io::Result as IoResult; +#[cfg(feature = "native-tls")] use crate::impls::native_tls::NativeTlsProvider; - #[cfg(feature = "rustls")] use crate::impls::rustls::RustlsProvider; use async_std_crate::net::TcpStream; @@ -20,18 +20,25 @@ use async_executors::AsyncStd; /// Currently, `native_tls` is preferred over `rustls` when both are available, /// because of its maturity within Arti. However, this might change in the /// future. +#[cfg(all(feature = "native-tls"))] pub use AsyncStdNativeTlsRuntime as PreferredRuntime; +#[cfg(all(feature = "rustls", not(feature = "native-tls")))] +pub use AsyncStdRustlsRuntime as PreferredRuntime; + /// A [`Runtime`](crate::Runtime) powered by `async_std` and `native_tls`. #[derive(Clone)] +#[cfg(all(feature = "native-tls"))] pub struct AsyncStdNativeTlsRuntime { /// The actual runtime object. inner: NativeTlsInner, } /// Implementation type for AsyncStdRuntime. +#[cfg(all(feature = "native-tls"))] type NativeTlsInner = CompoundRuntime>; +#[cfg(all(feature = "native-tls"))] crate::opaque::implement_opaque_runtime! { AsyncStdNativeTlsRuntime { inner : NativeTlsInner } } @@ -53,6 +60,7 @@ crate::opaque::implement_opaque_runtime! { AsyncStdRustlsRuntime { inner: RustlsInner } } +#[cfg(all(feature = "native-tls"))] impl AsyncStdNativeTlsRuntime { /// Return a new [`AsyncStdNativeTlsRuntime`] /// @@ -103,6 +111,7 @@ impl AsyncStdRustlsRuntime { } /// Run a test function using a freshly created async_std runtime. +#[cfg(any(feature = "native-tls", feature = "rustls"))] pub fn test_with_runtime(func: P) -> O where P: FnOnce(PreferredRuntime) -> F, diff --git a/crates/tor-rtcompat/src/impls.rs b/crates/tor-rtcompat/src/impls.rs index 9efcde0cf..6ef05085e 100644 --- a/crates/tor-rtcompat/src/impls.rs +++ b/crates/tor-rtcompat/src/impls.rs @@ -11,4 +11,5 @@ pub(crate) mod tokio; #[cfg(all(feature = "rustls"))] pub(crate) mod rustls; +#[cfg(all(feature = "native-tls"))] pub(crate) mod native_tls; diff --git a/crates/tor-rtcompat/src/impls/native_tls.rs b/crates/tor-rtcompat/src/impls/native_tls.rs index a0de354da..e1a7f72ab 100644 --- a/crates/tor-rtcompat/src/impls/native_tls.rs +++ b/crates/tor-rtcompat/src/impls/native_tls.rs @@ -4,6 +4,7 @@ use crate::traits::{CertifiedConn, TlsConnector, TlsProvider}; use async_trait::async_trait; use futures::{AsyncRead, AsyncWrite}; +use native_tls_crate as native_tls; use std::{ convert::TryInto, io::{Error as IoError, Result as IoResult}, diff --git a/crates/tor-rtcompat/src/lib.rs b/crates/tor-rtcompat/src/lib.rs index 06e81ec46..30542d1ef 100644 --- a/crates/tor-rtcompat/src/lib.rs +++ b/crates/tor-rtcompat/src/lib.rs @@ -140,6 +140,10 @@ #![warn(clippy::unseparated_literal_suffix)] #![deny(clippy::unwrap_used)] +#[cfg(all( + any(feature = "native-tls", feature = "rustls"), + any(feature = "async-std", feature = "tokio") +))] pub(crate) mod impls; pub mod task; @@ -148,7 +152,11 @@ mod opaque; mod timer; mod traits; -#[cfg(all(test, any(feature = "tokio", feature = "async-std")))] +#[cfg(all( + test, + any(feature = "native-tls", feature = "rustls"), + any(feature = "async-std", feature = "tokio") +))] mod test; pub use traits::{ @@ -163,17 +171,21 @@ pub mod tls { pub use crate::traits::{CertifiedConn, TlsConnector}; } -#[cfg(feature = "tokio")] +#[cfg(all(any(feature = "native-tls", feature = "rustls"), feature = "tokio"))] pub mod tokio; -#[cfg(feature = "async-std")] +#[cfg(all(any(feature = "native-tls", feature = "rustls"), feature = "async-std"))] pub mod async_std; pub use compound::CompoundRuntime; -#[cfg(all(feature = "async_std", not(feature = "tokio")))] +#[cfg(all( + any(feature = "native-tls", feature = "rustls"), + feature = "async-std", + not(feature = "tokio") +))] use async_std as preferred_backend_mod; -#[cfg(feature = "tokio")] +#[cfg(all(any(feature = "native-tls", feature = "rustls"), feature = "tokio"))] use tokio as preferred_backend_mod; /// The runtime that we prefer to use, out of all the runtimes compiled into the @@ -183,7 +195,10 @@ use tokio as preferred_backend_mod; /// performance. /// If `native_tls` and `rustls` are both available, we prefer `native_tls` since /// it has been used in Arti for longer. -#[cfg(any(feature = "tokio", feature = "async-std"))] +#[cfg(all( + any(feature = "native-tls", feature = "rustls"), + any(feature = "async-std", feature = "tokio") +))] pub use preferred_backend_mod::PreferredRuntime; /// Try to return an instance of the currently running [`Runtime`]. @@ -203,7 +218,10 @@ pub use preferred_backend_mod::PreferredRuntime; /// /// Once you have a runtime returned by this function, you should /// just create more handles to it via [`Clone`]. -#[cfg(any(feature = "async-std", feature = "tokio"))] +#[cfg(all( + any(feature = "native-tls", feature = "rustls"), + any(feature = "async-std", feature = "tokio") +))] pub fn current_user_runtime() -> std::io::Result { PreferredRuntime::current() } @@ -222,7 +240,10 @@ pub fn current_user_runtime() -> std::io::Result { /// /// If you need more fine-grained control over a runtime, you can /// create it using an appropriate builder type or function. -#[cfg(any(feature = "async-std", feature = "tokio"))] +#[cfg(all( + any(feature = "native-tls", feature = "rustls"), + any(feature = "async-std", feature = "tokio") +))] pub fn create_runtime() -> std::io::Result { PreferredRuntime::create() } @@ -249,7 +270,11 @@ pub mod testing__ { /// (This is a macro so that it can repeat the closure as two separate /// expressions, so it can take on two different types, if needed.) #[macro_export] -#[cfg(all(feature = "tokio", feature = "async-std"))] +#[cfg(all( + any(feature = "native-tls", feature = "rustls"), + feature = "tokio", + feature = "async-std" +))] macro_rules! test_with_all_runtimes { ( $fn:expr ) => {{ use $crate::testing__::TestOutcome; @@ -260,7 +285,11 @@ macro_rules! test_with_all_runtimes { /// Run a test closure, passing as argument every supported runtime. #[macro_export] -#[cfg(all(feature = "tokio", not(feature = "async-std")))] +#[cfg(all( + any(feature = "native-tls", feature = "rustls"), + feature = "tokio", + not(feature = "async-std") +))] macro_rules! test_with_all_runtimes { ( $fn:expr ) => {{ $crate::tokio::test_with_runtime($fn) @@ -269,7 +298,11 @@ macro_rules! test_with_all_runtimes { /// Run a test closure, passing as argument every supported runtime. #[macro_export] -#[cfg(all(not(feature = "tokio"), feature = "async-std"))] +#[cfg(all( + any(feature = "native-tls", feature = "rustls"), + not(feature = "tokio"), + feature = "async-std" +))] macro_rules! test_with_all_runtimes { ( $fn:expr ) => {{ $crate::async_std::test_with_runtime($fn) @@ -291,7 +324,11 @@ macro_rules! test_with_one_runtime { /// /// (Always prefers tokio if present.) #[macro_export] -#[cfg(all(not(feature = "tokio"), feature = "async-std"))] +#[cfg(all( + any(feature = "native-tls", feature = "rustls"), + not(feature = "tokio"), + feature = "async-std" +))] macro_rules! test_with_one_runtime { ( $fn:expr ) => {{ $crate::async_std::test_with_runtime($fn) diff --git a/crates/tor-rtcompat/src/task.rs b/crates/tor-rtcompat/src/task.rs index 84b97c8f5..5ee7eaa00 100644 --- a/crates/tor-rtcompat/src/task.rs +++ b/crates/tor-rtcompat/src/task.rs @@ -38,7 +38,11 @@ impl Future for YieldFuture { } } -#[cfg(all(test, any(feature = "tokio", feature = "async-std")))] +#[cfg(all( + test, + any(feature = "native-tls", feature = "rustls"), + any(feature = "tokio", feature = "async-std") +))] mod test { use super::yield_now; use crate::test_with_all_runtimes; diff --git a/crates/tor-rtcompat/src/test.rs b/crates/tor-rtcompat/src/test.rs index 27ec18859..6d3c4e5e2 100644 --- a/crates/tor-rtcompat/src/test.rs +++ b/crates/tor-rtcompat/src/test.rs @@ -6,6 +6,7 @@ use crate::traits::*; use futures::io::{AsyncReadExt, AsyncWriteExt}; use futures::stream::StreamExt; +use native_tls_crate as native_tls; use std::io::Result as IoResult; use std::net::{Ipv4Addr, SocketAddrV4}; use std::time::{Duration, Instant, SystemTime}; @@ -244,7 +245,7 @@ macro_rules! runtime_tests { macro_rules! tls_runtime_tests { { $($id:ident),* $(,)? } => { - #[cfg(feature="tokio")] + #[cfg(all(feature="tokio", feature = "native-tls"))] mod tokio_native_tls_tests { use std::io::Result as IoResult; $( @@ -254,7 +255,7 @@ macro_rules! tls_runtime_tests { } )* } - #[cfg(feature="async-std")] + #[cfg(all(feature="async-std", feature = "native-tls"))] mod async_std_native_tls_tests { use std::io::Result as IoResult; $( diff --git a/crates/tor-rtcompat/src/tokio.rs b/crates/tor-rtcompat/src/tokio.rs index bff4abe8e..c7f890dfb 100644 --- a/crates/tor-rtcompat/src/tokio.rs +++ b/crates/tor-rtcompat/src/tokio.rs @@ -1,10 +1,11 @@ //! Entry points for use with Tokio runtimes. -use crate::impls::native_tls::NativeTlsProvider; use crate::impls::tokio::TokioRuntimeHandle as Handle; use crate::{CompoundRuntime, SpawnBlocking}; use std::io::{Error as IoError, ErrorKind, Result as IoResult}; +#[cfg(feature = "native-tls")] +use crate::impls::native_tls::NativeTlsProvider; #[cfg(feature = "rustls")] use crate::impls::rustls::RustlsProvider; use crate::impls::tokio::net::TcpStream; @@ -18,7 +19,10 @@ use crate::impls::tokio::net::TcpStream; /// Currently, `native_tls` is preferred over `rustls` when both are available, /// because of its maturity within Arti. However, this might change in the /// future. +#[cfg(feature = "native-tls")] pub use TokioNativeTlsRuntime as PreferredRuntime; +#[cfg(all(feature = "rustls", not(feature = "native-tls")))] +pub use TokioRustlsRuntime as PreferredRuntime; /// A [`Runtime`] built around a Handle to a tokio runtime, and `native_tls`. /// @@ -28,12 +32,14 @@ pub use TokioNativeTlsRuntime as PreferredRuntime; /// implementations for Tokio's time, net, and io facilities, but we have /// no good way to check that when creating this object. #[derive(Clone)] +#[cfg(feature = "native-tls")] pub struct TokioNativeTlsRuntime { /// The actual [`CompoundRuntime`] that implements this. inner: HandleInner, } /// Implementation type for a TokioRuntimeHandle. +#[cfg(feature = "native-tls")] type HandleInner = CompoundRuntime>; /// A [`Runtime`] built around a Handle to a tokio runtime, and `rustls`. @@ -48,6 +54,7 @@ pub struct TokioRustlsRuntime { #[cfg(feature = "rustls")] type RustlsHandleInner = CompoundRuntime>; +#[cfg(feature = "native-tls")] crate::opaque::implement_opaque_runtime! { TokioNativeTlsRuntime { inner : HandleInner } } @@ -57,6 +64,7 @@ crate::opaque::implement_opaque_runtime! { TokioRustlsRuntime { inner : RustlsHandleInner } } +#[cfg(feature = "native-tls")] impl From for TokioNativeTlsRuntime { fn from(h: tokio_crate::runtime::Handle) -> Self { let h = Handle::new(h); @@ -76,6 +84,7 @@ impl From for TokioRustlsRuntime { } } +#[cfg(feature = "native-tls")] impl TokioNativeTlsRuntime { /// Create a new [`TokioNativeTlsRuntime`]. /// @@ -142,6 +151,7 @@ impl TokioRustlsRuntime { } /// As `Handle::try_current()`, but return an IoError on failure. +#[cfg(any(feature = "native-tls", feature = "rustls"))] fn current_handle() -> std::io::Result { tokio_crate::runtime::Handle::try_current().map_err(|e| IoError::new(ErrorKind::Other, e)) } @@ -151,6 +161,7 @@ fn current_handle() -> std::io::Result { /// # Panics /// /// Panics if we can't create a tokio runtime. +#[cfg(any(feature = "native-tls", feature = "rustls"))] pub fn test_with_runtime(func: P) -> O where P: FnOnce(PreferredRuntime) -> F, diff --git a/crates/tor-rtmock/Cargo.toml b/crates/tor-rtmock/Cargo.toml index 4299fd96d..ab7b6e6b0 100644 --- a/crates/tor-rtmock/Cargo.toml +++ b/crates/tor-rtmock/Cargo.toml @@ -22,4 +22,4 @@ tor-rtcompat = { version = "0.0.3", path = "../tor-rtcompat" } [dev-dependencies] futures-await-test = "0.3.0" rand = "0.8" -tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio"] } +tor-rtcompat = { path="../tor-rtcompat", version = "0.0.3", features=["tokio", "native-tls" ] }