GuardMgr: Change BridgeSet, BridgeRelay to use more references

This will match our needs better and help avoid some `Arc<>`s.

It will be especially helpful for avoiding `Arc`s we don't
actually have.
This commit is contained in:
Nick Mathewson 2022-11-03 15:43:07 -04:00
parent 51a98883c8
commit f4149cd133
2 changed files with 27 additions and 29 deletions

View File

@ -137,24 +137,24 @@ pub type BridgeDescList = HashMap<Arc<BridgeConfig>, Result<BridgeDesc, Box<dyn
//
// TODO pt-client: I doubt that this type is in its final form.
#[derive(Debug, Clone)]
pub(crate) struct BridgeSet {
pub(crate) struct BridgeSet<'a> {
/// When did this BridgeSet last change its listed bridges?
config_last_changed: SystemTime,
/// The configured bridges.
config: Vec<Arc<BridgeConfig>>,
config: &'a [BridgeConfig],
/// A map from those bridges to their descriptors. It may contain elements
/// that are not in `config`.
descs: Arc<BridgeDescList>,
descs: Option<&'a BridgeDescList>,
}
impl BridgeSet {
impl<'a> BridgeSet<'a> {
/// Create a new `BridgeSet` from its configuration.
#[allow(dead_code)] // TODO pt-client remove
pub(crate) fn new(config: Vec<Arc<BridgeConfig>>) -> Self {
pub(crate) fn new(config: &'a [BridgeConfig], descs: Option<&'a BridgeDescList>) -> Self {
Self {
config_last_changed: SystemTime::now(),
config_last_changed: SystemTime::now(), // TODO pt-client wrong.
config,
descs: Arc::new(BridgeDescList::default()),
descs,
}
}
@ -166,24 +166,23 @@ impl BridgeSet {
///
/// We check for a match by identity _and_ channel method, since channel
/// method is part of what makes two bridge lines different.
fn bridge_by_guard<T>(&self, guard: &T) -> Option<&Arc<BridgeConfig>>
fn bridge_by_guard<T>(&self, guard: &T) -> Option<&BridgeConfig>
where
T: ChanTarget,
{
self.config.iter().find(|bridge| {
guard.has_all_relay_ids_from(bridge.as_ref())
&& guard.chan_method() == bridge.chan_method()
guard.has_all_relay_ids_from(*bridge) && guard.chan_method() == bridge.chan_method()
})
}
/// Return a BridgeRelay wrapping the provided configuration, plus any known
/// descriptor for that configuration.
fn relay_by_bridge(&self, bridge: &Arc<BridgeConfig>) -> BridgeRelay {
let desc = match self.descs.get(bridge) {
fn relay_by_bridge(&self, bridge: &'a BridgeConfig) -> BridgeRelay<'a> {
let desc = match self.descs.and_then(|d| d.get(bridge)) {
Some(Ok(b)) => Some(b.clone()),
_ => None,
};
BridgeRelay::new(bridge.clone(), desc)
BridgeRelay::new(bridge, desc)
}
/// Look up a BridgeRelay corresponding to a given guard.
@ -215,7 +214,7 @@ impl BridgeSet {
}
}
impl Universe for BridgeSet {
impl<'a> Universe for BridgeSet<'a> {
fn contains<T: tor_linkspec::ChanTarget>(&self, guard: &T) -> Option<bool> {
match self.bridge_relay_by_guard(guard) {
CandidateStatus::Present(_) => Some(true),
@ -268,10 +267,8 @@ impl Universe for BridgeSet {
self.config
.iter()
.filter(|bridge_conf| {
filter.permits(bridge_conf.as_ref())
&& pre_existing
.all_overlapping(bridge_conf.as_ref())
.is_empty()
filter.permits(*bridge_conf)
&& pre_existing.all_overlapping(*bridge_conf).is_empty()
})
.choose_multiple(&mut rand::thread_rng(), n)
.into_iter()

View File

@ -1,7 +1,5 @@
//! Implementation code to make a bridge something that we can connect to and use to relay traffic.
use std::sync::Arc;
use tor_linkspec::{
ChanTarget, CircTarget, HasAddrs, HasChanMethod, HasRelayIds, RelayIdRef, RelayIdType,
};
@ -12,16 +10,19 @@ use super::{BridgeConfig, BridgeDesc};
/// it traffic.
#[derive(Clone, Debug)]
pub struct BridgeRelay {
pub struct BridgeRelay<'a> {
/// The local configurations for the bridge.
///
/// This is _always_ necessary, since it without it we can't know whether
/// any pluggable transports are needed.
bridge_line: Arc<BridgeConfig>,
bridge_line: &'a BridgeConfig,
/// A descriptor for the bridge.
///
/// If present, it MUST have every RelayId that the `bridge_line` does.
///
/// `BridgeDesc` is an `Arc<>` internally, so we aren't so worried about
/// having this be owned.
desc: Option<BridgeDesc>,
}
@ -34,12 +35,12 @@ pub struct BridgeRelay {
#[derive(Clone, Debug)]
pub struct BridgeRelayWithDesc<'a>(
/// This will _always_ be a bridge relay with a non-None desc.
&'a BridgeRelay,
&'a BridgeRelay<'a>,
);
impl BridgeRelay {
impl<'a> BridgeRelay<'a> {
/// Construct a new BridgeRelay from its parts.
pub(crate) fn new(bridge_line: Arc<BridgeConfig>, desc: Option<BridgeDesc>) -> Self {
pub(crate) fn new(bridge_line: &'a BridgeConfig, desc: Option<BridgeDesc>) -> Self {
Self { bridge_line, desc }
}
@ -56,7 +57,7 @@ impl BridgeRelay {
}
}
impl HasRelayIds for BridgeRelay {
impl<'a> HasRelayIds for BridgeRelay<'a> {
fn identity(&self, key_type: RelayIdType) -> Option<RelayIdRef<'_>> {
self.bridge_line
.identity(key_type)
@ -64,19 +65,19 @@ impl HasRelayIds for BridgeRelay {
}
}
impl HasAddrs for BridgeRelay {
impl<'a> HasAddrs for BridgeRelay<'a> {
fn addrs(&self) -> &[std::net::SocketAddr] {
todo!()
}
}
impl HasChanMethod for BridgeRelay {
impl<'a> HasChanMethod for BridgeRelay<'a> {
fn chan_method(&self) -> tor_linkspec::ChannelMethod {
todo!()
}
}
impl ChanTarget for BridgeRelay {}
impl<'a> ChanTarget for BridgeRelay<'a> {}
impl<'a> HasRelayIds for BridgeRelayWithDesc<'a> {
fn identity(&self, key_type: RelayIdType) -> Option<RelayIdRef<'_>> {