Commit 567995a7 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

ClientCirc: Move n_hops into a new Path type.

This will help with #415
parent 2c5d9852
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
pub(crate) mod celltypes;
pub(crate) mod halfcirc;
mod halfstream;
mod path;
pub(crate) mod reactor;
pub(crate) mod sendme;
mod streammap;
@@ -68,7 +69,6 @@ use futures::channel::{mpsc, oneshot};
use crate::circuit::sendme::StreamRecvWindow;
use futures::SinkExt;
use std::net::IpAddr;
use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Arc;
use tor_cell::relaycell::StreamId;
// use std::time::Duration;
@@ -88,7 +88,7 @@ pub const CIRCUIT_BUFFER_SIZE: usize = 128;
/// they all actually communicate with the Reactor which contains the primary
/// mutable state, and does the actual work.
//
// Effectively, this struct contains two Arcs: one for `hops` and one for
// Effectively, this struct contains two Arcs: one for `path` and one for
// `control` (which surely has something Arc-like in it).  We cannot unify
// these by putting a single Arc around the whole struct, and passing
// an Arc strong reference to the `Reactor`, because then `control` would
@@ -100,10 +100,8 @@ pub const CIRCUIT_BUFFER_SIZE: usize = 128;
// two atomic refcount changes/checks.  Wrapping it in another Arc would
// be overkill.
pub struct ClientCirc {
    /// Number of hops on this circuit.
    ///
    /// This value is incremented after the circuit successfully completes extending to a new hop.
    hops: Arc<AtomicU8>,
    /// Information about this circuit's path.
    path: Arc<path::Path>,
    /// A unique identifier for this circuit.
    unique_id: UniqId,
    /// Channel to send control messages to the reactor.
@@ -239,7 +237,7 @@ impl ClientCirc {
        // TODO: Possibly this should take a hop, rather than just
        // assuming it's the last hop.

        let num_hops = self.hops.load(Ordering::SeqCst);
        let num_hops = self.path.n_hops();
        if num_hops == 0 {
            return Err(Error::from(internal!(
                "Can't begin a stream at the 0th hop"
@@ -408,7 +406,7 @@ impl ClientCirc {

    #[cfg(test)]
    pub fn n_hops(&self) -> u8 {
        self.hops.load(Ordering::SeqCst)
        self.path.n_hops()
    }
}

@@ -427,7 +425,7 @@ impl PendingClientCirc {
    ) -> (PendingClientCirc, reactor::Reactor) {
        let crypto_out = OutboundClientCrypt::new();
        let (control_tx, control_rx) = mpsc::unbounded();
        let num_hops = Arc::new(AtomicU8::new(0));
        let path = Arc::new(path::Path::default());

        let reactor = Reactor {
            control: control_rx,
@@ -440,11 +438,11 @@ impl PendingClientCirc {
            channel_id: id,
            crypto_out,
            meta_handler: None,
            num_hops: Arc::clone(&num_hops),
            path: Arc::clone(&path),
        };

        let circuit = ClientCirc {
            hops: num_hops,
            path,
            unique_id,
            control: control_tx,
            #[cfg(test)]
+24 −0
Original line number Diff line number Diff line
//! Tracking for the path of a client circuit.

use std::sync::atomic::{AtomicU8, Ordering};

/// Helper struct that shares information
#[derive(Debug, Default)]
pub(super) struct Path {
    /// Number of hops on this circuit.
    ///
    /// This value is incremented after the circuit successfully completes extending to a new hop.
    n_hops: AtomicU8,
}

impl Path {
    /// Return the number of hops in this path
    pub(super) fn n_hops(&self) -> u8 {
        self.n_hops.load(Ordering::SeqCst)
    }

    /// Add 1 to the number of hops in this path.
    pub(super) fn inc_hops(&self) {
        self.n_hops.fetch_add(1, Ordering::SeqCst);
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -24,11 +24,11 @@ use futures::Sink;
use futures::Stream;
use tor_error::internal;

use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Arc;
use std::task::{Context, Poll};

use crate::channel::Channel;
use crate::circuit::path;
#[cfg(test)]
use crate::circuit::sendme::CircTag;
use crate::circuit::sendme::StreamSendWindow;
@@ -446,7 +446,7 @@ pub struct Reactor {
    /// List of hops state objects used by the reactor
    pub(super) hops: Vec<CircHop>,
    /// Shared atomic for the number of hops this circuit has.
    pub(super) num_hops: Arc<AtomicU8>,
    pub(super) path: Arc<path::Path>,
    /// An identifier for logging about this reactor's circuit.
    pub(super) unique_id: UniqId,
    /// This circuit's identifier on the upstream channel.
@@ -811,7 +811,7 @@ impl Reactor {
        self.hops.push(hop);
        self.crypto_in.add_layer(rev);
        self.crypto_out.add_layer(fwd);
        self.num_hops.fetch_add(1, Ordering::SeqCst);
        self.path.inc_hops();
    }

    /// Handle a RELAY cell on this circuit with stream ID 0.