Skip to main content

rust_p2p_core/route/
mod.rs

1//! Routing logic for selecting optimal paths between peers.
2//!
3//! This module manages routing decisions, tracking metrics like RTT (Round Trip Time)
4//! and hop count to select the best available path for communication.
5//!
6//! # Examples
7//!
8//! ```rust
9//! use rust_p2p_core::route::{RouteKey, ConnectProtocol};
10//!
11//! // RouteKey identifies a specific connection path
12//! // It combines protocol (UDP/TCP) and socket address
13//! ```
14
15use std::fmt;
16use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
17
18pub mod route_table;
19
20pub const DEFAULT_RTT: u32 = 9999;
21
22use crate::tunnel::udp::UDPIndex;
23
24/// Socket index identifying a specific socket in a socket manager.
25#[non_exhaustive]
26#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
27pub enum Index {
28    Udp(UDPIndex),
29    Tcp(usize),
30}
31impl Index {
32    pub fn index(&self) -> usize {
33        match self {
34            Index::Udp(index) => index.index(),
35            Index::Tcp(index) => *index,
36        }
37    }
38    pub fn protocol(&self) -> ConnectProtocol {
39        match self {
40            Index::Tcp(_) => ConnectProtocol::TCP,
41            Index::Udp(_) => ConnectProtocol::UDP,
42        }
43    }
44}
45
46/// Identifies a specific route to a peer.
47///
48/// `RouteKey` uniquely identifies a connection path by combining the
49/// socket index and remote address.
50///
51/// # Examples
52///
53/// ```rust
54/// use rust_p2p_core::route::{RouteKey, ConnectProtocol};
55///
56/// # fn example(route: RouteKey) {
57/// // Check the protocol
58/// if route.protocol() == ConnectProtocol::UDP {
59///     println!("UDP route to {}", route.addr());
60/// }
61/// # }
62/// ```
63#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
64pub struct RouteKey {
65    index: Index,
66    addr: SocketAddr,
67}
68impl Default for RouteKey {
69    fn default() -> Self {
70        Self {
71            index: Index::Tcp(0),
72            addr: SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0)),
73        }
74    }
75}
76impl RouteKey {
77    pub(crate) const fn new(index: Index, addr: SocketAddr) -> Self {
78        Self { index, addr }
79    }
80
81    /// Returns the connection protocol (UDP or TCP).
82    #[inline]
83    pub fn protocol(&self) -> ConnectProtocol {
84        self.index.protocol()
85    }
86
87    /// Returns the socket index.
88    #[inline]
89    pub fn index(&self) -> Index {
90        self.index
91    }
92
93    /// Returns the socket index as usize.
94    #[inline]
95    pub fn index_usize(&self) -> usize {
96        self.index.index()
97    }
98
99    /// Returns the remote socket address.
100    #[inline]
101    pub fn addr(&self) -> SocketAddr {
102        self.addr
103    }
104}
105
106/// Sorting key for comparing route quality.
107#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug)]
108pub struct RouteSortKey {
109    metric: u8,
110    rtt: u32,
111}
112
113/// Connection protocol type.
114///
115/// # Examples
116///
117/// ```rust
118/// use rust_p2p_core::route::ConnectProtocol;
119///
120/// let proto = ConnectProtocol::UDP;
121/// assert!(proto.is_udp());
122/// assert!(!proto.is_tcp());
123/// ```
124#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
125pub enum ConnectProtocol {
126    UDP,
127    TCP,
128}
129impl ConnectProtocol {
130    /// Returns true if this is TCP.
131    #[inline]
132    pub fn is_tcp(&self) -> bool {
133        self == &ConnectProtocol::TCP
134    }
135
136    /// Returns true if this is UDP.
137    #[inline]
138    pub fn is_udp(&self) -> bool {
139        self == &ConnectProtocol::UDP
140    }
141}
142
143impl fmt::Display for RouteKey {
144    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
145        let protocol = self.protocol();
146        write!(f, "{}://{}", protocol, self.addr())
147    }
148}
149
150impl fmt::Display for ConnectProtocol {
151    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152        match self {
153            ConnectProtocol::UDP => write!(f, "udp"),
154            ConnectProtocol::TCP => write!(f, "tcp"),
155        }
156    }
157}