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",
);
}
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
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 closest_nodes = self.find_closest_nodes(
let closest_nodes = match self.find_closest_nodes(
node_count,
key,
filters,
@ -54,7 +57,13 @@ impl RoutingTable {
|rti, 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)
}
@ -117,7 +126,7 @@ impl RoutingTable {
};
//
let closest_nodes = self.find_closest_nodes(
let closest_nodes = match self.find_closest_nodes(
node_count,
key,
filters,
@ -127,7 +136,13 @@ impl RoutingTable {
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
// 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,
filters: VecDeque<RoutingTableEntryFilter>,
transform: T,
) -> Vec<O>
) -> VeilidAPIResult<Vec<O>>
where
T: for<'r> FnMut(&'r RoutingTableInner, Option<Arc<BucketEntry>>) -> O + Send,
{

View File

@ -1162,7 +1162,7 @@ impl RoutingTableInner {
node_id: TypedKey,
mut filters: VecDeque<RoutingTableEntryFilter>,
transform: T,
) -> Vec<O>
) -> VeilidAPIResult<Vec<O>>
where
T: for<'r> FnMut(&'r RoutingTableInner, Option<Arc<BucketEntry>>) -> O,
{
@ -1170,7 +1170,9 @@ impl RoutingTableInner {
// Get the crypto 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
let filter = Box::new(
@ -1236,7 +1238,7 @@ impl RoutingTableInner {
let out =
self.find_peers_with_sort_and_filter(node_count, cur_ts, filters, sort, transform);
log_rtab!(">> find_closest_nodes: node count = {}", out.len());
out
Ok(out)
}
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
let closest_nodes = {
let routing_table = self.routing_table.clone();
@ -247,11 +247,14 @@ where
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();
ctx.closest_nodes = closest_nodes;
Ok(())
}
pub async fn run(self: Arc<Self>) -> TimeoutOr<Result<Option<R>, RPCError>> {
@ -264,7 +267,9 @@ where
};
// 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
if self.clone().evaluate_done() {

View File

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

View File

@ -199,6 +199,7 @@ impl RoutingContext {
kind: Option<CryptoKind>,
) -> VeilidAPIResult<DHTRecordDescriptor> {
let kind = kind.unwrap_or(best_crypto_kind());
Crypto::validate_crypto_kind(kind)?;
let storage_manager = self.api.storage_manager()?;
storage_manager
.create_record(kind, schema, self.unlocked_inner.safety_selection)
@ -213,6 +214,7 @@ impl RoutingContext {
key: TypedKey,
writer: Option<KeyPair>,
) -> VeilidAPIResult<DHTRecordDescriptor> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?;
storage_manager
.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.
/// Closing a record allows you to re-open it with a different routing context
pub async fn close_dht_record(&self, key: TypedKey) -> VeilidAPIResult<()> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?;
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
/// 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<()> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?;
storage_manager.delete_record(key).await
}
@ -244,6 +248,7 @@ impl RoutingContext {
subkey: ValueSubkey,
force_refresh: bool,
) -> VeilidAPIResult<Option<ValueData>> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?;
storage_manager.get_value(key, subkey, force_refresh).await
}
@ -257,6 +262,7 @@ impl RoutingContext {
subkey: ValueSubkey,
data: Vec<u8>,
) -> VeilidAPIResult<Option<ValueData>> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?;
storage_manager.set_value(key, subkey, data).await
}
@ -273,6 +279,7 @@ impl RoutingContext {
expiration: Timestamp,
count: u32,
) -> VeilidAPIResult<Timestamp> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?;
storage_manager
.watch_values(key, subkeys, expiration, count)
@ -286,6 +293,7 @@ impl RoutingContext {
key: TypedKey,
subkeys: ValueSubkeyRangeSet,
) -> VeilidAPIResult<bool> {
Crypto::validate_crypto_kind(key.kind)?;
let storage_manager = self.api.storage_manager()?;
storage_manager.cancel_watch_values(key, subkeys).await
}

View File

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