diff --git a/crates/tor-circmgr/src/lib.rs b/crates/tor-circmgr/src/lib.rs index 5d1c55017..8cc1faa27 100644 --- a/crates/tor-circmgr/src/lib.rs +++ b/crates/tor-circmgr/src/lib.rs @@ -441,17 +441,22 @@ impl CircMgr { /// /// Used to implement onion service clients and services. #[cfg(feature = "hs-common")] - #[allow(unused_variables, clippy::missing_panics_doc)] - pub async fn launch_specific_isolated( + #[allow(unused_variables, clippy::missing_panics_doc, dead_code)] // TODO XXX + pub(crate) async fn launch_hs_unmanaged( &self, target: tor_linkspec::OwnedCircTarget, + dir: &NetDir, // TODO hs: this should at least be an enum to define what kind of // circuit we want, in case we have different rules for different types. // It might also need to include a "anonymous?" flag for supporting // single onion services. preferences: (), ) -> Result { - todo!() // TODO hs implement. + let usage = TargetCircUsage::TimeoutTesting; // TODO HS: Wrong usage! + let (_supported_usage, client_circ) = self.mgr.launch_unmanaged(&usage, dir.into()).await?; + + // XXX: Need to retain the supported_usage, maybe? + Ok(client_circ) } /// Launch circuits preemptively, using the preemptive circuit predictor's diff --git a/crates/tor-circmgr/src/mgr.rs b/crates/tor-circmgr/src/mgr.rs index 23aa47cdc..7d52fe893 100644 --- a/crates/tor-circmgr/src/mgr.rs +++ b/crates/tor-circmgr/src/mgr.rs @@ -1367,6 +1367,24 @@ impl AbstractCircMgr { } } + /// Plan and launch a new circuit to a given target, bypassing our managed + /// pool of circuits. + /// + /// This method will always return a new circuit, and never return a circuit + /// that this CircMgr gives out for anything else. + /// + /// The new circuit will participate in the guard and timeout apparatus as + /// appropriate, no retry attempt will be made if the circuit fails. + #[cfg(feature = "hs-common")] + pub(crate) async fn launch_unmanaged( + &self, + usage: &::Usage, + dir: DirInfo<'_>, + ) -> Result<(::Spec, B::Circ)> { + let (_, plan) = self.plan_by_usage(dir, usage)?; + self.builder.build_circuit(plan.plan).await + } + /// Remove the circuit with a given `id` from this manager. /// /// After this function is called, that circuit will no longer be handed