diff --git a/crates/arti-client/src/config.rs b/crates/arti-client/src/config.rs index e2af900cf..e628b6d02 100644 --- a/crates/arti-client/src/config.rs +++ b/crates/arti-client/src/config.rs @@ -17,6 +17,7 @@ use std::collections::HashMap; use std::path::Path; use std::path::PathBuf; use std::time::Duration; +pub use tor_basic_utils::humantime_serde_option; pub use tor_config::{CfgPath, ConfigBuildError, Reconfigure}; /// Types for configuring how Tor circuits are built. @@ -46,6 +47,7 @@ pub mod dir { /// and requests. #[derive(Debug, Clone, Builder, Deserialize, Eq, PartialEq)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] #[serde(deny_unknown_fields)] pub struct ClientAddrConfig { /// Should we allow attempts to make Tor connections to local addresses? @@ -67,6 +69,7 @@ pub struct ClientAddrConfig { /// and requests—even those that are currently waiting. #[derive(Debug, Clone, Builder, Deserialize, Eq, PartialEq)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] #[serde(deny_unknown_fields)] #[non_exhaustive] pub struct StreamTimeoutConfig { @@ -74,17 +77,20 @@ pub struct StreamTimeoutConfig { /// to a host? #[builder(default = "default_connect_timeout()")] #[serde(with = "humantime_serde", default = "default_connect_timeout")] + #[builder(attrs(serde(with = "humantime_serde_option")))] pub(crate) connect_timeout: Duration, /// How long should we wait before timing out when resolving a DNS record? #[builder(default = "default_dns_resolve_timeout()")] #[serde(with = "humantime_serde", default = "default_dns_resolve_timeout")] + #[builder(attrs(serde(with = "humantime_serde_option")))] pub(crate) resolve_timeout: Duration, /// How long should we wait before timing out when resolving a DNS /// PTR record? #[builder(default = "default_dns_resolve_ptr_timeout()")] #[serde(with = "humantime_serde", default = "default_dns_resolve_ptr_timeout")] + #[builder(attrs(serde(with = "humantime_serde_option")))] pub(crate) resolve_ptr_timeout: Duration, } @@ -172,6 +178,7 @@ fn default_dns_resolve_ptr_timeout() -> Duration { #[derive(Deserialize, Debug, Clone, Builder, Eq, PartialEq)] #[serde(deny_unknown_fields)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] pub struct StorageConfig { /// Location on disk for cached directory information. #[builder(setter(into), default = "default_cache_dir()")] @@ -239,6 +246,7 @@ impl From for StorageConfigBuilder { #[derive(Deserialize, Debug, Clone, Builder, Eq, PartialEq)] #[serde(deny_unknown_fields)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] #[non_exhaustive] pub struct SystemConfig { /// Maximum number of file descriptors we should launch with diff --git a/crates/arti-config/src/options.rs b/crates/arti-config/src/options.rs index 4d832f424..e52db3a73 100644 --- a/crates/arti-config/src/options.rs +++ b/crates/arti-config/src/options.rs @@ -20,6 +20,7 @@ pub(crate) const ARTI_DEFAULTS: &str = concat!(include_str!("./arti_defaults.tom #[derive(Deserialize, Debug, Default, Clone, Builder, Eq, PartialEq)] #[serde(deny_unknown_fields)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] pub struct ApplicationConfig { /// If true, we should watch our configuration files for changes, and reload /// our configuration when they change. @@ -53,6 +54,7 @@ impl ApplicationConfig { #[serde(deny_unknown_fields)] #[non_exhaustive] // TODO(nickm) remove public elements when I revise this. #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] pub struct LoggingConfig { /// Filtering directives that determine tracing levels as described at /// @@ -188,6 +190,7 @@ impl LogfileConfig { #[derive(Deserialize, Debug, Clone, Builder, Eq, PartialEq)] #[serde(deny_unknown_fields)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] pub struct ProxyConfig { /// Port to listen on (at localhost) for incoming SOCKS /// connections. diff --git a/crates/tor-circmgr/src/config.rs b/crates/tor-circmgr/src/config.rs index def852c61..301336996 100644 --- a/crates/tor-circmgr/src/config.rs +++ b/crates/tor-circmgr/src/config.rs @@ -4,6 +4,7 @@ //! //! Most types in this module are re-exported by `arti-client`. +use tor_basic_utils::humantime_serde_option; use tor_config::ConfigBuildError; use derive_builder::Builder; @@ -22,6 +23,7 @@ use std::time::Duration; /// restrictive. #[derive(Debug, Clone, Builder, Deserialize, Eq, PartialEq)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] #[serde(deny_unknown_fields)] pub struct PathConfig { /// Set the length of a bit-prefix for a default IPv4 subnet-family. @@ -103,6 +105,7 @@ impl From for PathConfigBuilder { /// Except as noted, this configuration can be changed on a running Arti client. #[derive(Debug, Clone, Builder, Deserialize, Eq, PartialEq)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] #[serde(deny_unknown_fields)] pub struct PreemptiveCircuitConfig { /// If we have at least this many available circuits, we suspend @@ -128,6 +131,7 @@ pub struct PreemptiveCircuitConfig { /// available for that port? #[builder(default = "default_preemptive_duration()")] #[serde(with = "humantime_serde", default = "default_preemptive_duration")] + #[builder(attrs(serde(with = "humantime_serde_option")))] pub(crate) prediction_lifetime: Duration, /// How many available circuits should we try to have, at minimum, for each @@ -149,12 +153,14 @@ pub struct PreemptiveCircuitConfig { /// [#263](https://gitlab.torproject.org/tpo/core/arti/-/issues/263). #[derive(Debug, Clone, Builder, Deserialize, Eq, PartialEq)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] #[serde(deny_unknown_fields)] pub struct CircuitTiming { /// How long after a circuit has first been used should we give /// it out for new requests? #[builder(default = "default_max_dirtiness()")] #[serde(with = "humantime_serde", default = "default_max_dirtiness")] + #[builder(attrs(serde(with = "humantime_serde_option")))] pub(crate) max_dirtiness: Duration, /// When a circuit is requested, we stop retrying new circuits @@ -162,6 +168,7 @@ pub struct CircuitTiming { // TODO: Impose a maximum or minimum? #[builder(default = "default_request_timeout()")] #[serde(with = "humantime_serde", default = "default_request_timeout")] + #[builder(attrs(serde(with = "humantime_serde_option")))] pub(crate) request_timeout: Duration, /// When a circuit is requested, we stop retrying new circuits after @@ -176,6 +183,7 @@ pub struct CircuitTiming { /// request. #[builder(default = "default_request_loyalty()")] #[serde(with = "humantime_serde", default = "default_request_loyalty")] + #[builder(attrs(serde(with = "humantime_serde_option")))] pub(crate) request_loyalty: Duration, } diff --git a/crates/tor-dirmgr/src/authority.rs b/crates/tor-dirmgr/src/authority.rs index 475bce84c..175a1e9ad 100644 --- a/crates/tor-dirmgr/src/authority.rs +++ b/crates/tor-dirmgr/src/authority.rs @@ -14,6 +14,7 @@ use tor_netdoc::doc::authcert::{AuthCert, AuthCertKeyIds}; // we want our authorities format to be future-proof against adding new info // about each authority. #[derive(Deserialize, Debug, Clone, Builder, Eq, PartialEq)] +#[builder(derive(Deserialize))] pub struct Authority { /// A memorable nickname for this authority. #[builder(setter(into))] diff --git a/crates/tor-dirmgr/src/config.rs b/crates/tor-dirmgr/src/config.rs index 536d6bf4d..9c691e500 100644 --- a/crates/tor-dirmgr/src/config.rs +++ b/crates/tor-dirmgr/src/config.rs @@ -28,6 +28,7 @@ use serde::Deserialize; #[derive(Deserialize, Debug, Clone, Builder, Eq, PartialEq)] #[serde(deny_unknown_fields)] #[builder(build_fn(validate = "Self::validate", error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] pub struct NetworkConfig { /// List of locations to look in when downloading directory information, if /// we don't actually have a directory yet. @@ -110,6 +111,7 @@ impl NetworkConfigBuilder { #[derive(Deserialize, Debug, Clone, Builder, Eq, PartialEq)] #[serde(deny_unknown_fields)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] pub struct DownloadScheduleConfig { /// Top-level configuration for how to retry our initial bootstrap attempt. #[serde(default = "default_retry_bootstrap")] @@ -181,6 +183,7 @@ impl From for DownloadScheduleConfigBuilder { /// running Arti client. Those that cannot are documented. #[derive(Debug, Clone, Builder, Eq, PartialEq)] #[builder(build_fn(error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] pub struct DirMgrConfig { /// Location to use for storing and reading current-format /// directory information. diff --git a/crates/tor-netdir/src/fallback.rs b/crates/tor-netdir/src/fallback.rs index 3de0d9747..f4332b9f5 100644 --- a/crates/tor-netdir/src/fallback.rs +++ b/crates/tor-netdir/src/fallback.rs @@ -27,6 +27,7 @@ use std::net::SocketAddr; // be future-proof against adding new info about each fallback. #[derive(Debug, Clone, Deserialize, Builder, Eq, PartialEq)] #[builder(build_fn(validate = "FallbackDirBuilder::validate", error = "ConfigBuildError"))] +#[builder(derive(Deserialize))] pub struct FallbackDir { /// RSA identity for the directory relay rsa_identity: RsaIdentity,