Use hashset _inside_ GuardRestriction.

This approach saves us from a linear search when picking guards.
This commit is contained in:
Nick Mathewson 2021-12-06 09:44:56 -05:00
parent 54971e3c9a
commit cfc31dadd4
3 changed files with 8 additions and 7 deletions

View File

@ -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<tor_guardmgr::GuardRestriction> = 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(|| {

View File

@ -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),
}
}

View File

@ -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<pk::ed25519::Ed25519Identity>),
}
/// An error caused while creating or updating a guard manager.