From 2b0d04a5fe095a0a7ea32a659f3dc091aadc40aa Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 21 Jun 2023 11:52:13 -0400 Subject: [PATCH] circmgr: New API to expose estimate-based timeouts. This will help create good timeout values for various onion-service operations. --- crates/tor-circmgr/semver.md | 1 + crates/tor-circmgr/src/build.rs | 2 -- crates/tor-circmgr/src/lib.rs | 32 +++++++++++++++++++++++++++++- crates/tor-circmgr/src/timeouts.rs | 2 +- 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 crates/tor-circmgr/semver.md diff --git a/crates/tor-circmgr/semver.md b/crates/tor-circmgr/semver.md new file mode 100644 index 000000000..591e285dd --- /dev/null +++ b/crates/tor-circmgr/semver.md @@ -0,0 +1 @@ +ADDED: estimate_timeout function, and public timeouts::Action. diff --git a/crates/tor-circmgr/src/build.rs b/crates/tor-circmgr/src/build.rs index 88008ae40..ef66ba8d1 100644 --- a/crates/tor-circmgr/src/build.rs +++ b/crates/tor-circmgr/src/build.rs @@ -316,7 +316,6 @@ impl Builder { } /// Return a reference to this Builder's timeout estimator. - #[cfg(feature = "hs-common")] pub(crate) fn estimator(&self) -> &timeouts::Estimator { &self.timeouts } @@ -459,7 +458,6 @@ impl CircuitBuilder { } /// Return a reference to this builder's timeout estimator. - #[cfg(feature = "hs-common")] pub(crate) fn estimator(&self) -> &timeouts::Estimator { self.builder.estimator() } diff --git a/crates/tor-circmgr/src/lib.rs b/crates/tor-circmgr/src/lib.rs index bb9b2ab1c..50adb023d 100644 --- a/crates/tor-circmgr/src/lib.rs +++ b/crates/tor-circmgr/src/lib.rs @@ -68,7 +68,7 @@ pub mod isolation; mod mgr; pub mod path; mod preemptive; -mod timeouts; +pub mod timeouts; mod usage; pub use err::Error; @@ -548,6 +548,36 @@ impl CircMgr { self.mgr.retire_all_circuits(); } + /// Return an estimate-based delay for how long a given + /// [`Action`](timeouts::Action) should be allowed to complete. + /// + /// Note that **you do not need to use this function** in order to get + /// reasonable timeouts for the circuit-building operations provided by the + /// `tor-circmgr` crate: those, unless specifically noted, always use these + /// timeouts to cancel circuit operations that have taken too long. + /// + /// Instead, you should only use this function when you need to estimate how + /// long some _other_ operation should take to complete. For example, if + /// you are sending a request over a 3-hop circuit and waiting for a reply, + /// you might choose to wait for `estimate_timeout(Action::RoundTrip { + /// length: 3 })`. + /// + /// Note also that this function returns a _timeout_ that the operation + /// should be permitted to complete, not an estimated Duration that the + /// operation _will_ take to complete. Timeouts are chosen to ensure that + /// most operations will complete, but very slow ones will not. So even if + /// we expect that a circuit will complete in (say) 3 seconds, we might + /// still allow a timeout of 4.5 seconds, to ensure that most circuits can + /// complete. + /// + /// Estimate-based timeouts may change over time, given observations on the + /// actual amount of time needed for circuits to complete building. If not + /// enough information has been gathered, a reasonable default will be used. + pub fn estimate_timeout(&self, timeout_action: &timeouts::Action) -> std::time::Duration { + let (timeout, _abandon) = self.mgr.peek_builder().estimator().timeouts(timeout_action); + timeout + } + /// Expire every circuit that has been dirty for too long. /// /// Expired circuits are not closed while they still have users, diff --git a/crates/tor-circmgr/src/timeouts.rs b/crates/tor-circmgr/src/timeouts.rs index 9ec5a93f2..95acf7ad0 100644 --- a/crates/tor-circmgr/src/timeouts.rs +++ b/crates/tor-circmgr/src/timeouts.rs @@ -66,7 +66,7 @@ pub(crate) trait TimeoutEstimator { /// A possible action for which we can try to estimate a timeout. #[non_exhaustive] #[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub(crate) enum Action { +pub enum Action { /// Build a circuit of a given length. BuildCircuit { /// The length of the circuit to construct.