Loading crates/tor-circmgr/src/err.rs +10 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ pub enum Error { /// Problem creating or updating a guard manager. #[error("Problem creating or updating guards list: {0}")] GuardMgr(#[from] tor_guardmgr::GuardMgrError), GuardMgr(#[source] tor_guardmgr::GuardMgrError), /// Problem selecting a guard relay. #[error("Unable to select a guard relay: {0}")] Loading @@ -84,3 +84,12 @@ impl From<tor_rtcompat::TimeoutError> for Error { Error::CircTimeout } } impl From<tor_guardmgr::GuardMgrError> for Error { fn from(err: tor_guardmgr::GuardMgrError) -> Error { match err { tor_guardmgr::GuardMgrError::State(e) => Error::State(e), _ => Error::GuardMgr(err), } } } crates/tor-guardmgr/src/guard.rs +14 −0 Original line number Diff line number Diff line Loading @@ -201,6 +201,20 @@ impl Guard { self.reachable } /// Copy all _non-persistent_ status from `other` to self. /// /// Requires that the two `Guard`s have the same ID. pub(crate) fn copy_status_from(&mut self, other: &Guard) { debug_assert_eq!(self.id, other.id); self.last_tried_to_connect_at = other.last_tried_to_connect_at; self.retry_at = other.retry_at; self.reachable = other.reachable; self.failing_since = other.failing_since; self.is_dir_cache = other.is_dir_cache; self.exploratory_circ_pending = other.exploratory_circ_pending; } /// Change the reachability status for this guard. fn set_reachable(&mut self, r: Reachable) { if self.reachable != r { Loading crates/tor-guardmgr/src/lib.rs +18 −2 Original line number Diff line number Diff line Loading @@ -288,7 +288,11 @@ impl<R: Runtime> GuardMgr<R> { /// We only call this method if we _don't_ have the lock on the state /// files. If we have the lock, we only want to save. pub fn reload_persistent_state(&self) -> Result<(), GuardMgrError> { warn!("Not yet implemented"); let mut inner = self.inner.lock().expect("Poisoned lock"); if let Some(new_guards) = inner.default_storage.load()? { let now = self.runtime.wallclock(); inner.replace_guards_with(new_guards, now); } Ok(()) } Loading @@ -296,7 +300,11 @@ impl<R: Runtime> GuardMgr<R> { /// /// Requires that we hold the lock on the state files. pub fn upgrade_to_owned_persistent_state(&self) -> Result<(), GuardMgrError> { warn!("Not yet implemented"); let mut inner = self.inner.lock().expect("Poisoned lock"); debug_assert!(inner.default_storage.can_store()); let new_guards = inner.default_storage.load()?.unwrap_or_else(GuardSet::new); let now = self.runtime.wallclock(); inner.replace_guards_with(new_guards, now); Ok(()) } Loading Loading @@ -492,6 +500,14 @@ impl GuardMgrInner { self.active_guards.select_primary_guards(&self.params); } /// Replace the active guard set with `new_guards`, preserving /// non-persistent state for any guards that are retained. fn replace_guards_with(&mut self, mut new_guards: GuardSet, now: SystemTime) { new_guards.copy_status_from(&self.active_guards); self.active_guards = new_guards; self.update(now, None); } /// Called when the circuit manager reports (via [`GuardMonitor`]) that /// a guard succeeded or failed. /// Loading crates/tor-guardmgr/src/sample.rs +9 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,15 @@ impl GuardSet { self.primary_guards_invalidated = true; } /// Copy non-persistent status from every guard shared with `other`. pub(crate) fn copy_status_from(&mut self, other: &GuardSet) { for (id, guard) in self.guards.iter_mut() { if let Some(other_guard) = other.get(id) { guard.copy_status_from(other_guard); } } } /// Return a serializable state object that can be stored to disk /// to capture the current state of this GuardSet. fn get_state(&self) -> GuardSample<'_> { Loading Loading
crates/tor-circmgr/src/err.rs +10 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,7 @@ pub enum Error { /// Problem creating or updating a guard manager. #[error("Problem creating or updating guards list: {0}")] GuardMgr(#[from] tor_guardmgr::GuardMgrError), GuardMgr(#[source] tor_guardmgr::GuardMgrError), /// Problem selecting a guard relay. #[error("Unable to select a guard relay: {0}")] Loading @@ -84,3 +84,12 @@ impl From<tor_rtcompat::TimeoutError> for Error { Error::CircTimeout } } impl From<tor_guardmgr::GuardMgrError> for Error { fn from(err: tor_guardmgr::GuardMgrError) -> Error { match err { tor_guardmgr::GuardMgrError::State(e) => Error::State(e), _ => Error::GuardMgr(err), } } }
crates/tor-guardmgr/src/guard.rs +14 −0 Original line number Diff line number Diff line Loading @@ -201,6 +201,20 @@ impl Guard { self.reachable } /// Copy all _non-persistent_ status from `other` to self. /// /// Requires that the two `Guard`s have the same ID. pub(crate) fn copy_status_from(&mut self, other: &Guard) { debug_assert_eq!(self.id, other.id); self.last_tried_to_connect_at = other.last_tried_to_connect_at; self.retry_at = other.retry_at; self.reachable = other.reachable; self.failing_since = other.failing_since; self.is_dir_cache = other.is_dir_cache; self.exploratory_circ_pending = other.exploratory_circ_pending; } /// Change the reachability status for this guard. fn set_reachable(&mut self, r: Reachable) { if self.reachable != r { Loading
crates/tor-guardmgr/src/lib.rs +18 −2 Original line number Diff line number Diff line Loading @@ -288,7 +288,11 @@ impl<R: Runtime> GuardMgr<R> { /// We only call this method if we _don't_ have the lock on the state /// files. If we have the lock, we only want to save. pub fn reload_persistent_state(&self) -> Result<(), GuardMgrError> { warn!("Not yet implemented"); let mut inner = self.inner.lock().expect("Poisoned lock"); if let Some(new_guards) = inner.default_storage.load()? { let now = self.runtime.wallclock(); inner.replace_guards_with(new_guards, now); } Ok(()) } Loading @@ -296,7 +300,11 @@ impl<R: Runtime> GuardMgr<R> { /// /// Requires that we hold the lock on the state files. pub fn upgrade_to_owned_persistent_state(&self) -> Result<(), GuardMgrError> { warn!("Not yet implemented"); let mut inner = self.inner.lock().expect("Poisoned lock"); debug_assert!(inner.default_storage.can_store()); let new_guards = inner.default_storage.load()?.unwrap_or_else(GuardSet::new); let now = self.runtime.wallclock(); inner.replace_guards_with(new_guards, now); Ok(()) } Loading Loading @@ -492,6 +500,14 @@ impl GuardMgrInner { self.active_guards.select_primary_guards(&self.params); } /// Replace the active guard set with `new_guards`, preserving /// non-persistent state for any guards that are retained. fn replace_guards_with(&mut self, mut new_guards: GuardSet, now: SystemTime) { new_guards.copy_status_from(&self.active_guards); self.active_guards = new_guards; self.update(now, None); } /// Called when the circuit manager reports (via [`GuardMonitor`]) that /// a guard succeeded or failed. /// Loading
crates/tor-guardmgr/src/sample.rs +9 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,15 @@ impl GuardSet { self.primary_guards_invalidated = true; } /// Copy non-persistent status from every guard shared with `other`. pub(crate) fn copy_status_from(&mut self, other: &GuardSet) { for (id, guard) in self.guards.iter_mut() { if let Some(other_guard) = other.get(id) { guard.copy_status_from(other_guard); } } } /// Return a serializable state object that can be stored to disk /// to capture the current state of this GuardSet. fn get_state(&self) -> GuardSample<'_> { Loading