diff --git a/veilid-core/src/crypto/mod.rs b/veilid-core/src/crypto/mod.rs index 89175795..1b025ee4 100644 --- a/veilid-core/src/crypto/mod.rs +++ b/veilid-core/src/crypto/mod.rs @@ -29,6 +29,9 @@ pub type CryptoSystemVersion = Arc; /// Crypto kinds in order of preference, best cryptosystem is the first one, worst is the last one pub const VALID_CRYPTO_KINDS: [CryptoKind; 1] = [CRYPTO_KIND_VLD0]; +/// Number of cryptosystem signatures to keep on structures if many are present beyond the ones we consider valid +pub const MAX_CRYPTO_KINDS: usize = 3; +/// Return the best cryptosystem kind we support pub fn best_crypto_kind() -> CryptoKind { VALID_CRYPTO_KINDS[0] } @@ -87,6 +90,10 @@ impl Crypto { out } + pub fn config(&self) -> VeilidConfig { + self.unlocked_inner.config.clone() + } + pub async fn init(&self) -> EyreResult<()> { trace!("Crypto::init"); let table_store = self.unlocked_inner.table_store.clone(); diff --git a/veilid-core/src/network_manager/mod.rs b/veilid-core/src/network_manager/mod.rs index a1afd869..8562d16e 100644 --- a/veilid-core/src/network_manager/mod.rs +++ b/veilid-core/src/network_manager/mod.rs @@ -525,7 +525,7 @@ impl NetworkManager { let node_id = routing_table.node_id(vcrypto.kind()); let node_id_secret = routing_table.node_id_secret(vcrypto.kind()); - let receipt = Receipt::try_new(MAX_ENVELOPE_VERSION, node_id.kind, nonce, node_id.key, extra_data)?; + let receipt = Receipt::try_new(best_envelope_version(), node_id.kind, nonce, node_id.key, extra_data)?; let out = receipt .to_signed_data(self.crypto(), &node_id_secret) .wrap_err("failed to generate signed receipt")?; @@ -554,7 +554,7 @@ impl NetworkManager { let node_id = routing_table.node_id(vcrypto.kind()); let node_id_secret = routing_table.node_id_secret(vcrypto.kind()); - let receipt = Receipt::try_new(MAX_ENVELOPE_VERSION, node_id.kind, nonce, node_id.key, extra_data)?; + let receipt = Receipt::try_new(best_envelope_version(), node_id.kind, nonce, node_id.key, extra_data)?; let out = receipt .to_signed_data(self.crypto(), &node_id_secret) .wrap_err("failed to generate signed receipt")?; @@ -790,9 +790,9 @@ impl NetworkManager { log_net!("sending envelope to {:?}", node_ref); } - // Get node's min/max envelope version and see if we can send to it + // Get node's envelope versions and see if we can send to it // and if so, get the max version we can use - let Some(envelope_version) = node_ref.envelope_support().iter().rev().find(|x| VALID_ENVELOPE_VERSIONS.contains(x)) else { + let Some(envelope_version) = node_ref.envelope_support().into_iter().rev().find(|x| VALID_ENVELOPE_VERSIONS.contains(x)) else { bail!( "can't talk to this node {} because we dont support its envelope versions", node_ref diff --git a/veilid-core/src/routing_table/debug.rs b/veilid-core/src/routing_table/debug.rs index f4721ec3..355ede7e 100644 --- a/veilid-core/src/routing_table/debug.rs +++ b/veilid-core/src/routing_table/debug.rs @@ -1,5 +1,5 @@ use super::*; -use routing_table::tasks::bootstrap::BOOTSTRAP_TXT_VERSION; +use routing_table::tasks::bootstrap::BOOTSTRAP_TXT_VERSION_0; impl RoutingTable { pub(crate) fn debug_info_nodeinfo(&self) -> String { @@ -66,7 +66,7 @@ impl RoutingTable { out += "TXT Record:\n"; out += &format!( "{}|{}|{}|{}|", - BOOTSTRAP_TXT_VERSION, + BOOTSTRAP_TXT_VERSION_0, valid_envelope_versions, node_ids, some_hostname.unwrap() @@ -115,42 +115,45 @@ impl RoutingTable { let mut out = String::new(); - let blen = inner.buckets.len(); let mut b = 0; let mut cnt = 0; - out += &format!("Entries: {}\n", inner.bucket_entry_count); - while b < blen { - let filtered_entries: Vec<(&TypedKey, &Arc)> = inner.buckets[b] - .entries() - .filter(|e| { - let state = e.1.with(inner, |_rti, e| e.state(cur_ts)); - state >= min_state - }) - .collect(); - if !filtered_entries.is_empty() { - out += &format!(" Bucket #{}:\n", b); - for e in filtered_entries { - let state = e.1.with(inner, |_rti, e| e.state(cur_ts)); - out += &format!( - " {} [{}]\n", - e.0.encode(), - match state { - BucketEntryState::Reliable => "R", - BucketEntryState::Unreliable => "U", - BucketEntryState::Dead => "D", - } - ); + out += &format!("Entries: {}\n", inner.bucket_entry_count()); - cnt += 1; + for ck in &VALID_CRYPTO_KINDS { + let blen = inner.buckets[ck].len(); + while b < blen { + let filtered_entries: Vec<(&PublicKey, &Arc)> = inner.buckets[ck][b] + .entries() + .filter(|e| { + let state = e.1.with(inner, |_rti, e| e.state(cur_ts)); + state >= min_state + }) + .collect(); + if !filtered_entries.is_empty() { + out += &format!("{} Bucket #{}:\n", ck, b); + for e in filtered_entries { + let state = e.1.with(inner, |_rti, e| e.state(cur_ts)); + out += &format!( + " {} [{}]\n", + e.0.encode(), + match state { + BucketEntryState::Reliable => "R", + BucketEntryState::Unreliable => "U", + BucketEntryState::Dead => "D", + } + ); + + cnt += 1; + if cnt >= limit { + break; + } + } if cnt >= limit { break; } } - if cnt >= limit { - break; - } + b += 1; } - b += 1; } out @@ -175,26 +178,28 @@ impl RoutingTable { let mut out = String::new(); const COLS: usize = 16; - let rows = inner.buckets.len() / COLS; - let mut r = 0; - let mut b = 0; out += "Buckets:\n"; - while r < rows { - let mut c = 0; - out += format!(" {:>3}: ", b).as_str(); - while c < COLS { - let mut cnt = 0; - for e in inner.buckets[b].entries() { - if e.1.with(inner, |_rti, e| e.state(cur_ts) >= min_state) { - cnt += 1; + for ck in &VALID_CRYPTO_KINDS { + let rows = inner.buckets[ck].len() / COLS; + let mut r = 0; + let mut b = 0; + while r < rows { + let mut c = 0; + out += format!(" {:>3}: ", b).as_str(); + while c < COLS { + let mut cnt = 0; + for e in inner.buckets[ck][b].entries() { + if e.1.with(inner, |_rti, e| e.state(cur_ts) >= min_state) { + cnt += 1; + } } + out += format!("{:>3} ", cnt).as_str(); + b += 1; + c += 1; } - out += format!("{:>3} ", cnt).as_str(); - b += 1; - c += 1; + out += "\n"; + r += 1; } - out += "\n"; - r += 1; } out diff --git a/veilid-core/src/routing_table/mod.rs b/veilid-core/src/routing_table/mod.rs index af953db0..435346a0 100644 --- a/veilid-core/src/routing_table/mod.rs +++ b/veilid-core/src/routing_table/mod.rs @@ -200,27 +200,6 @@ impl RoutingTable { this } - ///////////////////////////////////// - /// Unlocked passthrough - pub fn network_manager(&self) -> NetworkManager { - self.unlocked_inner.network_manager() - } - pub fn crypto(&self) -> Crypto { - self.unlocked_inner.crypto() - } - pub fn rpc_processor(&self) -> RPCProcessor { - self.unlocked_inner.rpc_processor() - } - pub fn node_id(&self, kind: CryptoKind) -> TypedKey { - self.unlocked_inner.node_id(kind) - } - pub fn node_id_secret(&self, kind: CryptoKind) -> SecretKey { - self.unlocked_inner.node_id_secret(kind) - } - pub fn matches_own_node_id(&self, node_ids: &[TypedKey]) -> bool { - self.unlocked_inner.matches_own_node_id(node_ids) - } - ///////////////////////////////////// /// Initialization @@ -1092,3 +1071,11 @@ impl RoutingTable { best_inbound_relay.map(|e| NodeRef::new(self.clone(), e, None)) } } + +impl core::ops::Deref for RoutingTable { + type Target = RoutingTableUnlockedInner; + + fn deref(&self) -> &Self::Target { + &self.unlocked_inner + } +} diff --git a/veilid-core/src/routing_table/tasks/peer_minimum_refresh.rs b/veilid-core/src/routing_table/tasks/peer_minimum_refresh.rs index 077eff18..e6f028d6 100644 --- a/veilid-core/src/routing_table/tasks/peer_minimum_refresh.rs +++ b/veilid-core/src/routing_table/tasks/peer_minimum_refresh.rs @@ -24,8 +24,8 @@ impl RoutingTable { let noderefs = routing_table.find_fastest_nodes( min_peer_count, VecDeque::new(), - |_rti, k: TypedKey, v: Option>| { - NodeRef::new(routing_table.clone(), k, v.unwrap().clone(), None) + |_rti, entry: Option>| { + NodeRef::new(routing_table.clone(), entry.unwrap().clone(), None) }, ); diff --git a/veilid-core/src/routing_table/tasks/relay_management.rs b/veilid-core/src/routing_table/tasks/relay_management.rs index bd02bf87..ca80b81f 100644 --- a/veilid-core/src/routing_table/tasks/relay_management.rs +++ b/veilid-core/src/routing_table/tasks/relay_management.rs @@ -53,8 +53,7 @@ impl RoutingTable { // Register new outbound relay if let Some(nr) = self.register_node_with_peer_info( RoutingDomain::PublicInternet, - outbound_relay_peerinfo.node_id.key, - outbound_relay_peerinfo.signed_node_info, + outbound_relay_peerinfo, false, ) { info!("Outbound relay node selected: {}", nr); diff --git a/veilid-core/src/routing_table/tasks/rolling_transfers.rs b/veilid-core/src/routing_table/tasks/rolling_transfers.rs index 436381ec..6ea87bdb 100644 --- a/veilid-core/src/routing_table/tasks/rolling_transfers.rs +++ b/veilid-core/src/routing_table/tasks/rolling_transfers.rs @@ -21,13 +21,9 @@ impl RoutingTable { ); // Roll all bucket entry transfers - let entries: Vec> = inner - .buckets - .iter() - .flat_map(|b| b.entries().map(|(_k, v)| v.clone())) - .collect(); - for v in entries { - v.with_mut(inner, |_rti, e| e.roll_transfers(last_ts, cur_ts)); + let all_entries: Vec> = inner.all_entries.iter().collect(); + for entry in all_entries { + entry.with_mut(inner, |_rti, e| e.roll_transfers(last_ts, cur_ts)); } } diff --git a/veilid-core/src/rpc_processor/coders/signed_direct_node_info.rs b/veilid-core/src/rpc_processor/coders/signed_direct_node_info.rs index cda84813..dfbb8a12 100644 --- a/veilid-core/src/rpc_processor/coders/signed_direct_node_info.rs +++ b/veilid-core/src/rpc_processor/coders/signed_direct_node_info.rs @@ -43,14 +43,19 @@ pub fn decode_signed_direct_node_info( .map_err(RPCError::protocol)?; let node_info = decode_node_info(&ni_reader)?; + let timestamp = reader.reborrow().get_timestamp().into(); + let sigs_reader = reader .reborrow() .get_signatures() .map_err(RPCError::protocol)?; - let timestamp = reader.reborrow().get_timestamp().into(); + let sig_count = sigs_reader.len() as usize; + if sig_count > MAX_CRYPTO_KINDS { + return Err(RPCError::protocol("too many signatures")); + } - let mut typed_signatures = Vec::with_capacity(sigs_reader.len() as usize); + let mut typed_signatures = Vec::with_capacity(sig_count); for sig_reader in sigs_reader { let typed_signature = decode_typed_signature(&sig_reader)?; typed_signatures.push(typed_signature); diff --git a/veilid-core/src/rpc_processor/coders/signed_relayed_node_info.rs b/veilid-core/src/rpc_processor/coders/signed_relayed_node_info.rs index 02808c66..b14163e0 100644 --- a/veilid-core/src/rpc_processor/coders/signed_relayed_node_info.rs +++ b/veilid-core/src/rpc_processor/coders/signed_relayed_node_info.rs @@ -67,7 +67,11 @@ pub fn decode_signed_relayed_node_info( .reborrow() .get_relay_ids() .map_err(RPCError::protocol)?; - let mut relay_ids = TypedKeySet::with_capacity(rids_reader.len() as usize); + let rid_count = rids_reader.len() as usize; + if rid_count > MAX_CRYPTO_KINDS { + return Err(RPCError::protocol("too many relay ids")); + } + let mut relay_ids = TypedKeySet::with_capacity(rid_count); for rid_reader in rids_reader { let relay_id = decode_typed_key(&rid_reader)?; relay_ids.add(relay_id); @@ -79,14 +83,19 @@ pub fn decode_signed_relayed_node_info( .map_err(RPCError::protocol)?; let relay_info = decode_signed_direct_node_info(&ri_reader, crypto, &relay_ids)?; + let timestamp = reader.reborrow().get_timestamp().into(); + let sigs_reader = reader .reborrow() .get_signatures() .map_err(RPCError::protocol)?; - let timestamp = reader.reborrow().get_timestamp().into(); + let sig_count = sigs_reader.len() as usize; + if sig_count > MAX_CRYPTO_KINDS { + return Err(RPCError::protocol("too many signatures")); + } - let mut typed_signatures = Vec::with_capacity(sigs_reader.len() as usize); + let mut typed_signatures = Vec::with_capacity(sig_count); for sig_reader in sigs_reader { let typed_signature = decode_typed_signature(&sig_reader)?; typed_signatures.push(typed_signature); diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index 4496aed9..1a2a2a63 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -35,7 +35,7 @@ fn get_route_id(rss: RouteSpecStore) -> impl Fn(&str) -> Option { if text.is_empty() { return None; } - match TypedKey::try_decode(text).ok() { + match TypedKey::from_str(text).ok() { Some(key) => { let routes = rss.list_allocated_routes(|k, _| Some(*k)); if routes.contains(&key) { @@ -150,9 +150,9 @@ fn get_destination(routing_table: RoutingTable) -> impl FnOnce(&str) -> Option impl FnOnce(&str) -> Option impl FnOnce(&str) -> Option Option { usize::from_str(text).ok() } -fn get_dht_key(text: &str) -> Option { - TypedKey::try_decode(text).ok() +fn get_typed_key(text: &str) -> Option { + TypedKey::from_str(text).ok() } fn get_node_ref(routing_table: RoutingTable) -> impl FnOnce(&str) -> Option { @@ -198,7 +198,7 @@ fn get_node_ref(routing_table: RoutingTable) -> impl FnOnce(&str) -> Option Result { let args: Vec = args.split_whitespace().map(|s| s.to_owned()).collect(); - let node_id = get_debug_argument_at(&args, 0, "debug_entry", "node_id", get_dht_key)?; + let node_id = get_debug_argument_at(&args, 0, "debug_entry", "node_id", get_typed_key)?; // Dump routing table entry let routing_table = self.network_manager()?.routing_table(); @@ -623,7 +623,7 @@ impl VeilidAPI { let routing_table = netman.routing_table(); let rss = routing_table.route_spec_store(); - let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_dht_key)?; + let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_typed_key)?; // Release route let out = match rss.release_route(&route_id) { @@ -639,7 +639,7 @@ impl VeilidAPI { let routing_table = netman.routing_table(); let rss = routing_table.route_spec_store(); - let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_dht_key)?; + let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_typed_key)?; let full = { if args.len() > 2 { let full_val = get_debug_argument_at(&args, 2, "debug_route", "full", get_string)? @@ -685,7 +685,7 @@ impl VeilidAPI { let routing_table = netman.routing_table(); let rss = routing_table.route_spec_store(); - let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_dht_key)?; + let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_typed_key)?; // Unpublish route let out = if let Err(e) = rss.mark_route_published(&route_id, false) { @@ -701,7 +701,7 @@ impl VeilidAPI { let routing_table = netman.routing_table(); let rss = routing_table.route_spec_store(); - let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_dht_key)?; + let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_typed_key)?; match rss.debug_route(&route_id) { Some(s) => Ok(s), @@ -757,7 +757,7 @@ impl VeilidAPI { let routing_table = netman.routing_table(); let rss = routing_table.route_spec_store(); - let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_dht_key)?; + let route_id = get_debug_argument_at(&args, 1, "debug_route", "route_id", get_typed_key)?; let success = rss .test_route(&route_id) diff --git a/veilid-core/src/veilid_api/types.rs b/veilid-core/src/veilid_api/types.rs index e95c0905..c248ee39 100644 --- a/veilid-core/src/veilid_api/types.rs +++ b/veilid-core/src/veilid_api/types.rs @@ -279,8 +279,8 @@ pub struct VeilidStateNetwork { )] #[archive_attr(repr(C), derive(CheckBytes))] pub struct VeilidStateRoute { - pub dead_routes: Vec, - pub dead_remote_routes: Vec, + pub dead_routes: Vec, + pub dead_remote_routes: Vec, } #[derive( @@ -513,7 +513,7 @@ impl SafetySelection { #[archive_attr(repr(C), derive(CheckBytes))] pub struct SafetySpec { /// preferred safety route if it still exists - pub preferred_route: Option, + pub preferred_route: Option, /// must be greater than 0 pub hop_count: usize, /// prefer reliability over speed