guardmgr: Don't use guards that are marked as unlisted.

Closes #202.
This commit is contained in:
Nick Mathewson 2021-10-25 10:26:23 -04:00
parent b477f12d83
commit 84f81d14eb
2 changed files with 22 additions and 7 deletions

View File

@ -201,6 +201,11 @@ impl Guard {
self.reachable
}
/// Return true if this guard is listed in the latest NetDir.
pub(crate) fn usable(&self) -> bool {
self.unlisted_since.is_none()
}
/// Copy all _non-persistent_ status from `other` to self.
///
/// Requires that the two `Guard`s have the same ID.

View File

@ -157,8 +157,12 @@ impl GuardSet {
let guards = &self.guards; // avoid borrow issues
let filt = &self.active_filter;
self.primary
.retain(|id| guards.get(id).map(|g| filt.permits(g)).unwrap_or(false));
self.primary.retain(|id| {
guards
.get(id)
.map(|g| g.usable() && filt.permits(g))
.unwrap_or(false)
});
self.primary_guards_invalidated = true;
}
@ -262,7 +266,11 @@ impl GuardSet {
let n_filtered_usable = self
.guards
.values()
.filter(|g| self.active_filter.permits(*g) && g.reachable() != Reachable::Unreachable)
.filter(|g| {
g.usable()
&& self.active_filter.permits(*g)
&& g.reachable() != Reachable::Unreachable
})
.count();
if n_filtered_usable >= params.min_filtered_sample_size {
return false; // We have enough usage guards in our sample.
@ -406,10 +414,10 @@ impl GuardSet {
.chain(self.reachable_sample_ids())
// We only consider each guard the first time it appears.
.unique()
// We only consider guards that the filter allows.
// We only consider usable guards that the filter allows.
.filter_map(|id| {
let g = self.guards.get(id).expect("Inconsistent guard state");
if self.active_filter.permits(g) {
if g.usable() && self.active_filter.permits(g) {
Some(id.clone())
} else {
None
@ -617,7 +625,8 @@ impl GuardSet {
if guard.guard_id() == guard_id {
return Some(true);
}
if self.active_filter.permits(guard) && guard.conforms_to_usage(usage) {
if guard.usable() && self.active_filter.permits(guard) && guard.conforms_to_usage(usage)
{
match (src, guard.reachable()) {
(_, Reachable::Reachable) => return Some(false),
(_, Reachable::Unreachable) => (),
@ -652,7 +661,8 @@ impl GuardSet {
let mut options: Vec<_> = self
.preference_order()
.filter(|(_, g)| {
self.active_filter.permits(*g)
g.usable()
&& self.active_filter.permits(*g)
&& g.reachable() != Reachable::Unreachable
&& !g.exploratory_circ_pending()
&& g.conforms_to_usage(usage)