1
//! Module exposing tunnel-related types shared by clients and relays.
2

            
3
use std::sync::atomic::{AtomicU64, Ordering};
4

            
5
use crate::circuit::UniqId;
6
use derive_more::Display;
7

            
8
/// The unique identifier of a tunnel.
9
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Display)]
10
#[display("Tunnel {}", _0)]
11
#[cfg_attr(feature = "relay", visibility::make(pub))]
12
#[allow(unreachable_pub)] // TODO(#1447): use in ChanMgr's ChannelProvider impl
13
pub(crate) struct TunnelId(u64);
14

            
15
impl TunnelId {
16
    /// Create a new TunnelId.
17
    ///
18
    /// # Panics
19
    ///
20
    /// Panics if we have exhausted the possible space of u64 IDs.
21
390
    pub(crate) fn next() -> TunnelId {
22
        /// The next unique tunnel ID.
23
        static NEXT_TUNNEL_ID: AtomicU64 = AtomicU64::new(1);
24
390
        let id = NEXT_TUNNEL_ID.fetch_add(1, Ordering::Relaxed);
25
390
        assert!(id != 0, "Exhausted Tunnel ID space?!");
26
390
        TunnelId(id)
27
390
    }
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_uniq_id, tunnel_id)]
37
pub(crate) struct TunnelScopedCircId {
38
    /// The identifier of the owning tunnel
39
    tunnel_id: TunnelId,
40
    /// The process-unique identifier of the circuit
41
    circ_uniq_id: UniqId,
42
}
43

            
44
impl TunnelScopedCircId {
45
    /// Create a new [`TunnelScopedCircId`] from the specified identifiers.
46
494
    pub(crate) fn new(tunnel_id: TunnelId, circ_uniq_id: UniqId) -> Self {
47
494
        Self {
48
494
            tunnel_id,
49
494
            circ_uniq_id,
50
494
        }
51
494
    }
52

            
53
    /// Return the [`UniqId`].
54
18688
    pub(crate) fn unique_id(&self) -> UniqId {
55
18688
        self.circ_uniq_id
56
18688
    }
57
}