fix crash

This commit is contained in:
Christien Rioux 2023-08-05 11:33:27 -04:00
parent ef327fb963
commit 8e1ed1e3f1
8 changed files with 54 additions and 11 deletions

View File

@ -325,4 +325,11 @@ impl Crypto {
}, },
) )
} }
pub(crate) fn validate_crypto_kind(kind: CryptoKind) -> VeilidAPIResult<()> {
if !VALID_CRYPTO_KINDS.contains(&kind) {
apibail_generic!("invalid crypto kind");
}
Ok(())
}
} }

View File

@ -13,6 +13,9 @@ impl RoutingTable {
"Not finding closest peers because our network class is still invalid", "Not finding closest peers because our network class is still invalid",
); );
} }
if Crypto::validate_crypto_kind(key.kind).is_err() {
return NetworkResult::invalid_message("invalid crypto kind");
}
// find N nodes closest to the target node in our routing table // find N nodes closest to the target node in our routing table
let own_peer_info = self.get_own_peer_info(RoutingDomain::PublicInternet); let own_peer_info = self.get_own_peer_info(RoutingDomain::PublicInternet);
@ -46,7 +49,7 @@ impl RoutingTable {
}; };
let own_peer_info = self.get_own_peer_info(RoutingDomain::PublicInternet); let own_peer_info = self.get_own_peer_info(RoutingDomain::PublicInternet);
let closest_nodes = self.find_closest_nodes( let closest_nodes = match self.find_closest_nodes(
node_count, node_count,
key, key,
filters, filters,
@ -54,7 +57,13 @@ impl RoutingTable {
|rti, entry| { |rti, entry| {
rti.transform_to_peer_info(RoutingDomain::PublicInternet, &own_peer_info, entry) rti.transform_to_peer_info(RoutingDomain::PublicInternet, &own_peer_info, entry)
}, },
); ) {
Ok(v) => v,
Err(e) => {
error!("failed to find closest nodes for key {}: {}", key, e);
return NetworkResult::invalid_message("failed to find closest nodes for key");
}
};
NetworkResult::value(closest_nodes) NetworkResult::value(closest_nodes)
} }
@ -117,7 +126,7 @@ impl RoutingTable {
}; };
// //
let closest_nodes = self.find_closest_nodes( let closest_nodes = match self.find_closest_nodes(
node_count, node_count,
key, key,
filters, filters,
@ -127,7 +136,13 @@ impl RoutingTable {
e.make_peer_info(RoutingDomain::PublicInternet).unwrap() e.make_peer_info(RoutingDomain::PublicInternet).unwrap()
}) })
}, },
); ) {
Ok(v) => v,
Err(e) => {
error!("failed to find closest nodes for key {}: {}", key, e);
return NetworkResult::invalid_message("failed to find closest nodes for key");
}
};
// Validate peers returned are, in fact, closer to the key than the node we sent this to // Validate peers returned are, in fact, closer to the key than the node we sent this to
// This same test is used on the other side so we vet things here // This same test is used on the other side so we vet things here

View File

@ -1012,7 +1012,7 @@ impl RoutingTable {
node_id: TypedKey, node_id: TypedKey,
filters: VecDeque<RoutingTableEntryFilter>, filters: VecDeque<RoutingTableEntryFilter>,
transform: T, transform: T,
) -> Vec<O> ) -> VeilidAPIResult<Vec<O>>
where where
T: for<'r> FnMut(&'r RoutingTableInner, Option<Arc<BucketEntry>>) -> O + Send, T: for<'r> FnMut(&'r RoutingTableInner, Option<Arc<BucketEntry>>) -> O + Send,
{ {

View File

@ -1162,7 +1162,7 @@ impl RoutingTableInner {
node_id: TypedKey, node_id: TypedKey,
mut filters: VecDeque<RoutingTableEntryFilter>, mut filters: VecDeque<RoutingTableEntryFilter>,
transform: T, transform: T,
) -> Vec<O> ) -> VeilidAPIResult<Vec<O>>
where where
T: for<'r> FnMut(&'r RoutingTableInner, Option<Arc<BucketEntry>>) -> O, T: for<'r> FnMut(&'r RoutingTableInner, Option<Arc<BucketEntry>>) -> O,
{ {
@ -1170,7 +1170,9 @@ impl RoutingTableInner {
// Get the crypto kind // Get the crypto kind
let crypto_kind = node_id.kind; let crypto_kind = node_id.kind;
let vcrypto = self.unlocked_inner.crypto().get(crypto_kind).unwrap(); let Some(vcrypto) = self.unlocked_inner.crypto().get(crypto_kind) else {
apibail_generic!("invalid crypto kind");
};
// Filter to ensure entries support the crypto kind in use // Filter to ensure entries support the crypto kind in use
let filter = Box::new( let filter = Box::new(
@ -1236,7 +1238,7 @@ impl RoutingTableInner {
let out = let out =
self.find_peers_with_sort_and_filter(node_count, cur_ts, filters, sort, transform); self.find_peers_with_sort_and_filter(node_count, cur_ts, filters, sort, transform);
log_rtab!(">> find_closest_nodes: node count = {}", out.len()); log_rtab!(">> find_closest_nodes: node count = {}", out.len());
out Ok(out)
} }
pub fn sort_and_clean_closest_noderefs( pub fn sort_and_clean_closest_noderefs(

View File

@ -208,7 +208,7 @@ where
} }
} }
fn init_closest_nodes(self: Arc<Self>) { fn init_closest_nodes(self: Arc<Self>) -> Result<(), RPCError> {
// Get the 'node_count' closest nodes to the key out of our routing table // Get the 'node_count' closest nodes to the key out of our routing table
let closest_nodes = { let closest_nodes = {
let routing_table = self.routing_table.clone(); let routing_table = self.routing_table.clone();
@ -247,11 +247,14 @@ where
NodeRef::new(routing_table.clone(), v.unwrap().clone(), None) NodeRef::new(routing_table.clone(), v.unwrap().clone(), None)
}; };
routing_table.find_closest_nodes(self.node_count, self.node_id, filters, transform) routing_table
.find_closest_nodes(self.node_count, self.node_id, filters, transform)
.map_err(RPCError::invalid_format)?
}; };
let mut ctx = self.context.lock(); let mut ctx = self.context.lock();
ctx.closest_nodes = closest_nodes; ctx.closest_nodes = closest_nodes;
Ok(())
} }
pub async fn run(self: Arc<Self>) -> TimeoutOr<Result<Option<R>, RPCError>> { pub async fn run(self: Arc<Self>) -> TimeoutOr<Result<Option<R>, RPCError>> {
@ -264,7 +267,9 @@ where
}; };
// Initialize closest nodes list // Initialize closest nodes list
self.clone().init_closest_nodes(); if let Err(e) = self.clone().init_closest_nodes() {
return TimeoutOr::value(Err(e));
}
// Do a quick check to see if we're already done // Do a quick check to see if we're already done
if self.clone().evaluate_done() { if self.clone().evaluate_done() {

View File

@ -188,6 +188,10 @@ impl VeilidAPI {
stability: Stability, stability: Stability,
sequencing: Sequencing, sequencing: Sequencing,
) -> VeilidAPIResult<(RouteId, Vec<u8>)> { ) -> VeilidAPIResult<(RouteId, Vec<u8>)> {
for kind in crypto_kinds {
Crypto::validate_crypto_kind(*kind)?;
}
let default_route_hop_count: usize = { let default_route_hop_count: usize = {
let config = self.config()?; let config = self.config()?;
let c = config.get(); let c = config.get();

View File

@ -199,6 +199,7 @@ impl RoutingContext {
kind: Option<CryptoKind>, kind: Option<CryptoKind>,
) -> VeilidAPIResult<DHTRecordDescriptor> { ) -> VeilidAPIResult<DHTRecordDescriptor> {
let kind = kind.unwrap_or(best_crypto_kind()); let kind = kind.unwrap_or(best_crypto_kind());
Crypto::validate_crypto_kind(kind)?;
let storage_manager = self.api.storage_manager()?; let storage_manager = self.api.storage_manager()?;
storage_manager storage_manager
.create_record(kind, schema, self.unlocked_inner.safety_selection) .create_record(kind, schema, self.unlocked_inner.safety_selection)
@ -213,6 +214,7 @@ impl RoutingContext {
key: TypedKey, key: TypedKey,
writer: Option<KeyPair>, writer: Option<KeyPair>,
) -> VeilidAPIResult<DHTRecordDescriptor> { ) -> VeilidAPIResult<DHTRecordDescriptor> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?; let storage_manager = self.api.storage_manager()?;
storage_manager storage_manager
.open_record(key, writer, self.unlocked_inner.safety_selection) .open_record(key, writer, self.unlocked_inner.safety_selection)
@ -222,6 +224,7 @@ impl RoutingContext {
/// Closes a DHT record at a specific key that was opened with create_dht_record or open_dht_record. /// Closes a DHT record at a specific key that was opened with create_dht_record or open_dht_record.
/// Closing a record allows you to re-open it with a different routing context /// Closing a record allows you to re-open it with a different routing context
pub async fn close_dht_record(&self, key: TypedKey) -> VeilidAPIResult<()> { pub async fn close_dht_record(&self, key: TypedKey) -> VeilidAPIResult<()> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?; let storage_manager = self.api.storage_manager()?;
storage_manager.close_record(key).await storage_manager.close_record(key).await
} }
@ -230,6 +233,7 @@ impl RoutingContext {
/// Deleting a record does not delete it from the network, but will remove the storage of the record /// Deleting a record does not delete it from the network, but will remove the storage of the record
/// locally, and will prevent its value from being refreshed on the network by this node. /// locally, and will prevent its value from being refreshed on the network by this node.
pub async fn delete_dht_record(&self, key: TypedKey) -> VeilidAPIResult<()> { pub async fn delete_dht_record(&self, key: TypedKey) -> VeilidAPIResult<()> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?; let storage_manager = self.api.storage_manager()?;
storage_manager.delete_record(key).await storage_manager.delete_record(key).await
} }
@ -244,6 +248,7 @@ impl RoutingContext {
subkey: ValueSubkey, subkey: ValueSubkey,
force_refresh: bool, force_refresh: bool,
) -> VeilidAPIResult<Option<ValueData>> { ) -> VeilidAPIResult<Option<ValueData>> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?; let storage_manager = self.api.storage_manager()?;
storage_manager.get_value(key, subkey, force_refresh).await storage_manager.get_value(key, subkey, force_refresh).await
} }
@ -257,6 +262,7 @@ impl RoutingContext {
subkey: ValueSubkey, subkey: ValueSubkey,
data: Vec<u8>, data: Vec<u8>,
) -> VeilidAPIResult<Option<ValueData>> { ) -> VeilidAPIResult<Option<ValueData>> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?; let storage_manager = self.api.storage_manager()?;
storage_manager.set_value(key, subkey, data).await storage_manager.set_value(key, subkey, data).await
} }
@ -273,6 +279,7 @@ impl RoutingContext {
expiration: Timestamp, expiration: Timestamp,
count: u32, count: u32,
) -> VeilidAPIResult<Timestamp> { ) -> VeilidAPIResult<Timestamp> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?; let storage_manager = self.api.storage_manager()?;
storage_manager storage_manager
.watch_values(key, subkeys, expiration, count) .watch_values(key, subkeys, expiration, count)
@ -286,6 +293,7 @@ impl RoutingContext {
key: TypedKey, key: TypedKey,
subkeys: ValueSubkeyRangeSet, subkeys: ValueSubkeyRangeSet,
) -> VeilidAPIResult<bool> { ) -> VeilidAPIResult<bool> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?; let storage_manager = self.api.storage_manager()?;
storage_manager.cancel_watch_values(key, subkeys).await storage_manager.cancel_watch_values(key, subkeys).await
} }

View File

@ -23,6 +23,7 @@ String cryptoKindToString(CryptoKind kind) =>
const CryptoKind bestCryptoKind = cryptoKindVLD0; const CryptoKind bestCryptoKind = cryptoKindVLD0;
Uint8List cryptoKindToBytes(CryptoKind kind) { Uint8List cryptoKindToBytes(CryptoKind kind) {
assert(kind == cryptoKindVLD0, 'xxx');
final b = Uint8List(4); final b = Uint8List(4);
ByteData.sublistView(b).setUint32(0, kind); ByteData.sublistView(b).setUint32(0, kind);
return b; return b;
@ -34,6 +35,7 @@ CryptoKind cryptoKindFromString(String s) {
} }
final kind = final kind =
ByteData.sublistView(Uint8List.fromList(s.codeUnits)).getUint32(0); ByteData.sublistView(Uint8List.fromList(s.codeUnits)).getUint32(0);
assert(kind == cryptoKindVLD0, 'xxx');
return kind; return kind;
} }