Commit 2c28e217 authored by eta's avatar eta
Browse files

tor-dirmgr/state.rs: take an object to get a netdir, not a netdir

- Taking a previous netdir directly and keeping it around before we need
  it is a bit of a waste of memory, and also doesn't mesh well with how
  SharedMutArc works.
- To remedy this, introduce a new trait `PreviousNetDir` and have the
  state machines take that instead. (I was a bit tempted to just pass in
  the SharedMutArc directly. Maybe I should've done that.)
parent 27073a5d
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -187,7 +187,9 @@ pub struct DirMgr<R: Runtime> {
    ///
    /// We use the RwLock so that we can give this out to a bunch of other
    /// users, and replace it once a new directory is bootstrapped.
    netdir: SharedMutArc<NetDir>,
    // TODO(eta): Eurgh! This is so many Arcs! (especially considering this
    //            gets wrapped in an Arc)
    netdir: Arc<SharedMutArc<NetDir>>,

    /// A publisher handle that we notify whenever the consensus changes.
    events: event::FlagPublisher<DirEvent>,
@@ -523,7 +525,7 @@ impl<R: Runtime> DirMgr<R> {
                dirmgr.runtime.clone(),
                dirmgr.config.get(),
                CacheUsage::CacheOkay,
                dirmgr.netdir.get(),
                Some(dirmgr.netdir.clone()),
                #[cfg(feature = "dirfilter")]
                dirmgr
                    .filter
@@ -706,7 +708,7 @@ impl<R: Runtime> DirMgr<R> {
        offline: bool,
    ) -> Result<Self> {
        let store = Mutex::new(config.open_store(offline)?);
        let netdir = SharedMutArc::new();
        let netdir = Arc::new(SharedMutArc::new());
        let events = event::FlagPublisher::new();

        let (send_status, receive_status) = postage::watch::channel();
+24 −9
Original line number Diff line number Diff line
@@ -25,13 +25,13 @@ use tracing::{info, warn};
use crate::event::{DirStatus, DirStatusInner};

use crate::storage::DynStore;
use crate::DocSource;
use crate::{
    docmeta::{AuthCertMeta, ConsensusMeta},
    event,
    retry::DownloadSchedule,
    CacheUsage, ClientRequest, DirMgrConfig, DocId, DocumentText, Error, Readiness, Result,
};
use crate::{DocSource, SharedMutArc};
use tor_checkable::{ExternallySigned, SelfSigned, Timebound};
use tor_llcrypto::pk::rsa::RsaIdentity;
use tor_netdoc::doc::{
@@ -141,6 +141,18 @@ pub(crate) trait DirState: Send {
    fn reset(self: Box<Self>) -> Result<Box<dyn DirState>>;
}

/// An object that can provide a previous netdir for the bootstrapping state machines to use.
pub(crate) trait PreviousNetDir: Send + Sync + 'static + Debug {
    /// Get the previous netdir, if there still is one.
    fn get_netdir(&self) -> Option<Arc<NetDir>>;
}

impl PreviousNetDir for SharedMutArc<NetDir> {
    fn get_netdir(&self) -> Option<Arc<NetDir>> {
        self.get()
    }
}

/// Initial state: fetching or loading a consensus directory.
#[derive(Clone, Debug)]
pub(crate) struct GetConsensusState<R: Runtime> {
@@ -172,7 +184,7 @@ pub(crate) struct GetConsensusState<R: Runtime> {
    /// purposes.
    config: Arc<DirMgrConfig>,
    /// If one exists, the netdir we're trying to update.
    prev_netdir: Option<Arc<NetDir>>,
    prev_netdir: Option<Arc<dyn PreviousNetDir>>,

    /// A filter that gets applied to directory objects before we use them.
    #[cfg(feature = "dirfilter")]
@@ -187,7 +199,7 @@ impl<R: Runtime> GetConsensusState<R> {
        rt: R,
        config: Arc<DirMgrConfig>,
        cache_usage: CacheUsage,
        prev_netdir: Option<Arc<NetDir>>,
        prev_netdir: Option<Arc<dyn PreviousNetDir>>,
        #[cfg(feature = "dirfilter")] filter: Arc<dyn crate::filter::DirFilter>,
    ) -> Self {
        let authority_ids = config
@@ -195,7 +207,10 @@ impl<R: Runtime> GetConsensusState<R> {
            .iter()
            .map(|auth| auth.v3ident)
            .collect();
        let after = prev_netdir.as_ref().map(|nd| nd.lifetime().valid_after());
        let after = prev_netdir
            .as_ref()
            .and_then(|x| x.get_netdir())
            .map(|nd| nd.lifetime().valid_after());

        GetConsensusState {
            cache_usage,
@@ -392,7 +407,7 @@ struct GetCertsState<R: Runtime> {
    /// purposes.
    config: Arc<DirMgrConfig>,
    /// If one exists, the netdir we're trying to update.
    prev_netdir: Option<Arc<NetDir>>,
    prev_netdir: Option<Arc<dyn PreviousNetDir>>,

    /// A filter that gets applied to directory objects before we use them.
    #[cfg(feature = "dirfilter")]
@@ -580,7 +595,7 @@ struct GetMicrodescsState<R: Runtime> {
    /// purposes.
    config: Arc<DirMgrConfig>,
    /// If one exists, the netdir we're trying to update.
    prev_netdir: Option<Arc<NetDir>>,
    prev_netdir: Option<Arc<dyn PreviousNetDir>>,

    /// A filter that gets applied to directory objects before we use them.
    #[cfg(feature = "dirfilter")]
@@ -723,7 +738,7 @@ impl<R: Runtime> GetMicrodescsState<R> {
        meta: ConsensusMeta,
        rt: R,
        config: Arc<DirMgrConfig>,
        prev_netdir: Option<Arc<NetDir>>,
        prev_netdir: Option<Arc<dyn PreviousNetDir>>,
        #[cfg(feature = "dirfilter")] filter: Arc<dyn crate::filter::DirFilter>,
    ) -> Self {
        let reset_time = consensus.lifetime().valid_until();
@@ -731,8 +746,8 @@ impl<R: Runtime> GetMicrodescsState<R> {

        let params = &config.override_net_params;
        let mut partial_dir = PartialNetDir::new(consensus, Some(params));
        if let Some(old_dir) = prev_netdir.as_ref() {
            partial_dir.fill_from_previous_netdir(old_dir);
        if let Some(old_dir) = prev_netdir.as_ref().and_then(|x| x.get_netdir()) {
            partial_dir.fill_from_previous_netdir(&old_dir);
        }

        GetMicrodescsState {