protect route hops + refactor

This commit is contained in:
Christien Rioux 2023-10-25 22:32:06 -04:00
parent c70c260bb8
commit b964ddb6eb
50 changed files with 286 additions and 701 deletions

View file

@ -29,18 +29,18 @@ const NEVER_REACHED_PING_COUNT: u32 = 3;
// Do not change order here, it will mess up other sorts
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum BucketEntryState {
pub(crate) enum BucketEntryState {
Dead,
Unreliable,
Reliable,
}
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct LastConnectionKey(ProtocolType, AddressType);
pub(crate) struct LastConnectionKey(ProtocolType, AddressType);
/// Bucket entry information specific to the LocalNetwork RoutingDomain
#[derive(Debug, Serialize, Deserialize)]
pub struct BucketEntryPublicInternet {
pub(crate) struct BucketEntryPublicInternet {
/// The PublicInternet node info
signed_node_info: Option<Box<SignedNodeInfo>>,
/// The last node info timestamp of ours that this entry has seen
@ -51,7 +51,7 @@ pub struct BucketEntryPublicInternet {
/// Bucket entry information specific to the LocalNetwork RoutingDomain
#[derive(Debug, Serialize, Deserialize)]
pub struct BucketEntryLocalNetwork {
pub(crate) struct BucketEntryLocalNetwork {
/// The LocalNetwork node info
signed_node_info: Option<Box<SignedNodeInfo>>,
/// The last node info timestamp of ours that this entry has seen
@ -62,7 +62,7 @@ pub struct BucketEntryLocalNetwork {
/// The data associated with each bucket entry
#[derive(Debug, Serialize, Deserialize)]
pub struct BucketEntryInner {
pub(crate) struct BucketEntryInner {
/// The node ids matching this bucket entry, with the cryptography versions supported by this node as the 'kind' field
validated_node_ids: TypedKeyGroup,
/// The node ids claimed by the remote node that use cryptography versions we do not support
@ -828,7 +828,7 @@ impl BucketEntryInner {
}
#[derive(Debug)]
pub struct BucketEntry {
pub(crate) struct BucketEntry {
pub(super) ref_count: AtomicU32,
inner: RwLock<BucketEntryInner>,
}

View file

@ -57,8 +57,8 @@ const CACHE_VALIDITY_KEY: &[u8] = b"cache_validity_key";
// Critical sections
const LOCK_TAG_TICK: &str = "TICK";
pub type LowLevelProtocolPorts = BTreeSet<(LowLevelProtocolType, AddressType, u16)>;
pub type ProtocolToPortMapping = BTreeMap<(ProtocolType, AddressType), (LowLevelProtocolType, u16)>;
type LowLevelProtocolPorts = BTreeSet<(LowLevelProtocolType, AddressType, u16)>;
type ProtocolToPortMapping = BTreeMap<(ProtocolType, AddressType), (LowLevelProtocolType, u16)>;
#[derive(Clone, Debug)]
pub struct LowLevelPortInfo {
pub low_level_protocol_ports: LowLevelProtocolPorts,
@ -66,11 +66,12 @@ pub struct LowLevelPortInfo {
}
pub type RoutingTableEntryFilter<'t> =
Box<dyn FnMut(&RoutingTableInner, Option<Arc<BucketEntry>>) -> bool + Send + 't>;
pub type SerializedBuckets = Vec<Vec<u8>>;
pub type SerializedBucketMap = BTreeMap<CryptoKind, SerializedBuckets>;
type SerializedBuckets = Vec<Vec<u8>>;
type SerializedBucketMap = BTreeMap<CryptoKind, SerializedBuckets>;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct RoutingTableHealth {
pub(crate) struct RoutingTableHealth {
/// Number of reliable (long-term responsive) entries in the routing table
pub reliable_entry_count: usize,
/// Number of unreliable (occasionally unresponsive) entries in the routing table
@ -87,7 +88,12 @@ pub struct RoutingTableHealth {
pub type BucketIndex = (CryptoKind, usize);
pub struct RoutingTableUnlockedInner {
#[derive(Debug, Clone, Copy)]
pub(crate) struct RecentPeersEntry {
pub last_connection: ConnectionDescriptor,
}
pub(crate) struct RoutingTableUnlockedInner {
// Accessors
config: VeilidConfig,
network_manager: NetworkManager,
@ -192,7 +198,7 @@ impl RoutingTableUnlockedInner {
}
#[derive(Clone)]
pub struct RoutingTable {
pub(crate) struct RoutingTable {
inner: Arc<RwLock<RoutingTableInner>>,
unlocked_inner: Arc<RoutingTableUnlockedInner>,
}
@ -788,7 +794,7 @@ impl RoutingTable {
/// Only one protocol per low level protocol/port combination is required
/// For example, if WS/WSS and TCP protocols are on the same low-level TCP port, only TCP keepalives will be required
/// and we do not need to do WS/WSS keepalive as well. If they are on different ports, then we will need WS/WSS keepalives too.
pub fn get_low_level_port_info(&self) -> LowLevelPortInfo {
fn get_low_level_port_info(&self) -> LowLevelPortInfo {
let mut low_level_protocol_ports =
BTreeSet::<(LowLevelProtocolType, AddressType, u16)>::new();
let mut protocol_to_port =

View file

@ -4,7 +4,7 @@ use alloc::fmt;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pub struct NodeRefBaseCommon {
pub(crate) struct NodeRefBaseCommon {
routing_table: RoutingTable,
entry: Arc<BucketEntry>,
filter: Option<NodeRefFilter>,
@ -15,7 +15,7 @@ pub struct NodeRefBaseCommon {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
pub trait NodeRefBase: Sized {
pub(crate) trait NodeRefBase: Sized {
// Common field access
fn common(&self) -> &NodeRefBaseCommon;
fn common_mut(&mut self) -> &mut NodeRefBaseCommon;
@ -314,6 +314,17 @@ pub trait NodeRefBase: Sized {
})
}
fn protect_last_connection(&self) -> bool {
if let Some(descriptor) = self.last_connection() {
self.routing_table()
.network_manager()
.connection_manager()
.protect_connection(descriptor)
} else {
false
}
}
fn has_any_dial_info(&self) -> bool {
self.operate(|_rti, e| {
for rtd in RoutingDomain::all() {
@ -369,7 +380,7 @@ pub trait NodeRefBase: Sized {
/// Reference to a routing table entry
/// Keeps entry in the routing table until all references are gone
pub struct NodeRef {
pub(crate) struct NodeRef {
common: NodeRefBaseCommon,
}
@ -496,7 +507,7 @@ impl Drop for NodeRef {
/// For internal use inside the RoutingTable module where you have
/// already locked a RoutingTableInner
/// Keeps entry in the routing table until all references are gone
pub struct NodeRefLocked<'a> {
pub(crate) struct NodeRefLocked<'a> {
inner: Mutex<&'a RoutingTableInner>,
nr: NodeRef,
}
@ -559,7 +570,7 @@ impl<'a> fmt::Debug for NodeRefLocked<'a> {
/// For internal use inside the RoutingTable module where you have
/// already locked a RoutingTableInner
/// Keeps entry in the routing table until all references are gone
pub struct NodeRefLockedMut<'a> {
pub(crate) struct NodeRefLockedMut<'a> {
inner: Mutex<&'a mut RoutingTableInner>,
nr: NodeRef,
}

View file

@ -5,7 +5,7 @@ use super::*;
/// An encrypted private/safety route hop
#[derive(Clone, Debug)]
pub struct RouteHopData {
pub(crate) struct RouteHopData {
/// The nonce used in the encryption ENC(Xn,DH(PKn,SKapr))
pub nonce: Nonce,
/// The encrypted blob
@ -14,7 +14,7 @@ pub struct RouteHopData {
/// How to find a route node
#[derive(Clone, Debug)]
pub enum RouteNode {
pub(crate) enum RouteNode {
/// Route node is optimized, no contact method information as this node id has been seen before
NodeId(PublicKey),
/// Route node with full contact method information to ensure the peer is reachable
@ -79,7 +79,7 @@ impl RouteNode {
/// An unencrypted private/safety route hop
#[derive(Clone, Debug)]
pub struct RouteHop {
pub(crate) struct RouteHop {
/// The location of the hop
pub node: RouteNode,
/// The encrypted blob to pass to the next hop as its data (None for stubs)
@ -93,7 +93,7 @@ impl RouteHop {
/// The kind of hops a private route can have
#[derive(Clone, Debug)]
pub enum PrivateRouteHops {
pub(crate) enum PrivateRouteHops {
/// The first hop of a private route, unencrypted, route_hops == total hop count
FirstHop(Box<RouteHop>),
/// Private route internal node. Has > 0 private route hops left but < total hop count
@ -113,7 +113,7 @@ impl PrivateRouteHops {
}
/// A private route for receiver privacy
#[derive(Clone, Debug)]
pub struct PrivateRoute {
pub(crate) struct PrivateRoute {
/// The public key used for the entire route
pub public_key: TypedKey,
pub hop_count: u8,
@ -225,7 +225,7 @@ impl fmt::Display for PrivateRoute {
}
#[derive(Clone, Debug)]
pub enum SafetyRouteHops {
pub(crate) enum SafetyRouteHops {
/// Has >= 1 safety route hops
Data(RouteHopData),
/// Has 0 safety route hops
@ -233,7 +233,7 @@ pub enum SafetyRouteHops {
}
#[derive(Clone, Debug)]
pub struct SafetyRoute {
pub(crate) struct SafetyRoute {
pub public_key: TypedKey,
pub hop_count: u8,
pub hops: SafetyRouteHops,

View file

@ -703,7 +703,7 @@ impl RouteSpecStore {
// Test with double-round trip ping to self
let rpc_processor = self.unlocked_inner.routing_table.rpc_processor();
let _res = match rpc_processor.rpc_call_status(dest).await? {
let _res = match rpc_processor.rpc_call_status(dest, true).await? {
NetworkResult::Value(v) => v,
_ => {
// Did not error, but did not come back, just return false
@ -746,7 +746,7 @@ impl RouteSpecStore {
// Test with double-round trip ping to self
let rpc_processor = self.unlocked_inner.routing_table.rpc_processor();
let _res = match rpc_processor.rpc_call_status(dest).await? {
let _res = match rpc_processor.rpc_call_status(dest, true).await? {
NetworkResult::Value(v) => v,
_ => {
// Did not error, but did not come back, just return false

View file

@ -6,13 +6,8 @@ pub const RECENT_PEERS_TABLE_SIZE: usize = 64;
pub type EntryCounts = BTreeMap<(RoutingDomain, CryptoKind), usize>;
//////////////////////////////////////////////////////////////////////////
#[derive(Debug, Clone, Copy)]
pub struct RecentPeersEntry {
pub last_connection: ConnectionDescriptor,
}
/// RoutingTable rwlock-internal data
pub struct RoutingTableInner {
pub(crate) struct RoutingTableInner {
/// Extra pointer to unlocked members to simplify access
pub(super) unlocked_inner: Arc<RoutingTableUnlockedInner>,
/// Routing table buckets that hold references to entries, per crypto kind

View file

@ -109,8 +109,10 @@ impl RoutingTable {
unord.push(
async move {
rpc.rpc_call_status(Destination::direct(relay_nr_filtered))
.await
let out = rpc
.rpc_call_status(Destination::direct(relay_nr_filtered), true)
.await;
out
}
.instrument(Span::current())
.boxed(),
@ -145,7 +147,7 @@ impl RoutingTable {
let rpc = rpc.clone();
log_rtab!("--> Validator ping to {:?}", nr);
unord.push(
async move { rpc.rpc_call_status(Destination::direct(nr)).await }
async move { rpc.rpc_call_status(Destination::direct(nr), false).await }
.instrument(Span::current())
.boxed(),
);
@ -173,7 +175,7 @@ impl RoutingTable {
// Just do a single ping with the best protocol for all the nodes
unord.push(
async move { rpc.rpc_call_status(Destination::direct(nr)).await }
async move { rpc.rpc_call_status(Destination::direct(nr), false).await }
.instrument(Span::current())
.boxed(),
);

View file

@ -19,7 +19,6 @@ pub(crate) fn mock_routing_table() -> routing_table::RoutingTable {
let network_manager = network_manager::NetworkManager::new(
veilid_config.clone(),
storage_manager,
protected_store.clone(),
table_store.clone(),
#[cfg(feature = "unstable-blockstore")]
block_store.clone(),