wasm fixes

This commit is contained in:
John Smith 2023-03-12 12:24:21 -04:00
parent f8060715ce
commit 0ea858b08e
10 changed files with 84 additions and 74 deletions

View File

@ -83,6 +83,7 @@ impl ConnectionTable {
unord.push(v); unord.push(v);
} }
} }
inner.protocol_index_by_id.clear();
inner.id_by_descriptor.clear(); inner.id_by_descriptor.clear();
inner.ids_by_remote.clear(); inner.ids_by_remote.clear();
unord unord

View File

@ -542,7 +542,7 @@ impl RoutingTable {
} }
/// Attempt to empty the routing table /// Attempt to empty the routing table
/// should only be performed when there are no node_refs (detached) /// May not empty buckets completely if there are existing node_refs
pub fn purge_buckets(&self) { pub fn purge_buckets(&self) {
self.inner.write().purge_buckets(); self.inner.write().purge_buckets();
} }

View File

@ -1,7 +1,7 @@
use super::*; use super::*;
#[derive(Clone, Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)] #[derive(Clone, Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
#[archive_attr(repr(C), derive(CheckBytes))] #[archive_attr(repr(C, align(8)), derive(CheckBytes))]
pub struct RouteSpecDetail { pub struct RouteSpecDetail {
/// Crypto kind /// Crypto kind
pub crypto_kind: CryptoKind, pub crypto_kind: CryptoKind,
@ -13,7 +13,7 @@ pub struct RouteSpecDetail {
} }
#[derive(Clone, Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)] #[derive(Clone, Debug, RkyvArchive, RkyvSerialize, RkyvDeserialize)]
#[archive_attr(repr(C), derive(CheckBytes))] #[archive_attr(repr(C, align(8)), derive(CheckBytes))]
pub struct RouteSetSpecDetail { pub struct RouteSetSpecDetail {
/// Route set per crypto kind /// Route set per crypto kind
route_set: BTreeMap<PublicKey, RouteSpecDetail>, route_set: BTreeMap<PublicKey, RouteSpecDetail>,

View File

@ -471,13 +471,14 @@ impl VeilidAPI {
// Purge connection table // Purge connection table
let connection_manager = self.network_manager()?.connection_manager(); let connection_manager = self.network_manager()?.connection_manager();
connection_manager.shutdown().await; connection_manager.shutdown().await;
connection_manager.startup().await;
// Eliminate last_connections from routing table entries // Eliminate last_connections from routing table entries
self.network_manager()? self.network_manager()?
.routing_table() .routing_table()
.purge_last_connections(); .purge_last_connections();
connection_manager.startup().await;
Ok("Connections purged".to_owned()) Ok("Connections purged".to_owned())
} else if args[0] == "routes" { } else if args[0] == "routes" {
// Purge route spec store // Purge route spec store

View File

@ -118,15 +118,18 @@ class _MyAppState extends State<MyApp> with UiLoggy {
}); });
await Veilid.instance.attach(); await Veilid.instance.attach();
} else if (!startup && _startedUp) { } else if (!startup && _startedUp) {
await Veilid.instance.shutdownVeilidCore(); try {
if (_updateProcessor != null) { await Veilid.instance.shutdownVeilidCore();
await _updateProcessor; if (_updateProcessor != null) {
await _updateProcessor;
}
} finally {
setState(() {
_updateProcessor = null;
_updateStream = null;
_startedUp = false;
});
} }
setState(() {
_updateProcessor = null;
_updateStream = null;
_startedUp = false;
});
} }
} }

View File

@ -46,12 +46,12 @@ Future<VeilidConfig> getDefaultVeilidConfig(String programName) async {
clientWhitelistTimeoutMs: 300000, clientWhitelistTimeoutMs: 300000,
reverseConnectionReceiptTimeMs: 5000, reverseConnectionReceiptTimeMs: 5000,
holePunchReceiptTimeMs: 5000, holePunchReceiptTimeMs: 5000,
nodeId: null,
nodeIdSecret: null,
bootstrap: kIsWeb
? ["ws://bootstrap.dev.veilid.net:5150/ws"]
: ["bootstrap.dev.veilid.net"],
routingTable: VeilidConfigRoutingTable( routingTable: VeilidConfigRoutingTable(
nodeId: [],
nodeIdSecret: [],
bootstrap: kIsWeb
? ["ws://bootstrap.dev.veilid.net:5150/ws"]
: ["bootstrap.dev.veilid.net"],
limitOverAttached: 64, limitOverAttached: 64,
limitFullyAttached: 32, limitFullyAttached: 32,
limitAttachedStrong: 16, limitAttachedStrong: 16,

View File

@ -697,6 +697,9 @@ class VeilidConfigRPC {
//////////// ////////////
class VeilidConfigRoutingTable { class VeilidConfigRoutingTable {
List<String> nodeId;
List<String> nodeIdSecret;
List<String> bootstrap;
int limitOverAttached; int limitOverAttached;
int limitFullyAttached; int limitFullyAttached;
int limitAttachedStrong; int limitAttachedStrong;
@ -704,6 +707,9 @@ class VeilidConfigRoutingTable {
int limitAttachedWeak; int limitAttachedWeak;
VeilidConfigRoutingTable({ VeilidConfigRoutingTable({
required this.nodeId,
required this.nodeIdSecret,
required this.bootstrap,
required this.limitOverAttached, required this.limitOverAttached,
required this.limitFullyAttached, required this.limitFullyAttached,
required this.limitAttachedStrong, required this.limitAttachedStrong,
@ -713,6 +719,9 @@ class VeilidConfigRoutingTable {
Map<String, dynamic> get json { Map<String, dynamic> get json {
return { return {
'node_id': nodeId.map((p) => p).toList(),
'node_id_secret': nodeIdSecret.map((p) => p).toList(),
'bootstrap': bootstrap.map((p) => p).toList(),
'limit_over_attached': limitOverAttached, 'limit_over_attached': limitOverAttached,
'limit_fully_attached': limitFullyAttached, 'limit_fully_attached': limitFullyAttached,
'limit_attached_strong': limitAttachedStrong, 'limit_attached_strong': limitAttachedStrong,
@ -722,7 +731,10 @@ class VeilidConfigRoutingTable {
} }
VeilidConfigRoutingTable.fromJson(dynamic json) VeilidConfigRoutingTable.fromJson(dynamic json)
: limitOverAttached = json['limit_over_attached'], : nodeId = List<String>.from(json['node_id'].map((j) => j)),
nodeIdSecret = List<String>.from(json['node_id_secret'].map((j) => j)),
bootstrap = List<String>.from(json['bootstrap'].map((j) => j)),
limitOverAttached = json['limit_over_attached'],
limitFullyAttached = json['limit_fully_attached'], limitFullyAttached = json['limit_fully_attached'],
limitAttachedStrong = json['limit_attached_strong'], limitAttachedStrong = json['limit_attached_strong'],
limitAttachedGood = json['limit_attached_good'], limitAttachedGood = json['limit_attached_good'],
@ -741,9 +753,6 @@ class VeilidConfigNetwork {
int clientWhitelistTimeoutMs; int clientWhitelistTimeoutMs;
int reverseConnectionReceiptTimeMs; int reverseConnectionReceiptTimeMs;
int holePunchReceiptTimeMs; int holePunchReceiptTimeMs;
String? nodeId;
String? nodeIdSecret;
List<String> bootstrap;
VeilidConfigRoutingTable routingTable; VeilidConfigRoutingTable routingTable;
VeilidConfigRPC rpc; VeilidConfigRPC rpc;
VeilidConfigDHT dht; VeilidConfigDHT dht;
@ -764,9 +773,6 @@ class VeilidConfigNetwork {
required this.clientWhitelistTimeoutMs, required this.clientWhitelistTimeoutMs,
required this.reverseConnectionReceiptTimeMs, required this.reverseConnectionReceiptTimeMs,
required this.holePunchReceiptTimeMs, required this.holePunchReceiptTimeMs,
required this.nodeId,
required this.nodeIdSecret,
required this.bootstrap,
required this.routingTable, required this.routingTable,
required this.rpc, required this.rpc,
required this.dht, required this.dht,
@ -789,9 +795,6 @@ class VeilidConfigNetwork {
'client_whitelist_timeout_ms': clientWhitelistTimeoutMs, 'client_whitelist_timeout_ms': clientWhitelistTimeoutMs,
'reverse_connection_receipt_time_ms': reverseConnectionReceiptTimeMs, 'reverse_connection_receipt_time_ms': reverseConnectionReceiptTimeMs,
'hole_punch_receipt_time_ms': holePunchReceiptTimeMs, 'hole_punch_receipt_time_ms': holePunchReceiptTimeMs,
'node_id': nodeId,
'node_id_secret': nodeIdSecret,
'bootstrap': bootstrap,
'routing_table': routingTable.json, 'routing_table': routingTable.json,
'rpc': rpc.json, 'rpc': rpc.json,
'dht': dht.json, 'dht': dht.json,
@ -817,9 +820,6 @@ class VeilidConfigNetwork {
reverseConnectionReceiptTimeMs = reverseConnectionReceiptTimeMs =
json['reverse_connection_receipt_time_ms'], json['reverse_connection_receipt_time_ms'],
holePunchReceiptTimeMs = json['hole_punch_receipt_time_ms'], holePunchReceiptTimeMs = json['hole_punch_receipt_time_ms'],
nodeId = json['node_id'],
nodeIdSecret = json['node_id_secret'],
bootstrap = json['bootstrap'],
routingTable = VeilidConfigRoutingTable.fromJson(json['routing_table']), routingTable = VeilidConfigRoutingTable.fromJson(json['routing_table']),
rpc = VeilidConfigRPC.fromJson(json['rpc']), rpc = VeilidConfigRPC.fromJson(json['rpc']),
dht = VeilidConfigDHT.fromJson(json['dht']), dht = VeilidConfigDHT.fromJson(json['dht']),
@ -1159,26 +1159,26 @@ class PeerStats {
//////////// ////////////
class PeerTableData { class PeerTableData {
String nodeId; List<String> nodeIds;
PeerAddress peerAddress; PeerAddress peerAddress;
PeerStats peerStats; PeerStats peerStats;
PeerTableData({ PeerTableData({
required this.nodeId, required this.nodeIds,
required this.peerAddress, required this.peerAddress,
required this.peerStats, required this.peerStats,
}); });
Map<String, dynamic> get json { Map<String, dynamic> get json {
return { return {
'node_id': nodeId, 'node_ids': nodeIds.map((p) => p).toList(),
'peer_address': peerAddress.json, 'peer_address': peerAddress.json,
'peer_stats': peerStats.json, 'peer_stats': peerStats.json,
}; };
} }
PeerTableData.fromJson(dynamic json) PeerTableData.fromJson(dynamic json)
: nodeId = json['node_id'], : nodeIds = List<String>.from(json['node_ids'].map((j) => j)),
peerAddress = PeerAddress.fromJson(json['peer_address']), peerAddress = PeerAddress.fromJson(json['peer_address']),
peerStats = PeerStats.fromJson(json['peer_stats']); peerStats = PeerStats.fromJson(json['peer_stats']);
} }

View File

@ -861,8 +861,9 @@ class VeilidFFI implements Veilid {
final sendPort = recvPort.sendPort; final sendPort = recvPort.sendPort;
_newCustomPrivateRoute(sendPort.nativePort, stability.json.toNativeUtf8(), _newCustomPrivateRoute(sendPort.nativePort, stability.json.toNativeUtf8(),
sequencing.json.toNativeUtf8()); sequencing.json.toNativeUtf8());
final keyblob = await processFutureJson(RouteBlob.fromJson, recvPort.first); final routeBlob =
return keyblob; await processFutureJson(RouteBlob.fromJson, recvPort.first);
return routeBlob;
} }
@override @override

View File

@ -499,9 +499,9 @@ pub extern "C" fn new_private_route(port: i64) {
let (route_id, blob) = veilid_api.new_private_route().await?; let (route_id, blob) = veilid_api.new_private_route().await?;
let keyblob = VeilidFFIRouteBlob { route_id, blob }; let route_blob = VeilidFFIRouteBlob { route_id, blob };
APIResult::Ok(keyblob) APIResult::Ok(route_blob)
}); });
} }
@ -519,9 +519,9 @@ pub extern "C" fn new_custom_private_route(port: i64, stability: FfiStr, sequenc
.new_custom_private_route(&veilid_core::VALID_CRYPTO_KINDS, stability, sequencing) .new_custom_private_route(&veilid_core::VALID_CRYPTO_KINDS, stability, sequencing)
.await?; .await?;
let keyblob = VeilidFFIRouteBlob { route_id, blob }; let route_blob = VeilidFFIRouteBlob { route_id, blob };
APIResult::Ok(keyblob) APIResult::Ok(route_blob)
}); });
} }
@ -544,9 +544,9 @@ pub extern "C" fn import_remote_private_route(port: i64, blob: FfiStr) {
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn release_private_route(port: i64, key: FfiStr) { pub extern "C" fn release_private_route(port: i64, route_id: FfiStr) {
let route_id: veilid_core::RouteId = let route_id: veilid_core::RouteId =
veilid_core::deserialize_opt_json(key.into_opt_string()).unwrap(); veilid_core::deserialize_opt_json(route_id.into_opt_string()).unwrap();
DartIsolateWrapper::new(port).spawn_result(async move { DartIsolateWrapper::new(port).spawn_result(async move {
let veilid_api = get_veilid_api().await?; let veilid_api = get_veilid_api().await?;
veilid_api.release_private_route(route_id)?; veilid_api.release_private_route(route_id)?;

View File

@ -79,6 +79,28 @@ pub fn from_json<T: de::DeserializeOwned + Debug>(
deserialize_json(&s) deserialize_json(&s)
} }
// Parse target
fn parse_target(s: String) -> APIResult<veilid_core::Target> {
// Is this a route id?
if let Ok(rrid) = veilid_core::RouteId::from_str(&s) {
let veilid_api = get_veilid_api()?;
let routing_table = veilid_api.routing_table()?;
let rss = routing_table.route_spec_store();
// Is this a valid remote route id? (can't target allocated routes)
if rss.is_route_id_remote(&rrid) {
return Ok(veilid_core::Target::PrivateRoute(rrid));
}
}
// Is this a node id?
if let Ok(nid) = veilid_core::PublicKey::from_str(&s) {
return Ok(veilid_core::Target::NodeId(nid));
}
Err(veilid_core::VeilidAPIError::invalid_target())
}
// Utility types for async API results // Utility types for async API results
type APIResult<T> = Result<T, veilid_core::VeilidAPIError>; type APIResult<T> = Result<T, veilid_core::VeilidAPIError>;
const APIRESULT_UNDEFINED: APIResult<()> = APIResult::Ok(()); const APIRESULT_UNDEFINED: APIResult<()> = APIResult::Ok(());
@ -136,8 +158,8 @@ pub struct VeilidWASMConfig {
} }
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
pub struct VeilidKeyBlob { pub struct VeilidRouteBlob {
pub key: veilid_core::TypedKey, pub route_id: veilid_core::RouteId,
#[serde(with = "veilid_core::json_as_base64")] #[serde(with = "veilid_core::json_as_base64")]
pub blob: Vec<u8>, pub blob: Vec<u8>,
} }
@ -355,7 +377,6 @@ pub fn routing_context_app_call(id: u32, target: String, request: String) -> Pro
wrap_api_future_plain(async move { wrap_api_future_plain(async move {
let veilid_api = get_veilid_api()?; let veilid_api = get_veilid_api()?;
let routing_table = veilid_api.routing_table()?; let routing_table = veilid_api.routing_table()?;
let rss = routing_table.route_spec_store();
let routing_context = { let routing_context = {
let rc = (*ROUTING_CONTEXTS).borrow(); let rc = (*ROUTING_CONTEXTS).borrow();
@ -365,15 +386,7 @@ pub fn routing_context_app_call(id: u32, target: String, request: String) -> Pro
routing_context.clone() routing_context.clone()
}; };
let target: DHTKey = let target = parse_target(target)?;
DHTKey::try_decode(&target).map_err(|e| VeilidAPIError::parse_error(e, &target))?;
let target = if rss.get_remote_private_route(&target).is_some() {
veilid_core::Target::PrivateRoute(target)
} else {
veilid_core::Target::NodeId(veilid_core::NodeId::new(target))
};
let answer = routing_context.app_call(target, request).await?; let answer = routing_context.app_call(target, request).await?;
let answer = data_encoding::BASE64URL_NOPAD.encode(&answer); let answer = data_encoding::BASE64URL_NOPAD.encode(&answer);
APIResult::Ok(answer) APIResult::Ok(answer)
@ -388,7 +401,6 @@ pub fn routing_context_app_message(id: u32, target: String, message: String) ->
wrap_api_future_void(async move { wrap_api_future_void(async move {
let veilid_api = get_veilid_api()?; let veilid_api = get_veilid_api()?;
let routing_table = veilid_api.routing_table()?; let routing_table = veilid_api.routing_table()?;
let rss = routing_table.route_spec_store();
let routing_context = { let routing_context = {
let rc = (*ROUTING_CONTEXTS).borrow(); let rc = (*ROUTING_CONTEXTS).borrow();
@ -398,15 +410,7 @@ pub fn routing_context_app_message(id: u32, target: String, message: String) ->
routing_context.clone() routing_context.clone()
}; };
let target: DHTKey = let target = parse_target(target)?;
DHTKey::try_decode(&target).map_err(|e| VeilidAPIError::parse_error(e, &target))?;
let target = if rss.get_remote_private_route(&target).is_some() {
veilid_core::Target::PrivateRoute(target)
} else {
veilid_core::Target::NodeId(veilid_core::NodeId::new(target))
};
routing_context.app_message(target, message).await?; routing_context.app_message(target, message).await?;
APIRESULT_UNDEFINED APIRESULT_UNDEFINED
}) })
@ -417,11 +421,11 @@ pub fn new_private_route() -> Promise {
wrap_api_future_json(async move { wrap_api_future_json(async move {
let veilid_api = get_veilid_api()?; let veilid_api = get_veilid_api()?;
let (key, blob) = veilid_api.new_private_route().await?; let (route_id, blob) = veilid_api.new_private_route().await?;
let keyblob = VeilidKeyBlob { key, blob }; let route_blob = VeilidRouteBlob { route_id, blob };
APIResult::Ok(keyblob) APIResult::Ok(route_blob)
}) })
} }
@ -433,13 +437,13 @@ pub fn new_custom_private_route(stability: String, sequencing: String) -> Promis
wrap_api_future_json(async move { wrap_api_future_json(async move {
let veilid_api = get_veilid_api()?; let veilid_api = get_veilid_api()?;
let (key, blob) = veilid_api let (route_id, blob) = veilid_api
.new_custom_private_route(stability, sequencing) .new_custom_private_route(&veilid_core::VALID_CRYPTO_KINDS, stability, sequencing)
.await?; .await?;
let keyblob = VeilidKeyBlob { key, blob }; let route_blob = VeilidRouteBlob { route_id, blob };
APIResult::Ok(keyblob) APIResult::Ok(route_blob)
}) })
} }
@ -458,11 +462,11 @@ pub fn import_remote_private_route(blob: String) -> Promise {
} }
#[wasm_bindgen()] #[wasm_bindgen()]
pub fn release_private_route(key: String) -> Promise { pub fn release_private_route(route_id: String) -> Promise {
let key: veilid_core::TypedKey = veilid_core::deserialize_json(&key).unwrap(); let route_id: veilid_core::RouteId = veilid_core::deserialize_json(&route_id).unwrap();
wrap_api_future_void(async move { wrap_api_future_void(async move {
let veilid_api = get_veilid_api()?; let veilid_api = get_veilid_api()?;
veilid_api.release_private_route(&key)?; veilid_api.release_private_route(route_id)?;
APIRESULT_UNDEFINED APIRESULT_UNDEFINED
}) })
} }