diff --git a/veilid-core/src/network_manager/mod.rs b/veilid-core/src/network_manager/mod.rs index 4939baf8..02387a9e 100644 --- a/veilid-core/src/network_manager/mod.rs +++ b/veilid-core/src/network_manager/mod.rs @@ -110,7 +110,7 @@ pub(crate) enum NodeContactMethod { } #[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)] struct NodeContactMethodCacheKey { - own_node_info_ts: Option, + own_node_info_ts: Timestamp, target_node_info_ts: Timestamp, target_node_ref_filter: Option, target_node_ref_sequencing: Sequencing, diff --git a/veilid-core/src/network_manager/send_data.rs b/veilid-core/src/network_manager/send_data.rs index 6a3f5720..f1a7345b 100644 --- a/veilid-core/src/network_manager/send_data.rs +++ b/veilid-core/src/network_manager/send_data.rs @@ -329,7 +329,7 @@ impl NetworkManager { // Node A is our own node // Use whatever node info we've calculated so far - let peer_a = routing_table.get_best_effort_own_peer_info(routing_domain); + let peer_a = routing_table.get_own_peer_info(routing_domain); // Node B is the target node let peer_b = match target_node_ref.make_peer_info(routing_domain) { @@ -466,15 +466,18 @@ impl NetworkManager { // Get target routing domain let Some(routing_domain) = target_nr.best_routing_domain() else { - return Ok(NetworkResult::no_connection_other("No routing domain for target")); + return Ok(NetworkResult::no_connection_other("No routing domain for target for reverse connect")); + }; + + // Ensure we have a valid network class so our peer info is useful + if !self.routing_table().has_valid_network_class(routing_domain){ + return Ok(NetworkResult::no_connection_other("Network class not yet valid for reverse connect")); }; // Get our peer info - let Some(peer_info) = self + let peer_info = self .routing_table() - .get_own_peer_info(routing_domain) else { - return Ok(NetworkResult::no_connection_other("Own peer info not available")); - }; + .get_own_peer_info(routing_domain); // Issue the signal let rpc = self.rpc_processor(); @@ -562,15 +565,18 @@ impl NetworkManager { // Get target routing domain let Some(routing_domain) = target_nr.best_routing_domain() else { - return Ok(NetworkResult::no_connection_other("No routing domain for target")); + return Ok(NetworkResult::no_connection_other("No routing domain for target for hole punch")); + }; + + // Ensure we have a valid network class so our peer info is useful + if !self.routing_table().has_valid_network_class(routing_domain){ + return Ok(NetworkResult::no_connection_other("Network class not yet valid for hole punch")); }; // Get our peer info - let Some(peer_info) = self + let peer_info = self .routing_table() - .get_own_peer_info(routing_domain) else { - return Ok(NetworkResult::no_connection_other("Own peer info not available")); - }; + .get_own_peer_info(routing_domain); // Get the udp direct dialinfo for the hole punch let hole_punch_did = target_nr diff --git a/veilid-core/src/routing_table/find_peers.rs b/veilid-core/src/routing_table/find_peers.rs index 52787196..c60b3537 100644 --- a/veilid-core/src/routing_table/find_peers.rs +++ b/veilid-core/src/routing_table/find_peers.rs @@ -7,12 +7,15 @@ impl RoutingTable { key: TypedKey, capabilities: &[Capability], ) -> NetworkResult> { - let Some(own_peer_info) = self.get_own_peer_info(RoutingDomain::PublicInternet) else { + if !self.has_valid_network_class(RoutingDomain::PublicInternet) { // Our own node info is not yet available, drop this request. - return NetworkResult::service_unavailable("Not finding closest peers because our peer info is not yet available"); - }; + return NetworkResult::service_unavailable( + "Not finding closest peers because our network class is still invalid", + ); + } // find N nodes closest to the target node in our routing table + let own_peer_info = self.get_own_peer_info(RoutingDomain::PublicInternet); let filter = Box::new( move |rti: &RoutingTableInner, opt_entry: Option>| { // Ensure only things that are valid/signed in the PublicInternet domain are returned @@ -28,14 +31,10 @@ impl RoutingTable { Some(entry) => entry.with(rti, |_rti, e| { e.has_capabilities(RoutingDomain::PublicInternet, capabilities) }), - None => rti - .get_own_peer_info(RoutingDomain::PublicInternet) - .map(|pi| { - pi.signed_node_info() - .node_info() - .has_capabilities(capabilities) - }) - .unwrap_or(false), + None => own_peer_info + .signed_node_info() + .node_info() + .has_capabilities(capabilities), } }, ) as RoutingTableEntryFilter; @@ -46,6 +45,7 @@ impl RoutingTable { c.network.dht.max_find_node_count as usize }; + let own_peer_info = self.get_own_peer_info(RoutingDomain::PublicInternet); let closest_nodes = self.find_closest_nodes( node_count, key, diff --git a/veilid-core/src/routing_table/mod.rs b/veilid-core/src/routing_table/mod.rs index dc541449..4981aa60 100644 --- a/veilid-core/src/routing_table/mod.rs +++ b/veilid-core/src/routing_table/mod.rs @@ -549,27 +549,18 @@ impl RoutingTable { } /// Return a copy of our node's peerinfo - pub fn get_own_peer_info(&self, routing_domain: RoutingDomain) -> Option { + pub fn get_own_peer_info(&self, routing_domain: RoutingDomain) -> PeerInfo { self.inner.read().get_own_peer_info(routing_domain) } - /// Return the best effort copy of our node's peerinfo - /// This may be invalid and should not be passed to other nodes, - /// but may be used for contact method calculation - pub fn get_best_effort_own_peer_info(&self, routing_domain: RoutingDomain) -> PeerInfo { - self.inner - .read() - .get_best_effort_own_peer_info(routing_domain) - } - /// If we have a valid network class in this routing domain, then our 'NodeInfo' is valid /// If this is true, we can get our final peer info, otherwise we only have a 'best effort' peer info - pub fn has_valid_own_node_info(&self, routing_domain: RoutingDomain) -> bool { - self.inner.read().has_valid_own_node_info(routing_domain) + pub fn has_valid_network_class(&self, routing_domain: RoutingDomain) -> bool { + self.inner.read().has_valid_network_class(routing_domain) } /// Return our current node info timestamp - pub fn get_own_node_info_ts(&self, routing_domain: RoutingDomain) -> Option { + pub fn get_own_node_info_ts(&self, routing_domain: RoutingDomain) -> Timestamp { self.inner.read().get_own_node_info_ts(routing_domain) } diff --git a/veilid-core/src/routing_table/node_ref.rs b/veilid-core/src/routing_table/node_ref.rs index 6580e171..6a72bf20 100644 --- a/veilid-core/src/routing_table/node_ref.rs +++ b/veilid-core/src/routing_table/node_ref.rs @@ -309,7 +309,7 @@ pub trait NodeRefBase: Sized { } fn clear_last_connection(&self, connection_descriptor: ConnectionDescriptor) { - self.operate_mut(|rti, e| { + self.operate_mut(|_rti, e| { e.clear_last_connection(connection_descriptor); }) } diff --git a/veilid-core/src/routing_table/route_spec_store/route_spec_store.rs b/veilid-core/src/routing_table/route_spec_store/route_spec_store.rs index ef1f4762..fb85fcc9 100644 --- a/veilid-core/src/routing_table/route_spec_store/route_spec_store.rs +++ b/veilid-core/src/routing_table/route_spec_store/route_spec_store.rs @@ -186,12 +186,16 @@ impl RouteSpecStore { if hop_count > self.unlocked_inner.max_route_hop_count { bail!("Not allocating route longer than max route hop count"); } - - let Some(our_peer_info) = rti.get_own_peer_info(RoutingDomain::PublicInternet) else { - log_rtab!(debug "unable to allocate route until we have our own peer info"); + + // Ensure we have a valid network class so our peer info is useful + if !rti.has_valid_network_class(RoutingDomain::PublicInternet) { + log_rtab!(debug "unable to allocate route until we have a valid PublicInternet network class"); return Ok(None); }; + // Get our peer info + let our_peer_info = rti.get_own_peer_info(RoutingDomain::PublicInternet); + // Get relay node if we have one let opt_own_relay_nr = rti.relay_node(RoutingDomain::PublicInternet).map(|nr| nr.locked(rti)); @@ -1176,20 +1180,20 @@ impl RouteSpecStore { bail!("crypto not supported for route"); }; + // Ensure our network class is valid before attempting to assemble any routes + if !rti.has_valid_network_class(RoutingDomain::PublicInternet) { + bail!("can't make private routes until our node info is valid"); + } + // Make innermost route hop to our own node let mut route_hop = RouteHop { node: if optimized { - if !rti.has_valid_own_node_info(RoutingDomain::PublicInternet) { - bail!("can't make private routes until our node info is valid"); - } let Some(node_id) = routing_table.node_ids().get(rsd.crypto_kind) else { bail!("missing node id for crypto kind"); }; RouteNode::NodeId(node_id.value) } else { - let Some(pi) = rti.get_own_peer_info(RoutingDomain::PublicInternet) else { - bail!("can't make private routes until our node info is valid"); - }; + let pi = rti.get_own_peer_info(RoutingDomain::PublicInternet); RouteNode::PeerInfo(pi) }, next_hop: None, @@ -1377,15 +1381,7 @@ impl RouteSpecStore { let cur_ts = get_aligned_timestamp(); if let Some(rpri) = inner.cache.peek_remote_private_route_mut(cur_ts, &rrid) { - let our_node_info_ts = { - let rti = &*self.unlocked_inner.routing_table.inner.read(); - let Some(ts) = rti.get_own_node_info_ts(RoutingDomain::PublicInternet) else { - // Node info is invalid, skip this - return false; - }; - ts - }; - + let our_node_info_ts = self.unlocked_inner.routing_table.get_own_node_info_ts(RoutingDomain::PublicInternet); return rpri.has_seen_our_node_info_ts(our_node_info_ts); } } @@ -1404,14 +1400,7 @@ impl RouteSpecStore { key: &PublicKey, cur_ts: Timestamp, ) -> EyreResult<()> { - let our_node_info_ts = { - let rti = &*self.unlocked_inner.routing_table.inner.read(); - let Some(ts) = rti.get_own_node_info_ts(RoutingDomain::PublicInternet) else { - // Node info is invalid, skipping this - return Ok(()); - }; - ts - }; + let our_node_info_ts = self.unlocked_inner.routing_table.get_own_node_info_ts(RoutingDomain::PublicInternet); let inner = &mut *self.inner.lock(); diff --git a/veilid-core/src/routing_table/routing_domains.rs b/veilid-core/src/routing_table/routing_domains.rs index 6c3273dc..3d37737b 100644 --- a/veilid-core/src/routing_table/routing_domains.rs +++ b/veilid-core/src/routing_table/routing_domains.rs @@ -113,7 +113,7 @@ impl RoutingDomainDetailCommon { self.clear_cache(); } - pub fn has_valid_own_node_info(&self) -> bool { + pub fn has_valid_network_class(&self) -> bool { self.network_class.unwrap_or(NetworkClass::Invalid) != NetworkClass::Invalid } diff --git a/veilid-core/src/routing_table/routing_table_inner.rs b/veilid-core/src/routing_table/routing_table_inner.rs index c60d9e67..c8fc5fda 100644 --- a/veilid-core/src/routing_table/routing_table_inner.rs +++ b/veilid-core/src/routing_table/routing_table_inner.rs @@ -180,10 +180,6 @@ impl RoutingTableInner { routing_domain: RoutingDomain, node_info: &NodeInfo, ) -> bool { - // Should not be passing around nodeinfo with an invalid network class - if matches!(node_info.network_class(), NetworkClass::Invalid) { - return false; - } // Ensure all of the dial info works in this routing domain for did in node_info.dial_info_detail_list() { if !self.ensure_dial_info_is_valid(routing_domain, &did.dial_info) { @@ -204,6 +200,14 @@ impl RoutingTableInner { } // Ensure the relay is also valid in this routing domain if it is provided if let Some(relay_ni) = signed_node_info.relay_info() { + // If there is a relay, the relay should have inbound capable network class and the node's network class should be valid + if relay_ni.network_class() != NetworkClass::InboundCapable { + return false; + } + if signed_node_info.node_info().network_class() == NetworkClass::Invalid { + return false; + } + if !self.node_info_is_valid_in_routing_domain(routing_domain, relay_ni) { return false; } @@ -238,42 +242,23 @@ impl RoutingTableInner { }); } - /// Return if our node info is valid yet, which is only true if we have a valid network class - pub fn has_valid_own_node_info(&self, routing_domain: RoutingDomain) -> bool { - self.with_routing_domain(routing_domain, |rdd| rdd.common().has_valid_own_node_info()) + /// Return if this routing domain has a valid network class + pub fn has_valid_network_class(&self, routing_domain: RoutingDomain) -> bool { + self.with_routing_domain(routing_domain, |rdd| rdd.common().has_valid_network_class()) } /// Return a copy of our node's peerinfo - pub fn get_own_peer_info(&self, routing_domain: RoutingDomain) -> Option { - self.with_routing_domain(routing_domain, |rdd| { - if !rdd.common().has_valid_own_node_info() { - None - } else { - Some(rdd.common().with_peer_info(self, |pi| pi.clone())) - } - }) - } - - /// Return the best effort copy of our node's peerinfo - /// This may be invalid and should not be passed to other nodes, - /// but may be used for contact method calculation - pub fn get_best_effort_own_peer_info(&self, routing_domain: RoutingDomain) -> PeerInfo { + pub fn get_own_peer_info(&self, routing_domain: RoutingDomain) -> PeerInfo { self.with_routing_domain(routing_domain, |rdd| { rdd.common().with_peer_info(self, |pi| pi.clone()) }) } /// Return our current node info timestamp - pub fn get_own_node_info_ts(&self, routing_domain: RoutingDomain) -> Option { + pub fn get_own_node_info_ts(&self, routing_domain: RoutingDomain) -> Timestamp { self.with_routing_domain(routing_domain, |rdd| { - if !rdd.common().has_valid_own_node_info() { - None - } else { - Some( - rdd.common() - .with_peer_info(self, |pi| pi.signed_node_info().timestamp()), - ) - } + rdd.common() + .with_peer_info(self, |pi| pi.signed_node_info().timestamp()) }) } @@ -557,19 +542,17 @@ impl RoutingTableInner { let mut node_refs = Vec::::with_capacity(self.bucket_entry_count()); self.with_entries(cur_ts, BucketEntryState::Unreliable, |rti, entry| { if entry.with_inner(|e| { - // If this isn't in the routing domain we are checking, don't include it + // If this entry isn't in the routing domain we are checking, don't include it if !e.exists_in_routing_domain(rti, routing_domain) { return false; } - // If we need a ping then do it + // If this entry needs need a ping then do it if e.needs_ping(cur_ts) { return true; } - // If we need a ping because this node hasn't seen our latest node info, then do it - if let Some(own_node_info_ts) = own_node_info_ts { - if !e.has_seen_our_node_info_ts(routing_domain, own_node_info_ts) { - return true; - } + // If this entry needs a ping because this node hasn't seen our latest node info, then do it + if !e.has_seen_our_node_info_ts(routing_domain, own_node_info_ts) { + return true; } false }) { diff --git a/veilid-core/src/routing_table/tasks/private_route_management.rs b/veilid-core/src/routing_table/tasks/private_route_management.rs index 7e522377..b8ddba51 100644 --- a/veilid-core/src/routing_table/tasks/private_route_management.rs +++ b/veilid-core/src/routing_table/tasks/private_route_management.rs @@ -169,24 +169,11 @@ impl RoutingTable { _last_ts: Timestamp, cur_ts: Timestamp, ) -> EyreResult<()> { - // Get our node's current node info and network class and do the right thing - let network_class = self - .get_network_class(RoutingDomain::PublicInternet) - .unwrap_or(NetworkClass::Invalid); - // If we don't know our network class then don't do this yet - if network_class == NetworkClass::Invalid { + if !self.has_valid_network_class(RoutingDomain::PublicInternet) { return Ok(()); } - // If we don't have our own peer info then don't do this yet - if self - .get_own_peer_info(RoutingDomain::PublicInternet) - .is_none() - { - return Ok(()); - }; - // Test locally allocated routes first // This may remove dead routes let routes_needing_testing = self.get_allocated_routes_to_test(cur_ts); diff --git a/veilid-core/src/routing_table/tasks/relay_management.rs b/veilid-core/src/routing_table/tasks/relay_management.rs index 71515132..37ddab6c 100644 --- a/veilid-core/src/routing_table/tasks/relay_management.rs +++ b/veilid-core/src/routing_table/tasks/relay_management.rs @@ -10,9 +10,10 @@ impl RoutingTable { cur_ts: Timestamp, ) -> EyreResult<()> { // Get our node's current node info and network class and do the right thing - let Some(own_peer_info) = self.get_own_peer_info(RoutingDomain::PublicInternet) else { + if !self.has_valid_network_class(RoutingDomain::PublicInternet) { return Ok(()); - }; + } + let own_peer_info = self.get_own_peer_info(RoutingDomain::PublicInternet); let own_node_info = own_peer_info.signed_node_info().node_info(); let network_class = own_node_info.network_class(); let relay_node_filter = self.make_public_internet_relay_node_filter(); diff --git a/veilid-core/src/rpc_processor/destination.rs b/veilid-core/src/rpc_processor/destination.rs index 9e82758a..041d41a5 100644 --- a/veilid-core/src/rpc_processor/destination.rs +++ b/veilid-core/src/rpc_processor/destination.rs @@ -31,9 +31,19 @@ pub enum Destination { impl Destination { pub fn target(&self) -> Option { match self { - Destination::Direct { target, safety_selection: _ } => Some(target.clone()), - Destination::Relay { relay:_, target, safety_selection: _ } => Some(target.clone()), - Destination::PrivateRoute { private_route:_, safety_selection:_ } => None, + Destination::Direct { + target, + safety_selection: _, + } => Some(target.clone()), + Destination::Relay { + relay: _, + target, + safety_selection: _, + } => Some(target.clone()), + Destination::PrivateRoute { + private_route: _, + safety_selection: _, + } => None, } } pub fn direct(target: NodeRef) -> Self { @@ -217,7 +227,6 @@ impl RPCProcessor { private_route, safety_selection, } => { - let Some(avoid_node_id) = private_route.first_hop_node_id() else { return Err(RPCError::internal("destination private route must have first hop")); }; @@ -227,21 +236,21 @@ impl RPCProcessor { match safety_selection { SafetySelection::Unsafe(_) => { // Sent to a private route with no safety route, use a stub safety route for the response + if !routing_table.has_valid_network_class(RoutingDomain::PublicInternet) { + return Ok(NetworkResult::no_connection_other( + "Own node info must be valid to use private route", + )); + } // Determine if we can use optimized nodeinfo - let route_node = if rss - .has_remote_private_route_seen_our_node_info(&private_route.public_key.value) - { - if !routing_table.has_valid_own_node_info(RoutingDomain::PublicInternet) { - return Ok(NetworkResult::no_connection_other("Own node info must be valid to use private route")); - } - RouteNode::NodeId(routing_table.node_id(crypto_kind).value) - } else { - let Some(own_peer_info) = - routing_table.get_own_peer_info(RoutingDomain::PublicInternet) else { - return Ok(NetworkResult::no_connection_other("Own peer info must be valid to use private route")); - }; - RouteNode::PeerInfo(own_peer_info) + let route_node = if rss.has_remote_private_route_seen_our_node_info( + &private_route.public_key.value, + ) { + RouteNode::NodeId(routing_table.node_id(crypto_kind).value) + } else { + let own_peer_info = + routing_table.get_own_peer_info(RoutingDomain::PublicInternet); + RouteNode::PeerInfo(own_peer_info) }; Ok(NetworkResult::value(RespondTo::PrivateRoute( @@ -250,10 +259,12 @@ impl RPCProcessor { } SafetySelection::Safe(safety_spec) => { // Sent to a private route via a safety route, respond to private route - + // Check for loopback test - let opt_private_route_id = rss.get_route_id_for_key(&private_route.public_key.value); - let pr_key = if opt_private_route_id.is_some() && safety_spec.preferred_route == opt_private_route_id + let opt_private_route_id = + rss.get_route_id_for_key(&private_route.public_key.value); + let pr_key = if opt_private_route_id.is_some() + && safety_spec.preferred_route == opt_private_route_id { // Private route is also safety route during loopback test private_route.public_key.value @@ -308,7 +319,10 @@ impl RPCProcessor { }; // Reply directly to the request's source - let sender_node_id = TypedKey::new(detail.envelope.get_crypto_kind(), detail.envelope.get_sender_id()); + let sender_node_id = TypedKey::new( + detail.envelope.get_crypto_kind(), + detail.envelope.get_sender_id(), + ); // This may be a different node's reference than the 'sender' in the case of a relay let peer_noderef = detail.peer_noderef.clone(); @@ -320,18 +334,21 @@ impl RPCProcessor { } else { // Look up the sender node, we should have added it via senderNodeInfo before getting here. let res = match self.routing_table.lookup_node_ref(sender_node_id) { - Ok(v) => v, - Err(e) => return NetworkResult::invalid_message( - format!("failed to look up node info for respond to: {}", e) - )}; + Ok(v) => v, + Err(e) => { + return NetworkResult::invalid_message(format!( + "failed to look up node info for respond to: {}", + e + )) + } + }; if let Some(sender_noderef) = res { - NetworkResult::value(Destination::relay(peer_noderef, sender_noderef)) + NetworkResult::value(Destination::relay(peer_noderef, sender_noderef)) } else { return NetworkResult::invalid_message( "not responding to sender that has no node info", ); } - } } RespondTo::PrivateRoute(pr) => { diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index 422a495b..96de25d7 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -888,10 +888,9 @@ impl RPCProcessor { // Get the target's node info timestamp let target_node_info_ts = target.node_info_ts(routing_domain); - // Don't return our node info if it's not valid yet - let Some(own_peer_info) = routing_table.get_own_peer_info(routing_domain) else { - return SenderPeerInfo::new_no_peer_info(target_node_info_ts); - }; + // Return whatever peer info we have even if the network class is not yet valid + // That away we overwrite any prior existing valid-network-class nodeinfo in the remote routing table + let own_peer_info = routing_table.get_own_peer_info(routing_domain); // Get our node info timestamp let our_node_info_ts = own_peer_info.signed_node_info().timestamp(); @@ -1475,6 +1474,12 @@ impl RPCProcessor { let mut opt_sender_nr: Option = None; if let Some(sender_peer_info) = operation.sender_peer_info() { // Ensure the sender peer info is for the actual sender specified in the envelope + if !sender_peer_info.node_ids().contains(&sender_node_id) { + // Attempted to update peer info for the wrong node id + return Ok(NetworkResult::invalid_message( + "attempt to update peer info for non-sender node id", + )); + } // Sender PeerInfo was specified, update our routing table with it if !self.verify_node_info( diff --git a/veilid-core/src/rpc_processor/rpc_app_call.rs b/veilid-core/src/rpc_processor/rpc_app_call.rs index 4b54452a..984e8d9b 100644 --- a/veilid-core/src/rpc_processor/rpc_app_call.rs +++ b/veilid-core/src/rpc_processor/rpc_app_call.rs @@ -55,18 +55,16 @@ impl RPCProcessor { ) -> Result, RPCError> { // Ignore if disabled let routing_table = self.routing_table(); + + let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); + if !opi + .signed_node_info() + .node_info() + .has_capability(CAP_APPMESSAGE) { - if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) { - if !opi - .signed_node_info() - .node_info() - .has_capability(CAP_APPMESSAGE) - { - return Ok(NetworkResult::service_unavailable( - "app call is not available", - )); - } - } + return Ok(NetworkResult::service_unavailable( + "app call is not available", + )); } // Get the question diff --git a/veilid-core/src/rpc_processor/rpc_app_message.rs b/veilid-core/src/rpc_processor/rpc_app_message.rs index 56800099..d8798ff1 100644 --- a/veilid-core/src/rpc_processor/rpc_app_message.rs +++ b/veilid-core/src/rpc_processor/rpc_app_message.rs @@ -26,18 +26,15 @@ impl RPCProcessor { ) -> Result, RPCError> { // Ignore if disabled let routing_table = self.routing_table(); + let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); + if !opi + .signed_node_info() + .node_info() + .has_capability(CAP_APPMESSAGE) { - if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) { - if !opi - .signed_node_info() - .node_info() - .has_capability(CAP_APPMESSAGE) - { - return Ok(NetworkResult::service_unavailable( - "app message is not available", - )); - } - } + return Ok(NetworkResult::service_unavailable( + "app message is not available", + )); } // Get the statement diff --git a/veilid-core/src/rpc_processor/rpc_get_value.rs b/veilid-core/src/rpc_processor/rpc_get_value.rs index 085bb0bc..3895d9cb 100644 --- a/veilid-core/src/rpc_processor/rpc_get_value.rs +++ b/veilid-core/src/rpc_processor/rpc_get_value.rs @@ -175,15 +175,17 @@ impl RPCProcessor { } // Ignore if disabled let routing_table = self.routing_table(); + let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); + if !opi + .signed_node_info() + .node_info() + .has_capability(CAP_DHT) { - if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) { - if !opi.signed_node_info().node_info().has_capability(CAP_DHT) { - return Ok(NetworkResult::service_unavailable( - "dht is not available", - )); - } - } + return Ok(NetworkResult::service_unavailable( + "dht is not available", + )); } + // Get the question let kind = msg.operation.kind().clone(); let get_value_q = match kind { diff --git a/veilid-core/src/rpc_processor/rpc_route.rs b/veilid-core/src/rpc_processor/rpc_route.rs index 0c1b14be..aa055de1 100644 --- a/veilid-core/src/rpc_processor/rpc_route.rs +++ b/veilid-core/src/rpc_processor/rpc_route.rs @@ -367,14 +367,21 @@ impl RPCProcessor { ) -> Result, RPCError> { // Ignore if disabled let routing_table = self.routing_table(); + if !routing_table.has_valid_network_class(msg.header.routing_domain()) { + return Ok(NetworkResult::service_unavailable( + "can't route without valid network class", + )); + } + + let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); + if !opi + .signed_node_info() + .node_info() + .has_capability(CAP_ROUTE) { - if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) { - if !opi.signed_node_info().node_info().has_capability(CAP_ROUTE) { - return Ok(NetworkResult::service_unavailable( - "route is not available", - )); - } - } + return Ok(NetworkResult::service_unavailable( + "route is not available", + )); } // Get header detail, must be direct and not inside a route itself diff --git a/veilid-core/src/rpc_processor/rpc_set_value.rs b/veilid-core/src/rpc_processor/rpc_set_value.rs index 9973b5ef..82f9afc4 100644 --- a/veilid-core/src/rpc_processor/rpc_set_value.rs +++ b/veilid-core/src/rpc_processor/rpc_set_value.rs @@ -177,15 +177,17 @@ impl RPCProcessor { ) -> Result, RPCError> { // Ignore if disabled let routing_table = self.routing_table(); + let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); + if !opi + .signed_node_info() + .node_info() + .has_capability(CAP_DHT) { - if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) { - if !opi.signed_node_info().node_info().has_capability(CAP_DHT) { - return Ok(NetworkResult::service_unavailable( - "dht is not available", - )); - } - } + return Ok(NetworkResult::service_unavailable( + "dht is not available", + )); } + // Ensure this never came over a private route, safety route is okay though match &msg.header.detail { RPCMessageHeaderDetail::Direct(_) | RPCMessageHeaderDetail::SafetyRouted(_) => {} diff --git a/veilid-core/src/rpc_processor/rpc_signal.rs b/veilid-core/src/rpc_processor/rpc_signal.rs index 4b325d73..b24a4efe 100644 --- a/veilid-core/src/rpc_processor/rpc_signal.rs +++ b/veilid-core/src/rpc_processor/rpc_signal.rs @@ -39,15 +39,15 @@ impl RPCProcessor { ) -> Result, RPCError> { // Ignore if disabled let routing_table = self.routing_table(); + let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); + if !opi + .signed_node_info() + .node_info() + .has_capability(CAP_SIGNAL) { - if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) { - let ni = opi.signed_node_info().node_info(); - if !ni.has_capability(CAP_SIGNAL) { - return Ok(NetworkResult::service_unavailable( - "signal is not available", - )); - } - } + return Ok(NetworkResult::service_unavailable( + "signal is not available", + )); } // Can't allow anything other than direct packets here, as handling reverse connections diff --git a/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs b/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs index 37eaef96..ab6812e4 100644 --- a/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs +++ b/veilid-core/src/rpc_processor/rpc_validate_dial_info.rs @@ -58,6 +58,14 @@ impl RPCProcessor { &self, msg: RPCMessage, ) -> Result, RPCError> { + let routing_table = self.routing_table(); + if !routing_table.has_valid_network_class(msg.header.routing_domain()) { + return Ok(NetworkResult::service_unavailable( + "can't validate dial info without valid network class", + )); + } + let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); + let detail = match msg.header.detail { RPCMessageHeaderDetail::Direct(detail) => detail, RPCMessageHeaderDetail::SafetyRouted(_) | RPCMessageHeaderDetail::PrivateRouted(_) => { @@ -68,16 +76,16 @@ impl RPCProcessor { }; // Ignore if disabled - let routing_table = self.routing_table(); + let ni = opi.signed_node_info().node_info(); + if !opi + .signed_node_info() + .node_info() + .has_capability(CAP_VALIDATE_DIAL_INFO) + || !ni.is_fully_direct_inbound() { - if let Some(opi) = routing_table.get_own_peer_info(detail.routing_domain) { - let ni = opi.signed_node_info().node_info(); - if !ni.has_capability(CAP_VALIDATE_DIAL_INFO) || !ni.is_fully_direct_inbound() { - return Ok(NetworkResult::service_unavailable( - "validate dial info is not available", - )); - } - } + return Ok(NetworkResult::service_unavailable( + "validate dial info is not available", + )); } // Get the statement diff --git a/veilid-core/src/rpc_processor/rpc_value_changed.rs b/veilid-core/src/rpc_processor/rpc_value_changed.rs index fd5b1910..0776ce31 100644 --- a/veilid-core/src/rpc_processor/rpc_value_changed.rs +++ b/veilid-core/src/rpc_processor/rpc_value_changed.rs @@ -8,12 +8,9 @@ impl RPCProcessor { ) -> Result, RPCError> { // Ignore if disabled let routing_table = self.routing_table(); - { - if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) { - if !opi.signed_node_info().node_info().has_capability(CAP_DHT) { - return Ok(NetworkResult::service_unavailable("dht is not available")); - } - } + let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); + if !opi.signed_node_info().node_info().has_capability(CAP_DHT) { + return Ok(NetworkResult::service_unavailable("dht is not available")); } Err(RPCError::unimplemented("process_value_changed")) } diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index e6f28474..42095087 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -8,12 +8,9 @@ impl RPCProcessor { ) -> Result, RPCError> { // Ignore if disabled let routing_table = self.routing_table(); - { - if let Some(opi) = routing_table.get_own_peer_info(msg.header.routing_domain()) { - if !opi.signed_node_info().node_info().has_capability(CAP_DHT) { - return Ok(NetworkResult::service_unavailable("dht is not available")); - } - } + let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); + if !opi.signed_node_info().node_info().has_capability(CAP_DHT) { + return Ok(NetworkResult::service_unavailable("dht is not available")); } Err(RPCError::unimplemented("process_watch_value_q")) }