From 4a98ed13013cd0cd85ada3c61dc535ebf852dd0c Mon Sep 17 00:00:00 2001 From: eta <tor@eta.st> Date: Fri, 22 Apr 2022 16:39:28 +0100 Subject: [PATCH] tor-dirmgr: move query_into_requests into bootstrap.rs - There's no good reason these functions needed to be part of the dirmgr, apart from needing a runtime and a store. - However, we can just add those as arguments and copy them over. This commit does that. --- crates/tor-dirmgr/src/bootstrap.rs | 64 +++++++++++++++++++++++++++++- crates/tor-dirmgr/src/lib.rs | 51 ++++-------------------- 2 files changed, 71 insertions(+), 44 deletions(-) diff --git a/crates/tor-dirmgr/src/bootstrap.rs b/crates/tor-dirmgr/src/bootstrap.rs index 61a2a2ebb4..da4b478da5 100644 --- a/crates/tor-dirmgr/src/bootstrap.rs +++ b/crates/tor-dirmgr/src/bootstrap.rs @@ -11,7 +11,7 @@ use std::{ use crate::{ docid::{self, ClientRequest}, state::WriteNetDir, - upgrade_weak_ref, DirMgr, DirState, DocId, DocumentText, Error, Readiness, Result, + upgrade_weak_ref, DirMgr, DirState, DocId, DocQuery, DocumentText, Error, Readiness, Result, }; use futures::channel::oneshot; @@ -27,6 +27,7 @@ use crate::storage::Store; use once_cell::sync::Lazy; #[cfg(test)] use std::sync::Mutex; +use tor_netdoc::doc::netstatus::ConsensusFlavor; /// Load a set of documents from a `Store`, returning all documents found in the store. /// Note that this may be less than the number of documents in `missing`. @@ -41,6 +42,67 @@ fn load_documents_from_store( Ok(loaded) } +/// Construct an appropriate ClientRequest to download a consensus +/// of the given flavor. +// FIXME(eta): remove pub +pub(crate) fn make_consensus_request( + now: SystemTime, + flavor: ConsensusFlavor, + store: &dyn Store, +) -> Result<ClientRequest> { + let mut request = tor_dirclient::request::ConsensusRequest::new(flavor); + + let default_cutoff = crate::default_consensus_cutoff(now)?; + + match store.latest_consensus_meta(flavor) { + Ok(Some(meta)) => { + let valid_after = meta.lifetime().valid_after(); + request.set_last_consensus_date(std::cmp::max(valid_after, default_cutoff)); + request.push_old_consensus_digest(*meta.sha3_256_of_signed()); + } + latest => { + if let Err(e) = latest { + warn!("Error loading directory metadata: {}", e); + } + // If we don't have a consensus, then request one that's + // "reasonably new". That way, our clock is set far in the + // future, we won't download stuff we can't use. + request.set_last_consensus_date(default_cutoff); + } + } + + Ok(ClientRequest::Consensus(request)) +} + +/// Convert a DocQuery into a set of ClientRequests, suitable for sending +/// to a directory cache. +// FIXME(eta): remove pub +pub(crate) fn query_into_requests<R: Runtime>( + rt: &R, + q: DocQuery, + store: &dyn Store, +) -> Result<Vec<ClientRequest>> { + let mut res = Vec::new(); + for q in q.split_for_download() { + match q { + DocQuery::LatestConsensus { flavor, .. } => { + res.push(make_consensus_request(rt.wallclock(), flavor, store)?); + } + DocQuery::AuthCert(ids) => { + res.push(ClientRequest::AuthCert(ids.into_iter().collect())); + } + DocQuery::Microdesc(ids) => { + res.push(ClientRequest::Microdescs(ids.into_iter().collect())); + } + #[cfg(feature = "routerdesc")] + DocQuery::RouterDesc(ids) => { + res.push(ClientRequest::RouterDescs(ids.into_iter().collect())); + } + } + } + Ok(res) +} + /// Testing helper: if this is Some, then we return it in place of any /// response to fetch_single. /// diff --git a/crates/tor-dirmgr/src/lib.rs b/crates/tor-dirmgr/src/lib.rs index 8a6869ee6f..8766dc8f3c 100644 --- a/crates/tor-dirmgr/src/lib.rs +++ b/crates/tor-dirmgr/src/lib.rs @@ -804,57 +804,22 @@ impl<R: Runtime> DirMgr<R> { /// This conversion has to be a function of the dirmgr, since it may /// require knowledge about our current state. fn query_into_requests(&self, q: DocQuery) -> Result<Vec<ClientRequest>> { - let mut res = Vec::new(); - for q in q.split_for_download() { - match q { - DocQuery::LatestConsensus { flavor, .. } => { - res.push(self.make_consensus_request(self.runtime.wallclock(), flavor)?); - } - DocQuery::AuthCert(ids) => { - res.push(ClientRequest::AuthCert(ids.into_iter().collect())); - } - DocQuery::Microdesc(ids) => { - res.push(ClientRequest::Microdescs(ids.into_iter().collect())); - } - #[cfg(feature = "routerdesc")] - DocQuery::RouterDesc(ids) => { - res.push(ClientRequest::RouterDescs(ids.into_iter().collect())); - } - } - } - Ok(res) + // FIXME(eta): this code is not long for this world + let store = self.store.lock().expect("Directory storage lock poisoned"); + bootstrap::query_into_requests(&self.runtime, q, store.deref()) } /// Construct an appropriate ClientRequest to download a consensus /// of the given flavor. + #[allow(dead_code)] fn make_consensus_request( &self, now: SystemTime, flavor: ConsensusFlavor, ) -> Result<ClientRequest> { - let mut request = tor_dirclient::request::ConsensusRequest::new(flavor); - - let default_cutoff = default_consensus_cutoff(now)?; - - let r = self.store.lock().expect("Directory storage lock poisoned"); - match r.latest_consensus_meta(flavor) { - Ok(Some(meta)) => { - let valid_after = meta.lifetime().valid_after(); - request.set_last_consensus_date(std::cmp::max(valid_after, default_cutoff)); - request.push_old_consensus_digest(*meta.sha3_256_of_signed()); - } - latest => { - if let Err(e) = latest { - warn!("Error loading directory metadata: {}", e); - } - // If we don't have a consensus, then request one that's - // "reasonably new". That way, our clock is set far in the - // future, we won't download stuff we can't use. - request.set_last_consensus_date(default_cutoff); - } - } - - Ok(ClientRequest::Consensus(request)) + // FIXME(eta): this code is not long for this world + let store = self.store.lock().expect("Directory storage lock poisoned"); + bootstrap::make_consensus_request(now, flavor, store.deref()) } /// Given a request we sent and the response we got from a @@ -1053,7 +1018,7 @@ const CONSENSUS_ALLOW_SKEW: Duration = Duration::from_secs(3600 * 48); /// Given a time `now`, return the age of the oldest consensus that we should /// request at that time. -fn default_consensus_cutoff(now: SystemTime) -> Result<SystemTime> { +pub(crate) fn default_consensus_cutoff(now: SystemTime) -> Result<SystemTime> { let cutoff = time::OffsetDateTime::from(now - CONSENSUS_ALLOW_SKEW); // We now round cutoff to the next hour, so that we aren't leaking our exact // time to the directory cache. -- GitLab