GuardMgr: Also apply filters to fallback directories.

This commit is contained in:
Nick Mathewson 2022-06-01 11:08:42 -04:00
parent a189aaf1fb
commit e3c2a86195
2 changed files with 12 additions and 7 deletions

View File

@ -129,6 +129,7 @@ impl FallbackState {
&self, &self,
rng: &mut R, rng: &mut R,
now: Instant, now: Instant,
filter: &crate::GuardFilter,
) -> Result<&crate::FirstHop, PickGuardError> { ) -> Result<&crate::FirstHop, PickGuardError> {
if self.fallbacks.is_empty() { if self.fallbacks.is_empty() {
return Err(PickGuardError::NoCandidatesAvailable); return Err(PickGuardError::NoCandidatesAvailable);
@ -136,7 +137,7 @@ impl FallbackState {
self.fallbacks self.fallbacks
.iter() .iter()
.filter(|ent| ent.status.usable_at(now)) .filter(|ent| ent.status.usable_at(now) && filter.permits(&ent.fallback))
.choose(rng) .choose(rng)
.map(|ent| &ent.fallback) .map(|ent| &ent.fallback)
.ok_or_else(|| PickGuardError::AllFallbacksDown { .ok_or_else(|| PickGuardError::AllFallbacksDown {
@ -315,6 +316,7 @@ mod test {
]; ];
let list: FallbackList = fbs.into(); let list: FallbackList = fbs.into();
let mut set: FallbackState = list.into(); let mut set: FallbackState = list.into();
let filter = crate::GuardFilter::unfiltered();
let mut counts = [0_usize; 4]; let mut counts = [0_usize; 4];
let now = Instant::now(); let now = Instant::now();
@ -328,7 +330,7 @@ mod test {
} }
// Basic case: everybody is up. // Basic case: everybody is up.
for _ in 0..100 { for _ in 0..100 {
let fb = set.choose(&mut rng, now).unwrap(); let fb = set.choose(&mut rng, now, &filter).unwrap();
let idx = lookup_idx(&set, fb.id()).unwrap(); let idx = lookup_idx(&set, fb.id()).unwrap();
counts[idx] += 1; counts[idx] += 1;
} }
@ -340,7 +342,7 @@ mod test {
set.note_failure(&ids[2], now); set.note_failure(&ids[2], now);
counts = [0; 4]; counts = [0; 4];
for _ in 0..100 { for _ in 0..100 {
let fb = set.choose(&mut rng, now).unwrap(); let fb = set.choose(&mut rng, now, &filter).unwrap();
let idx = lookup_idx(&set, fb.id()).unwrap(); let idx = lookup_idx(&set, fb.id()).unwrap();
counts[idx] += 1; counts[idx] += 1;
} }
@ -352,14 +354,14 @@ mod test {
set.note_failure(id, now); set.note_failure(id, now);
} }
assert!(matches!( assert!(matches!(
set.choose(&mut rng, now), set.choose(&mut rng, now, &filter),
Err(PickGuardError::AllFallbacksDown { .. }) Err(PickGuardError::AllFallbacksDown { .. })
)); ));
// Construct an empty set; make sure we get the right error. // Construct an empty set; make sure we get the right error.
let empty_set = FallbackState::from(FallbackList::from(vec![])); let empty_set = FallbackState::from(FallbackList::from(vec![]));
assert!(matches!( assert!(matches!(
empty_set.choose(&mut rng, now), empty_set.choose(&mut rng, now, &filter),
Err(PickGuardError::NoCandidatesAvailable) Err(PickGuardError::NoCandidatesAvailable)
)); ));

View File

@ -1155,8 +1155,11 @@ impl GuardMgrInner {
&self, &self,
now: Instant, now: Instant,
) -> Result<(sample::ListKind, FirstHop), PickGuardError> { ) -> Result<(sample::ListKind, FirstHop), PickGuardError> {
let fallback = self.fallbacks.choose(&mut rand::thread_rng(), now)?; let filt = self.guards.active_guards().filter();
Ok((sample::ListKind::Fallback, fallback.clone()))
let fallback = self.fallbacks.choose(&mut rand::thread_rng(), now, filt)?;
let fallback = filt.modify_hop(fallback.clone())?;
Ok((sample::ListKind::Fallback, fallback))
} }
} }