GuardMgr: Pass correct universe to "Bridges" `GuardSet`.
This can probably be done in a simpler way, but for the moment I would prefer to try to minimize the amount of code I'm changing here.
This commit is contained in:
parent
f4149cd133
commit
697a355a21
|
@ -17,3 +17,5 @@ mod relay;
|
|||
pub use config::{BridgeConfig, BridgeParseError};
|
||||
pub use descs::{BridgeDesc, BridgeDescError, BridgeDescEvent, BridgeDescList, BridgeDescProvider};
|
||||
pub use relay::BridgeRelay;
|
||||
|
||||
pub(crate) use descs::BridgeSet;
|
||||
|
|
|
@ -110,7 +110,7 @@ pub use pending::{GuardMonitor, GuardStatus, GuardUsable};
|
|||
pub use skew::SkewEstimate;
|
||||
|
||||
use pending::{PendingRequest, RequestId};
|
||||
use sample::{GuardSet, Universe};
|
||||
use sample::{GuardSet, Universe, UniverseRef};
|
||||
|
||||
use crate::ids::{FirstHopIdInner, GuardId};
|
||||
|
||||
|
@ -720,7 +720,6 @@ impl GuardMgrInner {
|
|||
/// is one) from our [`BridgeDescProvider`](bridge::BridgeDescProvider) (if
|
||||
/// we have one).
|
||||
#[cfg(feature = "bridge-client")]
|
||||
#[allow(dead_code)]
|
||||
fn latest_bridge_desc_list(&self) -> Option<Arc<bridge::BridgeDescList>> {
|
||||
self.bridge_desc_provider
|
||||
.as_ref()
|
||||
|
@ -730,8 +729,10 @@ impl GuardMgrInner {
|
|||
|
||||
/// Run a function that takes `&mut self` and an optional NetDir.
|
||||
///
|
||||
/// We try to use the netdir
|
||||
/// from our [`NetDirProvider`] (if we have one).
|
||||
/// We try to use the netdir from our [`NetDirProvider`] (if we have one).
|
||||
/// Therefore, although its _parameters_ are suitable for every
|
||||
/// [`GuardSet`], its _contents_ might not be. For those, call
|
||||
/// [`with_opt_universe`](Self::with_opt_universe) instead.
|
||||
//
|
||||
// This function exists to handle the lifetime mess where sometimes the
|
||||
// resulting NetDir will borrow from `netdir`, and sometimes it will borrow
|
||||
|
@ -747,6 +748,37 @@ impl GuardMgrInner {
|
|||
}
|
||||
}
|
||||
|
||||
/// Run a function that takes `&mut self` and an optional [`UniverseRef`].
|
||||
///
|
||||
/// We try to get a universe from the appropriate source for the current
|
||||
/// active guard set.
|
||||
fn with_opt_universe<F, T>(&mut self, func: F) -> T
|
||||
where
|
||||
F: for<'a> FnOnce(&mut Self, Option<UniverseRef<'a>>) -> T,
|
||||
{
|
||||
// TODO pt-client: soon, make the function take an GuardSet and a set
|
||||
// of parameters, so we can't get the active set wrong.
|
||||
match self.guards.active_set {
|
||||
GuardSetSelector::Default | GuardSetSelector::Restricted => {
|
||||
if let Some(nd) = self.timely_netdir() {
|
||||
func(self, Some(UniverseRef::NetDir(nd.as_ref())))
|
||||
} else {
|
||||
func(self, None)
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "bridge-client")]
|
||||
GuardSetSelector::Bridges => {
|
||||
let bridge_descs = self.latest_bridge_desc_list();
|
||||
let bridge_config = self.configured_bridges.clone();
|
||||
let bridge_set = bridge::BridgeSet::new(
|
||||
bridge_config.as_ref(),
|
||||
bridge_descs.as_ref().map(|b| b.as_ref()),
|
||||
);
|
||||
func(self, Some(UniverseRef::BridgeSet(bridge_set)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the status of all guards in the active set, based on the passage
|
||||
/// of time and (optionally) a network directory. If no directory is
|
||||
/// provided, we try to find one from the installed provider.
|
||||
|
@ -756,13 +788,14 @@ impl GuardMgrInner {
|
|||
fn update(&mut self, now: SystemTime) {
|
||||
self.with_opt_netdir(|this, netdir| {
|
||||
this.update_active_set_and_filter(netdir);
|
||||
});
|
||||
self.with_opt_universe(|this, univ| {
|
||||
Self::update_guardset_internal(
|
||||
&this.params,
|
||||
now,
|
||||
this.guards.active_guards_mut(),
|
||||
netdir,
|
||||
univ.as_ref(),
|
||||
);
|
||||
//XXXX use real universe
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1226,20 +1259,20 @@ impl GuardMgrInner {
|
|||
};
|
||||
|
||||
// That didn't work. If we have a netdir, expand the sample and try again.
|
||||
let res = self.with_opt_netdir(|this, dir| {
|
||||
let dir = dir?;
|
||||
let res = self.with_opt_universe(|this, univ| {
|
||||
let univ = univ?;
|
||||
trace!("No guards available, trying to extend the sample.");
|
||||
Self::update_guardset_internal(
|
||||
&this.params,
|
||||
wallclock,
|
||||
this.guards.active_guards_mut(),
|
||||
Some(dir),
|
||||
Some(&univ),
|
||||
);
|
||||
if this
|
||||
.guards
|
||||
.active_guards_mut()
|
||||
.extend_sample_as_needed(wallclock, &this.params, dir)
|
||||
{
|
||||
if this.guards.active_guards_mut().extend_sample_as_needed(
|
||||
wallclock,
|
||||
&this.params,
|
||||
&univ,
|
||||
) {
|
||||
this.guards
|
||||
.active_guards_mut()
|
||||
.select_primary_guards(&this.params);
|
||||
|
|
|
@ -25,7 +25,7 @@ use std::collections::{HashMap, HashSet};
|
|||
use std::time::{Instant, SystemTime};
|
||||
use tracing::{debug, info};
|
||||
|
||||
pub(crate) use candidate::{Candidate, CandidateStatus, Universe, WeightThreshold};
|
||||
pub(crate) use candidate::{Candidate, CandidateStatus, Universe, UniverseRef, WeightThreshold};
|
||||
|
||||
/// A set of sampled guards, along with various orderings on subsets
|
||||
/// of the sample.
|
||||
|
|
|
@ -184,3 +184,68 @@ impl Universe for NetDir {
|
|||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// Reference to a [`Universe`] of one of the types supported by this crate.
|
||||
///
|
||||
/// This enum exists because `Universe` is not dyn-compatible.
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) enum UniverseRef<'a> {
|
||||
/// A reference to a netdir.
|
||||
NetDir(&'a NetDir),
|
||||
/// A BridgeSet (which is always references internally)
|
||||
#[cfg(feature = "bridge-client")]
|
||||
BridgeSet(crate::bridge::BridgeSet<'a>),
|
||||
}
|
||||
|
||||
impl<'a> Universe for UniverseRef<'a> {
|
||||
fn contains<T: ChanTarget>(&self, guard: &T) -> Option<bool> {
|
||||
match self {
|
||||
UniverseRef::NetDir(r) => r.contains(guard),
|
||||
#[cfg(feature = "bridge-client")]
|
||||
UniverseRef::BridgeSet(r) => r.contains(guard),
|
||||
}
|
||||
}
|
||||
|
||||
fn status<T: ChanTarget>(&self, guard: &T) -> CandidateStatus<Candidate> {
|
||||
match self {
|
||||
UniverseRef::NetDir(r) => r.status(guard),
|
||||
#[cfg(feature = "bridge-client")]
|
||||
UniverseRef::BridgeSet(r) => r.status(guard),
|
||||
}
|
||||
}
|
||||
|
||||
fn timestamp(&self) -> SystemTime {
|
||||
match self {
|
||||
UniverseRef::NetDir(r) => r.timestamp(),
|
||||
#[cfg(feature = "bridge-client")]
|
||||
UniverseRef::BridgeSet(r) => r.timestamp(),
|
||||
}
|
||||
}
|
||||
|
||||
fn weight_threshold<T>(&self, sample: &ByRelayIds<T>, params: &GuardParams) -> WeightThreshold
|
||||
where
|
||||
T: HasRelayIds,
|
||||
{
|
||||
match self {
|
||||
UniverseRef::NetDir(r) => r.weight_threshold(sample, params),
|
||||
#[cfg(feature = "bridge-client")]
|
||||
UniverseRef::BridgeSet(r) => r.weight_threshold(sample, params),
|
||||
}
|
||||
}
|
||||
|
||||
fn sample<T>(
|
||||
&self,
|
||||
pre_existing: &ByRelayIds<T>,
|
||||
filter: &GuardFilter,
|
||||
n: usize,
|
||||
) -> Vec<(Candidate, RelayWeight)>
|
||||
where
|
||||
T: HasRelayIds,
|
||||
{
|
||||
match self {
|
||||
UniverseRef::NetDir(r) => r.sample(pre_existing, filter, n),
|
||||
#[cfg(feature = "bridge-client")]
|
||||
UniverseRef::BridgeSet(r) => r.sample(pre_existing, filter, n),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue