Commit 764930b9 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

tor-proto: Remember peer information in circuit and channel

Each channel now remembers an OwnedChanTarget.

Each circuit now remembers a vector of OwnedChanTarget to represent
the path that it was constructed for.

Part of #415.
parent 567995a7
Loading
Loading
Loading
Loading
+15 −13
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ use crate::{Error, Result};
use std::pin::Pin;
use tor_cell::chancell::{msg, ChanCell, CircId};
use tor_error::internal;
use tor_linkspec::ChanTarget;
use tor_linkspec::{ChanTarget, OwnedChanTarget};
use tor_llcrypto::pk::ed25519::Ed25519Identity;
use tor_llcrypto::pk::rsa::RsaIdentity;

@@ -126,10 +126,8 @@ pub struct Channel {
pub(crate) struct ChannelDetails {
    /// A unique identifier for this channel.
    unique_id: UniqId,
    /// Validated Ed25519 identity for this peer.
    ed25519_id: Ed25519Identity,
    /// Validated RSA identity for this peer.
    rsa_id: RsaIdentity,
    /// Validated identity and address information for this peer.
    peer_id: OwnedChanTarget,
    /// If true, this channel is closing.
    closed: AtomicBool,
    /// Since when the channel became unused.
@@ -240,8 +238,7 @@ impl Channel {
        sink: BoxedChannelSink,
        stream: BoxedChannelStream,
        unique_id: UniqId,
        ed25519_id: Ed25519Identity,
        rsa_id: RsaIdentity,
        peer_id: OwnedChanTarget,
    ) -> (Self, reactor::Reactor) {
        use circmap::{CircIdRange, CircMap};
        let circmap = CircMap::new(CircIdRange::High);
@@ -254,8 +251,7 @@ impl Channel {

        let details = ChannelDetails {
            unique_id,
            ed25519_id,
            rsa_id,
            peer_id,
            closed,
            unused_since,
        };
@@ -288,12 +284,18 @@ impl Channel {

    /// Return the Ed25519 identity for the peer of this channel.
    pub fn peer_ed25519_id(&self) -> &Ed25519Identity {
        &self.details.ed25519_id
        self.details.peer_id.ed_identity()
    }

    /// Return the (legacy) RSA identity for the peer of this channel.
    pub fn peer_rsa_id(&self) -> &RsaIdentity {
        &self.details.rsa_id
        self.details.peer_id.rsa_identity()
    }

    /// Return an OwnedChanTarget representing the actual handshake used to
    /// create this channel.
    pub fn target(&self) -> &OwnedChanTarget {
        &self.details.peer_id
    }

    /// Return an error if this channel is somehow mismatched with the
@@ -452,11 +454,11 @@ pub(crate) mod test {
    fn fake_channel_details() -> Arc<ChannelDetails> {
        let unique_id = UniqId::new();
        let unused_since = OptTimestamp::new();
        let peer_id = OwnedChanTarget::new(vec![], [6_u8; 32].into(), [10_u8; 20].into());

        Arc::new(ChannelDetails {
            unique_id,
            ed25519_id: [6_u8; 32].into(),
            rsa_id: [10_u8; 20].into(),
            peer_id,
            closed: AtomicBool::new(false),
            unused_since,
        })
+8 −3
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ use std::net::SocketAddr;
use std::sync::Arc;

use tor_bytes::Reader;
use tor_linkspec::ChanTarget;
use tor_linkspec::{ChanTarget, OwnedChanTarget};
use tor_llcrypto as ll;
use tor_llcrypto::pk::ed25519::Ed25519Identity;
use tor_llcrypto::pk::rsa::RsaIdentity;
@@ -453,13 +453,18 @@ impl<T: AsyncRead + AsyncWrite + Send + Unpin + 'static> VerifiedChannel<T> {

        let (tls_sink, tls_stream) = self.tls.split();

        let peer_id = OwnedChanTarget::new(
            self.target_addr.into_iter().collect(),
            self.ed25519_id,
            self.rsa_id,
        );

        Ok(super::Channel::new(
            self.link_protocol,
            Box::new(tls_sink),
            Box::new(tls_stream),
            self.unique_id,
            self.ed25519_id,
            self.rsa_id,
            peer_id,
        ))
    }
}
+3 −4
Original line number Diff line number Diff line
@@ -417,6 +417,7 @@ pub(crate) mod test {
    use futures::sink::SinkExt;
    use futures::stream::StreamExt;
    use futures::task::SpawnExt;
    use tor_linkspec::OwnedChanTarget;

    type CodecResult = std::result::Result<ChanCell, CodecError>;

@@ -430,8 +431,7 @@ pub(crate) mod test {
        let (send1, recv1) = mpsc::channel(32);
        let (send2, recv2) = mpsc::channel(32);
        let unique_id = UniqId::new();
        let ed_id = [6; 32].into();
        let rsa_id = [10; 20].into();
        let dummy_target = OwnedChanTarget::new(vec![], [6; 32].into(), [10; 20].into());
        let send1 = send1.sink_map_err(|e| {
            trace!("got sink error: {}", e);
            CodecError::Cell(tor_cell::Error::ChanProto("dummy message".into()))
@@ -441,8 +441,7 @@ pub(crate) mod test {
            Box::new(send1),
            Box::new(recv2),
            unique_id,
            ed_id,
            rsa_id,
            dummy_target,
        );
        (chan, reactor, recv1, send2)
    }
+9 −4
Original line number Diff line number Diff line
@@ -61,13 +61,14 @@ use tor_cell::{
    relaycell::msg::{Begin, RelayMsg, Resolve, Resolved, ResolvedVal},
};

use tor_error::{bad_api_usage, internal};
use tor_linkspec::{CircTarget, LinkSpec};
use tor_error::{bad_api_usage, internal, into_internal};
use tor_linkspec::{CircTarget, LinkSpec, OwnedChanTarget};

use futures::channel::{mpsc, oneshot};

use crate::circuit::sendme::StreamRecvWindow;
use futures::SinkExt;
use std::convert::TryFrom;
use std::net::IpAddr;
use std::sync::Arc;
use tor_cell::relaycell::StreamId;
@@ -211,8 +212,10 @@ impl ClientCirc {

        let (tx, rx) = oneshot::channel();

        let peer_id = OwnedChanTarget::from_chan_target(target);
        self.control
            .unbounded_send(CtrlMsg::ExtendNtor {
                peer_id,
                public_key: key,
                linkspecs,
                require_sendme_auth,
@@ -243,7 +246,9 @@ impl ClientCirc {
                "Can't begin a stream at the 0th hop"
            )));
        }
        let hop_num: HopNum = (num_hops - 1).into();
        let hop_num: HopNum = u8::try_from(num_hops - 1)
            .map_err(into_internal!("Couldn't convert path length to u8"))?
            .into();
        let (sender, receiver) = mpsc::channel(STREAM_READER_BUFFER);
        let (tx, rx) = oneshot::channel();
        let (msg_tx, msg_rx) = mpsc::channel(CIRCUIT_BUFFER_SIZE);
@@ -405,7 +410,7 @@ impl ClientCirc {
    }

    #[cfg(test)]
    pub fn n_hops(&self) -> u8 {
    pub fn n_hops(&self) -> usize {
        self.path.n_hops()
    }
}
+11 −9
Original line number Diff line number Diff line
//! Tracking for the path of a client circuit.

use std::sync::atomic::{AtomicU8, Ordering};
use std::sync::Mutex;
use tor_linkspec::OwnedChanTarget;

/// Helper struct that shares information
#[derive(Debug, Default)]
pub(super) struct Path {
    /// Number of hops on this circuit.
    /// Information about the relays on this circuit.
    ///
    /// This value is incremented after the circuit successfully completes extending to a new hop.
    n_hops: AtomicU8,
    /// We only store ChanTarget information here, because it doesn't matter
    /// which ntor key we actually used with each hop.
    hops: Mutex<Vec<OwnedChanTarget>>,
}

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

    /// Add 1 to the number of hops in this path.
    pub(super) fn inc_hops(&self) {
        self.n_hops.fetch_add(1, Ordering::SeqCst);
    /// Add a hop to this  this path.
    pub(super) fn push_hop(&self, target: OwnedChanTarget) {
        self.hops.lock().expect("poisoned lock").push(target);
    }
}
Loading