arti: Move most public APIs behind `experimental-api`.

The remaining unconditionally public APIs are those related to our
configuration objects, and the main_main() API.

The rationale for making main_main() public is to have an actual
entry point.

The rationale for making the config APIs public is:

  1. We really do intend for others to be able to read our
     configuration files using this API.
  2. The structure of our configuration files is already part of our
     interface.

Closes #530.
This commit is contained in:
Nick Mathewson 2022-08-08 10:14:30 -04:00
parent 79c609e4f1
commit f548a6ac55
10 changed files with 45 additions and 13 deletions

1
Cargo.lock generated
View File

@ -112,6 +112,7 @@ dependencies = [
"tracing-journald",
"tracing-subscriber",
"trust-dns-proto",
"visibility",
"winapi 0.3.9",
]

View File

@ -18,6 +18,7 @@ full = ["async-std", "tokio", "native-tls", "journald", "arti-client/full", "dns
async-std = ["arti-client/async-std", "tor-rtcompat/async-std", "async-ctrlc", "once_cell"]
dns-proxy = ["trust-dns-proto"]
experimental-api = ["visibility"]
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"]
@ -31,7 +32,7 @@ accel-openssl = ["arti-client/accel-openssl"]
# This feature flag enables experimental features that are not supported. Turning it on may
# void your API.
experimental = ["arti-client/experimental"]
experimental = ["arti-client/experimental", "experimental-api"]
[dependencies]
anyhow = "1.0.23"
@ -59,6 +60,7 @@ tracing-appender = "0.2.0"
tracing-journald = { version = "0.3.0", optional = true }
tracing-subscriber = { version = "0.3.0", features = ["env-filter"] }
trust-dns-proto = { version = "0.21.1", optional = true }
visibility = { version = "0.0.1", optional = true }
[dev-dependencies]
itertools = "0.10.1"

3
crates/arti/semver.md Normal file
View File

@ -0,0 +1,3 @@
BREAKING: Most functions are now only available behind an experimental-api
feature.

View File

@ -224,7 +224,8 @@ where
}
/// Launch a DNS resolver to listen on a given local port, and run indefinitely.
pub async fn run_dns_resolver<R: Runtime>(
#[cfg_attr(feature = "experimental-api", visibility::make(pub))]
pub(crate) async fn run_dns_resolver<R: Runtime>(
runtime: R,
tor_client: TorClient<R>,
dns_port: u16,

View File

@ -8,7 +8,8 @@ use crate::Result;
/// This function can have pretty kludgy side-effects: see
/// documentation for `tokio::signal::ctrl_c` and `async_ctrlc` for
/// caveats. Notably, you can only call this once with async_std.
pub async fn wait_for_ctrl_c() -> Result<()> {
#[cfg_attr(feature = "experimental-api", visibility::make(pub))]
pub(crate) async fn wait_for_ctrl_c() -> Result<()> {
#[cfg(feature = "tokio")]
{
tokio_crate::signal::ctrl_c().await?;

View File

@ -93,6 +93,7 @@
//! versioning guarantees: we might break them or remove them between patch
//! versions.
//!
//! * `experimental-api` -- build with experimental, unstable API support.
//! * `experimental` -- Build with all experimental features above, along with
//! all experimental features from other arti crates.
//!
@ -152,14 +153,30 @@
#![allow(clippy::print_stdout)]
pub mod cfg;
#[cfg(feature = "dns-proxy")]
pub mod dns;
pub mod exit;
pub mod logging;
#[cfg(all(feature = "experimental-api", feature = "dns-proxy"))]
pub mod dns;
#[cfg(feature = "experimental-api")]
pub mod exit;
#[cfg(feature = "experimental-api")]
pub mod process;
#[cfg(feature = "experimental-api")]
pub mod socks;
#[cfg(feature = "experimental-api")]
pub mod watch_cfg;
#[cfg(all(not(feature = "experimental-api"), feature = "dns-proxy"))]
mod dns;
#[cfg(not(feature = "experimental-api"))]
mod exit;
#[cfg(not(feature = "experimental-api"))]
mod process;
#[cfg(not(feature = "experimental-api"))]
mod socks;
#[cfg(not(feature = "experimental-api"))]
mod watch_cfg;
use std::fmt::Write;
pub use cfg::{
@ -219,7 +236,8 @@ fn list_enabled_features() -> &'static [&'static str] {
/// # Panics
///
/// Currently, might panic if things go badly enough wrong
pub async fn run<R: Runtime>(
#[cfg_attr(feature = "experimental-api", visibility::make(pub))]
async fn run<R: Runtime>(
runtime: R,
socks_port: u16,
dns_port: u16,

View File

@ -259,7 +259,8 @@ where
/// Opaque structure that gets dropped when the program is shutting down,
/// after logs are no longer needed. The `Drop` impl flushes buffered messages.
pub struct LogGuards {
#[cfg_attr(feature = "experimental-api", visibility::make(pub))]
pub(crate) struct LogGuards {
/// The actual list of guards we're returning.
#[allow(unused)]
guards: Vec<WorkerGuard>,
@ -273,7 +274,8 @@ pub struct LogGuards {
///
/// Note that the returned LogGuard must be dropped precisely when the program
/// quits; they're used to ensure that all the log messages are flushed.
pub fn setup_logging(
#[cfg_attr(feature = "experimental-api", visibility::make(pub))]
pub(crate) fn setup_logging(
config: &LoggingConfig,
mistrust: &Mistrust,
cli: Option<&str>,

View File

@ -10,7 +10,8 @@ use crate::ArtiConfig;
/// # Limitations
///
/// This doesn't actually do anything on windows.
pub fn use_max_file_limit(config: &ArtiConfig) {
#[cfg_attr(feature = "experimental-api", visibility::make(pub))]
pub(crate) fn use_max_file_limit(config: &ArtiConfig) {
match rlimit::increase_nofile_limit(config.system.max_files) {
Ok(n) => tracing::debug!("Increased process file limit to {}", n),
Err(e) => tracing::warn!("Error while increasing file limit: {}", e),

View File

@ -46,7 +46,8 @@ See <a href="https://gitlab.torproject.org/tpo/core/arti/#todo-need-to-change-wh
/// Find out which kind of address family we can/should use for a
/// given `SocksRequest`.
pub fn stream_preference(req: &SocksRequest, addr: &str) -> StreamPrefs {
#[cfg_attr(feature = "experimental-api", visibility::make(pub))]
fn stream_preference(req: &SocksRequest, addr: &str) -> StreamPrefs {
let mut prefs = StreamPrefs::new();
if addr.parse::<Ipv4Addr>().is_ok() {
// If they asked for an IPv4 address correctly, nothing else will do.
@ -410,7 +411,8 @@ fn accept_err_is_fatal(err: &IoError) -> bool {
/// Requires a `runtime` to use for launching tasks and handling
/// timeouts, and a `tor_client` to use in connecting over the Tor
/// network.
pub async fn run_socks_proxy<R: Runtime>(
#[cfg_attr(feature = "experimental-api", visibility::make(pub))]
pub(crate) async fn run_socks_proxy<R: Runtime>(
runtime: R,
tor_client: TorClient<R>,
socks_port: u16,

View File

@ -21,7 +21,8 @@ const POLL_INTERVAL: Duration = Duration::from_secs(10);
///
/// Whenever one or more files in `files` changes, try to reload our
/// configuration from them and tell TorClient about it.
pub fn watch_for_config_changes<R: Runtime>(
#[cfg_attr(feature = "experimental-api", visibility::make(pub))]
pub(crate) fn watch_for_config_changes<R: Runtime>(
sources: ConfigurationSources,
original: ArtiConfig,
client: TorClient<R>,