tor_proto/
tunnel.rs

1//! Module exposing tunnel-related types shared by clients and relays.
2
3use std::sync::atomic::{AtomicU64, Ordering};
4
5use crate::circuit::UniqId;
6use derive_more::Display;
7
8/// The unique identifier of a tunnel.
9#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Display)]
10#[display("{}", _0)]
11#[cfg_attr(feature = "relay", visibility::make(pub))]
12#[allow(unreachable_pub)] // TODO(#1447): use in ChanMgr's ChannelProvider impl
13pub(crate) struct TunnelId(u64);
14
15impl TunnelId {
16    /// Create a new TunnelId.
17    ///
18    /// # Panics
19    ///
20    /// Panics if we have exhausted the possible space of u64 IDs.
21    pub(crate) fn next() -> TunnelId {
22        /// The next unique tunnel ID.
23        static NEXT_TUNNEL_ID: AtomicU64 = AtomicU64::new(1);
24        let id = NEXT_TUNNEL_ID.fetch_add(1, Ordering::Relaxed);
25        assert!(id != 0, "Exhausted Tunnel ID space?!");
26        TunnelId(id)
27    }
28}
29
30/// The identifier of a circuit [`UniqId`] within a tunnel.
31///
32/// This type is only needed for logging purposes: a circuit's [`UniqId`] is
33/// process-unique, but in the logs it's often useful to display the
34/// owning tunnel's ID alongside the circuit identifier.
35#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Display)]
36#[display("Circ {}.{}", tunnel_id, circ_id.display_chan_circ())]
37pub(crate) struct TunnelScopedCircId {
38    /// The identifier of the owning tunnel
39    tunnel_id: TunnelId,
40    /// The process-unique identifier of the circuit
41    circ_id: UniqId,
42}
43
44impl TunnelScopedCircId {
45    /// Create a new [`TunnelScopedCircId`] from the specified identifiers.
46    pub(crate) fn new(tunnel_id: TunnelId, circ_id: UniqId) -> Self {
47        Self { tunnel_id, circ_id }
48    }
49
50    /// Return the [`UniqId`].
51    pub(crate) fn unique_id(&self) -> UniqId {
52        self.circ_id
53    }
54}