Update arti-client to new NetDirProvider API.

This allows us to give better errors in the case where bootstrapping
succeeds at first, but fails thereafter for long enough to make our
directory expire.
This commit is contained in:
Nick Mathewson 2022-07-25 12:06:37 -04:00 committed by Ian Jackson
parent a0c48caa46
commit 1f79e1c49b
4 changed files with 35 additions and 6 deletions

2
Cargo.lock generated
View File

@ -168,6 +168,7 @@ dependencies = [
"tor-error", "tor-error",
"tor-guardmgr", "tor-guardmgr",
"tor-llcrypto", "tor-llcrypto",
"tor-netdir",
"tor-netdoc", "tor-netdoc",
"tor-persist", "tor-persist",
"tor-proto", "tor-proto",
@ -3808,6 +3809,7 @@ dependencies = [
"tor-basic-utils", "tor-basic-utils",
"tor-checkable", "tor-checkable",
"tor-config", "tor-config",
"tor-error",
"tor-linkspec", "tor-linkspec",
"tor-llcrypto", "tor-llcrypto",
"tor-netdoc", "tor-netdoc",

View File

@ -75,6 +75,7 @@ tor-dirmgr = { path = "../tor-dirmgr", version = "0.5.0" }
tor-error = { path = "../tor-error", version = "0.3.2" } tor-error = { path = "../tor-error", version = "0.3.2" }
tor-guardmgr = { path = "../tor-guardmgr", version = "0.4.0" } tor-guardmgr = { path = "../tor-guardmgr", version = "0.4.0" }
tor-llcrypto = { path = "../tor-llcrypto", version = "0.3.2" } tor-llcrypto = { path = "../tor-llcrypto", version = "0.3.2" }
tor-netdir = { path = "../tor-netdir", version = "0.4.0" }
tor-netdoc = { path = "../tor-netdoc", version = "0.4.1" } tor-netdoc = { path = "../tor-netdoc", version = "0.4.1" }
tor-persist = { path = "../tor-persist", version = "0.4.1" } tor-persist = { path = "../tor-persist", version = "0.4.1" }
tor-proto = { path = "../tor-proto", version = "0.4.0" } tor-proto = { path = "../tor-proto", version = "0.4.0" }

View File

@ -12,6 +12,7 @@ use tor_basic_utils::futures::{DropNotifyWatchSender, PostageWatchSenderExt};
use tor_circmgr::isolation::Isolation; use tor_circmgr::isolation::Isolation;
use tor_circmgr::{isolation::StreamIsolationBuilder, IsolationToken, TargetPort}; use tor_circmgr::{isolation::StreamIsolationBuilder, IsolationToken, TargetPort};
use tor_config::MutCfg; use tor_config::MutCfg;
use tor_dirmgr::Timeliness;
use tor_error::{internal, Bug}; use tor_error::{internal, Bug};
use tor_persist::{FsStateMgr, StateMgr}; use tor_persist::{FsStateMgr, StateMgr};
use tor_proto::circuit::ClientCirc; use tor_proto::circuit::ClientCirc;
@ -832,6 +833,24 @@ impl<R: Runtime> TorClient<R> {
&self.runtime &self.runtime
} }
/// Return a netdir that is timely according to the rules of `timeliness`.
///
/// Use `action` to
fn netdir(
&self,
timeliness: Timeliness,
action: &'static str,
) -> StdResult<Arc<tor_netdir::NetDir>, ErrorDetail> {
use tor_netdir::Error as E;
match self.dirmgr.netdir(timeliness) {
Ok(netdir) => Ok(netdir),
Err(E::NoInfo) | Err(E::NotEnoughInfo) => {
Err(ErrorDetail::BootstrapRequired { action })
}
Err(error) => Err(ErrorDetail::NoDir { error, action }),
}
}
/// Get or launch an exit-suitable circuit with a given set of /// Get or launch an exit-suitable circuit with a given set of
/// exit ports. /// exit ports.
async fn get_or_launch_exit_circ( async fn get_or_launch_exit_circ(
@ -840,12 +859,7 @@ impl<R: Runtime> TorClient<R> {
prefs: &StreamPrefs, prefs: &StreamPrefs,
) -> StdResult<ClientCirc, ErrorDetail> { ) -> StdResult<ClientCirc, ErrorDetail> {
self.wait_for_bootstrap().await?; self.wait_for_bootstrap().await?;
let dir = self let dir = self.netdir(Timeliness::Timely, "build a circuit")?;
.dirmgr
.latest_netdir()
.ok_or(ErrorDetail::BootstrapRequired {
action: "launch a circuit",
})?;
let isolation = { let isolation = {
let mut b = StreamIsolationBuilder::new(); let mut b = StreamIsolationBuilder::new();

View File

@ -204,6 +204,17 @@ enum ErrorDetail {
action: &'static str action: &'static str
}, },
/// Attempted to use a `TorClient` for something when it did not
/// have a valid directory.
#[error("Tried to {action} without a valid directory")]
NoDir {
/// The underlying error.
#[source]
error: tor_netdir::Error,
/// What we were trying to do that needed a directory.
action: &'static str,
},
/// A programming problem, either in our code or the code calling it. /// A programming problem, either in our code or the code calling it.
#[error("Programming problem")] #[error("Programming problem")]
Bug(#[from] tor_error::Bug), Bug(#[from] tor_error::Bug),
@ -283,6 +294,7 @@ impl tor_error::HasKind for ErrorDetail {
E::Address(_) | E::InvalidHostname => EK::InvalidStreamTarget, E::Address(_) | E::InvalidHostname => EK::InvalidStreamTarget,
E::LocalAddress => EK::ForbiddenStreamTarget, E::LocalAddress => EK::ForbiddenStreamTarget,
E::ChanMgrSetup(e) => e.kind(), E::ChanMgrSetup(e) => e.kind(),
E::NoDir { error, .. } => error.kind(),
E::Bug(e) => e.kind(), E::Bug(e) => e.kind(),
} }
} }