diff --git a/crates/tor-circmgr/src/path/exitpath.rs b/crates/tor-circmgr/src/path/exitpath.rs index 3b3a963fb..24fc7793e 100644 --- a/crates/tor-circmgr/src/path/exitpath.rs +++ b/crates/tor-circmgr/src/path/exitpath.rs @@ -141,25 +141,23 @@ impl<'a> ExitPathBuilder<'a> { Some(guardmgr) => { let mut b = tor_guardmgr::GuardUsageBuilder::default(); b.kind(tor_guardmgr::GuardUsageKind::Data); - let mut restrictions: Vec = Vec::new(); + let mut family = std::collections::HashSet::new(); guardmgr.update_network(netdir); // possibly unnecessary. if let Some(exit_relay) = chosen_exit { let id = exit_relay.ed_identity(); - restrictions.push(tor_guardmgr::GuardRestriction::AvoidId(*id)); + family.insert(*id); for rsaid in exit_relay.family().members() { let relay = netdir.by_rsa_id(rsaid); if let Some(r) = relay { for fam_relay in r.family().members() { if fam_relay == exit_relay.rsa_identity() { - restrictions.push(tor_guardmgr::GuardRestriction::AvoidId( - *r.ed_identity(), - )); + family.insert(*r.ed_identity()); } } } } } - b.restrictions(restrictions); + b.push_restriction(tor_guardmgr::GuardRestriction::AvoidAllIds(family)); let guard_usage = b.build().expect("Failed while building guard usage!"); let (guard, mut mon, usable) = guardmgr.select_guard(guard_usage, Some(netdir))?; let guard = guard.get_relay(netdir).ok_or_else(|| { diff --git a/crates/tor-guardmgr/src/guard.rs b/crates/tor-guardmgr/src/guard.rs index 1b0f31df6..e9dce5e29 100644 --- a/crates/tor-guardmgr/src/guard.rs +++ b/crates/tor-guardmgr/src/guard.rs @@ -306,6 +306,7 @@ impl Guard { fn obeys_restriction(&self, r: &GuardRestriction) -> bool { match r { GuardRestriction::AvoidId(ed) => &self.id.ed25519 != ed, + GuardRestriction::AvoidAllIds(ids) => !ids.contains(&self.id.ed25519), } } diff --git a/crates/tor-guardmgr/src/lib.rs b/crates/tor-guardmgr/src/lib.rs index 7eb7ccc12..9a1fa120b 100644 --- a/crates/tor-guardmgr/src/lib.rs +++ b/crates/tor-guardmgr/src/lib.rs @@ -133,7 +133,7 @@ use futures::channel::mpsc; use futures::task::{SpawnError, SpawnExt}; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::convert::{TryFrom, TryInto}; use std::net::SocketAddr; use std::sync::{Arc, Mutex}; @@ -919,6 +919,8 @@ impl GuardUsageBuilder { pub enum GuardRestriction { /// Don't pick a guard with the provided Ed25519 identity. AvoidId(pk::ed25519::Ed25519Identity), + /// Don't pick a guard with any of the provided Ed25519 identities. + AvoidAllIds(HashSet), } /// An error caused while creating or updating a guard manager.